]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #22541 - Manishearth:rollup, r=Gankro
authorbors <bors@rust-lang.org>
Thu, 19 Feb 2015 18:36:59 +0000 (18:36 +0000)
committerbors <bors@rust-lang.org>
Thu, 19 Feb 2015 18:36:59 +0000 (18:36 +0000)
Continued from #22520

829 files changed:
README.md
configure
mk/tests.mk
src/compiletest/common.rs
src/compiletest/compiletest.rs
src/compiletest/runtest.rs
src/doc/reference.md
src/doc/trpl/ffi.md
src/doc/trpl/patterns.md
src/liballoc/arc.rs
src/liballoc/boxed.rs
src/liballoc/lib.rs
src/liballoc/rc.rs
src/libarena/lib.rs
src/libcollections/binary_heap.rs
src/libcollections/bit.rs
src/libcollections/borrow.rs [new file with mode: 0644]
src/libcollections/borrow_stage0.rs [new file with mode: 0644]
src/libcollections/btree/map.rs
src/libcollections/btree/node.rs
src/libcollections/btree/set.rs
src/libcollections/dlist.rs [deleted file]
src/libcollections/enum_set.rs
src/libcollections/lib.rs
src/libcollections/linked_list.rs [new file with mode: 0644]
src/libcollections/ring_buf.rs [deleted file]
src/libcollections/slice.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollections/vec.rs
src/libcollections/vec_deque.rs [new file with mode: 0644]
src/libcollections/vec_map.rs
src/libcore/array.rs
src/libcore/atomic.rs
src/libcore/borrow.rs [deleted file]
src/libcore/cmp.rs
src/libcore/default.rs
src/libcore/fmt/mod.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/marker.rs
src/libcore/nonzero.rs
src/libcore/option.rs
src/libcore/ptr.rs
src/libcore/result.rs
src/libcore/slice.rs
src/libcore/str/mod.rs
src/libcoretest/hash/mod.rs
src/libcoretest/iter.rs
src/libcoretest/mem.rs
src/libcoretest/ptr.rs
src/libcoretest/slice.rs
src/libflate/lib.rs
src/libfmt_macros/lib.rs
src/libgetopts/lib.rs
src/libgraphviz/lib.rs
src/liblog/lib.rs
src/librand/distributions/mod.rs
src/librand/isaac.rs
src/librand/lib.rs
src/librustc/lint/builtin.rs
src/librustc/lint/context.rs
src/librustc/lint/mod.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/cstore.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/loader.rs
src/librustc/metadata/tydecode.rs
src/librustc/middle/astencode.rs
src/librustc/middle/cfg/graphviz.rs
src/librustc/middle/check_match.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/dataflow.rs
src/librustc/middle/dead.rs
src/librustc/middle/dependency_format.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/graph.rs
src/librustc/middle/infer/bivariate.rs [new file with mode: 0644]
src/librustc/middle/infer/combine.rs
src/librustc/middle/infer/equate.rs
src/librustc/middle/infer/error_reporting.rs
src/librustc/middle/infer/glb.rs
src/librustc/middle/infer/higher_ranked/mod.rs
src/librustc/middle/infer/lub.rs
src/librustc/middle/infer/mod.rs
src/librustc/middle/infer/region_inference/mod.rs
src/librustc/middle/infer/sub.rs
src/librustc/middle/infer/type_variable.rs
src/librustc/middle/infer/unify.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/liveness.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/subst.rs
src/librustc/middle/traits/coherence.rs
src/librustc/middle/traits/mod.rs
src/librustc/middle/traits/object_safety.rs
src/librustc/middle/traits/select.rs
src/librustc/middle/ty.rs
src/librustc/middle/weak_lang_items.rs
src/librustc/plugin/load.rs
src/librustc/session/config.rs
src/librustc/session/mod.rs
src/librustc/util/common.rs
src/librustc/util/lev_distance.rs
src/librustc/util/nodemap.rs
src/librustc/util/ppaux.rs
src/librustc_back/archive.rs
src/librustc_back/rpath.rs
src/librustc_back/target/mod.rs
src/librustc_borrowck/borrowck/check_loans.rs
src/librustc_borrowck/borrowck/fragments.rs
src/librustc_borrowck/borrowck/mod.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_llvm/archive_ro.rs
src/librustc_llvm/lib.rs
src/librustc_privacy/lib.rs
src/librustc_resolve/lib.rs
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/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/builder.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/debuginfo.rs
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/foreign.rs
src/librustc_trans/trans/glue.rs
src/librustc_trans/trans/intrinsic.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_typeck/astconv.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/callee.rs
src/librustc_typeck/check/implicator.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/regionck.rs
src/librustc_typeck/check/vtable.rs
src/librustc_typeck/check/wf.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/constrained_type_params.rs [new file with mode: 0644]
src/librustc_typeck/lib.rs
src/librustc_typeck/variance.rs
src/librustdoc/flock.rs
src/librustdoc/html/highlight.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/main.css
src/librustdoc/lib.rs
src/librustdoc/passes.rs
src/librustdoc/visit_ast.rs
src/libserialize/collection_impls.rs
src/libserialize/json.rs
src/libserialize/lib.rs
src/libserialize/serialize.rs
src/libstd/collections/hash/map.rs
src/libstd/collections/hash/map_stage0.rs [new file with mode: 0644]
src/libstd/collections/hash/mod.rs
src/libstd/collections/hash/set.rs
src/libstd/collections/hash/set_stage0.rs [new file with mode: 0644]
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/ffi/c_str.rs
src/libstd/ffi/mod.rs
src/libstd/ffi/os_str.rs
src/libstd/io/buffered.rs
src/libstd/io/cursor.rs
src/libstd/lib.rs
src/libstd/net/addr.rs
src/libstd/net/ip.rs
src/libstd/old_io/buffered.rs
src/libstd/old_io/mod.rs
src/libstd/old_io/net/pipe.rs
src/libstd/old_io/process.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
src/libstd/rand/mod.rs
src/libstd/rt/args.rs
src/libstd/sys/common/net.rs
src/libstd/sys/common/net2.rs
src/libstd/sys/common/wtf8.rs
src/libstd/sys/unix/backtrace.rs
src/libstd/sys/unix/ext.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/unix/fs2.rs
src/libstd/sys/unix/mod.rs
src/libstd/sys/unix/net.rs
src/libstd/sys/unix/os.rs
src/libstd/sys/unix/pipe.rs
src/libstd/sys/unix/process.rs
src/libstd/sys/unix/process2.rs
src/libstd/sys/unix/thread.rs
src/libstd/sys/windows/backtrace.rs
src/libstd/sys/windows/c.rs
src/libstd/sys/windows/mod.rs
src/libstd/sys/windows/os.rs
src/libstd/sys/windows/process.rs
src/libstd/thread.rs
src/libsyntax/ast.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/plugin.rs
src/libsyntax/diagnostics/registry.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/concat.rs
src/libsyntax/ext/concat_idents.rs
src/libsyntax/ext/deriving/bounds.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/deriving/hash.rs
src/libsyntax/ext/deriving/mod.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/quote.rs
src/libsyntax/ext/source_util.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/ext/tt/transcribe.rs
src/libsyntax/feature_gate.rs
src/libsyntax/lib.rs
src/libsyntax/owned_slice.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/small_vector.rs
src/libterm/lib.rs
src/libterm/terminfo/mod.rs
src/libterm/terminfo/parm.rs
src/libterm/terminfo/searcher.rs
src/libtest/lib.rs
src/libtest/stats.rs
src/llvm
src/rustbook/build.rs
src/rustbook/error.rs
src/rustbook/test.rs
src/test/auxiliary/coherence-orphan-lib.rs
src/test/auxiliary/default_type_params_xc.rs
src/test/auxiliary/inner_static.rs
src/test/auxiliary/issue-14421.rs
src/test/auxiliary/issue-16643.rs
src/test/auxiliary/issue-17662.rs
src/test/auxiliary/issue-2380.rs
src/test/auxiliary/issue-2526.rs
src/test/auxiliary/issue_20389.rs
src/test/auxiliary/issue_3907.rs
src/test/auxiliary/issue_8401.rs
src/test/auxiliary/issue_9123.rs
src/test/auxiliary/lang-item-public.rs
src/test/auxiliary/lint_group_plugin_test.rs
src/test/auxiliary/lint_plugin_test.rs
src/test/auxiliary/lint_stability.rs
src/test/auxiliary/nested_item.rs
src/test/auxiliary/orphan_check_diagnostics.rs
src/test/auxiliary/overloaded_autoderef_xc.rs
src/test/auxiliary/plugin_args.rs
src/test/auxiliary/private_trait_xc.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/trait_bounds_on_structs_and_enums_xc.rs
src/test/auxiliary/trait_impl_conflict.rs
src/test/auxiliary/use_from_trait_xc.rs
src/test/bench/core-set.rs
src/test/bench/shootout-fasta.rs
src/test/bench/shootout-meteor.rs
src/test/compile-fail/ascii-only-character-escape.rs [deleted file]
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-issue-17359.rs
src/test/compile-fail/associated-types-multiple-types-one-trait.rs
src/test/compile-fail/associated-types-no-suitable-supertrait.rs
src/test/compile-fail/associated-types-path-2.rs
src/test/compile-fail/associated-types-unconstrained.rs
src/test/compile-fail/attr-before-eof.rs [deleted file]
src/test/compile-fail/attr-before-ext.rs [deleted file]
src/test/compile-fail/attr-before-let.rs [deleted file]
src/test/compile-fail/attr-before-stmt.rs [deleted file]
src/test/compile-fail/attr-dangling-in-fn.rs [deleted file]
src/test/compile-fail/attr-dangling-in-mod.rs [deleted file]
src/test/compile-fail/attr.rs [deleted file]
src/test/compile-fail/attrs-after-extern-mod.rs [deleted file]
src/test/compile-fail/bad-char-literals.rs [deleted file]
src/test/compile-fail/bad-lit-suffixes.rs [deleted file]
src/test/compile-fail/bad-mid-path-type-params.rs
src/test/compile-fail/bad-sized.rs
src/test/compile-fail/bad-value-ident-false.rs [deleted file]
src/test/compile-fail/bad-value-ident-true.rs [deleted file]
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-conflicting-negative-trait-impl.rs
src/test/compile-fail/coherence-subtyping.rs [new file with mode: 0644]
src/test/compile-fail/cross-borrow-trait.rs
src/test/compile-fail/destructure-trait-ref.rs
src/test/compile-fail/doc-before-attr.rs [deleted file]
src/test/compile-fail/doc-before-eof.rs [deleted file]
src/test/compile-fail/doc-before-extern-rbrace.rs [deleted file]
src/test/compile-fail/doc-before-macro.rs [deleted file]
src/test/compile-fail/doc-before-rbrace.rs [deleted file]
src/test/compile-fail/doc-before-semi.rs [deleted file]
src/test/compile-fail/dst-bad-coerce1.rs
src/test/compile-fail/dst-bad-coerce2.rs
src/test/compile-fail/dst-bad-coerce3.rs
src/test/compile-fail/dst-bad-coercions.rs
src/test/compile-fail/dst-object-from-unsized-type.rs
src/test/compile-fail/exclusive-drop-and-copy.rs
src/test/compile-fail/extern-crate-as-no-string-help.rs [deleted file]
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-lifetime-trait-impl.rs
src/test/compile-fail/generic-non-trailing-defaults.rs [deleted file]
src/test/compile-fail/generic-type-less-params-with-defaults.rs
src/test/compile-fail/generic-type-more-params-with-defaults.rs
src/test/compile-fail/generic-type-params-name-repr.rs
src/test/compile-fail/int-literal-too-large-span.rs [deleted file]
src/test/compile-fail/issue-10412.rs [deleted file]
src/test/compile-fail/issue-11515.rs
src/test/compile-fail/issue-12560-1.rs [deleted file]
src/test/compile-fail/issue-13853-2.rs
src/test/compile-fail/issue-13853-3.rs
src/test/compile-fail/issue-13853.rs
src/test/compile-fail/issue-14182.rs [deleted file]
src/test/compile-fail/issue-14285.rs
src/test/compile-fail/issue-14853.rs
src/test/compile-fail/issue-16747.rs
src/test/compile-fail/issue-17383.rs [deleted file]
src/test/compile-fail/issue-17431-4.rs
src/test/compile-fail/issue-17431-5.rs
src/test/compile-fail/issue-17551.rs
src/test/compile-fail/issue-17718-const-mut.rs [deleted file]
src/test/compile-fail/issue-17904-2.rs [new file with mode: 0644]
src/test/compile-fail/issue-1802-2.rs [deleted file]
src/test/compile-fail/issue-18107.rs
src/test/compile-fail/issue-18611.rs
src/test/compile-fail/issue-18783.rs
src/test/compile-fail/issue-18819.rs
src/test/compile-fail/issue-19660.rs
src/test/compile-fail/issue-2063.rs
src/test/compile-fail/issue-20831-debruijn.rs
src/test/compile-fail/issue-21160.rs
src/test/compile-fail/issue-2611-4.rs
src/test/compile-fail/issue-3008-3.rs
src/test/compile-fail/issue-4972.rs
src/test/compile-fail/issue-5035-2.rs
src/test/compile-fail/issue-5543.rs
src/test/compile-fail/issue-5544-a.rs [deleted file]
src/test/compile-fail/issue-5544-b.rs [deleted file]
src/test/compile-fail/issue-5883.rs
src/test/compile-fail/issue-6458.rs
src/test/compile-fail/issue-7575.rs
src/test/compile-fail/issue-8537.rs [deleted file]
src/test/compile-fail/issue-8727.rs
src/test/compile-fail/keyword-as-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-break-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-else-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-enum-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-extern-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-fn-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-for-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-if-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-impl-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-let-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-loop-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-match-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-mod-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-pub-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-return-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-self-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-static-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-struct-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-super-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-super.rs [deleted file]
src/test/compile-fail/keyword-trait-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-type-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-unsafe-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-use-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-while-as-identifier.rs [deleted file]
src/test/compile-fail/keyword.rs [deleted file]
src/test/compile-fail/keywords-followed-by-double-colon.rs [deleted file]
src/test/compile-fail/kindck-copy.rs
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-send-object.rs
src/test/compile-fail/kindck-send-object1.rs
src/test/compile-fail/kindck-send-object2.rs
src/test/compile-fail/lex-bad-numeric-literals.rs [deleted file]
src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs [deleted file]
src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs
src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs
src/test/compile-fail/lifetime-no-keyword.rs [deleted file]
src/test/compile-fail/lifetime-obsoleted-self.rs [deleted file]
src/test/compile-fail/lint-missing-doc.rs
src/test/compile-fail/lint-non-camel-case-types.rs
src/test/compile-fail/lint-stability.rs
src/test/compile-fail/lint-visible-private-types.rs
src/test/compile-fail/liveness-use-after-send.rs
src/test/compile-fail/macros-no-semicolon-items.rs [deleted file]
src/test/compile-fail/map-types.rs
src/test/compile-fail/method-ambig-one-trait-coerce.rs [deleted file]
src/test/compile-fail/mod_file_disambig.rs [new file with mode: 0644]
src/test/compile-fail/mod_file_not_owning.rs [new file with mode: 0644]
src/test/compile-fail/no-binary-float-literal.rs [deleted file]
src/test/compile-fail/no-hex-float-literal.rs [deleted file]
src/test/compile-fail/no-unsafe-self.rs [deleted file]
src/test/compile-fail/non-str-meta.rs [deleted file]
src/test/compile-fail/object-does-not-impl-trait.rs
src/test/compile-fail/object-lifetime-default-mybox.rs
src/test/compile-fail/object-safety-issue-22040.rs [new file with mode: 0644]
src/test/compile-fail/object-safety-no-static.rs
src/test/compile-fail/object-safety-phantom-fn.rs [new file with mode: 0644]
src/test/compile-fail/object-safety-supertrait-mentions-Self.rs [new file with mode: 0644]
src/test/compile-fail/obsolete-for-sized.rs [deleted file]
src/test/compile-fail/obsolete-proc.rs [deleted file]
src/test/compile-fail/on-unimplemented-bad-anno.rs
src/test/compile-fail/on-unimplemented.rs
src/test/compile-fail/orphan-check-diagnostics.rs
src/test/compile-fail/priv-in-bad-locations.rs
src/test/compile-fail/privacy-ns2.rs
src/test/compile-fail/privacy1.rs
src/test/compile-fail/privacy4.rs
src/test/compile-fail/qquote-1.rs [deleted file]
src/test/compile-fail/qquote-2.rs [deleted file]
src/test/compile-fail/region-object-lifetime-in-coercion.rs
src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs
src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs
src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs
src/test/compile-fail/regions-assoc-type-outlives-container.rs
src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs
src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs
src/test/compile-fail/regions-bound-missing-bound-in-impl.rs
src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.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-2.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 [new file with mode: 0644]
src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs
src/test/compile-fail/regions-close-param-into-object.rs
src/test/compile-fail/regions-fn-bound.rs [deleted file]
src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs
src/test/compile-fail/regions-infer-covariance-due-to-decl.rs
src/test/compile-fail/regions-infer-invariance-due-to-decl.rs
src/test/compile-fail/require-parens-for-chained-comparison.rs [deleted file]
src/test/compile-fail/required-lang-item.rs
src/test/compile-fail/shadowed-type-parameter.rs
src/test/compile-fail/slice-1.rs
src/test/compile-fail/slightly-nice-generic-literal-messages.rs
src/test/compile-fail/staticness-mismatch.rs
src/test/compile-fail/struct-no-fields-2.rs [deleted file]
src/test/compile-fail/struct-no-fields-3.rs [deleted file]
src/test/compile-fail/struct-no-fields-4.rs [deleted file]
src/test/compile-fail/struct-no-fields-5.rs [deleted file]
src/test/compile-fail/struct-variant-no-fields.rs [deleted file]
src/test/compile-fail/struct-variant-no-pub.rs [deleted file]
src/test/compile-fail/syntax-trait-polarity.rs [deleted file]
src/test/compile-fail/tag-variant-disr-non-nullary.rs [deleted file]
src/test/compile-fail/trailing-carriage-return-in-string.rs [deleted file]
src/test/compile-fail/trailing-plus-in-bounds.rs [deleted file]
src/test/compile-fail/trait-as-struct-constructor.rs
src/test/compile-fail/trait-bounds-cant-coerce.rs
src/test/compile-fail/trait-bounds-impl-comparison-1.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-not-on-impl.rs [deleted file]
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.rs
src/test/compile-fail/trait-bounds-sugar.rs
src/test/compile-fail/trait-impl-1.rs
src/test/compile-fail/trait-object-safety.rs
src/test/compile-fail/trait-static-method-generic-inference.rs
src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs [new file with mode: 0644]
src/test/compile-fail/type-parameter-defaults-referencing-Self.rs [new file with mode: 0644]
src/test/compile-fail/type-parameters-in-field-exprs.rs [deleted file]
src/test/compile-fail/typeck-negative-impls-builtin.rs
src/test/compile-fail/typeck_type_placeholder_mismatch.rs
src/test/compile-fail/ufcs-qpath-missing-params.rs
src/test/compile-fail/unboxed-closure-feature-gate.rs
src/test/compile-fail/unboxed-closure-sugar-default.rs
src/test/compile-fail/unboxed-closure-sugar-equiv.rs
src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs
src/test/compile-fail/unboxed-closure-sugar-region.rs
src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs
src/test/compile-fail/unnecessary-private.rs
src/test/compile-fail/unsized-inherent-impl-self-type.rs
src/test/compile-fail/unsized-trait-impl-self-type.rs
src/test/compile-fail/unsized-trait-impl-trait-arg.rs
src/test/compile-fail/unsized2.rs [deleted file]
src/test/compile-fail/unsized3.rs
src/test/compile-fail/unsized6.rs
src/test/compile-fail/unsized7.rs
src/test/compile-fail/unused-attr.rs
src/test/compile-fail/useless-priv.rs
src/test/compile-fail/useless-priv2.rs
src/test/compile-fail/variance-contravariant-arg-object.rs [new file with mode: 0644]
src/test/compile-fail/variance-contravariant-arg-trait-match.rs [new file with mode: 0644]
src/test/compile-fail/variance-contravariant-self-trait-match.rs [new file with mode: 0644]
src/test/compile-fail/variance-covariant-arg-object.rs [new file with mode: 0644]
src/test/compile-fail/variance-covariant-arg-trait-match.rs [new file with mode: 0644]
src/test/compile-fail/variance-covariant-self-trait-match.rs [new file with mode: 0644]
src/test/compile-fail/variance-deprecated-markers.rs [new file with mode: 0644]
src/test/compile-fail/variance-invariant-arg-object.rs [new file with mode: 0644]
src/test/compile-fail/variance-invariant-arg-trait-match.rs [new file with mode: 0644]
src/test/compile-fail/variance-invariant-self-trait-match.rs [new file with mode: 0644]
src/test/compile-fail/variance-issue-20533.rs [new file with mode: 0644]
src/test/compile-fail/variance-regions-direct.rs
src/test/compile-fail/variance-regions-indirect.rs
src/test/compile-fail/variance-regions-unused-direct.rs [new file with mode: 0644]
src/test/compile-fail/variance-regions-unused-indirect.rs [new file with mode: 0644]
src/test/compile-fail/variance-trait-bounds.rs [new file with mode: 0644]
src/test/compile-fail/variance-trait-object-bound.rs
src/test/compile-fail/variance-types-bounds.rs [new file with mode: 0644]
src/test/compile-fail/variance-types.rs [new file with mode: 0644]
src/test/compile-fail/variance-unused-region-param.rs [new file with mode: 0644]
src/test/compile-fail/variance-unused-type-param.rs [new file with mode: 0644]
src/test/compile-fail/variance-use-contravariant-struct-1.rs [new file with mode: 0644]
src/test/compile-fail/variance-use-contravariant-struct-2.rs [new file with mode: 0644]
src/test/compile-fail/variance-use-covariant-struct-1.rs [new file with mode: 0644]
src/test/compile-fail/variance-use-covariant-struct-2.rs [new file with mode: 0644]
src/test/compile-fail/variance-use-invariant-struct-1.rs [new file with mode: 0644]
src/test/compile-fail/virtual-structs.rs [deleted file]
src/test/compile-fail/visible-private-types-generics.rs
src/test/compile-fail/visible-private-types-supertrait.rs
src/test/compile-fail/where-clause-method-substituion.rs
src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs [deleted file]
src/test/compile-fail/where-clauses-not-parameter.rs
src/test/debuginfo/type-names.rs
src/test/parse-fail/ascii-only-character-escape.rs [new file with mode: 0644]
src/test/parse-fail/attr-before-eof.rs [new file with mode: 0644]
src/test/parse-fail/attr-before-ext.rs [new file with mode: 0644]
src/test/parse-fail/attr-before-let.rs [new file with mode: 0644]
src/test/parse-fail/attr-before-stmt.rs [new file with mode: 0644]
src/test/parse-fail/attr-dangling-in-fn.rs [new file with mode: 0644]
src/test/parse-fail/attr-dangling-in-mod.rs [new file with mode: 0644]
src/test/parse-fail/attr.rs [new file with mode: 0644]
src/test/parse-fail/attrs-after-extern-mod.rs [new file with mode: 0644]
src/test/parse-fail/bad-char-literals.rs [new file with mode: 0644]
src/test/parse-fail/bad-lit-suffixes.rs [new file with mode: 0644]
src/test/parse-fail/bad-value-ident-false.rs [new file with mode: 0644]
src/test/parse-fail/bad-value-ident-true.rs [new file with mode: 0644]
src/test/parse-fail/doc-before-attr.rs [new file with mode: 0644]
src/test/parse-fail/doc-before-eof.rs [new file with mode: 0644]
src/test/parse-fail/doc-before-extern-rbrace.rs [new file with mode: 0644]
src/test/parse-fail/doc-before-macro.rs [new file with mode: 0644]
src/test/parse-fail/doc-before-rbrace.rs [new file with mode: 0644]
src/test/parse-fail/doc-before-semi.rs [new file with mode: 0644]
src/test/parse-fail/extern-crate-as-no-string-help.rs [new file with mode: 0644]
src/test/parse-fail/generic-non-trailing-defaults.rs [new file with mode: 0644]
src/test/parse-fail/int-literal-too-large-span.rs [new file with mode: 0644]
src/test/parse-fail/issue-10412.rs [new file with mode: 0644]
src/test/parse-fail/issue-12560-1.rs [new file with mode: 0644]
src/test/parse-fail/issue-14182.rs [new file with mode: 0644]
src/test/parse-fail/issue-17383.rs [new file with mode: 0644]
src/test/parse-fail/issue-17718-const-mut.rs [new file with mode: 0644]
src/test/parse-fail/issue-1802-2.rs [new file with mode: 0644]
src/test/parse-fail/issue-5544-a.rs [new file with mode: 0644]
src/test/parse-fail/issue-5544-b.rs [new file with mode: 0644]
src/test/parse-fail/issue-8537.rs [new file with mode: 0644]
src/test/parse-fail/keyword-as-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-break-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-else-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-enum-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-extern-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-fn-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-for-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-if-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-impl-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-let-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-loop-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-match-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-mod-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-pub-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-return-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-self-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-static-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-struct-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-super-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-super.rs [new file with mode: 0644]
src/test/parse-fail/keyword-trait-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-type-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-unsafe-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-use-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-while-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword.rs [new file with mode: 0644]
src/test/parse-fail/keywords-followed-by-double-colon.rs [new file with mode: 0644]
src/test/parse-fail/lex-bad-numeric-literals.rs [new file with mode: 0644]
src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs [new file with mode: 0644]
src/test/parse-fail/lifetime-no-keyword.rs [new file with mode: 0644]
src/test/parse-fail/lifetime-obsoleted-self.rs [new file with mode: 0644]
src/test/parse-fail/macros-no-semicolon-items.rs [new file with mode: 0644]
src/test/parse-fail/mod_file_disambig.rs [deleted file]
src/test/parse-fail/mod_file_not_owning.rs [deleted file]
src/test/parse-fail/no-binary-float-literal.rs [new file with mode: 0644]
src/test/parse-fail/no-hex-float-literal.rs [new file with mode: 0644]
src/test/parse-fail/no-unsafe-self.rs [new file with mode: 0644]
src/test/parse-fail/non-str-meta.rs [new file with mode: 0644]
src/test/parse-fail/obsolete-for-sized.rs [new file with mode: 0644]
src/test/parse-fail/obsolete-proc.rs [new file with mode: 0644]
src/test/parse-fail/qquote-1.rs [new file with mode: 0644]
src/test/parse-fail/qquote-2.rs [new file with mode: 0644]
src/test/parse-fail/regions-fn-bound.rs [new file with mode: 0644]
src/test/parse-fail/require-parens-for-chained-comparison.rs [new file with mode: 0644]
src/test/parse-fail/struct-no-fields-2.rs [new file with mode: 0644]
src/test/parse-fail/struct-no-fields-3.rs [new file with mode: 0644]
src/test/parse-fail/struct-no-fields-4.rs [new file with mode: 0644]
src/test/parse-fail/struct-no-fields-5.rs [new file with mode: 0644]
src/test/parse-fail/struct-variant-no-fields.rs [new file with mode: 0644]
src/test/parse-fail/struct-variant-no-pub.rs [new file with mode: 0644]
src/test/parse-fail/syntax-trait-polarity.rs [new file with mode: 0644]
src/test/parse-fail/tag-variant-disr-non-nullary.rs [new file with mode: 0644]
src/test/parse-fail/trailing-carriage-return-in-string.rs [new file with mode: 0644]
src/test/parse-fail/trailing-plus-in-bounds.rs [new file with mode: 0644]
src/test/parse-fail/trait-bounds-not-on-impl.rs [new file with mode: 0644]
src/test/parse-fail/type-parameters-in-field-exprs.rs [new file with mode: 0644]
src/test/parse-fail/unsized2.rs [new file with mode: 0644]
src/test/parse-fail/virtual-structs.rs [new file with mode: 0644]
src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs [new file with mode: 0644]
src/test/pretty/empty-impl.rs
src/test/pretty/path-type-bounds.rs
src/test/run-fail/bug-811.rs
src/test/run-make/rustdoc-json/foo.rs
src/test/run-make/rustdoc-negative-impl/foo.rs
src/test/run-make/rustdoc-search-index/index.rs
src/test/run-make/rustdoc-smoke/foo.rs
src/test/run-make/rustdoc-viewpath-self/foo.rs
src/test/run-make/rustdoc-where/foo.rs
src/test/run-make/save-analysis/foo.rs
src/test/run-make/simd-ffi/simd.rs
src/test/run-make/symbols-are-reasonable/lib.rs
src/test/run-make/target-specs/foo.rs
src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
src/test/run-pass-valgrind/dst-dtor-1.rs
src/test/run-pass/associated-types-basic.rs
src/test/run-pass/associated-types-conditional-dispatch.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-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-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-ref-in-struct-literal.rs
src/test/run-pass/associated-types-resolve-lifetime.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/bitv-perf-test.rs
src/test/run-pass/borrowck-trait-lifetime.rs
src/test/run-pass/bug-7295.rs
src/test/run-pass/builtin-superkinds-in-metadata.rs
src/test/run-pass/builtin-superkinds-phantom-typaram.rs
src/test/run-pass/c-stack-returning-int64.rs
src/test/run-pass/class-typarams.rs
src/test/run-pass/const-polymorphic-paths.rs
src/test/run-pass/deriving-hash.rs
src/test/run-pass/deriving-meta-multiple.rs
src/test/run-pass/deriving-meta.rs
src/test/run-pass/dst-coercions.rs
src/test/run-pass/enum-null-pointer-opt.rs
src/test/run-pass/explicit-self-generic.rs
src/test/run-pass/export-non-interference.rs [deleted file]
src/test/run-pass/foreign-fn-linkname.rs
src/test/run-pass/generic-default-type-params-cross-crate.rs
src/test/run-pass/hrtb-opt-in-copy.rs
src/test/run-pass/inner-static.rs
src/test/run-pass/issue-10456.rs
src/test/run-pass/issue-10802.rs
src/test/run-pass/issue-10902.rs
src/test/run-pass/issue-11205.rs
src/test/run-pass/issue-11384.rs
src/test/run-pass/issue-11612.rs
src/test/run-pass/issue-11677.rs
src/test/run-pass/issue-11736.rs
src/test/run-pass/issue-13105.rs
src/test/run-pass/issue-14399.rs
src/test/run-pass/issue-14589.rs
src/test/run-pass/issue-14958.rs
src/test/run-pass/issue-14959.rs
src/test/run-pass/issue-15858.rs
src/test/run-pass/issue-16596.rs
src/test/run-pass/issue-16643.rs
src/test/run-pass/issue-17662.rs
src/test/run-pass/issue-17732.rs
src/test/run-pass/issue-17771.rs
src/test/run-pass/issue-17816.rs
src/test/run-pass/issue-17904.rs
src/test/run-pass/issue-18232.rs
src/test/run-pass/issue-18906.rs
src/test/run-pass/issue-19121.rs
src/test/run-pass/issue-19129-2.rs
src/test/run-pass/issue-19135.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-19631.rs
src/test/run-pass/issue-19632.rs
src/test/run-pass/issue-20055-box-trait.rs
src/test/run-pass/issue-20343.rs
src/test/run-pass/issue-20763-1.rs
src/test/run-pass/issue-20763-2.rs
src/test/run-pass/issue-21363.rs
src/test/run-pass/issue-21909.rs
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-2383.rs
src/test/run-pass/issue-2611-3.rs
src/test/run-pass/issue-2734.rs
src/test/run-pass/issue-2735.rs
src/test/run-pass/issue-4107.rs
src/test/run-pass/issue-5192.rs
src/test/run-pass/issue-5708.rs
src/test/run-pass/issue-6128.rs
src/test/run-pass/issue-6318.rs
src/test/run-pass/issue-7575.rs
src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs
src/test/run-pass/issue-7911.rs
src/test/run-pass/issue-8248.rs
src/test/run-pass/issue-8249.rs
src/test/run-pass/issue-9719.rs
src/test/run-pass/lint-cstack.rs
src/test/run-pass/method-early-bound-lifetimes-on-self.rs
src/test/run-pass/method-recursive-blanket-impl.rs
src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs
src/test/run-pass/overloaded-autoderef-vtable.rs
src/test/run-pass/overloaded-calls-param-vtables.rs
src/test/run-pass/parameterized-trait-with-bounds.rs
src/test/run-pass/privacy-ns.rs
src/test/run-pass/regions-assoc-type-static-bound.rs
src/test/run-pass/regions-bound-lists-feature-gate-2.rs
src/test/run-pass/regions-bound-lists-feature-gate.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-infer-bivariance.rs [deleted file]
src/test/run-pass/regions-issue-21422.rs [new file with mode: 0644]
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-refcell.rs
src/test/run-pass/rename-directory.rs
src/test/run-pass/self-impl.rs
src/test/run-pass/send_str_hashmap.rs
src/test/run-pass/send_str_treemap.rs
src/test/run-pass/simple-match-generic-tag.rs
src/test/run-pass/syntax-trait-polarity.rs
src/test/run-pass/trailing-comma.rs
src/test/run-pass/trait-bounds-basic.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-default-method-bound-subst4.rs
src/test/run-pass/trait-impl.rs
src/test/run-pass/trait-inheritance-num2.rs
src/test/run-pass/trait-inheritance-static2.rs
src/test/run-pass/trait-object-generics.rs
src/test/run-pass/trait-static-method-overwriting.rs
src/test/run-pass/traits-issue-22019.rs
src/test/run-pass/unboxed-closures-infer-recursive-fn.rs
src/test/run-pass/unique-object-move.rs
src/test/run-pass/unsized.rs
src/test/run-pass/unsized2.rs
src/test/run-pass/variadic-ffi.rs
src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs [new file with mode: 0644]
src/test/run-pass/variance-trait-matching.rs [new file with mode: 0644]
src/test/run-pass/variance-vec-covariant.rs [new file with mode: 0644]
src/test/run-pass/visible-private-types-feature-gate.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-for-self.rs

index 065c4ed7c7bcba936febf4094080f62ae189118c..b6a73730d351cc9f37c39a0fdc8d49bb59e75aca 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,14 +1,16 @@
 # The Rust Programming Language
 
 This is a compiler for Rust, including standard libraries, tools and
-documentation.
+documentation. Rust is a systems programming language that is fast,
+memory safe and multithreaded, but does not employ a garbage collector
+or otherwise impose significant runtime overhead.
 
 ## Quick Start
 
-Read ["Installing Rust"][install] from [The Book][trpl].
+Read ["Installing Rust"] from [The Book].
 
-[install]: http://doc.rust-lang.org/book/installing-rust.html
-[trpl]: http://doc.rust-lang.org/book/index.html
+["Installing Rust"]: http://doc.rust-lang.org/book/installing-rust.html
+[The Book]: http://doc.rust-lang.org/book/index.html
 
 ## Building from Source
 
@@ -19,22 +21,14 @@ Read ["Installing Rust"][install] from [The Book][trpl].
     * `curl`
     * `git`
 
-2. Download and build Rust:
-
-    You can either download a [tarball] or build directly from the [repo].
-
-    To build from the [tarball] do:
-
-        $ curl -O https://static.rust-lang.org/dist/rustc-nightly-src.tar.gz
-        $ tar -xzf rustc-nightly-src.tar.gz
-        $ cd rustc-nightly
-
-    Or to build from the [repo] do:
+2. Clone the [source] with `git`:
 
         $ git clone https://github.com/rust-lang/rust.git
         $ cd rust
 
-    Now that you have Rust's source code, you can configure and build it:
+[source]: https://github.com/rust-lang/rust
+
+3. Build and install:
 
         $ ./configure
         $ make && make install
@@ -46,7 +40,10 @@ Read ["Installing Rust"][install] from [The Book][trpl].
 
     When complete, `make install` will place several programs into
     `/usr/local/bin`: `rustc`, the Rust compiler, and `rustdoc`, the
-    API-documentation tool.
+    API-documentation tool. This install does not include [Cargo],
+    Rust's package manager, which you may also want to build.
+
+[Cargo]: https://github.com/rust-lang/cargo
 
 ### Building on Windows
 
@@ -72,9 +69,6 @@ $ pacman -S base-devel
         $ ./configure
         $ make && make install
 
-[repo]: https://github.com/rust-lang/rust
-[tarball]: https://static.rust-lang.org/dist/rustc-nightly-src.tar.gz
-
 ## Notes
 
 Since the Rust compiler is written in Rust, it must be built by a
@@ -94,9 +88,9 @@ supported build environments that are most likely to work.
 Rust currently needs about 1.5 GiB of RAM to build without swapping; if it hits
 swap, it will take a very long time to build.
 
-There is a lot more documentation in the [wiki].
+There is more advice about hacking on Rust in [CONTRIBUTING.md].
 
-[wiki]: https://github.com/rust-lang/rust/wiki
+[CONTRIBUTING.md]: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md
 
 ## Getting help
 
@@ -114,6 +108,14 @@ The Rust community congregates in a few places:
 
 To contribute to Rust, please see [CONTRIBUTING.md](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,
+
+[IRC]: https://en.wikipedia.org/wiki/Internet_Relay_Chat
+[#rust]: irc://irc.mozilla.org/rust
+
 ## License
 
 Rust is primarily distributed under the terms of both the MIT license
index ec1e741fb9c5b10ad9aa854eae345f1039419735..d1b27a96f93b9caf7da8a4fbb9ac0b9e06a24a63 100755 (executable)
--- a/configure
+++ b/configure
@@ -1056,6 +1056,7 @@ do
     make_dir $h/test/run-pass-fulldeps
     make_dir $h/test/run-fail
     make_dir $h/test/compile-fail
+    make_dir $h/test/parse-fail
     make_dir $h/test/compile-fail-fulldeps
     make_dir $h/test/bench
     make_dir $h/test/perf
index d85977243707445737d2b87b2c30747faf8a0d5d..692d28bfad3d56c5e5cba49ea9489b7268bb45b1 100644 (file)
@@ -174,12 +174,12 @@ check-notidy: cleantmptestlogs cleantestlibs all check-stage2
 check-lite: cleantestlibs cleantmptestlogs \
        $(foreach crate,$(TEST_TARGET_CRATES),check-stage2-$(crate)) \
        check-stage2-rpass check-stage2-rpass-valgrind \
-       check-stage2-rfail check-stage2-cfail check-stage2-rmake
+       check-stage2-rfail check-stage2-cfail check-stage2-pfail check-stage2-rmake
        $(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log
 
 # Only check the 'reference' tests: rpass/cfail/rfail/rmake.
 check-ref: cleantestlibs cleantmptestlogs check-stage2-rpass check-stage2-rpass-valgrind \
-       check-stage2-rfail check-stage2-cfail check-stage2-rmake
+       check-stage2-rfail check-stage2-cfail check-stage2-pfail check-stage2-rmake
        $(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log
 
 # Only check the docs.
@@ -291,6 +291,7 @@ check-stage$(1)-T-$(2)-H-$(3)-exec: \
        check-stage$(1)-T-$(2)-H-$(3)-rpass-exec \
        check-stage$(1)-T-$(2)-H-$(3)-rfail-exec \
        check-stage$(1)-T-$(2)-H-$(3)-cfail-exec \
+       check-stage$(1)-T-$(2)-H-$(3)-pfail-exec \
     check-stage$(1)-T-$(2)-H-$(3)-rpass-valgrind-exec \
     check-stage$(1)-T-$(2)-H-$(3)-rpass-full-exec \
        check-stage$(1)-T-$(2)-H-$(3)-cfail-full-exec \
@@ -470,7 +471,8 @@ RPASS_VALGRIND_TESTS := $(RPASS_VALGRIND_RS)
 RPASS_FULL_TESTS := $(RPASS_FULL_RS)
 CFAIL_FULL_TESTS := $(CFAIL_FULL_RS)
 RFAIL_TESTS := $(RFAIL_RS)
-CFAIL_TESTS := $(CFAIL_RS) $(PFAIL_RS)
+CFAIL_TESTS := $(CFAIL_RS)
+PFAIL_TESTS := $(PFAIL_RS)
 BENCH_TESTS := $(BENCH_RS)
 PERF_TESTS := $(PERF_RS)
 PRETTY_TESTS := $(PRETTY_RS)
@@ -508,6 +510,11 @@ CTEST_BUILD_BASE_cfail = compile-fail
 CTEST_MODE_cfail = compile-fail
 CTEST_RUNTOOL_cfail = $(CTEST_RUNTOOL)
 
+CTEST_SRC_BASE_pfail = parse-fail
+CTEST_BUILD_BASE_pfail = parse-fail
+CTEST_MODE_pfail = parse-fail
+CTEST_RUNTOOL_pfail = $(CTEST_RUNTOOL)
+
 CTEST_SRC_BASE_bench = bench
 CTEST_BUILD_BASE_bench = bench
 CTEST_MODE_bench = run-pass
@@ -630,6 +637,7 @@ CTEST_DEPS_rpass-full_$(1)-T-$(2)-H-$(3) = $$(RPASS_FULL_TESTS) $$(CSREQ$(1)_T_$
 CTEST_DEPS_cfail-full_$(1)-T-$(2)-H-$(3) = $$(CFAIL_FULL_TESTS) $$(CSREQ$(1)_T_$(3)_H_$(3)) $$(SREQ$(1)_T_$(2)_H_$(3))
 CTEST_DEPS_rfail_$(1)-T-$(2)-H-$(3) = $$(RFAIL_TESTS)
 CTEST_DEPS_cfail_$(1)-T-$(2)-H-$(3) = $$(CFAIL_TESTS)
+CTEST_DEPS_pfail_$(1)-T-$(2)-H-$(3) = $$(PFAIL_TESTS)
 CTEST_DEPS_bench_$(1)-T-$(2)-H-$(3) = $$(BENCH_TESTS)
 CTEST_DEPS_perf_$(1)-T-$(2)-H-$(3) = $$(PERF_TESTS)
 CTEST_DEPS_debuginfo-gdb_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_GDB_TESTS)
@@ -698,7 +706,7 @@ endif
 
 endef
 
-CTEST_NAMES = rpass rpass-valgrind rpass-full cfail-full rfail cfail bench perf debuginfo-gdb debuginfo-lldb codegen
+CTEST_NAMES = rpass rpass-valgrind rpass-full cfail-full rfail cfail pfail bench perf debuginfo-gdb debuginfo-lldb codegen
 
 $(foreach host,$(CFG_HOST), \
  $(eval $(foreach target,$(CFG_TARGET), \
@@ -857,6 +865,7 @@ TEST_GROUPS = \
        cfail-full \
        rfail \
        cfail \
+       pfail \
        bench \
        perf \
        rmake \
index df2981a6c8334a385180a405c4f8155797e020ee..2c046d252799ee02338b399fb4e38a1b1cae75e4 100644 (file)
@@ -15,6 +15,7 @@
 #[derive(Clone, Copy, PartialEq, Debug)]
 pub enum Mode {
     CompileFail,
+    ParseFail,
     RunFail,
     RunPass,
     RunPassValgrind,
@@ -29,6 +30,7 @@ impl FromStr for Mode {
     fn from_str(s: &str) -> Result<Mode, ()> {
         match s {
           "compile-fail" => Ok(CompileFail),
+          "parse-fail" => Ok(ParseFail),
           "run-fail" => Ok(RunFail),
           "run-pass" => Ok(RunPass),
           "run-pass-valgrind" => Ok(RunPassValgrind),
@@ -45,6 +47,7 @@ impl fmt::Display for Mode {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::Display::fmt(match *self {
             CompileFail => "compile-fail",
+            ParseFail => "parse-fail",
             RunFail => "run-fail",
             RunPass => "run-pass",
             RunPassValgrind => "run-pass-valgrind",
index 86710d50d8a065b0b9e6b9bc212ab862e7c13399..278ce5565d9fc38d8ce9bec899e5fcf3109d0ab1 100644 (file)
@@ -21,6 +21,7 @@
 #![feature(test)]
 #![feature(unicode)]
 #![feature(env)]
+#![feature(core)]
 
 #![deny(warnings)]
 
@@ -72,7 +73,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
           reqopt("", "aux-base", "directory to find auxiliary test files", "PATH"),
           reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET"),
           reqopt("", "mode", "which sort of compile tests to run",
-                 "(compile-fail|run-fail|run-pass|run-pass-valgrind|pretty|debug-info)"),
+                 "(compile-fail|parse-fail|run-fail|run-pass|run-pass-valgrind|pretty|debug-info)"),
           optflag("", "ignored", "run tests marked as ignored"),
           optopt("", "runtool", "supervisor program to run tests under \
                                  (eg. emulator, valgrind)", "PROGRAM"),
index 658c0cb3f4e83955019aa990658884961afcfdb8..1cbb8742bbc5ae511b89c812ecd115d869501c5b 100644 (file)
@@ -11,7 +11,7 @@
 use self::TargetLocation::*;
 
 use common::Config;
-use common::{CompileFail, Pretty, RunFail, RunPass, RunPassValgrind, DebugInfoGdb};
+use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind, DebugInfoGdb};
 use common::{Codegen, DebugInfoLldb};
 use errors;
 use header::TestProps;
@@ -66,6 +66,7 @@ pub fn run_metrics(config: Config, testfile: String, mm: &mut MetricMap) {
     debug!("loaded props");
     match config.mode {
       CompileFail => run_cfail_test(&config, &props, &testfile),
+      ParseFail => run_cfail_test(&config, &props, &testfile),
       RunFail => run_rfail_test(&config, &props, &testfile),
       RunPass => run_rpass_test(&config, &props, &testfile),
       RunPassValgrind => run_valgrind_test(&config, &props, &testfile),
@@ -88,7 +89,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("compile-fail test compiled successfully!",
+        fatal_proc_rec(&format!("{} test compiled successfully!", config.mode)[],
                       &proc_res);
     }
 
@@ -688,7 +689,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
                                                .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");
@@ -1133,7 +1134,7 @@ fn compile_test_(config: &Config, props: &TestProps,
     // FIXME (#9639): This needs to handle non-utf8 paths
     let mut link_args = vec!("-L".to_string(),
                              aux_dir.as_str().unwrap().to_string());
-    link_args.extend(extra_args.iter().map(|s| s.clone()));
+    link_args.extend(extra_args.iter().cloned());
     let args = make_compile_args(config,
                                  props,
                                  link_args,
index 70baebf0d30acf33416294085fc6568f91a66122..db940947040d48f41c4811bb46c4aca7e8ae1244 100644 (file)
@@ -572,7 +572,7 @@ the final namespace qualifier is omitted.
 Two examples of paths with type arguments:
 
 ```
-# struct HashMap<K, V>;
+# struct HashMap<K, V>(K,V);
 # fn f() {
 # fn id<T>(t: T) -> T { t }
 type T = HashMap<i32,String>; // Type arguments used in a type expression
@@ -1599,7 +1599,7 @@ pointer values (pointing to a type for which an implementation of the given
 trait is in scope) to pointers to the trait name, used as a type.
 
 ```
-# trait Shape { }
+# trait Shape { fn dummy(&self) { } }
 # impl Shape for i32 { }
 # let mycircle = 0i32;
 let myshape: Box<Shape> = Box::new(mycircle) as Box<Shape>;
@@ -1630,8 +1630,8 @@ let x: f64 = Num::from_i32(42);
 Traits may inherit from other traits. For example, in
 
 ```
-trait Shape { fn area() -> f64; }
-trait Circle : Shape { fn radius() -> f64; }
+trait Shape { fn area(&self) -> f64; }
+trait Circle : Shape { fn radius(&self) -> f64; }
 ```
 
 the syntax `Circle : Shape` means that types that implement `Circle` must also
@@ -1725,7 +1725,7 @@ type parameters taken by the trait it implements. Implementation parameters
 are written after the `impl` keyword.
 
 ```
-# trait Seq<T> { }
+# trait Seq<T> { fn dummy(&self, _: T) { } }
 impl<T> Seq<T> for Vec<T> {
    /* ... */
 }
@@ -3583,7 +3583,7 @@ An example of each kind:
 ```{rust}
 let vec: Vec<i32> = vec![1, 2, 3];
 let arr: [i32; 3] = [1, 2, 3];
-let s: &[i32] = &vec[];
+let s: &[i32] = &vec[..];
 ```
 
 As you can see, the `vec!` macro allows you to create a `Vec<T>` easily. The
index f2b95f19edce21336c808454969cc3ff27f50ac5..97e826579fd9bbc473c13c6d2d0bd4c7db0e0ead 100644 (file)
@@ -435,8 +435,8 @@ extern {
 }
 
 fn main() {
-    let prompt = CString::from_slice(b"[my-awesome-shell] $");
-    unsafe { 
+    let prompt = CString::new("[my-awesome-shell] $").unwrap();
+    unsafe {
         rl_prompt = prompt.as_ptr();
 
         println!("{:?}", rl_prompt);
@@ -541,6 +541,6 @@ pub extern fn hello_rust() -> *const u8 {
 
 The `extern` makes this function adhere to the C calling convention, as
 discussed above in "[Foreign Calling
-Conventions](guide-ffi.html#foreign-calling-conventions)". The `no_mangle`
+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 122cffe36975f397a4974e9e3537e3e8d19a9189..9e82e48fd18b7f1fe829d33e7e1eb1b799226f3c 100644 (file)
@@ -180,7 +180,7 @@ If you want to match against a slice or array, you can use `&`:
 fn main() {
     let v = vec!["match_this", "1"];
 
-    match &v[] {
+    match &v[..] {
         ["match_this", second] => println!("The second element is {}", second),
         _ => {},
     }
index 3830d7fe29532c228a9521286bfa250ae040b06b..934e6ab2159166bd9823779a88670684997731ae 100644 (file)
@@ -73,7 +73,6 @@
 
 use core::atomic;
 use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst};
-use core::borrow::BorrowFrom;
 use core::fmt;
 use core::cmp::{Ordering};
 use core::default::Default;
@@ -244,12 +243,6 @@ fn clone(&self) -> Arc<T> {
     }
 }
 
-impl<T> BorrowFrom<Arc<T>> for T {
-    fn borrow_from(owned: &Arc<T>) -> &T {
-        &**owned
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Deref for Arc<T> {
     type Target = T;
@@ -605,11 +598,19 @@ 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) {
+        (**self).hash(state)
+    }
+}
 
 #[cfg(test)]
 mod tests {
index 340a8d59612f21af31e685b6f5e40fb824b234cf..a3516bd667b7a18cb6e9f0653481511bc5f04779 100644 (file)
 
 //! A pointer type for heap allocation.
 //!
-//! `Box<T>`, casually referred to as a 'box', provides the simplest form of heap allocation in
-//! Rust. Boxes provide ownership for this allocation, and drop their contents when they go out of
-//! scope.
+//! `Box<T>`, casually referred to as a 'box', provides the simplest form of
+//! heap allocation in Rust. Boxes provide ownership for this allocation, and
+//! drop their contents when they go out of scope.
 //!
-//! Boxes are useful in two situations: recursive data structures, and occasionally when returning
-//! data. [The Pointer chapter of the Book](../../../book/pointers.html#best-practices-1) explains
-//! these cases in detail.
+//! Boxes are useful in two situations: recursive data structures, and
+//! occasionally when returning data. [The Pointer chapter of the
+//! Book](../../../book/pointers.html#best-practices-1) explains these cases in
+//! detail.
 //!
 //! # Examples
 //!
@@ -58,8 +59,8 @@
 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.
+/// 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:
 ///
@@ -219,12 +220,20 @@ fn cmp(&self, other: &Box<T>) -> Ordering {
 #[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) {
+        (**self).hash(state);
+    }
+}
 
 /// Extension methods for an owning `Any` trait object.
 #[unstable(feature = "alloc",
index b3c2638f3ae282a190c5318fe147c1873f7ea844..bc349ebebdeed0a317a30943c9aefa6142a096ff 100644 (file)
@@ -73,7 +73,6 @@
 #![feature(unboxed_closures)]
 #![feature(unsafe_no_drop_flag)]
 #![feature(core)]
-#![feature(hash)]
 #![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")),
             feature(libc))]
 
index f361c36ec8fa73bafb333c6a1a5284d851164ea9..9d39511543188736cd20c9935d80a9f0d3469e78 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use core::borrow::BorrowFrom;
 use core::cell::Cell;
 use core::clone::Clone;
 use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
 use core::default::Default;
 use core::fmt;
-use core::hash::{self, Hash};
+use core::hash::{Hasher, Hash};
 use core::marker;
 use core::mem::{transmute, min_align_of, size_of, forget};
 use core::nonzero::NonZero;
@@ -349,12 +348,6 @@ pub fn make_unique(&mut self) -> &mut T {
     }
 }
 
-impl<T> BorrowFrom<Rc<T>> for T {
-    fn borrow_from(owned: &Rc<T>) -> &T {
-        &**owned
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Deref for Rc<T> {
     type Target = T;
@@ -599,12 +592,20 @@ fn cmp(&self, other: &Rc<T>) -> Ordering { (**self).cmp(&**other) }
 }
 
 // FIXME (#18248) Make `T` `Sized?`
-impl<S: hash::Hasher, T: Hash<S>> Hash<S> for Rc<T> {
+#[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) {
+        (**self).hash(state);
+    }
+}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: fmt::Display> fmt::Display for Rc<T> {
index 4cd3d587580f05ed183efc54d8e268dbdb4ea051..b43f9adfb26d92ed9c8f8f4ee8df7bc634c0cb46 100644 (file)
@@ -96,7 +96,7 @@ pub struct Arena<'longer_than_self> {
     head: RefCell<Chunk>,
     copy_head: RefCell<Chunk>,
     chunks: RefCell<Vec<Chunk>>,
-    _invariant: marker::InvariantLifetime<'longer_than_self>,
+    _marker: marker::PhantomData<*mut &'longer_than_self()>,
 }
 
 impl<'a> Arena<'a> {
@@ -111,7 +111,7 @@ pub fn new_with_size(initial_size: usize) -> Arena<'a> {
             head: RefCell::new(chunk(initial_size, false)),
             copy_head: RefCell::new(chunk(initial_size, true)),
             chunks: RefCell::new(Vec::new()),
-            _invariant: marker::InvariantLifetime,
+            _marker: marker::PhantomData,
         }
     }
 }
@@ -361,6 +361,8 @@ pub struct TypedArena<T> {
 }
 
 struct TypedArenaChunk<T> {
+    marker: marker::PhantomData<T>,
+
     /// Pointer to the next arena segment.
     next: *mut TypedArenaChunk<T>,
 
index 6196d94b5a6bd9be2d9892530686dc557b779069..9f549fd7237711dce941f7ef0d37e0eec9e8db73 100644 (file)
@@ -650,8 +650,8 @@ impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Ord> FromIterator<T> for BinaryHeap<T> {
-    fn from_iter<Iter: Iterator<Item=T>>(iter: Iter) -> BinaryHeap<T> {
-        BinaryHeap::from_vec(iter.collect())
+    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> BinaryHeap<T> {
+        BinaryHeap::from_vec(iter.into_iter().collect())
     }
 }
 
@@ -677,7 +677,8 @@ fn into_iter(self) -> Iter<'a, T> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Ord> Extend<T> for BinaryHeap<T> {
-    fn extend<Iter: Iterator<Item=T>>(&mut self, iter: Iter) {
+    fn extend<I: IntoIterator<Item=T>>(&mut self, iterable: I) {
+        let iter = iterable.into_iter();
         let (lower, _) = iter.size_hint();
 
         self.reserve(lower);
index 0b762788b208aca548cd565912652c2457a8c2bf..11c576eab152551c274b9036b4ac99a5ee30ae39 100644 (file)
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// FIXME(Gankro): Bitv and BitvSet are very tightly coupled. Ideally (for
-// maintenance), they should be in separate files/modules, with BitvSet only
-// using Bitv's public API. This will be hard for performance though, because
-// `Bitv` will not want to leak its internal representation while its internal
+// FIXME(Gankro): BitVec and BitSet are very tightly coupled. Ideally (for
+// maintenance), they should be in separate files/modules, with BitSet only
+// using BitVec's public API. This will be hard for performance though, because
+// `BitVec` will not want to leak its internal representation while its internal
 // representation as `u32`s must be assumed for best performance.
 
-// FIXME(tbu-): `Bitv`'s methods shouldn't be `union`, `intersection`, but
+// FIXME(tbu-): `BitVec`'s methods shouldn't be `union`, `intersection`, but
 // rather `or` and `and`.
 
 // (1) Be careful, most things can overflow here because the amount of bits in
@@ -25,8 +25,8 @@
 //     methods rely on it (for *CORRECTNESS*).
 // (3) Make sure that the unused bits in the last word are zeroed out, again
 //     other methods rely on it for *CORRECTNESS*.
-// (4) `BitvSet` is tightly coupled with `Bitv`, so any changes you make in
-// `Bitv` will need to be reflected in `BitvSet`.
+// (4) `BitSet` is tightly coupled with `BitVec`, so any changes you make in
+// `BitVec` will need to be reflected in `BitSet`.
 
 //! Collections implemented with bit vectors.
 //!
 //! [sieve]: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
 //!
 //! ```
-//! use std::collections::{BitvSet, Bitv};
+//! use std::collections::{BitSet, BitVec};
 //! use std::num::Float;
 //! use std::iter;
 //!
 //! let max_prime = 10000;
 //!
-//! // Store the primes as a BitvSet
+//! // Store the primes as a BitSet
 //! let primes = {
 //!     // Assume all numbers are prime to begin, and then we
 //!     // cross off non-primes progressively
-//!     let mut bv = Bitv::from_elem(max_prime, true);
+//!     let mut bv = BitVec::from_elem(max_prime, true);
 //!
 //!     // Neither 0 nor 1 are prime
 //!     bv.set(0, false);
@@ -62,7 +62,7 @@
 //!             for j in iter::range_step(i * i, max_prime, i) { bv.set(j, false) }
 //!         }
 //!     }
-//!     BitvSet::from_bitv(bv)
+//!     BitSet::from_bit_vec(bv)
 //! };
 //!
 //! // Simple primality tests below our max bound
@@ -75,7 +75,7 @@
 //! }
 //! println!("");
 //!
-//! // We can manipulate the internal Bitv
+//! // We can manipulate the internal BitVec
 //! let num_primes = primes.get_ref().iter().filter(|x| *x).count();
 //! println!("There are {} primes below {}", num_primes, max_prime);
 //! ```
@@ -94,7 +94,7 @@
 use core::ops::Index;
 use core::slice;
 use core::{u8, u32, usize};
-use bitv_set; //so meta
+use bit_set; //so meta
 
 use Vec;
 
@@ -112,7 +112,7 @@ fn reverse_bits(byte: u8) -> u8 {
 
 // Take two BitV's, and return iterators of their words, where the shorter one
 // has been padded with 0's
-fn match_words <'a,'b>(a: &'a Bitv, b: &'b Bitv) -> (MatchWords<'a>, MatchWords<'b>) {
+fn match_words <'a,'b>(a: &'a BitVec, b: &'b BitVec) -> (MatchWords<'a>, MatchWords<'b>) {
     let a_len = a.storage.len();
     let b_len = b.storage.len();
 
@@ -134,9 +134,9 @@ fn match_words <'a,'b>(a: &'a Bitv, b: &'b Bitv) -> (MatchWords<'a>, MatchWords<
 /// # Examples
 ///
 /// ```rust
-/// use std::collections::Bitv;
+/// use std::collections::BitVec;
 ///
-/// let mut bv = Bitv::from_elem(10, false);
+/// let mut bv = BitVec::from_elem(10, false);
 ///
 /// // insert all primes less than 10
 /// bv.set(2, true);
@@ -158,7 +158,7 @@ fn match_words <'a,'b>(a: &'a Bitv, b: &'b Bitv) -> (MatchWords<'a>, MatchWords<
 /// ```
 #[unstable(feature = "collections",
            reason = "RFC 509")]
-pub struct Bitv {
+pub struct BitVec {
     /// Internal representation of the bit vector
     storage: Vec<u32>,
     /// The number of valid bits in the internal representation
@@ -166,7 +166,7 @@ pub struct Bitv {
 }
 
 // FIXME(Gankro): NopeNopeNopeNopeNope (wait for IndexGet to be a thing)
-impl Index<usize> for Bitv {
+impl Index<usize> for BitVec {
     type Output = bool;
 
     #[inline]
@@ -202,12 +202,12 @@ fn mask_for_bits(bits: usize) -> u32 {
     !0u32 >> (u32::BITS - bits % u32::BITS) % u32::BITS
 }
 
-impl Bitv {
+impl BitVec {
     /// Applies the given operation to the blocks of self and other, and sets
     /// self to be the result. This relies on the caller not to corrupt the
     /// last word.
     #[inline]
-    fn process<F>(&mut self, other: &Bitv, mut op: F) -> bool where F: FnMut(u32, u32) -> u32 {
+    fn process<F>(&mut self, other: &BitVec, mut op: F) -> bool where F: FnMut(u32, u32) -> u32 {
         assert_eq!(self.len(), other.len());
         // This could theoretically be a `debug_assert!`.
         assert_eq!(self.storage.len(), other.storage.len());
@@ -235,7 +235,7 @@ fn blocks(&self) -> Blocks {
     }
 
     /// An operation might screw up the unused bits in the last block of the
-    /// `Bitv`. As per (3), it's assumed to be all 0s. This method fixes it up.
+    /// `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;
         if extra_bits > 0 {
@@ -245,44 +245,44 @@ fn fix_last_block(&mut self) {
         }
     }
 
-    /// Creates an empty `Bitv`.
+    /// Creates an empty `BitVec`.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
-    /// let mut bv = Bitv::new();
+    /// use std::collections::BitVec;
+    /// let mut bv = BitVec::new();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new() -> Bitv {
-        Bitv { storage: Vec::new(), nbits: 0 }
+    pub fn new() -> BitVec {
+        BitVec { storage: Vec::new(), nbits: 0 }
     }
 
-    /// Creates a `Bitv` that holds `nbits` elements, setting each element
+    /// Creates a `BitVec` that holds `nbits` elements, setting each element
     /// to `bit`.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(10, false);
+    /// let mut bv = BitVec::from_elem(10, false);
     /// assert_eq!(bv.len(), 10);
     /// for x in bv.iter() {
     ///     assert_eq!(x, false);
     /// }
     /// ```
-    pub fn from_elem(nbits: usize, bit: bool) -> Bitv {
+    pub fn from_elem(nbits: usize, bit: bool) -> BitVec {
         let nblocks = blocks_for_bits(nbits);
-        let mut bitv = Bitv {
+        let mut bit_vec = BitVec {
             storage: repeat(if bit { !0u32 } else { 0u32 }).take(nblocks).collect(),
             nbits: nbits
         };
-        bitv.fix_last_block();
-        bitv
+        bit_vec.fix_last_block();
+        bit_vec
     }
 
-    /// Constructs a new, empty `Bitv` with the specified capacity.
+    /// Constructs a new, empty `BitVec` with the specified capacity.
     ///
     /// The bitvector will be able to hold at least `capacity` bits without
     /// reallocating. If `capacity` is 0, it will not allocate.
@@ -290,38 +290,38 @@ pub fn from_elem(nbits: usize, bit: bool) -> Bitv {
     /// It is important to note that this function does not specify the
     /// *length* of the returned bitvector, but only the *capacity*.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn with_capacity(nbits: usize) -> Bitv {
-        Bitv {
+    pub fn with_capacity(nbits: usize) -> BitVec {
+        BitVec {
             storage: Vec::with_capacity(blocks_for_bits(nbits)),
             nbits: 0,
         }
     }
 
-    /// Transforms a byte-vector into a `Bitv`. Each byte becomes eight bits,
+    /// Transforms a byte-vector into a `BitVec`. Each byte becomes eight bits,
     /// with the most significant bits of each byte coming first. Each
     /// bit becomes `true` if equal to 1 or `false` if equal to 0.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let bv = Bitv::from_bytes(&[0b10100000, 0b00010010]);
+    /// let bv = BitVec::from_bytes(&[0b10100000, 0b00010010]);
     /// assert!(bv.eq_vec(&[true, false, true, false,
     ///                     false, false, false, false,
     ///                     false, false, false, true,
     ///                     false, false, true, false]));
     /// ```
-    pub fn from_bytes(bytes: &[u8]) -> Bitv {
+    pub fn from_bytes(bytes: &[u8]) -> BitVec {
         let len = bytes.len().checked_mul(u8::BITS).expect("capacity overflow");
-        let mut bitv = Bitv::with_capacity(len);
+        let mut bit_vec = BitVec::with_capacity(len);
         let complete_words = bytes.len() / 4;
         let extra_bytes = bytes.len() % 4;
 
-        bitv.nbits = len;
+        bit_vec.nbits = len;
 
         for i in 0..complete_words {
-            bitv.storage.push(
+            bit_vec.storage.push(
                 ((reverse_bits(bytes[i * 4 + 0]) as u32) << 0) |
                 ((reverse_bits(bytes[i * 4 + 1]) as u32) << 8) |
                 ((reverse_bits(bytes[i * 4 + 2]) as u32) << 16) |
@@ -334,29 +334,29 @@ pub fn from_bytes(bytes: &[u8]) -> Bitv {
             for (i, &byte) in bytes[complete_words*4..].iter().enumerate() {
                 last_word |= (reverse_bits(byte) as u32) << (i * 8);
             }
-            bitv.storage.push(last_word);
+            bit_vec.storage.push(last_word);
         }
 
-        bitv
+        bit_vec
     }
 
-    /// Creates a `Bitv` of the specified length where the value at each index
+    /// Creates a `BitVec` of the specified length where the value at each index
     /// is `f(index)`.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let bv = Bitv::from_fn(5, |i| { i % 2 == 0 });
+    /// let bv = BitVec::from_fn(5, |i| { i % 2 == 0 });
     /// assert!(bv.eq_vec(&[true, false, true, false, true]));
     /// ```
-    pub fn from_fn<F>(len: usize, mut f: F) -> Bitv where F: FnMut(usize) -> bool {
-        let mut bitv = Bitv::from_elem(len, false);
+    pub fn from_fn<F>(len: usize, mut f: F) -> BitVec where F: FnMut(usize) -> bool {
+        let mut bit_vec = BitVec::from_elem(len, false);
         for i in 0..len {
-            bitv.set(i, f(i));
+            bit_vec.set(i, f(i));
         }
-        bitv
+        bit_vec
     }
 
     /// Retrieves the value at index `i`, or `None` if the index is out of bounds.
@@ -364,9 +364,9 @@ pub fn from_fn<F>(len: usize, mut f: F) -> Bitv where F: FnMut(usize) -> bool {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let bv = Bitv::from_bytes(&[0b01100000]);
+    /// let bv = BitVec::from_bytes(&[0b01100000]);
     /// assert_eq!(bv.get(0), Some(false));
     /// assert_eq!(bv.get(1), Some(true));
     /// assert_eq!(bv.get(100), None);
@@ -396,9 +396,9 @@ pub fn get(&self, i: usize) -> Option<bool> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(5, false);
+    /// let mut bv = BitVec::from_elem(5, false);
     /// bv.set(3, true);
     /// assert_eq!(bv[3], true);
     /// ```
@@ -420,14 +420,14 @@ pub fn set(&mut self, i: usize, x: bool) {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
     /// let before = 0b01100000;
     /// let after  = 0b11111111;
     ///
-    /// let mut bv = Bitv::from_bytes(&[before]);
+    /// let mut bv = BitVec::from_bytes(&[before]);
     /// bv.set_all();
-    /// assert_eq!(bv, Bitv::from_bytes(&[after]));
+    /// assert_eq!(bv, BitVec::from_bytes(&[after]));
     /// ```
     #[inline]
     pub fn set_all(&mut self) {
@@ -440,14 +440,14 @@ pub fn set_all(&mut self) {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
     /// let before = 0b01100000;
     /// let after  = 0b10011111;
     ///
-    /// let mut bv = Bitv::from_bytes(&[before]);
+    /// let mut bv = BitVec::from_bytes(&[before]);
     /// bv.negate();
-    /// assert_eq!(bv, Bitv::from_bytes(&[after]));
+    /// assert_eq!(bv, BitVec::from_bytes(&[after]));
     /// ```
     #[inline]
     pub fn negate(&mut self) {
@@ -468,20 +468,20 @@ pub fn negate(&mut self) {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
     /// let a   = 0b01100100;
     /// let b   = 0b01011010;
     /// let res = 0b01111110;
     ///
-    /// let mut a = Bitv::from_bytes(&[a]);
-    /// let b = Bitv::from_bytes(&[b]);
+    /// let mut a = BitVec::from_bytes(&[a]);
+    /// let b = BitVec::from_bytes(&[b]);
     ///
     /// assert!(a.union(&b));
-    /// assert_eq!(a, Bitv::from_bytes(&[res]));
+    /// assert_eq!(a, BitVec::from_bytes(&[res]));
     /// ```
     #[inline]
-    pub fn union(&mut self, other: &Bitv) -> bool {
+    pub fn union(&mut self, other: &BitVec) -> bool {
         self.process(other, |w1, w2| w1 | w2)
     }
 
@@ -498,20 +498,20 @@ pub fn union(&mut self, other: &Bitv) -> bool {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
     /// let a   = 0b01100100;
     /// let b   = 0b01011010;
     /// let res = 0b01000000;
     ///
-    /// let mut a = Bitv::from_bytes(&[a]);
-    /// let b = Bitv::from_bytes(&[b]);
+    /// let mut a = BitVec::from_bytes(&[a]);
+    /// let b = BitVec::from_bytes(&[b]);
     ///
     /// assert!(a.intersect(&b));
-    /// assert_eq!(a, Bitv::from_bytes(&[res]));
+    /// assert_eq!(a, BitVec::from_bytes(&[res]));
     /// ```
     #[inline]
-    pub fn intersect(&mut self, other: &Bitv) -> bool {
+    pub fn intersect(&mut self, other: &BitVec) -> bool {
         self.process(other, |w1, w2| w1 & w2)
     }
 
@@ -528,27 +528,27 @@ pub fn intersect(&mut self, other: &Bitv) -> bool {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
     /// let a   = 0b01100100;
     /// let b   = 0b01011010;
     /// let a_b = 0b00100100; // a - b
     /// let b_a = 0b00011010; // b - a
     ///
-    /// let mut bva = Bitv::from_bytes(&[a]);
-    /// let bvb = Bitv::from_bytes(&[b]);
+    /// let mut bva = BitVec::from_bytes(&[a]);
+    /// let bvb = BitVec::from_bytes(&[b]);
     ///
     /// assert!(bva.difference(&bvb));
-    /// assert_eq!(bva, Bitv::from_bytes(&[a_b]));
+    /// assert_eq!(bva, BitVec::from_bytes(&[a_b]));
     ///
-    /// let bva = Bitv::from_bytes(&[a]);
-    /// let mut bvb = Bitv::from_bytes(&[b]);
+    /// let bva = BitVec::from_bytes(&[a]);
+    /// let mut bvb = BitVec::from_bytes(&[b]);
     ///
     /// assert!(bvb.difference(&bva));
-    /// assert_eq!(bvb, Bitv::from_bytes(&[b_a]));
+    /// assert_eq!(bvb, BitVec::from_bytes(&[b_a]));
     /// ```
     #[inline]
-    pub fn difference(&mut self, other: &Bitv) -> bool {
+    pub fn difference(&mut self, other: &BitVec) -> bool {
         self.process(other, |w1, w2| w1 & !w2)
     }
 
@@ -557,9 +557,9 @@ pub fn difference(&mut self, other: &Bitv) -> bool {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(5, true);
+    /// let mut bv = BitVec::from_elem(5, true);
     /// assert_eq!(bv.all(), true);
     ///
     /// bv.set(1, false);
@@ -581,15 +581,15 @@ pub fn all(&self) -> bool {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let bv = Bitv::from_bytes(&[0b01110100, 0b10010010]);
+    /// let bv = BitVec::from_bytes(&[0b01110100, 0b10010010]);
     /// assert_eq!(bv.iter().filter(|x| *x).count(), 7);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter(&self) -> Iter {
-        Iter { bitv: self, next_idx: 0, end_idx: self.nbits }
+        Iter { bit_vec: self, next_idx: 0, end_idx: self.nbits }
     }
 
     /// Returns `true` if all bits are 0.
@@ -597,9 +597,9 @@ pub fn iter(&self) -> Iter {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(10, false);
+    /// let mut bv = BitVec::from_elem(10, false);
     /// assert_eq!(bv.none(), true);
     ///
     /// bv.set(3, true);
@@ -614,9 +614,9 @@ pub fn none(&self) -> bool {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(10, false);
+    /// let mut bv = BitVec::from_elem(10, false);
     /// assert_eq!(bv.any(), false);
     ///
     /// bv.set(3, true);
@@ -628,33 +628,33 @@ pub fn any(&self) -> bool {
     }
 
     /// Organises the bits into bytes, such that the first bit in the
-    /// `Bitv` becomes the high-order bit of the first byte. If the
-    /// size of the `Bitv` is not a multiple of eight then trailing bits
+    /// `BitVec` becomes the high-order bit of the first byte. If the
+    /// size of the `BitVec` is not a multiple of eight then trailing bits
     /// will be filled-in with `false`.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(3, true);
+    /// let mut bv = BitVec::from_elem(3, true);
     /// bv.set(1, false);
     ///
     /// assert_eq!(bv.to_bytes(), vec!(0b10100000));
     ///
-    /// let mut bv = Bitv::from_elem(9, false);
+    /// let mut bv = BitVec::from_elem(9, false);
     /// bv.set(2, true);
     /// bv.set(8, true);
     ///
     /// assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000));
     /// ```
     pub fn to_bytes(&self) -> Vec<u8> {
-        fn bit(bitv: &Bitv, byte: usize, bit: usize) -> u8 {
+        fn bit(bit_vec: &BitVec, byte: usize, bit: usize) -> u8 {
             let offset = byte * 8 + bit;
-            if offset >= bitv.nbits {
+            if offset >= bit_vec.nbits {
                 0
             } else {
-                (bitv[offset] as u8) << (7 - bit)
+                (bit_vec[offset] as u8) << (7 - bit)
             }
         }
 
@@ -672,19 +672,19 @@ fn bit(bitv: &Bitv, byte: usize, bit: usize) -> u8 {
         ).collect()
     }
 
-    /// Compares a `Bitv` to a slice of `bool`s.
-    /// Both the `Bitv` and slice must have the same length.
+    /// Compares a `BitVec` to a slice of `bool`s.
+    /// Both the `BitVec` and slice must have the same length.
     ///
     /// # Panics
     ///
-    /// Panics if the `Bitv` and slice are of different length.
+    /// Panics if the `BitVec` and slice are of different length.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let bv = Bitv::from_bytes(&[0b10100000]);
+    /// let bv = BitVec::from_bytes(&[0b10100000]);
     ///
     /// assert!(bv.eq_vec(&[true, false, true, false,
     ///                     false, false, false, false]));
@@ -694,7 +694,7 @@ pub fn eq_vec(&self, v: &[bool]) -> bool {
         iter::order::eq(self.iter(), v.iter().cloned())
     }
 
-    /// Shortens a `Bitv`, dropping excess elements.
+    /// Shortens a `BitVec`, dropping excess elements.
     ///
     /// If `len` is greater than the vector's current length, this has no
     /// effect.
@@ -702,9 +702,9 @@ pub fn eq_vec(&self, v: &[bool]) -> bool {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_bytes(&[0b01001011]);
+    /// let mut bv = BitVec::from_bytes(&[0b01001011]);
     /// bv.truncate(2);
     /// assert!(bv.eq_vec(&[false, true]));
     /// ```
@@ -719,7 +719,7 @@ pub fn truncate(&mut self, len: usize) {
     }
 
     /// Reserves capacity for at least `additional` more bits to be inserted in the given
-    /// `Bitv`. The collection may reserve more space to avoid frequent reallocations.
+    /// `BitVec`. The collection may reserve more space to avoid frequent reallocations.
     ///
     /// # Panics
     ///
@@ -728,9 +728,9 @@ pub fn truncate(&mut self, len: usize) {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(3, false);
+    /// let mut bv = BitVec::from_elem(3, false);
     /// bv.reserve(10);
     /// assert_eq!(bv.len(), 3);
     /// assert!(bv.capacity() >= 13);
@@ -745,7 +745,7 @@ pub fn reserve(&mut self, additional: usize) {
     }
 
     /// Reserves the minimum capacity for exactly `additional` more bits to be inserted in the
-    /// given `Bitv`. Does nothing if the capacity is already sufficient.
+    /// given `BitVec`. Does nothing if the capacity is already sufficient.
     ///
     /// Note that the allocator may give the collection more space than it requests. Therefore
     /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future
@@ -758,9 +758,9 @@ pub fn reserve(&mut self, additional: usize) {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_elem(3, false);
+    /// let mut bv = BitVec::from_elem(3, false);
     /// bv.reserve(10);
     /// assert_eq!(bv.len(), 3);
     /// assert!(bv.capacity() >= 13);
@@ -780,9 +780,9 @@ pub fn reserve_exact(&mut self, additional: usize) {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::new();
+    /// let mut bv = BitVec::new();
     /// bv.reserve(10);
     /// assert!(bv.capacity() >= 10);
     /// ```
@@ -792,7 +792,7 @@ pub fn capacity(&self) -> usize {
         self.storage.capacity().checked_mul(u32::BITS).unwrap_or(usize::MAX)
     }
 
-    /// Grows the `Bitv` in-place, adding `n` copies of `value` to the `Bitv`.
+    /// Grows the `BitVec` in-place, adding `n` copies of `value` to the `BitVec`.
     ///
     /// # Panics
     ///
@@ -801,9 +801,9 @@ pub fn capacity(&self) -> usize {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_bytes(&[0b01001011]);
+    /// let mut bv = BitVec::from_bytes(&[0b01001011]);
     /// bv.grow(2, true);
     /// assert_eq!(bv.len(), 10);
     /// assert_eq!(bv.to_bytes(), vec!(0b01001011, 0b11000000));
@@ -846,14 +846,14 @@ pub fn grow(&mut self, n: usize, value: bool) {
         self.fix_last_block();
     }
 
-    /// Removes the last bit from the Bitv, and returns it. Returns None if the Bitv is empty.
+    /// Removes the last bit from the BitVec, and returns it. Returns None if the BitVec is empty.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::from_bytes(&[0b01001001]);
+    /// let mut bv = BitVec::from_bytes(&[0b01001001]);
     /// assert_eq!(bv.pop(), Some(true));
     /// assert_eq!(bv.pop(), Some(false));
     /// assert_eq!(bv.len(), 6);
@@ -881,9 +881,9 @@ pub fn pop(&mut self) -> Option<bool> {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::Bitv;
+    /// use std::collections::BitVec;
     ///
-    /// let mut bv = Bitv::new();
+    /// let mut bv = BitVec::new();
     /// bv.push(true);
     /// bv.push(false);
     /// assert!(bv.eq_vec(&[true, false]));
@@ -917,24 +917,25 @@ pub fn clear(&mut self) {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Default for Bitv {
+impl Default for BitVec {
     #[inline]
-    fn default() -> Bitv { Bitv::new() }
+    fn default() -> BitVec { BitVec::new() }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl FromIterator<bool> for Bitv {
-    fn from_iter<I:Iterator<Item=bool>>(iterator: I) -> Bitv {
-        let mut ret = Bitv::new();
-        ret.extend(iterator);
+impl FromIterator<bool> for BitVec {
+    fn from_iter<I: IntoIterator<Item=bool>>(iter: I) -> BitVec {
+        let mut ret = BitVec::new();
+        ret.extend(iter);
         ret
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Extend<bool> for Bitv {
+impl Extend<bool> for BitVec {
     #[inline]
-    fn extend<I: Iterator<Item=bool>>(&mut self, iterator: I) {
+    fn extend<I: IntoIterator<Item=bool>>(&mut self, iterable: I) {
+        let iterator = iterable.into_iter();
         let (min, _) = iterator.size_hint();
         self.reserve(min);
         for element in iterator {
@@ -944,37 +945,37 @@ fn extend<I: Iterator<Item=bool>>(&mut self, iterator: I) {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Clone for Bitv {
+impl Clone for BitVec {
     #[inline]
-    fn clone(&self) -> Bitv {
-        Bitv { storage: self.storage.clone(), nbits: self.nbits }
+    fn clone(&self) -> BitVec {
+        BitVec { storage: self.storage.clone(), nbits: self.nbits }
     }
 
     #[inline]
-    fn clone_from(&mut self, source: &Bitv) {
+    fn clone_from(&mut self, source: &BitVec) {
         self.nbits = source.nbits;
         self.storage.clone_from(&source.storage);
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl PartialOrd for Bitv {
+impl PartialOrd for BitVec {
     #[inline]
-    fn partial_cmp(&self, other: &Bitv) -> Option<Ordering> {
+    fn partial_cmp(&self, other: &BitVec) -> Option<Ordering> {
         iter::order::partial_cmp(self.iter(), other.iter())
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Ord for Bitv {
+impl Ord for BitVec {
     #[inline]
-    fn cmp(&self, other: &Bitv) -> Ordering {
+    fn cmp(&self, other: &BitVec) -> Ordering {
         iter::order::cmp(self.iter(), other.iter())
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for Bitv {
+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 }));
@@ -984,7 +985,8 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Bitv {
+#[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() {
@@ -992,11 +994,21 @@ fn hash(&self, state: &mut S) {
         }
     }
 }
+#[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);
+        for elem in self.blocks() {
+            elem.hash(state);
+        }
+    }
+}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl cmp::PartialEq for Bitv {
+impl cmp::PartialEq for BitVec {
     #[inline]
-    fn eq(&self, other: &Bitv) -> bool {
+    fn eq(&self, other: &BitVec) -> bool {
         if self.nbits != other.nbits {
             return false;
         }
@@ -1005,13 +1017,13 @@ fn eq(&self, other: &Bitv) -> bool {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl cmp::Eq for Bitv {}
+impl cmp::Eq for BitVec {}
 
-/// An iterator for `Bitv`.
+/// An iterator for `BitVec`.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct Iter<'a> {
-    bitv: &'a Bitv,
+    bit_vec: &'a BitVec,
     next_idx: usize,
     end_idx: usize,
 }
@@ -1025,7 +1037,7 @@ fn next(&mut self) -> Option<bool> {
         if self.next_idx != self.end_idx {
             let idx = self.next_idx;
             self.next_idx += 1;
-            Some(self.bitv[idx])
+            Some(self.bit_vec[idx])
         } else {
             None
         }
@@ -1043,7 +1055,7 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
     fn next_back(&mut self) -> Option<bool> {
         if self.next_idx != self.end_idx {
             self.end_idx -= 1;
-            Some(self.bitv[self.end_idx])
+            Some(self.bit_vec[self.end_idx])
         } else {
             None
         }
@@ -1065,13 +1077,13 @@ fn idx(&mut self, index: usize) -> Option<bool> {
         if index >= self.indexable() {
             None
         } else {
-            Some(self.bitv[index])
+            Some(self.bit_vec[index])
         }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> IntoIterator for &'a Bitv {
+impl<'a> IntoIterator for &'a BitVec {
     type Item = bool;
     type IntoIter = Iter<'a>;
 
@@ -1090,10 +1102,10 @@ fn into_iter(self) -> Iter<'a> {
 /// # Examples
 ///
 /// ```
-/// use std::collections::{BitvSet, Bitv};
+/// use std::collections::{BitSet, BitVec};
 ///
 /// // It's a regular set
-/// let mut s = BitvSet::new();
+/// let mut s = BitSet::new();
 /// s.insert(0);
 /// s.insert(3);
 /// s.insert(7);
@@ -1104,8 +1116,8 @@ fn into_iter(self) -> Iter<'a> {
 ///     println!("There is no 7");
 /// }
 ///
-/// // Can initialize from a `Bitv`
-/// let other = BitvSet::from_bitv(Bitv::from_bytes(&[0b11010000]));
+/// // Can initialize from a `BitVec`
+/// let other = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11010000]));
 ///
 /// s.union_with(&other);
 ///
@@ -1114,115 +1126,115 @@ fn into_iter(self) -> Iter<'a> {
 ///     println!("{}", x);
 /// }
 ///
-/// // Can convert back to a `Bitv`
-/// let bv: Bitv = s.into_bitv();
+/// // Can convert back to a `BitVec`
+/// let bv: BitVec = s.into_bit_vec();
 /// assert!(bv[3]);
 /// ```
 #[derive(Clone)]
 #[unstable(feature = "collections",
            reason = "RFC 509")]
-pub struct BitvSet {
-    bitv: Bitv,
+pub struct BitSet {
+    bit_vec: BitVec,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Default for BitvSet {
+impl Default for BitSet {
     #[inline]
-    fn default() -> BitvSet { BitvSet::new() }
+    fn default() -> BitSet { BitSet::new() }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl FromIterator<usize> for BitvSet {
-    fn from_iter<I:Iterator<Item=usize>>(iterator: I) -> BitvSet {
-        let mut ret = BitvSet::new();
-        ret.extend(iterator);
+impl FromIterator<usize> for BitSet {
+    fn from_iter<I: IntoIterator<Item=usize>>(iter: I) -> BitSet {
+        let mut ret = BitSet::new();
+        ret.extend(iter);
         ret
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Extend<usize> for BitvSet {
+impl Extend<usize> for BitSet {
     #[inline]
-    fn extend<I: Iterator<Item=usize>>(&mut self, iterator: I) {
-        for i in iterator {
+    fn extend<I: IntoIterator<Item=usize>>(&mut self, iter: I) {
+        for i in iter {
             self.insert(i);
         }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl PartialOrd for BitvSet {
+impl PartialOrd for BitSet {
     #[inline]
-    fn partial_cmp(&self, other: &BitvSet) -> Option<Ordering> {
+    fn partial_cmp(&self, other: &BitSet) -> Option<Ordering> {
         let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref());
         iter::order::partial_cmp(a_iter, b_iter)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Ord for BitvSet {
+impl Ord for BitSet {
     #[inline]
-    fn cmp(&self, other: &BitvSet) -> Ordering {
+    fn cmp(&self, other: &BitSet) -> Ordering {
         let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref());
         iter::order::cmp(a_iter, b_iter)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl cmp::PartialEq for BitvSet {
+impl cmp::PartialEq for BitSet {
     #[inline]
-    fn eq(&self, other: &BitvSet) -> bool {
+    fn eq(&self, other: &BitSet) -> bool {
         let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref());
         iter::order::eq(a_iter, b_iter)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl cmp::Eq for BitvSet {}
+impl cmp::Eq for BitSet {}
 
-impl BitvSet {
-    /// Creates a new empty `BitvSet`.
+impl BitSet {
+    /// Creates a new empty `BitSet`.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::new();
+    /// let mut s = BitSet::new();
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new() -> BitvSet {
-        BitvSet { bitv: Bitv::new() }
+    pub fn new() -> BitSet {
+        BitSet { bit_vec: BitVec::new() }
     }
 
-    /// Creates a new `BitvSet` with initially no contents, able to
+    /// Creates a new `BitSet` with initially no contents, able to
     /// hold `nbits` elements without resizing.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::with_capacity(100);
+    /// let mut s = BitSet::with_capacity(100);
     /// assert!(s.capacity() >= 100);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn with_capacity(nbits: usize) -> BitvSet {
-        let bitv = Bitv::from_elem(nbits, false);
-        BitvSet::from_bitv(bitv)
+    pub fn with_capacity(nbits: usize) -> BitSet {
+        let bit_vec = BitVec::from_elem(nbits, false);
+        BitSet::from_bit_vec(bit_vec)
     }
 
-    /// Creates a new `BitvSet` from the given bit vector.
+    /// Creates a new `BitSet` from the given bit vector.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{Bitv, BitvSet};
+    /// use std::collections::{BitVec, BitSet};
     ///
-    /// let bv = Bitv::from_bytes(&[0b01100000]);
-    /// let s = BitvSet::from_bitv(bv);
+    /// let bv = BitVec::from_bytes(&[0b01100000]);
+    /// let s = BitSet::from_bit_vec(bv);
     ///
     /// // Print 1, 2 in arbitrary order
     /// for x in s.iter() {
@@ -1230,8 +1242,16 @@ pub fn with_capacity(nbits: usize) -> BitvSet {
     /// }
     /// ```
     #[inline]
-    pub fn from_bitv(bitv: Bitv) -> BitvSet {
-        BitvSet { bitv: bitv }
+    pub fn from_bit_vec(bit_vec: BitVec) -> 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
@@ -1240,19 +1260,19 @@ pub fn from_bitv(bitv: Bitv) -> BitvSet {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::with_capacity(100);
+    /// let mut s = BitSet::with_capacity(100);
     /// assert!(s.capacity() >= 100);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn capacity(&self) -> usize {
-        self.bitv.capacity()
+        self.bit_vec.capacity()
     }
 
-    /// Reserves capacity for the given `BitvSet` to contain `len` distinct elements. In the case
-    /// of `BitvSet` this means reallocations will not occur as long as all inserted elements
+    /// Reserves capacity for the given `BitSet` to contain `len` distinct elements. In the case
+    /// of `BitSet` this means reallocations will not occur as long as all inserted elements
     /// are less than `len`.
     ///
     /// The collection may reserve more space to avoid frequent reallocations.
@@ -1261,22 +1281,22 @@ pub fn capacity(&self) -> usize {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::new();
+    /// let mut s = BitSet::new();
     /// s.reserve_len(10);
     /// assert!(s.capacity() >= 10);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn reserve_len(&mut self, len: usize) {
-        let cur_len = self.bitv.len();
+        let cur_len = self.bit_vec.len();
         if len >= cur_len {
-            self.bitv.reserve(len - cur_len);
+            self.bit_vec.reserve(len - cur_len);
         }
     }
 
-    /// Reserves the minimum capacity for the given `BitvSet` to contain `len` distinct elements.
-    /// In the case of `BitvSet` this means reallocations will not occur as long as all inserted
+    /// Reserves the minimum capacity for the given `BitSet` to contain `len` distinct elements.
+    /// In the case of `BitSet` this means reallocations will not occur as long as all inserted
     /// elements are less than `len`.
     ///
     /// Note that the allocator may give the collection more space than it requests. Therefore
@@ -1287,17 +1307,17 @@ pub fn reserve_len(&mut self, len: usize) {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::new();
+    /// let mut s = BitSet::new();
     /// s.reserve_len_exact(10);
     /// assert!(s.capacity() >= 10);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn reserve_len_exact(&mut self, len: usize) {
-        let cur_len = self.bitv.len();
+        let cur_len = self.bit_vec.len();
         if len >= cur_len {
-            self.bitv.reserve_exact(len - cur_len);
+            self.bit_vec.reserve_exact(len - cur_len);
         }
     }
 
@@ -1307,19 +1327,19 @@ pub fn reserve_len_exact(&mut self, len: usize) {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::new();
+    /// let mut s = BitSet::new();
     /// s.insert(0);
     /// s.insert(3);
     ///
-    /// let bv = s.into_bitv();
+    /// let bv = s.into_bit_vec();
     /// assert!(bv[0]);
     /// assert!(bv[3]);
     /// ```
     #[inline]
-    pub fn into_bitv(self) -> Bitv {
-        self.bitv
+    pub fn into_bit_vec(self) -> BitVec {
+        self.bit_vec
     }
 
     /// Returns a reference to the underlying bit vector.
@@ -1327,44 +1347,44 @@ pub fn into_bitv(self) -> Bitv {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::new();
+    /// let mut s = BitSet::new();
     /// s.insert(0);
     ///
     /// let bv = s.get_ref();
     /// assert_eq!(bv[0], true);
     /// ```
     #[inline]
-    pub fn get_ref(&self) -> &Bitv {
-        &self.bitv
+    pub fn get_ref(&self) -> &BitVec {
+        &self.bit_vec
     }
 
     #[inline]
-    fn other_op<F>(&mut self, other: &BitvSet, mut f: F) where F: FnMut(u32, u32) -> u32 {
-        // Unwrap Bitvs
-        let self_bitv = &mut self.bitv;
-        let other_bitv = &other.bitv;
+    fn other_op<F>(&mut self, other: &BitSet, mut f: F) where F: FnMut(u32, u32) -> u32 {
+        // Unwrap BitVecs
+        let self_bit_vec = &mut self.bit_vec;
+        let other_bit_vec = &other.bit_vec;
 
-        let self_len = self_bitv.len();
-        let other_len = other_bitv.len();
+        let self_len = self_bit_vec.len();
+        let other_len = other_bit_vec.len();
 
         // Expand the vector if necessary
         if self_len < other_len {
-            self_bitv.grow(other_len - self_len, false);
+            self_bit_vec.grow(other_len - self_len, false);
         }
 
         // virtually pad other with 0's for equal lengths
         let other_words = {
-            let (_, result) = match_words(self_bitv, other_bitv);
+            let (_, result) = match_words(self_bit_vec, other_bit_vec);
             result
         };
 
         // Apply values found in other
         for (i, w) in other_words {
-            let old = self_bitv.storage[i];
+            let old = self_bit_vec.storage[i];
             let new = f(old, w);
-            self_bitv.storage[i] = new;
+            self_bit_vec.storage[i] = new;
         }
     }
 
@@ -1373,9 +1393,9 @@ fn other_op<F>(&mut self, other: &BitvSet, mut f: F) where F: FnMut(u32, u32) ->
     /// # Examples
     ///
     /// ```
-    /// use std::collections::BitvSet;
+    /// use std::collections::BitSet;
     ///
-    /// let mut s = BitvSet::new();
+    /// let mut s = BitSet::new();
     /// s.insert(32183231);
     /// s.remove(&32183231);
     ///
@@ -1389,25 +1409,25 @@ fn other_op<F>(&mut self, other: &BitvSet, mut f: F) where F: FnMut(u32, u32) ->
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn shrink_to_fit(&mut self) {
-        let bitv = &mut self.bitv;
+        let bit_vec = &mut self.bit_vec;
         // Obtain original length
-        let old_len = bitv.storage.len();
+        let old_len = bit_vec.storage.len();
         // Obtain coarse trailing zero length
-        let n = bitv.storage.iter().rev().take_while(|&&n| n == 0).count();
+        let n = bit_vec.storage.iter().rev().take_while(|&&n| n == 0).count();
         // Truncate
         let trunc_len = cmp::max(old_len - n, 1);
-        bitv.storage.truncate(trunc_len);
-        bitv.nbits = trunc_len * u32::BITS;
+        bit_vec.storage.truncate(trunc_len);
+        bit_vec.nbits = trunc_len * u32::BITS;
     }
 
-    /// Iterator over each u32 stored in the `BitvSet`.
+    /// Iterator over each u32 stored in the `BitSet`.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{Bitv, BitvSet};
+    /// use std::collections::{BitVec, BitSet};
     ///
-    /// let s = BitvSet::from_bitv(Bitv::from_bytes(&[0b01001010]));
+    /// let s = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01001010]));
     ///
     /// // Print 1, 4, 6 in arbitrary order
     /// for x in s.iter() {
@@ -1416,7 +1436,7 @@ pub fn shrink_to_fit(&mut self) {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn iter(&self) -> bitv_set::Iter {
+    pub fn iter(&self) -> bit_set::Iter {
         SetIter {set: self, next_idx: 0}
     }
 
@@ -1426,10 +1446,10 @@ pub fn iter(&self) -> bitv_set::Iter {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{Bitv, BitvSet};
+    /// use std::collections::{BitVec, BitSet};
     ///
-    /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000]));
-    /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000]));
+    /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
+    /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000]));
     ///
     /// // Print 0, 1, 2, 4 in arbitrary order
     /// for x in a.union(&b) {
@@ -1438,7 +1458,7 @@ pub fn iter(&self) -> bitv_set::Iter {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn union<'a>(&'a self, other: &'a BitvSet) -> Union<'a> {
+    pub fn union<'a>(&'a self, other: &'a BitSet) -> Union<'a> {
         fn or(w1: u32, w2: u32) -> u32 { w1 | w2 }
 
         Union(TwoBitPositions {
@@ -1456,10 +1476,10 @@ fn or(w1: u32, w2: u32) -> u32 { w1 | w2 }
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{Bitv, BitvSet};
+    /// use std::collections::{BitVec, BitSet};
     ///
-    /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000]));
-    /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000]));
+    /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
+    /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000]));
     ///
     /// // Print 2
     /// for x in a.intersection(&b) {
@@ -1468,9 +1488,9 @@ fn or(w1: u32, w2: u32) -> u32 { w1 | w2 }
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Intersection<'a> {
+    pub fn intersection<'a>(&'a self, other: &'a BitSet) -> Intersection<'a> {
         fn bitand(w1: u32, w2: u32) -> u32 { w1 & w2 }
-        let min = cmp::min(self.bitv.len(), other.bitv.len());
+        let min = cmp::min(self.bit_vec.len(), other.bit_vec.len());
         Intersection(TwoBitPositions {
             set: self,
             other: other,
@@ -1486,10 +1506,10 @@ fn bitand(w1: u32, w2: u32) -> u32 { w1 & w2 }
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{BitvSet, Bitv};
+    /// use std::collections::{BitSet, BitVec};
     ///
-    /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000]));
-    /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000]));
+    /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
+    /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000]));
     ///
     /// // Print 1, 4 in arbitrary order
     /// for x in a.difference(&b) {
@@ -1505,7 +1525,7 @@ fn bitand(w1: u32, w2: u32) -> u32 { w1 & w2 }
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn difference<'a>(&'a self, other: &'a BitvSet) -> Difference<'a> {
+    pub fn difference<'a>(&'a self, other: &'a BitSet) -> Difference<'a> {
         fn diff(w1: u32, w2: u32) -> u32 { w1 & !w2 }
 
         Difference(TwoBitPositions {
@@ -1524,10 +1544,10 @@ fn diff(w1: u32, w2: u32) -> u32 { w1 & !w2 }
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{BitvSet, Bitv};
+    /// use std::collections::{BitSet, BitVec};
     ///
-    /// let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101000]));
-    /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100000]));
+    /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
+    /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100000]));
     ///
     /// // Print 0, 1, 4 in arbitrary order
     /// for x in a.symmetric_difference(&b) {
@@ -1536,7 +1556,7 @@ fn diff(w1: u32, w2: u32) -> u32 { w1 & !w2 }
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> SymmetricDifference<'a> {
+    pub fn symmetric_difference<'a>(&'a self, other: &'a BitSet) -> SymmetricDifference<'a> {
         fn bitxor(w1: u32, w2: u32) -> u32 { w1 ^ w2 }
 
         SymmetricDifference(TwoBitPositions {
@@ -1553,21 +1573,21 @@ fn bitxor(w1: u32, w2: u32) -> u32 { w1 ^ w2 }
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{BitvSet, Bitv};
+    /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
     /// let b   = 0b10100000;
     /// let res = 0b11101000;
     ///
-    /// let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[a]));
-    /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[b]));
-    /// let res = BitvSet::from_bitv(Bitv::from_bytes(&[res]));
+    /// let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[a]));
+    /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[b]));
+    /// let res = BitSet::from_bit_vec(BitVec::from_bytes(&[res]));
     ///
     /// a.union_with(&b);
     /// assert_eq!(a, res);
     /// ```
     #[inline]
-    pub fn union_with(&mut self, other: &BitvSet) {
+    pub fn union_with(&mut self, other: &BitSet) {
         self.other_op(other, |w1, w2| w1 | w2);
     }
 
@@ -1576,21 +1596,21 @@ pub fn union_with(&mut self, other: &BitvSet) {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{BitvSet, Bitv};
+    /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
     /// let b   = 0b10100000;
     /// let res = 0b00100000;
     ///
-    /// let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[a]));
-    /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[b]));
-    /// let res = BitvSet::from_bitv(Bitv::from_bytes(&[res]));
+    /// let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[a]));
+    /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[b]));
+    /// let res = BitSet::from_bit_vec(BitVec::from_bytes(&[res]));
     ///
     /// a.intersect_with(&b);
     /// assert_eq!(a, res);
     /// ```
     #[inline]
-    pub fn intersect_with(&mut self, other: &BitvSet) {
+    pub fn intersect_with(&mut self, other: &BitSet) {
         self.other_op(other, |w1, w2| w1 & w2);
     }
 
@@ -1600,29 +1620,29 @@ pub fn intersect_with(&mut self, other: &BitvSet) {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{BitvSet, Bitv};
+    /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
     /// let b   = 0b10100000;
     /// let a_b = 0b01001000; // a - b
     /// let b_a = 0b10000000; // b - a
     ///
-    /// let mut bva = BitvSet::from_bitv(Bitv::from_bytes(&[a]));
-    /// let bvb = BitvSet::from_bitv(Bitv::from_bytes(&[b]));
-    /// let bva_b = BitvSet::from_bitv(Bitv::from_bytes(&[a_b]));
-    /// let bvb_a = BitvSet::from_bitv(Bitv::from_bytes(&[b_a]));
+    /// let mut bva = BitSet::from_bit_vec(BitVec::from_bytes(&[a]));
+    /// let bvb = BitSet::from_bit_vec(BitVec::from_bytes(&[b]));
+    /// let bva_b = BitSet::from_bit_vec(BitVec::from_bytes(&[a_b]));
+    /// let bvb_a = BitSet::from_bit_vec(BitVec::from_bytes(&[b_a]));
     ///
     /// bva.difference_with(&bvb);
     /// assert_eq!(bva, bva_b);
     ///
-    /// let bva = BitvSet::from_bitv(Bitv::from_bytes(&[a]));
-    /// let mut bvb = BitvSet::from_bitv(Bitv::from_bytes(&[b]));
+    /// let bva = BitSet::from_bit_vec(BitVec::from_bytes(&[a]));
+    /// let mut bvb = BitSet::from_bit_vec(BitVec::from_bytes(&[b]));
     ///
     /// bvb.difference_with(&bva);
     /// assert_eq!(bvb, bvb_a);
     /// ```
     #[inline]
-    pub fn difference_with(&mut self, other: &BitvSet) {
+    pub fn difference_with(&mut self, other: &BitSet) {
         self.other_op(other, |w1, w2| w1 & !w2);
     }
 
@@ -1632,21 +1652,21 @@ pub fn difference_with(&mut self, other: &BitvSet) {
     /// # Examples
     ///
     /// ```
-    /// use std::collections::{BitvSet, Bitv};
+    /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
     /// let b   = 0b10100000;
     /// let res = 0b11001000;
     ///
-    /// let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[a]));
-    /// let b = BitvSet::from_bitv(Bitv::from_bytes(&[b]));
-    /// let res = BitvSet::from_bitv(Bitv::from_bytes(&[res]));
+    /// let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[a]));
+    /// let b = BitSet::from_bit_vec(BitVec::from_bytes(&[b]));
+    /// let res = BitSet::from_bit_vec(BitVec::from_bytes(&[res]));
     ///
     /// a.symmetric_difference_with(&b);
     /// assert_eq!(a, res);
     /// ```
     #[inline]
-    pub fn symmetric_difference_with(&mut self, other: &BitvSet) {
+    pub fn symmetric_difference_with(&mut self, other: &BitSet) {
         self.other_op(other, |w1, w2| w1 ^ w2);
     }
 
@@ -1654,57 +1674,57 @@ pub fn symmetric_difference_with(&mut self, other: &BitvSet) {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn len(&self) -> usize  {
-        self.bitv.blocks().fold(0, |acc, n| acc + n.count_ones())
+        self.bit_vec.blocks().fold(0, |acc, n| acc + n.count_ones())
     }
 
     /// Returns whether there are no bits set in this set
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_empty(&self) -> bool {
-        self.bitv.none()
+        self.bit_vec.none()
     }
 
     /// Clears all bits in this set
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn clear(&mut self) {
-        self.bitv.clear();
+        self.bit_vec.clear();
     }
 
     /// Returns `true` if this set contains the specified integer.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn contains(&self, value: &usize) -> bool {
-        let bitv = &self.bitv;
-        *value < bitv.nbits && bitv[*value]
+        let bit_vec = &self.bit_vec;
+        *value < bit_vec.nbits && bit_vec[*value]
     }
 
     /// Returns `true` if the set has no elements in common with `other`.
     /// This is equivalent to checking for an empty intersection.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_disjoint(&self, other: &BitvSet) -> bool {
+    pub fn is_disjoint(&self, other: &BitSet) -> bool {
         self.intersection(other).next().is_none()
     }
 
     /// Returns `true` if the set is a subset of another.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_subset(&self, other: &BitvSet) -> bool {
-        let self_bitv = &self.bitv;
-        let other_bitv = &other.bitv;
-        let other_blocks = blocks_for_bits(other_bitv.len());
+    pub fn is_subset(&self, other: &BitSet) -> bool {
+        let self_bit_vec = &self.bit_vec;
+        let other_bit_vec = &other.bit_vec;
+        let other_blocks = blocks_for_bits(other_bit_vec.len());
 
         // Check that `self` intersect `other` is self
-        self_bitv.blocks().zip(other_bitv.blocks()).all(|(w1, w2)| w1 & w2 == w1) &&
+        self_bit_vec.blocks().zip(other_bit_vec.blocks()).all(|(w1, w2)| w1 & w2 == w1) &&
         // Make sure if `self` has any more blocks than `other`, they're all 0
-        self_bitv.blocks().skip(other_blocks).all(|w| w == 0)
+        self_bit_vec.blocks().skip(other_blocks).all(|w| w == 0)
     }
 
     /// Returns `true` if the set is a superset of another.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_superset(&self, other: &BitvSet) -> bool {
+    pub fn is_superset(&self, other: &BitSet) -> bool {
         other.is_subset(self)
     }
 
@@ -1717,12 +1737,12 @@ pub fn insert(&mut self, value: usize) -> bool {
         }
 
         // Ensure we have enough space to hold the new element
-        let len = self.bitv.len();
+        let len = self.bit_vec.len();
         if value >= len {
-            self.bitv.grow(value - len + 1, false)
+            self.bit_vec.grow(value - len + 1, false)
         }
 
-        self.bitv.set(value, true);
+        self.bit_vec.set(value, true);
         return true;
     }
 
@@ -1734,16 +1754,16 @@ pub fn remove(&mut self, value: &usize) -> bool {
             return false;
         }
 
-        self.bitv.set(*value, false);
+        self.bit_vec.set(*value, false);
 
         return true;
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for BitvSet {
+impl fmt::Debug for BitSet {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(fmt, "BitvSet {{"));
+        try!(write!(fmt, "BitSet {{"));
         let mut first = true;
         for n in self {
             if !first {
@@ -1756,27 +1776,37 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for BitvSet {
+#[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 {
+            pos.hash(state);
+        }
+    }
+}
 
-/// An iterator for `BitvSet`.
+/// An iterator for `BitSet`.
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct SetIter<'a> {
-    set: &'a BitvSet,
+    set: &'a BitSet,
     next_idx: usize
 }
 
-/// An iterator combining two `BitvSet` iterators.
+/// An iterator combining two `BitSet` iterators.
 #[derive(Clone)]
 struct TwoBitPositions<'a> {
-    set: &'a BitvSet,
-    other: &'a BitvSet,
+    set: &'a BitSet,
+    other: &'a BitSet,
     merge: fn(u32, u32) -> u32,
     current_word: u32,
     next_idx: usize
@@ -1796,7 +1826,7 @@ impl<'a> Iterator for SetIter<'a> {
     type Item = usize;
 
     fn next(&mut self) -> Option<usize> {
-        while self.next_idx < self.set.bitv.len() {
+        while self.next_idx < self.set.bit_vec.len() {
             let idx = self.next_idx;
             self.next_idx += 1;
 
@@ -1810,7 +1840,7 @@ fn next(&mut self) -> Option<usize> {
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        (0, Some(self.set.bitv.len() - self.next_idx))
+        (0, Some(self.set.bit_vec.len() - self.next_idx))
     }
 }
 
@@ -1819,20 +1849,20 @@ impl<'a> Iterator for TwoBitPositions<'a> {
     type Item = usize;
 
     fn next(&mut self) -> Option<usize> {
-        while self.next_idx < self.set.bitv.len() ||
-              self.next_idx < self.other.bitv.len() {
+        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;
             if bit_idx == 0 {
-                let s_bitv = &self.set.bitv;
-                let o_bitv = &self.other.bitv;
+                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 Bitv might be longer than the other
+                // one BitVec might be longer than the other
                 let word_idx = self.next_idx / u32::BITS;
-                let w1 = if word_idx < s_bitv.storage.len() {
-                             s_bitv.storage[word_idx]
+                let w1 = if word_idx < s_bit_vec.storage.len() {
+                             s_bit_vec.storage[word_idx]
                          } else { 0 };
-                let w2 = if word_idx < o_bitv.storage.len() {
-                             o_bitv.storage[word_idx]
+                let w2 = if word_idx < o_bit_vec.storage.len() {
+                             o_bit_vec.storage[word_idx]
                          } else { 0 };
                 self.current_word = (self.merge)(w1, w2);
             }
@@ -1847,7 +1877,7 @@ fn next(&mut self) -> Option<usize> {
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let cap = cmp::max(self.set.bitv.len(), self.other.bitv.len());
+        let cap = cmp::max(self.set.bit_vec.len(), self.other.bit_vec.len());
         (0, Some(cap - self.next_idx))
     }
 }
@@ -1885,7 +1915,7 @@ impl<'a> Iterator for SymmetricDifference<'a> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> IntoIterator for &'a BitvSet {
+impl<'a> IntoIterator for &'a BitSet {
     type Item = usize;
     type IntoIter = SetIter<'a>;
 
@@ -1899,20 +1929,20 @@ mod tests {
     use prelude::*;
     use core::u32;
 
-    use super::Bitv;
+    use super::BitVec;
 
     #[test]
     fn test_to_str() {
-        let zerolen = Bitv::new();
+        let zerolen = BitVec::new();
         assert_eq!(format!("{:?}", zerolen), "");
 
-        let eightbits = Bitv::from_elem(8, false);
+        let eightbits = BitVec::from_elem(8, false);
         assert_eq!(format!("{:?}", eightbits), "00000000")
     }
 
     #[test]
     fn test_0_elements() {
-        let act = Bitv::new();
+        let act = BitVec::new();
         let exp = Vec::new();
         assert!(act.eq_vec(&exp));
         assert!(act.none() && act.all());
@@ -1920,17 +1950,17 @@ fn test_0_elements() {
 
     #[test]
     fn test_1_element() {
-        let mut act = Bitv::from_elem(1, false);
+        let mut act = BitVec::from_elem(1, false);
         assert!(act.eq_vec(&[false]));
         assert!(act.none() && !act.all());
-        act = Bitv::from_elem(1, true);
+        act = BitVec::from_elem(1, true);
         assert!(act.eq_vec(&[true]));
         assert!(!act.none() && act.all());
     }
 
     #[test]
     fn test_2_elements() {
-        let mut b = Bitv::from_elem(2, false);
+        let mut b = BitVec::from_elem(2, false);
         b.set(0, true);
         b.set(1, false);
         assert_eq!(format!("{:?}", b), "10");
@@ -1942,18 +1972,18 @@ fn test_10_elements() {
         let mut act;
         // all 0
 
-        act = Bitv::from_elem(10, false);
+        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 = Bitv::from_elem(10, true);
+        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 = Bitv::from_elem(10, false);
+        act = BitVec::from_elem(10, false);
         act.set(0, true);
         act.set(1, true);
         act.set(2, true);
@@ -1963,7 +1993,7 @@ fn test_10_elements() {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(10, false);
+        act = BitVec::from_elem(10, false);
         act.set(5, true);
         act.set(6, true);
         act.set(7, true);
@@ -1973,7 +2003,7 @@ fn test_10_elements() {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(10, false);
+        act = BitVec::from_elem(10, false);
         act.set(0, true);
         act.set(3, true);
         act.set(6, true);
@@ -1987,7 +2017,7 @@ fn test_31_elements() {
         let mut act;
         // all 0
 
-        act = Bitv::from_elem(31, false);
+        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,
@@ -1995,7 +2025,7 @@ fn test_31_elements() {
         assert!(act.none() && !act.all());
         // all 1
 
-        act = Bitv::from_elem(31, true);
+        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,
@@ -2003,7 +2033,7 @@ fn test_31_elements() {
         assert!(!act.none() && act.all());
         // mixed
 
-        act = Bitv::from_elem(31, false);
+        act = BitVec::from_elem(31, false);
         act.set(0, true);
         act.set(1, true);
         act.set(2, true);
@@ -2019,7 +2049,7 @@ fn test_31_elements() {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(31, false);
+        act = BitVec::from_elem(31, false);
         act.set(16, true);
         act.set(17, true);
         act.set(18, true);
@@ -2035,7 +2065,7 @@ fn test_31_elements() {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(31, false);
+        act = BitVec::from_elem(31, false);
         act.set(24, true);
         act.set(25, true);
         act.set(26, true);
@@ -2050,7 +2080,7 @@ fn test_31_elements() {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(31, false);
+        act = BitVec::from_elem(31, false);
         act.set(3, true);
         act.set(17, true);
         act.set(30, true);
@@ -2066,7 +2096,7 @@ fn test_32_elements() {
         let mut act;
         // all 0
 
-        act = Bitv::from_elem(32, false);
+        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,
@@ -2074,7 +2104,7 @@ fn test_32_elements() {
         assert!(act.none() && !act.all());
         // all 1
 
-        act = Bitv::from_elem(32, true);
+        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,
@@ -2082,7 +2112,7 @@ fn test_32_elements() {
         assert!(!act.none() && act.all());
         // mixed
 
-        act = Bitv::from_elem(32, false);
+        act = BitVec::from_elem(32, false);
         act.set(0, true);
         act.set(1, true);
         act.set(2, true);
@@ -2098,7 +2128,7 @@ fn test_32_elements() {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(32, false);
+        act = BitVec::from_elem(32, false);
         act.set(16, true);
         act.set(17, true);
         act.set(18, true);
@@ -2114,7 +2144,7 @@ fn test_32_elements() {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(32, false);
+        act = BitVec::from_elem(32, false);
         act.set(24, true);
         act.set(25, true);
         act.set(26, true);
@@ -2130,7 +2160,7 @@ fn test_32_elements() {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(32, false);
+        act = BitVec::from_elem(32, false);
         act.set(3, true);
         act.set(17, true);
         act.set(30, true);
@@ -2147,7 +2177,7 @@ fn test_33_elements() {
         let mut act;
         // all 0
 
-        act = Bitv::from_elem(33, false);
+        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,
@@ -2155,7 +2185,7 @@ fn test_33_elements() {
         assert!(act.none() && !act.all());
         // all 1
 
-        act = Bitv::from_elem(33, true);
+        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,
@@ -2163,7 +2193,7 @@ fn test_33_elements() {
         assert!(!act.none() && act.all());
         // mixed
 
-        act = Bitv::from_elem(33, false);
+        act = BitVec::from_elem(33, false);
         act.set(0, true);
         act.set(1, true);
         act.set(2, true);
@@ -2179,7 +2209,7 @@ fn test_33_elements() {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(33, false);
+        act = BitVec::from_elem(33, false);
         act.set(16, true);
         act.set(17, true);
         act.set(18, true);
@@ -2195,7 +2225,7 @@ fn test_33_elements() {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(33, false);
+        act = BitVec::from_elem(33, false);
         act.set(24, true);
         act.set(25, true);
         act.set(26, true);
@@ -2211,7 +2241,7 @@ fn test_33_elements() {
         assert!(!act.none() && !act.all());
         // mixed
 
-        act = Bitv::from_elem(33, false);
+        act = BitVec::from_elem(33, false);
         act.set(3, true);
         act.set(17, true);
         act.set(30, true);
@@ -2226,24 +2256,24 @@ fn test_33_elements() {
 
     #[test]
     fn test_equal_differing_sizes() {
-        let v0 = Bitv::from_elem(10, false);
-        let v1 = Bitv::from_elem(11, false);
+        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 = Bitv::from_elem(10, false);
-        let v1 = Bitv::from_elem(110, false);
+        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 = Bitv::from_elem(1, false);
+        let mut a = BitVec::from_elem(1, false);
         a.set(0, true);
 
-        let mut b = Bitv::from_elem(1, true);
+        let mut b = BitVec::from_elem(1, true);
         b.set(0, true);
 
         assert_eq!(a, b);
@@ -2251,12 +2281,12 @@ fn test_equal_sneaky_small() {
 
     #[test]
     fn test_equal_sneaky_big() {
-        let mut a = Bitv::from_elem(100, false);
+        let mut a = BitVec::from_elem(100, false);
         for i in 0..100 {
             a.set(i, true);
         }
 
-        let mut b = Bitv::from_elem(100, true);
+        let mut b = BitVec::from_elem(100, true);
         for i in 0..100 {
             b.set(i, true);
         }
@@ -2266,18 +2296,18 @@ fn test_equal_sneaky_big() {
 
     #[test]
     fn test_from_bytes() {
-        let bitv = Bitv::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
+        let bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
         let str = concat!("10110110", "00000000", "11111111");
-        assert_eq!(format!("{:?}", bitv), str);
+        assert_eq!(format!("{:?}", bit_vec), str);
     }
 
     #[test]
     fn test_to_bytes() {
-        let mut bv = Bitv::from_elem(3, true);
+        let mut bv = BitVec::from_elem(3, true);
         bv.set(1, false);
         assert_eq!(bv.to_bytes(), vec!(0b10100000));
 
-        let mut bv = Bitv::from_elem(9, false);
+        let mut bv = BitVec::from_elem(9, false);
         bv.set(2, true);
         bv.set(8, true);
         assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000));
@@ -2286,32 +2316,32 @@ fn test_to_bytes() {
     #[test]
     fn test_from_bools() {
         let bools = vec![true, false, true, true];
-        let bitv: Bitv = bools.iter().map(|n| *n).collect();
-        assert_eq!(format!("{:?}", bitv), "1011");
+        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!(Bitv::from_bytes(&[0b00100110]).iter().collect::<Vec<bool>>(), bools);
+        assert_eq!(BitVec::from_bytes(&[0b00100110]).iter().collect::<Vec<bool>>(), bools);
     }
 
     #[test]
-    fn test_bitv_iterator() {
+    fn test_bit_vec_iterator() {
         let bools = vec![true, false, true, true];
-        let bitv: Bitv = bools.iter().map(|n| *n).collect();
+        let bit_vec: BitVec = bools.iter().map(|n| *n).collect();
 
-        assert_eq!(bitv.iter().collect::<Vec<bool>>(), bools);
+        assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), bools);
 
         let long: Vec<_> = (0i32..10000).map(|i| i % 2 == 0).collect();
-        let bitv: Bitv = long.iter().map(|n| *n).collect();
-        assert_eq!(bitv.iter().collect::<Vec<bool>>(), long)
+        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 = Bitv::from_elem(3, false);
-        let mut b2 = Bitv::from_elem(3, false);
+        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);
@@ -2324,8 +2354,8 @@ fn test_small_difference() {
 
     #[test]
     fn test_big_difference() {
-        let mut b1 = Bitv::from_elem(100, false);
-        let mut b2 = Bitv::from_elem(100, false);
+        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);
@@ -2338,7 +2368,7 @@ fn test_big_difference() {
 
     #[test]
     fn test_small_clear() {
-        let mut b = Bitv::from_elem(14, true);
+        let mut b = BitVec::from_elem(14, true);
         assert!(!b.none() && b.all());
         b.clear();
         assert!(b.none() && !b.all());
@@ -2346,16 +2376,16 @@ fn test_small_clear() {
 
     #[test]
     fn test_big_clear() {
-        let mut b = Bitv::from_elem(140, true);
+        let mut b = BitVec::from_elem(140, true);
         assert!(!b.none() && b.all());
         b.clear();
         assert!(b.none() && !b.all());
     }
 
     #[test]
-    fn test_bitv_lt() {
-        let mut a = Bitv::from_elem(5, false);
-        let mut b = Bitv::from_elem(5, false);
+    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);
@@ -2370,8 +2400,8 @@ fn test_bitv_lt() {
 
     #[test]
     fn test_ord() {
-        let mut a = Bitv::from_elem(5, false);
-        let mut b = Bitv::from_elem(5, false);
+        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);
@@ -2385,26 +2415,26 @@ fn test_ord() {
 
 
     #[test]
-    fn test_small_bitv_tests() {
-        let v = Bitv::from_bytes(&[0]);
+    fn test_small_bit_vec_tests() {
+        let v = BitVec::from_bytes(&[0]);
         assert!(!v.all());
         assert!(!v.any());
         assert!(v.none());
 
-        let v = Bitv::from_bytes(&[0b00010100]);
+        let v = BitVec::from_bytes(&[0b00010100]);
         assert!(!v.all());
         assert!(v.any());
         assert!(!v.none());
 
-        let v = Bitv::from_bytes(&[0xFF]);
+        let v = BitVec::from_bytes(&[0xFF]);
         assert!(v.all());
         assert!(v.any());
         assert!(!v.none());
     }
 
     #[test]
-    fn test_big_bitv_tests() {
-        let v = Bitv::from_bytes(&[ // 88 bits
+    fn test_big_bit_vec_tests() {
+        let v = BitVec::from_bytes(&[ // 88 bits
             0, 0, 0, 0,
             0, 0, 0, 0,
             0, 0, 0]);
@@ -2412,7 +2442,7 @@ fn test_big_bitv_tests() {
         assert!(!v.any());
         assert!(v.none());
 
-        let v = Bitv::from_bytes(&[ // 88 bits
+        let v = BitVec::from_bytes(&[ // 88 bits
             0, 0, 0b00010100, 0,
             0, 0, 0, 0b00110100,
             0, 0, 0]);
@@ -2420,7 +2450,7 @@ fn test_big_bitv_tests() {
         assert!(v.any());
         assert!(!v.none());
 
-        let v = Bitv::from_bytes(&[ // 88 bits
+        let v = BitVec::from_bytes(&[ // 88 bits
             0xFF, 0xFF, 0xFF, 0xFF,
             0xFF, 0xFF, 0xFF, 0xFF,
             0xFF, 0xFF, 0xFF]);
@@ -2430,8 +2460,8 @@ fn test_big_bitv_tests() {
     }
 
     #[test]
-    fn test_bitv_push_pop() {
-        let mut s = Bitv::from_elem(5 * u32::BITS - 2, false);
+    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);
@@ -2453,29 +2483,29 @@ fn test_bitv_push_pop() {
     }
 
     #[test]
-    fn test_bitv_truncate() {
-        let mut s = Bitv::from_elem(5 * u32::BITS, true);
+    fn test_bit_vec_truncate() {
+        let mut s = BitVec::from_elem(5 * u32::BITS, true);
 
-        assert_eq!(s, Bitv::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, Bitv::from_elem(4 * u32::BITS, true));
+        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, Bitv::from_elem(4 * u32::BITS, true));
+        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, Bitv::from_elem(3 * u32::BITS - 10, true));
+        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, Bitv::from_elem(0, true));
+        assert_eq!(s, BitVec::from_elem(0, true));
         assert_eq!(s.len(), 0);
     }
 
     #[test]
-    fn test_bitv_reserve() {
-        let mut s = Bitv::from_elem(5 * u32::BITS, true);
+    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);
@@ -2498,25 +2528,25 @@ fn test_bitv_reserve() {
     }
 
     #[test]
-    fn test_bitv_grow() {
-        let mut bitv = Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010]);
-        bitv.grow(32, true);
-        assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
+    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]));
-        bitv.grow(64, false);
-        assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
+        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]));
-        bitv.grow(16, true);
-        assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
+        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_bitv_extend() {
-        let mut bitv = Bitv::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
-        let ext = Bitv::from_bytes(&[0b01001001, 0b10010010, 0b10111101]);
-        bitv.extend(ext.iter());
-        assert_eq!(bitv, Bitv::from_bytes(&[0b10110110, 0b00000000, 0b11111111,
+    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]));
     }
 }
@@ -2525,14 +2555,14 @@ fn test_bitv_extend() {
 
 
 #[cfg(test)]
-mod bitv_bench {
+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::Bitv;
+    use super::BitVec;
 
     static BENCH_BITS : usize = 1 << 14;
 
@@ -2544,67 +2574,67 @@ fn rng() -> rand::IsaacRng {
     #[bench]
     fn bench_usize_small(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = 0 as usize;
+        let mut bit_vec = 0 as usize;
         b.iter(|| {
             for _ in 0..100 {
-                bitv |= 1 << ((r.next_u32() as usize) % u32::BITS);
+                bit_vec |= 1 << ((r.next_u32() as usize) % u32::BITS);
             }
-            black_box(&bitv);
+            black_box(&bit_vec);
         });
     }
 
     #[bench]
-    fn bench_bitv_set_big_fixed(b: &mut Bencher) {
+    fn bench_bit_set_big_fixed(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = Bitv::from_elem(BENCH_BITS, false);
+        let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
         b.iter(|| {
             for _ in 0..100 {
-                bitv.set((r.next_u32() as usize) % BENCH_BITS, true);
+                bit_vec.set((r.next_u32() as usize) % BENCH_BITS, true);
             }
-            black_box(&bitv);
+            black_box(&bit_vec);
         });
     }
 
     #[bench]
-    fn bench_bitv_set_big_variable(b: &mut Bencher) {
+    fn bench_bit_set_big_variable(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = Bitv::from_elem(BENCH_BITS, false);
+        let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
         b.iter(|| {
             for _ in 0..100 {
-                bitv.set((r.next_u32() as usize) % BENCH_BITS, r.gen());
+                bit_vec.set((r.next_u32() as usize) % BENCH_BITS, r.gen());
             }
-            black_box(&bitv);
+            black_box(&bit_vec);
         });
     }
 
     #[bench]
-    fn bench_bitv_set_small(b: &mut Bencher) {
+    fn bench_bit_set_small(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = Bitv::from_elem(u32::BITS, false);
+        let mut bit_vec = BitVec::from_elem(u32::BITS, false);
         b.iter(|| {
             for _ in 0..100 {
-                bitv.set((r.next_u32() as usize) % u32::BITS, true);
+                bit_vec.set((r.next_u32() as usize) % u32::BITS, true);
             }
-            black_box(&bitv);
+            black_box(&bit_vec);
         });
     }
 
     #[bench]
-    fn bench_bitv_big_union(b: &mut Bencher) {
-        let mut b1 = Bitv::from_elem(BENCH_BITS, false);
-        let b2 = Bitv::from_elem(BENCH_BITS, false);
+    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_bitv_small_iter(b: &mut Bencher) {
-        let bitv = Bitv::from_elem(u32::BITS, false);
+    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 &bitv {
+                for pres in &bit_vec {
                     sum += pres as usize;
                 }
             }
@@ -2613,11 +2643,11 @@ fn bench_bitv_small_iter(b: &mut Bencher) {
     }
 
     #[bench]
-    fn bench_bitv_big_iter(b: &mut Bencher) {
-        let bitv = Bitv::from_elem(BENCH_BITS, false);
+    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 &bitv {
+            for pres in &bit_vec {
                 sum += pres as usize;
             }
             sum
@@ -2632,27 +2662,27 @@ fn bench_bitv_big_iter(b: &mut Bencher) {
 
 
 #[cfg(test)]
-mod bitv_set_test {
+mod bit_set_test {
     use prelude::*;
     use std::iter::range_step;
 
-    use super::{Bitv, BitvSet};
+    use super::{BitVec, BitSet};
 
     #[test]
-    fn test_bitv_set_show() {
-        let mut s = BitvSet::new();
+    fn test_bit_set_show() {
+        let mut s = BitSet::new();
         s.insert(1);
         s.insert(10);
         s.insert(50);
         s.insert(2);
-        assert_eq!("BitvSet {1, 2, 10, 50}", format!("{:?}", s));
+        assert_eq!("BitSet {1, 2, 10, 50}", format!("{:?}", s));
     }
 
     #[test]
-    fn test_bitv_set_from_usizes() {
+    fn test_bit_set_from_usizes() {
         let usizes = vec![0, 2, 2, 3];
-        let a: BitvSet = usizes.into_iter().collect();
-        let mut b = BitvSet::new();
+        let a: BitSet = usizes.into_iter().collect();
+        let mut b = BitSet::new();
         b.insert(0);
         b.insert(2);
         b.insert(3);
@@ -2660,14 +2690,14 @@ fn test_bitv_set_from_usizes() {
     }
 
     #[test]
-    fn test_bitv_set_iterator() {
+    fn test_bit_set_iterator() {
         let usizes = vec![0, 2, 2, 3];
-        let bitv: BitvSet = usizes.into_iter().collect();
+        let bit_vec: BitSet = usizes.into_iter().collect();
 
-        let idxs: Vec<_> = bitv.iter().collect();
+        let idxs: Vec<_> = bit_vec.iter().collect();
         assert_eq!(idxs, vec![0, 2, 3]);
 
-        let long: BitvSet = (0..10000).filter(|&n| n % 2 == 0).collect();
+        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();
@@ -2675,12 +2705,12 @@ fn test_bitv_set_iterator() {
     }
 
     #[test]
-    fn test_bitv_set_frombitv_init() {
+    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 = BitvSet::from_bitv(Bitv::from_elem(l, b));
+                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));
@@ -2689,9 +2719,9 @@ fn test_bitv_set_frombitv_init() {
     }
 
     #[test]
-    fn test_bitv_masking() {
-        let b = Bitv::from_elem(140, true);
-        let mut bs = BitvSet::from_bitv(b);
+    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));
@@ -2702,8 +2732,8 @@ fn test_bitv_masking() {
     }
 
     #[test]
-    fn test_bitv_set_basic() {
-        let mut b = BitvSet::new();
+    fn test_bit_set_basic() {
+        let mut b = BitSet::new();
         assert!(b.insert(3));
         assert!(!b.insert(3));
         assert!(b.contains(&3));
@@ -2717,9 +2747,9 @@ fn test_bitv_set_basic() {
     }
 
     #[test]
-    fn test_bitv_set_intersection() {
-        let mut a = BitvSet::new();
-        let mut b = BitvSet::new();
+    fn test_bit_set_intersection() {
+        let mut a = BitSet::new();
+        let mut b = BitSet::new();
 
         assert!(a.insert(11));
         assert!(a.insert(1));
@@ -2740,9 +2770,9 @@ fn test_bitv_set_intersection() {
     }
 
     #[test]
-    fn test_bitv_set_difference() {
-        let mut a = BitvSet::new();
-        let mut b = BitvSet::new();
+    fn test_bit_set_difference() {
+        let mut a = BitSet::new();
+        let mut b = BitSet::new();
 
         assert!(a.insert(1));
         assert!(a.insert(3));
@@ -2759,9 +2789,9 @@ fn test_bitv_set_difference() {
     }
 
     #[test]
-    fn test_bitv_set_symmetric_difference() {
-        let mut a = BitvSet::new();
-        let mut b = BitvSet::new();
+    fn test_bit_set_symmetric_difference() {
+        let mut a = BitSet::new();
+        let mut b = BitSet::new();
 
         assert!(a.insert(1));
         assert!(a.insert(3));
@@ -2780,9 +2810,9 @@ fn test_bitv_set_symmetric_difference() {
     }
 
     #[test]
-    fn test_bitv_set_union() {
-        let mut a = BitvSet::new();
-        let mut b = BitvSet::new();
+    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));
@@ -2805,9 +2835,9 @@ fn test_bitv_set_union() {
     }
 
     #[test]
-    fn test_bitv_set_subset() {
-        let mut set1 = BitvSet::new();
-        let mut set2 = BitvSet::new();
+    fn test_bit_set_subset() {
+        let mut set1 = BitSet::new();
+        let mut set2 = BitSet::new();
 
         assert!(set1.is_subset(&set2)); //  {}  {}
         set2.insert(100);
@@ -2831,11 +2861,11 @@ fn test_bitv_set_subset() {
     }
 
     #[test]
-    fn test_bitv_set_is_disjoint() {
-        let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01000000]));
-        let c = BitvSet::new();
-        let d = BitvSet::from_bitv(Bitv::from_bytes(&[0b00110000]));
+    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));
@@ -2849,19 +2879,19 @@ fn test_bitv_set_is_disjoint() {
     }
 
     #[test]
-    fn test_bitv_set_union_with() {
+    fn test_bit_set_union_with() {
         //a should grow to include larger elements
-        let mut a = BitvSet::new();
+        let mut a = BitSet::new();
         a.insert(0);
-        let mut b = BitvSet::new();
+        let mut b = BitSet::new();
         b.insert(5);
-        let expected = BitvSet::from_bitv(Bitv::from_bytes(&[0b10000100]));
+        let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100]));
         a.union_with(&b);
         assert_eq!(a, expected);
 
         // Standard
-        let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01100010]));
+        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);
@@ -2870,10 +2900,10 @@ fn test_bitv_set_union_with() {
     }
 
     #[test]
-    fn test_bitv_set_intersect_with() {
+    fn test_bit_set_intersect_with() {
         // Explicitly 0'ed bits
-        let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000]));
+        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);
@@ -2881,8 +2911,8 @@ fn test_bitv_set_intersect_with() {
         assert!(b.is_empty());
 
         // Uninitialized bits should behave like 0's
-        let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let mut b = BitvSet::new();
+        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);
@@ -2890,8 +2920,8 @@ fn test_bitv_set_intersect_with() {
         assert!(b.is_empty());
 
         // Standard
-        let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01100010]));
+        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);
@@ -2900,22 +2930,22 @@ fn test_bitv_set_intersect_with() {
     }
 
     #[test]
-    fn test_bitv_set_difference_with() {
+    fn test_bit_set_difference_with() {
         // Explicitly 0'ed bits
-        let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000]));
-        let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
+        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 = BitvSet::new();
-        let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b11111111]));
+        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 = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01100010]));
+        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);
@@ -2924,27 +2954,27 @@ fn test_bitv_set_difference_with() {
     }
 
     #[test]
-    fn test_bitv_set_symmetric_difference_with() {
+    fn test_bit_set_symmetric_difference_with() {
         //a should grow to include larger elements
-        let mut a = BitvSet::new();
+        let mut a = BitSet::new();
         a.insert(0);
         a.insert(1);
-        let mut b = BitvSet::new();
+        let mut b = BitSet::new();
         b.insert(1);
         b.insert(5);
-        let expected = BitvSet::from_bitv(Bitv::from_bytes(&[0b10000100]));
+        let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100]));
         a.symmetric_difference_with(&b);
         assert_eq!(a, expected);
 
-        let mut a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let b = BitvSet::new();
+        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 = BitvSet::from_bitv(Bitv::from_bytes(&[0b11100010]));
-        let mut b = BitvSet::from_bitv(Bitv::from_bytes(&[0b01101010]));
+        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);
@@ -2953,10 +2983,10 @@ fn test_bitv_set_symmetric_difference_with() {
     }
 
     #[test]
-    fn test_bitv_set_eq() {
-        let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000]));
-        let c = BitvSet::new();
+    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);
@@ -2967,10 +2997,10 @@ fn test_bitv_set_eq() {
     }
 
     #[test]
-    fn test_bitv_set_cmp() {
-        let a = BitvSet::from_bitv(Bitv::from_bytes(&[0b10100010]));
-        let b = BitvSet::from_bitv(Bitv::from_bytes(&[0b00000000]));
-        let c = BitvSet::new();
+    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);
@@ -2981,8 +3011,8 @@ fn test_bitv_set_cmp() {
     }
 
     #[test]
-    fn test_bitv_remove() {
-        let mut a = BitvSet::new();
+    fn test_bit_vec_remove() {
+        let mut a = BitSet::new();
 
         assert!(a.insert(1));
         assert!(a.remove(&1));
@@ -2996,8 +3026,8 @@ fn test_bitv_remove() {
     }
 
     #[test]
-    fn test_bitv_clone() {
-        let mut a = BitvSet::new();
+    fn test_bit_vec_clone() {
+        let mut a = BitSet::new();
 
         assert!(a.insert(1));
         assert!(a.insert(100));
@@ -3020,14 +3050,14 @@ fn test_bitv_clone() {
 
 
 #[cfg(test)]
-mod bitv_set_bench {
+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::{Bitv, BitvSet};
+    use super::{BitVec, BitSet};
 
     static BENCH_BITS : usize = 1 << 14;
 
@@ -3037,36 +3067,36 @@ fn rng() -> rand::IsaacRng {
     }
 
     #[bench]
-    fn bench_bitvset_small(b: &mut Bencher) {
+    fn bench_bit_vecset_small(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = BitvSet::new();
+        let mut bit_vec = BitSet::new();
         b.iter(|| {
             for _ in 0..100 {
-                bitv.insert((r.next_u32() as usize) % u32::BITS);
+                bit_vec.insert((r.next_u32() as usize) % u32::BITS);
             }
-            black_box(&bitv);
+            black_box(&bit_vec);
         });
     }
 
     #[bench]
-    fn bench_bitvset_big(b: &mut Bencher) {
+    fn bench_bit_vecset_big(b: &mut Bencher) {
         let mut r = rng();
-        let mut bitv = BitvSet::new();
+        let mut bit_vec = BitSet::new();
         b.iter(|| {
             for _ in 0..100 {
-                bitv.insert((r.next_u32() as usize) % BENCH_BITS);
+                bit_vec.insert((r.next_u32() as usize) % BENCH_BITS);
             }
-            black_box(&bitv);
+            black_box(&bit_vec);
         });
     }
 
     #[bench]
-    fn bench_bitvset_iter(b: &mut Bencher) {
-        let bitv = BitvSet::from_bitv(Bitv::from_fn(BENCH_BITS,
+    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 &bitv {
+            for idx in &bit_vec {
                 sum += idx as usize;
             }
             sum
diff --git a/src/libcollections/borrow.rs b/src/libcollections/borrow.rs
new file mode 100644 (file)
index 0000000..901d7a7
--- /dev/null
@@ -0,0 +1,316 @@
+// 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 {
+    /// 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 {
+        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 {
+    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 {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Ord for Cow<'a, B> where B: Ord + ToOwned {
+    #[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,
+{
+    #[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,
+{
+    #[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")]
+#[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]
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        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
+    }
+}
diff --git a/src/libcollections/borrow_stage0.rs b/src/libcollections/borrow_stage0.rs
new file mode 100644 (file)
index 0000000..c1d74b1
--- /dev/null
@@ -0,0 +1,313 @@
+// 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 747211e923859df6d1fbab7b13bfb3716f56afa9..7823f536c7a213a8f5f3b2b8e0c7a6a6fad81c73 100644 (file)
@@ -19,7 +19,6 @@
 
 use core::prelude::*;
 
-use core::borrow::BorrowFrom;
 use core::cmp::Ordering;
 use core::default::Default;
 use core::fmt::Debug;
@@ -29,7 +28,8 @@
 use core::{iter, fmt, mem};
 use Bound::{self, Included, Excluded, Unbounded};
 
-use ring_buf::RingBuf;
+use borrow::Borrow;
+use vec_deque::VecDeque;
 
 use self::Continuation::{Continue, Finished};
 use self::StackOp::*;
@@ -75,7 +75,7 @@ pub struct BTreeMap<K, V> {
 
 /// An abstract base over-which all other BTree iterators are built.
 struct AbsIter<T> {
-    traversals: RingBuf<T>,
+    traversals: VecDeque<T>,
     size: usize,
 }
 
@@ -208,7 +208,7 @@ pub fn clear(&mut self) {
     /// assert_eq!(map.get(&2), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V> where Q: BorrowFrom<K> + Ord {
+    pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V> where K: Borrow<Q>, Q: Ord {
         let mut cur_node = &self.root;
         loop {
             match Node::search(cur_node, key) {
@@ -240,7 +240,7 @@ pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V> where Q: BorrowFrom<K> + Ord
     /// assert_eq!(map.contains_key(&2), false);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool where Q: BorrowFrom<K> + Ord {
+    pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool where K: Borrow<Q>, Q: Ord {
         self.get(key).is_some()
     }
 
@@ -264,7 +264,7 @@ pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool where Q: BorrowFrom<K> +
     /// ```
     // See `get` for implementation notes, this is basically a copy-paste with mut's added
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V> where Q: BorrowFrom<K> + Ord {
+    pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V> where K: Borrow<Q>, Q: Ord {
         // temp_node is a Borrowck hack for having a mutable value outlive a loop iteration
         let mut temp_node = &mut self.root;
         loop {
@@ -434,7 +434,7 @@ pub fn insert(&mut self, mut key: K, mut value: V) -> Option<V> {
     /// assert_eq!(map.remove(&1), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V> where Q: BorrowFrom<K> + Ord {
+    pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V> where K: Borrow<Q>, Q: Ord {
         // See `swap` for a more thorough description of the stuff going on in here
         let mut stack = stack::PartialSearchStack::new(self);
         loop {
@@ -512,13 +512,22 @@ mod stack {
     use super::super::node::handle;
     use vec::Vec;
 
+    struct InvariantLifetime<'id>(
+        marker::PhantomData<::core::cell::Cell<&'id ()>>);
+
+    impl<'id> InvariantLifetime<'id> {
+        fn new() -> InvariantLifetime<'id> {
+            InvariantLifetime(marker::PhantomData)
+        }
+    }
+
     /// A generic mutable reference, identical to `&mut` except for the fact that its lifetime
     /// parameter is invariant. This means that wherever an `IdRef` is expected, only an `IdRef`
     /// with the exact requested lifetime can be used. This is in contrast to normal references,
     /// where `&'static` can be used in any function expecting any lifetime reference.
     pub struct IdRef<'id, T: 'id> {
         inner: &'id mut T,
-        marker: marker::InvariantLifetime<'id>
+        _marker: InvariantLifetime<'id>,
     }
 
     impl<'id, T> Deref for IdRef<'id, T> {
@@ -560,7 +569,7 @@ pub struct SearchStack<'a, K:'a, V:'a, Type, NodeType> {
     pub struct Pusher<'id, 'a, K:'a, V:'a> {
         map: &'a mut BTreeMap<K, V>,
         stack: Stack<K, V>,
-        marker: marker::InvariantLifetime<'id>
+        _marker: InvariantLifetime<'id>,
     }
 
     impl<'a, K, V> PartialSearchStack<'a, K, V> {
@@ -595,11 +604,11 @@ pub fn with<T, F: for<'id> FnOnce(Pusher<'id, 'a, K, V>,
             let pusher = Pusher {
                 map: self.map,
                 stack: self.stack,
-                marker: marker::InvariantLifetime
+                _marker: InvariantLifetime::new(),
             };
             let node = IdRef {
                 inner: unsafe { &mut *self.next },
-                marker: marker::InvariantLifetime
+                _marker: InvariantLifetime::new(),
             };
 
             closure(pusher, node)
@@ -826,7 +835,7 @@ pub fn insert(mut self, key: K, val: V) -> &'a mut V {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Ord, V> FromIterator<(K, V)> for BTreeMap<K, V> {
-    fn from_iter<T: Iterator<Item=(K, V)>>(iter: T) -> BTreeMap<K, V> {
+    fn from_iter<T: IntoIterator<Item=(K, V)>>(iter: T) -> BTreeMap<K, V> {
         let mut map = BTreeMap::new();
         map.extend(iter);
         map
@@ -836,13 +845,14 @@ fn from_iter<T: Iterator<Item=(K, V)>>(iter: T) -> BTreeMap<K, V> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Ord, V> Extend<(K, V)> for BTreeMap<K, V> {
     #[inline]
-    fn extend<T: Iterator<Item=(K, V)>>(&mut self, iter: T) {
+    fn extend<T: IntoIterator<Item=(K, V)>>(&mut self, iter: T) {
         for (k, v) in iter {
             self.insert(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) {
@@ -851,6 +861,15 @@ fn hash(&self, state: &mut S) {
         }
     }
 }
+#[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) {
+        for elt in self {
+            elt.hash(state);
+        }
+    }
+}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Ord, V> Default for BTreeMap<K, V> {
@@ -903,7 +922,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Ord, Q: ?Sized, V> Index<Q> for BTreeMap<K, V>
-    where Q: BorrowFrom<K> + Ord
+    where K: Borrow<Q>, Q: Ord
 {
     type Output = V;
 
@@ -914,7 +933,7 @@ fn index(&self, key: &Q) -> &V {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Ord, Q: ?Sized, V> IndexMut<Q> for BTreeMap<K, V>
-    where Q: BorrowFrom<K> + Ord
+    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")
@@ -1189,7 +1208,7 @@ impl<K, V> BTreeMap<K, V> {
     pub fn iter(&self) -> Iter<K, V> {
         let len = self.len();
         // NB. The initial capacity for ringbuf is large enough to avoid reallocs in many cases.
-        let mut lca = RingBuf::new();
+        let mut lca = VecDeque::new();
         lca.push_back(Traverse::traverse(&self.root));
         Iter {
             inner: AbsIter {
@@ -1221,7 +1240,7 @@ pub fn iter(&self) -> Iter<K, V> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter_mut(&mut self) -> IterMut<K, V> {
         let len = self.len();
-        let mut lca = RingBuf::new();
+        let mut lca = VecDeque::new();
         lca.push_back(Traverse::traverse(&mut self.root));
         IterMut {
             inner: AbsIter {
@@ -1250,7 +1269,7 @@ pub fn iter_mut(&mut self) -> IterMut<K, V> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_iter(self) -> IntoIter<K, V> {
         let len = self.len();
-        let mut lca = RingBuf::new();
+        let mut lca = VecDeque::new();
         lca.push_back(Traverse::traverse(self.root));
         IntoIter {
             inner: AbsIter {
@@ -1342,7 +1361,7 @@ macro_rules! range_impl {
             // A deque that encodes two search paths containing (left-to-right):
             // a series of truncated-from-the-left iterators, the LCA's doubly-truncated iterator,
             // and a series of truncated-from-the-right iterators.
-            let mut traversals = RingBuf::new();
+            let mut traversals = VecDeque::new();
             let (root, min, max) = ($root, $min, $max);
 
             let mut leftmost = None;
index 24523d4dcc9d327c57edba07739f1390a56c9ab8..f0fc12da7275e000d814d796db75a0f58c2a48f2 100644 (file)
 
 use core::prelude::*;
 
-use core::borrow::BorrowFrom;
 use core::cmp::Ordering::{Greater, Less, Equal};
 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 alloc::heap;
+use alloc::heap::{self, EMPTY};
+
+use borrow::Borrow;
 
 /// Represents the result of an Insertion: either the item fit, or the node had to split
 pub enum InsertionResult<K, V> {
@@ -57,8 +59,8 @@ pub struct Node<K, V> {
     keys: Unique<K>,
     vals: Unique<V>,
 
-    // In leaf nodes, this will be null, and no space will be allocated for edges.
-    edges: Unique<Node<K, V>>,
+    // In leaf nodes, this will be None, and no space will be allocated for edges.
+    edges: Option<Unique<Node<K, V>>>,
 
     // At any given time, there will be `_len` keys, `_len` values, and (in an internal node)
     // `_len + 1` edges. In a leaf node, there will never be any edges.
@@ -278,8 +280,11 @@ fn drop(&mut self) {
 #[unsafe_destructor]
 impl<K, V> Drop for Node<K, V> {
     fn drop(&mut self) {
-        if self.keys.ptr.is_null() {
-            // We have already cleaned up this node.
+        if self.keys.is_null() {
+            // Since we have #[unsafe_no_drop_flag], we have to watch
+            // out for a null value being stored in self.keys. (Using
+            // null is technically a violation of the `Unique`
+            // requirements, though.)
             return;
         }
 
@@ -292,7 +297,7 @@ fn drop(&mut self) {
             self.destroy();
         }
 
-        self.keys.ptr = ptr::null_mut();
+        self.keys = unsafe { Unique::new(0 as *mut K) };
     }
 }
 
@@ -308,9 +313,9 @@ unsafe fn new_internal(capacity: usize) -> Node<K, V> {
         let (vals_offset, edges_offset) = calculate_offsets_generic::<K, V>(capacity, false);
 
         Node {
-            keys: Unique(buffer as *mut K),
-            vals: Unique(buffer.offset(vals_offset as isize) as *mut V),
-            edges: Unique(buffer.offset(edges_offset as isize) as *mut Node<K, V>),
+            keys: Unique::new(buffer as *mut K),
+            vals: Unique::new(buffer.offset(vals_offset as isize) as *mut V),
+            edges: Some(Unique::new(buffer.offset(edges_offset as isize) as *mut Node<K, V>)),
             _len: 0,
             _capacity: capacity,
         }
@@ -326,9 +331,9 @@ fn new_leaf(capacity: usize) -> Node<K, V> {
         let (vals_offset, _) = calculate_offsets_generic::<K, V>(capacity, true);
 
         Node {
-            keys: Unique(buffer as *mut K),
-            vals: Unique(unsafe { buffer.offset(vals_offset as isize) as *mut V }),
-            edges: Unique(ptr::null_mut()),
+            keys: unsafe { Unique::new(buffer as *mut K) },
+            vals: unsafe { Unique::new(buffer.offset(vals_offset as isize) as *mut V) },
+            edges: None,
             _len: 0,
             _capacity: capacity,
         }
@@ -337,18 +342,18 @@ fn new_leaf(capacity: usize) -> Node<K, V> {
     unsafe fn destroy(&mut self) {
         let (alignment, size) =
                 calculate_allocation_generic::<K, V>(self.capacity(), self.is_leaf());
-        heap::deallocate(self.keys.ptr as *mut u8, size, alignment);
+        heap::deallocate(*self.keys as *mut u8, size, alignment);
     }
 
     #[inline]
     pub fn as_slices<'a>(&'a self) -> (&'a [K], &'a [V]) {
         unsafe {(
             mem::transmute(raw::Slice {
-                data: self.keys.ptr,
+                data: *self.keys as *const K,
                 len: self.len()
             }),
             mem::transmute(raw::Slice {
-                data: self.vals.ptr,
+                data: *self.vals as *const V,
                 len: self.len()
             })
         )}
@@ -367,8 +372,12 @@ pub fn as_slices_internal<'b>(&'b self) -> NodeSlice<'b, K, V> {
             &[]
         } else {
             unsafe {
+                let data = match self.edges {
+                    None => heap::EMPTY as *const Node<K,V>,
+                    Some(ref p) => **p as *const Node<K,V>,
+                };
                 mem::transmute(raw::Slice {
-                    data: self.edges.ptr,
+                    data: data,
                     len: self.len() + 1
                 })
             }
@@ -524,7 +533,8 @@ fn clone(&self) -> Node<K, V> {
 #[derive(Copy)]
 pub struct Handle<NodeRef, Type, NodeType> {
     node: NodeRef,
-    index: usize
+    index: usize,
+    marker: PhantomData<(Type, NodeType)>,
 }
 
 pub mod handle {
@@ -543,13 +553,13 @@ impl<K: Ord, V> Node<K, V> {
     /// `Found` will be yielded with the matching index. If it doesn't find an exact match,
     /// `GoDown` will be yielded with the index of the subtree the key must lie in.
     pub fn search<Q: ?Sized, NodeRef: Deref<Target=Node<K, V>>>(node: NodeRef, key: &Q)
-                  -> SearchResult<NodeRef> where Q: BorrowFrom<K> + Ord {
+                  -> SearchResult<NodeRef> where K: Borrow<Q>, Q: Ord {
         // FIXME(Gankro): Tune when to search linear or binary based on B (and maybe K/V).
         // For the B configured as of this writing (B = 6), binary search was *significantly*
         // worse for usizes.
         match node.as_slices_internal().search_linear(key) {
-            (index, true) => Found(Handle { node: node, index: index }),
-            (index, false) => GoDown(Handle { node: node, index: index }),
+            (index, true) => Found(Handle { node: node, index: index, marker: PhantomData }),
+            (index, false) => GoDown(Handle { node: node, index: index, marker: PhantomData }),
         }
     }
 }
@@ -586,7 +596,7 @@ pub fn capacity(&self) -> usize {
 
     /// If the node has any children
     pub fn is_leaf(&self) -> bool {
-        self.edges.ptr.is_null()
+        self.edges.is_none()
     }
 
     /// if the node has too few elements
@@ -618,7 +628,8 @@ impl<K, V, NodeRef, Type, NodeType> Handle<NodeRef, Type, NodeType> where
     pub fn as_raw(&mut self) -> Handle<*mut Node<K, V>, Type, NodeType> {
         Handle {
             node: &mut *self.node as *mut _,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 }
@@ -630,7 +641,8 @@ impl<K, V, Type, NodeType> Handle<*mut Node<K, V>, Type, NodeType> {
     pub unsafe fn from_raw<'a>(&'a self) -> Handle<&'a Node<K, V>, Type, NodeType> {
         Handle {
             node: &*self.node,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 
@@ -640,7 +652,8 @@ pub unsafe fn from_raw<'a>(&'a self) -> Handle<&'a Node<K, V>, Type, NodeType> {
     pub unsafe fn from_raw_mut<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, Type, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 }
@@ -688,12 +701,14 @@ pub fn force(self) -> ForceResult<NodeRef, Type> {
         if self.node.is_leaf() {
             Leaf(Handle {
                 node: self.node,
-                index: self.index
+                index: self.index,
+                marker: PhantomData,
             })
         } else {
             Internal(Handle {
                 node: self.node,
-                index: self.index
+                index: self.index,
+                marker: PhantomData,
             })
         }
     }
@@ -826,7 +841,8 @@ impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::Edge, NodeType> where
     unsafe fn left_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::KV, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index - 1
+            index: self.index - 1,
+            marker: PhantomData,
         }
     }
 
@@ -836,7 +852,8 @@ unsafe fn left_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::KV, No
     unsafe fn right_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::KV, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 }
@@ -876,7 +893,8 @@ pub fn into_kv_mut(self) -> (&'a mut K, &'a mut V) {
     pub fn into_left_edge(self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 }
@@ -926,7 +944,8 @@ impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::KV, NodeType> where
     pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 
@@ -935,7 +954,8 @@ pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::Edge, N
     pub fn right_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index + 1
+            index: self.index + 1,
+            marker: PhantomData,
         }
     }
 }
@@ -1044,7 +1064,8 @@ pub fn kv_handle(&mut self, index: usize) -> Handle<&mut Node<K, V>, handle::KV,
         debug_assert!(index < self.len(), "kv_handle index out of bounds");
         Handle {
             node: self,
-            index: index
+            index: index,
+            marker: PhantomData,
         }
     }
 
@@ -1064,7 +1085,7 @@ pub fn into_iter(self) -> MoveTraversal<K, V> {
                     vals: RawItems::from_slice(self.vals()),
                     edges: RawItems::from_slice(self.edges()),
 
-                    ptr: self.keys.ptr as *mut u8,
+                    ptr: *self.keys as *mut u8,
                     capacity: self.capacity(),
                     is_leaf: self.is_leaf()
                 },
@@ -1491,9 +1512,9 @@ macro_rules! node_slice_impl {
         impl<'a, K: Ord + 'a, V: 'a> $NodeSlice<'a, K, V> {
             /// Performs linear search in a slice. Returns a tuple of (index, is_exact_match).
             fn search_linear<Q: ?Sized>(&self, key: &Q) -> (usize, bool)
-                    where Q: BorrowFrom<K> + Ord {
+                    where K: Borrow<Q>, Q: Ord {
                 for (i, k) in self.keys.iter().enumerate() {
-                    match key.cmp(BorrowFrom::borrow_from(k)) {
+                    match key.cmp(k.borrow()) {
                         Greater => {},
                         Equal => return (i, true),
                         Less => return (i, false),
index 7ef887b70cc6ca4ec0736f56de47ba4330de0922..929b2f58043035105097de82e38a1702575f2477 100644 (file)
@@ -13,7 +13,6 @@
 
 use core::prelude::*;
 
-use core::borrow::BorrowFrom;
 use core::cmp::Ordering::{self, Less, Greater, Equal};
 use core::default::Default;
 use core::fmt::Debug;
@@ -21,6 +20,7 @@
 use core::iter::{Peekable, Map, FromIterator, IntoIterator};
 use core::ops::{BitOr, BitAnd, BitXor, Sub};
 
+use borrow::Borrow;
 use btree_map::{BTreeMap, Keys};
 use Bound;
 
@@ -336,7 +336,7 @@ pub fn clear(&mut self) {
     /// assert_eq!(set.contains(&4), false);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool where Q: BorrowFrom<T> + Ord {
+    pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool where T: Borrow<Q>, Q: Ord {
         self.map.contains_key(value)
     }
 
@@ -466,14 +466,14 @@ pub fn insert(&mut self, value: T) -> bool {
     /// assert_eq!(set.remove(&2), false);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool where Q: BorrowFrom<T> + Ord {
+    pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool where T: Borrow<Q>, Q: Ord {
         self.map.remove(value).is_some()
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Ord> FromIterator<T> for BTreeSet<T> {
-    fn from_iter<Iter: Iterator<Item=T>>(iter: Iter) -> BTreeSet<T> {
+    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> BTreeSet<T> {
         let mut set = BTreeSet::new();
         set.extend(iter);
         set
@@ -503,7 +503,7 @@ fn into_iter(self) -> Iter<'a, T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Ord> Extend<T> for BTreeSet<T> {
     #[inline]
-    fn extend<Iter: Iterator<Item=T>>(&mut self, iter: Iter) {
+    fn extend<Iter: IntoIterator<Item=T>>(&mut self, iter: Iter) {
         for elem in iter {
             self.insert(elem);
         }
diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs
deleted file mode 100644 (file)
index eb1bf93..0000000
+++ /dev/null
@@ -1,1505 +0,0 @@
-// 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.
-
-//! A doubly-linked list with owned nodes.
-//!
-//! The `DList` allows pushing and popping elements at either end and is thus
-//! efficiently usable as a double-ended queue.
-
-// DList is constructed like a singly-linked list over the field `next`.
-// including the last link being None; each Node owns its `next` field.
-//
-// Backlinks over DList::prev are raw pointers that form a full chain in
-// the reverse direction.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use core::prelude::*;
-
-use alloc::boxed::Box;
-use core::cmp::Ordering;
-use core::default::Default;
-use core::fmt;
-use core::hash::{Writer, Hasher, Hash};
-use core::iter::{self, FromIterator, IntoIterator};
-use core::mem;
-use core::ptr;
-
-/// A doubly-linked list.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct DList<T> {
-    length: usize,
-    list_head: Link<T>,
-    list_tail: Rawlink<Node<T>>,
-}
-
-type Link<T> = Option<Box<Node<T>>>;
-
-struct Rawlink<T> {
-    p: *mut 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> {}
-
-struct Node<T> {
-    next: Link<T>,
-    prev: Rawlink<Node<T>>,
-    value: T,
-}
-
-/// An iterator over references to the items of a `DList`.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Iter<'a, T:'a> {
-    head: &'a Link<T>,
-    tail: Rawlink<Node<T>>,
-    nelem: usize,
-}
-
-// FIXME #19839: deriving is too aggressive on the bounds (T doesn't need to be Clone).
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> Clone for Iter<'a, T> {
-    fn clone(&self) -> Iter<'a, T> {
-        Iter {
-            head: self.head.clone(),
-            tail: self.tail,
-            nelem: self.nelem,
-        }
-    }
-}
-
-/// An iterator over mutable references to the items of a `DList`.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct IterMut<'a, T:'a> {
-    list: &'a mut DList<T>,
-    head: Rawlink<Node<T>>,
-    tail: Rawlink<Node<T>>,
-    nelem: usize,
-}
-
-/// An iterator over mutable references to the items of a `DList`.
-#[derive(Clone)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct IntoIter<T> {
-    list: DList<T>
-}
-
-/// Rawlink is a type like Option<T> but for holding a raw pointer
-impl<T> Rawlink<T> {
-    /// Like Option::None for Rawlink
-    fn none() -> Rawlink<T> {
-        Rawlink{p: ptr::null_mut()}
-    }
-
-    /// Like Option::Some for Rawlink
-    fn some(n: &mut T) -> Rawlink<T> {
-        Rawlink{p: n}
-    }
-
-    /// Convert the `Rawlink` into an Option value
-    fn resolve_immut<'a>(&self) -> Option<&'a T> {
-        unsafe {
-            mem::transmute(self.p.as_ref())
-        }
-    }
-
-    /// Convert the `Rawlink` into an Option value
-    fn resolve<'a>(&mut self) -> Option<&'a mut T> {
-        if self.p.is_null() {
-            None
-        } else {
-            Some(unsafe { mem::transmute(self.p) })
-        }
-    }
-
-    /// Return the `Rawlink` and replace with `Rawlink::none()`
-    fn take(&mut self) -> Rawlink<T> {
-        mem::replace(self, Rawlink::none())
-    }
-}
-
-impl<T> Clone for Rawlink<T> {
-    #[inline]
-    fn clone(&self) -> Rawlink<T> {
-        Rawlink{p: self.p}
-    }
-}
-
-impl<T> Node<T> {
-    fn new(v: T) -> Node<T> {
-        Node{value: v, next: None, prev: Rawlink::none()}
-    }
-}
-
-/// Set the .prev field on `next`, then return `Some(next)`
-fn link_with_prev<T>(mut next: Box<Node<T>>, prev: Rawlink<Node<T>>)
-                  -> Link<T> {
-    next.prev = prev;
-    Some(next)
-}
-
-// private methods
-impl<T> DList<T> {
-    /// Add a Node first in the list
-    #[inline]
-    fn push_front_node(&mut self, mut new_head: Box<Node<T>>) {
-        match self.list_head {
-            None => {
-                self.list_tail = Rawlink::some(&mut *new_head);
-                self.list_head = link_with_prev(new_head, Rawlink::none());
-            }
-            Some(ref mut head) => {
-                new_head.prev = Rawlink::none();
-                head.prev = Rawlink::some(&mut *new_head);
-                mem::swap(head, &mut new_head);
-                head.next = Some(new_head);
-            }
-        }
-        self.length += 1;
-    }
-
-    /// Remove the first Node and return it, or None if the list is empty
-    #[inline]
-    fn pop_front_node(&mut self) -> Option<Box<Node<T>>> {
-        self.list_head.take().map(|mut front_node| {
-            self.length -= 1;
-            match front_node.next.take() {
-                Some(node) => self.list_head = link_with_prev(node, Rawlink::none()),
-                None => self.list_tail = Rawlink::none()
-            }
-            front_node
-        })
-    }
-
-    /// Add a Node last in the list
-    #[inline]
-    fn push_back_node(&mut self, mut new_tail: Box<Node<T>>) {
-        match self.list_tail.resolve() {
-            None => return self.push_front_node(new_tail),
-            Some(tail) => {
-                self.list_tail = Rawlink::some(&mut *new_tail);
-                tail.next = link_with_prev(new_tail, Rawlink::some(tail));
-            }
-        }
-        self.length += 1;
-    }
-
-    /// Remove the last Node and return it, or None if the list is empty
-    #[inline]
-    fn pop_back_node(&mut self) -> Option<Box<Node<T>>> {
-        self.list_tail.resolve().map_or(None, |tail| {
-            self.length -= 1;
-            self.list_tail = tail.prev;
-            match tail.prev.resolve() {
-                None => self.list_head.take(),
-                Some(tail_prev) => tail_prev.next.take()
-            }
-        })
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for DList<T> {
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn default() -> DList<T> { DList::new() }
-}
-
-impl<T> DList<T> {
-    /// Creates an empty `DList`.
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new() -> DList<T> {
-        DList{list_head: None, list_tail: Rawlink::none(), length: 0}
-    }
-
-    /// Moves all elements from `other` to the end of the list.
-    ///
-    /// This reuses all the nodes from `other` and moves them into `self`. After
-    /// this operation, `other` becomes empty.
-    ///
-    /// This operation should compute in O(1) time and O(1) memory.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::DList;
-    ///
-    /// let mut a = DList::new();
-    /// let mut b = DList::new();
-    /// a.push_back(1);
-    /// a.push_back(2);
-    /// b.push_back(3);
-    /// b.push_back(4);
-    ///
-    /// a.append(&mut b);
-    ///
-    /// for e in a.iter() {
-    ///     println!("{}", e); // prints 1, then 2, then 3, then 4
-    /// }
-    /// println!("{}", b.len()); // prints 0
-    /// ```
-    pub fn append(&mut self, other: &mut DList<T>) {
-        match self.list_tail.resolve() {
-            None => {
-                self.length = other.length;
-                self.list_head = other.list_head.take();
-                self.list_tail = other.list_tail.take();
-            },
-            Some(tail) => {
-                // Carefully empty `other`.
-                let o_tail = other.list_tail.take();
-                let o_length = other.length;
-                match other.list_head.take() {
-                    None => return,
-                    Some(node) => {
-                        tail.next = link_with_prev(node, self.list_tail);
-                        self.list_tail = o_tail;
-                        self.length += o_length;
-                    }
-                }
-            }
-        }
-        other.length = 0;
-    }
-
-    /// Provides a forward iterator.
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn iter(&self) -> Iter<T> {
-        Iter{nelem: self.len(), head: &self.list_head, tail: self.list_tail}
-    }
-
-    /// Provides a forward iterator with mutable references.
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn iter_mut(&mut self) -> IterMut<T> {
-        let head_raw = match self.list_head {
-            Some(ref mut h) => Rawlink::some(&mut **h),
-            None => Rawlink::none(),
-        };
-        IterMut{
-            nelem: self.len(),
-            head: head_raw,
-            tail: self.list_tail,
-            list: self
-        }
-    }
-
-    /// Consumes the list into an iterator yielding elements by value.
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_iter(self) -> IntoIter<T> {
-        IntoIter{list: self}
-    }
-
-    /// Returns `true` if the `DList` is empty.
-    ///
-    /// This operation should compute in O(1) time.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::DList;
-    ///
-    /// let mut dl = DList::new();
-    /// assert!(dl.is_empty());
-    ///
-    /// dl.push_front("foo");
-    /// assert!(!dl.is_empty());
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_empty(&self) -> bool {
-        self.list_head.is_none()
-    }
-
-    /// Returns the length of the `DList`.
-    ///
-    /// This operation should compute in O(1) time.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::DList;
-    ///
-    /// let mut dl = DList::new();
-    ///
-    /// dl.push_front(2);
-    /// assert_eq!(dl.len(), 1);
-    ///
-    /// dl.push_front(1);
-    /// assert_eq!(dl.len(), 2);
-    ///
-    /// dl.push_back(3);
-    /// assert_eq!(dl.len(), 3);
-    ///
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn len(&self) -> usize {
-        self.length
-    }
-
-    /// Removes all elements from the `DList`.
-    ///
-    /// This operation should compute in O(n) time.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::DList;
-    ///
-    /// let mut dl = DList::new();
-    ///
-    /// dl.push_front(2);
-    /// dl.push_front(1);
-    /// assert_eq!(dl.len(), 2);
-    /// assert_eq!(dl.front(), Some(&1));
-    ///
-    /// dl.clear();
-    /// assert_eq!(dl.len(), 0);
-    /// assert_eq!(dl.front(), None);
-    ///
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn clear(&mut self) {
-        *self = DList::new()
-    }
-
-    /// Provides a reference to the front element, or `None` if the list is
-    /// empty.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::DList;
-    ///
-    /// let mut dl = DList::new();
-    /// assert_eq!(dl.front(), None);
-    ///
-    /// dl.push_front(1);
-    /// assert_eq!(dl.front(), Some(&1));
-    ///
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn front(&self) -> Option<&T> {
-        self.list_head.as_ref().map(|head| &head.value)
-    }
-
-    /// Provides a mutable reference to the front element, or `None` if the list
-    /// is empty.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::DList;
-    ///
-    /// let mut dl = DList::new();
-    /// assert_eq!(dl.front(), None);
-    ///
-    /// dl.push_front(1);
-    /// assert_eq!(dl.front(), Some(&1));
-    ///
-    /// match dl.front_mut() {
-    ///     None => {},
-    ///     Some(x) => *x = 5,
-    /// }
-    /// assert_eq!(dl.front(), Some(&5));
-    ///
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn front_mut(&mut self) -> Option<&mut T> {
-        self.list_head.as_mut().map(|head| &mut head.value)
-    }
-
-    /// Provides a reference to the back element, or `None` if the list is
-    /// empty.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::DList;
-    ///
-    /// let mut dl = DList::new();
-    /// assert_eq!(dl.back(), None);
-    ///
-    /// dl.push_back(1);
-    /// assert_eq!(dl.back(), Some(&1));
-    ///
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn back(&self) -> Option<&T> {
-        self.list_tail.resolve_immut().as_ref().map(|tail| &tail.value)
-    }
-
-    /// Provides a mutable reference to the back element, or `None` if the list
-    /// is empty.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::DList;
-    ///
-    /// let mut dl = DList::new();
-    /// assert_eq!(dl.back(), None);
-    ///
-    /// dl.push_back(1);
-    /// assert_eq!(dl.back(), Some(&1));
-    ///
-    /// match dl.back_mut() {
-    ///     None => {},
-    ///     Some(x) => *x = 5,
-    /// }
-    /// assert_eq!(dl.back(), Some(&5));
-    ///
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn back_mut(&mut self) -> Option<&mut T> {
-        self.list_tail.resolve().map(|tail| &mut tail.value)
-    }
-
-    /// Adds an element first in the list.
-    ///
-    /// This operation should compute in O(1) time.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::DList;
-    ///
-    /// let mut dl = DList::new();
-    ///
-    /// dl.push_front(2);
-    /// assert_eq!(dl.front().unwrap(), &2);
-    ///
-    /// dl.push_front(1);
-    /// assert_eq!(dl.front().unwrap(), &1);
-    ///
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn push_front(&mut self, elt: T) {
-        self.push_front_node(box Node::new(elt))
-    }
-
-    /// Removes the first element and returns it, or `None` if the list is
-    /// empty.
-    ///
-    /// This operation should compute in O(1) time.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::DList;
-    ///
-    /// let mut d = DList::new();
-    /// assert_eq!(d.pop_front(), None);
-    ///
-    /// d.push_front(1);
-    /// d.push_front(3);
-    /// assert_eq!(d.pop_front(), Some(3));
-    /// assert_eq!(d.pop_front(), Some(1));
-    /// assert_eq!(d.pop_front(), None);
-    ///
-    /// ```
-    ///
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn pop_front(&mut self) -> Option<T> {
-        self.pop_front_node().map(|box Node{value, ..}| value)
-    }
-
-    /// Appends an element to the back of a list
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::DList;
-    ///
-    /// let mut d = DList::new();
-    /// d.push_back(1);
-    /// d.push_back(3);
-    /// assert_eq!(3, *d.back().unwrap());
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn push_back(&mut self, elt: T) {
-        self.push_back_node(box Node::new(elt))
-    }
-
-    /// Removes the last element from a list and returns it, or `None` if
-    /// it is empty.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::DList;
-    ///
-    /// let mut d = DList::new();
-    /// assert_eq!(d.pop_back(), None);
-    /// d.push_back(1);
-    /// d.push_back(3);
-    /// assert_eq!(d.pop_back(), Some(3));
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn pop_back(&mut self) -> Option<T> {
-        self.pop_back_node().map(|box Node{value, ..}| value)
-    }
-
-    /// Splits the list into two at the given index. Returns everything after the given index,
-    /// including the index.
-    ///
-    /// # Panics
-    ///
-    /// Panics if `at > len`.
-    ///
-    /// This operation should compute in O(n) time.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::DList;
-    ///
-    /// let mut d = DList::new();
-    ///
-    /// d.push_front(1);
-    /// d.push_front(2);
-    /// d.push_front(3);
-    ///
-    /// let mut splitted = d.split_off(2);
-    ///
-    /// assert_eq!(splitted.pop_front(), Some(1));
-    /// assert_eq!(splitted.pop_front(), None);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn split_off(&mut self, at: usize) -> DList<T> {
-        let len = self.len();
-        assert!(at <= len, "Cannot split off at a nonexistent index");
-        if at == 0 {
-            return mem::replace(self, DList::new());
-        } else if at == len {
-            return DList::new();
-        }
-
-        // Below, we iterate towards the `i-1`th node, either from the start or the end,
-        // depending on which would be faster.
-        let mut split_node = if at - 1 <= len - 1 - (at - 1) {
-            let mut iter = self.iter_mut();
-            // instead of skipping using .skip() (which creates a new struct),
-            // we skip manually so we can access the head field without
-            // depending on implementation details of Skip
-            for _ in 0..at - 1 {
-                iter.next();
-            }
-            iter.head
-        }  else {
-            // better off starting from the end
-            let mut iter = self.iter_mut();
-            for _ in 0..len - 1 - (at - 1) {
-                iter.next_back();
-            }
-            iter.tail
-        };
-
-        let mut splitted_list = DList {
-            list_head: None,
-            list_tail: self.list_tail,
-            length: len - at
-        };
-
-        mem::swap(&mut split_node.resolve().unwrap().next, &mut splitted_list.list_head);
-        self.list_tail = split_node;
-        self.length = at;
-
-        splitted_list
-    }
-}
-
-#[unsafe_destructor]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Drop for DList<T> {
-    fn drop(&mut self) {
-        // Dissolve the dlist in backwards direction
-        // Just dropping the list_head can lead to stack exhaustion
-        // when length is >> 1_000_000
-        let mut tail = self.list_tail;
-        loop {
-            match tail.resolve() {
-                None => break,
-                Some(prev) => {
-                    prev.next.take(); // release Box<Node<T>>
-                    tail = prev.prev;
-                }
-            }
-        }
-        self.length = 0;
-        self.list_head = None;
-        self.list_tail = Rawlink::none();
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, A> Iterator for Iter<'a, A> {
-    type Item = &'a A;
-
-    #[inline]
-    fn next(&mut self) -> Option<&'a A> {
-        if self.nelem == 0 {
-            return None;
-        }
-        self.head.as_ref().map(|head| {
-            self.nelem -= 1;
-            self.head = &head.next;
-            &head.value
-        })
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.nelem, Some(self.nelem))
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, A> DoubleEndedIterator for Iter<'a, A> {
-    #[inline]
-    fn next_back(&mut self) -> Option<&'a A> {
-        if self.nelem == 0 {
-            return None;
-        }
-        self.tail.resolve_immut().as_ref().map(|prev| {
-            self.nelem -= 1;
-            self.tail = prev.prev;
-            &prev.value
-        })
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, A> ExactSizeIterator for Iter<'a, A> {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, A> Iterator for IterMut<'a, A> {
-    type Item = &'a mut A;
-    #[inline]
-    fn next(&mut self) -> Option<&'a mut A> {
-        if self.nelem == 0 {
-            return None;
-        }
-        self.head.resolve().map(|next| {
-            self.nelem -= 1;
-            self.head = match next.next {
-                Some(ref mut node) => Rawlink::some(&mut **node),
-                None => Rawlink::none(),
-            };
-            &mut next.value
-        })
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.nelem, Some(self.nelem))
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, A> DoubleEndedIterator for IterMut<'a, A> {
-    #[inline]
-    fn next_back(&mut self) -> Option<&'a mut A> {
-        if self.nelem == 0 {
-            return None;
-        }
-        self.tail.resolve().map(|prev| {
-            self.nelem -= 1;
-            self.tail = prev.prev;
-            &mut prev.value
-        })
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, A> ExactSizeIterator for IterMut<'a, A> {}
-
-// private methods for IterMut
-impl<'a, A> IterMut<'a, A> {
-    fn insert_next_node(&mut self, mut ins_node: Box<Node<A>>) {
-        // Insert before `self.head` so that it is between the
-        // previously yielded element and self.head.
-        //
-        // The inserted node will not appear in further iteration.
-        match self.head.resolve() {
-            None => { self.list.push_back_node(ins_node); }
-            Some(node) => {
-                let prev_node = match node.prev.resolve() {
-                    None => return self.list.push_front_node(ins_node),
-                    Some(prev) => prev,
-                };
-                let node_own = prev_node.next.take().unwrap();
-                ins_node.next = link_with_prev(node_own, Rawlink::some(&mut *ins_node));
-                prev_node.next = link_with_prev(ins_node, Rawlink::some(prev_node));
-                self.list.length += 1;
-            }
-        }
-    }
-}
-
-impl<'a, A> IterMut<'a, A> {
-    /// Inserts `elt` just after the element most recently returned by `.next()`.
-    /// The inserted element does not appear in the iteration.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::DList;
-    ///
-    /// let mut list: DList<_> = vec![1, 3, 4].into_iter().collect();
-    ///
-    /// {
-    ///     let mut it = list.iter_mut();
-    ///     assert_eq!(it.next().unwrap(), &1);
-    ///     // insert `2` after `1`
-    ///     it.insert_next(2);
-    /// }
-    /// {
-    ///     let vec: Vec<_> = list.into_iter().collect();
-    ///     assert_eq!(vec, vec![1, 2, 3, 4]);
-    /// }
-    /// ```
-    #[inline]
-    #[unstable(feature = "collections",
-               reason = "this is probably better handled by a cursor type -- we'll see")]
-    pub fn insert_next(&mut self, elt: A) {
-        self.insert_next_node(box Node::new(elt))
-    }
-
-    /// Provides a reference to the next element, without changing the iterator.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::DList;
-    ///
-    /// let mut list: DList<_> = vec![1, 2, 3].into_iter().collect();
-    ///
-    /// let mut it = list.iter_mut();
-    /// assert_eq!(it.next().unwrap(), &1);
-    /// assert_eq!(it.peek_next().unwrap(), &2);
-    /// // We just peeked at 2, so it was not consumed from the iterator.
-    /// assert_eq!(it.next().unwrap(), &2);
-    /// ```
-    #[inline]
-    #[unstable(feature = "collections",
-               reason = "this is probably better handled by a cursor type -- we'll see")]
-    pub fn peek_next(&mut self) -> Option<&mut A> {
-        if self.nelem == 0 {
-            return None
-        }
-        self.head.resolve().map(|head| &mut head.value)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A> Iterator for IntoIter<A> {
-    type Item = A;
-
-    #[inline]
-    fn next(&mut self) -> Option<A> { self.list.pop_front() }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.list.length, Some(self.list.length))
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A> DoubleEndedIterator for IntoIter<A> {
-    #[inline]
-    fn next_back(&mut self) -> Option<A> { self.list.pop_back() }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A> FromIterator<A> for DList<A> {
-    fn from_iter<T: Iterator<Item=A>>(iterator: T) -> DList<A> {
-        let mut ret = DList::new();
-        ret.extend(iterator);
-        ret
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> IntoIterator for DList<T> {
-    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, T> IntoIterator for &'a DList<T> {
-    type Item = &'a T;
-    type IntoIter = Iter<'a, T>;
-
-    fn into_iter(self) -> Iter<'a, T> {
-        self.iter()
-    }
-}
-
-impl<'a, T> IntoIterator for &'a mut DList<T> {
-    type Item = &'a mut T;
-    type IntoIter = IterMut<'a, T>;
-
-    fn into_iter(mut self) -> IterMut<'a, T> {
-        self.iter_mut()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A> Extend<A> for DList<A> {
-    fn extend<T: Iterator<Item=A>>(&mut self, iterator: T) {
-        for elt in iterator { self.push_back(elt); }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A: PartialEq> PartialEq for DList<A> {
-    fn eq(&self, other: &DList<A>) -> bool {
-        self.len() == other.len() &&
-            iter::order::eq(self.iter(), other.iter())
-    }
-
-    fn ne(&self, other: &DList<A>) -> bool {
-        self.len() != other.len() ||
-            iter::order::ne(self.iter(), other.iter())
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Eq> Eq for DList<A> {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A: PartialOrd> PartialOrd for DList<A> {
-    fn partial_cmp(&self, other: &DList<A>) -> Option<Ordering> {
-        iter::order::partial_cmp(self.iter(), other.iter())
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Ord> Ord for DList<A> {
-    #[inline]
-    fn cmp(&self, other: &DList<A>) -> Ordering {
-        iter::order::cmp(self.iter(), other.iter())
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Clone> Clone for DList<A> {
-    fn clone(&self) -> DList<A> {
-        self.iter().map(|x| x.clone()).collect()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A: fmt::Debug> fmt::Debug for DList<A> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "DList ["));
-
-        for (i, e) in self.iter().enumerate() {
-            if i != 0 { try!(write!(f, ", ")); }
-            try!(write!(f, "{:?}", *e));
-        }
-
-        write!(f, "]")
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<S: Writer + Hasher, A: Hash<S>> Hash<S> for DList<A> {
-    fn hash(&self, state: &mut S) {
-        self.len().hash(state);
-        for elt in self {
-            elt.hash(state);
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use std::rand;
-    use std::hash::{self, SipHasher};
-    use std::thread;
-    use test::Bencher;
-    use test;
-
-    use super::{DList, Node};
-
-    pub fn check_links<T>(list: &DList<T>) {
-        let mut len = 0;
-        let mut last_ptr: Option<&Node<T>> = None;
-        let mut node_ptr: &Node<T>;
-        match list.list_head {
-            None => { assert_eq!(0, list.length); return }
-            Some(ref node) => node_ptr = &**node,
-        }
-        loop {
-            match (last_ptr, node_ptr.prev.resolve_immut()) {
-                (None   , None      ) => {}
-                (None   , _         ) => panic!("prev link for list_head"),
-                (Some(p), Some(pptr)) => {
-                    assert_eq!(p as *const Node<T>, pptr as *const Node<T>);
-                }
-                _ => panic!("prev link is none, not good"),
-            }
-            match node_ptr.next {
-                Some(ref next) => {
-                    last_ptr = Some(node_ptr);
-                    node_ptr = &**next;
-                    len += 1;
-                }
-                None => {
-                    len += 1;
-                    break;
-                }
-            }
-        }
-        assert_eq!(len, list.length);
-    }
-
-    #[test]
-    fn test_basic() {
-        let mut m = DList::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 = DList::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() -> DList<i32> {
-        list_from(&[0,1,2,3,4,5,6])
-    }
-
-    #[cfg(test)]
-    fn list_from<T: Clone>(v: &[T]) -> DList<T> {
-        v.iter().map(|x| (*x).clone()).collect()
-    }
-
-    #[test]
-    fn test_append() {
-        // Empty to empty
-        {
-            let mut m = DList::<i32>::new();
-            let mut n = DList::new();
-            m.append(&mut n);
-            check_links(&m);
-            assert_eq!(m.len(), 0);
-            assert_eq!(n.len(), 0);
-        }
-        // Non-empty to empty
-        {
-            let mut m = DList::new();
-            let mut n = DList::new();
-            n.push_back(2);
-            m.append(&mut n);
-            check_links(&m);
-            assert_eq!(m.len(), 1);
-            assert_eq!(m.pop_back(), Some(2));
-            assert_eq!(n.len(), 0);
-            check_links(&m);
-        }
-        // Empty to non-empty
-        {
-            let mut m = DList::new();
-            let mut n = DList::new();
-            m.push_back(2);
-            m.append(&mut n);
-            check_links(&m);
-            assert_eq!(m.len(), 1);
-            assert_eq!(m.pop_back(), Some(2));
-            check_links(&m);
-        }
-
-        // Non-empty to non-empty
-        let v = vec![1,2,3,4,5];
-        let u = vec![9,8,1,2,3,4,5];
-        let mut m = list_from(&v);
-        let mut n = list_from(&u);
-        m.append(&mut n);
-        check_links(&m);
-        let mut sum = v;
-        sum.push_all(&u);
-        assert_eq!(sum.len(), m.len());
-        for elt in sum {
-            assert_eq!(m.pop_front(), Some(elt))
-        }
-        assert_eq!(n.len(), 0);
-        // let's make sure it's working properly, since we
-        // did some direct changes to private members
-        n.push_back(3);
-        assert_eq!(n.len(), 1);
-        assert_eq!(n.pop_front(), Some(3));
-        check_links(&n);
-    }
-
-    #[test]
-    fn test_split_off() {
-        // singleton
-        {
-            let mut m = DList::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 = DList::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 = DList::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 = DList::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 = DList::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 = DList::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 = DList::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 = DList::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]);
-        let len = m.len();
-        {
-            let mut it = m.iter_mut();
-            it.insert_next(-2);
-            loop {
-                match it.next() {
-                    None => break,
-                    Some(elt) => {
-                        it.insert_next(*elt + 1);
-                        match it.peek_next() {
-                            Some(x) => assert_eq!(*x, *elt + 2),
-                            None => assert_eq!(8, *elt),
-                        }
-                    }
-                }
-            }
-            it.insert_next(0);
-            it.insert_next(1);
-        }
-        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 = DList::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_send() {
-        let n = list_from(&[1,2,3]);
-        thread::spawn(move || {
-            check_links(&n);
-            let a: &[_] = &[&1,&2,&3];
-            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 = DList::new();
-      let mut y = DList::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 {
-            fuzz_test(3);
-            fuzz_test(16);
-            fuzz_test(189);
-        }
-    }
-
-    #[test]
-    fn test_show() {
-        let list: DList<_> = (0..10).collect();
-        assert_eq!(format!("{:?}", list), "DList [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
-
-        let list: DList<_> = vec!["just", "one", "test", "more"].iter().cloned().collect();
-        assert_eq!(format!("{:?}", list), "DList [\"just\", \"one\", \"test\", \"more\"]");
-    }
-
-    #[cfg(test)]
-    fn fuzz_test(sz: i32) {
-        let mut m: DList<_> = DList::new();
-        let mut v = vec![];
-        for i in 0..sz {
-            check_links(&m);
-            let r: u8 = rand::random();
-            match r % 6 {
-                0 => {
-                    m.pop_back();
-                    v.pop();
-                }
-                1 => {
-                    if !v.is_empty() {
-                        m.pop_front();
-                        v.remove(0);
-                    }
-                }
-                2 | 4 =>  {
-                    m.push_front(-i);
-                    v.insert(0, -i);
-                }
-                3 | 5 | _ => {
-                    m.push_back(i);
-                    v.push(i);
-                }
-            }
-        }
-
-        check_links(&m);
-
-        let mut i = 0;
-        for (a, &b) in m.into_iter().zip(v.iter()) {
-            i += 1;
-            assert_eq!(a, b);
-        }
-        assert_eq!(i, v.len());
-    }
-
-    #[bench]
-    fn bench_collect_into(b: &mut test::Bencher) {
-        let v = &[0; 64];
-        b.iter(|| {
-            let _: DList<_> = v.iter().cloned().collect();
-        })
-    }
-
-    #[bench]
-    fn bench_push_front(b: &mut test::Bencher) {
-        let mut m: DList<_> = DList::new();
-        b.iter(|| {
-            m.push_front(0);
-        })
-    }
-
-    #[bench]
-    fn bench_push_back(b: &mut test::Bencher) {
-        let mut m: DList<_> = DList::new();
-        b.iter(|| {
-            m.push_back(0);
-        })
-    }
-
-    #[bench]
-    fn bench_push_back_pop_back(b: &mut test::Bencher) {
-        let mut m: DList<_> = DList::new();
-        b.iter(|| {
-            m.push_back(0);
-            m.pop_back();
-        })
-    }
-
-    #[bench]
-    fn bench_push_front_pop_front(b: &mut test::Bencher) {
-        let mut m: DList<_> = DList::new();
-        b.iter(|| {
-            m.push_front(0);
-            m.pop_front();
-        })
-    }
-
-    #[bench]
-    fn bench_iter(b: &mut test::Bencher) {
-        let v = &[0; 128];
-        let m: DList<_> = 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: DList<_> = 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: DList<_> = 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: DList<_> = v.iter().cloned().collect();
-        b.iter(|| {
-            assert!(m.iter_mut().rev().count() == 128);
-        })
-    }
-}
index d5403ca5d9b195b0e867ad76c2dd945c850b3415..0c95742606083fbe33402ca667d840ed620c406c 100644 (file)
@@ -14,6 +14,7 @@
 //! representation to hold C-like enum variants.
 
 use core::prelude::*;
+use core::marker;
 use core::fmt;
 use core::num::Int;
 use core::iter::{FromIterator, IntoIterator};
@@ -26,7 +27,8 @@
 pub struct EnumSet<E> {
     // We must maintain the invariant that no bits are set
     // for which no variant exists
-    bits: usize
+    bits: usize,
+    marker: marker::PhantomData<E>,
 }
 
 impl<E> Copy for EnumSet<E> {}
@@ -86,7 +88,7 @@ impl<E:CLike> EnumSet<E> {
     #[unstable(feature = "collections",
                reason = "matches collection reform specification, waiting for dust to settle")]
     pub fn new() -> EnumSet<E> {
-        EnumSet {bits: 0}
+        EnumSet {bits: 0, marker: marker::PhantomData}
     }
 
     /// Returns the number of elements in the given `EnumSet`.
@@ -130,12 +132,14 @@ pub fn is_subset(&self, other: &EnumSet<E>) -> bool {
 
     /// Returns the union of both `EnumSets`.
     pub fn union(&self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits | e.bits}
+        EnumSet {bits: self.bits | e.bits,
+                 marker: marker::PhantomData}
     }
 
     /// Returns the intersection of both `EnumSets`.
     pub fn intersection(&self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits & e.bits}
+        EnumSet {bits: self.bits & e.bits,
+                 marker: marker::PhantomData}
     }
 
     /// Adds an enum to the `EnumSet`, and returns `true` if it wasn't there before
@@ -175,7 +179,7 @@ impl<E:CLike> Sub for EnumSet<E> {
     type Output = EnumSet<E>;
 
     fn sub(self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits & !e.bits}
+        EnumSet {bits: self.bits & !e.bits, marker: marker::PhantomData}
     }
 }
 
@@ -183,7 +187,7 @@ impl<E:CLike> BitOr for EnumSet<E> {
     type Output = EnumSet<E>;
 
     fn bitor(self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits | e.bits}
+        EnumSet {bits: self.bits | e.bits, marker: marker::PhantomData}
     }
 }
 
@@ -191,7 +195,7 @@ impl<E:CLike> BitAnd for EnumSet<E> {
     type Output = EnumSet<E>;
 
     fn bitand(self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits & e.bits}
+        EnumSet {bits: self.bits & e.bits, marker: marker::PhantomData}
     }
 }
 
@@ -199,7 +203,7 @@ impl<E:CLike> BitXor for EnumSet<E> {
     type Output = EnumSet<E>;
 
     fn bitxor(self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits ^ e.bits}
+        EnumSet {bits: self.bits ^ e.bits, marker: marker::PhantomData}
     }
 }
 
@@ -207,6 +211,7 @@ fn bitxor(self, e: EnumSet<E>) -> EnumSet<E> {
 pub struct Iter<E> {
     index: usize,
     bits: usize,
+    marker: marker::PhantomData<E>,
 }
 
 // FIXME(#19839) Remove in favor of `#[derive(Clone)]`
@@ -215,13 +220,14 @@ fn clone(&self) -> Iter<E> {
         Iter {
             index: self.index,
             bits: self.bits,
+            marker: marker::PhantomData,
         }
     }
 }
 
 impl<E:CLike> Iter<E> {
     fn new(bits: usize) -> Iter<E> {
-        Iter { index: 0, bits: bits }
+        Iter { index: 0, bits: bits, marker: marker::PhantomData }
     }
 }
 
@@ -250,9 +256,9 @@ fn size_hint(&self) -> (usize, Option<usize>) {
 }
 
 impl<E:CLike> FromIterator<E> for EnumSet<E> {
-    fn from_iter<I:Iterator<Item=E>>(iterator: I) -> EnumSet<E> {
+    fn from_iter<I: IntoIterator<Item=E>>(iter: I) -> EnumSet<E> {
         let mut ret = EnumSet::new();
-        ret.extend(iterator);
+        ret.extend(iter);
         ret
     }
 }
@@ -268,8 +274,8 @@ fn into_iter(self) -> Iter<E> {
 }
 
 impl<E:CLike> Extend<E> for EnumSet<E> {
-    fn extend<I: Iterator<Item=E>>(&mut self, iterator: I) {
-        for element in iterator {
+    fn extend<I: IntoIterator<Item=E>>(&mut self, iter: I) {
+        for element in iter {
             self.insert(element);
         }
     }
index cacbf3bce80f018e80016abe6d3396a407ecd402..6569ab9c05acd768f56d4d4d5d9b9ddd32c65943 100644 (file)
@@ -26,7 +26,6 @@
 #![feature(box_syntax)]
 #![feature(box_patterns)]
 #![feature(core)]
-#![feature(hash)]
 #![feature(staged_api)]
 #![feature(unboxed_closures)]
 #![feature(unicode)]
 #[cfg(test)] #[macro_use] extern crate log;
 
 pub use binary_heap::BinaryHeap;
-pub use bitv::Bitv;
-pub use bitv_set::BitvSet;
+pub use bit_vec::BitVec;
+pub use bit_set::BitSet;
 pub use btree_map::BTreeMap;
 pub use btree_set::BTreeSet;
-pub use dlist::DList;
+pub use linked_list::LinkedList;
 pub use enum_set::EnumSet;
-pub use ring_buf::RingBuf;
+pub use vec_deque::VecDeque;
 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;
 
 pub mod binary_heap;
 mod bit;
 mod btree;
-pub mod dlist;
+pub mod linked_list;
 pub mod enum_set;
 pub mod fmt;
-pub mod ring_buf;
+pub mod vec_deque;
 pub mod slice;
 pub mod str;
 pub mod string;
 pub mod vec;
 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 bitv {
-    pub use bit::{Bitv, Iter};
+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",
            reason = "RFC 509")]
-pub mod bitv_set {
-    pub use bit::{BitvSet, Union, Intersection, Difference, SymmetricDifference};
+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")]
@@ -117,7 +147,6 @@ mod std {
 #[cfg(test)]
 mod prelude {
     // from core.
-    pub use core::borrow::IntoCow;
     pub use core::clone::Clone;
     pub use core::cmp::{PartialEq, Eq, PartialOrd, Ord};
     pub use core::cmp::Ordering::{Less, Equal, Greater};
@@ -143,6 +172,7 @@ mod prelude {
     pub use unicode::char::CharExt;
 
     // from collections.
+    pub use borrow::IntoCow;
     pub use slice::SliceConcatExt;
     pub use string::{String, ToString};
     pub use vec::Vec;
diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs
new file mode 100644 (file)
index 0000000..c142819
--- /dev/null
@@ -0,0 +1,1522 @@
+// 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.
+
+//! A doubly-linked list with owned nodes.
+//!
+//! The `LinkedList` allows pushing and popping elements at either end and is thus
+//! efficiently usable as a double-ended queue.
+
+// LinkedList is constructed like a singly-linked list over the field `next`.
+// including the last link being None; each Node owns its `next` field.
+//
+// Backlinks over LinkedList::prev are raw pointers that form a full chain in
+// the reverse direction.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use core::prelude::*;
+
+use alloc::boxed::Box;
+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> {
+    length: usize,
+    list_head: Link<T>,
+    list_tail: Rawlink<Node<T>>,
+}
+
+type Link<T> = Option<Box<Node<T>>>;
+
+struct Rawlink<T> {
+    p: *mut 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> {}
+
+struct Node<T> {
+    next: Link<T>,
+    prev: Rawlink<Node<T>>,
+    value: T,
+}
+
+/// An iterator over references to the items of a `LinkedList`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Iter<'a, T:'a> {
+    head: &'a Link<T>,
+    tail: Rawlink<Node<T>>,
+    nelem: usize,
+}
+
+// FIXME #19839: deriving is too aggressive on the bounds (T doesn't need to be Clone).
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> Clone for Iter<'a, T> {
+    fn clone(&self) -> Iter<'a, T> {
+        Iter {
+            head: self.head.clone(),
+            tail: self.tail,
+            nelem: self.nelem,
+        }
+    }
+}
+
+/// An iterator over mutable references to the items of a `LinkedList`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct IterMut<'a, T:'a> {
+    list: &'a mut LinkedList<T>,
+    head: Rawlink<Node<T>>,
+    tail: Rawlink<Node<T>>,
+    nelem: usize,
+}
+
+/// An iterator over mutable references to the items of a `LinkedList`.
+#[derive(Clone)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct IntoIter<T> {
+    list: LinkedList<T>
+}
+
+/// Rawlink is a type like Option<T> but for holding a raw pointer
+impl<T> Rawlink<T> {
+    /// Like Option::None for Rawlink
+    fn none() -> Rawlink<T> {
+        Rawlink{p: ptr::null_mut()}
+    }
+
+    /// Like Option::Some for Rawlink
+    fn some(n: &mut T) -> Rawlink<T> {
+        Rawlink{p: n}
+    }
+
+    /// Convert the `Rawlink` into an Option value
+    fn resolve_immut<'a>(&self) -> Option<&'a T> {
+        unsafe {
+            mem::transmute(self.p.as_ref())
+        }
+    }
+
+    /// Convert the `Rawlink` into an Option value
+    fn resolve<'a>(&mut self) -> Option<&'a mut T> {
+        if self.p.is_null() {
+            None
+        } else {
+            Some(unsafe { mem::transmute(self.p) })
+        }
+    }
+
+    /// Return the `Rawlink` and replace with `Rawlink::none()`
+    fn take(&mut self) -> Rawlink<T> {
+        mem::replace(self, Rawlink::none())
+    }
+}
+
+impl<T> Clone for Rawlink<T> {
+    #[inline]
+    fn clone(&self) -> Rawlink<T> {
+        Rawlink{p: self.p}
+    }
+}
+
+impl<T> Node<T> {
+    fn new(v: T) -> Node<T> {
+        Node{value: v, next: None, prev: Rawlink::none()}
+    }
+}
+
+/// Set the .prev field on `next`, then return `Some(next)`
+fn link_with_prev<T>(mut next: Box<Node<T>>, prev: Rawlink<Node<T>>)
+                  -> Link<T> {
+    next.prev = prev;
+    Some(next)
+}
+
+// private methods
+impl<T> LinkedList<T> {
+    /// Add a Node first in the list
+    #[inline]
+    fn push_front_node(&mut self, mut new_head: Box<Node<T>>) {
+        match self.list_head {
+            None => {
+                self.list_tail = Rawlink::some(&mut *new_head);
+                self.list_head = link_with_prev(new_head, Rawlink::none());
+            }
+            Some(ref mut head) => {
+                new_head.prev = Rawlink::none();
+                head.prev = Rawlink::some(&mut *new_head);
+                mem::swap(head, &mut new_head);
+                head.next = Some(new_head);
+            }
+        }
+        self.length += 1;
+    }
+
+    /// Remove the first Node and return it, or None if the list is empty
+    #[inline]
+    fn pop_front_node(&mut self) -> Option<Box<Node<T>>> {
+        self.list_head.take().map(|mut front_node| {
+            self.length -= 1;
+            match front_node.next.take() {
+                Some(node) => self.list_head = link_with_prev(node, Rawlink::none()),
+                None => self.list_tail = Rawlink::none()
+            }
+            front_node
+        })
+    }
+
+    /// Add a Node last in the list
+    #[inline]
+    fn push_back_node(&mut self, mut new_tail: Box<Node<T>>) {
+        match self.list_tail.resolve() {
+            None => return self.push_front_node(new_tail),
+            Some(tail) => {
+                self.list_tail = Rawlink::some(&mut *new_tail);
+                tail.next = link_with_prev(new_tail, Rawlink::some(tail));
+            }
+        }
+        self.length += 1;
+    }
+
+    /// Remove the last Node and return it, or None if the list is empty
+    #[inline]
+    fn pop_back_node(&mut self) -> Option<Box<Node<T>>> {
+        self.list_tail.resolve().map_or(None, |tail| {
+            self.length -= 1;
+            self.list_tail = tail.prev;
+            match tail.prev.resolve() {
+                None => self.list_head.take(),
+                Some(tail_prev) => tail_prev.next.take()
+            }
+        })
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> Default for LinkedList<T> {
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn default() -> LinkedList<T> { LinkedList::new() }
+}
+
+impl<T> LinkedList<T> {
+    /// Creates an empty `LinkedList`.
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn new() -> LinkedList<T> {
+        LinkedList{list_head: None, list_tail: Rawlink::none(), length: 0}
+    }
+
+    /// Moves all elements from `other` to the end of the list.
+    ///
+    /// This reuses all the nodes from `other` and moves them into `self`. After
+    /// this operation, `other` becomes empty.
+    ///
+    /// This operation should compute in O(1) time and O(1) memory.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let mut a = LinkedList::new();
+    /// let mut b = LinkedList::new();
+    /// a.push_back(1);
+    /// a.push_back(2);
+    /// b.push_back(3);
+    /// b.push_back(4);
+    ///
+    /// a.append(&mut b);
+    ///
+    /// for e in a.iter() {
+    ///     println!("{}", e); // prints 1, then 2, then 3, then 4
+    /// }
+    /// println!("{}", b.len()); // prints 0
+    /// ```
+    pub fn append(&mut self, other: &mut LinkedList<T>) {
+        match self.list_tail.resolve() {
+            None => {
+                self.length = other.length;
+                self.list_head = other.list_head.take();
+                self.list_tail = other.list_tail.take();
+            },
+            Some(tail) => {
+                // Carefully empty `other`.
+                let o_tail = other.list_tail.take();
+                let o_length = other.length;
+                match other.list_head.take() {
+                    None => return,
+                    Some(node) => {
+                        tail.next = link_with_prev(node, self.list_tail);
+                        self.list_tail = o_tail;
+                        self.length += o_length;
+                    }
+                }
+            }
+        }
+        other.length = 0;
+    }
+
+    /// Provides a forward iterator.
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn iter(&self) -> Iter<T> {
+        Iter{nelem: self.len(), head: &self.list_head, tail: self.list_tail}
+    }
+
+    /// Provides a forward iterator with mutable references.
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn iter_mut(&mut self) -> IterMut<T> {
+        let head_raw = match self.list_head {
+            Some(ref mut h) => Rawlink::some(&mut **h),
+            None => Rawlink::none(),
+        };
+        IterMut{
+            nelem: self.len(),
+            head: head_raw,
+            tail: self.list_tail,
+            list: self
+        }
+    }
+
+    /// Consumes the list into an iterator yielding elements by value.
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn into_iter(self) -> IntoIter<T> {
+        IntoIter{list: self}
+    }
+
+    /// Returns `true` if the `LinkedList` is empty.
+    ///
+    /// This operation should compute in O(1) time.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let mut dl = LinkedList::new();
+    /// assert!(dl.is_empty());
+    ///
+    /// dl.push_front("foo");
+    /// assert!(!dl.is_empty());
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_empty(&self) -> bool {
+        self.list_head.is_none()
+    }
+
+    /// Returns the length of the `LinkedList`.
+    ///
+    /// This operation should compute in O(1) time.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let mut dl = LinkedList::new();
+    ///
+    /// dl.push_front(2);
+    /// assert_eq!(dl.len(), 1);
+    ///
+    /// dl.push_front(1);
+    /// assert_eq!(dl.len(), 2);
+    ///
+    /// dl.push_back(3);
+    /// assert_eq!(dl.len(), 3);
+    ///
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn len(&self) -> usize {
+        self.length
+    }
+
+    /// Removes all elements from the `LinkedList`.
+    ///
+    /// This operation should compute in O(n) time.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let mut dl = LinkedList::new();
+    ///
+    /// dl.push_front(2);
+    /// dl.push_front(1);
+    /// assert_eq!(dl.len(), 2);
+    /// assert_eq!(dl.front(), Some(&1));
+    ///
+    /// dl.clear();
+    /// assert_eq!(dl.len(), 0);
+    /// assert_eq!(dl.front(), None);
+    ///
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn clear(&mut self) {
+        *self = LinkedList::new()
+    }
+
+    /// Provides a reference to the front element, or `None` if the list is
+    /// empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let mut dl = LinkedList::new();
+    /// assert_eq!(dl.front(), None);
+    ///
+    /// dl.push_front(1);
+    /// assert_eq!(dl.front(), Some(&1));
+    ///
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn front(&self) -> Option<&T> {
+        self.list_head.as_ref().map(|head| &head.value)
+    }
+
+    /// Provides a mutable reference to the front element, or `None` if the list
+    /// is empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let mut dl = LinkedList::new();
+    /// assert_eq!(dl.front(), None);
+    ///
+    /// dl.push_front(1);
+    /// assert_eq!(dl.front(), Some(&1));
+    ///
+    /// match dl.front_mut() {
+    ///     None => {},
+    ///     Some(x) => *x = 5,
+    /// }
+    /// assert_eq!(dl.front(), Some(&5));
+    ///
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn front_mut(&mut self) -> Option<&mut T> {
+        self.list_head.as_mut().map(|head| &mut head.value)
+    }
+
+    /// Provides a reference to the back element, or `None` if the list is
+    /// empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let mut dl = LinkedList::new();
+    /// assert_eq!(dl.back(), None);
+    ///
+    /// dl.push_back(1);
+    /// assert_eq!(dl.back(), Some(&1));
+    ///
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn back(&self) -> Option<&T> {
+        self.list_tail.resolve_immut().as_ref().map(|tail| &tail.value)
+    }
+
+    /// Provides a mutable reference to the back element, or `None` if the list
+    /// is empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let mut dl = LinkedList::new();
+    /// assert_eq!(dl.back(), None);
+    ///
+    /// dl.push_back(1);
+    /// assert_eq!(dl.back(), Some(&1));
+    ///
+    /// match dl.back_mut() {
+    ///     None => {},
+    ///     Some(x) => *x = 5,
+    /// }
+    /// assert_eq!(dl.back(), Some(&5));
+    ///
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn back_mut(&mut self) -> Option<&mut T> {
+        self.list_tail.resolve().map(|tail| &mut tail.value)
+    }
+
+    /// Adds an element first in the list.
+    ///
+    /// This operation should compute in O(1) time.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let mut dl = LinkedList::new();
+    ///
+    /// dl.push_front(2);
+    /// assert_eq!(dl.front().unwrap(), &2);
+    ///
+    /// dl.push_front(1);
+    /// assert_eq!(dl.front().unwrap(), &1);
+    ///
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn push_front(&mut self, elt: T) {
+        self.push_front_node(box Node::new(elt))
+    }
+
+    /// Removes the first element and returns it, or `None` if the list is
+    /// empty.
+    ///
+    /// This operation should compute in O(1) time.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let mut d = LinkedList::new();
+    /// assert_eq!(d.pop_front(), None);
+    ///
+    /// d.push_front(1);
+    /// d.push_front(3);
+    /// assert_eq!(d.pop_front(), Some(3));
+    /// assert_eq!(d.pop_front(), Some(1));
+    /// assert_eq!(d.pop_front(), None);
+    ///
+    /// ```
+    ///
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn pop_front(&mut self) -> Option<T> {
+        self.pop_front_node().map(|box Node{value, ..}| value)
+    }
+
+    /// Appends an element to the back of a list
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let mut d = LinkedList::new();
+    /// d.push_back(1);
+    /// d.push_back(3);
+    /// assert_eq!(3, *d.back().unwrap());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn push_back(&mut self, elt: T) {
+        self.push_back_node(box Node::new(elt))
+    }
+
+    /// Removes the last element from a list and returns it, or `None` if
+    /// it is empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let mut d = LinkedList::new();
+    /// assert_eq!(d.pop_back(), None);
+    /// d.push_back(1);
+    /// d.push_back(3);
+    /// assert_eq!(d.pop_back(), Some(3));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn pop_back(&mut self) -> Option<T> {
+        self.pop_back_node().map(|box Node{value, ..}| value)
+    }
+
+    /// Splits the list into two at the given index. Returns everything after the given index,
+    /// including the index.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `at > len`.
+    ///
+    /// This operation should compute in O(n) time.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let mut d = LinkedList::new();
+    ///
+    /// d.push_front(1);
+    /// d.push_front(2);
+    /// d.push_front(3);
+    ///
+    /// let mut splitted = d.split_off(2);
+    ///
+    /// assert_eq!(splitted.pop_front(), Some(1));
+    /// assert_eq!(splitted.pop_front(), None);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn split_off(&mut self, at: usize) -> LinkedList<T> {
+        let len = self.len();
+        assert!(at <= len, "Cannot split off at a nonexistent index");
+        if at == 0 {
+            return mem::replace(self, LinkedList::new());
+        } else if at == len {
+            return LinkedList::new();
+        }
+
+        // Below, we iterate towards the `i-1`th node, either from the start or the end,
+        // depending on which would be faster.
+        let mut split_node = if at - 1 <= len - 1 - (at - 1) {
+            let mut iter = self.iter_mut();
+            // instead of skipping using .skip() (which creates a new struct),
+            // we skip manually so we can access the head field without
+            // depending on implementation details of Skip
+            for _ in 0..at - 1 {
+                iter.next();
+            }
+            iter.head
+        }  else {
+            // better off starting from the end
+            let mut iter = self.iter_mut();
+            for _ in 0..len - 1 - (at - 1) {
+                iter.next_back();
+            }
+            iter.tail
+        };
+
+        let mut splitted_list = LinkedList {
+            list_head: None,
+            list_tail: self.list_tail,
+            length: len - at
+        };
+
+        mem::swap(&mut split_node.resolve().unwrap().next, &mut splitted_list.list_head);
+        self.list_tail = split_node;
+        self.length = at;
+
+        splitted_list
+    }
+}
+
+#[unsafe_destructor]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> Drop for LinkedList<T> {
+    fn drop(&mut self) {
+        // Dissolve the linked_list in backwards direction
+        // Just dropping the list_head can lead to stack exhaustion
+        // when length is >> 1_000_000
+        let mut tail = self.list_tail;
+        loop {
+            match tail.resolve() {
+                None => break,
+                Some(prev) => {
+                    prev.next.take(); // release Box<Node<T>>
+                    tail = prev.prev;
+                }
+            }
+        }
+        self.length = 0;
+        self.list_head = None;
+        self.list_tail = Rawlink::none();
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, A> Iterator for Iter<'a, A> {
+    type Item = &'a A;
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a A> {
+        if self.nelem == 0 {
+            return None;
+        }
+        self.head.as_ref().map(|head| {
+            self.nelem -= 1;
+            self.head = &head.next;
+            &head.value
+        })
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.nelem, Some(self.nelem))
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, A> DoubleEndedIterator for Iter<'a, A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<&'a A> {
+        if self.nelem == 0 {
+            return None;
+        }
+        self.tail.resolve_immut().as_ref().map(|prev| {
+            self.nelem -= 1;
+            self.tail = prev.prev;
+            &prev.value
+        })
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, A> ExactSizeIterator for Iter<'a, A> {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, A> Iterator for IterMut<'a, A> {
+    type Item = &'a mut A;
+    #[inline]
+    fn next(&mut self) -> Option<&'a mut A> {
+        if self.nelem == 0 {
+            return None;
+        }
+        self.head.resolve().map(|next| {
+            self.nelem -= 1;
+            self.head = match next.next {
+                Some(ref mut node) => Rawlink::some(&mut **node),
+                None => Rawlink::none(),
+            };
+            &mut next.value
+        })
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.nelem, Some(self.nelem))
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, A> DoubleEndedIterator for IterMut<'a, A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<&'a mut A> {
+        if self.nelem == 0 {
+            return None;
+        }
+        self.tail.resolve().map(|prev| {
+            self.nelem -= 1;
+            self.tail = prev.prev;
+            &mut prev.value
+        })
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, A> ExactSizeIterator for IterMut<'a, A> {}
+
+// private methods for IterMut
+impl<'a, A> IterMut<'a, A> {
+    fn insert_next_node(&mut self, mut ins_node: Box<Node<A>>) {
+        // Insert before `self.head` so that it is between the
+        // previously yielded element and self.head.
+        //
+        // The inserted node will not appear in further iteration.
+        match self.head.resolve() {
+            None => { self.list.push_back_node(ins_node); }
+            Some(node) => {
+                let prev_node = match node.prev.resolve() {
+                    None => return self.list.push_front_node(ins_node),
+                    Some(prev) => prev,
+                };
+                let node_own = prev_node.next.take().unwrap();
+                ins_node.next = link_with_prev(node_own, Rawlink::some(&mut *ins_node));
+                prev_node.next = link_with_prev(ins_node, Rawlink::some(prev_node));
+                self.list.length += 1;
+            }
+        }
+    }
+}
+
+impl<'a, A> IterMut<'a, A> {
+    /// Inserts `elt` just after the element most recently returned by `.next()`.
+    /// The inserted element does not appear in the iteration.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let mut list: LinkedList<_> = vec![1, 3, 4].into_iter().collect();
+    ///
+    /// {
+    ///     let mut it = list.iter_mut();
+    ///     assert_eq!(it.next().unwrap(), &1);
+    ///     // insert `2` after `1`
+    ///     it.insert_next(2);
+    /// }
+    /// {
+    ///     let vec: Vec<_> = list.into_iter().collect();
+    ///     assert_eq!(vec, vec![1, 2, 3, 4]);
+    /// }
+    /// ```
+    #[inline]
+    #[unstable(feature = "collections",
+               reason = "this is probably better handled by a cursor type -- we'll see")]
+    pub fn insert_next(&mut self, elt: A) {
+        self.insert_next_node(box Node::new(elt))
+    }
+
+    /// Provides a reference to the next element, without changing the iterator.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::LinkedList;
+    ///
+    /// let mut list: LinkedList<_> = vec![1, 2, 3].into_iter().collect();
+    ///
+    /// let mut it = list.iter_mut();
+    /// assert_eq!(it.next().unwrap(), &1);
+    /// assert_eq!(it.peek_next().unwrap(), &2);
+    /// // We just peeked at 2, so it was not consumed from the iterator.
+    /// assert_eq!(it.next().unwrap(), &2);
+    /// ```
+    #[inline]
+    #[unstable(feature = "collections",
+               reason = "this is probably better handled by a cursor type -- we'll see")]
+    pub fn peek_next(&mut self) -> Option<&mut A> {
+        if self.nelem == 0 {
+            return None
+        }
+        self.head.resolve().map(|head| &mut head.value)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A> Iterator for IntoIter<A> {
+    type Item = A;
+
+    #[inline]
+    fn next(&mut self) -> Option<A> { self.list.pop_front() }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.list.length, Some(self.list.length))
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A> DoubleEndedIterator for IntoIter<A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<A> { self.list.pop_back() }
+}
+
+#[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();
+        ret.extend(iter);
+        ret
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> IntoIterator for LinkedList<T> {
+    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, T> IntoIterator for &'a LinkedList<T> {
+    type Item = &'a T;
+    type IntoIter = Iter<'a, T>;
+
+    fn into_iter(self) -> Iter<'a, T> {
+        self.iter()
+    }
+}
+
+impl<'a, T> IntoIterator for &'a mut LinkedList<T> {
+    type Item = &'a mut T;
+    type IntoIter = IterMut<'a, T>;
+
+    fn into_iter(mut self) -> IterMut<'a, T> {
+        self.iter_mut()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A> Extend<A> for LinkedList<A> {
+    fn extend<T: IntoIterator<Item=A>>(&mut self, iter: T) {
+        for elt in iter { self.push_back(elt); }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: PartialEq> PartialEq for LinkedList<A> {
+    fn eq(&self, other: &LinkedList<A>) -> bool {
+        self.len() == other.len() &&
+            iter::order::eq(self.iter(), other.iter())
+    }
+
+    fn ne(&self, other: &LinkedList<A>) -> bool {
+        self.len() != other.len() ||
+            iter::order::ne(self.iter(), other.iter())
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: Eq> Eq for LinkedList<A> {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: PartialOrd> PartialOrd for LinkedList<A> {
+    fn partial_cmp(&self, other: &LinkedList<A>) -> Option<Ordering> {
+        iter::order::partial_cmp(self.iter(), other.iter())
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: Ord> Ord for LinkedList<A> {
+    #[inline]
+    fn cmp(&self, other: &LinkedList<A>) -> Ordering {
+        iter::order::cmp(self.iter(), other.iter())
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: Clone> Clone for LinkedList<A> {
+    fn clone(&self) -> LinkedList<A> {
+        self.iter().cloned().collect()
+    }
+}
+
+#[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, "]")
+    }
+}
+
+#[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);
+        for elt in self {
+            elt.hash(state);
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use prelude::*;
+    use std::rand;
+    use std::hash::{self, SipHasher};
+    use std::thread;
+    use test::Bencher;
+    use test;
+
+    use super::{LinkedList, Node};
+
+    pub fn check_links<T>(list: &LinkedList<T>) {
+        let mut len = 0;
+        let mut last_ptr: Option<&Node<T>> = None;
+        let mut node_ptr: &Node<T>;
+        match list.list_head {
+            None => { assert_eq!(0, list.length); return }
+            Some(ref node) => node_ptr = &**node,
+        }
+        loop {
+            match (last_ptr, node_ptr.prev.resolve_immut()) {
+                (None   , None      ) => {}
+                (None   , _         ) => panic!("prev link for list_head"),
+                (Some(p), Some(pptr)) => {
+                    assert_eq!(p as *const Node<T>, pptr as *const Node<T>);
+                }
+                _ => panic!("prev link is none, not good"),
+            }
+            match node_ptr.next {
+                Some(ref next) => {
+                    last_ptr = Some(node_ptr);
+                    node_ptr = &**next;
+                    len += 1;
+                }
+                None => {
+                    len += 1;
+                    break;
+                }
+            }
+        }
+        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
+        {
+            let mut m = LinkedList::<i32>::new();
+            let mut n = LinkedList::new();
+            m.append(&mut n);
+            check_links(&m);
+            assert_eq!(m.len(), 0);
+            assert_eq!(n.len(), 0);
+        }
+        // Non-empty to empty
+        {
+            let mut m = LinkedList::new();
+            let mut n = LinkedList::new();
+            n.push_back(2);
+            m.append(&mut n);
+            check_links(&m);
+            assert_eq!(m.len(), 1);
+            assert_eq!(m.pop_back(), Some(2));
+            assert_eq!(n.len(), 0);
+            check_links(&m);
+        }
+        // Empty to non-empty
+        {
+            let mut m = LinkedList::new();
+            let mut n = LinkedList::new();
+            m.push_back(2);
+            m.append(&mut n);
+            check_links(&m);
+            assert_eq!(m.len(), 1);
+            assert_eq!(m.pop_back(), Some(2));
+            check_links(&m);
+        }
+
+        // Non-empty to non-empty
+        let v = vec![1,2,3,4,5];
+        let u = vec![9,8,1,2,3,4,5];
+        let mut m = list_from(&v);
+        let mut n = list_from(&u);
+        m.append(&mut n);
+        check_links(&m);
+        let mut sum = v;
+        sum.push_all(&u);
+        assert_eq!(sum.len(), m.len());
+        for elt in sum {
+            assert_eq!(m.pop_front(), Some(elt))
+        }
+        assert_eq!(n.len(), 0);
+        // let's make sure it's working properly, since we
+        // did some direct changes to private members
+        n.push_back(3);
+        assert_eq!(n.len(), 1);
+        assert_eq!(n.pop_front(), Some(3));
+        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]);
+        let len = m.len();
+        {
+            let mut it = m.iter_mut();
+            it.insert_next(-2);
+            loop {
+                match it.next() {
+                    None => break,
+                    Some(elt) => {
+                        it.insert_next(*elt + 1);
+                        match it.peek_next() {
+                            Some(x) => assert_eq!(*x, *elt + 2),
+                            None => assert_eq!(8, *elt),
+                        }
+                    }
+                }
+            }
+            it.insert_next(0);
+            it.insert_next(1);
+        }
+        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());
+    }
+
+    #[test]
+    fn test_send() {
+        let n = list_from(&[1,2,3]);
+        thread::spawn(move || {
+            check_links(&n);
+            let a: &[_] = &[&1,&2,&3];
+            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 {
+            fuzz_test(3);
+            fuzz_test(16);
+            fuzz_test(189);
+        }
+    }
+
+    #[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();
+        let mut v = vec![];
+        for i in 0..sz {
+            check_links(&m);
+            let r: u8 = rand::random();
+            match r % 6 {
+                0 => {
+                    m.pop_back();
+                    v.pop();
+                }
+                1 => {
+                    if !v.is_empty() {
+                        m.pop_front();
+                        v.remove(0);
+                    }
+                }
+                2 | 4 =>  {
+                    m.push_front(-i);
+                    v.insert(0, -i);
+                }
+                3 | 5 | _ => {
+                    m.push_back(i);
+                    v.push(i);
+                }
+            }
+        }
+
+        check_links(&m);
+
+        let mut i = 0;
+        for (a, &b) in m.into_iter().zip(v.iter()) {
+            i += 1;
+            assert_eq!(a, b);
+        }
+        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);
+        })
+    }
+}
diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs
deleted file mode 100644 (file)
index 6dcdb21..0000000
+++ /dev/null
@@ -1,2876 +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.
-
-//! RingBuf is a double-ended queue, which is implemented with the help of a
-//! growing circular buffer.
-//!
-//! This queue has `O(1)` amortized inserts and removals from both ends of the
-//! container. It also has `O(1)` indexing like a vector. The contained elements
-//! are not required to be copyable, and the queue will be sendable if the
-//! contained type is sendable.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use core::prelude::*;
-
-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;
-use core::raw::Slice as RawSlice;
-
-use core::hash::{Writer, Hash, Hasher};
-use core::cmp;
-
-use alloc::heap;
-
-static INITIAL_CAPACITY: usize = 7; // 2^3 - 1
-static MINIMUM_CAPACITY: usize = 1; // 2 - 1
-
-/// `RingBuf` is a circular buffer, which can be used as a double-ended queue efficiently.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct RingBuf<T> {
-    // tail and head are pointers into the buffer. Tail always points
-    // to the first element that could be read, Head always points
-    // to where data should be written.
-    // If tail == head the buffer is empty. The length of the ringbuf
-    // is defined as the distance between the two.
-
-    tail: usize,
-    head: usize,
-    cap: usize,
-    ptr: *mut T
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<T: Send> Send for RingBuf<T> {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<T: Sync> Sync for RingBuf<T> {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Clone> Clone for RingBuf<T> {
-    fn clone(&self) -> RingBuf<T> {
-        self.iter().cloned().collect()
-    }
-}
-
-#[unsafe_destructor]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Drop for RingBuf<T> {
-    fn drop(&mut self) {
-        self.clear();
-        unsafe {
-            if mem::size_of::<T>() != 0 {
-                heap::deallocate(self.ptr as *mut u8,
-                                 self.cap * mem::size_of::<T>(),
-                                 mem::min_align_of::<T>())
-            }
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for RingBuf<T> {
-    #[inline]
-    fn default() -> RingBuf<T> { RingBuf::new() }
-}
-
-impl<T> RingBuf<T> {
-    /// Turn ptr into a slice
-    #[inline]
-    unsafe fn buffer_as_slice(&self) -> &[T] {
-        mem::transmute(RawSlice { data: self.ptr, len: 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, len: self.cap })
-    }
-
-    /// Moves an element out of the buffer
-    #[inline]
-    unsafe fn buffer_read(&mut self, off: usize) -> T {
-        ptr::read(self.ptr.offset(off as isize))
-    }
-
-    /// Writes an element into the buffer, moving it.
-    #[inline]
-    unsafe fn buffer_write(&mut self, off: usize, t: T) {
-        ptr::write(self.ptr.offset(off as isize), t);
-    }
-
-    /// Returns true iff the buffer is at capacity
-    #[inline]
-    fn is_full(&self) -> bool { self.cap - self.len() == 1 }
-
-    /// Returns the index in the underlying buffer for a given logical element
-    /// index.
-    #[inline]
-    fn wrap_index(&self, idx: usize) -> usize { wrap_index(idx, 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) {
-        debug_assert!(dst + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
-                      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),
-            self.ptr.offset(src as isize),
-            len);
-    }
-
-    /// Copies a contiguous block of memory len long from src to dst
-    #[inline]
-    unsafe fn copy_nonoverlapping(&self, dst: usize, src: usize, len: usize) {
-        debug_assert!(dst + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
-                      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),
-            self.ptr.offset(src as isize),
-            len);
-    }
-}
-
-impl<T> RingBuf<T> {
-    /// Creates an empty `RingBuf`.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new() -> RingBuf<T> {
-        RingBuf::with_capacity(INITIAL_CAPACITY)
-    }
-
-    /// Creates an empty `RingBuf` with space for at least `n` elements.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn with_capacity(n: usize) -> RingBuf<T> {
-        // +1 since the ringbuffer always leaves one space empty
-        let cap = cmp::max(n + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
-        assert!(cap > n, "capacity overflow");
-        let size = cap.checked_mul(mem::size_of::<T>())
-                      .expect("capacity overflow");
-
-        let ptr = if mem::size_of::<T>() != 0 {
-            unsafe {
-                let ptr = heap::allocate(size, mem::min_align_of::<T>())  as *mut T;;
-                if ptr.is_null() { ::alloc::oom() }
-                ptr
-            }
-        } else {
-            heap::EMPTY as *mut T
-        };
-
-        RingBuf {
-            tail: 0,
-            head: 0,
-            cap: cap,
-            ptr: ptr
-        }
-    }
-
-    /// Retrieves an element in the `RingBuf` by index.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf = RingBuf::new();
-    /// buf.push_back(3);
-    /// buf.push_back(4);
-    /// buf.push_back(5);
-    /// assert_eq!(buf.get(1).unwrap(), &4);
-    /// ```
-    #[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);
-            unsafe { Some(&*self.ptr.offset(idx as isize)) }
-        } else {
-            None
-        }
-    }
-
-    /// Retrieves an element in the `RingBuf` mutably by index.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf = RingBuf::new();
-    /// buf.push_back(3);
-    /// buf.push_back(4);
-    /// buf.push_back(5);
-    /// match buf.get_mut(1) {
-    ///     None => {}
-    ///     Some(elem) => {
-    ///         *elem = 7;
-    ///     }
-    /// }
-    ///
-    /// assert_eq!(buf[1], 7);
-    /// ```
-    #[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);
-            unsafe { Some(&mut *self.ptr.offset(idx as isize)) }
-        } else {
-            None
-        }
-    }
-
-    /// Swaps elements at indices `i` and `j`.
-    ///
-    /// `i` and `j` may be equal.
-    ///
-    /// Fails if there is no element with either index.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf = RingBuf::new();
-    /// buf.push_back(3);
-    /// buf.push_back(4);
-    /// buf.push_back(5);
-    /// buf.swap(0, 2);
-    /// assert_eq!(buf[0], 5);
-    /// assert_eq!(buf[2], 3);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    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);
-        unsafe {
-            ptr::swap(self.ptr.offset(ri as isize), self.ptr.offset(rj as isize))
-        }
-    }
-
-    /// Returns the number of elements the `RingBuf` can hold without
-    /// reallocating.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let buf: RingBuf<i32> = RingBuf::with_capacity(10);
-    /// assert!(buf.capacity() >= 10);
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn capacity(&self) -> usize { self.cap - 1 }
-
-    /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the
-    /// given `RingBuf`. Does nothing if the capacity is already sufficient.
-    ///
-    /// Note that the allocator may give the collection more space than it requests. Therefore
-    /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future
-    /// insertions are expected.
-    ///
-    /// # Panics
-    ///
-    /// Panics if the new capacity overflows `usize`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf: RingBuf<i32> = vec![1].into_iter().collect();
-    /// buf.reserve_exact(10);
-    /// assert!(buf.capacity() >= 11);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn reserve_exact(&mut self, additional: usize) {
-        self.reserve(additional);
-    }
-
-    /// Reserves capacity for at least `additional` more elements to be inserted in the given
-    /// `Ringbuf`. The collection may reserve more space to avoid frequent reallocations.
-    ///
-    /// # Panics
-    ///
-    /// Panics if the new capacity overflows `usize`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf: RingBuf<i32> = vec![1].into_iter().collect();
-    /// buf.reserve(10);
-    /// assert!(buf.capacity() >= 11);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn reserve(&mut self, additional: usize) {
-        let new_len = self.len() + additional;
-        assert!(new_len + 1 > self.len(), "capacity overflow");
-        if new_len > self.capacity() {
-            let count = (new_len + 1).next_power_of_two();
-            assert!(count >= new_len + 1);
-
-            if mem::size_of::<T>() != 0 {
-                let old = self.cap * mem::size_of::<T>();
-                let new = count.checked_mul(mem::size_of::<T>())
-                               .expect("capacity overflow");
-                unsafe {
-                    self.ptr = heap::reallocate(self.ptr as *mut u8,
-                                                old,
-                                                new,
-                                                mem::min_align_of::<T>()) as *mut T;
-                    if self.ptr.is_null() { ::alloc::oom() }
-                }
-            }
-
-            // Move the shortest contiguous section of the ring buffer
-            //    T             H
-            //   [o o o o o o o . ]
-            //    T             H
-            // A [o o o o o o o . . . . . . . . . ]
-            //        H T
-            //   [o o . o o o o o ]
-            //          T             H
-            // B [. . . o o o o o o o . . . . . . ]
-            //              H T
-            //   [o o o o o . o o ]
-            //              H                 T
-            // C [o o o o o . . . . . . . . . o o ]
-
-            let oldcap = self.cap;
-            self.cap = count;
-
-            if self.tail <= self.head { // A
-                // Nop
-            } else if self.head < oldcap - self.tail { // B
-                unsafe {
-                    self.copy_nonoverlapping(oldcap, 0, self.head);
-                }
-                self.head += oldcap;
-                debug_assert!(self.head > self.tail);
-            } else { // C
-                let new_tail = count - (oldcap - self.tail);
-                unsafe {
-                    self.copy_nonoverlapping(new_tail, self.tail, oldcap - self.tail);
-                }
-                self.tail = new_tail;
-                debug_assert!(self.head < self.tail);
-            }
-            debug_assert!(self.head < self.cap);
-            debug_assert!(self.tail < self.cap);
-            debug_assert!(self.cap.count_ones() == 1);
-        }
-    }
-
-    /// Shrinks the capacity of the ringbuf as much as possible.
-    ///
-    /// It will drop down as close as possible to the length but the allocator may still inform the
-    /// ringbuf that there is space for a few more elements.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf = RingBuf::with_capacity(15);
-    /// buf.extend(0..4);
-    /// assert_eq!(buf.capacity(), 15);
-    /// buf.shrink_to_fit();
-    /// assert!(buf.capacity() >= 4);
-    /// ```
-    pub fn shrink_to_fit(&mut self) {
-        // +1 since the ringbuffer always leaves one space empty
-        // len + 1 can't overflow for an existing, well-formed ringbuf.
-        let target_cap = cmp::max(self.len() + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
-        if target_cap < self.cap {
-            // There are three cases of interest:
-            //   All elements are out of desired bounds
-            //   Elements are contiguous, and head is out of desired bounds
-            //   Elements are discontiguous, and tail is out of desired bounds
-            //
-            // At all other times, element positions are unaffected.
-            //
-            // Indicates that elements at the head should be moved.
-            let head_outside = self.head == 0 || self.head >= target_cap;
-            // Move elements from out of desired bounds (positions after target_cap)
-            if self.tail >= target_cap && head_outside {
-                //                    T             H
-                //   [. . . . . . . . o o o o o o o . ]
-                //    T             H
-                //   [o o o o o o o . ]
-                unsafe {
-                    self.copy_nonoverlapping(0, self.tail, self.len());
-                }
-                self.head = self.len();
-                self.tail = 0;
-            } else if self.tail != 0 && self.tail < target_cap && head_outside {
-                //          T             H
-                //   [. . . 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);
-                unsafe {
-                    self.copy_nonoverlapping(0, target_cap, len);
-                }
-                self.head = len;
-                debug_assert!(self.head < self.tail);
-            } else if self.tail >= target_cap {
-                //              H                 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);
-                let len = self.cap - self.tail;
-                let new_tail = target_cap - len;
-                unsafe {
-                    self.copy_nonoverlapping(new_tail, self.tail, len);
-                }
-                self.tail = new_tail;
-                debug_assert!(self.head < self.tail);
-            }
-
-            if mem::size_of::<T>() != 0 {
-                let old = self.cap * mem::size_of::<T>();
-                let new_size = target_cap * mem::size_of::<T>();
-                unsafe {
-                    self.ptr = heap::reallocate(self.ptr as *mut u8,
-                                                old,
-                                                new_size,
-                                                mem::min_align_of::<T>()) as *mut T;
-                    if self.ptr.is_null() { ::alloc::oom() }
-                }
-            }
-            self.cap = target_cap;
-            debug_assert!(self.head < self.cap);
-            debug_assert!(self.tail < self.cap);
-            debug_assert!(self.cap.count_ones() == 1);
-        }
-    }
-
-    /// Shorten a ringbuf, dropping excess elements from the back.
-    ///
-    /// If `len` is greater than the ringbuf's current length, this has no
-    /// effect.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf = RingBuf::new();
-    /// buf.push_back(5);
-    /// buf.push_back(10);
-    /// buf.push_back(15);
-    /// buf.truncate(1);
-    /// assert_eq!(buf.len(), 1);
-    /// assert_eq!(Some(&5), buf.get(0));
-    /// ```
-    #[unstable(feature = "collections",
-               reason = "matches collection reform specification; waiting on panic semantics")]
-    pub fn truncate(&mut self, len: usize) {
-        for _ in len..self.len() {
-            self.pop_back();
-        }
-    }
-
-    /// Returns a front-to-back iterator.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf = RingBuf::new();
-    /// buf.push_back(5);
-    /// buf.push_back(3);
-    /// buf.push_back(4);
-    /// let b: &[_] = &[&5, &3, &4];
-    /// assert_eq!(buf.iter().collect::<Vec<&i32>>().as_slice(), b);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn iter(&self) -> Iter<T> {
-        Iter {
-            tail: self.tail,
-            head: self.head,
-            ring: unsafe { self.buffer_as_slice() }
-        }
-    }
-
-    /// Returns a front-to-back iterator that returns mutable references.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf = RingBuf::new();
-    /// buf.push_back(5);
-    /// buf.push_back(3);
-    /// buf.push_back(4);
-    /// for num in buf.iter_mut() {
-    ///     *num = *num - 2;
-    /// }
-    /// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
-    /// 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::ContravariantLifetime,
-        }
-    }
-
-    /// Consumes the list into an iterator yielding elements by value.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_iter(self) -> IntoIter<T> {
-        IntoIter {
-            inner: self,
-        }
-    }
-
-    /// Returns a pair of slices which contain, in order, the contents of the
-    /// `RingBuf`.
-    #[inline]
-    #[unstable(feature = "collections",
-               reason = "matches collection reform specification, waiting for dust to settle")]
-    pub fn as_slices(&self) -> (&[T], &[T]) {
-        unsafe {
-            let contiguous = self.is_contiguous();
-            let buf = self.buffer_as_slice();
-            if contiguous {
-                let (empty, buf) = buf.split_at(0);
-                (&buf[self.tail..self.head], empty)
-            } else {
-                let (mid, right) = buf.split_at(self.tail);
-                let (left, _) = mid.split_at(self.head);
-                (right, left)
-            }
-        }
-    }
-
-    /// Returns a pair of slices which contain, in order, the contents of the
-    /// `RingBuf`.
-    #[inline]
-    #[unstable(feature = "collections",
-               reason = "matches collection reform specification, waiting for dust to settle")]
-    pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) {
-        unsafe {
-            let contiguous = self.is_contiguous();
-            let head = self.head;
-            let tail = self.tail;
-            let buf = self.buffer_as_mut_slice();
-
-            if contiguous {
-                let (empty, buf) = buf.split_at_mut(0);
-                (&mut buf[tail .. head], empty)
-            } else {
-                let (mid, right) = buf.split_at_mut(tail);
-                let (left, _) = mid.split_at_mut(head);
-
-                (right, left)
-            }
-        }
-    }
-
-    /// Returns the number of elements in the `RingBuf`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut v = RingBuf::new();
-    /// assert_eq!(v.len(), 0);
-    /// v.push_back(1);
-    /// assert_eq!(v.len(), 1);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn len(&self) -> usize { count(self.tail, self.head, self.cap) }
-
-    /// Returns true if the buffer contains no elements
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut v = RingBuf::new();
-    /// assert!(v.is_empty());
-    /// v.push_front(1);
-    /// assert!(!v.is_empty());
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_empty(&self) -> bool { self.len() == 0 }
-
-    /// Creates a draining iterator that clears the `RingBuf` and iterates over
-    /// the removed items from start to end.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut v = RingBuf::new();
-    /// v.push_back(1);
-    /// assert_eq!(v.drain().next(), Some(1));
-    /// assert!(v.is_empty());
-    /// ```
-    #[inline]
-    #[unstable(feature = "collections",
-               reason = "matches collection reform specification, waiting for dust to settle")]
-    pub fn drain(&mut self) -> Drain<T> {
-        Drain {
-            inner: self,
-        }
-    }
-
-    /// Clears the buffer, removing all values.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut v = RingBuf::new();
-    /// v.push_back(1);
-    /// v.clear();
-    /// assert!(v.is_empty());
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[inline]
-    pub fn clear(&mut self) {
-        self.drain();
-    }
-
-    /// Provides a reference to the front element, or `None` if the sequence is
-    /// empty.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut d = RingBuf::new();
-    /// assert_eq!(d.front(), None);
-    ///
-    /// d.push_back(1);
-    /// d.push_back(2);
-    /// assert_eq!(d.front(), Some(&1));
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn front(&self) -> Option<&T> {
-        if !self.is_empty() { Some(&self[0]) } else { None }
-    }
-
-    /// Provides a mutable reference to the front element, or `None` if the
-    /// sequence is empty.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut d = RingBuf::new();
-    /// assert_eq!(d.front_mut(), None);
-    ///
-    /// d.push_back(1);
-    /// d.push_back(2);
-    /// match d.front_mut() {
-    ///     Some(x) => *x = 9,
-    ///     None => (),
-    /// }
-    /// assert_eq!(d.front(), Some(&9));
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn front_mut(&mut self) -> Option<&mut T> {
-        if !self.is_empty() { Some(&mut self[0]) } else { None }
-    }
-
-    /// Provides a reference to the back element, or `None` if the sequence is
-    /// empty.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut d = RingBuf::new();
-    /// assert_eq!(d.back(), None);
-    ///
-    /// d.push_back(1);
-    /// d.push_back(2);
-    /// assert_eq!(d.back(), Some(&2));
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn back(&self) -> Option<&T> {
-        if !self.is_empty() { Some(&self[self.len() - 1]) } else { None }
-    }
-
-    /// Provides a mutable reference to the back element, or `None` if the
-    /// sequence is empty.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut d = RingBuf::new();
-    /// assert_eq!(d.back(), None);
-    ///
-    /// d.push_back(1);
-    /// d.push_back(2);
-    /// match d.back_mut() {
-    ///     Some(x) => *x = 9,
-    ///     None => (),
-    /// }
-    /// assert_eq!(d.back(), Some(&9));
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn back_mut(&mut self) -> Option<&mut T> {
-        let len = self.len();
-        if !self.is_empty() { Some(&mut self[len - 1]) } else { None }
-    }
-
-    /// Removes the first element and returns it, or `None` if the sequence is
-    /// empty.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut d = RingBuf::new();
-    /// d.push_back(1);
-    /// d.push_back(2);
-    ///
-    /// assert_eq!(d.pop_front(), Some(1));
-    /// assert_eq!(d.pop_front(), Some(2));
-    /// assert_eq!(d.pop_front(), None);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn pop_front(&mut self) -> Option<T> {
-        if self.is_empty() {
-            None
-        } else {
-            let tail = self.tail;
-            self.tail = self.wrap_index(self.tail + 1);
-            unsafe { Some(self.buffer_read(tail)) }
-        }
-    }
-
-    /// Inserts an element first in the sequence.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut d = RingBuf::new();
-    /// d.push_front(1);
-    /// d.push_front(2);
-    /// assert_eq!(d.front(), Some(&2));
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn push_front(&mut self, t: T) {
-        if self.is_full() {
-            self.reserve(1);
-            debug_assert!(!self.is_full());
-        }
-
-        self.tail = self.wrap_index(self.tail - 1);
-        let tail = self.tail;
-        unsafe { self.buffer_write(tail, t); }
-    }
-
-    /// Appends an element to the back of a buffer
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf = RingBuf::new();
-    /// buf.push_back(1);
-    /// buf.push_back(3);
-    /// assert_eq!(3, *buf.back().unwrap());
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn push_back(&mut self, t: T) {
-        if self.is_full() {
-            self.reserve(1);
-            debug_assert!(!self.is_full());
-        }
-
-        let head = self.head;
-        self.head = self.wrap_index(self.head + 1);
-        unsafe { self.buffer_write(head, t) }
-    }
-
-    /// Removes the last element from a buffer and returns it, or `None` if
-    /// it is empty.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf = RingBuf::new();
-    /// assert_eq!(buf.pop_back(), None);
-    /// buf.push_back(1);
-    /// buf.push_back(3);
-    /// assert_eq!(buf.pop_back(), Some(3));
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn pop_back(&mut self) -> Option<T> {
-        if self.is_empty() {
-            None
-        } else {
-            self.head = self.wrap_index(self.head - 1);
-            let head = self.head;
-            unsafe { Some(self.buffer_read(head)) }
-        }
-    }
-
-    #[inline]
-    fn is_contiguous(&self) -> bool {
-        self.tail <= self.head
-    }
-
-    /// Removes an element from anywhere in the ringbuf and returns it, replacing it with the last
-    /// element.
-    ///
-    /// This does not preserve ordering, but is O(1).
-    ///
-    /// Returns `None` if `index` is out of bounds.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf = RingBuf::new();
-    /// assert_eq!(buf.swap_back_remove(0), None);
-    /// buf.push_back(5);
-    /// buf.push_back(99);
-    /// buf.push_back(15);
-    /// buf.push_back(20);
-    /// buf.push_back(10);
-    /// assert_eq!(buf.swap_back_remove(1), Some(99));
-    /// ```
-    #[unstable(feature = "collections",
-               reason = "the naming of this function may be altered")]
-    pub fn swap_back_remove(&mut self, index: usize) -> Option<T> {
-        let length = self.len();
-        if length > 0 && index < length - 1 {
-            self.swap(index, length - 1);
-        } else if index >= length {
-            return None;
-        }
-        self.pop_back()
-    }
-
-    /// Removes an element from anywhere in the ringbuf and returns it, replacing it with the first
-    /// element.
-    ///
-    /// This does not preserve ordering, but is O(1).
-    ///
-    /// Returns `None` if `index` is out of bounds.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf = RingBuf::new();
-    /// assert_eq!(buf.swap_front_remove(0), None);
-    /// buf.push_back(15);
-    /// buf.push_back(5);
-    /// buf.push_back(10);
-    /// buf.push_back(99);
-    /// buf.push_back(20);
-    /// assert_eq!(buf.swap_front_remove(3), Some(99));
-    /// ```
-    #[unstable(feature = "collections",
-               reason = "the naming of this function may be altered")]
-    pub fn swap_front_remove(&mut self, index: usize) -> Option<T> {
-        let length = self.len();
-        if length > 0 && index < length && index != 0 {
-            self.swap(index, 0);
-        } else if index >= length {
-            return None;
-        }
-        self.pop_front()
-    }
-
-    /// Inserts an element at position `i` within the ringbuf. Whichever
-    /// end is closer to the insertion point will be moved to make room,
-    /// and all the affected elements will be moved to new positions.
-    ///
-    /// # Panics
-    ///
-    /// Panics if `i` is greater than ringbuf's length
-    ///
-    /// # Examples
-    /// ```rust
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf = RingBuf::new();
-    /// buf.push_back(10);
-    /// buf.push_back(12);
-    /// buf.insert(1,11);
-    /// assert_eq!(Some(&11), buf.get(1));
-    /// ```
-    pub fn insert(&mut self, i: usize, t: T) {
-        assert!(i <= self.len(), "index out of bounds");
-        if self.is_full() {
-            self.reserve(1);
-            debug_assert!(!self.is_full());
-        }
-
-        // Move the least number of elements in the ring buffer and insert
-        // the given object
-        //
-        // At most len/2 - 1 elements will be moved. O(min(n, n-i))
-        //
-        // There are three main cases:
-        //  Elements are contiguous
-        //      - special case when tail is 0
-        //  Elements are discontiguous and the insert is in the tail section
-        //  Elements are discontiguous and the insert is in the head section
-        //
-        // For each of those there are two more cases:
-        //  Insert is closer to tail
-        //  Insert is closer to head
-        //
-        // Key: H - self.head
-        //      T - self.tail
-        //      o - Valid element
-        //      I - Insertion element
-        //      A - The element that should be after the insertion point
-        //      M - Indicates element was moved
-
-        let idx = self.wrap_index(self.tail + i);
-
-        let distance_to_tail = i;
-        let distance_to_head = self.len() - i;
-
-        let contiguous = self.is_contiguous();
-
-        match (contiguous, distance_to_tail <= distance_to_head, idx >= self.tail) {
-            (true, true, _) if i == 0 => {
-                // push_front
-                //
-                //       T
-                //       I             H
-                //      [A o o o o o o . . . . . . . . .]
-                //
-                //                       H         T
-                //      [A o o o o o o o . . . . . I]
-                //
-
-                self.tail = self.wrap_index(self.tail - 1);
-            },
-            (true, true, _) => unsafe {
-                // contiguous, insert closer to tail:
-                //
-                //             T   I         H
-                //      [. . . o o A o o o o . . . . . .]
-                //
-                //           T               H
-                //      [. . o o I A o o o o . . . . . .]
-                //           M M
-                //
-                // contiguous, insert closer to tail and tail is 0:
-                //
-                //
-                //       T   I         H
-                //      [o o A o o o o . . . . . . . . .]
-                //
-                //                       H             T
-                //      [o I A o o o o o . . . . . . . o]
-                //       M                             M
-
-                let new_tail = self.wrap_index(self.tail - 1);
-
-                self.copy(new_tail, self.tail, 1);
-                // Already moved the tail, so we only copy `i - 1` elements.
-                self.copy(self.tail, self.tail + 1, i - 1);
-
-                self.tail = new_tail;
-            },
-            (true, false, _) => unsafe {
-                //  contiguous, insert closer to head:
-                //
-                //             T       I     H
-                //      [. . . o o o o A o o . . . . . .]
-                //
-                //             T               H
-                //      [. . . o o o o I A o o . . . . .]
-                //                       M M M
-
-                self.copy(idx + 1, idx, self.head - idx);
-                self.head = self.wrap_index(self.head + 1);
-            },
-            (false, true, true) => unsafe {
-                // discontiguous, insert closer to tail, tail section:
-                //
-                //                   H         T   I
-                //      [o o o o o o . . . . . o o A o o]
-                //
-                //                   H       T
-                //      [o o o o o o . . . . o o I A o o]
-                //                           M M
-
-                self.copy(self.tail - 1, self.tail, i);
-                self.tail -= 1;
-            },
-            (false, false, true) => unsafe {
-                // discontiguous, insert closer to head, tail section:
-                //
-                //           H             T         I
-                //      [o o . . . . . . . o o o o o A o]
-                //
-                //             H           T
-                //      [o o o . . . . . . o o o o o I A]
-                //       M M M                         M
-
-                // copy elements up to new head
-                self.copy(1, 0, self.head);
-
-                // copy last element into empty spot at bottom of buffer
-                self.copy(0, self.cap - 1, 1);
-
-                // move elements from idx to end forward not including ^ element
-                self.copy(idx + 1, idx, self.cap - 1 - idx);
-
-                self.head += 1;
-            },
-            (false, true, false) if idx == 0 => unsafe {
-                // discontiguous, insert is closer to tail, head section,
-                // and is at index zero in the internal buffer:
-                //
-                //       I                   H     T
-                //      [A o o o o o o o o o . . . o o o]
-                //
-                //                           H   T
-                //      [A o o o o o o o o o . . o o o I]
-                //                               M M M
-
-                // copy elements up to new tail
-                self.copy(self.tail - 1, self.tail, self.cap - self.tail);
-
-                // copy last element into empty spot at bottom of buffer
-                self.copy(self.cap - 1, 0, 1);
-
-                self.tail -= 1;
-            },
-            (false, true, false) => unsafe {
-                // discontiguous, insert closer to tail, head section:
-                //
-                //             I             H     T
-                //      [o o o A o o o o o o . . . o o o]
-                //
-                //                           H   T
-                //      [o o I A o o o o o o . . o o o o]
-                //       M M                     M M M M
-
-                // copy elements up to new tail
-                self.copy(self.tail - 1, self.tail, self.cap - self.tail);
-
-                // copy last element into empty spot at bottom of buffer
-                self.copy(self.cap - 1, 0, 1);
-
-                // move elements from idx-1 to end forward not including ^ element
-                self.copy(0, 1, idx - 1);
-
-                self.tail -= 1;
-            },
-            (false, false, false) => unsafe {
-                // discontiguous, insert closer to head, head section:
-                //
-                //               I     H           T
-                //      [o o o o A o o . . . . . . o o o]
-                //
-                //                     H           T
-                //      [o o o o I A o o . . . . . o o o]
-                //                 M M M
-
-                self.copy(idx + 1, idx, self.head - idx);
-                self.head += 1;
-            }
-        }
-
-        // tail might've been changed so we need to recalculate
-        let new_idx = self.wrap_index(self.tail + i);
-        unsafe {
-            self.buffer_write(new_idx, t);
-        }
-    }
-
-    /// Removes and returns the element at position `i` from the ringbuf.
-    /// Whichever end is closer to the removal point will be moved to make
-    /// room, and all the affected elements will be moved to new positions.
-    /// Returns `None` if `i` is out of bounds.
-    ///
-    /// # Examples
-    /// ```rust
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf = RingBuf::new();
-    /// buf.push_back(5);
-    /// buf.push_back(10);
-    /// buf.push_back(12);
-    /// buf.push_back(15);
-    /// buf.remove(2);
-    /// assert_eq!(Some(&15), buf.get(2));
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn remove(&mut self, i: usize) -> Option<T> {
-        if self.is_empty() || self.len() <= i {
-            return None;
-        }
-
-        // There are three main cases:
-        //  Elements are contiguous
-        //  Elements are discontiguous and the removal is in the tail section
-        //  Elements are discontiguous and the removal is in the head section
-        //      - special case when elements are technically contiguous,
-        //        but self.head = 0
-        //
-        // For each of those there are two more cases:
-        //  Insert is closer to tail
-        //  Insert is closer to head
-        //
-        // Key: H - self.head
-        //      T - self.tail
-        //      o - Valid element
-        //      x - Element marked for removal
-        //      R - Indicates element that is being removed
-        //      M - Indicates element was moved
-
-        let idx = self.wrap_index(self.tail + i);
-
-        let elem = unsafe {
-            Some(self.buffer_read(idx))
-        };
-
-        let distance_to_tail = i;
-        let distance_to_head = self.len() - i;
-
-        let contiguous = self.is_contiguous();
-
-        match (contiguous, distance_to_tail <= distance_to_head, idx >= self.tail) {
-            (true, true, _) => unsafe {
-                // contiguous, remove closer to tail:
-                //
-                //             T   R         H
-                //      [. . . o o x o o o o . . . . . .]
-                //
-                //               T           H
-                //      [. . . . o o o o o o . . . . . .]
-                //               M M
-
-                self.copy(self.tail + 1, self.tail, i);
-                self.tail += 1;
-            },
-            (true, false, _) => unsafe {
-                // contiguous, remove closer to head:
-                //
-                //             T       R     H
-                //      [. . . o o o o x o o . . . . . .]
-                //
-                //             T           H
-                //      [. . . o o o o o o . . . . . . .]
-                //                     M M
-
-                self.copy(idx, idx + 1, self.head - idx - 1);
-                self.head -= 1;
-            },
-            (false, true, true) => unsafe {
-                // discontiguous, remove closer to tail, tail section:
-                //
-                //                   H         T   R
-                //      [o o o o o o . . . . . o o x o o]
-                //
-                //                   H           T
-                //      [o o o o o o . . . . . . o o o o]
-                //                               M M
-
-                self.copy(self.tail + 1, self.tail, i);
-                self.tail = self.wrap_index(self.tail + 1);
-            },
-            (false, false, false) => unsafe {
-                // discontiguous, remove closer to head, head section:
-                //
-                //               R     H           T
-                //      [o o o o x o o . . . . . . o o o]
-                //
-                //                   H             T
-                //      [o o o o o o . . . . . . . o o o]
-                //               M M
-
-                self.copy(idx, idx + 1, self.head - idx - 1);
-                self.head -= 1;
-            },
-            (false, false, true) => unsafe {
-                // discontiguous, remove closer to head, tail section:
-                //
-                //             H           T         R
-                //      [o o o . . . . . . o o o o o x o]
-                //
-                //           H             T
-                //      [o o . . . . . . . o o o o o o o]
-                //       M M                         M M
-                //
-                // or quasi-discontiguous, remove next to head, tail section:
-                //
-                //       H                 T         R
-                //      [. . . . . . . . . o o o o o x o]
-                //
-                //                         T           H
-                //      [. . . . . . . . . o o o o o o .]
-                //                                   M
-
-                // draw in elements in the tail section
-                self.copy(idx, idx + 1, self.cap - idx - 1);
-
-                // Prevents underflow.
-                if self.head != 0 {
-                    // copy first element into empty spot
-                    self.copy(self.cap - 1, 0, 1);
-
-                    // move elements in the head section backwards
-                    self.copy(0, 1, self.head - 1);
-                }
-
-                self.head = self.wrap_index(self.head - 1);
-            },
-            (false, true, false) => unsafe {
-                // discontiguous, remove closer to tail, head section:
-                //
-                //           R               H     T
-                //      [o o x o o o o o o o . . . o o o]
-                //
-                //                           H       T
-                //      [o o o o o o o o o o . . . . o o]
-                //       M M M                       M M
-
-                // draw in elements up to idx
-                self.copy(1, 0, idx);
-
-                // copy last element into empty spot
-                self.copy(0, self.cap - 1, 1);
-
-                // 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);
-            }
-        }
-
-        return elem;
-    }
-
-    /// Splits the collection into two at the given index.
-    ///
-    /// Returns a newly allocated `Self`. `self` contains elements `[0, at)`,
-    /// and the returned `Self` contains elements `[at, len)`.
-    ///
-    /// Note that the capacity of `self` does not change.
-    ///
-    /// # Panics
-    ///
-    /// Panics if `at > len`
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf: RingBuf<_> = vec![1,2,3].into_iter().collect();
-    /// let buf2 = buf.split_off(1);
-    /// // buf = [1], buf2 = [2, 3]
-    /// assert_eq!(buf.len(), 1);
-    /// assert_eq!(buf2.len(), 2);
-    /// ```
-    #[inline]
-    #[unstable(feature = "collections",
-               reason = "new API, waiting for dust to settle")]
-    pub fn split_off(&mut self, at: usize) -> Self {
-        let len = self.len();
-        assert!(at <= len, "`at` out of bounds");
-
-        let other_len = len - at;
-        let mut other = RingBuf::with_capacity(other_len);
-
-        unsafe {
-            let (first_half, second_half) = self.as_slices();
-
-            let first_len = first_half.len();
-            let second_len = second_half.len();
-            if at < first_len {
-                // `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);
-
-                // 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);
-            } 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);
-            }
-        }
-
-        // Cleanup where the ends of the buffers are
-        self.head = self.wrap_index(self.head - other_len);
-        other.head = other.wrap_index(other_len);
-
-        other
-    }
-
-    /// Moves all the elements of `other` into `Self`, leaving `other` empty.
-    ///
-    /// # Panics
-    ///
-    /// Panics if the new number of elements in self overflows a `usize`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf: RingBuf<_> = vec![1, 2, 3].into_iter().collect();
-    /// let mut buf2: RingBuf<_> = vec![4, 5, 6].into_iter().collect();
-    /// buf.append(&mut buf2);
-    /// assert_eq!(buf.len(), 6);
-    /// assert_eq!(buf2.len(), 0);
-    /// ```
-    #[inline]
-    #[unstable(feature = "collections",
-               reason = "new API, waiting for dust to settle")]
-    pub fn append(&mut self, other: &mut Self) {
-        // naive impl
-        self.extend(other.drain());
-    }
-}
-
-impl<T: Clone> RingBuf<T> {
-    /// Modifies the ringbuf in-place so that `len()` is equal to new_len,
-    /// either by removing excess elements or by appending copies of a value to the back.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::RingBuf;
-    ///
-    /// let mut buf = RingBuf::new();
-    /// buf.push_back(5);
-    /// buf.push_back(10);
-    /// buf.push_back(15);
-    /// buf.resize(2, 0);
-    /// buf.resize(6, 20);
-    /// for (a, b) in [5, 10, 20, 20, 20, 20].iter().zip(buf.iter()) {
-    ///     assert_eq!(a, b);
-    /// }
-    /// ```
-    #[unstable(feature = "collections",
-               reason = "matches collection reform specification; waiting on panic semantics")]
-    pub fn resize(&mut self, new_len: usize, value: T) {
-        let len = self.len();
-
-        if new_len > len {
-            self.extend(repeat(value).take(new_len - len))
-        } else {
-            self.truncate(new_len);
-        }
-    }
-}
-
-/// Returns the index in the underlying buffer for a given logical element index.
-#[inline]
-fn wrap_index(index: usize, size: usize) -> usize {
-    // size is always a power of 2
-    index & (size - 1)
-}
-
-/// Calculate the number of elements left to be read in the buffer
-#[inline]
-fn count(tail: usize, head: usize, size: usize) -> usize {
-    // size is always a power of 2
-    (head - tail) & (size - 1)
-}
-
-/// `RingBuf` iterator.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Iter<'a, T:'a> {
-    ring: &'a [T],
-    tail: usize,
-    head: usize
-}
-
-// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
-impl<'a, T> Clone for Iter<'a, T> {
-    fn clone(&self) -> Iter<'a, T> {
-        Iter {
-            ring: self.ring,
-            tail: self.tail,
-            head: self.head
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> Iterator for Iter<'a, T> {
-    type Item = &'a T;
-
-    #[inline]
-    fn next(&mut self) -> Option<&'a T> {
-        if self.tail == self.head {
-            return None;
-        }
-        let tail = self.tail;
-        self.tail = wrap_index(self.tail + 1, self.ring.len());
-        unsafe { Some(self.ring.get_unchecked(tail)) }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        let len = count(self.tail, self.head, self.ring.len());
-        (len, Some(len))
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
-    #[inline]
-    fn next_back(&mut self) -> Option<&'a T> {
-        if self.tail == self.head {
-            return None;
-        }
-        self.head = wrap_index(self.head - 1, self.ring.len());
-        unsafe { Some(self.ring.get_unchecked(self.head)) }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> RandomAccessIterator for Iter<'a, T> {
-    #[inline]
-    fn indexable(&self) -> usize {
-        let (len, _) = self.size_hint();
-        len
-    }
-
-    #[inline]
-    fn idx(&mut self, j: usize) -> Option<&'a T> {
-        if j >= self.indexable() {
-            None
-        } else {
-            let idx = wrap_index(self.tail + 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.
-/// `RingBuf` mutable iterator.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct IterMut<'a, T:'a> {
-    ptr: *mut T,
-    tail: usize,
-    head: usize,
-    cap: usize,
-    marker: marker::ContravariantLifetime<'a>,
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> Iterator for IterMut<'a, T> {
-    type Item = &'a mut T;
-
-    #[inline]
-    fn next(&mut self) -> Option<&'a mut T> {
-        if self.tail == self.head {
-            return None;
-        }
-        let tail = self.tail;
-        self.tail = wrap_index(self.tail + 1, self.cap);
-
-        unsafe {
-            Some(&mut *self.ptr.offset(tail as isize))
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        let len = count(self.tail, self.head, self.cap);
-        (len, Some(len))
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
-    #[inline]
-    fn next_back(&mut self) -> Option<&'a mut T> {
-        if self.tail == self.head {
-            return None;
-        }
-        self.head = wrap_index(self.head - 1, self.cap);
-
-        unsafe {
-            Some(&mut *self.ptr.offset(self.head as isize))
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}
-
-/// A by-value RingBuf iterator
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct IntoIter<T> {
-    inner: RingBuf<T>,
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Iterator for IntoIter<T> {
-    type Item = T;
-
-    #[inline]
-    fn next(&mut self) -> Option<T> {
-        self.inner.pop_front()
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        let len = self.inner.len();
-        (len, Some(len))
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> DoubleEndedIterator for IntoIter<T> {
-    #[inline]
-    fn next_back(&mut self) -> Option<T> {
-        self.inner.pop_back()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> ExactSizeIterator for IntoIter<T> {}
-
-/// A draining RingBuf iterator
-#[unstable(feature = "collections",
-           reason = "matches collection reform specification, waiting for dust to settle")]
-pub struct Drain<'a, T: 'a> {
-    inner: &'a mut RingBuf<T>,
-}
-
-#[unsafe_destructor]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T: 'a> Drop for Drain<'a, T> {
-    fn drop(&mut self) {
-        for _ in self.by_ref() {}
-        self.inner.head = 0;
-        self.inner.tail = 0;
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T: 'a> Iterator for Drain<'a, T> {
-    type Item = T;
-
-    #[inline]
-    fn next(&mut self) -> Option<T> {
-        self.inner.pop_front()
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        let len = self.inner.len();
-        (len, Some(len))
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
-    #[inline]
-    fn next_back(&mut self) -> Option<T> {
-        self.inner.pop_back()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A: PartialEq> PartialEq for RingBuf<A> {
-    fn eq(&self, other: &RingBuf<A>) -> bool {
-        self.len() == other.len() &&
-            self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Eq> Eq for RingBuf<A> {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A: PartialOrd> PartialOrd for RingBuf<A> {
-    fn partial_cmp(&self, other: &RingBuf<A>) -> Option<Ordering> {
-        iter::order::partial_cmp(self.iter(), other.iter())
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Ord> Ord for RingBuf<A> {
-    #[inline]
-    fn cmp(&self, other: &RingBuf<A>) -> Ordering {
-        iter::order::cmp(self.iter(), other.iter())
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<S: Writer + Hasher, A: Hash<S>> Hash<S> for RingBuf<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")]
-impl<A> Index<usize> for RingBuf<A> {
-    type Output = A;
-
-    #[inline]
-    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 RingBuf<A> {
-    #[inline]
-    fn index_mut(&mut self, i: &usize) -> &mut A {
-        self.get_mut(*i).expect("Out of bounds access")
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A> FromIterator<A> for RingBuf<A> {
-    fn from_iter<T: Iterator<Item=A>>(iterator: T) -> RingBuf<A> {
-        let (lower, _) = iterator.size_hint();
-        let mut deq = RingBuf::with_capacity(lower);
-        deq.extend(iterator);
-        deq
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> IntoIterator for RingBuf<T> {
-    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, T> IntoIterator for &'a RingBuf<T> {
-    type Item = &'a T;
-    type IntoIter = Iter<'a, T>;
-
-    fn into_iter(self) -> Iter<'a, T> {
-        self.iter()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> IntoIterator for &'a mut RingBuf<T> {
-    type Item = &'a mut T;
-    type IntoIter = IterMut<'a, T>;
-
-    fn into_iter(mut self) -> IterMut<'a, T> {
-        self.iter_mut()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A> Extend<A> for RingBuf<A> {
-    fn extend<T: Iterator<Item=A>>(&mut self, iterator: T) {
-        for elt in iterator {
-            self.push_back(elt);
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: fmt::Debug> fmt::Debug for RingBuf<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "RingBuf ["));
-
-        for (i, e) in self.iter().enumerate() {
-            if i != 0 { try!(write!(f, ", ")); }
-            try!(write!(f, "{:?}", *e));
-        }
-
-        write!(f, "]")
-    }
-}
-
-#[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;
-    use test;
-
-    use super::RingBuf;
-
-    #[test]
-    #[allow(deprecated)]
-    fn test_simple() {
-        let mut d = RingBuf::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 = RingBuf::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 = RingBuf::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 = RingBuf::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 = RingBuf::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 = RingBuf::new();
-        for i in 1..4 {
-            deq.push_front(i);
-        }
-        deq[3];
-    }
-
-    #[bench]
-    fn bench_new(b: &mut test::Bencher) {
-        b.iter(|| {
-            let ring: RingBuf<i32> = RingBuf::new();
-            test::black_box(ring);
-        })
-    }
-
-    #[bench]
-    fn bench_push_back_100(b: &mut test::Bencher) {
-        let mut deq = RingBuf::with_capacity(101);
-        b.iter(|| {
-            for i in 0..100 {
-                deq.push_back(i);
-            }
-            deq.head = 0;
-            deq.tail = 0;
-        })
-    }
-
-    #[bench]
-    fn bench_push_front_100(b: &mut test::Bencher) {
-        let mut deq = RingBuf::with_capacity(101);
-        b.iter(|| {
-            for i in 0..100 {
-                deq.push_front(i);
-            }
-            deq.head = 0;
-            deq.tail = 0;
-        })
-    }
-
-    #[bench]
-    fn bench_pop_back_100(b: &mut test::Bencher) {
-        let mut deq= RingBuf::<i32>::with_capacity(101);
-
-        b.iter(|| {
-            deq.head = 100;
-            deq.tail = 0;
-            while !deq.is_empty() {
-                test::black_box(deq.pop_back());
-            }
-        })
-    }
-
-    #[bench]
-    fn bench_pop_front_100(b: &mut test::Bencher) {
-        let mut deq = RingBuf::<i32>::with_capacity(101);
-
-        b.iter(|| {
-            deq.head = 100;
-            deq.tail = 0;
-            while !deq.is_empty() {
-                test::black_box(deq.pop_front());
-            }
-        })
-    }
-
-    #[bench]
-    fn bench_grow_1025(b: &mut test::Bencher) {
-        b.iter(|| {
-            let mut deq = RingBuf::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: RingBuf<_> = (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: RingBuf<_> = (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(i32),
-        Twopar(i32, i32),
-        Threepar(i32, i32, i32),
-    }
-
-    #[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 = RingBuf::with_capacity(0);
-        d.push_back(1);
-        assert_eq!(d.len(), 1);
-        let mut d = RingBuf::with_capacity(50);
-        d.push_back(1);
-        assert_eq!(d.len(), 1);
-    }
-
-    #[test]
-    fn test_with_capacity_non_power_two() {
-        let mut d3 = RingBuf::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
-        // RingBuf 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 = RingBuf::new();
-        d.push_back(0);
-        d.reserve_exact(50);
-        assert!(d.capacity() >= 51);
-    }
-
-    #[test]
-    fn test_reserve() {
-        let mut d = RingBuf::new();
-        d.push_back(0);
-        d.reserve(50);
-        assert!(d.capacity() >= 51);
-    }
-
-    #[test]
-    fn test_swap() {
-        let mut d: RingBuf<_> = (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 = RingBuf::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 = RingBuf::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 = RingBuf::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 = RingBuf::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 = RingBuf::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: RingBuf<i32> = RingBuf::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 = RingBuf::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 = RingBuf::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 = RingBuf::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: RingBuf<i32> = RingBuf::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 = RingBuf::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 = RingBuf::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: RingBuf<_> = RingBuf::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: RingBuf<_> = 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: RingBuf<_> = 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 = RingBuf::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 = RingBuf::new();
-        assert!(d == RingBuf::with_capacity(0));
-        d.push_front(137);
-        d.push_front(17);
-        d.push_front(42);
-        d.push_back(137);
-        let mut e = RingBuf::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 == RingBuf::new());
-    }
-
-    #[test]
-    fn test_hash() {
-      let mut x = RingBuf::new();
-      let mut y = RingBuf::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 = RingBuf::new();
-        let mut y = RingBuf::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: RingBuf<_> = (0..10).collect();
-        assert_eq!(format!("{:?}", ringbuf), "RingBuf [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
-
-        let ringbuf: RingBuf<_> = vec!["just", "one", "test", "more"].iter()
-                                                                        .cloned()
-                                                                        .collect();
-        assert_eq!(format!("{:?}", ringbuf), "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 = RingBuf::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 = RingBuf::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 = RingBuf::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 = RingBuf::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 = RingBuf::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 = RingBuf::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 = RingBuf::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 = RingBuf::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) {
-            // This test checks that every single combination of tail position and length is tested.
-            // Capacity 15 should be large enough to cover every case.
-            let mut tester = RingBuf::with_capacity(15);
-            let usable_cap = tester.capacity();
-            let final_len = usable_cap / 2;
-
-            for len in 0..final_len {
-                let expected = if back {
-                    (0..len).collect()
-                } else {
-                    (0..len).rev().collect()
-                };
-                for tail_pos in 0..usable_cap {
-                    tester.tail = tail_pos;
-                    tester.head = tail_pos;
-                    if back {
-                        for i in 0..len * 2 {
-                            tester.push_front(i);
-                        }
-                        for i in 0..len {
-                            assert_eq!(tester.swap_back_remove(i), Some(len * 2 - 1 - i));
-                        }
-                    } else {
-                        for i in 0..len * 2 {
-                            tester.push_back(i);
-                        }
-                        for i in 0..len {
-                            let idx = tester.len() - 1 - i;
-                            assert_eq!(tester.swap_front_remove(idx), Some(len * 2 - 1 - i));
-                        }
-                    }
-                    assert!(tester.tail < tester.cap);
-                    assert!(tester.head < tester.cap);
-                    assert_eq!(tester, expected);
-                }
-            }
-        }
-        test(true);
-        test(false);
-    }
-
-    #[test]
-    fn test_insert() {
-        // This test checks that every single combination of tail position, length, and
-        // insertion position is tested. Capacity 15 should be large enough to cover every case.
-
-        let mut tester = RingBuf::with_capacity(15);
-        // can't guarantee we got 15, so have to get what we got.
-        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
-        // this test isn't covering what it wants to
-        let cap = tester.capacity();
-
-
-        // 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();
-            for tail_pos in 0..cap {
-                for to_insert in 0..len {
-                    tester.tail = tail_pos;
-                    tester.head = tail_pos;
-                    for i in 0..len {
-                        if i != to_insert {
-                            tester.push_back(i);
-                        }
-                    }
-                    tester.insert(to_insert, to_insert);
-                    assert!(tester.tail < tester.cap);
-                    assert!(tester.head < tester.cap);
-                    assert_eq!(tester, expected);
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn test_remove() {
-        // This test checks that every single combination of tail position, length, and
-        // removal position is tested. Capacity 15 should be large enough to cover every case.
-
-        let mut tester = RingBuf::with_capacity(15);
-        // can't guarantee we got 15, so have to get what we got.
-        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
-        // this test isn't covering what it wants to
-        let cap = tester.capacity();
-
-        // 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();
-            for tail_pos in 0..cap {
-                for to_remove in 0..len + 1 {
-                    tester.tail = tail_pos;
-                    tester.head = tail_pos;
-                    for i in 0..len {
-                        if i == to_remove {
-                            tester.push_back(1234);
-                        }
-                        tester.push_back(i);
-                    }
-                    if to_remove == len {
-                        tester.push_back(1234);
-                    }
-                    tester.remove(to_remove);
-                    assert!(tester.tail < tester.cap);
-                    assert!(tester.head < tester.cap);
-                    assert_eq!(tester, expected);
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn test_shrink_to_fit() {
-        // This test checks that every single combination of head and tail position,
-        // is tested. Capacity 15 should be large enough to cover every case.
-
-        let mut tester = RingBuf::with_capacity(15);
-        // can't guarantee we got 15, so have to get what we got.
-        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
-        // this test isn't covering what it wants to
-        let cap = tester.capacity();
-        tester.reserve(63);
-        let max_cap = tester.capacity();
-
-        for len in 0..cap + 1 {
-            // 0, 1, 2, .., len - 1
-            let expected = iter::count(0, 1).take(len).collect();
-            for tail_pos in 0..max_cap + 1 {
-                tester.tail = tail_pos;
-                tester.head = tail_pos;
-                tester.reserve(63);
-                for i in 0..len {
-                    tester.push_back(i);
-                }
-                tester.shrink_to_fit();
-                assert!(tester.capacity() <= cap);
-                assert!(tester.tail < tester.cap);
-                assert!(tester.head < tester.cap);
-                assert_eq!(tester, expected);
-            }
-        }
-    }
-
-    #[test]
-    fn test_front() {
-        let mut ring = RingBuf::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: RingBuf<i32> = RingBuf::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: RingBuf<i32> = RingBuf::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
-        // split position is tested. Capacity 15 should be large enough to cover every case.
-
-        let mut tester = RingBuf::with_capacity(15);
-        // can't guarantee we got 15, so have to get what we got.
-        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
-        // this test isn't covering what it wants to
-        let cap = tester.capacity();
-
-        // len is the length *before* splitting
-        for len in 0..cap {
-            // 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();
-                // at, at + 1, .., len - 1 (may be empty)
-                let expected_other = iter::count(at, 1).take(len - at).collect();
-
-                for tail_pos in 0..cap {
-                    tester.tail = tail_pos;
-                    tester.head = tail_pos;
-                    for i in 0..len {
-                        tester.push_back(i);
-                    }
-                    let result = tester.split_off(at);
-                    assert!(tester.tail < tester.cap);
-                    assert!(tester.head < tester.cap);
-                    assert!(result.tail < result.cap);
-                    assert!(result.head < result.cap);
-                    assert_eq!(tester, expected_self);
-                    assert_eq!(result, expected_other);
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn test_append() {
-        let mut a: RingBuf<_> = vec![1, 2, 3].into_iter().collect();
-        let mut b: RingBuf<_> = 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 06ae8127c00fbf3cf1c8dfb74d1a5043267df350..776b8b3af147c262b31fafccd74c9b376f070279 100644 (file)
@@ -88,7 +88,6 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use alloc::boxed::Box;
-use core::borrow::{BorrowFrom, BorrowFromMut, ToOwned};
 use core::clone::Clone;
 use core::cmp::Ordering::{self, Greater, Less};
 use core::cmp::{self, Ord, PartialEq};
 use core::slice as core_slice;
 use self::Direction::*;
 
+use borrow::{Borrow, BorrowMut, ToOwned};
 use vec::Vec;
 
 pub use core::slice::{Chunks, AsSlice, Windows};
@@ -1175,18 +1175,19 @@ pub fn new(length: usize) -> ElementSwaps {
 // Standard trait implementations for slices
 ////////////////////////////////////////////////////////////////////////////////
 
-#[unstable(feature = "collections", reason = "trait is unstable")]
-impl<T> BorrowFrom<Vec<T>> for [T] {
-    fn borrow_from(owned: &Vec<T>) -> &[T] { &owned[] }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> Borrow<[T]> for Vec<T> {
+    fn borrow(&self) -> &[T] { &self[..] }
 }
 
-#[unstable(feature = "collections", reason = "trait is unstable")]
-impl<T> BorrowFromMut<Vec<T>> for [T] {
-    fn borrow_from_mut(owned: &mut Vec<T>) -> &mut [T] { &mut owned[] }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> BorrowMut<[T]> for Vec<T> {
+    fn borrow_mut(&mut self) -> &mut [T] { &mut self[..] }
 }
 
-#[unstable(feature = "collections", reason = "trait is unstable")]
-impl<T: Clone> ToOwned<Vec<T>> for [T] {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Clone> ToOwned for [T] {
+    type Owned = Vec<T>;
     fn to_owned(&self) -> Vec<T> { self.to_vec() }
 }
 
@@ -1743,7 +1744,7 @@ fn test_slice() {
     #[test]
     fn test_slice_from() {
         let vec: &[_] = &[1, 2, 3, 4];
-        assert_eq!(&vec[], vec);
+        assert_eq!(&vec[..], vec);
         let b: &[_] = &[3, 4];
         assert_eq!(&vec[2..], b);
         let b: &[_] = &[];
@@ -2264,15 +2265,15 @@ fn test_permute_fail() {
     #[test]
     fn test_total_ord() {
         let c = &[1, 2, 3];
-        [1, 2, 3, 4][].cmp(c) == Greater;
+        [1, 2, 3, 4][..].cmp(c) == Greater;
         let c = &[1, 2, 3, 4];
-        [1, 2, 3][].cmp(c) == Less;
+        [1, 2, 3][..].cmp(c) == Less;
         let c = &[1, 2, 3, 6];
-        [1, 2, 3, 4][].cmp(c) == Equal;
+        [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;
+        [1, 2, 3, 4, 5, 5, 5, 5][..].cmp(c) == Less;
         let c = &[1, 2, 3, 4];
-        [2, 2][].cmp(c) == Greater;
+        [2, 2][..].cmp(c) == Greater;
     }
 
     #[test]
index 2d4dc2bcf30d35bfbd53d8b88abd2924cbf5cf55..ec0a487acdc77c734c2ae207624c869e95708e25 100644 (file)
@@ -55,7 +55,6 @@
 use self::RecompositionState::*;
 use self::DecompositionType::*;
 
-use core::borrow::{BorrowFrom, ToOwned};
 use core::char::CharExt;
 use core::clone::Clone;
 use core::iter::AdditiveIterator;
@@ -68,7 +67,8 @@
 use core::str as core_str;
 use unicode::str::{UnicodeStr, Utf16Encoder};
 
-use ring_buf::RingBuf;
+use vec_deque::VecDeque;
+use borrow::{Borrow, ToOwned};
 use slice::SliceExt;
 use string::String;
 use unicode;
@@ -261,7 +261,7 @@ enum RecompositionState {
 pub struct Recompositions<'a> {
     iter: Decompositions<'a>,
     state: RecompositionState,
-    buffer: RingBuf<char>,
+    buffer: VecDeque<char>,
     composee: Option<char>,
     last_ccc: Option<u8>
 }
@@ -386,13 +386,14 @@ macro_rules! utf8_acc_cont_byte {
     ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as u32)
 }
 
-#[unstable(feature = "collections", reason = "trait is unstable")]
-impl BorrowFrom<String> for str {
-    fn borrow_from(owned: &String) -> &str { &owned[] }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Borrow<str> for String {
+    fn borrow(&self) -> &str { &self[..] }
 }
 
-#[unstable(feature = "collections", reason = "trait is unstable")]
-impl ToOwned<String> for str {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl ToOwned for str {
+    type Owned = String;
     fn to_owned(&self) -> String {
         unsafe {
             String::from_utf8_unchecked(self.as_bytes().to_owned())
@@ -466,7 +467,7 @@ fn replace(&self, from: &str, to: &str) -> String {
                reason = "this functionality may be moved to libunicode")]
     fn nfd_chars(&self) -> Decompositions {
         Decompositions {
-            iter: self[].chars(),
+            iter: self[..].chars(),
             buffer: Vec::new(),
             sorted: false,
             kind: Canonical
@@ -480,7 +481,7 @@ fn nfd_chars(&self) -> Decompositions {
                reason = "this functionality may be moved to libunicode")]
     fn nfkd_chars(&self) -> Decompositions {
         Decompositions {
-            iter: self[].chars(),
+            iter: self[..].chars(),
             buffer: Vec::new(),
             sorted: false,
             kind: Compatible
@@ -496,7 +497,7 @@ fn nfc_chars(&self) -> Recompositions {
         Recompositions {
             iter: self.nfd_chars(),
             state: Composing,
-            buffer: RingBuf::new(),
+            buffer: VecDeque::new(),
             composee: None,
             last_ccc: None
         }
@@ -511,7 +512,7 @@ fn nfkc_chars(&self) -> Recompositions {
         Recompositions {
             iter: self.nfkd_chars(),
             state: Composing,
-            buffer: RingBuf::new(),
+            buffer: VecDeque::new(),
             composee: None,
             last_ccc: None
         }
@@ -530,7 +531,7 @@ fn nfkc_chars(&self) -> Recompositions {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn contains(&self, pat: &str) -> bool {
-        core_str::StrExt::contains(&self[], pat)
+        core_str::StrExt::contains(&self[..], pat)
     }
 
     /// Returns true if a string contains a char pattern.
@@ -547,7 +548,7 @@ fn contains(&self, pat: &str) -> bool {
     #[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)
+        core_str::StrExt::contains_char(&self[..], pat)
     }
 
     /// An iterator over the characters of `self`. Note, this iterates
@@ -561,7 +562,7 @@ fn contains_char<P: CharEq>(&self, pat: P) -> bool {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn chars(&self) -> Chars {
-        core_str::StrExt::chars(&self[])
+        core_str::StrExt::chars(&self[..])
     }
 
     /// An iterator over the bytes of `self`
@@ -574,13 +575,13 @@ fn chars(&self) -> Chars {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn bytes(&self) -> Bytes {
-        core_str::StrExt::bytes(&self[])
+        core_str::StrExt::bytes(&self[..])
     }
 
     /// An iterator over the characters of `self` and their byte offsets.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn char_indices(&self) -> CharIndices {
-        core_str::StrExt::char_indices(&self[])
+        core_str::StrExt::char_indices(&self[..])
     }
 
     /// An iterator over substrings of `self`, separated by characters
@@ -603,7 +604,7 @@ fn char_indices(&self) -> CharIndices {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn split<P: CharEq>(&self, pat: P) -> Split<P> {
-        core_str::StrExt::split(&self[], pat)
+        core_str::StrExt::split(&self[..], pat)
     }
 
     /// An iterator over substrings of `self`, separated by characters
@@ -630,7 +631,7 @@ fn split<P: CharEq>(&self, pat: P) -> Split<P> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn splitn<P: CharEq>(&self, count: usize, pat: P) -> SplitN<P> {
-        core_str::StrExt::splitn(&self[], count, pat)
+        core_str::StrExt::splitn(&self[..], count, pat)
     }
 
     /// An iterator over substrings of `self`, separated by characters
@@ -659,7 +660,7 @@ fn splitn<P: CharEq>(&self, count: usize, pat: P) -> SplitN<P> {
     /// ```
     #[unstable(feature = "collections", reason = "might get removed")]
     fn split_terminator<P: CharEq>(&self, pat: P) -> SplitTerminator<P> {
-        core_str::StrExt::split_terminator(&self[], pat)
+        core_str::StrExt::split_terminator(&self[..], pat)
     }
 
     /// An iterator over substrings of `self`, separated by characters
@@ -680,7 +681,7 @@ fn split_terminator<P: CharEq>(&self, pat: P) -> SplitTerminator<P> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn rsplitn<P: CharEq>(&self, count: usize, pat: P) -> RSplitN<P> {
-        core_str::StrExt::rsplitn(&self[], count, pat)
+        core_str::StrExt::rsplitn(&self[..], count, pat)
     }
 
     /// An iterator over the start and end indices of the disjoint
@@ -706,7 +707,7 @@ fn rsplitn<P: CharEq>(&self, count: usize, pat: P) -> RSplitN<P> {
     #[unstable(feature = "collections",
                reason = "might have its iterator type changed")]
     fn match_indices<'a>(&'a self, pat: &'a str) -> MatchIndices<'a> {
-        core_str::StrExt::match_indices(&self[], pat)
+        core_str::StrExt::match_indices(&self[..], pat)
     }
 
     /// An iterator over the substrings of `self` separated by the pattern `sep`.
@@ -723,7 +724,7 @@ fn match_indices<'a>(&'a self, pat: &'a str) -> MatchIndices<'a> {
     #[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)
+        core_str::StrExt::split_str(&self[..], pat)
     }
 
     /// An iterator over the lines of a string (subsequences separated
@@ -739,7 +740,7 @@ fn split_str<'a>(&'a self, pat: &'a str) -> SplitStr<'a> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn lines(&self) -> Lines {
-        core_str::StrExt::lines(&self[])
+        core_str::StrExt::lines(&self[..])
     }
 
     /// An iterator over the lines of a string, separated by either
@@ -755,7 +756,7 @@ fn lines(&self) -> Lines {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn lines_any(&self) -> LinesAny {
-        core_str::StrExt::lines_any(&self[])
+        core_str::StrExt::lines_any(&self[..])
     }
 
     /// Deprecated: use `s[a .. b]` instead.
@@ -802,7 +803,7 @@ fn lines_any(&self) -> LinesAny {
     #[unstable(feature = "collections",
                reason = "may have yet to prove its worth")]
     fn slice_chars(&self, begin: usize, end: usize) -> &str {
-        core_str::StrExt::slice_chars(&self[], begin, end)
+        core_str::StrExt::slice_chars(&self[..], begin, end)
     }
 
     /// Takes a bytewise (not UTF-8) slice from a string.
@@ -813,7 +814,7 @@ fn slice_chars(&self, begin: usize, end: usize) -> &str {
     /// the entire slice as well.
     #[stable(feature = "rust1", since = "1.0.0")]
     unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
-        core_str::StrExt::slice_unchecked(&self[], begin, end)
+        core_str::StrExt::slice_unchecked(&self[..], begin, end)
     }
 
     /// Returns true if the pattern `pat` is a prefix of the string.
@@ -825,7 +826,7 @@ unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn starts_with(&self, pat: &str) -> bool {
-        core_str::StrExt::starts_with(&self[], pat)
+        core_str::StrExt::starts_with(&self[..], pat)
     }
 
     /// Returns true if the pattern `pat` is a suffix of the string.
@@ -837,7 +838,7 @@ fn starts_with(&self, pat: &str) -> bool {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn ends_with(&self, pat: &str) -> bool {
-        core_str::StrExt::ends_with(&self[], pat)
+        core_str::StrExt::ends_with(&self[..], pat)
     }
 
     /// Returns a string with all pre- and suffixes that match
@@ -857,7 +858,7 @@ fn ends_with(&self, pat: &str) -> bool {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn trim_matches<P: CharEq>(&self, pat: P) -> &str {
-        core_str::StrExt::trim_matches(&self[], pat)
+        core_str::StrExt::trim_matches(&self[..], pat)
     }
 
     /// Returns a string with all prefixes that match
@@ -877,7 +878,7 @@ fn trim_matches<P: CharEq>(&self, pat: P) -> &str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn trim_left_matches<P: CharEq>(&self, pat: P) -> &str {
-        core_str::StrExt::trim_left_matches(&self[], pat)
+        core_str::StrExt::trim_left_matches(&self[..], pat)
     }
 
     /// Returns a string with all suffixes that match
@@ -897,7 +898,7 @@ fn trim_left_matches<P: CharEq>(&self, pat: P) -> &str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn trim_right_matches<P: CharEq>(&self, pat: P) -> &str {
-        core_str::StrExt::trim_right_matches(&self[], pat)
+        core_str::StrExt::trim_right_matches(&self[..], pat)
     }
 
     /// Check that `index`-th byte lies at the start and/or end of a
@@ -926,7 +927,7 @@ fn trim_right_matches<P: CharEq>(&self, pat: P) -> &str {
     #[unstable(feature = "collections",
                reason = "naming is uncertain with container conventions")]
     fn is_char_boundary(&self, index: usize) -> bool {
-        core_str::StrExt::is_char_boundary(&self[], index)
+        core_str::StrExt::is_char_boundary(&self[..], index)
     }
 
     /// Pluck a character out of a string and return the index of the next
@@ -985,7 +986,7 @@ fn is_char_boundary(&self, index: usize) -> bool {
     #[unstable(feature = "collections",
                reason = "naming is uncertain with container conventions")]
     fn char_range_at(&self, start: usize) -> CharRange {
-        core_str::StrExt::char_range_at(&self[], start)
+        core_str::StrExt::char_range_at(&self[..], start)
     }
 
     /// Given a byte position and a str, return the previous char and its position.
@@ -1001,7 +1002,7 @@ fn char_range_at(&self, start: usize) -> CharRange {
     #[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)
+        core_str::StrExt::char_range_at_reverse(&self[..], start)
     }
 
     /// Plucks the character starting at the `i`th byte of a string.
@@ -1022,7 +1023,7 @@ fn char_range_at_reverse(&self, start: usize) -> CharRange {
     #[unstable(feature = "collections",
                reason = "naming is uncertain with container conventions")]
     fn char_at(&self, i: usize) -> char {
-        core_str::StrExt::char_at(&self[], i)
+        core_str::StrExt::char_at(&self[..], i)
     }
 
     /// Plucks the character ending at the `i`th byte of a string.
@@ -1034,7 +1035,7 @@ fn char_at(&self, i: usize) -> char {
     #[unstable(feature = "collections",
                reason = "naming is uncertain with container conventions")]
     fn char_at_reverse(&self, i: usize) -> char {
-        core_str::StrExt::char_at_reverse(&self[], i)
+        core_str::StrExt::char_at_reverse(&self[..], i)
     }
 
     /// Work with the byte buffer of a string as a byte slice.
@@ -1046,7 +1047,7 @@ fn char_at_reverse(&self, i: usize) -> char {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn as_bytes(&self) -> &[u8] {
-        core_str::StrExt::as_bytes(&self[])
+        core_str::StrExt::as_bytes(&self[..])
     }
 
     /// Returns the byte index of the first character of `self` that
@@ -1074,7 +1075,7 @@ fn as_bytes(&self) -> &[u8] {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn find<P: CharEq>(&self, pat: P) -> Option<usize> {
-        core_str::StrExt::find(&self[], pat)
+        core_str::StrExt::find(&self[..], pat)
     }
 
     /// Returns the byte index of the last character of `self` that
@@ -1102,7 +1103,7 @@ fn find<P: CharEq>(&self, pat: P) -> Option<usize> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn rfind<P: CharEq>(&self, pat: P) -> Option<usize> {
-        core_str::StrExt::rfind(&self[], pat)
+        core_str::StrExt::rfind(&self[..], pat)
     }
 
     /// Returns the byte index of the first matching substring
@@ -1127,7 +1128,7 @@ fn rfind<P: CharEq>(&self, pat: P) -> Option<usize> {
     #[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)
+        core_str::StrExt::find_str(&self[..], needle)
     }
 
     /// Retrieves the first character from a string slice and returns
@@ -1151,7 +1152,7 @@ fn find_str(&self, needle: &str) -> Option<usize> {
     #[unstable(feature = "collections",
                reason = "awaiting conventions about shifting and slices")]
     fn slice_shift_char(&self) -> Option<(char, &str)> {
-        core_str::StrExt::slice_shift_char(&self[])
+        core_str::StrExt::slice_shift_char(&self[..])
     }
 
     /// Returns the byte offset of an inner slice relative to an enclosing outer slice.
@@ -1171,7 +1172,7 @@ fn slice_shift_char(&self) -> Option<(char, &str)> {
     #[unstable(feature = "collections",
                reason = "awaiting convention about comparability of arbitrary slices")]
     fn subslice_offset(&self, inner: &str) -> usize {
-        core_str::StrExt::subslice_offset(&self[], inner)
+        core_str::StrExt::subslice_offset(&self[..], inner)
     }
 
     /// Return an unsafe pointer to the strings buffer.
@@ -1182,14 +1183,14 @@ fn subslice_offset(&self, inner: &str) -> usize {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     fn as_ptr(&self) -> *const u8 {
-        core_str::StrExt::as_ptr(&self[])
+        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 {
-        Utf16Units { encoder: Utf16Encoder::new(self[].chars()) }
+        Utf16Units { encoder: Utf16Encoder::new(self[..].chars()) }
     }
 
     /// Return the number of bytes in this string
@@ -1203,7 +1204,7 @@ fn utf16_units(&self) -> Utf16Units {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     fn len(&self) -> usize {
-        core_str::StrExt::len(&self[])
+        core_str::StrExt::len(&self[..])
     }
 
     /// Returns true if this slice contains no bytes
@@ -1216,7 +1217,7 @@ fn len(&self) -> usize {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn is_empty(&self) -> bool {
-        core_str::StrExt::is_empty(&self[])
+        core_str::StrExt::is_empty(&self[..])
     }
 
     /// Parse this string into the specified type.
@@ -1230,7 +1231,7 @@ fn is_empty(&self) -> bool {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
-        core_str::StrExt::parse(&self[])
+        core_str::StrExt::parse(&self[..])
     }
 
     /// Returns an iterator over the
@@ -1255,7 +1256,7 @@ fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
     #[unstable(feature = "collections",
                reason = "this functionality may only be provided by libunicode")]
     fn graphemes(&self, is_extended: bool) -> Graphemes {
-        UnicodeStr::graphemes(&self[], is_extended)
+        UnicodeStr::graphemes(&self[..], is_extended)
     }
 
     /// Returns an iterator over the grapheme clusters of self and their byte offsets.
@@ -1271,7 +1272,7 @@ fn graphemes(&self, is_extended: bool) -> Graphemes {
     #[unstable(feature = "collections",
                reason = "this functionality may only be provided by libunicode")]
     fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices {
-        UnicodeStr::grapheme_indices(&self[], is_extended)
+        UnicodeStr::grapheme_indices(&self[..], is_extended)
     }
 
     /// An iterator over the words of a string (subsequences separated
@@ -1288,7 +1289,7 @@ fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices {
     #[unstable(feature = "str_words",
                reason = "the precise algorithm to use is unclear")]
     fn words(&self) -> Words {
-        UnicodeStr::words(&self[])
+        UnicodeStr::words(&self[..])
     }
 
     /// Returns a string's displayed width in columns, treating control
@@ -1303,25 +1304,25 @@ fn words(&self) -> Words {
     #[unstable(feature = "collections",
                reason = "this functionality may only be provided by libunicode")]
     fn width(&self, is_cjk: bool) -> usize {
-        UnicodeStr::width(&self[], is_cjk)
+        UnicodeStr::width(&self[..], is_cjk)
     }
 
     /// Returns a string with leading and trailing whitespace removed.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn trim(&self) -> &str {
-        UnicodeStr::trim(&self[])
+        UnicodeStr::trim(&self[..])
     }
 
     /// Returns a string with leading whitespace removed.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn trim_left(&self) -> &str {
-        UnicodeStr::trim_left(&self[])
+        UnicodeStr::trim_left(&self[..])
     }
 
     /// Returns a string with trailing whitespace removed.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn trim_right(&self) -> &str {
-        UnicodeStr::trim_right(&self[])
+        UnicodeStr::trim_right(&self[..])
     }
 }
 
@@ -2704,7 +2705,7 @@ fn test_graphemes() {
             &["\u{378}\u{308}\u{903}"], &["\u{378}\u{308}", "\u{903}"]),
         ];
 
-        for &(s, g) in &test_same[] {
+        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()));
index 69fd28d1723685067d77df6a650b693f6f7b09c2..3b179d0b94c97cccddcdef0ddd6c7c070270cfc1 100644 (file)
 
 use core::prelude::*;
 
-use core::borrow::{Cow, IntoCow};
 use core::default::Default;
 use core::error::Error;
 use core::fmt;
 use core::hash;
-use core::iter::FromIterator;
+use core::iter::{IntoIterator, FromIterator};
 use core::mem;
 use core::ops::{self, Deref, Add, Index};
 use core::ptr;
@@ -29,6 +28,7 @@
 use unicode::str as unicode_str;
 use unicode::str::Utf16Item;
 
+use borrow::{Cow, IntoCow};
 use str::{self, CharRange, FromStr, Utf8Error};
 use vec::{DerefVec, Vec, as_vec};
 
@@ -142,7 +142,7 @@ pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
     /// assert_eq!(output.as_slice(), "Hello \u{FFFD}World");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> CowString<'a> {
+    pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> {
         let mut i = 0;
         match str::from_utf8(v) {
             Ok(s) => return Cow::Borrowed(s),
@@ -709,18 +709,18 @@ fn description(&self) -> &str { "invalid utf-16" }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl FromIterator<char> for String {
-    fn from_iter<I:Iterator<Item=char>>(iterator: I) -> String {
+    fn from_iter<I: IntoIterator<Item=char>>(iter: I) -> String {
         let mut buf = String::new();
-        buf.extend(iterator);
+        buf.extend(iter);
         buf
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> FromIterator<&'a str> for String {
-    fn from_iter<I:Iterator<Item=&'a str>>(iterator: I) -> String {
+    fn from_iter<I: IntoIterator<Item=&'a str>>(iter: I) -> String {
         let mut buf = String::new();
-        buf.extend(iterator);
+        buf.extend(iter);
         buf
     }
 }
@@ -728,7 +728,8 @@ fn from_iter<I:Iterator<Item=&'a str>>(iterator: I) -> String {
 #[unstable(feature = "collections",
            reason = "waiting on Extend stabilization")]
 impl Extend<char> for String {
-    fn extend<I:Iterator<Item=char>>(&mut self, iterator: I) {
+    fn extend<I: IntoIterator<Item=char>>(&mut self, iterable: I) {
+        let iterator = iterable.into_iter();
         let (lower_bound, _) = iterator.size_hint();
         self.reserve(lower_bound);
         for ch in iterator {
@@ -740,7 +741,8 @@ fn extend<I:Iterator<Item=char>>(&mut self, iterator: I) {
 #[unstable(feature = "collections",
            reason = "waiting on Extend stabilization")]
 impl<'a> Extend<&'a str> for String {
-    fn extend<I: Iterator<Item=&'a str>>(&mut self, iterator: I) {
+    fn extend<I: IntoIterator<Item=&'a str>>(&mut self, iterable: I) {
+        let iterator = iterable.into_iter();
         // A guess that at least one byte per iterator element will be needed.
         let (lower_bound, _) = iterator.size_hint();
         self.reserve(lower_bound);
@@ -780,10 +782,10 @@ fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) }
 }
 
 impl_eq! { String, &'a str }
-impl_eq! { CowString<'a>, String }
+impl_eq! { Cow<'a, str>, String }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b> PartialEq<&'b str> for CowString<'a> {
+impl<'a, 'b> PartialEq<&'b str> for Cow<'a, str> {
     #[inline]
     fn eq(&self, other: &&'b str) -> bool { PartialEq::eq(&**self, &**other) }
     #[inline]
@@ -791,11 +793,11 @@ fn ne(&self, other: &&'b str) -> bool { PartialEq::ne(&**self, &**other) }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b> PartialEq<CowString<'a>> for &'b str {
+impl<'a, 'b> PartialEq<Cow<'a, str>> for &'b str {
     #[inline]
-    fn eq(&self, other: &CowString<'a>) -> bool { PartialEq::eq(&**self, &**other) }
+    fn eq(&self, other: &Cow<'a, str>) -> bool { PartialEq::eq(&**self, &**other) }
     #[inline]
-    fn ne(&self, other: &CowString<'a>) -> bool { PartialEq::ne(&**self, &**other) }
+    fn ne(&self, other: &Cow<'a, str>) -> bool { PartialEq::ne(&**self, &**other) }
 }
 
 #[unstable(feature = "collections", reason = "waiting on Str stabilization")]
@@ -833,12 +835,21 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 #[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) {
+        (**self).hash(hasher)
+    }
+}
 
 #[unstable(feature = "collections",
            reason = "recent addition, needs more experience")]
@@ -857,7 +868,7 @@ impl ops::Index<ops::Range<usize>> for String {
     type Output = str;
     #[inline]
     fn index(&self, index: &ops::Range<usize>) -> &str {
-        &self[][*index]
+        &self[..][*index]
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -865,7 +876,7 @@ impl ops::Index<ops::RangeTo<usize>> for String {
     type Output = str;
     #[inline]
     fn index(&self, index: &ops::RangeTo<usize>) -> &str {
-        &self[][*index]
+        &self[..][*index]
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -873,7 +884,7 @@ impl ops::Index<ops::RangeFrom<usize>> for String {
     type Output = str;
     #[inline]
     fn index(&self, index: &ops::RangeFrom<usize>) -> &str {
-        &self[][*index]
+        &self[..][*index]
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -891,7 +902,7 @@ impl ops::Deref for String {
 
     #[inline]
     fn deref(&self) -> &str {
-        unsafe { mem::transmute(&self.vec[]) }
+        unsafe { mem::transmute(&self.vec[..]) }
     }
 }
 
@@ -958,31 +969,34 @@ fn to_string(&self) -> String {
     }
 }
 
-impl IntoCow<'static, String, str> for String {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl IntoCow<'static, str> for String {
     #[inline]
-    fn into_cow(self) -> CowString<'static> {
+    fn into_cow(self) -> Cow<'static, str> {
         Cow::Owned(self)
     }
 }
 
-impl<'a> IntoCow<'a, String, str> for &'a str {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> IntoCow<'a, str> for &'a str {
     #[inline]
-    fn into_cow(self) -> CowString<'a> {
+    fn into_cow(self) -> Cow<'a, str> {
         Cow::Borrowed(self)
     }
 }
 
-/// A clone-on-write string
-#[stable(feature = "rust1", since = "1.0.0")]
-pub type CowString<'a> = Cow<'a, String, str>;
-
-impl<'a> Str for CowString<'a> {
+impl<'a> Str for Cow<'a, str> {
     #[inline]
     fn as_slice<'b>(&'b self) -> &'b str {
         &**self
     }
 }
 
+/// 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]
@@ -1287,7 +1301,7 @@ fn insert() {
     #[test]
     fn test_slicing() {
         let s = "foobar".to_string();
-        assert_eq!("foobar", &s[]);
+        assert_eq!("foobar", &s[..]);
         assert_eq!("foo", &s[..3]);
         assert_eq!("bar", &s[3..]);
         assert_eq!("oob", &s[1..4]);
index bde733644b5b58e4cce2a263fa5813befb555b29..1cc2a5235abec1a1af6a5cfe6a7361a758d7910c 100644 (file)
 
 use alloc::boxed::Box;
 use alloc::heap::{EMPTY, allocate, reallocate, deallocate};
-use core::borrow::{Cow, IntoCow};
 use core::cmp::max;
 use core::cmp::{Ordering};
 use core::default::Default;
 use core::fmt;
 use core::hash::{self, Hash};
+use core::intrinsics::assume;
 use core::iter::{repeat, FromIterator, IntoIterator};
-use core::marker::{self, ContravariantLifetime, InvariantType};
+use core::marker::PhantomData;
 use core::mem;
-use core::nonzero::NonZero;
 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;
 
+use borrow::{Cow, IntoCow};
+
 /// A growable list type, written `Vec<T>` but pronounced 'vector.'
 ///
 /// # Examples
 #[unsafe_no_drop_flag]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Vec<T> {
-    ptr: NonZero<*mut T>,
+    ptr: Unique<T>,
     len: usize,
     cap: usize,
-    _own: marker::PhantomData<T>,
 }
 
 unsafe impl<T: Send> Send for Vec<T> { }
@@ -249,10 +250,9 @@ pub fn with_capacity(capacity: usize) -> Vec<T> {
     pub unsafe fn from_raw_parts(ptr: *mut T, length: usize,
                                  capacity: usize) -> Vec<T> {
         Vec {
-            ptr: NonZero::new(ptr),
+            ptr: Unique::new(ptr),
             len: length,
             cap: capacity,
-            _own: marker::PhantomData,
         }
     }
 
@@ -373,7 +373,7 @@ pub fn shrink_to_fit(&mut self) {
                                      self.len * mem::size_of::<T>(),
                                      mem::min_align_of::<T>()) as *mut T;
                 if ptr.is_null() { ::alloc::oom() }
-                self.ptr = NonZero::new(ptr);
+                self.ptr = Unique::new(ptr);
             }
             self.cap = self.len;
         }
@@ -655,7 +655,7 @@ pub fn push(&mut self, value: T) {
             unsafe {
                 let ptr = alloc_or_realloc(*self.ptr, old_size, size);
                 if ptr.is_null() { ::alloc::oom() }
-                self.ptr = NonZero::new(ptr);
+                self.ptr = Unique::new(ptr);
             }
             self.cap = max(self.cap, 2) * 2;
         }
@@ -756,7 +756,7 @@ pub fn drain(&mut self) -> Drain<T> {
             Drain {
                 ptr: begin,
                 end: end,
-                marker: ContravariantLifetime,
+                marker: PhantomData,
             }
         }
     }
@@ -871,6 +871,8 @@ pub fn map_in_place<U, F>(self, mut f: F) -> Vec<U> where F: FnMut(T) -> U {
                 end_t: unsafe { start.offset(offset) },
                 start_u: start as *mut U,
                 end_u: start as *mut U,
+
+                _marker: PhantomData,
             };
             //  start_t
             //  start_u
@@ -967,8 +969,7 @@ pub fn map_in_place<U, F>(self, mut f: F) -> Vec<U> where F: FnMut(T) -> U {
             let mut pv = PartialVecZeroSized::<T,U> {
                 num_t: vec.len(),
                 num_u: 0,
-                marker_t: InvariantType,
-                marker_u: InvariantType,
+                marker: PhantomData,
             };
             unsafe { mem::forget(vec); }
 
@@ -1226,7 +1227,7 @@ fn grow_capacity(&mut self, capacity: usize) {
             unsafe {
                 let ptr = alloc_or_realloc(*self.ptr, self.cap * mem::size_of::<T>(), size);
                 if ptr.is_null() { ::alloc::oom() }
-                self.ptr = NonZero::new(ptr);
+                self.ptr = Unique::new(ptr);
             }
             self.cap = capacity;
         }
@@ -1302,12 +1303,21 @@ fn clone_from(&mut self, other: &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) {
+        Hash::hash(&**self, state)
+    }
+}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Index<usize> for Vec<T> {
@@ -1407,7 +1417,8 @@ fn deref_mut(&mut self) -> &mut [T] { self.as_mut_slice() }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> FromIterator<T> for Vec<T> {
     #[inline]
-    fn from_iter<I:Iterator<Item=T>>(mut iterator: I) -> Vec<T> {
+    fn from_iter<I: IntoIterator<Item=T>>(iterable: I) -> Vec<T> {
+        let mut iterator = iterable.into_iter();
         let (lower, _) = iterator.size_hint();
         let mut vector = Vec::with_capacity(lower);
 
@@ -1480,7 +1491,8 @@ fn into_iter(mut self) -> slice::IterMut<'a, T> {
 #[unstable(feature = "collections", reason = "waiting on Extend stability")]
 impl<T> Extend<T> for Vec<T> {
     #[inline]
-    fn extend<I: Iterator<Item=T>>(&mut self, iterator: I) {
+    fn extend<I: IntoIterator<Item=T>>(&mut self, iterable: I) {
+        let iterator = iterable.into_iter();
         let (lower, _) = iterator.size_hint();
         self.reserve(lower);
         for element in iterator {
@@ -1517,34 +1529,34 @@ fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) }
 impl_eq! { Vec<A>, &'b [B] }
 impl_eq! { Vec<A>, &'b mut [B] }
 
-impl<'a, A, B> PartialEq<Vec<B>> for CowVec<'a, A> where A: PartialEq<B> + Clone {
+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<CowVec<'a, A>> for Vec<B> where A: Clone, B: PartialEq<A> {
+impl<'a, A, B> PartialEq<Cow<'a, [A]>> for Vec<B> where A: Clone, B: PartialEq<A> {
     #[inline]
-    fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
+    fn eq(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::eq(&**self, &**other) }
     #[inline]
-    fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) }
+    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 CowVec<'a, A> where A: PartialEq<B> + Clone {
+        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<CowVec<'a, A>> for $rhs where A: Clone, B: PartialEq<A> {
+        impl<'a, 'b, A, B> PartialEq<Cow<'a, [A]>> for $rhs where A: Clone, B: PartialEq<A> {
             #[inline]
-            fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
+            fn eq(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::eq(&**self, &**other) }
             #[inline]
-            fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) }
+            fn ne(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::ne(&**self, &**other) }
         }
     }
 }
@@ -1552,8 +1564,7 @@ fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) }
 impl_eq_for_cowvec! { &'b [B] }
 impl_eq_for_cowvec! { &'b mut [B] }
 
-#[unstable(feature = "collections",
-           reason = "waiting on PartialOrd stability")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: PartialOrd> PartialOrd for Vec<T> {
     #[inline]
     fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
@@ -1561,10 +1572,10 @@ fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
     }
 }
 
-#[unstable(feature = "collections", reason = "waiting on Eq stability")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Eq> Eq for Vec<T> {}
 
-#[unstable(feature = "collections", reason = "waiting on Ord stability")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Ord> Ord for Vec<T> {
     #[inline]
     fn cmp(&self, other: &Vec<T>) -> Ordering {
@@ -1587,8 +1598,12 @@ impl<T> AsSlice<T> for Vec<T> {
     #[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: *self.ptr,
+                data: p,
                 len: self.len
             })
         }
@@ -1643,26 +1658,26 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 // Clone-on-write
 ////////////////////////////////////////////////////////////////////////////////
 
-#[unstable(feature = "collections",
-           reason = "unclear how valuable this alias is")]
 /// A clone-on-write vector
-pub type CowVec<'a, T> = Cow<'a, Vec<T>, [T]>;
+#[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 CowVec<'a, T> where T: Clone {
-    fn from_iter<I: Iterator<Item=T>>(it: I) -> CowVec<'a, T> {
+impl<'a, T> FromIterator<T> for Cow<'a, [T]> where T: Clone {
+    fn from_iter<I: IntoIterator<Item=T>>(it: I) -> Cow<'a, [T]> {
         Cow::Owned(FromIterator::from_iter(it))
     }
 }
 
-impl<'a, T: 'a> IntoCow<'a, Vec<T>, [T]> for Vec<T> where T: Clone {
-    fn into_cow(self) -> CowVec<'a, T> {
+impl<'a, T: 'a> IntoCow<'a, [T]> for Vec<T> where T: Clone {
+    fn into_cow(self) -> Cow<'a, [T]> {
         Cow::Owned(self)
     }
 }
 
-impl<'a, T> IntoCow<'a, Vec<T>, [T]> for &'a [T] where T: Clone {
-    fn into_cow(self) -> CowVec<'a, T> {
+impl<'a, T> IntoCow<'a, [T]> for &'a [T] where T: Clone {
+    fn into_cow(self) -> Cow<'a, [T]> {
         Cow::Borrowed(self)
     }
 }
@@ -1779,10 +1794,10 @@ fn drop(&mut self) {
 #[unsafe_no_drop_flag]
 #[unstable(feature = "collections",
            reason = "recently added as part of collections reform 2")]
-pub struct Drain<'a, T> {
+pub struct Drain<'a, T:'a> {
     ptr: *const T,
     end: *const T,
-    marker: ContravariantLifetime<'a>,
+    marker: PhantomData<&'a T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1867,9 +1882,9 @@ fn drop(&mut self) {
 
 /// Wrapper type providing a `&Vec<T>` reference via `Deref`.
 #[unstable(feature = "collections")]
-pub struct DerefVec<'a, T> {
+pub struct DerefVec<'a, T:'a> {
     x: Vec<T>,
-    l: ContravariantLifetime<'a>
+    l: PhantomData<&'a T>,
 }
 
 #[unstable(feature = "collections")]
@@ -1897,7 +1912,7 @@ pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> {
     unsafe {
         DerefVec {
             x: Vec::from_raw_parts(x.as_ptr() as *mut T, x.len(), x.len()),
-            l: ContravariantLifetime::<'a>
+            l: PhantomData,
         }
     }
 }
@@ -1921,6 +1936,8 @@ struct PartialVecNonZeroSized<T,U> {
     end_u: *mut U,
     start_t: *mut T,
     end_t: *mut T,
+
+    _marker: PhantomData<U>,
 }
 
 /// An owned, partially type-converted vector of zero-sized elements.
@@ -1930,8 +1947,7 @@ struct PartialVecNonZeroSized<T,U> {
 struct PartialVecZeroSized<T,U> {
     num_t: usize,
     num_u: usize,
-    marker_t: InvariantType<T>,
-    marker_u: InvariantType<U>,
+    marker: PhantomData<::core::cell::Cell<(T,U)>>,
 }
 
 #[unsafe_destructor]
@@ -2589,7 +2605,7 @@ fn do_bench_from_slice(b: &mut Bencher, src_len: usize) {
         b.bytes = src_len as u64;
 
         b.iter(|| {
-            let dst = src.clone()[].to_vec();
+            let dst = src.clone()[..].to_vec();
             assert_eq!(dst.len(), src_len);
             assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
         });
diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs
new file mode 100644 (file)
index 0000000..3ba22a4
--- /dev/null
@@ -0,0 +1,2896 @@
+// 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.
+
+//! VecDeque is a double-ended queue, which is implemented with the help of a
+//! growing ring buffer.
+//!
+//! This queue has `O(1)` amortized inserts and removals from both ends of the
+//! container. It also has `O(1)` indexing like a vector. The contained elements
+//! are not required to be copyable, and the queue will be sendable if the
+//! contained type is sendable.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use core::prelude::*;
+
+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::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
+
+/// `VecDeque` is a growable ring buffer, which can be used as a
+/// double-ended queue efficiently.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct VecDeque<T> {
+    // tail and head are pointers into the buffer. Tail always points
+    // to the first element that could be read, Head always points
+    // to where data should be written.
+    // If tail == head the buffer is empty. The length of the ringbuf
+    // is defined as the distance between the two.
+
+    tail: usize,
+    head: usize,
+    cap: usize,
+    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> {
+        self.iter().cloned().collect()
+    }
+}
+
+#[unsafe_destructor]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> Drop for VecDeque<T> {
+    fn drop(&mut self) {
+        self.clear();
+        unsafe {
+            if mem::size_of::<T>() != 0 {
+                heap::deallocate(*self.ptr as *mut u8,
+                                 self.cap * mem::size_of::<T>(),
+                                 mem::min_align_of::<T>())
+            }
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> Default for VecDeque<T> {
+    #[inline]
+    fn default() -> VecDeque<T> { VecDeque::new() }
+}
+
+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 })
+    }
+
+    /// 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 })
+    }
+
+    /// Moves an element out of the buffer
+    #[inline]
+    unsafe fn buffer_read(&mut self, off: usize) -> T {
+        ptr::read(self.ptr.offset(off as isize))
+    }
+
+    /// Writes an element into the buffer, moving it.
+    #[inline]
+    unsafe fn buffer_write(&mut self, off: usize, t: T) {
+        ptr::write(self.ptr.offset(off as isize), t);
+    }
+
+    /// Returns true iff the buffer is at capacity
+    #[inline]
+    fn is_full(&self) -> bool { self.cap - self.len() == 1 }
+
+    /// Returns the index in the underlying buffer for a given logical element
+    /// index.
+    #[inline]
+    fn wrap_index(&self, idx: usize) -> usize { wrap_index(idx, 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) {
+        debug_assert!(dst + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
+                      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),
+            self.ptr.offset(src as isize),
+            len);
+    }
+
+    /// Copies a contiguous block of memory len long from src to dst
+    #[inline]
+    unsafe fn copy_nonoverlapping(&self, dst: usize, src: usize, len: usize) {
+        debug_assert!(dst + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
+                      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),
+            self.ptr.offset(src as isize),
+            len);
+    }
+}
+
+impl<T> VecDeque<T> {
+    /// Creates an empty `VecDeque`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn new() -> VecDeque<T> {
+        VecDeque::with_capacity(INITIAL_CAPACITY)
+    }
+
+    /// Creates an empty `VecDeque` with space for at least `n` elements.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn with_capacity(n: usize) -> VecDeque<T> {
+        // +1 since the ringbuffer always leaves one space empty
+        let cap = cmp::max(n + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
+        assert!(cap > n, "capacity overflow");
+        let size = cap.checked_mul(mem::size_of::<T>())
+                      .expect("capacity overflow");
+
+        let ptr = unsafe {
+            if mem::size_of::<T>() != 0 {
+                let ptr = heap::allocate(size, mem::min_align_of::<T>())  as *mut T;;
+                if ptr.is_null() { ::alloc::oom() }
+                Unique::new(ptr)
+            } else {
+                Unique::new(heap::EMPTY as *mut T)
+            }
+        };
+
+        VecDeque {
+            tail: 0,
+            head: 0,
+            cap: cap,
+            ptr: ptr,
+        }
+    }
+
+    /// Retrieves an element in the `VecDeque` by index.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// buf.push_back(3);
+    /// buf.push_back(4);
+    /// buf.push_back(5);
+    /// assert_eq!(buf.get(1).unwrap(), &4);
+    /// ```
+    #[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);
+            unsafe { Some(&*self.ptr.offset(idx as isize)) }
+        } else {
+            None
+        }
+    }
+
+    /// Retrieves an element in the `VecDeque` mutably by index.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// buf.push_back(3);
+    /// buf.push_back(4);
+    /// buf.push_back(5);
+    /// match buf.get_mut(1) {
+    ///     None => {}
+    ///     Some(elem) => {
+    ///         *elem = 7;
+    ///     }
+    /// }
+    ///
+    /// assert_eq!(buf[1], 7);
+    /// ```
+    #[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);
+            unsafe { Some(&mut *self.ptr.offset(idx as isize)) }
+        } else {
+            None
+        }
+    }
+
+    /// Swaps elements at indices `i` and `j`.
+    ///
+    /// `i` and `j` may be equal.
+    ///
+    /// Fails if there is no element with either index.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// buf.push_back(3);
+    /// buf.push_back(4);
+    /// buf.push_back(5);
+    /// buf.swap(0, 2);
+    /// assert_eq!(buf[0], 5);
+    /// assert_eq!(buf[2], 3);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    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);
+        unsafe {
+            ptr::swap(self.ptr.offset(ri as isize), self.ptr.offset(rj as isize))
+        }
+    }
+
+    /// Returns the number of elements the `VecDeque` can hold without
+    /// reallocating.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let buf: VecDeque<i32> = VecDeque::with_capacity(10);
+    /// assert!(buf.capacity() >= 10);
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn capacity(&self) -> usize { self.cap - 1 }
+
+    /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the
+    /// given `VecDeque`. Does nothing if the capacity is already sufficient.
+    ///
+    /// Note that the allocator may give the collection more space than it requests. Therefore
+    /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future
+    /// insertions are expected.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the new capacity overflows `usize`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf: VecDeque<i32> = vec![1].into_iter().collect();
+    /// buf.reserve_exact(10);
+    /// assert!(buf.capacity() >= 11);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn reserve_exact(&mut self, additional: usize) {
+        self.reserve(additional);
+    }
+
+    /// Reserves capacity for at least `additional` more elements to be inserted in the given
+    /// `Ringbuf`. The collection may reserve more space to avoid frequent reallocations.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the new capacity overflows `usize`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf: VecDeque<i32> = vec![1].into_iter().collect();
+    /// buf.reserve(10);
+    /// assert!(buf.capacity() >= 11);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn reserve(&mut self, additional: usize) {
+        let new_len = self.len() + additional;
+        assert!(new_len + 1 > self.len(), "capacity overflow");
+        if new_len > self.capacity() {
+            let count = (new_len + 1).next_power_of_two();
+            assert!(count >= new_len + 1);
+
+            if mem::size_of::<T>() != 0 {
+                let old = self.cap * mem::size_of::<T>();
+                let new = count.checked_mul(mem::size_of::<T>())
+                               .expect("capacity overflow");
+                unsafe {
+                    let ptr = heap::reallocate(*self.ptr as *mut u8,
+                                               old,
+                                               new,
+                                               mem::min_align_of::<T>()) as *mut T;
+                    if ptr.is_null() { ::alloc::oom() }
+                    self.ptr = Unique::new(ptr);
+                }
+            }
+
+            // Move the shortest contiguous section of the ring buffer
+            //    T             H
+            //   [o o o o o o o . ]
+            //    T             H
+            // A [o o o o o o o . . . . . . . . . ]
+            //        H T
+            //   [o o . o o o o o ]
+            //          T             H
+            // B [. . . o o o o o o o . . . . . . ]
+            //              H T
+            //   [o o o o o . o o ]
+            //              H                 T
+            // C [o o o o o . . . . . . . . . o o ]
+
+            let oldcap = self.cap;
+            self.cap = count;
+
+            if self.tail <= self.head { // A
+                // Nop
+            } else if self.head < oldcap - self.tail { // B
+                unsafe {
+                    self.copy_nonoverlapping(oldcap, 0, self.head);
+                }
+                self.head += oldcap;
+                debug_assert!(self.head > self.tail);
+            } else { // C
+                let new_tail = count - (oldcap - self.tail);
+                unsafe {
+                    self.copy_nonoverlapping(new_tail, self.tail, oldcap - self.tail);
+                }
+                self.tail = new_tail;
+                debug_assert!(self.head < self.tail);
+            }
+            debug_assert!(self.head < self.cap);
+            debug_assert!(self.tail < self.cap);
+            debug_assert!(self.cap.count_ones() == 1);
+        }
+    }
+
+    /// Shrinks the capacity of the ringbuf as much as possible.
+    ///
+    /// It will drop down as close as possible to the length but the allocator may still inform the
+    /// ringbuf that there is space for a few more elements.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::with_capacity(15);
+    /// buf.extend(0..4);
+    /// assert_eq!(buf.capacity(), 15);
+    /// buf.shrink_to_fit();
+    /// assert!(buf.capacity() >= 4);
+    /// ```
+    pub fn shrink_to_fit(&mut self) {
+        // +1 since the ringbuffer always leaves one space empty
+        // len + 1 can't overflow for an existing, well-formed ringbuf.
+        let target_cap = cmp::max(self.len() + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
+        if target_cap < self.cap {
+            // There are three cases of interest:
+            //   All elements are out of desired bounds
+            //   Elements are contiguous, and head is out of desired bounds
+            //   Elements are discontiguous, and tail is out of desired bounds
+            //
+            // At all other times, element positions are unaffected.
+            //
+            // Indicates that elements at the head should be moved.
+            let head_outside = self.head == 0 || self.head >= target_cap;
+            // Move elements from out of desired bounds (positions after target_cap)
+            if self.tail >= target_cap && head_outside {
+                //                    T             H
+                //   [. . . . . . . . o o o o o o o . ]
+                //    T             H
+                //   [o o o o o o o . ]
+                unsafe {
+                    self.copy_nonoverlapping(0, self.tail, self.len());
+                }
+                self.head = self.len();
+                self.tail = 0;
+            } else if self.tail != 0 && self.tail < target_cap && head_outside {
+                //          T             H
+                //   [. . . 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);
+                unsafe {
+                    self.copy_nonoverlapping(0, target_cap, len);
+                }
+                self.head = len;
+                debug_assert!(self.head < self.tail);
+            } else if self.tail >= target_cap {
+                //              H                 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);
+                let len = self.cap - self.tail;
+                let new_tail = target_cap - len;
+                unsafe {
+                    self.copy_nonoverlapping(new_tail, self.tail, len);
+                }
+                self.tail = new_tail;
+                debug_assert!(self.head < self.tail);
+            }
+
+            if mem::size_of::<T>() != 0 {
+                let old = self.cap * mem::size_of::<T>();
+                let new_size = target_cap * mem::size_of::<T>();
+                unsafe {
+                    let ptr = heap::reallocate(*self.ptr as *mut u8,
+                                               old,
+                                               new_size,
+                                               mem::min_align_of::<T>()) as *mut T;
+                    if ptr.is_null() { ::alloc::oom() }
+                    self.ptr = Unique::new(ptr);
+                }
+            }
+            self.cap = target_cap;
+            debug_assert!(self.head < self.cap);
+            debug_assert!(self.tail < self.cap);
+            debug_assert!(self.cap.count_ones() == 1);
+        }
+    }
+
+    /// Shorten a ringbuf, dropping excess elements from the back.
+    ///
+    /// If `len` is greater than the ringbuf's current length, this has no
+    /// effect.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// buf.push_back(5);
+    /// buf.push_back(10);
+    /// buf.push_back(15);
+    /// buf.truncate(1);
+    /// assert_eq!(buf.len(), 1);
+    /// assert_eq!(Some(&5), buf.get(0));
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "matches collection reform specification; waiting on panic semantics")]
+    pub fn truncate(&mut self, len: usize) {
+        for _ in len..self.len() {
+            self.pop_back();
+        }
+    }
+
+    /// Returns a front-to-back iterator.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// buf.push_back(5);
+    /// buf.push_back(3);
+    /// buf.push_back(4);
+    /// let b: &[_] = &[&5, &3, &4];
+    /// assert_eq!(buf.iter().collect::<Vec<&i32>>().as_slice(), b);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn iter(&self) -> Iter<T> {
+        Iter {
+            tail: self.tail,
+            head: self.head,
+            ring: unsafe { self.buffer_as_slice() }
+        }
+    }
+
+    /// Returns a front-to-back iterator that returns mutable references.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// buf.push_back(5);
+    /// buf.push_back(3);
+    /// buf.push_back(4);
+    /// for num in buf.iter_mut() {
+    ///     *num = *num - 2;
+    /// }
+    /// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
+    /// 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,
+        }
+    }
+
+    /// Consumes the list into an iterator yielding elements by value.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn into_iter(self) -> IntoIter<T> {
+        IntoIter {
+            inner: self,
+        }
+    }
+
+    /// Returns a pair of slices which contain, in order, the contents of the
+    /// `VecDeque`.
+    #[inline]
+    #[unstable(feature = "collections",
+               reason = "matches collection reform specification, waiting for dust to settle")]
+    pub fn as_slices(&self) -> (&[T], &[T]) {
+        unsafe {
+            let contiguous = self.is_contiguous();
+            let buf = self.buffer_as_slice();
+            if contiguous {
+                let (empty, buf) = buf.split_at(0);
+                (&buf[self.tail..self.head], empty)
+            } else {
+                let (mid, right) = buf.split_at(self.tail);
+                let (left, _) = mid.split_at(self.head);
+                (right, left)
+            }
+        }
+    }
+
+    /// Returns a pair of slices which contain, in order, the contents of the
+    /// `VecDeque`.
+    #[inline]
+    #[unstable(feature = "collections",
+               reason = "matches collection reform specification, waiting for dust to settle")]
+    pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) {
+        unsafe {
+            let contiguous = self.is_contiguous();
+            let head = self.head;
+            let tail = self.tail;
+            let buf = self.buffer_as_mut_slice();
+
+            if contiguous {
+                let (empty, buf) = buf.split_at_mut(0);
+                (&mut buf[tail .. head], empty)
+            } else {
+                let (mid, right) = buf.split_at_mut(tail);
+                let (left, _) = mid.split_at_mut(head);
+
+                (right, left)
+            }
+        }
+    }
+
+    /// Returns the number of elements in the `VecDeque`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut v = VecDeque::new();
+    /// assert_eq!(v.len(), 0);
+    /// v.push_back(1);
+    /// assert_eq!(v.len(), 1);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn len(&self) -> usize { count(self.tail, self.head, self.cap) }
+
+    /// Returns true if the buffer contains no elements
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut v = VecDeque::new();
+    /// assert!(v.is_empty());
+    /// v.push_front(1);
+    /// assert!(!v.is_empty());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+    /// Creates a draining iterator that clears the `VecDeque` and iterates over
+    /// the removed items from start to end.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut v = VecDeque::new();
+    /// v.push_back(1);
+    /// assert_eq!(v.drain().next(), Some(1));
+    /// assert!(v.is_empty());
+    /// ```
+    #[inline]
+    #[unstable(feature = "collections",
+               reason = "matches collection reform specification, waiting for dust to settle")]
+    pub fn drain(&mut self) -> Drain<T> {
+        Drain {
+            inner: self,
+        }
+    }
+
+    /// Clears the buffer, removing all values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut v = VecDeque::new();
+    /// v.push_back(1);
+    /// v.clear();
+    /// assert!(v.is_empty());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn clear(&mut self) {
+        self.drain();
+    }
+
+    /// Provides a reference to the front element, or `None` if the sequence is
+    /// empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut d = VecDeque::new();
+    /// assert_eq!(d.front(), None);
+    ///
+    /// d.push_back(1);
+    /// d.push_back(2);
+    /// assert_eq!(d.front(), Some(&1));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn front(&self) -> Option<&T> {
+        if !self.is_empty() { Some(&self[0]) } else { None }
+    }
+
+    /// Provides a mutable reference to the front element, or `None` if the
+    /// sequence is empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut d = VecDeque::new();
+    /// assert_eq!(d.front_mut(), None);
+    ///
+    /// d.push_back(1);
+    /// d.push_back(2);
+    /// match d.front_mut() {
+    ///     Some(x) => *x = 9,
+    ///     None => (),
+    /// }
+    /// assert_eq!(d.front(), Some(&9));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn front_mut(&mut self) -> Option<&mut T> {
+        if !self.is_empty() { Some(&mut self[0]) } else { None }
+    }
+
+    /// Provides a reference to the back element, or `None` if the sequence is
+    /// empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut d = VecDeque::new();
+    /// assert_eq!(d.back(), None);
+    ///
+    /// d.push_back(1);
+    /// d.push_back(2);
+    /// assert_eq!(d.back(), Some(&2));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn back(&self) -> Option<&T> {
+        if !self.is_empty() { Some(&self[self.len() - 1]) } else { None }
+    }
+
+    /// Provides a mutable reference to the back element, or `None` if the
+    /// sequence is empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut d = VecDeque::new();
+    /// assert_eq!(d.back(), None);
+    ///
+    /// d.push_back(1);
+    /// d.push_back(2);
+    /// match d.back_mut() {
+    ///     Some(x) => *x = 9,
+    ///     None => (),
+    /// }
+    /// assert_eq!(d.back(), Some(&9));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn back_mut(&mut self) -> Option<&mut T> {
+        let len = self.len();
+        if !self.is_empty() { Some(&mut self[len - 1]) } else { None }
+    }
+
+    /// Removes the first element and returns it, or `None` if the sequence is
+    /// empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut d = VecDeque::new();
+    /// d.push_back(1);
+    /// d.push_back(2);
+    ///
+    /// assert_eq!(d.pop_front(), Some(1));
+    /// assert_eq!(d.pop_front(), Some(2));
+    /// assert_eq!(d.pop_front(), None);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn pop_front(&mut self) -> Option<T> {
+        if self.is_empty() {
+            None
+        } else {
+            let tail = self.tail;
+            self.tail = self.wrap_index(self.tail + 1);
+            unsafe { Some(self.buffer_read(tail)) }
+        }
+    }
+
+    /// Inserts an element first in the sequence.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut d = VecDeque::new();
+    /// d.push_front(1);
+    /// d.push_front(2);
+    /// assert_eq!(d.front(), Some(&2));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn push_front(&mut self, t: T) {
+        if self.is_full() {
+            self.reserve(1);
+            debug_assert!(!self.is_full());
+        }
+
+        self.tail = self.wrap_index(self.tail - 1);
+        let tail = self.tail;
+        unsafe { self.buffer_write(tail, t); }
+    }
+
+    /// Appends an element to the back of a buffer
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// buf.push_back(1);
+    /// buf.push_back(3);
+    /// assert_eq!(3, *buf.back().unwrap());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn push_back(&mut self, t: T) {
+        if self.is_full() {
+            self.reserve(1);
+            debug_assert!(!self.is_full());
+        }
+
+        let head = self.head;
+        self.head = self.wrap_index(self.head + 1);
+        unsafe { self.buffer_write(head, t) }
+    }
+
+    /// Removes the last element from a buffer and returns it, or `None` if
+    /// it is empty.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// assert_eq!(buf.pop_back(), None);
+    /// buf.push_back(1);
+    /// buf.push_back(3);
+    /// assert_eq!(buf.pop_back(), Some(3));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn pop_back(&mut self) -> Option<T> {
+        if self.is_empty() {
+            None
+        } else {
+            self.head = self.wrap_index(self.head - 1);
+            let head = self.head;
+            unsafe { Some(self.buffer_read(head)) }
+        }
+    }
+
+    #[inline]
+    fn is_contiguous(&self) -> bool {
+        self.tail <= self.head
+    }
+
+    /// Removes an element from anywhere in the ringbuf and returns it, replacing it with the last
+    /// element.
+    ///
+    /// This does not preserve ordering, but is O(1).
+    ///
+    /// Returns `None` if `index` is out of bounds.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// assert_eq!(buf.swap_back_remove(0), None);
+    /// buf.push_back(5);
+    /// buf.push_back(99);
+    /// buf.push_back(15);
+    /// buf.push_back(20);
+    /// buf.push_back(10);
+    /// assert_eq!(buf.swap_back_remove(1), Some(99));
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "the naming of this function may be altered")]
+    pub fn swap_back_remove(&mut self, index: usize) -> Option<T> {
+        let length = self.len();
+        if length > 0 && index < length - 1 {
+            self.swap(index, length - 1);
+        } else if index >= length {
+            return None;
+        }
+        self.pop_back()
+    }
+
+    /// Removes an element from anywhere in the ringbuf and returns it, replacing it with the first
+    /// element.
+    ///
+    /// This does not preserve ordering, but is O(1).
+    ///
+    /// Returns `None` if `index` is out of bounds.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// assert_eq!(buf.swap_front_remove(0), None);
+    /// buf.push_back(15);
+    /// buf.push_back(5);
+    /// buf.push_back(10);
+    /// buf.push_back(99);
+    /// buf.push_back(20);
+    /// assert_eq!(buf.swap_front_remove(3), Some(99));
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "the naming of this function may be altered")]
+    pub fn swap_front_remove(&mut self, index: usize) -> Option<T> {
+        let length = self.len();
+        if length > 0 && index < length && index != 0 {
+            self.swap(index, 0);
+        } else if index >= length {
+            return None;
+        }
+        self.pop_front()
+    }
+
+    /// Inserts an element at position `i` within the ringbuf. Whichever
+    /// end is closer to the insertion point will be moved to make room,
+    /// and all the affected elements will be moved to new positions.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i` is greater than ringbuf's length
+    ///
+    /// # Examples
+    /// ```rust
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// buf.push_back(10);
+    /// buf.push_back(12);
+    /// buf.insert(1,11);
+    /// assert_eq!(Some(&11), buf.get(1));
+    /// ```
+    pub fn insert(&mut self, i: usize, t: T) {
+        assert!(i <= self.len(), "index out of bounds");
+        if self.is_full() {
+            self.reserve(1);
+            debug_assert!(!self.is_full());
+        }
+
+        // Move the least number of elements in the ring buffer and insert
+        // the given object
+        //
+        // At most len/2 - 1 elements will be moved. O(min(n, n-i))
+        //
+        // There are three main cases:
+        //  Elements are contiguous
+        //      - special case when tail is 0
+        //  Elements are discontiguous and the insert is in the tail section
+        //  Elements are discontiguous and the insert is in the head section
+        //
+        // For each of those there are two more cases:
+        //  Insert is closer to tail
+        //  Insert is closer to head
+        //
+        // Key: H - self.head
+        //      T - self.tail
+        //      o - Valid element
+        //      I - Insertion element
+        //      A - The element that should be after the insertion point
+        //      M - Indicates element was moved
+
+        let idx = self.wrap_index(self.tail + i);
+
+        let distance_to_tail = i;
+        let distance_to_head = self.len() - i;
+
+        let contiguous = self.is_contiguous();
+
+        match (contiguous, distance_to_tail <= distance_to_head, idx >= self.tail) {
+            (true, true, _) if i == 0 => {
+                // push_front
+                //
+                //       T
+                //       I             H
+                //      [A o o o o o o . . . . . . . . .]
+                //
+                //                       H         T
+                //      [A o o o o o o o . . . . . I]
+                //
+
+                self.tail = self.wrap_index(self.tail - 1);
+            },
+            (true, true, _) => unsafe {
+                // contiguous, insert closer to tail:
+                //
+                //             T   I         H
+                //      [. . . o o A o o o o . . . . . .]
+                //
+                //           T               H
+                //      [. . o o I A o o o o . . . . . .]
+                //           M M
+                //
+                // contiguous, insert closer to tail and tail is 0:
+                //
+                //
+                //       T   I         H
+                //      [o o A o o o o . . . . . . . . .]
+                //
+                //                       H             T
+                //      [o I A o o o o o . . . . . . . o]
+                //       M                             M
+
+                let new_tail = self.wrap_index(self.tail - 1);
+
+                self.copy(new_tail, self.tail, 1);
+                // Already moved the tail, so we only copy `i - 1` elements.
+                self.copy(self.tail, self.tail + 1, i - 1);
+
+                self.tail = new_tail;
+            },
+            (true, false, _) => unsafe {
+                //  contiguous, insert closer to head:
+                //
+                //             T       I     H
+                //      [. . . o o o o A o o . . . . . .]
+                //
+                //             T               H
+                //      [. . . o o o o I A o o . . . . .]
+                //                       M M M
+
+                self.copy(idx + 1, idx, self.head - idx);
+                self.head = self.wrap_index(self.head + 1);
+            },
+            (false, true, true) => unsafe {
+                // discontiguous, insert closer to tail, tail section:
+                //
+                //                   H         T   I
+                //      [o o o o o o . . . . . o o A o o]
+                //
+                //                   H       T
+                //      [o o o o o o . . . . o o I A o o]
+                //                           M M
+
+                self.copy(self.tail - 1, self.tail, i);
+                self.tail -= 1;
+            },
+            (false, false, true) => unsafe {
+                // discontiguous, insert closer to head, tail section:
+                //
+                //           H             T         I
+                //      [o o . . . . . . . o o o o o A o]
+                //
+                //             H           T
+                //      [o o o . . . . . . o o o o o I A]
+                //       M M M                         M
+
+                // copy elements up to new head
+                self.copy(1, 0, self.head);
+
+                // copy last element into empty spot at bottom of buffer
+                self.copy(0, self.cap - 1, 1);
+
+                // move elements from idx to end forward not including ^ element
+                self.copy(idx + 1, idx, self.cap - 1 - idx);
+
+                self.head += 1;
+            },
+            (false, true, false) if idx == 0 => unsafe {
+                // discontiguous, insert is closer to tail, head section,
+                // and is at index zero in the internal buffer:
+                //
+                //       I                   H     T
+                //      [A o o o o o o o o o . . . o o o]
+                //
+                //                           H   T
+                //      [A o o o o o o o o o . . o o o I]
+                //                               M M M
+
+                // copy elements up to new tail
+                self.copy(self.tail - 1, self.tail, self.cap - self.tail);
+
+                // copy last element into empty spot at bottom of buffer
+                self.copy(self.cap - 1, 0, 1);
+
+                self.tail -= 1;
+            },
+            (false, true, false) => unsafe {
+                // discontiguous, insert closer to tail, head section:
+                //
+                //             I             H     T
+                //      [o o o A o o o o o o . . . o o o]
+                //
+                //                           H   T
+                //      [o o I A o o o o o o . . o o o o]
+                //       M M                     M M M M
+
+                // copy elements up to new tail
+                self.copy(self.tail - 1, self.tail, self.cap - self.tail);
+
+                // copy last element into empty spot at bottom of buffer
+                self.copy(self.cap - 1, 0, 1);
+
+                // move elements from idx-1 to end forward not including ^ element
+                self.copy(0, 1, idx - 1);
+
+                self.tail -= 1;
+            },
+            (false, false, false) => unsafe {
+                // discontiguous, insert closer to head, head section:
+                //
+                //               I     H           T
+                //      [o o o o A o o . . . . . . o o o]
+                //
+                //                     H           T
+                //      [o o o o I A o o . . . . . o o o]
+                //                 M M M
+
+                self.copy(idx + 1, idx, self.head - idx);
+                self.head += 1;
+            }
+        }
+
+        // tail might've been changed so we need to recalculate
+        let new_idx = self.wrap_index(self.tail + i);
+        unsafe {
+            self.buffer_write(new_idx, t);
+        }
+    }
+
+    /// Removes and returns the element at position `i` from the ringbuf.
+    /// Whichever end is closer to the removal point will be moved to make
+    /// room, and all the affected elements will be moved to new positions.
+    /// Returns `None` if `i` is out of bounds.
+    ///
+    /// # Examples
+    /// ```rust
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// buf.push_back(5);
+    /// buf.push_back(10);
+    /// buf.push_back(12);
+    /// buf.push_back(15);
+    /// buf.remove(2);
+    /// assert_eq!(Some(&15), buf.get(2));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn remove(&mut self, i: usize) -> Option<T> {
+        if self.is_empty() || self.len() <= i {
+            return None;
+        }
+
+        // There are three main cases:
+        //  Elements are contiguous
+        //  Elements are discontiguous and the removal is in the tail section
+        //  Elements are discontiguous and the removal is in the head section
+        //      - special case when elements are technically contiguous,
+        //        but self.head = 0
+        //
+        // For each of those there are two more cases:
+        //  Insert is closer to tail
+        //  Insert is closer to head
+        //
+        // Key: H - self.head
+        //      T - self.tail
+        //      o - Valid element
+        //      x - Element marked for removal
+        //      R - Indicates element that is being removed
+        //      M - Indicates element was moved
+
+        let idx = self.wrap_index(self.tail + i);
+
+        let elem = unsafe {
+            Some(self.buffer_read(idx))
+        };
+
+        let distance_to_tail = i;
+        let distance_to_head = self.len() - i;
+
+        let contiguous = self.is_contiguous();
+
+        match (contiguous, distance_to_tail <= distance_to_head, idx >= self.tail) {
+            (true, true, _) => unsafe {
+                // contiguous, remove closer to tail:
+                //
+                //             T   R         H
+                //      [. . . o o x o o o o . . . . . .]
+                //
+                //               T           H
+                //      [. . . . o o o o o o . . . . . .]
+                //               M M
+
+                self.copy(self.tail + 1, self.tail, i);
+                self.tail += 1;
+            },
+            (true, false, _) => unsafe {
+                // contiguous, remove closer to head:
+                //
+                //             T       R     H
+                //      [. . . o o o o x o o . . . . . .]
+                //
+                //             T           H
+                //      [. . . o o o o o o . . . . . . .]
+                //                     M M
+
+                self.copy(idx, idx + 1, self.head - idx - 1);
+                self.head -= 1;
+            },
+            (false, true, true) => unsafe {
+                // discontiguous, remove closer to tail, tail section:
+                //
+                //                   H         T   R
+                //      [o o o o o o . . . . . o o x o o]
+                //
+                //                   H           T
+                //      [o o o o o o . . . . . . o o o o]
+                //                               M M
+
+                self.copy(self.tail + 1, self.tail, i);
+                self.tail = self.wrap_index(self.tail + 1);
+            },
+            (false, false, false) => unsafe {
+                // discontiguous, remove closer to head, head section:
+                //
+                //               R     H           T
+                //      [o o o o x o o . . . . . . o o o]
+                //
+                //                   H             T
+                //      [o o o o o o . . . . . . . o o o]
+                //               M M
+
+                self.copy(idx, idx + 1, self.head - idx - 1);
+                self.head -= 1;
+            },
+            (false, false, true) => unsafe {
+                // discontiguous, remove closer to head, tail section:
+                //
+                //             H           T         R
+                //      [o o o . . . . . . o o o o o x o]
+                //
+                //           H             T
+                //      [o o . . . . . . . o o o o o o o]
+                //       M M                         M M
+                //
+                // or quasi-discontiguous, remove next to head, tail section:
+                //
+                //       H                 T         R
+                //      [. . . . . . . . . o o o o o x o]
+                //
+                //                         T           H
+                //      [. . . . . . . . . o o o o o o .]
+                //                                   M
+
+                // draw in elements in the tail section
+                self.copy(idx, idx + 1, self.cap - idx - 1);
+
+                // Prevents underflow.
+                if self.head != 0 {
+                    // copy first element into empty spot
+                    self.copy(self.cap - 1, 0, 1);
+
+                    // move elements in the head section backwards
+                    self.copy(0, 1, self.head - 1);
+                }
+
+                self.head = self.wrap_index(self.head - 1);
+            },
+            (false, true, false) => unsafe {
+                // discontiguous, remove closer to tail, head section:
+                //
+                //           R               H     T
+                //      [o o x o o o o o o o . . . o o o]
+                //
+                //                           H       T
+                //      [o o o o o o o o o o . . . . o o]
+                //       M M M                       M M
+
+                // draw in elements up to idx
+                self.copy(1, 0, idx);
+
+                // copy last element into empty spot
+                self.copy(0, self.cap - 1, 1);
+
+                // 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);
+            }
+        }
+
+        return elem;
+    }
+
+    /// Splits the collection into two at the given index.
+    ///
+    /// Returns a newly allocated `Self`. `self` contains elements `[0, at)`,
+    /// and the returned `Self` contains elements `[at, len)`.
+    ///
+    /// Note that the capacity of `self` does not change.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `at > len`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf: VecDeque<_> = vec![1,2,3].into_iter().collect();
+    /// let buf2 = buf.split_off(1);
+    /// // buf = [1], buf2 = [2, 3]
+    /// assert_eq!(buf.len(), 1);
+    /// assert_eq!(buf2.len(), 2);
+    /// ```
+    #[inline]
+    #[unstable(feature = "collections",
+               reason = "new API, waiting for dust to settle")]
+    pub fn split_off(&mut self, at: usize) -> Self {
+        let len = self.len();
+        assert!(at <= len, "`at` out of bounds");
+
+        let other_len = len - at;
+        let mut other = VecDeque::with_capacity(other_len);
+
+        unsafe {
+            let (first_half, second_half) = self.as_slices();
+
+            let first_len = first_half.len();
+            let second_len = second_half.len();
+            if at < first_len {
+                // `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);
+
+                // 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);
+            } 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);
+            }
+        }
+
+        // Cleanup where the ends of the buffers are
+        self.head = self.wrap_index(self.head - other_len);
+        other.head = other.wrap_index(other_len);
+
+        other
+    }
+
+    /// Moves all the elements of `other` into `Self`, leaving `other` empty.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the new number of elements in self overflows a `usize`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
+    /// let mut buf2: VecDeque<_> = vec![4, 5, 6].into_iter().collect();
+    /// buf.append(&mut buf2);
+    /// assert_eq!(buf.len(), 6);
+    /// assert_eq!(buf2.len(), 0);
+    /// ```
+    #[inline]
+    #[unstable(feature = "collections",
+               reason = "new API, waiting for dust to settle")]
+    pub fn append(&mut self, other: &mut Self) {
+        // naive impl
+        self.extend(other.drain());
+    }
+}
+
+impl<T: Clone> VecDeque<T> {
+    /// Modifies the ringbuf in-place so that `len()` is equal to new_len,
+    /// either by removing excess elements or by appending copies of a value to the back.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut buf = VecDeque::new();
+    /// buf.push_back(5);
+    /// buf.push_back(10);
+    /// buf.push_back(15);
+    /// buf.resize(2, 0);
+    /// buf.resize(6, 20);
+    /// for (a, b) in [5, 10, 20, 20, 20, 20].iter().zip(buf.iter()) {
+    ///     assert_eq!(a, b);
+    /// }
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "matches collection reform specification; waiting on panic semantics")]
+    pub fn resize(&mut self, new_len: usize, value: T) {
+        let len = self.len();
+
+        if new_len > len {
+            self.extend(repeat(value).take(new_len - len))
+        } else {
+            self.truncate(new_len);
+        }
+    }
+}
+
+/// Returns the index in the underlying buffer for a given logical element index.
+#[inline]
+fn wrap_index(index: usize, size: usize) -> usize {
+    // size is always a power of 2
+    index & (size - 1)
+}
+
+/// Calculate the number of elements left to be read in the buffer
+#[inline]
+fn count(tail: usize, head: usize, size: usize) -> usize {
+    // size is always a power of 2
+    (head - tail) & (size - 1)
+}
+
+/// `VecDeque` iterator.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Iter<'a, T:'a> {
+    ring: &'a [T],
+    tail: usize,
+    head: usize
+}
+
+// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+impl<'a, T> Clone for Iter<'a, T> {
+    fn clone(&self) -> Iter<'a, T> {
+        Iter {
+            ring: self.ring,
+            tail: self.tail,
+            head: self.head
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> Iterator for Iter<'a, T> {
+    type Item = &'a T;
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a T> {
+        if self.tail == self.head {
+            return None;
+        }
+        let tail = self.tail;
+        self.tail = wrap_index(self.tail + 1, self.ring.len());
+        unsafe { Some(self.ring.get_unchecked(tail)) }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let len = count(self.tail, self.head, self.ring.len());
+        (len, Some(len))
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<&'a T> {
+        if self.tail == self.head {
+            return None;
+        }
+        self.head = wrap_index(self.head - 1, self.ring.len());
+        unsafe { Some(self.ring.get_unchecked(self.head)) }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> RandomAccessIterator for Iter<'a, T> {
+    #[inline]
+    fn indexable(&self) -> usize {
+        let (len, _) = self.size_hint();
+        len
+    }
+
+    #[inline]
+    fn idx(&mut self, j: usize) -> Option<&'a T> {
+        if j >= self.indexable() {
+            None
+        } else {
+            let idx = wrap_index(self.tail + 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,
+    tail: usize,
+    head: usize,
+    cap: usize,
+    marker: marker::PhantomData<&'a mut T>,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> Iterator for IterMut<'a, T> {
+    type Item = &'a mut T;
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a mut T> {
+        if self.tail == self.head {
+            return None;
+        }
+        let tail = self.tail;
+        self.tail = wrap_index(self.tail + 1, self.cap);
+
+        unsafe {
+            Some(&mut *self.ptr.offset(tail as isize))
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let len = count(self.tail, self.head, self.cap);
+        (len, Some(len))
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<&'a mut T> {
+        if self.tail == self.head {
+            return None;
+        }
+        self.head = wrap_index(self.head - 1, self.cap);
+
+        unsafe {
+            Some(&mut *self.ptr.offset(self.head as isize))
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}
+
+/// A by-value VecDeque iterator
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct IntoIter<T> {
+    inner: VecDeque<T>,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> Iterator for IntoIter<T> {
+    type Item = T;
+
+    #[inline]
+    fn next(&mut self) -> Option<T> {
+        self.inner.pop_front()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let len = self.inner.len();
+        (len, Some(len))
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> DoubleEndedIterator for IntoIter<T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<T> {
+        self.inner.pop_back()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> ExactSizeIterator for IntoIter<T> {}
+
+/// A draining VecDeque iterator
+#[unstable(feature = "collections",
+           reason = "matches collection reform specification, waiting for dust to settle")]
+pub struct Drain<'a, T: 'a> {
+    inner: &'a mut VecDeque<T>,
+}
+
+#[unsafe_destructor]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: 'a> Drop for Drain<'a, T> {
+    fn drop(&mut self) {
+        for _ in self.by_ref() {}
+        self.inner.head = 0;
+        self.inner.tail = 0;
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: 'a> Iterator for Drain<'a, T> {
+    type Item = T;
+
+    #[inline]
+    fn next(&mut self) -> Option<T> {
+        self.inner.pop_front()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let len = self.inner.len();
+        (len, Some(len))
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<T> {
+        self.inner.pop_back()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: 'a> ExactSizeIterator for Drain<'a, T> {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: PartialEq> PartialEq for VecDeque<A> {
+    fn eq(&self, other: &VecDeque<A>) -> bool {
+        self.len() == other.len() &&
+            self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: Eq> Eq for VecDeque<A> {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: PartialOrd> PartialOrd for VecDeque<A> {
+    fn partial_cmp(&self, other: &VecDeque<A>) -> Option<Ordering> {
+        iter::order::partial_cmp(self.iter(), other.iter())
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: Ord> Ord for VecDeque<A> {
+    #[inline]
+    fn cmp(&self, other: &VecDeque<A>) -> Ordering {
+        iter::order::cmp(self.iter(), other.iter())
+    }
+}
+
+#[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);
+        for elt in self {
+            elt.hash(state);
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+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")
+    }
+}
+
+#[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")
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A> FromIterator<A> for VecDeque<A> {
+    fn from_iter<T: IntoIterator<Item=A>>(iterable: T) -> VecDeque<A> {
+        let iterator = iterable.into_iter();
+        let (lower, _) = iterator.size_hint();
+        let mut deq = VecDeque::with_capacity(lower);
+        deq.extend(iterator);
+        deq
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> IntoIterator for VecDeque<T> {
+    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, T> IntoIterator for &'a VecDeque<T> {
+    type Item = &'a T;
+    type IntoIter = Iter<'a, T>;
+
+    fn into_iter(self) -> Iter<'a, T> {
+        self.iter()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> IntoIterator for &'a mut VecDeque<T> {
+    type Item = &'a mut T;
+    type IntoIter = IterMut<'a, T>;
+
+    fn into_iter(mut self) -> IterMut<'a, T> {
+        self.iter_mut()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A> Extend<A> for VecDeque<A> {
+    fn extend<T: IntoIterator<Item=A>>(&mut self, iter: T) {
+        for elt in iter {
+            self.push_back(elt);
+        }
+    }
+}
+
+#[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 ["));
+
+        for (i, e) in self.iter().enumerate() {
+            if i != 0 { try!(write!(f, ", ")); }
+            try!(write!(f, "{:?}", *e));
+        }
+
+        write!(f, "]")
+    }
+}
+
+#[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;
+    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);
+        b.iter(|| {
+            for i in 0..100 {
+                deq.push_back(i);
+            }
+            deq.head = 0;
+            deq.tail = 0;
+        })
+    }
+
+    #[bench]
+    fn bench_push_front_100(b: &mut test::Bencher) {
+        let mut deq = VecDeque::with_capacity(101);
+        b.iter(|| {
+            for i in 0..100 {
+                deq.push_front(i);
+            }
+            deq.head = 0;
+            deq.tail = 0;
+        })
+    }
+
+    #[bench]
+    fn bench_pop_back_100(b: &mut test::Bencher) {
+        let mut deq= VecDeque::<i32>::with_capacity(101);
+
+        b.iter(|| {
+            deq.head = 100;
+            deq.tail = 0;
+            while !deq.is_empty() {
+                test::black_box(deq.pop_back());
+            }
+        })
+    }
+
+    #[bench]
+    fn bench_pop_front_100(b: &mut test::Bencher) {
+        let mut deq = VecDeque::<i32>::with_capacity(101);
+
+        b.iter(|| {
+            deq.head = 100;
+            deq.tail = 0;
+            while !deq.is_empty() {
+                test::black_box(deq.pop_front());
+            }
+        })
+    }
+
+    #[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) {
+            // This test checks that every single combination of tail position and length is tested.
+            // Capacity 15 should be large enough to cover every case.
+            let mut tester = VecDeque::with_capacity(15);
+            let usable_cap = tester.capacity();
+            let final_len = usable_cap / 2;
+
+            for len in 0..final_len {
+                let expected = if back {
+                    (0..len).collect()
+                } else {
+                    (0..len).rev().collect()
+                };
+                for tail_pos in 0..usable_cap {
+                    tester.tail = tail_pos;
+                    tester.head = tail_pos;
+                    if back {
+                        for i in 0..len * 2 {
+                            tester.push_front(i);
+                        }
+                        for i in 0..len {
+                            assert_eq!(tester.swap_back_remove(i), Some(len * 2 - 1 - i));
+                        }
+                    } else {
+                        for i in 0..len * 2 {
+                            tester.push_back(i);
+                        }
+                        for i in 0..len {
+                            let idx = tester.len() - 1 - i;
+                            assert_eq!(tester.swap_front_remove(idx), Some(len * 2 - 1 - i));
+                        }
+                    }
+                    assert!(tester.tail < tester.cap);
+                    assert!(tester.head < tester.cap);
+                    assert_eq!(tester, expected);
+                }
+            }
+        }
+        test(true);
+        test(false);
+    }
+
+    #[test]
+    fn test_insert() {
+        // This test checks that every single combination of tail position, length, and
+        // insertion position is tested. Capacity 15 should be large enough to cover every case.
+
+        let mut tester = VecDeque::with_capacity(15);
+        // can't guarantee we got 15, so have to get what we got.
+        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
+        // this test isn't covering what it wants to
+        let cap = tester.capacity();
+
+
+        // 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();
+            for tail_pos in 0..cap {
+                for to_insert in 0..len {
+                    tester.tail = tail_pos;
+                    tester.head = tail_pos;
+                    for i in 0..len {
+                        if i != to_insert {
+                            tester.push_back(i);
+                        }
+                    }
+                    tester.insert(to_insert, to_insert);
+                    assert!(tester.tail < tester.cap);
+                    assert!(tester.head < tester.cap);
+                    assert_eq!(tester, expected);
+                }
+            }
+        }
+    }
+
+    #[test]
+    fn test_remove() {
+        // This test checks that every single combination of tail position, length, and
+        // removal position is tested. Capacity 15 should be large enough to cover every case.
+
+        let mut tester = VecDeque::with_capacity(15);
+        // can't guarantee we got 15, so have to get what we got.
+        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
+        // this test isn't covering what it wants to
+        let cap = tester.capacity();
+
+        // 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();
+            for tail_pos in 0..cap {
+                for to_remove in 0..len + 1 {
+                    tester.tail = tail_pos;
+                    tester.head = tail_pos;
+                    for i in 0..len {
+                        if i == to_remove {
+                            tester.push_back(1234);
+                        }
+                        tester.push_back(i);
+                    }
+                    if to_remove == len {
+                        tester.push_back(1234);
+                    }
+                    tester.remove(to_remove);
+                    assert!(tester.tail < tester.cap);
+                    assert!(tester.head < tester.cap);
+                    assert_eq!(tester, expected);
+                }
+            }
+        }
+    }
+
+    #[test]
+    fn test_shrink_to_fit() {
+        // This test checks that every single combination of head and tail position,
+        // is tested. Capacity 15 should be large enough to cover every case.
+
+        let mut tester = VecDeque::with_capacity(15);
+        // can't guarantee we got 15, so have to get what we got.
+        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
+        // this test isn't covering what it wants to
+        let cap = tester.capacity();
+        tester.reserve(63);
+        let max_cap = tester.capacity();
+
+        for len in 0..cap + 1 {
+            // 0, 1, 2, .., len - 1
+            let expected = iter::count(0, 1).take(len).collect();
+            for tail_pos in 0..max_cap + 1 {
+                tester.tail = tail_pos;
+                tester.head = tail_pos;
+                tester.reserve(63);
+                for i in 0..len {
+                    tester.push_back(i);
+                }
+                tester.shrink_to_fit();
+                assert!(tester.capacity() <= cap);
+                assert!(tester.tail < tester.cap);
+                assert!(tester.head < tester.cap);
+                assert_eq!(tester, expected);
+            }
+        }
+    }
+
+    #[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
+        // split position is tested. Capacity 15 should be large enough to cover every case.
+
+        let mut tester = VecDeque::with_capacity(15);
+        // can't guarantee we got 15, so have to get what we got.
+        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
+        // this test isn't covering what it wants to
+        let cap = tester.capacity();
+
+        // len is the length *before* splitting
+        for len in 0..cap {
+            // 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();
+                // at, at + 1, .., len - 1 (may be empty)
+                let expected_other = iter::count(at, 1).take(len - at).collect();
+
+                for tail_pos in 0..cap {
+                    tester.tail = tail_pos;
+                    tester.head = tail_pos;
+                    for i in 0..len {
+                        tester.push_back(i);
+                    }
+                    let result = tester.split_off(at);
+                    assert!(tester.tail < tester.cap);
+                    assert!(tester.head < tester.cap);
+                    assert!(result.tail < result.cap);
+                    assert!(result.head < result.cap);
+                    assert_eq!(tester, expected_self);
+                    assert_eq!(result, expected_other);
+                }
+            }
+        }
+    }
+
+    #[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 82ccfd0614fd5e14c94f1e47a9d11efcc70410a7..54589a3142345833b443956f65a17227b35fe915 100644 (file)
@@ -20,7 +20,8 @@
 use core::cmp::Ordering;
 use core::default::Default;
 use core::fmt;
-use core::hash::{Hash, Writer, Hasher};
+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;
@@ -99,6 +100,7 @@ impl<V> Default for VecMap<V> {
     fn default() -> VecMap<V> { VecMap::new() }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<V:Clone> Clone for VecMap<V> {
     #[inline]
     fn clone(&self) -> VecMap<V> {
@@ -111,6 +113,7 @@ fn clone_from(&mut self, source: &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
@@ -123,6 +126,20 @@ fn hash(&self, state: &mut S) {
         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
+        // during iteration.
+        let mut count: usize = 0;
+        for elt in self {
+            elt.hash(state);
+            count += 1;
+        }
+        count.hash(state);
+    }
+}
 
 impl<V> VecMap<V> {
     /// Creates an empty `VecMap`.
@@ -661,7 +678,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<V> FromIterator<(usize, V)> for VecMap<V> {
-    fn from_iter<Iter: Iterator<Item=(usize, V)>>(iter: Iter) -> VecMap<V> {
+    fn from_iter<I: IntoIterator<Item=(usize, V)>>(iter: I) -> VecMap<V> {
         let mut map = VecMap::new();
         map.extend(iter);
         map
@@ -700,7 +717,7 @@ fn into_iter(mut self) -> IterMut<'a, T> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<V> Extend<(usize, V)> for VecMap<V> {
-    fn extend<Iter: Iterator<Item=(usize, V)>>(&mut self, iter: Iter) {
+    fn extend<I: IntoIterator<Item=(usize, V)>>(&mut self, iter: I) {
         for (k, v) in iter {
             self.insert(k, v);
         }
@@ -859,7 +876,7 @@ pub struct IntoIter<V> {
 }
 
 #[unstable(feature = "collections")]
-pub struct Drain<'a, V> {
+pub struct Drain<'a, V:'a> {
     iter: FilterMap<
     Enumerate<vec::Drain<'a, Option<V>>>,
     fn((usize, Option<V>)) -> Option<(usize, V)>>
index 838ca4e478b72223c20583ac4089e99a66469a04..afb5d95c9f8d79219b122a529749d35a35ceafab 100644 (file)
@@ -17,7 +17,7 @@
 use clone::Clone;
 use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
 use fmt;
-use hash::{Hash, Hasher, self};
+use hash::{Hash, self};
 use iter::IntoIterator;
 use marker::Copy;
 use ops::Deref;
@@ -35,16 +35,24 @@ macro_rules! array_impls {
                 }
             }
 
-            impl<S: hash::Writer + Hasher, T: Hash<S>> Hash<S> for [T; $N] {
+            #[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)
+                    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) {
+                    Hash::hash(&self[..], state)
                 }
             }
 
             #[stable(feature = "rust1", since = "1.0.0")]
             impl<T: fmt::Debug> fmt::Debug for [T; $N] {
                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-                    fmt::Debug::fmt(&&self[], f)
+                    fmt::Debug::fmt(&&self[..], f)
                 }
             }
 
@@ -72,11 +80,11 @@ fn into_iter(self) -> IterMut<'a, T> {
             impl<A, B> PartialEq<[B; $N]> for [A; $N] where A: PartialEq<B> {
                 #[inline]
                 fn eq(&self, other: &[B; $N]) -> bool {
-                    &self[] == &other[]
+                    &self[..] == &other[..]
                 }
                 #[inline]
                 fn ne(&self, other: &[B; $N]) -> bool {
-                    &self[] != &other[]
+                    &self[..] != &other[..]
                 }
             }
 
@@ -87,11 +95,11 @@ fn into_iter(self) -> IterMut<'a, T> {
             {
                 #[inline(always)]
                 fn eq(&self, other: &Rhs) -> bool {
-                    PartialEq::eq(&self[], &**other)
+                    PartialEq::eq(&self[..], &**other)
                 }
                 #[inline(always)]
                 fn ne(&self, other: &Rhs) -> bool {
-                    PartialEq::ne(&self[], &**other)
+                    PartialEq::ne(&self[..], &**other)
                 }
             }
 
@@ -102,11 +110,11 @@ fn ne(&self, other: &Rhs) -> bool {
             {
                 #[inline(always)]
                 fn eq(&self, other: &[B; $N]) -> bool {
-                    PartialEq::eq(&**self, &other[])
+                    PartialEq::eq(&**self, &other[..])
                 }
                 #[inline(always)]
                 fn ne(&self, other: &[B; $N]) -> bool {
-                    PartialEq::ne(&**self, &other[])
+                    PartialEq::ne(&**self, &other[..])
                 }
             }
 
@@ -117,23 +125,23 @@ fn ne(&self, other: &Rhs) -> bool {
             impl<T:PartialOrd> PartialOrd for [T; $N] {
                 #[inline]
                 fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> {
-                    PartialOrd::partial_cmp(&&self[], &&other[])
+                    PartialOrd::partial_cmp(&&self[..], &&other[..])
                 }
                 #[inline]
                 fn lt(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::lt(&&self[], &&other[])
+                    PartialOrd::lt(&&self[..], &&other[..])
                 }
                 #[inline]
                 fn le(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::le(&&self[], &&other[])
+                    PartialOrd::le(&&self[..], &&other[..])
                 }
                 #[inline]
                 fn ge(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::ge(&&self[], &&other[])
+                    PartialOrd::ge(&&self[..], &&other[..])
                 }
                 #[inline]
                 fn gt(&self, other: &[T; $N]) -> bool {
-                    PartialOrd::gt(&&self[], &&other[])
+                    PartialOrd::gt(&&self[..], &&other[..])
                 }
             }
 
@@ -141,7 +149,7 @@ fn ne(&self, other: &Rhs) -> bool {
             impl<T:Ord> Ord for [T; $N] {
                 #[inline]
                 fn cmp(&self, other: &[T; $N]) -> Ordering {
-                    Ord::cmp(&&self[], &&other[])
+                    Ord::cmp(&&self[..], &&other[..])
                 }
             }
         )+
index 05d864accc130050edb18322e7866b4fed50bc7f..6afe5b2257d279736daa4db1799d48a679f3e53b 100644 (file)
@@ -76,6 +76,7 @@
 
 use intrinsics;
 use cell::UnsafeCell;
+use marker::PhantomData;
 
 /// A boolean type which can be safely shared between threads.
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -105,6 +106,7 @@ unsafe impl Sync for AtomicUsize {}
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct AtomicPtr<T> {
     p: UnsafeCell<usize>,
+    _marker: PhantomData<*mut T>,
 }
 
 unsafe impl<T> Sync for AtomicPtr<T> {}
@@ -791,7 +793,8 @@ impl<T> AtomicPtr<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(p: *mut T) -> AtomicPtr<T> {
-        AtomicPtr { p: UnsafeCell::new(p as usize) }
+        AtomicPtr { p: UnsafeCell::new(p as usize),
+                    _marker: PhantomData }
     }
 
     /// Loads a value from the pointer.
diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs
deleted file mode 100644 (file)
index 035443e..0000000
+++ /dev/null
@@ -1,265 +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.
-//!
-//! # The `BorrowFrom` traits
-//!
-//! 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 `BorrowFrom`
-//! trait: if `T: BorrowFrom<U>`, then `&T` can be borrowed from `&U`.  A given
-//! type can be borrowed as multiple different types. In particular, `Vec<T>:
-//! BorrowFrom<Vec<T>>` and `[T]: BorrowFrom<Vec<T>>`.
-//!
-//! # The `ToOwned` trait
-//!
-//! 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.
-//!
-//! # The `Cow` (clone-on-write) type
-//!
-//! 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 `BorrowFrom` 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.
-
-#![unstable(feature = "core",
-            reason = "recently added as part of collections reform")]
-
-use clone::Clone;
-use cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
-use fmt;
-use marker::Sized;
-use ops::Deref;
-use option::Option;
-use self::Cow::*;
-
-/// A trait for borrowing data.
-#[old_orphan_check]
-pub trait BorrowFrom<Owned: ?Sized> {
-    /// Immutably borrow from an owned value.
-    fn borrow_from(owned: &Owned) -> &Self;
-}
-
-/// A trait for mutably borrowing data.
-#[old_orphan_check]
-pub trait BorrowFromMut<Owned: ?Sized> : BorrowFrom<Owned> {
-    /// Mutably borrow from an owned value.
-    fn borrow_from_mut(owned: &mut Owned) -> &mut Self;
-}
-
-impl<T: ?Sized> BorrowFrom<T> for T {
-    fn borrow_from(owned: &T) -> &T { owned }
-}
-
-impl<T: ?Sized> BorrowFromMut<T> for T {
-    fn borrow_from_mut(owned: &mut T) -> &mut T { owned }
-}
-
-impl<'a, T: ?Sized> BorrowFrom<&'a T> for T {
-    fn borrow_from<'b>(owned: &'b &'a T) -> &'b T { &**owned }
-}
-
-impl<'a, T: ?Sized> BorrowFrom<&'a mut T> for T {
-    fn borrow_from<'b>(owned: &'b &'a mut T) -> &'b T { &**owned }
-}
-
-impl<'a, T: ?Sized> BorrowFromMut<&'a mut T> for T {
-    fn borrow_from_mut<'b>(owned: &'b mut &'a mut T) -> &'b mut T { &mut **owned }
-}
-
-impl<'a, T, B: ?Sized> BorrowFrom<Cow<'a, T, B>> for B where B: ToOwned<T> {
-    fn borrow_from<'b>(owned: &'b Cow<'a, T, B>) -> &'b B {
-        &**owned
-    }
-}
-
-/// Trait for moving into a `Cow`
-#[old_orphan_check]
-pub trait IntoCow<'a, T, B: ?Sized> {
-    /// Moves `self` into `Cow`
-    fn into_cow(self) -> Cow<'a, T, B>;
-}
-
-impl<'a, T, B: ?Sized> IntoCow<'a, T, B> for Cow<'a, T, B> where B: ToOwned<T> {
-    fn into_cow(self) -> Cow<'a, T, B> {
-        self
-    }
-}
-
-/// A generalization of Clone to borrowed data.
-#[old_orphan_check]
-pub trait ToOwned<Owned>: BorrowFrom<Owned> {
-    /// Create owned data from borrowed data, usually by copying.
-    fn to_owned(&self) -> Owned;
-}
-
-impl<T> ToOwned<T> for T where T: Clone {
-    fn to_owned(&self) -> T { self.clone() }
-}
-
-/// A clone-on-write smart pointer.
-///
-/// # Example
-///
-/// ```rust
-/// use std::borrow::Cow;
-///
-/// fn abs_all(input: &mut Cow<Vec<int>, [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;
-///         }
-///     }
-/// }
-/// ```
-pub enum Cow<'a, T, B: ?Sized + 'a> where B: ToOwned<T> {
-    /// Borrowed data.
-    Borrowed(&'a B),
-
-    /// Owned data.
-    Owned(T)
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> Clone for Cow<'a, T, B> where B: ToOwned<T> {
-    fn clone(&self) -> Cow<'a, T, B> {
-        match *self {
-            Borrowed(b) => Borrowed(b),
-            Owned(ref o) => {
-                let b: &B = BorrowFrom::borrow_from(o);
-                Owned(b.to_owned())
-            },
-        }
-    }
-}
-
-impl<'a, T, B: ?Sized> Cow<'a, T, B> where B: ToOwned<T> {
-    /// Acquire a mutable reference to the owned form of the data.
-    ///
-    /// Copies the data if it is not already owned.
-    pub fn to_mut(&mut self) -> &mut T {
-        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.
-    pub fn into_owned(self) -> T {
-        match self {
-            Borrowed(borrowed) => borrowed.to_owned(),
-            Owned(owned) => owned
-        }
-    }
-
-    /// Returns true if this `Cow` wraps a borrowed value
-    pub fn is_borrowed(&self) -> bool {
-        match *self {
-            Borrowed(_) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns true if this `Cow` wraps an owned value
-    pub fn is_owned(&self) -> bool {
-        match *self {
-            Owned(_) => true,
-            _ => false,
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> Deref for Cow<'a, T, B> where B: ToOwned<T>  {
-    type Target = B;
-
-    fn deref(&self) -> &B {
-        match *self {
-            Borrowed(borrowed) => borrowed,
-            Owned(ref owned) => BorrowFrom::borrow_from(owned)
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> Eq for Cow<'a, T, B> where B: Eq + ToOwned<T> {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> Ord for Cow<'a, T, B> where B: Ord + ToOwned<T> {
-    #[inline]
-    fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering {
-        Ord::cmp(&**self, &**other)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b, T, U, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, U, C>> for Cow<'a, T, B> where
-    B: PartialEq<C> + ToOwned<T>,
-    C: ToOwned<U>,
-{
-    #[inline]
-    fn eq(&self, other: &Cow<'b, U, C>) -> bool {
-        PartialEq::eq(&**self, &**other)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned<T> {
-    #[inline]
-    fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option<Ordering> {
-        PartialOrd::partial_cmp(&**self, &**other)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> fmt::Debug for Cow<'a, T, B> where
-    B: fmt::Debug + ToOwned<T>,
-    T: 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, T, B: ?Sized> fmt::Display for Cow<'a, T, B> where
-    B: fmt::Display + ToOwned<T>,
-    T: 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),
-        }
-    }
-}
index 19ec245300d02ab325fec9e3cc6d834a5877201e..b37bad5f7546c21094828cf36e6c54e70593d210 100644 (file)
@@ -215,7 +215,7 @@ impl Ord for Ordering {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn cmp(&self, other: &Ordering) -> Ordering {
-        (*self as int).cmp(&(*other as int))
+        (*self as i32).cmp(&(*other as i32))
     }
 }
 
@@ -224,7 +224,7 @@ impl PartialOrd for Ordering {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
-        (*self as int).partial_cmp(&(*other as int))
+        (*self as i32).partial_cmp(&(*other as i32))
     }
 }
 
@@ -482,7 +482,7 @@ fn ne(&self, _other: &()) -> bool { false }
     }
 
     partial_eq_impl! {
-        bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64
+        bool char usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64
     }
 
     macro_rules! eq_impl {
@@ -492,7 +492,7 @@ impl Eq for $t {}
         )*)
     }
 
-    eq_impl! { () bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 }
+    eq_impl! { () bool char usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 
     macro_rules! partial_ord_impl {
         ($($t:ty)*) => ($(
@@ -535,7 +535,7 @@ fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
         }
     }
 
-    partial_ord_impl! { char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
+    partial_ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 
     macro_rules! ord_impl {
         ($($t:ty)*) => ($(
@@ -565,7 +565,7 @@ fn cmp(&self, other: &bool) -> Ordering {
         }
     }
 
-    ord_impl! { char uint u8 u16 u32 u64 int i8 i16 i32 i64 }
+    ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 
     // & pointers
 
index d79b613f589495c92ef4f360c6103386af567e65..7f46d9cbe5021d3da0308e397e8c3418ba8a82c5 100644 (file)
@@ -16,7 +16,7 @@
 //!
 //! ```
 //! struct SomeOptions {
-//!     foo: int,
+//!     foo: i32,
 //!     bar: f32,
 //! }
 //! ```
@@ -28,7 +28,7 @@
 //!
 //! #[derive(Default)]
 //! struct SomeOptions {
-//!     foo: int,
+//!     foo: i32,
 //!     bar: f32,
 //! }
 //!
@@ -56,7 +56,7 @@
 //!
 //! #[derive(Default)]
 //! struct SomeOptions {
-//!     foo: int,
+//!     foo: i32,
 //!     bar: f32,
 //!     baz: Kind,
 //! }
@@ -73,7 +73,7 @@
 //! # use std::default::Default;
 //! # #[derive(Default)]
 //! # struct SomeOptions {
-//! #     foo: int,
+//! #     foo: i32,
 //! #     bar: f32,
 //! # }
 //! fn main() {
@@ -93,7 +93,7 @@
 /// ```
 /// #[derive(Default)]
 /// struct SomeOptions {
-///     foo: int,
+///     foo: i32,
 ///     bar: f32,
 /// }
 /// ```
@@ -113,7 +113,7 @@ pub trait Default {
     ///
     /// let i: i8 = Default::default();
     /// let (x, y): (Option<String>, f64) = Default::default();
-    /// let (a, b, (c, d)): (int, uint, (bool, bool)) = Default::default();
+    /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default();
     /// ```
     ///
     /// Making your own:
@@ -150,13 +150,13 @@ fn default() -> $t { $v }
 default_impl! { bool, false }
 default_impl! { char, '\x00' }
 
-default_impl! { uint, 0 }
+default_impl! { usize, 0 }
 default_impl! { u8, 0 }
 default_impl! { u16, 0 }
 default_impl! { u32, 0 }
 default_impl! { u64, 0 }
 
-default_impl! { int, 0 }
+default_impl! { isize, 0 }
 default_impl! { i8, 0 }
 default_impl! { i16, 0 }
 default_impl! { i32, 0 }
index 67c8c9fec09ab9df4fd04c16439b783dcc423e89..a2c1bbc03317e9da08451e0b2b2d6194d385568b 100644 (file)
@@ -16,7 +16,7 @@
 use cell::{Cell, RefCell, Ref, RefMut, BorrowState};
 use char::CharExt;
 use iter::{Iterator, IteratorExt};
-use marker::{Copy, Sized};
+use marker::{Copy, PhantomData, Sized};
 use mem;
 use option::Option;
 use option::Option::{Some, None};
@@ -914,6 +914,11 @@ fn fmt(&self, f: &mut Formatter) -> Result {
         f.pad("()")
     }
 }
+impl<T> Debug for PhantomData<T> {
+    fn fmt(&self, f: &mut Formatter) -> Result {
+        f.pad("PhantomData")
+    }
+}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Copy + Debug> Debug for Cell<T> {
index a5d2618eff948959e881f655beaa839d75b4536d..2e83334b93732378c960019def28bbef57e2ee77 100644 (file)
@@ -35,7 +35,7 @@
 //! the trait `Hash`:
 //!
 //! ```rust
-//! use std::hash::{hash, Hash, Hasher, Writer, SipHasher};
+//! use std::hash::{hash, Hash, Hasher, SipHasher};
 //!
 //! struct Person {
 //!     id: uint,
@@ -43,8 +43,8 @@
 //!     phone: u64,
 //! }
 //!
-//! impl<H: Hasher + Writer> Hash<H> for Person {
-//!     fn hash(&self, state: &mut H) {
+//! impl Hash for Person {
+//!     fn hash<H: Hasher>(&self, state: &mut H) {
 //!         self.id.hash(state);
 //!         self.phone.hash(state);
 //!     }
 //! assert_eq!(hash::<_, SipHasher>(&person1), hash::<_, SipHasher>(&person2));
 //! ```
 
-#![unstable(feature = "hash",
-            reason = "module was recently redesigned")]
+#![stable(feature = "rust1", since = "1.0.0")]
 
 use prelude::*;
 
-use borrow::{Cow, ToOwned};
 use default::Default;
 use mem;
-use num::Int;
 
 pub use self::sip::SipHasher;
 
 /// 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))]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Hash {
+    /// Feeds this value into the state given, updating the hasher as necessary.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn hash<H: Hasher>(&self, state: &mut H);
+
+    /// Feeds a slice of this type into the state provided.
+    #[unstable(feature = "hash", reason = "module was recently redesigned")]
+    fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) where Self: Sized {
+        for piece in data {
+            piece.hash(state);
+        }
+    }
+}
+
+/// 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")]
+    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) {
+        if cfg!(target_pointer_width = "32") {
+            self.write_u32(i as u32)
+        } else {
+            self.write_u64(i as u64)
+        }
+    }
+
+    /// 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
@@ -99,6 +197,7 @@ pub trait Hasher {
 #[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]);
 }
@@ -107,148 +206,292 @@ pub trait Writer {
 ///
 /// 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();
+    value.hash(&mut h);
+    h.finish()
+}
+
 //////////////////////////////////////////////////////////////////////////////
 
-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 as $uty).to_le() as $ty)
-                };
-                state.write(&a)
+#[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_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 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)
+    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);
-                        )*
+    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_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<'a, S: Hasher, T: ?Sized + Hash<S>> Hash<S> for &'a 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<'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 *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);
+        }
     }
 }
 
-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);
+#[cfg(not(stage0))]
+mod impls {
+    use prelude::*;
+
+    use slice;
+    use super::*;
+
+    macro_rules! impl_write {
+        ($(($ty:ident, $meth:ident),)*) => {$(
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl Hash for $ty {
+                fn hash<H: Hasher>(&self, state: &mut H) {
+                    state.$meth(*self)
+                }
+
+                fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) {
+                    let newlen = data.len() * ::$ty::BYTES;
+                    let ptr = data.as_ptr() as *const u8;
+                    state.write(unsafe { slice::from_raw_parts(ptr, newlen) })
+                }
+            }
+        )*}
     }
-}
 
-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);
+    impl_write! {
+        (u8, write_u8),
+        (u16, write_u16),
+        (u32, write_u32),
+        (u64, write_u64),
+        (usize, write_usize),
+        (i8, write_i8),
+        (i16, write_i16),
+        (i32, write_i32),
+        (i64, write_i64),
+        (isize, write_isize),
     }
-}
 
-impl<'a, T, B: ?Sized, S: Hasher> Hash<S> for Cow<'a, T, B>
-    where B: Hash<S> + ToOwned<T>
-{
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        Hash::hash(&**self, state)
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl Hash for bool {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            state.write_u8(*self as u8)
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl Hash for char {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            state.write_u32(*self as u32)
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl Hash for str {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            state.write(self.as_bytes());
+            state.write_u8(0xff)
+        }
+    }
+
+    macro_rules! impl_hash_tuple {
+        () => (
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl Hash for () {
+                fn hash<H: Hasher>(&self, _state: &mut H) {}
+            }
+        );
+
+        ( $($name:ident)+) => (
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl<$($name: Hash),*> Hash for ($($name,)*) {
+                #[allow(non_snake_case)]
+                fn hash<S: Hasher>(&self, state: &mut S) {
+                    let ($(ref $name,)*) = *self;
+                    $($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 }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T: Hash> Hash for [T] {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            self.len().hash(state);
+            Hash::hash_slice(self, state)
+        }
+    }
+
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<'a, T: ?Sized + Hash> Hash for &'a T {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            (**self).hash(state);
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<'a, T: ?Sized + Hash> Hash for &'a mut T {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            (**self).hash(state);
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T> Hash for *const T {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            state.write_usize(*self as usize)
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T> Hash for *mut T {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            state.write_usize(*self as usize)
+        }
     }
 }
index d405d0d28beb3636fbac2387771a037a4f9f02cf..ce8917cc20589a93b0edddccc6ede9ed5fe7e329 100644 (file)
@@ -15,7 +15,9 @@
 use prelude::*;
 use default::Default;
 
-use super::{Hasher, Writer};
+use super::Hasher;
+#[cfg(stage0)]
+use super::Writer;
 
 /// An implementation of SipHash 2-4.
 ///
@@ -30,6 +32,7 @@
 /// strong, this implementation has not been reviewed for such purposes.
 /// As such, all cryptographic uses of this implementation are strongly
 /// discouraged.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct SipHasher {
     k0: u64,
     k1: u64,
@@ -88,12 +91,14 @@ macro_rules! compress {
 impl SipHasher {
     /// Creates a new `SipHasher` with the two initial keys set to 0.
     #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new() -> SipHasher {
         SipHasher::new_with_keys(0, 0)
     }
 
     /// Creates a `SipHasher` that is keyed off the provided keys.
     #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
         let mut state = SipHasher {
             k0: key0,
@@ -114,10 +119,16 @@ pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
     #[unstable(feature = "hash")]
     #[deprecated(since = "1.0.0", reason = "renamed to finish")]
     pub fn result(&self) -> u64 { self.finish() }
-}
 
-impl Writer for SipHasher {
-    #[inline]
+    fn reset(&mut self) {
+        self.length = 0;
+        self.v0 = self.k0 ^ 0x736f6d6570736575;
+        self.v1 = self.k1 ^ 0x646f72616e646f6d;
+        self.v2 = self.k0 ^ 0x6c7967656e657261;
+        self.v3 = self.k1 ^ 0x7465646279746573;
+        self.ntail = 0;
+    }
+
     fn write(&mut self, msg: &[u8]) {
         let length = msg.len();
         self.length += length;
@@ -164,16 +175,28 @@ fn write(&mut self, msg: &[u8]) {
     }
 }
 
+#[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.length = 0;
-        self.v0 = self.k0 ^ 0x736f6d6570736575;
-        self.v1 = self.k1 ^ 0x646f72616e646f6d;
-        self.v2 = self.k0 ^ 0x6c7967656e657261;
-        self.v3 = self.k1 ^ 0x7465646279746573;
-        self.ntail = 0;
+        self.reset();
+    }
+
+    #[inline]
+    #[cfg(not(stage0))]
+    fn write(&mut self, msg: &[u8]) {
+        self.write(msg)
     }
 
     fn finish(&self) -> u64 {
@@ -199,6 +222,7 @@ fn finish(&self) -> u64 {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Clone for SipHasher {
     #[inline]
     fn clone(&self) -> SipHasher {
@@ -216,6 +240,7 @@ fn clone(&self) -> SipHasher {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Default for SipHasher {
     fn default() -> SipHasher {
         SipHasher::new()
index 050c144b742994bf1d51dd8d57fc7286192b3f61..b2ee95963878edb13af4a4b99c9cf529377b13f4 100644 (file)
 #[derive(Copy)]
 pub struct TyDesc {
     // sizeof(T)
-    pub size: uint,
+    pub size: usize,
 
     // alignof(T)
-    pub align: uint,
+    pub align: usize,
 
     // Called when a value of type `T` is no longer needed
     pub drop_glue: GlueFn,
@@ -186,15 +186,15 @@ pub struct TyDesc {
     /// would *exactly* overwrite a value. When laid out in vectors
     /// and structures there may be additional padding between
     /// elements.
-    pub fn size_of<T>() -> uint;
+    pub fn size_of<T>() -> usize;
 
     /// Move a value to an uninitialized memory location.
     ///
     /// Drop glue is not run on the destination.
     pub fn move_val_init<T>(dst: &mut T, src: T);
 
-    pub fn min_align_of<T>() -> uint;
-    pub fn pref_align_of<T>() -> uint;
+    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;
@@ -253,7 +253,7 @@ pub struct TyDesc {
     ///
     /// This is implemented as an intrinsic to avoid converting to and from an
     /// integer, since the conversion would throw away aliasing information.
-    pub fn offset<T>(dst: *const T, offset: int) -> *const T;
+    pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
 
     /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
     /// and destination may *not* overlap.
@@ -294,7 +294,7 @@ pub struct TyDesc {
     /// }
     /// ```
     #[unstable(feature = "core")]
-    pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint);
+    pub fn copy_nonoverlapping_memory<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.
@@ -324,13 +324,13 @@ pub struct TyDesc {
     /// ```
     ///
     #[unstable(feature = "core")]
-    pub fn copy_memory<T>(dst: *mut T, src: *const T, count: uint);
+    pub fn copy_memory<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: uint);
+    pub fn set_memory<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
@@ -338,19 +338,19 @@ pub struct TyDesc {
     ///
     /// The volatile parameter parameter is set to `true`, so it will not be optimized out.
     pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
-                                                  count: uint);
+                                                  count: usize);
     /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
     /// a size of `count` * `size_of::<T>()` and an alignment of
     /// `min_align_of::<T>()`
     ///
     /// The volatile parameter parameter is set to `true`, so it will not be optimized out.
-    pub fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: uint);
+    pub fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: usize);
     /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
     /// size of `count` * `size_of::<T>()` and an alignment of
     /// `min_align_of::<T>()`.
     ///
     /// The volatile parameter parameter is set to `true`, so it will not be optimized out.
-    pub fn volatile_set_memory<T>(dst: *mut T, val: u8, count: uint);
+    pub fn volatile_set_memory<T>(dst: *mut T, val: u8, count: usize);
 
     /// Perform a volatile load from the `src` pointer.
     pub fn volatile_load<T>(src: *const T) -> T;
index fffba1561a38038d75b3df26db4cbf3bec63d646..8fb10b5b2dc2a53ca3d40709ce7c2abcd46b6e66 100644 (file)
@@ -62,6 +62,7 @@
 use cmp;
 use cmp::Ord;
 use default::Default;
+use marker;
 use mem;
 use num::{ToPrimitive, Int};
 use ops::{Add, Deref, FnMut};
@@ -113,9 +114,9 @@ fn size_hint(&self) -> (usize, Option<usize>) { (**self).size_hint() }
 #[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 an external iterator.
+    /// Build a container with elements from something iterable.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn from_iter<T: Iterator<Item=A>>(iterator: T) -> Self;
+    fn from_iter<T: IntoIterator<Item=A>>(iterator: T) -> Self;
 }
 
 /// Conversion into an `Iterator`
@@ -147,7 +148,7 @@ fn into_iter(self) -> I {
 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: Iterator<Item=A>>(&mut self, iterator: T);
+    fn extend<T: IntoIterator<Item=A>>(&mut self, iterable: T);
 }
 
 /// An extension trait providing numerous methods applicable to all iterators.
@@ -332,7 +333,7 @@ fn enumerate(self) -> Enumerate<Self> {
     ///
     /// ```
     /// let xs = [100, 200, 300];
-    /// let mut it = xs.iter().map(|x| *x).peekable();
+    /// let mut it = xs.iter().cloned().peekable();
     /// assert_eq!(*it.peek().unwrap(), 100);
     /// assert_eq!(it.next().unwrap(), 100);
     /// assert_eq!(it.next().unwrap(), 200);
@@ -522,11 +523,11 @@ fn fuse(self) -> Fuse<Self> {
     ///
     /// let a = [1, 4, 2, 3, 8, 9, 6];
     /// let sum = a.iter()
-    ///             .map(|&x| x)
-    ///             .inspect(|&x| println!("filtering {}", x))
-    ///             .filter(|&x| x % 2 == 0)
-    ///             .inspect(|&x| println!("{} made it through", x))
-    ///             .sum();
+    ///            .map(|x| *x)
+    ///            .inspect(|&x| println!("filtering {}", x))
+    ///            .filter(|&x| x % 2 == 0)
+    ///            .inspect(|&x| println!("{} made it through", x))
+    ///            .sum();
     /// println!("{}", sum);
     /// ```
     #[inline]
@@ -561,7 +562,7 @@ fn by_ref(&mut self) -> &mut Self { self }
     ///
     /// ```
     /// let a = [1, 2, 3, 4, 5];
-    /// let b: Vec<_> = a.iter().map(|&x| x).collect();
+    /// let b: Vec<_> = a.iter().cloned().collect();
     /// assert_eq!(a, b);
     /// ```
     #[inline]
@@ -937,7 +938,7 @@ fn rev(self) -> Rev<Self> {
     ///
     /// ```
     /// let a = [(1, 2), (3, 4)];
-    /// let (left, right): (Vec<_>, Vec<_>) = a.iter().map(|&x| x).unzip();
+    /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip();
     /// assert_eq!([1, 3], left);
     /// assert_eq!([2, 4], right);
     /// ```
@@ -947,7 +948,7 @@ fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
         FromB: Default + Extend<B>,
         Self: Iterator<Item=(A, B)>,
     {
-        struct SizeHint<A>(usize, Option<usize>);
+        struct SizeHint<A>(usize, Option<usize>, marker::PhantomData<A>);
         impl<A> Iterator for SizeHint<A> {
             type Item = A;
 
@@ -961,8 +962,8 @@ fn size_hint(&self) -> (usize, Option<usize>) {
         let mut ts: FromA = Default::default();
         let mut us: FromB = Default::default();
 
-        ts.extend(SizeHint(lo, hi));
-        us.extend(SizeHint(lo, hi));
+        ts.extend(SizeHint(lo, hi, marker::PhantomData));
+        us.extend(SizeHint(lo, hi, marker::PhantomData));
 
         for (t, u) in self {
             ts.extend(Some(t).into_iter());
@@ -1142,7 +1143,7 @@ pub trait AdditiveIterator<A> {
     /// use std::iter::AdditiveIterator;
     ///
     /// let a = [1i32, 2, 3, 4, 5];
-    /// let mut it = a.iter().map(|&x| x);
+    /// let mut it = a.iter().cloned();
     /// assert!(it.sum() == 15);
     /// ```
     fn sum(self) -> A;
@@ -1305,6 +1306,23 @@ impl<T, D, I> ExactSizeIterator for Cloned<I> where
     I: ExactSizeIterator<Item=D>,
 {}
 
+#[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>
+{
+    #[inline]
+    fn indexable(&self) -> usize {
+        self.it.indexable()
+    }
+
+    #[inline]
+    fn idx(&mut self, index: usize) -> Option<T> {
+        self.it.idx(index).cloned()
+    }
+}
+
 /// An iterator that repeats endlessly
 #[derive(Clone)]
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
@@ -2047,8 +2065,8 @@ pub struct Scan<I, St, F> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<B, I: Iterator, St, F> Iterator for Scan<I, St, F> where
-    F: FnMut(&mut St, I::Item) -> Option<B>,
+impl<A, B, I: Iterator<Item=A>, St, F> Iterator for Scan<I, St, F> where
+    F: FnMut(&mut St, A) -> Option<B>,
 {
     type Item = B;
 
index f0c60ffe4bf66f8bb0794d105ac56b83230c14d5..3c58480ff0cfa1d70275b9f04bf6931782575468 100644 (file)
 
 pub mod any;
 pub mod atomic;
-pub mod borrow;
 pub mod cell;
 pub mod char;
 pub mod panicking;
index 56e1c5dedc1cebbc06c21b043629542de6dc4bea..d284eb341792b4d363c3cd6896346b7db581a32d 100644 (file)
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use clone::Clone;
+use cmp;
+use option::Option;
+use hash::Hash;
+use hash::Hasher;
 
 /// Types able to be transferred across thread boundaries.
 #[unstable(feature = "core",
@@ -37,12 +41,11 @@ pub unsafe trait Send: 'static {
     // empty.
 }
 /// Types able to be transferred across thread boundaries.
-#[unstable(feature = "core",
-           reason = "will be overhauled with new lifetime rules; see RFC 458")]
+#[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 {
+pub unsafe trait Send : MarkerTrait {
     // empty.
 }
 
@@ -50,7 +53,7 @@ pub unsafe trait Send {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang="sized"]
 #[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"]
-pub trait Sized {
+pub trait Sized : MarkerTrait {
     // Empty.
 }
 
@@ -155,7 +158,7 @@ pub trait Sized {
 /// 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 {
+pub trait Copy : MarkerTrait {
     // Empty.
 }
 
@@ -204,236 +207,179 @@ pub trait Copy {
 /// 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).
-#[unstable(feature = "core",
-           reason = "will be overhauled with new lifetime rules; see RFC 458")]
+#[stable(feature = "rust1", since = "1.0.0")]
 #[lang="sync"]
 #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
-pub unsafe trait Sync {
+pub unsafe trait Sync : MarkerTrait {
     // Empty
 }
 
-/// A marker type that indicates to the compiler that the instances
-/// of the type itself owns instances of the type parameter `T`.
-///
-/// This is used to indicate 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. For example, the type may hold a `*mut T`, which the
-/// compiler does not automatically treat as owned.
+/// 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.
 #[unstable(feature = "core",
-           reason = "Newly added to deal with scoping and destructor changes")]
-#[lang="phantom_data"]
-#[derive(PartialEq, Eq, PartialOrd, Ord)]
-pub struct PhantomData<T: ?Sized>;
+           reason = "likely to change with new variance strategy")]
+#[lang="no_copy_bound"]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct NoCopy;
 
-impl<T: ?Sized> Copy for PhantomData<T> {}
-impl<T: ?Sized> Clone for PhantomData<T> {
-    fn clone(&self) -> PhantomData<T> { *self }
+/// A type which is considered managed by the GC. This is typically
+/// embedded in other types.
+#[unstable(feature = "core",
+           reason = "likely to change with new variance strategy")]
+#[lang="managed_bound"]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
+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) {
+            }
+        }
+
+        impl<T:?Sized> cmp::PartialEq for $t<T> {
+            fn eq(&self, _other: &$t<T>) -> bool {
+                true
+            }
+        }
+
+        impl<T:?Sized> cmp::Eq for $t<T> {
+        }
+
+        impl<T:?Sized> cmp::PartialOrd for $t<T> {
+            fn partial_cmp(&self, _other: &$t<T>) -> Option<cmp::Ordering> {
+                Option::Some(cmp::Ordering::Equal)
+            }
+        }
+
+        impl<T:?Sized> cmp::Ord for $t<T> {
+            fn cmp(&self, _other: &$t<T>) -> cmp::Ordering {
+                cmp::Ordering::Equal
+            }
+        }
+
+        impl<T:?Sized> Copy for $t<T> { }
+
+        impl<T:?Sized> Clone for $t<T> {
+            fn clone(&self) -> $t<T> {
+                $t
+            }
+        }
+        )
 }
 
-/// A marker type whose type parameter `T` is considered to be
-/// covariant with respect to the type itself. This is (typically)
-/// used to indicate that an instance of the type `T` is being stored
-/// into memory and read from, even though that may not be apparent.
-///
-/// For more information about variance, refer to this Wikipedia
-/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
-///
-/// *Note:* It is very unusual to have to add a covariant constraint.
-/// If you are not sure, you probably want to use `InvariantType`.
+/// `MarkerTrait` is intended to be used as the supertrait for traits
+/// that don't have any methods but instead serve just to designate
+/// categories of types. An example would be the `Send` trait, which
+/// indicates types that are sendable: `Send` does not itself offer
+/// any methods, but instead is used to gate access to data.
+///
+/// FIXME. Better documentation needed here!
+pub trait MarkerTrait : PhantomFn<Self> { }
+impl<T:?Sized> MarkerTrait for T { }
+
+/// `PhantomFn` is a marker trait for use with traits that contain
+/// type or lifetime parameters that do not appear in any of their
+/// methods. In that case, you can either remove those parameters, or
+/// add a `PhantomFn` supertrait that reflects the signature of
+/// methods that compiler should "pretend" exists. This most commonly
+/// occurs for traits with no methods: in that particular case, you
+/// can extend `MarkerTrait`, which is equivalent to
+/// `PhantomFn<Self>`.
 ///
 /// # Example
 ///
-/// Given a struct `S` that includes a type parameter `T`
-/// but does not actually *reference* that type parameter:
+/// As an example, consider a trait with no methods like `Even`, meant
+/// to represent types that are "even":
 ///
-/// ```ignore
-/// use std::mem;
-///
-/// struct S<T> { x: *() }
-/// fn get<T>(s: &S<T>) -> T {
-///    unsafe {
-///        let x: *T = mem::transmute(s.x);
-///        *x
-///    }
-/// }
+/// ```rust,ignore
+/// trait Even { }
 /// ```
 ///
-/// The type system would currently infer that the value of
-/// the type parameter `T` is irrelevant, and hence a `S<int>` is
-/// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for
-/// any `U`). But this is incorrect because `get()` converts the
-/// `*()` into a `*T` and reads from it. Therefore, we should include the
-/// a marker field `CovariantType<T>` to inform the type checker that
-/// `S<T>` is a subtype of `S<U>` if `T` is a subtype of `U`
-/// (for example, `S<&'static int>` is a subtype of `S<&'a int>`
-/// for some lifetime `'a`, but not the other way around).
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="covariant_type"]
-#[derive(PartialEq, Eq, PartialOrd, Ord)]
-pub struct CovariantType<T: ?Sized>;
-
-impl<T: ?Sized> Copy for CovariantType<T> {}
-impl<T: ?Sized> Clone for CovariantType<T> {
-    fn clone(&self) -> CovariantType<T> { *self }
-}
-
-/// A marker type whose type parameter `T` is considered to be
-/// contravariant with respect to the type itself. This is (typically)
-/// used to indicate that an instance of the type `T` will be consumed
-/// (but not read from), even though that may not be apparent.
+/// In this case, because the implicit parameter `Self` is unused, the
+/// compiler will issue an error. The only purpose of this trait is to
+/// categorize types (and hence instances of those types) as "even" or
+/// not, so if we *were* going to have a method, it might look like:
 ///
-/// For more information about variance, refer to this Wikipedia
-/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
+/// ```rust,ignore
+/// trait Even {
+///     fn is_even(self) -> bool { true }
+/// }
+/// ```
 ///
-/// *Note:* It is very unusual to have to add a contravariant constraint.
-/// If you are not sure, you probably want to use `InvariantType`.
+/// Therefore, we can model a method like this as follows:
 ///
-/// # Example
+/// ```rust
+/// use std::marker::PhantomFn;
+/// trait Even : PhantomFn<Self> { }
+/// ```
 ///
-/// Given a struct `S` that includes a type parameter `T`
-/// but does not actually *reference* that type parameter:
+/// Another equivalent, but clearer, option would be to use
+/// `MarkerTrait`:
 ///
+/// ```rust
+/// use std::marker::MarkerTrait;
+/// trait Even : MarkerTrait { }
 /// ```
-/// use std::mem;
-///
-/// struct S<T> { x: *const () }
-/// fn get<T>(s: &S<T>, v: T) {
-///    unsafe {
-///        let x: fn(T) = mem::transmute(s.x);
-///        x(v)
-///    }
-/// }
-/// ```
-///
-/// The type system would currently infer that the value of
-/// the type parameter `T` is irrelevant, and hence a `S<int>` is
-/// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for
-/// any `U`). But this is incorrect because `get()` converts the
-/// `*()` into a `fn(T)` and then passes a value of type `T` to it.
-///
-/// Supplying a `ContravariantType` marker would correct the
-/// problem, because it would mark `S` so that `S<T>` is only a
-/// subtype of `S<U>` if `U` is a subtype of `T`; given that the
-/// function requires arguments of type `T`, it must also accept
-/// arguments of type `U`, hence such a conversion is safe.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="contravariant_type"]
-#[derive(PartialEq, Eq, PartialOrd, Ord)]
-pub struct ContravariantType<T: ?Sized>;
-
-impl<T: ?Sized> Copy for ContravariantType<T> {}
-impl<T: ?Sized> Clone for ContravariantType<T> {
-    fn clone(&self) -> ContravariantType<T> { *self }
-}
-
-/// A marker type whose type parameter `T` is considered to be
-/// invariant with respect to the type itself. This is (typically)
-/// used to indicate that instances of the type `T` may be read or
-/// written, even though that may not be apparent.
 ///
-/// For more information about variance, refer to this Wikipedia
-/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
+/// # Parameters
 ///
-/// # Example
+/// - `A` represents the type of the method's argument. You can use a
+///   tuple to represent "multiple" arguments. Any types appearing here
+///   will be considered "contravariant".
+/// - `R`, if supplied, represents the method's return type. This defaults
+///   to `()` as it is rarely needed.
 ///
-/// The Cell type is an example of an `InvariantType` which uses unsafe
-/// code to achieve "interior" mutability:
+/// # Additional reading
 ///
-/// ```
-/// struct Cell<T> { value: T }
-/// ```
+/// More details and background can be found in [RFC 738][738].
 ///
-/// The type system would infer that `value` is only read here
-/// and never written, but in fact `Cell` uses unsafe code to achieve
-/// interior mutability. In order to get correct behavior, the
-/// `InvariantType` marker must be applied.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="invariant_type"]
-#[derive(PartialEq, Eq, PartialOrd, Ord)]
-pub struct InvariantType<T: ?Sized>;
-
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-impl<T: ?Sized> Copy for InvariantType<T> {}
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-impl<T: ?Sized> Clone for InvariantType<T> {
-    fn clone(&self) -> InvariantType<T> { *self }
-}
-
-/// As `CovariantType`, but for lifetime parameters. Using
-/// `CovariantLifetime<'a>` indicates that it is ok to substitute
-/// a *longer* lifetime for `'a` than the one you originally
-/// started with (e.g., you could convert any lifetime `'foo` to
-/// `'static`). You almost certainly want `ContravariantLifetime`
-/// instead, or possibly `InvariantLifetime`. The only case where
-/// it would be appropriate is that you have a (type-casted, and
-/// hence hidden from the type system) function pointer with a
-/// signature like `fn(&'a T)` (and no other uses of `'a`). In
-/// this case, it is ok to substitute a larger lifetime for `'a`
-/// (e.g., `fn(&'static T)`), because the function is only
-/// becoming more selective in terms of what it accepts as
-/// argument.
-///
-/// For more information about variance, refer to this Wikipedia
-/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="covariant_lifetime"]
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct CovariantLifetime<'a>;
+/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md
+#[lang="phantom_fn"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
 
-/// As `ContravariantType`, but for lifetime parameters. Using
-/// `ContravariantLifetime<'a>` indicates that it is ok to
-/// substitute a *shorter* lifetime for `'a` than the one you
-/// originally started with (e.g., you could convert `'static` to
-/// any lifetime `'foo`). This is appropriate for cases where you
-/// have an unsafe pointer that is actually a pointer into some
-/// memory with lifetime `'a`, and thus you want to limit the
-/// lifetime of your data structure to `'a`. An example of where
-/// this is used is the iterator for vectors.
-///
-/// For more information about variance, refer to this Wikipedia
-/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="contravariant_lifetime"]
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct ContravariantLifetime<'a>;
+#[cfg(stage0)] // built into the trait matching system after stage0
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
 
-/// As `InvariantType`, but for lifetime parameters. Using
-/// `InvariantLifetime<'a>` indicates that it is not ok to
-/// substitute any other lifetime for `'a` besides its original
-/// value. This is appropriate for cases where you have an unsafe
-/// pointer that is actually a pointer into memory with lifetime `'a`,
-/// and this pointer is itself stored in an inherently mutable
-/// location (such as a `Cell`).
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="invariant_lifetime"]
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct InvariantLifetime<'a>;
+/// Specific to stage0. You should not be seeing these docs!
+#[cfg(stage0)]
+#[lang="covariant_type"] // only relevant to stage0
+pub struct PhantomData<T:?Sized>;
 
-/// 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.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="no_copy_bound"]
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
-pub struct NoCopy;
+/// `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.
+///
+/// For 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>;
 
-/// A type which is considered managed by the GC. This is typically
-/// embedded in other types.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="managed_bound"]
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
-pub struct Managed;
+impls! { PhantomData }
 
 #[cfg(not(stage0))]
 mod impls {
@@ -442,3 +388,40 @@ mod impls {
     unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {}
     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>;
+
+/// 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>;
+
+/// 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 5644f76306929e0fbfe7a531058e679bb12a9fb3..230587b726fd1e022748df5e76ab48899237be7f 100644 (file)
 
 //! Exposes the NonZero lang item which provides optimization hints.
 
+use marker::{Sized, MarkerTrait};
 use ops::Deref;
-use ptr::Unique;
 
 /// Unsafe trait to indicate what types are usable with the NonZero struct
-pub unsafe trait Zeroable {}
+pub unsafe trait Zeroable : MarkerTrait {}
 
-unsafe impl<T> Zeroable for *const T {}
-unsafe impl<T> Zeroable for *mut T {}
-unsafe impl<T> Zeroable for Unique<T> { }
+unsafe impl<T:?Sized> Zeroable for *const T {}
+unsafe impl<T:?Sized> Zeroable for *mut T {}
 unsafe impl Zeroable for isize {}
 unsafe impl Zeroable for usize {}
 unsafe impl Zeroable for i8 {}
index 9a89682127fb1633df1538942e52ac7a277af71e..abfef72a5dbc33b735a67416a191f2e1b093600c 100644 (file)
 use cmp::{Eq, Ord};
 use default::Default;
 use iter::{ExactSizeIterator};
-use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator};
+use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, IntoIterator};
 use mem;
 use ops::{Deref, FnOnce};
 use result::Result::{Ok, Err};
@@ -909,7 +909,7 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn from_iter<I: Iterator<Item=Option<A>>>(iter: I) -> Option<V> {
+    fn from_iter<I: IntoIterator<Item=Option<A>>>(iter: I) -> Option<V> {
         // FIXME(#11084): This could be replaced with Iterator::scan when this
         // performance bug is closed.
 
@@ -934,7 +934,7 @@ fn next(&mut self) -> Option<T> {
             }
         }
 
-        let mut adapter = Adapter { iter: iter, found_none: false };
+        let mut adapter = Adapter { iter: iter.into_iter(), found_none: false };
         let v: V = FromIterator::from_iter(adapter.by_ref());
 
         if adapter.found_none {
index 072c60c7036cffceb2c5c88beb2e14841ebb7a17..16b84dcf18e24aed5952b17cfbf1b7f45b1648c0 100644 (file)
 use mem;
 use clone::Clone;
 use intrinsics;
+use ops::Deref;
 use option::Option::{self, Some, None};
-use marker::{self, Send, Sized, Sync};
+use marker::{PhantomData, Send, Sized, Sync};
+use nonzero::NonZero;
 
 use cmp::{PartialEq, Eq, Ord, PartialOrd};
 use cmp::Ordering::{self, Less, Equal, Greater};
@@ -303,7 +305,7 @@ impl<T> PtrExt for *const T {
 
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_null(self) -> bool { self as usize == 0 }
+    fn is_null(self) -> bool { self == 0 as *const T }
 
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -330,7 +332,7 @@ impl<T> PtrExt for *mut T {
 
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_null(self) -> bool { self as usize == 0 }
+    fn is_null(self) -> bool { self == 0 as *mut T }
 
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -517,15 +519,16 @@ fn ge(&self, other: &*mut T) -> bool { *self >= *other }
 
 /// A wrapper around a raw `*mut T` that indicates that the possessor
 /// of this wrapper owns the referent. This in turn implies that the
-/// `Unique<T>` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a
-/// raw `*mut T` (which conveys no particular ownership semantics).
-/// Useful for building abstractions like `Vec<T>` or `Box<T>`, which
+/// `Unique<T>` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a raw
+/// `*mut T` (which conveys no particular ownership semantics).  It
+/// also implies that the referent of the pointer should not be
+/// 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> {
-    /// The wrapped `*mut T`.
-    pub ptr: *mut T,
-    _own: marker::PhantomData<T>,
+pub struct Unique<T:?Sized> {
+    pointer: NonZero<*const T>,
+    _marker: PhantomData<T>,
 }
 
 /// `Unique` pointers are `Send` if `T` is `Send` because the data they
@@ -542,25 +545,34 @@ unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
 #[unstable(feature = "core", reason = "recently added to this module")]
 unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
 
-impl<T> Unique<T> {
-    /// Returns a null Unique.
+impl<T:?Sized> Unique<T> {
+    /// Create a new `Unique`.
     #[unstable(feature = "core",
                reason = "recently added to this module")]
-    pub fn null() -> Unique<T> {
-        Unique(null_mut())
+    pub unsafe fn new(ptr: *mut T) -> Unique<T> {
+        Unique { pointer: NonZero::new(ptr as *const T), _marker: PhantomData }
     }
 
-    /// Return an (unsafe) pointer into the memory owned by `self`.
+    /// Dereference the content.
     #[unstable(feature = "core",
                reason = "recently added to this module")]
-    pub unsafe fn offset(self, offset: isize) -> *mut T {
-        self.ptr.offset(offset)
+    pub unsafe fn get(&self) -> &T {
+        &**self.pointer
+    }
+
+    /// Mutably dereference the content.
+    #[unstable(feature = "core",
+               reason = "recently added to this module")]
+    pub unsafe fn get_mut(&mut self) -> &mut T {
+        &mut ***self
     }
 }
 
-/// Creates a `Unique` wrapped around `ptr`, taking ownership of the
-/// data referenced by `ptr`.
-#[allow(non_snake_case)]
-pub fn Unique<T: ?Sized>(ptr: *mut T) -> Unique<T> {
-    Unique { ptr: ptr, _own: marker::PhantomData }
+impl<T:?Sized> Deref for Unique<T> {
+    type Target = *mut T;
+
+    #[inline]
+    fn deref<'a>(&'a self) -> &'a *mut T {
+        unsafe { mem::transmute(&*self.pointer) }
+    }
 }
index 1a874ee178ba0fd8c477c69e2232b01a1d50edd5..23e936a75d7097e04f972a3da25796a285090711 100644 (file)
 
 use clone::Clone;
 use fmt;
-use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator};
+use iter::{Iterator, IteratorExt, DoubleEndedIterator,
+           FromIterator, ExactSizeIterator, IntoIterator};
 use ops::{FnMut, FnOnce};
 use option::Option::{self, None, Some};
 use slice::AsSlice;
@@ -906,7 +907,7 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
     /// assert!(res == Ok(vec!(2, 3)));
     /// ```
     #[inline]
-    fn from_iter<I: Iterator<Item=Result<A, E>>>(iter: I) -> Result<V, E> {
+    fn from_iter<I: IntoIterator<Item=Result<A, E>>>(iter: I) -> Result<V, E> {
         // FIXME(#11084): This could be replaced with Iterator::scan when this
         // performance bug is closed.
 
@@ -931,7 +932,7 @@ fn next(&mut self) -> Option<T> {
             }
         }
 
-        let mut adapter = Adapter { iter: iter, err: None };
+        let mut adapter = Adapter { iter: iter.into_iter(), err: None };
         let v: V = FromIterator::from_iter(adapter.by_ref());
 
         match adapter.err {
index bbfe7e58ef4ac4f703b0294c5e6cbab7d1da8b29..a86da53b372a9bfc2b14969f445fc7ad1be40465 100644 (file)
@@ -140,11 +140,11 @@ fn iter<'a>(&'a self) -> Iter<'a, T> {
             if mem::size_of::<T>() == 0 {
                 Iter {ptr: p,
                       end: (p as usize + self.len()) as *const T,
-                      marker: marker::ContravariantLifetime::<'a>}
+                      _marker: marker::PhantomData}
             } else {
                 Iter {ptr: p,
                       end: p.offset(self.len() as isize),
-                      marker: marker::ContravariantLifetime::<'a>}
+                      _marker: marker::PhantomData}
             }
         }
     }
@@ -279,11 +279,11 @@ fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> {
             if mem::size_of::<T>() == 0 {
                 IterMut {ptr: p,
                          end: (p as usize + self.len()) as *mut T,
-                         marker: marker::ContravariantLifetime::<'a>}
+                         _marker: marker::PhantomData}
             } else {
                 IterMut {ptr: p,
                          end: p.offset(self.len() as isize),
-                         marker: marker::ContravariantLifetime::<'a>}
+                         _marker: marker::PhantomData}
             }
         }
     }
@@ -733,7 +733,7 @@ macro_rules! make_slice {
 pub struct Iter<'a, T: 'a> {
     ptr: *const T,
     end: *const T,
-    marker: marker::ContravariantLifetime<'a>
+    _marker: marker::PhantomData<&'a T>,
 }
 
 #[unstable(feature = "core")]
@@ -790,7 +790,7 @@ impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Clone for Iter<'a, T> {
-    fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, marker: self.marker } }
+    fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } }
 }
 
 #[unstable(feature = "core", reason = "trait is experimental")]
@@ -823,7 +823,7 @@ fn idx(&mut self, index: usize) -> Option<&'a T> {
 pub struct IterMut<'a, T: 'a> {
     ptr: *mut T,
     end: *mut T,
-    marker: marker::ContravariantLifetime<'a>,
+    _marker: marker::PhantomData<&'a mut T>,
 }
 
 
index ce26abe606dd4b432e7f85101e41e1de83e507d9..eec997b9f10fc76f3090ae58a4d59b5655c1f2b5 100644 (file)
@@ -1280,7 +1280,7 @@ fn index(&self, _index: &ops::RangeFull) -> &str {
 /// Any string that can be represented as a slice
 #[unstable(feature = "core",
            reason = "Instead of taking this bound generically, this trait will be \
-                     replaced with one of slicing syntax (&foo[]), deref coercions, or \
+                     replaced with one of slicing syntax (&foo[..]), deref coercions, or \
                      a more generic conversion trait")]
 pub trait Str {
     /// Work with `self` as a slice.
index fd0d3c676a45ab4d1c0c50cb20087092526576dd..9b6af182f729c291751d2db896acfbc4e5c74200 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use std::mem;
-use std::hash::{Hash, Hasher, Writer};
+use std::hash::{Hash, Hasher};
 use std::default::Default;
 
 struct MyHasher {
@@ -22,25 +22,19 @@ fn default() -> MyHasher {
     }
 }
 
-impl Writer for MyHasher {
-    // Most things we'll just add up the bytes.
+impl Hasher for MyHasher {
     fn write(&mut self, buf: &[u8]) {
         for byte in buf {
             self.hash += *byte as u64;
         }
     }
-}
-
-impl Hasher for MyHasher {
-    type Output = u64;
-    fn reset(&mut self) { self.hash = 0; }
     fn finish(&self) -> u64 { self.hash }
 }
 
 
 #[test]
 fn test_writer_hasher() {
-    fn hash<T: Hash<MyHasher>>(t: &T) -> u64 {
+    fn hash<T: Hash>(t: &T) -> u64 {
         ::std::hash::hash::<_, MyHasher>(t)
     }
 
@@ -90,9 +84,9 @@ struct Custom { hash: u64 }
 struct CustomHasher { output: u64 }
 
 impl Hasher for CustomHasher {
-    type Output = u64;
-    fn reset(&mut self) { self.output = 0; }
     fn finish(&self) -> u64 { self.output }
+    fn write(&mut self, data: &[u8]) { panic!() }
+    fn write_u64(&mut self, data: u64) { self.output = data; }
 }
 
 impl Default for CustomHasher {
@@ -101,15 +95,15 @@ fn default() -> CustomHasher {
     }
 }
 
-impl Hash<CustomHasher> for Custom {
-    fn hash(&self, state: &mut CustomHasher) {
-        state.output = self.hash;
+impl Hash for Custom {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        state.write_u64(self.hash);
     }
 }
 
 #[test]
 fn test_custom_state() {
-    fn hash<T: Hash<CustomHasher>>(t: &T) -> u64 {
+    fn hash<T: Hash>(t: &T) -> u64 {
         ::std::hash::hash::<_, CustomHasher>(t)
     }
 
index 7eb0fb97bed2a54f48efce97d6b65f759c55da5c..39a590c73074332d91a6de9319df3a52e2e70546 100644 (file)
@@ -91,7 +91,7 @@ fn test_iterator_chain() {
     assert_eq!(i, expected.len());
 
     let ys = count(30, 10).take(4);
-    let mut it = xs.iter().map(|&x| x).chain(ys);
+    let mut it = xs.iter().cloned().chain(ys);
     let mut i = 0;
     for x in it {
         assert_eq!(x, expected[i]);
@@ -119,7 +119,7 @@ fn test_iterator_enumerate() {
 #[test]
 fn test_iterator_peekable() {
     let xs = vec![0, 1, 2, 3, 4, 5];
-    let mut it = xs.iter().map(|&x|x).peekable();
+    let mut it = xs.iter().cloned().peekable();
 
     assert_eq!(it.len(), 6);
     assert_eq!(it.peek().unwrap(), &0);
@@ -259,12 +259,12 @@ fn test_inspect() {
     let mut n = 0;
 
     let ys = xs.iter()
-               .map(|&x| x)
+               .cloned()
                .inspect(|_| n += 1)
                .collect::<Vec<uint>>();
 
     assert_eq!(n, xs.len());
-    assert_eq!(&xs[], &ys[]);
+    assert_eq!(&xs[..], &ys[..]);
 }
 
 #[test]
@@ -329,33 +329,33 @@ fn test_iterator_len() {
 #[test]
 fn test_iterator_sum() {
     let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().map(|&x| x).sum(), 6);
-    assert_eq!(v.iter().map(|&x| x).sum(), 55);
-    assert_eq!(v[..0].iter().map(|&x| x).sum(), 0);
+    assert_eq!(v[..4].iter().cloned().sum(), 6);
+    assert_eq!(v.iter().cloned().sum(), 55);
+    assert_eq!(v[..0].iter().cloned().sum(), 0);
 }
 
 #[test]
 fn test_iterator_product() {
     let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().map(|&x| x).product(), 0);
-    assert_eq!(v[1..5].iter().map(|&x| x).product(), 24);
-    assert_eq!(v[..0].iter().map(|&x| x).product(), 1);
+    assert_eq!(v[..4].iter().cloned().product(), 0);
+    assert_eq!(v[1..5].iter().cloned().product(), 24);
+    assert_eq!(v[..0].iter().cloned().product(), 1);
 }
 
 #[test]
 fn test_iterator_max() {
     let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().map(|&x| x).max(), Some(3));
-    assert_eq!(v.iter().map(|&x| x).max(), Some(10));
-    assert_eq!(v[..0].iter().map(|&x| x).max(), None);
+    assert_eq!(v[..4].iter().cloned().max(), Some(3));
+    assert_eq!(v.iter().cloned().max(), Some(10));
+    assert_eq!(v[..0].iter().cloned().max(), None);
 }
 
 #[test]
 fn test_iterator_min() {
     let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().map(|&x| x).min(), Some(0));
-    assert_eq!(v.iter().map(|&x| x).min(), Some(0));
-    assert_eq!(v[..0].iter().map(|&x| x).min(), None);
+    assert_eq!(v[..4].iter().cloned().min(), Some(0));
+    assert_eq!(v.iter().cloned().min(), Some(0));
+    assert_eq!(v[..0].iter().cloned().min(), None);
 }
 
 #[test]
@@ -373,7 +373,7 @@ fn test_iterator_size_hint() {
     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().map(|&i| i)).size_hint(), (uint::MAX, None));
+    assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (uint::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));
@@ -398,7 +398,7 @@ fn test_iterator_size_hint() {
 #[test]
 fn test_collect() {
     let a = vec![1, 2, 3, 4, 5];
-    let b: Vec<int> = a.iter().map(|&x| x).collect();
+    let b: Vec<int> = a.iter().cloned().collect();
     assert!(a == b);
 }
 
@@ -471,7 +471,7 @@ fn test_rev() {
     let mut it = xs.iter();
     it.next();
     it.next();
-    assert!(it.rev().map(|&x| x).collect::<Vec<int>>() ==
+    assert!(it.rev().cloned().collect::<Vec<int>>() ==
             vec![16, 14, 12, 10, 8, 6]);
 }
 
@@ -508,7 +508,7 @@ fn test_double_ended_map() {
 #[test]
 fn test_double_ended_enumerate() {
     let xs = [1, 2, 3, 4, 5, 6];
-    let mut it = xs.iter().map(|&x| x).enumerate();
+    let mut it = xs.iter().cloned().enumerate();
     assert_eq!(it.next(), Some((0, 1)));
     assert_eq!(it.next(), Some((1, 2)));
     assert_eq!(it.next_back(), Some((5, 6)));
@@ -522,8 +522,8 @@ fn test_double_ended_enumerate() {
 fn test_double_ended_zip() {
     let xs = [1, 2, 3, 4, 5, 6];
     let ys = [1, 2, 3, 7];
-    let a = xs.iter().map(|&x| x);
-    let b = ys.iter().map(|&x| x);
+    let a = xs.iter().cloned();
+    let b = ys.iter().cloned();
     let mut it = a.zip(b);
     assert_eq!(it.next(), Some((1, 1)));
     assert_eq!(it.next(), Some((2, 2)));
@@ -713,7 +713,7 @@ fn test_random_access_inspect() {
 fn test_random_access_map() {
     let xs = [1, 2, 3, 4, 5];
 
-    let mut it = xs.iter().map(|x| *x);
+    let mut it = xs.iter().cloned();
     assert_eq!(xs.len(), it.indexable());
     for (i, elt) in xs.iter().enumerate() {
         assert_eq!(Some(*elt), it.idx(i));
index 421ce76caaf46e5ae9a1851555b867ddd093eafa..5aeb330b78b54023ac388d83d22f5eeff636b319 100644 (file)
@@ -92,7 +92,7 @@ fn test_transmute_copy() {
 
 #[test]
 fn test_transmute() {
-    trait Foo {}
+    trait Foo { fn dummy(&self) { } }
     impl Foo for int {}
 
     let a = box 100 as Box<Foo>;
index 9c2e242c105096ab4717e60fe993a68f38018c60..57456bfb1a79ba04ce4b68c77999d37c2b507a90 100644 (file)
@@ -171,8 +171,8 @@ fn test_set_memory() {
 #[test]
 fn test_unsized_unique() {
     let xs: &mut [_] = &mut [1, 2, 3];
-    let ptr = Unique(xs as *mut [_]);
-    let ys = unsafe { &mut *ptr.ptr };
+    let ptr = unsafe { Unique::new(xs as *mut [_]) };
+    let ys = unsafe { &mut **ptr };
     let zs: &mut [_] = &mut [1, 2, 3];
     assert!(ys == zs);
 }
index 6d5cc38ef0a74f98c86d206a97f01fb5589240f2..46c7730cc6470aeb852892cb2f1cf3f31506dcb3 100644 (file)
@@ -43,13 +43,13 @@ macro_rules! test {
 
             {
                 let mut iter = data.iter();
-                assert_eq!(&iter[], &other_data[]);
+                assert_eq!(&iter[..], &other_data[..]);
 
                 iter.next();
-                assert_eq!(&iter[], &other_data[1..]);
+                assert_eq!(&iter[..], &other_data[1..]);
 
                 iter.next_back();
-                assert_eq!(&iter[], &other_data[1..2]);
+                assert_eq!(&iter[..], &other_data[1..2]);
 
                 let s = iter.as_slice();
                 iter.next();
@@ -57,17 +57,17 @@ macro_rules! test {
             }
             {
                 let mut iter = data.iter_mut();
-                assert_eq!(&iter[], &other_data[]);
+                assert_eq!(&iter[..], &other_data[..]);
                 // mutability:
                 assert!(&mut iter[] == other_data);
 
                 iter.next();
-                assert_eq!(&iter[], &other_data[1..]);
+                assert_eq!(&iter[..], &other_data[1..]);
                 assert!(&mut iter[] == &mut other_data[1..]);
 
                 iter.next_back();
 
-                assert_eq!(&iter[], &other_data[1..2]);
+                assert_eq!(&iter[..], &other_data[1..2]);
                 assert!(&mut iter[] == &mut other_data[1..2]);
 
                 let s = iter.into_slice();
index ff6400a11dfe8b3b7c620228240dafe590ebc81d..24660b3f396c105031903ceb43822ff6b690cb66 100644 (file)
@@ -45,13 +45,13 @@ pub struct Bytes {
 impl Deref for Bytes {
     type Target = [u8];
     fn deref(&self) -> &[u8] {
-        unsafe { slice::from_raw_parts_mut(self.ptr.ptr, self.len) }
+        unsafe { slice::from_raw_parts(*self.ptr, self.len) }
     }
 }
 
 impl Drop for Bytes {
     fn drop(&mut self) {
-        unsafe { libc::free(self.ptr.ptr as *mut _); }
+        unsafe { libc::free(*self.ptr as *mut _); }
     }
 }
 
@@ -84,7 +84,7 @@ fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<Bytes> {
                                              &mut outsz,
                                              flags);
         if !res.is_null() {
-            let res = Unique(res as *mut u8);
+            let res = Unique::new(res as *mut u8);
             Some(Bytes { ptr: res, len: outsz as uint })
         } else {
             None
@@ -110,7 +110,7 @@ fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<Bytes> {
                                                &mut outsz,
                                                flags);
         if !res.is_null() {
-            let res = Unique(res as *mut u8);
+            let res = Unique::new(res as *mut u8);
             Some(Bytes { ptr: res, len: outsz as uint })
         } else {
             None
index 1c7e97d784c685b91472669c1502d19ce404a709..be77622ac1db7c52335525cefd8753423177258f 100644 (file)
@@ -215,11 +215,11 @@ fn must_consume(&mut self, c: char) {
             }
             Some((_, other)) => {
                 self.err(&format!("expected `{:?}`, found `{:?}`", c,
-                                  other)[]);
+                                  other));
             }
             None => {
                 self.err(&format!("expected `{:?}` but string was terminated",
-                                  c)[]);
+                                  c));
             }
         }
     }
index c743119f4090911bb5d69e0d7383f82e1efc6fef..fdd7f7395c2b7af5955aa3f52f7cecd52e9cff74 100644 (file)
@@ -287,7 +287,7 @@ pub fn long_to_short(&self) -> Opt {
 
 impl Matches {
     fn opt_vals(&self, nm: &str) -> Vec<Optval> {
-        match find_opt(&self.opts[], Name::from_str(nm)) {
+        match find_opt(&self.opts[..], Name::from_str(nm)) {
             Some(id) => self.vals[id].clone(),
             None => panic!("No option '{}' defined", nm)
         }
@@ -326,7 +326,7 @@ pub fn opts_present(&self, names: &[String]) -> bool {
     /// Returns the string argument supplied to one of several matching options or `None`.
     pub fn opts_str(&self, names: &[String]) -> Option<String> {
         for nm in names {
-            match self.opt_val(&nm[]) {
+            match self.opt_val(&nm[..]) {
                 Some(Val(ref s)) => return Some(s.clone()),
                 _ => ()
             }
@@ -593,7 +593,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
     while i < l {
         let cur = args[i].clone();
         let curlen = cur.len();
-        if !is_arg(&cur[]) {
+        if !is_arg(&cur[..]) {
             free.push(cur);
         } else if cur == "--" {
             let mut j = i + 1;
@@ -667,7 +667,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
                         v.push(Val((i_arg.clone())
                             .unwrap()));
                     } else if name_pos < names.len() || i + 1 == l ||
-                            is_arg(&args[i + 1][]) {
+                            is_arg(&args[i + 1][..]) {
                         let v = &mut vals[optid];
                         v.push(Given);
                     } else {
@@ -730,7 +730,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
             0 => {}
             1 => {
                 row.push('-');
-                row.push_str(&short_name[]);
+                row.push_str(&short_name[..]);
                 row.push(' ');
             }
             _ => panic!("the short name should only be 1 ascii char long"),
@@ -741,7 +741,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
             0 => {}
             _ => {
                 row.push_str("--");
-                row.push_str(&long_name[]);
+                row.push_str(&long_name[..]);
                 row.push(' ');
             }
         }
@@ -749,10 +749,10 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
         // arg
         match hasarg {
             No => {}
-            Yes => row.push_str(&hint[]),
+            Yes => row.push_str(&hint[..]),
             Maybe => {
                 row.push('[');
-                row.push_str(&hint[]);
+                row.push_str(&hint[..]);
                 row.push(']');
             }
         }
@@ -765,7 +765,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
                 row.push(' ');
             }
         } else {
-            row.push_str(&desc_sep[]);
+            row.push_str(&desc_sep[..]);
         }
 
         // Normalize desc to contain words separated by one space character
@@ -777,14 +777,14 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
 
         // FIXME: #5516 should be graphemes not codepoints
         let mut desc_rows = Vec::new();
-        each_split_within(&desc_normalized_whitespace[], 54, |substr| {
+        each_split_within(&desc_normalized_whitespace[..], 54, |substr| {
             desc_rows.push(substr.to_string());
             true
         });
 
         // 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
     });
@@ -803,10 +803,10 @@ fn format_option(opt: &OptGroup) -> String {
     // Use short_name is possible, but fallback to long_name.
     if opt.short_name.len() > 0 {
         line.push('-');
-        line.push_str(&opt.short_name[]);
+        line.push_str(&opt.short_name[..]);
     } else {
         line.push_str("--");
-        line.push_str(&opt.long_name[]);
+        line.push_str(&opt.long_name[..]);
     }
 
     if opt.hasarg != No {
@@ -814,7 +814,7 @@ fn format_option(opt: &OptGroup) -> String {
         if opt.hasarg == Maybe {
             line.push('[');
         }
-        line.push_str(&opt.hint[]);
+        line.push_str(&opt.hint[..]);
         if opt.hasarg == Maybe {
             line.push(']');
         }
@@ -836,7 +836,7 @@ pub fn short_usage(program_name: &str, opts: &[OptGroup]) -> String {
     line.push_str(&opts.iter()
                        .map(format_option)
                        .collect::<Vec<String>>()
-                       .connect(" ")[]);
+                       .connect(" ")[..]);
     line
 }
 
index 230deabee0034eaff12df6802944b6e415464fee..acd52c752e8aa1b29e79505937f332cc2f311dcb 100644 (file)
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 #![feature(int_uint)]
 #![feature(collections)]
-#![feature(core)]
 #![feature(old_io)]
 
 use self::LabelText::*;
 
-use std::borrow::IntoCow;
+use std::borrow::{IntoCow, Cow};
 use std::old_io;
-use std::string::CowString;
-use std::vec::CowVec;
 
 /// The text for a graphviz label on a node or edge.
 pub enum LabelText<'a> {
@@ -291,7 +288,7 @@ pub enum LabelText<'a> {
     ///
     /// Occurrences of backslashes (`\`) are escaped, and thus appear
     /// as backslashes in the rendered label.
-    LabelStr(CowString<'a>),
+    LabelStr(Cow<'a, str>),
 
     /// This kind of label uses the graphviz label escString type:
     /// http://www.graphviz.org/content/attrs#kescString
@@ -303,7 +300,7 @@ pub enum LabelText<'a> {
     /// to break a line (centering the line preceding the `\n`), there
     /// are also the escape sequences `\l` which left-justifies the
     /// preceding line and `\r` which right-justifies it.
-    EscStr(CowString<'a>),
+    EscStr(Cow<'a, str>),
 }
 
 // There is a tension in the design of the labelling API.
@@ -340,7 +337,7 @@ pub enum LabelText<'a> {
 
 /// `Id` is a Graphviz `ID`.
 pub struct Id<'a> {
-    name: CowString<'a>,
+    name: Cow<'a, str>,
 }
 
 impl<'a> Id<'a> {
@@ -358,7 +355,7 @@ impl<'a> Id<'a> {
     ///
     /// Passing an invalid string (containing spaces, brackets,
     /// quotes, ...) will return an empty `Err` value.
-    pub fn new<Name: IntoCow<'a, String, str>>(name: Name) -> Result<Id<'a>, ()> {
+    pub fn new<Name: IntoCow<'a, str>>(name: Name) -> Result<Id<'a>, ()> {
         let name = name.into_cow();
         {
             let mut chars = name.chars();
@@ -387,7 +384,7 @@ pub fn as_slice(&'a self) -> &'a str {
         &*self.name
     }
 
-    pub fn name(self) -> CowString<'a> {
+    pub fn name(self) -> Cow<'a, str> {
         self.name
     }
 }
@@ -427,11 +424,11 @@ fn edge_label(&'a self, e: &E) -> LabelText<'a> {
 }
 
 impl<'a> LabelText<'a> {
-    pub fn label<S:IntoCow<'a, String, str>>(s: S) -> LabelText<'a> {
+    pub fn label<S:IntoCow<'a, str>>(s: S) -> LabelText<'a> {
         LabelStr(s.into_cow())
     }
 
-    pub fn escaped<S:IntoCow<'a, String, str>>(s: S) -> LabelText<'a> {
+    pub fn escaped<S:IntoCow<'a, str>>(s: S) -> LabelText<'a> {
         EscStr(s.into_cow())
     }
 
@@ -455,7 +452,7 @@ fn escape_str(s: &str) -> String {
     pub fn escape(&self) -> String {
         match self {
             &LabelStr(ref s) => s.escape_default(),
-            &EscStr(ref s) => LabelText::escape_str(&s[]),
+            &EscStr(ref s) => LabelText::escape_str(&s[..]),
         }
     }
 
@@ -463,7 +460,7 @@ pub fn escape(&self) -> String {
     /// yields same content as self.  The result obeys the law
     /// render(`lt`) == render(`EscStr(lt.pre_escaped_content())`) for
     /// all `lt: LabelText`.
-    fn pre_escaped_content(self) -> CowString<'a> {
+    fn pre_escaped_content(self) -> Cow<'a, str> {
         match self {
             EscStr(s) => s,
             LabelStr(s) => if s.contains_char('\\') {
@@ -484,13 +481,13 @@ pub fn suffix_line(self, suffix: LabelText) -> LabelText<'static> {
         let mut prefix = self.pre_escaped_content().into_owned();
         let suffix = suffix.pre_escaped_content();
         prefix.push_str(r"\n\n");
-        prefix.push_str(&suffix[]);
+        prefix.push_str(&suffix[..]);
         EscStr(prefix.into_cow())
     }
 }
 
-pub type Nodes<'a,N> = CowVec<'a,N>;
-pub type Edges<'a,E> = CowVec<'a,E>;
+pub type Nodes<'a,N> = Cow<'a,[N]>;
+pub type Edges<'a,E> = Cow<'a,[E]>;
 
 // (The type parameters in GraphWalk should be associated items,
 // when/if Rust supports such.)
@@ -678,7 +675,7 @@ fn id_name<'a>(n: &Node) -> Id<'a> {
 
     impl<'a> Labeller<'a, Node, &'a Edge> for LabelledGraph {
         fn graph_id(&'a self) -> Id<'a> {
-            Id::new(&self.name[]).unwrap()
+            Id::new(&self.name[..]).unwrap()
         }
         fn node_id(&'a self, n: &Node) -> Id<'a> {
             id_name(n)
index 4dab07acfd2a0285626f962f7325440adf07709f..c2c7f20ce9cdfcff7ead7cf1f79caaf23ff2962e 100644 (file)
@@ -287,7 +287,7 @@ 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,
+        Some(filter) if !args.to_string().contains(&filter[..]) => return,
         _ => {}
     }
 
@@ -382,7 +382,7 @@ fn enabled(level: u32,
     // Search for the longest match, the vector is assumed to be pre-sorted.
     for directive in iter.rev() {
         match directive.name {
-            Some(ref name) if !module.starts_with(&name[]) => {},
+            Some(ref name) if !module.starts_with(&name[..]) => {},
             Some(..) | None => {
                 return level <= directive.level
             }
@@ -397,7 +397,7 @@ fn enabled(level: u32,
 /// `Once` primitive (and this function is called from that primitive).
 fn init() {
     let (mut directives, filter) = match env::var("RUST_LOG") {
-        Ok(spec) => directive::parse_logging_spec(&spec[]),
+        Ok(spec) => directive::parse_logging_spec(&spec[..]),
         Err(..) => (Vec::new(), None),
     };
 
index d1d24cea8714e7c1b4fe544c9dfaf363b9903cb7..5a85552dc384eb10536faa8520621827fe5416cd 100644 (file)
@@ -21,6 +21,7 @@
 
 use core::prelude::*;
 use core::num::{Float, Int};
+use core::marker::PhantomData;
 
 use {Rng, Rand};
 
@@ -56,7 +57,13 @@ pub trait IndependentSample<Support>: Sample<Support> {
 
 /// A wrapper for generating types that implement `Rand` via the
 /// `Sample` & `IndependentSample` traits.
-pub struct RandSample<Sup>;
+pub struct RandSample<Sup> { _marker: PhantomData<Sup> }
+
+impl<Sup> RandSample<Sup> {
+    pub fn new() -> RandSample<Sup> {
+        RandSample { _marker: PhantomData }
+    }
+}
 
 impl<Sup: Rand> Sample<Sup> for RandSample<Sup> {
     fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
@@ -285,7 +292,7 @@ fn next_u64(&mut self) -> u64 {
 
     #[test]
     fn test_rand_sample() {
-        let mut rand_sample = RandSample::<ConstRand>;
+        let mut rand_sample = RandSample::<ConstRand>::new();
 
         assert_eq!(rand_sample.sample(&mut ::test::rng()), ConstRand(0));
         assert_eq!(rand_sample.ind_sample(&mut ::test::rng()), ConstRand(0));
index f15523fc010b61118d77eaac322844de6cdb5d6b..701749ff3443f6e0280ad1308001854ea645cfe2 100644 (file)
@@ -215,7 +215,7 @@ 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().map(|&x| x).chain(repeat(0u32));
+        let seed_iter = seed.iter().cloned().chain(repeat(0u32));
 
         for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
             *rsl_elem = seed_elem;
@@ -458,7 +458,7 @@ 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().map(|&x| x).chain(repeat(0u64));
+        let seed_iter = seed.iter().cloned().chain(repeat(0u64));
 
         for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
             *rsl_elem = seed_elem;
index 915c70bbf8ce1d90a6818dc8367ed95c00da4588..7588bf7c5158e7f27114784bbe2d025ec8dbfdbe 100644 (file)
@@ -41,6 +41,7 @@
 #[cfg(test)] #[macro_use] extern crate log;
 
 use core::prelude::*;
+use core::marker::PhantomData;
 
 pub use isaac::{IsaacRng, Isaac64Rng};
 pub use chacha::ChaChaRng;
@@ -206,7 +207,7 @@ fn gen<T: Rand>(&mut self) -> T {
     ///                     .collect::<Vec<(f64, bool)>>());
     /// ```
     fn gen_iter<'a, T: Rand>(&'a mut self) -> Generator<'a, T, Self> {
-        Generator { rng: self }
+        Generator { rng: self, _marker: PhantomData }
     }
 
     /// Generate a random value in the range [`low`, `high`).
@@ -317,6 +318,7 @@ fn shuffle<T>(&mut self, values: &mut [T]) {
 /// This iterator is created via the `gen_iter` method on `Rng`.
 pub struct Generator<'a, T, R:'a> {
     rng: &'a mut R,
+    _marker: PhantomData<T>
 }
 
 impl<'a, T: Rand, R: Rng> Iterator for Generator<'a, T, R> {
index eb51046d7c9a75ad2e918255266a87cf9e69d8cf..dc81e89902bb4c093b42d8c65386c7707777510f 100644 (file)
@@ -37,7 +37,7 @@
 use util::nodemap::{FnvHashMap, NodeSet};
 use lint::{Level, Context, LintPass, LintArray, Lint};
 
-use std::collections::BitvSet;
+use std::collections::BitSet;
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::num::SignedInt;
 use std::{cmp, slice};
@@ -508,7 +508,7 @@ fn check_heap_type<'a, 'tcx>(&self, cx: &Context<'a, 'tcx>,
         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[]);
+            cx.span_lint(BOX_POINTERS, span, &m[..]);
         }
     }
 }
@@ -736,7 +736,7 @@ fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
                     }
                 } else {
                     let attrs = csearch::get_item_attrs(&cx.sess().cstore, did);
-                    warned |= check_must_use(cx, &attrs[], s.span);
+                    warned |= check_must_use(cx, &attrs[..], s.span);
                 }
             }
             _ => {}
@@ -803,7 +803,7 @@ fn to_camel_case(s: &str) -> String {
             } else {
                 format!("{} `{}` should have a camel case name such as `{}`", sort, s, c)
             };
-            cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m[]);
+            cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m[..]);
         }
     }
 }
@@ -950,7 +950,7 @@ fn is_snake_case(ident: ast::Ident) -> bool {
 
         if !is_snake_case(ident) {
             let sc = NonSnakeCase::to_snake_case(&s);
-            if sc != &s[] {
+            if sc != &s[..] {
                 cx.span_lint(NON_SNAKE_CASE, span,
                     &*format!("{} `{}` should have a snake case name such as `{}`",
                             sort, s, sc));
@@ -1033,7 +1033,7 @@ fn check_upper_case(cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
         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[] {
+            if uc != &s[..] {
                 cx.span_lint(NON_UPPER_CASE_GLOBALS, span,
                     &format!("{} `{}` should have an upper case name such as `{}`",
                              sort, s, uc));
@@ -1196,7 +1196,7 @@ fn check_item(&mut self, cx: &Context, item: &ast::Item) {
                                     let m = format!("braces around {} is unnecessary",
                                                     &token::get_ident(*name));
                                     cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
-                                                 &m[]);
+                                                 &m[..]);
                                 },
                                 _ => ()
                             }
@@ -1474,7 +1474,7 @@ 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"),
+                Some(l) => attr::contains_name(&l[..], "hidden"),
             }
         });
         self.doc_hidden_stack.push(doc_hidden);
@@ -1702,7 +1702,7 @@ fn output(cx: &Context, span: Span, stability: &Option<attr::Stability>,
                 _ => format!("use of {} item", label)
             };
 
-            cx.span_lint(lint, span, &msg[]);
+            cx.span_lint(lint, span, &msg[..]);
         }
     }
 }
@@ -1791,7 +1791,7 @@ fn check_fn(&mut self, cx: &Context, fn_kind: visit::FnKind, _: &ast::FnDecl,
         let mut work_queue = vec![cfg.entry];
         let mut reached_exit_without_self_call = false;
         let mut self_call_spans = vec![];
-        let mut visited = BitvSet::new();
+        let mut visited = BitSet::new();
 
         while let Some(idx) = work_queue.pop() {
             let cfg_id = idx.node_id();
index 42a6861f452a66f95d6f0f0c301979165a92264a..068c179d3431fe7c18087fd92dd1dc7a9a475f54 100644 (file)
@@ -125,11 +125,11 @@ pub fn register_pass(&mut self, sess: Option<&Session>,
                 match (sess, from_plugin) {
                     // We load builtin lints first, so a duplicate is a compiler bug.
                     // Use early_error when handling -W help with no crate.
-                    (None, _) => early_error(&msg[]),
-                    (Some(sess), false) => sess.bug(&msg[]),
+                    (None, _) => early_error(&msg[..]),
+                    (Some(sess), false) => sess.bug(&msg[..]),
 
                     // A duplicate name from a plugin is a user error.
-                    (Some(sess), true)  => sess.err(&msg[]),
+                    (Some(sess), true)  => sess.err(&msg[..]),
                 }
             }
 
@@ -150,11 +150,11 @@ pub fn register_group(&mut self, sess: Option<&Session>,
             match (sess, from_plugin) {
                 // We load builtin lints first, so a duplicate is a compiler bug.
                 // Use early_error when handling -W help with no crate.
-                (None, _) => early_error(&msg[]),
-                (Some(sess), false) => sess.bug(&msg[]),
+                (None, _) => early_error(&msg[..]),
+                (Some(sess), false) => sess.bug(&msg[..]),
 
                 // A duplicate name from a plugin is a user error.
-                (Some(sess), true)  => sess.err(&msg[]),
+                (Some(sess), true)  => sess.err(&msg[..]),
             }
         }
     }
@@ -251,8 +251,8 @@ fn find_lint(&self, lint_name: &str, sess: &Session, span: Option<Span>)
                 let warning = format!("lint {} has been renamed to {}",
                                       lint_name, new_name);
                 match span {
-                    Some(span) => sess.span_warn(span, &warning[]),
-                    None => sess.warn(&warning[]),
+                    Some(span) => sess.span_warn(span, &warning[..]),
+                    None => sess.warn(&warning[..]),
                 };
                 Some(lint_id)
             }
@@ -262,13 +262,13 @@ fn find_lint(&self, lint_name: &str, sess: &Session, span: Option<Span>)
 
     pub fn process_command_line(&mut self, sess: &Session) {
         for &(ref lint_name, level) in &sess.opts.lint_opts {
-            match self.find_lint(&lint_name[], sess, None) {
+            match self.find_lint(&lint_name[..], sess, None) {
                 Some(lint_id) => self.set_level(lint_id, (level, CommandLine)),
                 None => {
                     match self.lint_groups.iter().map(|(&x, pair)| (x, pair.0.clone()))
                                                  .collect::<FnvHashMap<&'static str,
                                                                        Vec<LintId>>>()
-                                                 .get(&lint_name[]) {
+                                                 .get(&lint_name[..]) {
                         Some(v) => {
                             v.iter()
                              .map(|lint_id: &LintId|
@@ -411,15 +411,15 @@ pub fn raw_emit_lint(sess: &Session, lint: &'static Lint,
     if level == Forbid { level = Deny; }
 
     match (level, span) {
-        (Warn, Some(sp)) => sess.span_warn(sp, &msg[]),
-        (Warn, None)     => sess.warn(&msg[]),
-        (Deny, Some(sp)) => sess.span_err(sp, &msg[]),
-        (Deny, None)     => sess.err(&msg[]),
+        (Warn, Some(sp)) => sess.span_warn(sp, &msg[..]),
+        (Warn, None)     => sess.warn(&msg[..]),
+        (Deny, Some(sp)) => sess.span_err(sp, &msg[..]),
+        (Deny, None)     => sess.err(&msg[..]),
         _ => sess.bug("impossible level in raw_emit_lint"),
     }
 
     if let Some(note) = note {
-        sess.note(&note[]);
+        sess.note(&note[..]);
     }
 
     if let Some(span) = def {
@@ -503,7 +503,7 @@ fn with_lint_attrs<F>(&mut self,
                     match self.lints.find_lint(&lint_name, &self.tcx.sess, Some(span)) {
                         Some(lint_id) => vec![(lint_id, level, span)],
                         None => {
-                            match self.lints.lint_groups.get(&lint_name[]) {
+                            match self.lints.lint_groups.get(&lint_name[..]) {
                                 Some(&(ref v, _)) => v.iter()
                                                       .map(|lint_id: &LintId|
                                                            (*lint_id, level, span))
@@ -729,7 +729,7 @@ fn visit_id(&mut self, id: ast::NodeId) {
             None => {}
             Some(lints) => {
                 for (lint_id, span, msg) in lints {
-                    self.span_lint(lint_id.lint, span, &msg[])
+                    self.span_lint(lint_id.lint, span, &msg[..])
                 }
             }
         }
index 5dc23d27ee11bb94d6488dc527b4e4f561b771ac..bdcc10ebceca061899bf93a64540a42c37de4253 100644 (file)
@@ -185,12 +185,20 @@ fn eq(&self, other: &LintId) -> bool {
 
 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;
+        ptr.hash(state);
+    }
+}
 
 impl LintId {
     /// Get the `LintId` for a `Lint`.
index 0871c36d892c6cb30ed6135e9fb763e760db58fb..d48a404176ace37d2727925a3fd958ea309f32c4 100644 (file)
@@ -183,7 +183,7 @@ fn extract_crate_info(&self, i: &ast::Item) -> Option<CrateInfo> {
                 let name = match *path_opt {
                     Some((ref path_str, _)) => {
                         let name = path_str.to_string();
-                        validate_crate_name(Some(self.sess), &name[],
+                        validate_crate_name(Some(self.sess), &name[..],
                                             Some(i.span));
                         name
                     }
@@ -321,7 +321,7 @@ fn existing_match(&self, name: &str, hash: Option<&Svh>, kind: PathKind)
             let source = self.sess.cstore.get_used_crate_source(cnum).unwrap();
             if let Some(locs) = self.sess.opts.externs.get(name) {
                 let found = locs.iter().any(|l| {
-                    let l = fs::realpath(&Path::new(&l[])).ok();
+                    let l = fs::realpath(&Path::new(&l[..])).ok();
                     source.dylib.as_ref().map(|p| &p.0) == l.as_ref() ||
                     source.rlib.as_ref().map(|p| &p.0) == l.as_ref()
                 });
@@ -459,8 +459,8 @@ fn read_extension_crate(&mut self, span: Span, info: &CrateInfo) -> ExtensionCra
         let mut load_ctxt = loader::Context {
             sess: self.sess,
             span: span,
-            ident: &ident[],
-            crate_name: &name[],
+            ident: &ident[..],
+            crate_name: &name[..],
             hash: None,
             filesearch: self.sess.host_filesearch(PathKind::Crate),
             target: &self.sess.host,
@@ -562,7 +562,7 @@ pub fn find_plugin_registrar(&mut self, span: Span, name: &str) -> Option<(Path,
                                   name,
                                   config::host_triple(),
                                   self.sess.opts.target_triple);
-            self.sess.span_err(span, &message[]);
+            self.sess.span_err(span, &message[..]);
             self.sess.abort_if_errors();
         }
 
@@ -575,7 +575,7 @@ pub fn find_plugin_registrar(&mut self, span: Span, name: &str) -> Option<(Path,
                 let message = format!("plugin `{}` only found in rlib format, \
                                        but must be available in dylib format",
                                        name);
-                self.sess.span_err(span, &message[]);
+                self.sess.span_err(span, &message[..]);
                 // No need to abort because the loading code will just ignore this
                 // empty dylib.
                 None
index 0a3e173b35ee517cde4025249d01381356729d71..a3f7d57da67486b39a976a8289743612960ef5b4 100644 (file)
@@ -139,8 +139,7 @@ pub fn add_used_crate_source(&self, src: CrateSource) {
     pub fn get_used_crate_source(&self, cnum: ast::CrateNum)
                                      -> Option<CrateSource> {
         self.used_crate_sources.borrow_mut()
-            .iter().find(|source| source.cnum == cnum)
-            .map(|source| source.clone())
+            .iter().find(|source| source.cnum == cnum).cloned()
     }
 
     pub fn reset(&self) {
@@ -218,7 +217,7 @@ pub fn add_extern_mod_stmt_cnum(&self,
 
     pub fn find_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId)
                                      -> Option<ast::CrateNum> {
-        self.extern_mod_crate_map.borrow().get(&emod_id).map(|x| *x)
+        self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
     }
 }
 
index 3123fa31abdd1ed18a2dd5b360db452a49d0047c..42a70cec5dfee08903c604b672a124e0e4aef4da 100644 (file)
@@ -163,7 +163,7 @@ fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) {
     rbml_w.end_tag();
 
     rbml_w.start_tag(tag_mod_child);
-    rbml_w.wr_str(&s[]);
+    rbml_w.wr_str(&s[..]);
     rbml_w.end_tag();
 }
 
@@ -353,9 +353,9 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
                 let fields = ty::lookup_struct_fields(ecx.tcx, def_id);
                 let idx = encode_info_for_struct(ecx,
                                                  rbml_w,
-                                                 &fields[],
+                                                 &fields[..],
                                                  index);
-                encode_struct_fields(rbml_w, &fields[], def_id);
+                encode_struct_fields(rbml_w, &fields[..], def_id);
                 encode_index(rbml_w, idx, write_i64);
             }
         }
@@ -1158,7 +1158,7 @@ fn add_to_index(item: &ast::Item, rbml_w: &Encoder,
            class itself */
         let idx = encode_info_for_struct(ecx,
                                          rbml_w,
-                                         &fields[],
+                                         &fields[..],
                                          index);
 
         /* Index the class*/
@@ -1181,7 +1181,7 @@ fn add_to_index(item: &ast::Item, rbml_w: &Encoder,
         /* Encode def_ids for each field and method
          for methods, write all the stuff get_trait_method
         needs to know*/
-        encode_struct_fields(rbml_w, &fields[], def_id);
+        encode_struct_fields(rbml_w, &fields[..], def_id);
 
         encode_inlined_item(ecx, rbml_w, IIItemRef(item));
 
@@ -1588,6 +1588,7 @@ 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>,
@@ -1628,6 +1629,47 @@ fn encode_index<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, mut write_fn:
     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),
+    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;
+        (&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();
+}
 
 fn write_i64(writer: &mut SeekableMemWriter, &n: &i64) {
     let wr: &mut SeekableMemWriter = writer;
index 3158ccd076522f76dc9eec476b9122bc09bbadd4..01d1f4e7011f8586c7196884fc851e35ee039d1c 100644 (file)
@@ -322,7 +322,7 @@ pub fn report_load_errs(&mut self) {
             &Some(ref r) => format!("{} which `{}` depends on",
                                     message, r.ident)
         };
-        self.sess.span_err(self.span, &message[]);
+        self.sess.span_err(self.span, &message[..]);
 
         if self.rejected_via_triple.len() > 0 {
             let mismatches = self.rejected_via_triple.iter();
@@ -404,7 +404,7 @@ fn find_library_crate(&mut self) -> Option<Library> {
                 None => return FileDoesntMatch,
                 Some(file) => file,
             };
-            let (hash, rlib) = if file.starts_with(&rlib_prefix[]) &&
+            let (hash, rlib) = if file.starts_with(&rlib_prefix[..]) &&
                                   file.ends_with(".rlib") {
                 (&file[(rlib_prefix.len()) .. (file.len() - ".rlib".len())],
                  true)
@@ -413,7 +413,7 @@ fn find_library_crate(&mut self) -> Option<Library> {
                 (&file[(dylib_prefix.len()) .. (file.len() - dypair.1.len())],
                  false)
             } else {
-                if file.starts_with(&staticlib_prefix[]) &&
+                if file.starts_with(&staticlib_prefix[..]) &&
                    file.ends_with(".a") {
                     staticlibs.push(CrateMismatch {
                         path: path.clone(),
@@ -627,7 +627,7 @@ fn find_commandline_library(&mut self, locs: &[String]) -> Option<Library> {
         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| Path::new(&l[..])).filter(|loc| {
                 if !loc.exists() {
                     sess.err(&format!("extern location for {} does not exist: {}",
                                      self.crate_name, loc.display())[]);
@@ -645,8 +645,8 @@ fn find_commandline_library(&mut self, locs: &[String]) -> Option<Library> {
                     return true
                 } else {
                     let (ref prefix, ref suffix) = dylibname;
-                    if file.starts_with(&prefix[]) &&
-                       file.ends_with(&suffix[]) {
+                    if file.starts_with(&prefix[..]) &&
+                       file.ends_with(&suffix[..]) {
                         return true
                     }
                 }
@@ -744,7 +744,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
         }
     }
     unsafe {
-        let buf = CString::from_slice(filename.as_vec());
+        let buf = CString::new(filename.as_vec()).unwrap();
         let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
         if mb as int == 0 {
             return Err(format!("error reading library: '{}'",
index 94654b849229a3a058b3b42d78b03392e31c7c65..5805725a8fc8b7cb6ad2f37651f437f33278182b 100644 (file)
@@ -641,7 +641,7 @@ fn parse_abi_set(st: &mut PState) -> abi::Abi {
     assert_eq!(next(st), '[');
     scan(st, |c| c == ']', |bytes| {
         let abi_str = str::from_utf8(bytes).unwrap();
-        abi::lookup(&abi_str[]).expect(abi_str)
+        abi::lookup(&abi_str[..]).expect(abi_str)
     })
 }
 
index c3302debdfaff0e545e9aea32bc210159b75ea0e..ae10eb686b010244ed71bcdf07de52c2d93616e6 100644 (file)
@@ -134,7 +134,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
             // Do an Option dance to use the path after it is moved below.
             let s = ast_map::path_to_string(path.iter().cloned());
             path_as_str = Some(s);
-            path_as_str.as_ref().map(|x| &x[])
+            path_as_str.as_ref().map(|x| &x[..])
         });
         let mut ast_dsr = reader::Decoder::new(ast_doc);
         let from_id_range = Decodable::decode(&mut ast_dsr).unwrap();
index 1f0fe4f1acaeaa37669e606b0fac7a17f1eabfff..46b4a51c9d6fee7b00295727dbd71d600698cf47 100644 (file)
@@ -92,7 +92,7 @@ fn edge_label(&self, e: &Edge<'a>) -> dot::LabelText<'a> {
             let s = replace_newline_with_backslash_l(s);
             label.push_str(&format!("exiting scope_{} {}",
                                    i,
-                                   &s[])[]);
+                                   &s[..])[]);
         }
         dot::LabelText::EscStr(label.into_cow())
     }
index 03456f8529028a36a8527a3f00cc3a5e8e99548a..86c59b24e3e933663ed2100f3d5ede07fe3dc82a 100644 (file)
@@ -25,7 +25,7 @@
 use middle::ty;
 use std::cmp::Ordering;
 use std::fmt;
-use std::iter::{range_inclusive, AdditiveIterator, FromIterator, repeat};
+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};
@@ -76,7 +76,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             pretty_printed_matrix.iter().map(|row| row[col].len()).max().unwrap_or(0)
         }).collect();
 
-        let total_width = column_widths.iter().map(|n| *n).sum() + column_count * 3 + 1;
+        let total_width = column_widths.iter().cloned().sum() + column_count * 3 + 1;
         let br = repeat('+').take(total_width).collect::<String>();
         try!(write!(f, "{}\n", br));
         for row in pretty_printed_matrix {
@@ -94,8 +94,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 impl<'a> FromIterator<Vec<&'a Pat>> for Matrix<'a> {
-    fn from_iter<T: Iterator<Item=Vec<&'a Pat>>>(iterator: T) -> Matrix<'a> {
-        Matrix(iterator.collect())
+    fn from_iter<T: IntoIterator<Item=Vec<&'a Pat>>>(iter: T) -> Matrix<'a> {
+        Matrix(iter.into_iter().collect())
     }
 }
 
@@ -200,7 +200,7 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
             }
 
             // Fourth, check for unreachable arms.
-            check_arms(cx, &inlined_arms[], source);
+            check_arms(cx, &inlined_arms[..], source);
 
             // Finally, check if the whole match expression is exhaustive.
             // Check for empty enum, because is_useful only works on inhabited types.
@@ -291,7 +291,7 @@ fn check_arms(cx: &MatchCheckCtxt,
         for pat in pats {
             let v = vec![&**pat];
 
-            match is_useful(cx, &seen, &v[], LeaveOutWitness) {
+            match is_useful(cx, &seen, &v[..], LeaveOutWitness) {
                 NotUseful => {
                     match source {
                         ast::MatchSource::IfLetDesugar { .. } => {
@@ -351,7 +351,7 @@ fn raw_pat<'a>(p: &'a Pat) -> &'a Pat {
 fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: ast::MatchSource) {
     match is_useful(cx, matrix, &[DUMMY_WILD_PAT], ConstructWitness) {
         UsefulWithWitness(pats) => {
-            let witness = match &pats[] {
+            let witness = match &pats[..] {
                 [ref witness] => &**witness,
                 [] => DUMMY_WILD_PAT,
                 _ => unreachable!()
@@ -360,7 +360,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: ast:
                 ast::MatchSource::ForLoopDesugar => {
                     // `witness` has the form `Some(<head>)`, peel off the `Some`
                     let witness = match witness.node {
-                        ast::PatEnum(_, Some(ref pats)) => match &pats[] {
+                        ast::PatEnum(_, Some(ref pats)) => match &pats[..] {
                             [ref pat] => &**pat,
                             _ => unreachable!(),
                         },
@@ -664,7 +664,7 @@ fn is_useful(cx: &MatchCheckCtxt,
                         UsefulWithWitness(pats) => UsefulWithWitness({
                             let arity = constructor_arity(cx, &c, left_ty);
                             let mut result = {
-                                let pat_slice = &pats[];
+                                let pat_slice = &pats[..];
                                 let subpats: Vec<_> = (0..arity).map(|i| {
                                     pat_slice.get(i).map_or(DUMMY_WILD_PAT, |p| &**p)
                                 }).collect();
@@ -711,10 +711,10 @@ fn is_useful_specialized(cx: &MatchCheckCtxt, &Matrix(ref m): &Matrix,
                          witness: WitnessPreference) -> Usefulness {
     let arity = constructor_arity(cx, &ctor, lty);
     let matrix = Matrix(m.iter().filter_map(|r| {
-        specialize(cx, &r[], &ctor, 0, arity)
+        specialize(cx, &r[..], &ctor, 0, arity)
     }).collect());
     match specialize(cx, v, &ctor, 0, arity) {
-        Some(v) => is_useful(cx, &matrix, &v[], witness),
+        Some(v) => is_useful(cx, &matrix, &v[..], witness),
         None => NotUseful
     }
 }
index 3d03cd946c48fadf517ca238ab75d540e63dd313..5bf7422dbc0d41ce7051d5a801238c4d4a28b12f 100644 (file)
@@ -62,7 +62,7 @@ fn variant_expr<'a>(variants: &'a [P<ast::Variant>], id: ast::NodeId)
             None => None,
             Some(ast_map::NodeItem(it)) => match it.node {
                 ast::ItemEnum(ast::EnumDef { ref variants }, _) => {
-                    variant_expr(&variants[], variant_def.node)
+                    variant_expr(&variants[..], variant_def.node)
                 }
                 _ => None
             },
@@ -83,7 +83,7 @@ fn variant_expr<'a>(variants: &'a [P<ast::Variant>], id: ast::NodeId)
                     // NOTE this doesn't do the right thing, it compares inlined
                     // NodeId's to the original variant_def's NodeId, but they
                     // come from different crates, so they will likely never match.
-                    variant_expr(&variants[], variant_def.node).map(|e| e.id)
+                    variant_expr(&variants[..], variant_def.node).map(|e| e.id)
                 }
                 _ => None
             },
@@ -209,7 +209,7 @@ 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(e.span, &s[..])
     }
 }
 
@@ -501,7 +501,7 @@ fn lit_to_const(lit: &ast::Lit, ty_hint: Option<Ty>) -> const_val {
     match lit.node {
         ast::LitStr(ref s, _) => const_str((*s).clone()),
         ast::LitBinary(ref data) => {
-            const_binary(Rc::new(data.iter().map(|x| *x).collect()))
+            const_binary(data.clone())
         }
         ast::LitByte(n) => const_uint(n as u64),
         ast::LitChar(n) => const_uint(n as u64),
@@ -552,14 +552,14 @@ pub fn compare_lit_exprs<'tcx>(tcx: &ty::ctxt<'tcx>,
     let a = match eval_const_expr_partial(tcx, a, ty_hint) {
         Ok(a) => a,
         Err(s) => {
-            tcx.sess.span_err(a.span, &s[]);
+            tcx.sess.span_err(a.span, &s[..]);
             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[]);
+            tcx.sess.span_err(b.span, &s[..]);
             return None;
         }
     };
index b792a44d4d89aad86e57da055cdd5ea1c81fe3d8..085d5cbc347e5b015801586b7756c1f2acce7b67 100644 (file)
@@ -89,7 +89,7 @@ struct PropagationContext<'a, 'b: 'a, 'tcx: 'b, O: 'a> {
 }
 
 fn to_cfgidx_or_die(id: ast::NodeId, index: &NodeMap<CFGIndex>) -> CFGIndex {
-    let opt_cfgindex = index.get(&id).map(|&i|i);
+    let opt_cfgindex = index.get(&id).cloned();
     opt_cfgindex.unwrap_or_else(|| {
         panic!("nodeid_to_index does not have entry for NodeId {}", id);
     })
@@ -312,7 +312,7 @@ pub fn each_bit_for_node<F>(&self, e: EntryOrExit, cfgidx: CFGIndex, f: F) -> bo
                 let mut t = on_entry.to_vec();
                 self.apply_gen_kill(cfgidx, &mut t);
                 temp_bits = t;
-                &temp_bits[]
+                &temp_bits[..]
             }
         };
         debug!("{} each_bit_for_node({:?}, cfgidx={:?}) bits={}",
@@ -400,7 +400,7 @@ pub fn add_kills_from_flow_exits(&mut self, cfg: &cfg::CFG) {
 
             let mut changed = false;
             for &node_id in &edge.data.exiting_scopes {
-                let opt_cfg_idx = self.nodeid_to_index.get(&node_id).map(|&i|i);
+                let opt_cfg_idx = self.nodeid_to_index.get(&node_id).cloned();
                 match opt_cfg_idx {
                     Some(cfg_idx) => {
                         let (start, end) = self.compute_id_range(cfg_idx);
@@ -421,7 +421,7 @@ pub fn add_kills_from_flow_exits(&mut self, cfg: &cfg::CFG) {
                 let bits = &mut self.kills[start.. end];
                 debug!("{} add_kills_from_flow_exits flow_exit={:?} bits={} [before]",
                        self.analysis_name, flow_exit, mut_bits_to_string(bits));
-                bits.clone_from_slice(&orig_kills[]);
+                bits.clone_from_slice(&orig_kills[..]);
                 debug!("{} add_kills_from_flow_exits flow_exit={:?} bits={} [after]",
                        self.analysis_name, flow_exit, mut_bits_to_string(bits));
             }
index b2335f91ad9869641801490e62637710aee4fa86..ff78deb8d12ea6ba945531b6c34f0762b38a2ee6 100644 (file)
@@ -321,7 +321,7 @@ fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool {
     for attr in lint::gather_attrs(attrs) {
         match attr {
             Ok((ref name, lint::Allow, _))
-                if &name[] == dead_code => return true,
+                if &name[..] == dead_code => return true,
             _ => (),
         }
     }
index 6d35a82d153cd6c5151e9fedd428c0ae963364e6..ad9f4eade5c90d25538240080640f300aace049a 100644 (file)
@@ -158,7 +158,7 @@ fn calculate_type(sess: &session::Session,
 
     // Collect what we've got so far in the return vector.
     let mut ret = (1..sess.cstore.next_crate_num()).map(|i| {
-        match formats.get(&i).map(|v| *v) {
+        match formats.get(&i).cloned() {
             v @ Some(cstore::RequireDynamic) => v,
             _ => None,
         }
index 8dbac7f515ea8fc23412fda8f8c49192efceaecf..e99d214742a0b668b40becf51bccafc8c387022b 100644 (file)
@@ -29,7 +29,6 @@
 use middle::ty::{MethodStatic, MethodStaticClosure};
 use util::ppaux::Repr;
 
-use std::marker;
 use syntax::{ast, ast_util};
 use syntax::ptr::P;
 use syntax::codemap::Span;
@@ -128,16 +127,14 @@ pub enum MatchMode {
     MovingMatch,
 }
 
-#[derive(PartialEq,Debug)]
-enum TrackMatchMode<T> {
+#[derive(Copy, PartialEq, Debug)]
+enum TrackMatchMode {
     Unknown,
     Definite(MatchMode),
     Conflicting,
 }
 
-impl<T> marker::Copy for TrackMatchMode<T> {}
-
-impl<T> TrackMatchMode<T> {
+impl TrackMatchMode {
     // Builds up the whole match mode for a pattern from its constituent
     // parts.  The lattice looks like this:
     //
@@ -931,7 +928,7 @@ fn walk_overloaded_operator(&mut self,
         return true;
     }
 
-    fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &ast::Arm) -> TrackMatchMode<Span> {
+    fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &ast::Arm) -> TrackMatchMode {
         let mut mode = Unknown;
         for pat in &arm.pats {
             self.determine_pat_move_mode(discr_cmt.clone(), &**pat, &mut mode);
@@ -966,7 +963,7 @@ fn walk_irrefutable_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &ast::Pat) {
     fn determine_pat_move_mode(&mut self,
                                cmt_discr: mc::cmt<'tcx>,
                                pat: &ast::Pat,
-                               mode: &mut TrackMatchMode<Span>) {
+                               mode: &mut TrackMatchMode) {
         debug!("determine_pat_move_mode cmt_discr={} pat={}", cmt_discr.repr(self.tcx()),
                pat.repr(self.tcx()));
         return_if_err!(self.mc.cat_pattern(cmt_discr, pat, |_mc, cmt_pat, pat| {
@@ -1166,7 +1163,7 @@ fn walk_pat(&mut self,
                                 let msg = format!("Pattern has unexpected def: {:?} and type {}",
                                                   def,
                                                   cmt_pat.ty.repr(tcx));
-                                tcx.sess.span_bug(pat.span, &msg[])
+                                tcx.sess.span_bug(pat.span, &msg[..])
                             }
                         }
                     }
index 4dd7a4a226629bf4b338bcfdb1abc6ce6e613ff1..436f04fc9e9cf9744f7d484757c9022146e47883 100644 (file)
@@ -34,7 +34,7 @@
 
 use std::fmt::{Formatter, Error, Debug};
 use std::usize;
-use std::collections::BitvSet;
+use std::collections::BitSet;
 
 pub struct Graph<N,E> {
     nodes: Vec<Node<N>> ,
@@ -292,7 +292,7 @@ pub fn depth_traverse<'a>(&'a self, start: NodeIndex) -> DepthFirstTraversal<'a,
         DepthFirstTraversal {
             graph: self,
             stack: vec![start],
-            visited: BitvSet::new()
+            visited: BitSet::new()
         }
     }
 }
@@ -300,7 +300,7 @@ pub fn depth_traverse<'a>(&'a self, start: NodeIndex) -> DepthFirstTraversal<'a,
 pub struct DepthFirstTraversal<'g, N:'g, E:'g> {
     graph: &'g Graph<N, E>,
     stack: Vec<NodeIndex>,
-    visited: BitvSet
+    visited: BitSet
 }
 
 impl<'g, N, E> Iterator for DepthFirstTraversal<'g, N, E> {
diff --git a/src/librustc/middle/infer/bivariate.rs b/src/librustc/middle/infer/bivariate.rs
new file mode 100644 (file)
index 0000000..93c80fb
--- /dev/null
@@ -0,0 +1,145 @@
+// 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.
+
+//! Applies the "bivariance relationship" to two types and/or regions.
+//! If (A,B) are bivariant then either A <: B or B <: A. It occurs
+//! when type/lifetime parameters are unconstrained. Usually this is
+//! an error, but we permit it in the specific case where a type
+//! parameter is constrained in a where-clause via an associated type.
+//!
+//! There are several ways one could implement bivariance. You could
+//! just do nothing at all, for example, or you could fully verify
+//! that one of the two subtyping relationships hold. We choose to
+//! thread a middle line: we relate types up to regions, but ignore
+//! all region relationships.
+//!
+//! At one point, handling bivariance in this fashion was necessary
+//! for inference, but I'm actually not sure if that is true anymore.
+//! In particular, it might be enough to say (A,B) are bivariant for
+//! all (A,B).
+
+use middle::ty::{BuiltinBounds};
+use middle::ty::{self, Ty};
+use middle::ty::TyVar;
+use middle::infer::combine::*;
+use middle::infer::{cres};
+use middle::infer::type_variable::{BiTo};
+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 }
+}
+
+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)
+    }
+
+    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));
+
+        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 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 builtin_bounds(&self,
+                      a: BuiltinBounds,
+                      b: BuiltinBounds)
+                      -> cres<'tcx, BuiltinBounds>
+    {
+        if a != b {
+            Err(ty::terr_builtin_bounds(expected_found(self, a, b)))
+        } else {
+            Ok(a)
+        }
+    }
+
+    fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'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); }
+
+        let infcx = self.fields.infcx;
+        let a = infcx.type_variables.borrow().replace_if_possible(a);
+        let b = infcx.type_variables.borrow().replace_if_possible(b);
+        match (&a.sty, &b.sty) {
+            (&ty::ty_infer(TyVar(a_id)), &ty::ty_infer(TyVar(b_id))) => {
+                infcx.type_variables.borrow_mut().relate_vars(a_id, BiTo, b_id);
+                Ok(a)
+            }
+
+            (&ty::ty_infer(TyVar(a_id)), _) => {
+                try!(self.fields.instantiate(b, BiTo, a_id));
+                Ok(a)
+            }
+
+            (_, &ty::ty_infer(TyVar(b_id))) => {
+                try!(self.fields.instantiate(a, BiTo, b_id));
+                Ok(a)
+            }
+
+            _ => {
+                super_tys(self, a, b)
+            }
+        }
+    }
+
+    fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
+        where T : Combineable<'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));
+        Ok(ty::Binder(c))
+    }
+}
index daa820f43b57ec186aa67ae79ae2d5d587a14214..0eeafb767d8a625d2792a3c393f4888aec8cf68c 100644 (file)
@@ -32,6 +32,7 @@
 // is also useful to track which value is the "expected" value in
 // terms of error reporting.
 
+use super::bivariate::Bivariate;
 use super::equate::Equate;
 use super::glb::Glb;
 use super::lub::Lub;
@@ -39,7 +40,7 @@
 use super::unify::InferCtxtMethodsForSimplyUnifiableTypes;
 use super::{InferCtxt, cres};
 use super::{MiscVariable, TypeTrace};
-use super::type_variable::{RelationDir, EqTo, SubtypeOf, SupertypeOf};
+use super::type_variable::{RelationDir, BiTo, EqTo, SubtypeOf, SupertypeOf};
 
 use middle::subst;
 use middle::subst::{ErasedRegions, NonerasedRegions, Substs};
@@ -48,7 +49,7 @@
 use middle::ty::{BuiltinBounds};
 use middle::ty::{self, Ty};
 use middle::ty_fold;
-use middle::ty_fold::{TypeFoldable};
+use middle::ty_fold::{TypeFolder, TypeFoldable};
 use util::ppaux::Repr;
 
 use std::rc::Rc;
 use syntax::codemap::Span;
 
 pub trait Combine<'tcx> : Sized {
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx>;
     fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.infcx().tcx }
     fn tag(&self) -> String;
-    fn a_is_expected(&self) -> bool;
-    fn trace(&self) -> TypeTrace<'tcx>;
 
-    fn equate<'a>(&'a self) -> Equate<'a, 'tcx>;
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx>;
-    fn lub<'a>(&'a self) -> Lub<'a, 'tcx>;
-    fn glb<'a>(&'a self) -> Glb<'a, 'tcx>;
+    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 contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'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 tps(&self,
-           _: subst::ParamSpace,
-           as_: &[Ty<'tcx>],
-           bs: &[Ty<'tcx>])
-           -> cres<'tcx, Vec<Ty<'tcx>>> {
-        // FIXME -- In general, we treat variance a bit wrong
-        // here. For historical reasons, we treat tps and Self
-        // as invariant. This is overly conservative.
-
-        if as_.len() != bs.len() {
-            return Err(ty::terr_ty_param_size(expected_found(self,
-                                                             as_.len(),
-                                                             bs.len())));
-        }
+    fn regions_with_variance(&self, variance: ty::Variance, a: ty::Region, b: ty::Region)
+                             -> cres<'tcx, ty::Region>;
 
-        try!(as_.iter().zip(bs.iter())
-                .map(|(a, b)| self.equate().tys(*a, *b))
-                .collect::<cres<Vec<Ty>>>());
-        Ok(as_.to_vec())
-    }
+    fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region>;
 
     fn substs(&self,
               item_def_id: ast::DefId,
@@ -100,6 +92,11 @@ fn substs(&self,
               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 {
@@ -119,7 +116,8 @@ fn substs_variances(&self,
         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 tps = try!(self.tps(space, a_tps, b_tps));
+            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);
         }
 
@@ -132,20 +130,7 @@ fn substs_variances(&self,
                 for &space in &subst::ParamSpace::all() {
                     let a_regions = a.get_slice(space);
                     let b_regions = b.get_slice(space);
-
-                    let mut invariance = Vec::new();
-                    let r_variances = match variances {
-                        Some(variances) => {
-                            variances.regions.get_slice(space)
-                        }
-                        None => {
-                            for _ in a_regions {
-                                invariance.push(ty::Invariant);
-                            }
-                            &invariance[]
-                        }
-                    };
-
+                    let r_variances = variances.map(|v| v.regions.get_slice(space));
                     let regions = try!(relate_region_params(self,
                                                             r_variances,
                                                             a_regions,
@@ -157,13 +142,34 @@ fn substs_variances(&self,
 
         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: &[ty::Variance],
+                                                        variances: Option<&[ty::Variance]>,
                                                         a_rs: &[ty::Region],
                                                         b_rs: &[ty::Region])
-                                                        -> cres<'tcx, Vec<ty::Region>> {
+                                                        -> cres<'tcx, Vec<ty::Region>>
+        {
             let tcx = this.infcx().tcx;
-            let num_region_params = variances.len();
+            let num_region_params = a_rs.len();
 
             debug!("relate_region_params(\
                    a_rs={}, \
@@ -173,22 +179,18 @@ fn relate_region_params<'tcx, C: Combine<'tcx>>(this: &C,
                    b_rs.repr(tcx),
                    variances.repr(tcx));
 
-            assert_eq!(num_region_params, a_rs.len());
+            assert_eq!(num_region_params,
+                       variances.map_or(num_region_params,
+                                        |v| v.len()));
+
             assert_eq!(num_region_params, b_rs.len());
-            let mut rs = vec!();
-            for i in 0..num_region_params {
+
+            (0..a_rs.len()).map(|i| {
                 let a_r = a_rs[i];
                 let b_r = b_rs[i];
-                let variance = variances[i];
-                let r = match variance {
-                    ty::Invariant => this.equate().regions(a_r, b_r),
-                    ty::Covariant => this.regions(a_r, b_r),
-                    ty::Contravariant => this.contraregions(a_r, b_r),
-                    ty::Bivariant => Ok(a_r),
-                };
-                rs.push(try!(r));
-            }
-            Ok(rs)
+                let variance = variances.map_or(ty::Invariant, |v| v[i]);
+                this.regions_with_variance(variance, a_r, b_r)
+            }).collect()
         }
     }
 
@@ -241,7 +243,7 @@ fn argvecs<'tcx, C: Combine<'tcx>>(combiner: &C,
     }
 
     fn args(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        self.contratys(a, b).and_then(|t| Ok(t))
+        self.tys_with_variance(ty::Contravariant, a, b).and_then(|t| Ok(t))
     }
 
     fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety>;
@@ -309,7 +311,7 @@ fn existential_bounds(&self,
                           b: &ty::ExistentialBounds<'tcx>)
                           -> cres<'tcx, ty::ExistentialBounds<'tcx>>
     {
-        let r = try!(self.contraregions(a.region_bound, b.region_bound));
+        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,
@@ -322,11 +324,6 @@ fn builtin_bounds(&self,
                       b: ty::BuiltinBounds)
                       -> cres<'tcx, ty::BuiltinBounds>;
 
-    fn contraregions(&self, a: ty::Region, b: ty::Region)
-                  -> cres<'tcx, ty::Region>;
-
-    fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region>;
-
     fn trait_refs(&self,
                   a: &ty::TraitRef<'tcx>,
                   b: &ty::TraitRef<'tcx>)
@@ -540,7 +537,8 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
       }
 
       (&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => {
-            let r = try!(this.contraregions(*a_r, *b_r));
+            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
@@ -644,6 +642,10 @@ fn equate(&self) -> Equate<'f, 'tcx> {
         Equate((*self).clone())
     }
 
+    fn bivariate(&self) -> Bivariate<'f, 'tcx> {
+        Bivariate((*self).clone())
+    }
+
     fn sub(&self) -> Sub<'f, 'tcx> {
         Sub((*self).clone())
     }
@@ -697,7 +699,7 @@ pub fn instantiate(&self,
                         EqTo => {
                             self.generalize(a_ty, b_vid, false)
                         }
-                        SupertypeOf | SubtypeOf => {
+                        BiTo | SupertypeOf | SubtypeOf => {
                             self.generalize(a_ty, b_vid, true)
                         }
                     });
@@ -721,6 +723,10 @@ pub fn instantiate(&self,
             // 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));
                 }
@@ -730,7 +736,7 @@ pub fn instantiate(&self,
                 }
 
                 SupertypeOf => {
-                    try!(self.sub().contratys(a_ty, b_ty));
+                    try!(self.sub().tys_with_variance(ty::Contravariant, a_ty, b_ty));
                 }
             }
         }
index f0bde22286488c3fb6272dac63018e0b4fb7c1e1..7194e20b0cf655224c08530e4f569c158d197cab 100644 (file)
 use middle::ty::TyVar;
 use middle::infer::combine::*;
 use middle::infer::{cres};
-use middle::infer::glb::Glb;
-use middle::infer::InferCtxt;
-use middle::infer::lub::Lub;
-use middle::infer::sub::Sub;
-use middle::infer::{TypeTrace, Subtype};
+use middle::infer::{Subtype};
 use middle::infer::type_variable::{EqTo};
 use util::ppaux::{Repr};
 
@@ -33,21 +29,20 @@ pub fn Equate<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Equate<'f, 'tcx> {
 }
 
 impl<'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> {
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx }
-    fn tag(&self) -> String { "eq".to_string() }
-    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
-    fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() }
+    fn tag(&self) -> String { "Equate".to_string() }
+    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
 
-    fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) }
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) }
-    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 contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
+    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 contraregions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> {
+    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)
     }
 
index 72b33613c66aab63e81c562e53237821decd3058..53032f9b9ac64ac512d673d0faece23d2bee32a9 100644 (file)
@@ -200,9 +200,9 @@ fn report_region_errors(&self,
                                 ref trace_origins,
                                 ref same_regions) => {
                     if !same_regions.is_empty() {
-                        self.report_processed_errors(&var_origins[],
-                                                     &trace_origins[],
-                                                     &same_regions[]);
+                        self.report_processed_errors(&var_origins[..],
+                                                     &trace_origins[..],
+                                                     &same_regions[..]);
                     }
                 }
             }
@@ -675,6 +675,17 @@ fn report_concrete_failure(&self,
                     sup,
                     "");
             }
+            infer::Operand(span) => {
+                self.tcx.sess.span_err(
+                    span,
+                    "lifetime of operand does not outlive \
+                     the operation");
+                note_and_explain_region(
+                    self.tcx,
+                    "the operand is only valid for ",
+                    sup,
+                    "");
+            }
             infer::AddrOf(span) => {
                 self.tcx.sess.span_err(
                     span,
@@ -824,7 +835,7 @@ fn give_suggestion(&self, same_regions: &[SameRegions]) {
         let parent = self.tcx.map.get_parent(scope_id);
         let parent_node = self.tcx.map.find(parent);
         let taken = lifetimes_in_scope(self.tcx, scope_id);
-        let life_giver = LifeGiver::with_taken(&taken[]);
+        let life_giver = LifeGiver::with_taken(&taken[..]);
         let node_inner = match parent_node {
             Some(ref node) => match *node {
                 ast_map::NodeItem(ref item) => {
@@ -924,7 +935,7 @@ fn new(tcx: &'a ty::ctxt<'tcx>,
 
     fn rebuild(&self)
                -> (ast::FnDecl, Option<ast::ExplicitSelf_>, ast::Generics) {
-        let mut expl_self_opt = self.expl_self_opt.map(|x| x.clone());
+        let mut expl_self_opt = self.expl_self_opt.cloned();
         let mut inputs = self.fn_decl.inputs.clone();
         let mut output = self.fn_decl.output.clone();
         let mut ty_params = self.generics.ty_params.clone();
@@ -942,7 +953,7 @@ fn rebuild(&self)
             }
             expl_self_opt = self.rebuild_expl_self(expl_self_opt, lifetime,
                                                    &anon_nums, &region_names);
-            inputs = self.rebuild_args_ty(&inputs[], lifetime,
+            inputs = self.rebuild_args_ty(&inputs[..], lifetime,
                                           &anon_nums, &region_names);
             output = self.rebuild_output(&output, lifetime, &anon_nums, &region_names);
             ty_params = self.rebuild_ty_params(ty_params, lifetime,
@@ -1426,7 +1437,7 @@ fn give_expl_lifetime_param(&self,
                                               opt_explicit_self, generics);
         let msg = format!("consider using an explicit lifetime \
                            parameter as shown: {}", suggested_fn);
-        self.tcx.sess.span_help(span, &msg[]);
+        self.tcx.sess.span_help(span, &msg[..]);
     }
 
     fn report_inference_failure(&self,
@@ -1593,6 +1604,11 @@ fn note_region_origin(&self, origin: &SubregionOrigin<'tcx>) {
                     span,
                     "...so that return value is valid for the call");
             }
+            infer::Operand(span) => {
+                self.tcx.sess.span_err(
+                    span,
+                    "...so that operand is valid for operation");
+            }
             infer::AddrOf(span) => {
                 self.tcx.sess.span_note(
                     span,
@@ -1771,7 +1787,7 @@ fn give_lifetime(&self) -> ast::Lifetime {
             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);
+                                    token::str_to_ident(&s[..]).name);
                 self.generated.borrow_mut().push(lifetime);
                 break;
             }
index ff0c2d92f45eeae58ec193540288669275f7055b..33303808e84910ebb7062c4bf9147451ee7aaecd 100644 (file)
 
 use super::combine::*;
 use super::lattice::*;
-use super::equate::Equate;
 use super::higher_ranked::HigherRankedRelations;
-use super::lub::Lub;
-use super::sub::Sub;
-use super::{cres, InferCtxt};
-use super::{TypeTrace, Subtype};
+use super::{cres};
+use super::Subtype;
 
 use middle::ty::{BuiltinBounds};
 use middle::ty::{self, Ty};
@@ -34,15 +31,30 @@ pub fn Glb<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Glb<'f, 'tcx> {
 }
 
 impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx }
-    fn tag(&self) -> String { "glb".to_string() }
-    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
-    fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() }
+    fn tag(&self) -> String { "Glb".to_string() }
+    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
 
-    fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) }
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) }
-    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 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),
+        }
+    }
+
+    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;
@@ -75,10 +87,6 @@ fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> {
         }
     }
 
-    fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        self.lub().tys(a, b)
-    }
-
     fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> {
         match (a, b) {
           (Unsafety::Normal, _) | (_, Unsafety::Normal) => Ok(Unsafety::Normal),
@@ -104,11 +112,6 @@ fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> {
         Ok(self.fields.infcx.region_vars.glb_regions(Subtype(self.trace()), a, b))
     }
 
-    fn contraregions(&self, a: ty::Region, b: ty::Region)
-                    -> cres<'tcx, ty::Region> {
-        self.lub().regions(a, b)
-    }
-
     fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
         super_lattice_tys(self, a, b)
     }
index 4469e27a5b05af10e8e56825a2af5e1d02899e4c..a729156c88b3588e3d85e442d6878b6c526fcd15 100644 (file)
@@ -31,7 +31,7 @@ fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binde
         where T : Combineable<'tcx>;
 }
 
-trait InferCtxtExt<'tcx> {
+trait InferCtxtExt {
     fn tainted_regions(&self, snapshot: &CombinedSnapshot, r: ty::Region) -> Vec<ty::Region>;
 
     fn region_vars_confined_to_snapshot(&self,
@@ -371,7 +371,7 @@ fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>,
     }))
 }
 
-impl<'a,'tcx> InferCtxtExt<'tcx> for InferCtxt<'a,'tcx> {
+impl<'a,'tcx> InferCtxtExt for InferCtxt<'a,'tcx> {
     fn tainted_regions(&self, snapshot: &CombinedSnapshot, r: ty::Region) -> Vec<ty::Region> {
         self.region_vars.tainted(&snapshot.region_vars_snapshot, r)
     }
index 204560e87ee3b2718943c488adc71b5d6221d3ac..3570effa9fa709ff2de3c304db15f75f6dd4d428 100644 (file)
@@ -9,13 +9,10 @@
 // except according to those terms.
 
 use super::combine::*;
-use super::equate::Equate;
-use super::glb::Glb;
 use super::higher_ranked::HigherRankedRelations;
 use super::lattice::*;
-use super::sub::Sub;
-use super::{cres, InferCtxt};
-use super::{TypeTrace, Subtype};
+use super::{cres};
+use super::{Subtype};
 
 use middle::ty::{BuiltinBounds};
 use middle::ty::{self, Ty};
@@ -34,15 +31,30 @@ pub fn Lub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Lub<'f, 'tcx> {
 }
 
 impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx }
-    fn tag(&self) -> String { "lub".to_string() }
-    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
-    fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() }
+    fn tag(&self) -> String { "Lub".to_string() }
+    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
 
-    fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) }
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) }
-    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 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),
+        }
+    }
 
     fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> {
         let tcx = self.tcx();
@@ -70,10 +82,6 @@ fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> {
         }
     }
 
-    fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        self.glb().tys(a, b)
-    }
-
     fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> {
         match (a, b) {
           (Unsafety::Unsafe, _) | (_, Unsafety::Unsafe) => Ok(Unsafety::Unsafe),
@@ -90,11 +98,6 @@ fn builtin_bounds(&self,
         Ok(a.intersection(b))
     }
 
-    fn contraregions(&self, a: ty::Region, b: ty::Region)
-                    -> cres<'tcx, ty::Region> {
-        self.glb().regions(a, b)
-    }
-
     fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> {
         debug!("{}.regions({}, {})",
                self.tag(),
index 00e377d65fea7830d9820e1e055ff348e0d07404..b0576ff55ff7390605b889c93df55b3b10aa6b2f 100644 (file)
@@ -45,6 +45,7 @@
 use self::unify::{UnificationTable, InferCtxtMethodsForSimplyUnifiableTypes};
 use self::error_reporting::ErrorReporting;
 
+pub mod bivariate;
 pub mod combine;
 pub mod equate;
 pub mod error_reporting;
@@ -209,6 +210,9 @@ pub enum SubregionOrigin<'tcx> {
     // Region in return type of invoked fn must enclose call
     CallReturn(Span),
 
+    // Operands must be in scope
+    Operand(Span),
+
     // Region resulting from a `&` expr must enclose the `&` expr
     AddrOf(Span),
 
@@ -1194,6 +1198,7 @@ pub fn span(&self) -> Span {
             CallRcvr(a) => a,
             CallArg(a) => a,
             CallReturn(a) => a,
+            Operand(a) => a,
             AddrOf(a) => a,
             AutoBorrow(a) => a,
             SafeDestructor(a) => a,
@@ -1257,6 +1262,7 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
             CallRcvr(a) => format!("CallRcvr({})", a.repr(tcx)),
             CallArg(a) => format!("CallArg({})", a.repr(tcx)),
             CallReturn(a) => format!("CallReturn({})", a.repr(tcx)),
+            Operand(a) => format!("Operand({})", a.repr(tcx)),
             AddrOf(a) => format!("AddrOf({})", a.repr(tcx)),
             AutoBorrow(a) => format!("AutoBorrow({})", a.repr(tcx)),
             SafeDestructor(a) => format!("SafeDestructor({})", a.repr(tcx)),
index 5cdfdcc7c9b6ca8224d744503fe5936b502d7213..b4fd34f206fa728d258a40241a13fafa32a84a80 100644 (file)
@@ -977,7 +977,7 @@ fn infer_variable_values(&self,
         self.expansion(&mut var_data);
         self.contraction(&mut var_data);
         let values =
-            self.extract_values_and_collect_conflicts(&var_data[],
+            self.extract_values_and_collect_conflicts(&var_data[..],
                                                       errors);
         self.collect_concrete_region_errors(&values, errors);
         values
index 1e0d14544ff888c882b06034ca11692241423735..33da3092b2a256f8d4c8232f9eb50827603a87c8 100644 (file)
 
 use super::combine::*;
 use super::{cres, CresCompare};
-use super::equate::Equate;
-use super::glb::Glb;
 use super::higher_ranked::HigherRankedRelations;
-use super::InferCtxt;
-use super::lub::Lub;
-use super::{TypeTrace, Subtype};
+use super::{Subtype};
 use super::type_variable::{SubtypeOf, SupertypeOf};
 
 use middle::ty::{BuiltinBounds};
@@ -37,28 +33,30 @@ pub fn Sub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Sub<'f, 'tcx> {
 }
 
 impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx }
-    fn tag(&self) -> String { "sub".to_string() }
-    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> { Equate(self.fields.clone()) }
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) }
-    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 contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        Sub(self.fields.switch_expected()).tys(b, a)
+    fn tag(&self) -> String { "Sub".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 => Sub(self.fields.switch_expected()).tys(b, a),
+        }
     }
 
-    fn contraregions(&self, a: ty::Region, b: ty::Region)
-                     -> cres<'tcx, ty::Region> {
-                         let opp = CombineFields {
-                             a_is_expected: !self.fields.a_is_expected,
-                             ..self.fields.clone()
-                         };
-                         Sub(opp).regions(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 regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> {
         debug!("{}.regions({}, {})",
index 9b8a4a844120ddd328c27e0f9b8db38be69ccb28..a856137af090a706c68461ad0beac834086e1aa5 100644 (file)
@@ -14,6 +14,7 @@
 
 use middle::ty::{self, Ty};
 use std::cmp::min;
+use std::marker::PhantomData;
 use std::mem;
 use std::u32;
 use util::snapshot_vec as sv;
@@ -42,13 +43,13 @@ enum UndoEntry {
     Relate(ty::TyVid, ty::TyVid),
 }
 
-struct Delegate<'tcx>;
+struct Delegate<'tcx>(PhantomData<&'tcx ()>);
 
 type Relation = (RelationDir, ty::TyVid);
 
 #[derive(Copy, PartialEq, Debug)]
 pub enum RelationDir {
-    SubtypeOf, SupertypeOf, EqTo
+    SubtypeOf, SupertypeOf, EqTo, BiTo
 }
 
 impl RelationDir {
@@ -56,14 +57,15 @@ fn opposite(self) -> RelationDir {
         match self {
             SubtypeOf => SupertypeOf,
             SupertypeOf => SubtypeOf,
-            EqTo => EqTo
+            EqTo => EqTo,
+            BiTo => BiTo,
         }
     }
 }
 
 impl<'tcx> TypeVariableTable<'tcx> {
     pub fn new() -> TypeVariableTable<'tcx> {
-        TypeVariableTable { values: sv::SnapshotVec::new(Delegate) }
+        TypeVariableTable { values: sv::SnapshotVec::new(Delegate(PhantomData)) }
     }
 
     fn relations<'a>(&'a mut self, a: ty::TyVid) -> &'a mut Vec<Relation> {
index 235f3f994c65e40aa79c901e4f5a8cd4e7067126..0675cec6f69b5d61a0dac228d73d24f8c3108cf3 100644 (file)
@@ -18,6 +18,7 @@
 use middle::infer::InferCtxt;
 use std::cell::RefCell;
 use std::fmt::Debug;
+use std::marker::PhantomData;
 use syntax::ast;
 use util::snapshot_vec as sv;
 
@@ -79,7 +80,7 @@ pub struct UnificationTable<K:UnifyKey> {
 /// made during the snapshot may either be *committed* or *rolled back*.
 pub struct Snapshot<K:UnifyKey> {
     // Link snapshot to the key type `K` of the table.
-    marker: marker::CovariantType<K>,
+    marker: marker::PhantomData<K>,
     snapshot: sv::Snapshot,
 }
 
@@ -92,7 +93,7 @@ pub struct Node<K:UnifyKey> {
 }
 
 #[derive(Copy)]
-pub struct Delegate<K>;
+pub struct Delegate<K>(PhantomData<K>);
 
 // We can't use V:LatticeValue, much as I would like to,
 // because frequently the pattern is that V=Option<U> for some
@@ -102,14 +103,14 @@ pub struct Node<K:UnifyKey> {
 impl<K:UnifyKey> UnificationTable<K> {
     pub fn new() -> UnificationTable<K> {
         UnificationTable {
-            values: sv::SnapshotVec::new(Delegate),
+            values: sv::SnapshotVec::new(Delegate(PhantomData)),
         }
     }
 
     /// Starts a new snapshot. Each snapshot must be either
     /// rolled back or committed in a "LIFO" (stack) order.
     pub fn snapshot(&mut self) -> Snapshot<K> {
-        Snapshot { marker: marker::CovariantType::<K>,
+        Snapshot { marker: marker::PhantomData::<K>,
                    snapshot: self.values.start_snapshot() }
     }
 
index e13a5672778e24da1a4a88980b21fc01eacff0ce..56c5928a132b14cd56ac92d19588bc227c912c55 100644 (file)
@@ -147,18 +147,12 @@ struct LanguageItemCollector<'a> {
 
 impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> {
     fn visit_item(&mut self, item: &ast::Item) {
-        match extract(&item.attrs) {
-            Some(value) => {
-                let item_index = self.item_refs.get(&value[]).map(|x| *x);
-
-                match item_index {
-                    Some(item_index) => {
-                        self.collect_item(item_index, local_def(item.id), item.span)
-                    }
-                    None => {}
-                }
+        if let Some(value) = extract(&item.attrs) {
+            let item_index = self.item_refs.get(&value[..]).cloned();
+
+            if let Some(item_index) = item_index {
+                self.collect_item(item_index, local_def(item.id), item.span)
             }
-            None => {}
         }
 
         visit::walk_item(self, item);
@@ -312,12 +306,13 @@ pub fn collect_language_items(krate: &ast::Crate,
     ExchangeHeapLangItem,            "exchange_heap",           exchange_heap;
     OwnedBoxLangItem,                "owned_box",               owned_box;
 
+    PhantomFnItem,                   "phantom_fn",              phantom_fn;
     PhantomDataItem,                 "phantom_data",            phantom_data;
 
+    // Deprecated:
     CovariantTypeItem,               "covariant_type",          covariant_type;
     ContravariantTypeItem,           "contravariant_type",      contravariant_type;
     InvariantTypeItem,               "invariant_type",          invariant_type;
-
     CovariantLifetimeItem,           "covariant_lifetime",      covariant_lifetime;
     ContravariantLifetimeItem,       "contravariant_lifetime",  contravariant_lifetime;
     InvariantLifetimeItem,           "invariant_lifetime",      invariant_lifetime;
index d4fe09793131f29d8117f8e35942c1762e1874cf..e58136fb3f4e454e18c6269b16ebd57f0dea5642 100644 (file)
@@ -1119,7 +1119,7 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
           // Uninteresting cases: just propagate in rev exec order
 
           ast::ExprVec(ref exprs) => {
-            self.propagate_through_exprs(&exprs[], succ)
+            self.propagate_through_exprs(&exprs[..], succ)
           }
 
           ast::ExprRepeat(ref element, ref count) => {
@@ -1143,7 +1143,7 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
             } else {
                 succ
             };
-            let succ = self.propagate_through_exprs(&args[], succ);
+            let succ = self.propagate_through_exprs(&args[..], succ);
             self.propagate_through_expr(&**f, succ)
           }
 
@@ -1156,11 +1156,11 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
             } else {
                 succ
             };
-            self.propagate_through_exprs(&args[], succ)
+            self.propagate_through_exprs(&args[..], succ)
           }
 
           ast::ExprTup(ref exprs) => {
-            self.propagate_through_exprs(&exprs[], succ)
+            self.propagate_through_exprs(&exprs[..], succ)
           }
 
           ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op.node) => {
index 2f0462ab8c338177692ca3314e247c5c3e467e71..e539f6ae6cb9382898b2167093e91fe5b288e3db 100644 (file)
@@ -407,7 +407,7 @@ pub fn mark_as_terminating_scope(&self, scope_id: CodeExtent) {
 
     pub fn opt_encl_scope(&self, id: CodeExtent) -> Option<CodeExtent> {
         //! Returns the narrowest scope that encloses `id`, if any.
-        self.scope_map.borrow().get(&id).map(|x| *x)
+        self.scope_map.borrow().get(&id).cloned()
     }
 
     #[allow(dead_code)] // used in middle::cfg
index e91d7d8c52cde8fcbe52af0d0ce6b4797dde80c3..3ba08c1032031075224aaa0dddcd1ac67902f5d4 100644 (file)
@@ -562,7 +562,7 @@ pub fn early_bound_lifetimes<'a>(generics: &'a ast::Generics) -> Vec<ast::Lifeti
 
     generics.lifetimes.iter()
         .filter(|l| referenced_idents.iter().any(|&i| i == l.lifetime.name))
-        .map(|l| (*l).clone())
+        .cloned()
         .collect()
 }
 
index 9bf35bd4284722c62a4f39880f5fbd70d543a042..04fd03ab34224a3af51bfeed5ab69aad2c355bf4 100644 (file)
@@ -113,7 +113,7 @@ pub fn has_regions_escaping_depth(&self, depth: u32) -> bool {
     }
 
     pub fn self_ty(&self) -> Option<Ty<'tcx>> {
-        self.types.get_self().map(|&t| t)
+        self.types.get_self().cloned()
     }
 
     pub fn with_self_ty(&self, self_ty: Ty<'tcx>) -> Substs<'tcx> {
index 3a7522cafee90f283354aa24e520dd40c52211ca..e199a60c370e30cf732f0dbb2d3a300f9276e3f8 100644 (file)
 
 //! See `doc.rs` for high-level documentation
 
+use super::Normalized;
 use super::SelectionContext;
-use super::{Obligation, ObligationCause};
+use super::{ObligationCause};
+use super::PredicateObligation;
 use super::project;
 use super::util;
 
 use middle::subst::{Subst, TypeSpace};
-use middle::ty::{self, Ty};
-use middle::infer::InferCtxt;
+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 util::ppaux::Repr;
 
-pub fn impl_can_satisfy(infcx: &InferCtxt,
-                        impl1_def_id: ast::DefId,
-                        impl2_def_id: ast::DefId)
-                        -> 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,
+                         impl2_def_id: ast::DefId)
+                         -> bool
 {
     debug!("impl_can_satisfy(\
            impl1_def_id={}, \
@@ -35,28 +38,68 @@ pub fn impl_can_satisfy(infcx: &InferCtxt,
            impl1_def_id.repr(infcx.tcx),
            impl2_def_id.repr(infcx.tcx));
 
-    let param_env = ty::empty_parameter_environment(infcx.tcx);
-    let mut selcx = SelectionContext::intercrate(infcx, &param_env);
-    let cause = ObligationCause::dummy();
-
-    // `impl1` provides an implementation of `Foo<X,Y> for Z`.
-    let impl1_substs =
-        util::fresh_substs_for_impl(infcx, DUMMY_SP, impl1_def_id);
-    let impl1_trait_ref =
-        (*ty::impl_trait_ref(infcx.tcx, impl1_def_id).unwrap()).subst(infcx.tcx, &impl1_substs);
-    let impl1_trait_ref =
-        project::normalize(&mut selcx, cause.clone(), &impl1_trait_ref);
-
-    // Determine whether `impl2` can provide an implementation for those
-    // same types.
-    let obligation = Obligation::new(cause,
-                                     ty::Binder(ty::TraitPredicate {
-                                         trait_ref: Rc::new(impl1_trait_ref.value),
-                                     }));
-    debug!("impl_can_satisfy(obligation={})", obligation.repr(infcx.tcx));
-    selcx.evaluate_impl(impl2_def_id, &obligation) &&
-        impl1_trait_ref.obligations.iter().all(
-            |o| selcx.evaluate_obligation(o))
+    let param_env = &ty::empty_parameter_environment(infcx.tcx);
+    let selcx = &mut SelectionContext::intercrate(infcx, param_env);
+    infcx.probe(|_| {
+        overlap(selcx, impl1_def_id, impl2_def_id) || overlap(selcx, impl2_def_id, impl1_def_id)
+    })
+}
+
+/// Can the types from impl `a` be used to satisfy impl `b`?
+/// (Including all conditions)
+fn overlap(selcx: &mut SelectionContext,
+           a_def_id: ast::DefId,
+           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);
+
+    // Does `a <: b` hold? If not, no overlap.
+    if let Err(_) = infer::mk_sub_poly_trait_refs(selcx.infcx(),
+                                                  true,
+                                                  infer::Misc(DUMMY_SP),
+                                                  a_trait_ref.to_poly_trait_ref(),
+                                                  b_trait_ref.to_poly_trait_ref()) {
+        return false;
+    }
+
+    // Are any of the obligations unsatisfiable? If so, no overlap.
+    a_obligations.iter()
+                 .chain(b_obligations.iter())
+                 .all(|o| selcx.evaluate_obligation(o))
+}
+
+/// 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)
+                                     -> (Rc<ty::TraitRef<'tcx>>,
+                                         Vec<PredicateObligation<'tcx>>)
+{
+    let impl_substs =
+        &util::fresh_substs_for_impl(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 =
+        impl_trait_ref.subst(selcx.tcx(), impl_substs);
+    let Normalized { value: impl_trait_ref, obligations: normalization_obligations1 } =
+        project::normalize(selcx, ObligationCause::dummy(), &impl_trait_ref);
+
+    let predicates = ty::lookup_predicates(selcx.tcx(), impl_def_id);
+    let predicates = predicates.instantiate(selcx.tcx(), impl_substs);
+    let Normalized { value: predicates, obligations: normalization_obligations2 } =
+        project::normalize(selcx, ObligationCause::dummy(), &predicates);
+    let impl_obligations =
+        util::predicates_for_generics(selcx.tcx(), ObligationCause::dummy(), 0, &predicates);
+
+    let impl_obligations: Vec<_> =
+        impl_obligations.into_iter()
+        .chain(normalization_obligations1.into_iter())
+        .chain(normalization_obligations2.into_iter())
+        .collect();
+
+    (impl_trait_ref, impl_obligations)
 }
 
 pub enum OrphanCheckErr<'tcx> {
index 57c9fa7a4d964a0b834e473247e2278f24631761..a63dcfc24a10ec6d76314be312d3e0d81a671433 100644 (file)
@@ -28,6 +28,7 @@
 pub use self::error_reporting::report_fulfillment_errors;
 pub use self::error_reporting::suggest_new_overflow_limit;
 pub use self::coherence::orphan_check;
+pub use self::coherence::overlapping_impls;
 pub use self::coherence::OrphanCheckErr;
 pub use self::fulfill::{FulfillmentContext, RegionObligation};
 pub use self::project::MismatchedProjectionTypes;
@@ -270,16 +271,6 @@ pub struct VtableObjectData<'tcx> {
     pub object_ty: Ty<'tcx>,
 }
 
-/// True if there exist types that satisfy both of the two given impls.
-pub fn overlapping_impls(infcx: &InferCtxt,
-                         impl1_def_id: ast::DefId,
-                         impl2_def_id: ast::DefId)
-                         -> bool
-{
-    coherence::impl_can_satisfy(infcx, impl1_def_id, impl2_def_id) &&
-    coherence::impl_can_satisfy(infcx, impl2_def_id, impl1_def_id)
-}
-
 /// Creates predicate obligations from the generic bounds.
 pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
                                      cause: ObligationCause<'tcx>,
index b2701ae875c0cb51cc1b914236bda73260b64e1a..f10f7eb3951c7a0468a3a5e86367e9d4c024060f 100644 (file)
@@ -20,7 +20,7 @@
 use super::supertraits;
 use super::elaborate_predicates;
 
-use middle::subst::{self, SelfSpace};
+use middle::subst::{self, SelfSpace, TypeSpace};
 use middle::traits;
 use middle::ty::{self, Ty};
 use std::rc::Rc;
@@ -31,6 +31,10 @@ pub enum ObjectSafetyViolation<'tcx> {
     /// Self : Sized declared on the trait
     SizedSelf,
 
+    /// Supertrait reference references `Self` an in illegal location
+    /// (e.g. `trait Foo : Bar<Self>`)
+    SupertraitSelf,
+
     /// Method has something illegal
     Method(Rc<ty::Method<'tcx>>, MethodViolationCode),
 }
@@ -57,7 +61,7 @@ pub fn is_object_safe<'tcx>(tcx: &ty::ctxt<'tcx>,
 {
     // Because we query yes/no results frequently, we keep a cache:
     let cached_result =
-        tcx.object_safety_cache.borrow().get(&trait_ref.def_id()).map(|&r| r);
+        tcx.object_safety_cache.borrow().get(&trait_ref.def_id()).cloned();
 
     let result =
         cached_result.unwrap_or_else(|| {
@@ -110,6 +114,9 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
     if trait_has_sized_self(tcx, trait_def_id) {
         violations.push(ObjectSafetyViolation::SizedSelf);
     }
+    if supertraits_reference_self(tcx, trait_def_id) {
+        violations.push(ObjectSafetyViolation::SupertraitSelf);
+    }
 
     debug!("object_safety_violations_for_trait(trait_def_id={}) = {}",
            trait_def_id.repr(tcx),
@@ -118,6 +125,35 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
     violations
 }
 
+fn supertraits_reference_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_ref = trait_def.trait_ref.clone();
+    let predicates = ty::predicates_for_trait_ref(tcx, &ty::Binder(trait_ref));
+    predicates
+        .into_iter()
+        .any(|predicate| {
+            match predicate {
+                ty::Predicate::Trait(ref data) => {
+                    // In the case of a trait predicate, we can skip the "self" type.
+                    Some(data.def_id()) != tcx.lang_items.phantom_fn() &&
+                        data.0.trait_ref.substs.types.get_slice(TypeSpace)
+                                                     .iter()
+                                                     .cloned()
+                                                     .any(is_self)
+                }
+                ty::Predicate::Projection(..) |
+                ty::Predicate::TypeOutlives(..) |
+                ty::Predicate::RegionOutlives(..) |
+                ty::Predicate::Equate(..) => {
+                    false
+                }
+            }
+        })
+}
+
 fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>,
                               trait_def_id: ast::DefId)
                               -> bool
@@ -138,11 +174,7 @@ fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>,
         .any(|predicate| {
             match predicate {
                 ty::Predicate::Trait(ref trait_pred) if trait_pred.def_id() == sized_def_id => {
-                    let self_ty = trait_pred.0.self_ty();
-                    match self_ty.sty {
-                        ty::ty_param(ref data) => data.space == subst::SelfSpace,
-                        _ => false,
-                    }
+                    is_self(trait_pred.0.self_ty())
                 }
                 ty::Predicate::Projection(..) |
                 ty::Predicate::Trait(..) |
@@ -295,8 +327,17 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
         match *self {
             ObjectSafetyViolation::SizedSelf =>
                 format!("SizedSelf"),
+            ObjectSafetyViolation::SupertraitSelf =>
+                format!("SupertraitSelf"),
             ObjectSafetyViolation::Method(ref m, code) =>
                 format!("Method({},{:?})", m.repr(tcx), code),
         }
     }
 }
+
+fn is_self<'tcx>(ty: Ty<'tcx>) -> bool {
+    match ty.sty {
+        ty::ty_param(ref data) => data.space == subst::SelfSpace,
+        _ => false,
+    }
+}
index 027415de998dfbae2049fe51b8d1f83fed696955..0e29892084175d180047412a39c9a2e936c750a7 100644 (file)
@@ -132,6 +132,7 @@ pub enum MethodMatchedData {
 /// parameters) that would have to be inferred from the impl.
 #[derive(PartialEq,Eq,Debug,Clone)]
 enum SelectionCandidate<'tcx> {
+    PhantomFnCandidate,
     BuiltinCandidate(ty::BuiltinBound),
     ParamCandidate(ty::PolyTraitRef<'tcx>),
     ImplCandidate(ast::DefId),
@@ -736,7 +737,7 @@ fn check_candidate_cache(&mut self,
     {
         let cache = self.pick_candidate_cache();
         let hashmap = cache.hashmap.borrow();
-        hashmap.get(&cache_fresh_trait_pred.0.trait_ref).map(|c| (*c).clone())
+        hashmap.get(&cache_fresh_trait_pred.0.trait_ref).cloned()
     }
 
     fn insert_candidate_cache(&mut self,
@@ -793,8 +794,6 @@ fn assemble_candidates<'o>(&mut self,
                                stack: &TraitObligationStack<'o, 'tcx>)
                                -> Result<SelectionCandidateSet<'tcx>, SelectionError<'tcx>>
     {
-        // Check for overflow.
-
         let TraitObligationStack { obligation, .. } = *stack;
 
         let mut candidates = SelectionCandidateSet {
@@ -802,6 +801,14 @@ fn assemble_candidates<'o>(&mut self,
             ambiguous: false
         };
 
+        // Check for the `PhantomFn` trait. This is really just a
+        // special annotation that is *always* considered to match, no
+        // matter what the type parameters are etc.
+        if self.tcx().lang_items.phantom_fn() == Some(obligation.predicate.def_id()) {
+            candidates.vec.push(PhantomFnCandidate);
+            return Ok(candidates);
+        }
+
         // Other bounds. Consider both in-scope bounds from fn decl
         // and applicable impls. There is a certain set of precedence rules here.
 
@@ -996,7 +1003,7 @@ fn assemble_candidates_from_caller_bounds<'o>(&mut self,
 
         let all_bounds =
             util::transitive_bounds(
-                self.tcx(), &caller_trait_refs[]);
+                self.tcx(), &caller_trait_refs[..]);
 
         let matching_bounds =
             all_bounds.filter(
@@ -1521,7 +1528,7 @@ fn builtin_bound(&mut self,
                     ty::substd_enum_variants(self.tcx(), def_id, substs)
                     .iter()
                     .flat_map(|variant| variant.args.iter())
-                    .map(|&ty| ty)
+                    .cloned()
                     .collect();
                 nominal(self, bound, def_id, types)
             }
@@ -1629,6 +1636,7 @@ fn confirm_candidate(&mut self,
                     try!(self.confirm_builtin_candidate(obligation, builtin_bound))))
             }
 
+            PhantomFnCandidate |
             ErrorCandidate => {
                 Ok(VtableBuiltin(VtableBuiltinData { nested: VecPerParamSpace::empty() }))
             }
@@ -2295,6 +2303,7 @@ fn derived_cause(&self,
 impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> {
     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
         match *self {
+            PhantomFnCandidate => format!("PhantomFnCandidate"),
             ErrorCandidate => format!("ErrorCandidate"),
             BuiltinCandidate(b) => format!("BuiltinCandidate({:?})", b),
             ParamCandidate(ref a) => format!("ParamCandidate({})", a.repr(tcx)),
index e3eda02b0a8429a0e7283995f4534e756cd89291..e9908397f970387782fb097c4d478013d92c480a 100644 (file)
 use util::nodemap::{FnvHashMap};
 
 use arena::TypedArena;
-use std::borrow::{BorrowFrom, Cow};
+use std::borrow::{Borrow, Cow};
 use std::cell::{Cell, RefCell};
 use std::cmp;
 use std::fmt;
-use std::hash::{Hash, Writer, SipHasher, Hasher};
+use std::hash::{Hash, SipHasher, Hasher};
+#[cfg(stage0)] use std::hash::Writer;
 use std::mem;
 use std::ops;
 use std::rc::Rc;
-use std::vec::CowVec;
+use std::vec::{CowVec, IntoIter};
 use collections::enum_set::{EnumSet, CLike};
 use std::collections::{HashMap, HashSet};
 use syntax::abi;
@@ -958,11 +959,18 @@ fn eq(&self, other: &TyS<'tcx>) -> bool {
 }
 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)
+    }
+}
 
 pub type Ty<'tcx> = &'tcx TyS<'tcx>;
 
@@ -980,15 +988,22 @@ fn eq(&self, other: &InternedTy<'tcx>) -> bool {
 
 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)
+    }
+}
 
-impl<'tcx> BorrowFrom<InternedTy<'tcx>> for sty<'tcx> {
-    fn borrow_from<'a>(ty: &'a InternedTy<'tcx>) -> &'a sty<'tcx> {
-        &ty.ty.sty
+impl<'tcx> Borrow<sty<'tcx>> for InternedTy<'tcx> {
+    fn borrow<'a>(&'a self) -> &'a sty<'tcx> {
+        &self.ty.sty
     }
 }
 
@@ -2004,6 +2019,40 @@ fn as_predicate(&self) -> Predicate<'tcx> {
 }
 
 impl<'tcx> Predicate<'tcx> {
+    /// Iterates over the types in this predicate. Note that in all
+    /// cases this is skipping over a binder, so late-bound regions
+    /// with depth 0 are bound by the predicate.
+    pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> {
+        let vec: Vec<_> = match *self {
+            ty::Predicate::Trait(ref data) => {
+                data.0.trait_ref.substs.types.as_slice().to_vec()
+            }
+            ty::Predicate::Equate(ty::Binder(ref data)) => {
+                vec![data.0, data.1]
+            }
+            ty::Predicate::TypeOutlives(ty::Binder(ref data)) => {
+                vec![data.0]
+            }
+            ty::Predicate::RegionOutlives(..) => {
+                vec![]
+            }
+            ty::Predicate::Projection(ref data) => {
+                let trait_inputs = data.0.projection_ty.trait_ref.substs.types.as_slice();
+                trait_inputs.iter()
+                            .cloned()
+                            .chain(Some(data.0.ty).into_iter())
+                            .collect()
+            }
+        };
+
+        // The only reason to collect into a vector here is that I was
+        // too lazy to make the full (somewhat complicated) iterator
+        // type that would be needed here. But I wanted this fn to
+        // return an iterator conceptually, rather than a `Vec`, so as
+        // to be closer to `Ty::walk`.
+        vec.into_iter()
+    }
+
     pub fn has_escaping_regions(&self) -> bool {
         match *self {
             Predicate::Trait(ref trait_ref) => trait_ref.has_escaping_regions(),
@@ -2331,7 +2380,7 @@ pub fn trait_did(&self, cx: &ctxt) -> ast::DefId {
         };
         match result {
             Ok(trait_did) => trait_did,
-            Err(err) => cx.sess.fatal(&err[]),
+            Err(err) => cx.sess.fatal(&err[..]),
         }
     }
 }
@@ -2665,7 +2714,7 @@ fn add_sty(&mut self, st: &sty) {
             }
 
             &ty_tup(ref ts) => {
-                self.add_tys(&ts[]);
+                self.add_tys(&ts[..]);
             }
 
             &ty_bare_fn(_, ref f) => {
@@ -2836,7 +2885,7 @@ pub fn mk_ctor_fn<'tcx>(cx: &ctxt<'tcx>,
                         def_id: ast::DefId,
                         input_tys: &[Ty<'tcx>],
                         output: Ty<'tcx>) -> Ty<'tcx> {
-    let input_args = input_tys.iter().map(|ty| *ty).collect();
+    let input_args = input_tys.iter().cloned().collect();
     mk_bare_fn(cx,
                Some(def_id),
                cx.mk_bare_fn(BareFnTy {
@@ -2959,6 +3008,13 @@ pub fn walk_children(&'tcx self) -> TypeWalker<'tcx> {
         assert_eq!(r, Some(self));
         walker
     }
+
+    pub fn as_opt_param_ty(&self) -> Option<ty::ParamTy> {
+        match self.sty {
+            ty::ty_param(ref d) => Some(d.clone()),
+            _ => None,
+        }
+    }
 }
 
 pub fn walk_ty<'tcx, F>(ty_root: Ty<'tcx>, mut f: F)
@@ -3451,7 +3507,7 @@ fn tc_ty<'tcx>(cx: &ctxt<'tcx>,
             ty_struct(did, substs) => {
                 let flds = struct_fields(cx, did, substs);
                 let mut res =
-                    TypeContents::union(&flds[],
+                    TypeContents::union(&flds[..],
                                         |f| tc_mt(cx, f.mt, cache));
 
                 if !lookup_repr_hints(cx, did).contains(&attr::ReprExtern) {
@@ -3474,14 +3530,14 @@ fn tc_ty<'tcx>(cx: &ctxt<'tcx>,
             }
 
             ty_tup(ref tys) => {
-                TypeContents::union(&tys[],
+                TypeContents::union(&tys[..],
                                     |ty| tc_ty(cx, *ty, cache))
             }
 
             ty_enum(did, substs) => {
                 let variants = substd_enum_variants(cx, did, substs);
                 let mut res =
-                    TypeContents::union(&variants[], |variant| {
+                    TypeContents::union(&variants[..], |variant| {
                         TypeContents::union(&variant.args[],
                                             |arg_ty| {
                             tc_ty(cx, *arg_ty, cache)
@@ -3805,7 +3861,7 @@ fn are_inner_types_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
                                        -> Representability {
         match ty.sty {
             ty_tup(ref ts) => {
-                find_nonrepresentable(cx, sp, seen, ts.iter().map(|ty| *ty))
+                find_nonrepresentable(cx, sp, seen, ts.iter().cloned())
             }
             // Fixed-length vectors.
             // FIXME(#11924) Behavior undecided for zero-length vectors.
@@ -4112,7 +4168,7 @@ pub fn positional_element_ty<'tcx>(cx: &ctxt<'tcx>,
                                    variant: Option<ast::DefId>) -> Option<Ty<'tcx>> {
 
     match (&ty.sty, variant) {
-        (&ty_tup(ref v), None) => v.get(i).map(|&t| t),
+        (&ty_tup(ref v), None) => v.get(i).cloned(),
 
 
         (&ty_struct(def_id, substs), None) => lookup_struct_fields(cx, def_id)
@@ -4933,7 +4989,7 @@ pub fn note_and_explain_type_err(cx: &ctxt, err: &type_err) {
 }
 
 pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option<ast::DefId> {
-    cx.provided_method_sources.borrow().get(&id).map(|x| *x)
+    cx.provided_method_sources.borrow().get(&id).cloned()
 }
 
 pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
@@ -4944,7 +5000,7 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
                 match item.node {
                     ItemTrait(_, _, _, ref ms) => {
                         let (_, p) =
-                            ast_util::split_trait_methods(&ms[]);
+                            ast_util::split_trait_methods(&ms[..]);
                         p.iter()
                          .map(|m| {
                             match impl_or_trait_item(
@@ -6600,7 +6656,7 @@ fn accum_substs(accumulator: &mut Vec<Region>, substs: &Substs) {
 }
 
 /// A free variable referred to in a function.
-#[derive(Copy, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
 pub struct Freevar {
     /// The variable being accessed free.
     pub def: def::Def,
@@ -6625,7 +6681,7 @@ pub fn with_freevars<T, F>(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where
 {
     match tcx.freevars.borrow().get(&fid) {
         None => f(&[]),
-        Some(d) => f(&d[])
+        Some(d) => f(&d[..])
     }
 }
 
index ee3fd681a005223af9a6df5537ce566c1b99f1bc..60a9ffc7d2e13b80a6e1824a55efdb6e02315504 100644 (file)
@@ -55,7 +55,7 @@ pub fn check_crate(krate: &ast::Crate,
 
 pub fn link_name(attrs: &[ast::Attribute]) -> Option<InternedString> {
     lang_items::extract(attrs).and_then(|name| {
-        $(if &name[] == stringify!($name) {
+        $(if &name[..] == stringify!($name) {
             Some(InternedString::new(stringify!($sym)))
         } else)* {
             None
index 1895cbcb5421e341f051dd3b4c6109b8dc6f811e..b3bc898748fdc00ba3637c5efde0d0bc473255cd 100644 (file)
@@ -111,19 +111,19 @@ fn dylink_registrar(&mut self,
             // inside this crate, so continue would spew "macro undefined"
             // errors
             Err(err) => {
-                self.sess.span_fatal(span, &err[])
+                self.sess.span_fatal(span, &err[..])
             }
         };
 
         unsafe {
             let registrar =
-                match lib.symbol(&symbol[]) {
+                match lib.symbol(&symbol[..]) {
                     Ok(registrar) => {
                         mem::transmute::<*mut u8,PluginRegistrarFun>(registrar)
                     }
                     // again fatal if we can't register macros
                     Err(err) => {
-                        self.sess.span_fatal(span, &err[])
+                        self.sess.span_fatal(span, &err[..])
                     }
                 };
 
index 5768539b2cd76fe5502a20598bc5e1bee9ace8c4..93a25de0491fe018ab8fef7d7e11435c80c211e4 100644 (file)
@@ -629,7 +629,7 @@ pub fn build_configuration(sess: &Session) -> ast::CrateConfig {
         append_configuration(&mut user_cfg, InternedString::new("test"))
     }
     let mut v = user_cfg.into_iter().collect::<Vec<_>>();
-    v.push_all(&default_cfg[]);
+    v.push_all(&default_cfg[..]);
     v
 }
 
@@ -824,7 +824,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String> ) -> ast::CrateConfig {
 pub fn build_session_options(matches: &getopts::Matches) -> Options {
     let unparsed_crate_types = matches.opt_strs("crate-type");
     let crate_types = parse_crate_types_from_list(unparsed_crate_types)
-        .unwrap_or_else(|e| early_error(&e[]));
+        .unwrap_or_else(|e| early_error(&e[..]));
 
     let mut lint_opts = vec!();
     let mut describe_lints = false;
@@ -923,7 +923,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     let mut search_paths = SearchPaths::new();
     for s in &matches.opt_strs("L") {
-        search_paths.add_path(&s[]);
+        search_paths.add_path(&s[..]);
     }
 
     let libs = matches.opt_strs("l").into_iter().map(|s| {
@@ -981,7 +981,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
                     --debuginfo");
     }
 
-    let color = match matches.opt_str("color").as_ref().map(|s| &s[]) {
+    let color = match matches.opt_str("color").as_ref().map(|s| &s[..]) {
         Some("auto")   => Auto,
         Some("always") => Always,
         Some("never")  => Never,
@@ -1119,7 +1119,7 @@ fn test_switch_implies_cfg_test() {
         let sessopts = build_session_options(matches);
         let sess = build_session(sessopts, None, registry);
         let cfg = build_configuration(&sess);
-        assert!((attr::contains_name(&cfg[], "test")));
+        assert!((attr::contains_name(&cfg[..], "test")));
     }
 
     // When the user supplies --test and --cfg test, don't implicitly add
index bd44dbe78f5438d8a86cbcad98df0732895df8e1..c1c5518887577d83462db5a07e032c48012f497e 100644 (file)
@@ -75,13 +75,13 @@ pub fn fatal(&self, msg: &str) -> ! {
     }
     pub fn span_err(&self, sp: Span, msg: &str) {
         match split_msg_into_multilines(msg) {
-            Some(msg) => self.diagnostic().span_err(sp, &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) {
         match split_msg_into_multilines(msg) {
-            Some(msg) => self.diagnostic().span_err_with_code(sp, &msg[], code),
+            Some(msg) => self.diagnostic().span_err_with_code(sp, &msg[..], code),
             None => self.diagnostic().span_err_with_code(sp, msg, code)
         }
     }
index d3d0f56c3ce904b7836f4f51ea80c4d4e39d2267..c9d50b9cecf84ff005f033b439c589b5202a61fa 100644 (file)
@@ -13,7 +13,8 @@
 use std::cell::{RefCell, Cell};
 use std::collections::HashMap;
 use std::fmt::Debug;
-use std::hash::{Hash, Hasher};
+use std::hash::Hash;
+#[cfg(stage0)] use std::hash::Hasher;
 use std::iter::repeat;
 use std::time::Duration;
 use std::collections::hash_state::HashState;
@@ -144,11 +145,54 @@ pub fn block_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) -
 /// 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,
+          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))]
+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,
 {
     if source == destination {
         return true;
@@ -206,12 +250,57 @@ 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,
           U: Clone,
           S: HashState,
           <S as HashState>::Hasher: Hasher<Output=u64>,
           F: FnOnce(T) -> U,
+{
+    let key = arg.clone();
+    let result = cache.borrow().get(&key).cloned();
+    match result {
+        Some(result) => result,
+        None => {
+            let result = f(arg);
+            cache.borrow_mut().insert(key, result.clone());
+            result
+        }
+    }
+}
+/// 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());
index ca1bb7d7a9404f0c2fea79bda4dac885476450a9..10a7b2abea80bb389e3213ec3895b27661ded2d8 100644 (file)
@@ -48,7 +48,7 @@ fn test_lev_distance() {
     for c in (0u32..MAX as u32)
              .filter_map(|i| from_u32(i))
              .map(|i| i.to_string()) {
-        assert_eq!(lev_distance(&c[], &c[]), 0);
+        assert_eq!(lev_distance(&c[..], &c[..]), 0);
     }
 
     let a = "\nMäry häd Ã¤ little lämb\n\nLittle lämb\n";
index f8e3defe19d632ac9c6b40ec63edc804f384ed1f..1b07ce789e77c8e7713c3ff2f2831fde021fc818 100644 (file)
@@ -15,7 +15,8 @@
 use std::collections::hash_state::{DefaultState};
 use std::collections::{HashMap, HashSet};
 use std::default::Default;
-use std::hash::{Hasher, Writer, Hash};
+use std::hash::{Hasher, Hash};
+#[cfg(stage0)] use std::hash::Writer;
 use syntax::ast;
 
 pub type FnvHashMap<K, V> = HashMap<K, V, DefaultState<FnvHasher>>;
 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()
+}
 
 pub fn NodeMap<T>() -> NodeMap<T> { FnvHashMap() }
 pub fn DefIdMap<T>() -> DefIdMap<T> { FnvHashMap() }
@@ -52,12 +63,14 @@ 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;
@@ -68,3 +81,16 @@ fn write(&mut self, bytes: &[u8]) {
         *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;
+        }
+        *self = FnvHasher(hash);
+    }
+    fn finish(&self) -> u64 { self.0 }
+}
index d54199a679a266f8cacdf913fa2287a8f76d3d83..1d46c011bb32e7298334fa4a1ea5318b1565feb4 100644 (file)
@@ -28,7 +28,8 @@
 
 use std::collections::HashMap;
 use std::collections::hash_state::HashState;
-use std::hash::{Hash, Hasher};
+use std::hash::Hash;
+#[cfg(stage0)] use std::hash::Hasher;
 use std::rc::Rc;
 use syntax::abi;
 use syntax::ast_map;
@@ -292,7 +293,7 @@ fn bare_fn_to_string<'tcx>(cx: &ctxt<'tcx>,
             Some(def_id) => {
                 s.push_str(" {");
                 let path_str = ty::item_path_str(cx, def_id);
-                s.push_str(&path_str[]);
+                s.push_str(&path_str[..]);
                 s.push_str("}");
             }
             None => { }
@@ -376,7 +377,7 @@ fn infer_ty_to_string(cx: &ctxt, ty: ty::InferTy) -> String {
                 .iter()
                 .map(|elem| ty_to_string(cx, *elem))
                 .collect::<Vec<_>>();
-            match &strs[] {
+            match &strs[..] {
                 [ref string] => format!("({},)", string),
                 strs => format!("({})", strs.connect(", "))
             }
@@ -508,13 +509,26 @@ pub fn parameterized<'tcx,GG>(cx: &ctxt<'tcx>,
     // avoid those ICEs.
     let generics = get_generics();
 
+    let has_self = substs.self_ty().is_some();
     let tps = substs.types.get_slice(subst::TypeSpace);
     let ty_params = generics.types.get_slice(subst::TypeSpace);
     let has_defaults = ty_params.last().map_or(false, |def| def.default.is_some());
     let num_defaults = if has_defaults {
         ty_params.iter().zip(tps.iter()).rev().take_while(|&(def, &actual)| {
             match def.default {
-                Some(default) => default.subst(cx, substs) == actual,
+                Some(default) => {
+                    if !has_self && ty::type_has_self(default) {
+                        // In an object type, there is no `Self`, and
+                        // thus if the default value references Self,
+                        // the user will be required to give an
+                        // explicit value. We can't even do the
+                        // substitution below to check without causing
+                        // an ICE. (#18956).
+                        false
+                    } else {
+                        default.subst(cx, substs) == actual
+                    }
+                }
                 None => false
             }
         }).count()
@@ -625,7 +639,7 @@ fn repr(&self, tcx: &ctxt<'tcx>) -> String {
 
 impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for OwnedSlice<T> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
-        repr_vec(tcx, &self[])
+        repr_vec(tcx, &self[..])
     }
 }
 
@@ -633,7 +647,7 @@ fn repr(&self, tcx: &ctxt<'tcx>) -> String {
 // autoderef cannot convert the &[T] handler
 impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Vec<T> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
-        repr_vec(tcx, &self[])
+        repr_vec(tcx, &self[..])
     }
 }
 
@@ -673,7 +687,7 @@ fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
                       &base,
                       trait_ref.substs,
                       trait_ref.def_id,
-                      &projection_bounds[],
+                      &projection_bounds[..],
                       || ty::lookup_trait_def(tcx, trait_ref.def_id).generics.clone())
     }
 }
@@ -1259,7 +1273,7 @@ fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
                 }
             })
         });
-        let names: Vec<_> = names.iter().map(|s| &s[]).collect();
+        let names: Vec<_> = names.iter().map(|s| &s[..]).collect();
 
         let value_str = unbound_value.user_string(tcx);
         if names.len() == 0 {
@@ -1420,6 +1434,7 @@ fn repr(&self, tcx: &ctxt<'tcx>) -> String {
     }
 }
 
+#[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>,
@@ -1435,6 +1450,21 @@ fn repr(&self, tcx: &ctxt<'tcx>) -> String {
     }
 }
 
+#[cfg(not(stage0))]
+impl<'tcx, S, K, V> Repr<'tcx> for HashMap<K, V, S>
+    where K: Hash + Eq + Repr<'tcx>,
+          V: Repr<'tcx>,
+          S: HashState,
+{
+    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(", "))
+    }
+}
+
 impl<'tcx, T, U> Repr<'tcx> for ty::OutlivesPredicate<T,U>
     where T : Repr<'tcx> + TypeFoldable<'tcx>,
           U : Repr<'tcx> + TypeFoldable<'tcx>,
index b779963a2191711774c1edbcb54171b5dd30d357..c45ee258342ec1be9c24a8f83d03f2bdae694488 100644 (file)
@@ -53,7 +53,7 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
           args: &str, cwd: Option<&Path>,
           paths: &[&Path]) -> ProcessOutput {
     let ar = match *maybe_ar_prog {
-        Some(ref ar) => &ar[],
+        Some(ref ar) => &ar[..],
         None => "ar"
     };
     let mut cmd = Command::new(ar);
@@ -84,7 +84,7 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
             o
         },
         Err(e) => {
-            handler.err(&format!("could not exec `{}`: {}", &ar[],
+            handler.err(&format!("could not exec `{}`: {}", &ar[..],
                              e)[]);
             handler.abort_if_errors();
             panic!("rustc::back::archive::run_ar() should not reach this point");
@@ -101,10 +101,10 @@ pub fn find_library(name: &str, osprefix: &str, ossuffix: &str,
 
     for path in search_paths {
         debug!("looking for {} inside {:?}", name, path.display());
-        let test = path.join(&oslibname[]);
+        let test = path.join(&oslibname[..]);
         if test.exists() { return test }
         if oslibname != unixlibname {
-            let test = path.join(&unixlibname[]);
+            let test = path.join(&unixlibname[..]);
             if test.exists() { return test }
         }
     }
@@ -192,12 +192,12 @@ pub fn add_rlib(&mut self, rlib: &Path, name: &str,
         // as simple comparison is not enough - there
         // might be also an extra name suffix
         let obj_start = format!("{}", name);
-        let obj_start = &obj_start[];
+        let obj_start = &obj_start[..];
         // Ignoring all bytecode files, no matter of
         // name
         let bc_ext = ".bytecode.deflate";
 
-        self.add_archive(rlib, &name[], |fname: &str| {
+        self.add_archive(rlib, &name[..], |fname: &str| {
             let skip_obj = lto && fname.starts_with(obj_start)
                 && fname.ends_with(".o");
             skip_obj || fname.ends_with(bc_ext) || fname == METADATA_FILENAME
@@ -234,7 +234,7 @@ pub fn build(self) -> Archive<'a> {
             // allow running `ar s file.a` to update symbols only.
             if self.should_update_symbols {
                 run_ar(self.archive.handler, &self.archive.maybe_ar_prog,
-                       "s", Some(self.work_dir.path()), &args[]);
+                       "s", Some(self.work_dir.path()), &args[..]);
             }
             return self.archive;
         }
@@ -254,7 +254,7 @@ pub fn build(self) -> Archive<'a> {
                 // Add the archive members seen so far, without updating the
                 // symbol table (`S`).
                 run_ar(self.archive.handler, &self.archive.maybe_ar_prog,
-                       "cruS", Some(self.work_dir.path()), &args[]);
+                       "cruS", Some(self.work_dir.path()), &args[..]);
 
                 args.clear();
                 args.push(&abs_dst);
@@ -269,7 +269,7 @@ pub fn build(self) -> Archive<'a> {
         // necessary.
         let flags = if self.should_update_symbols { "crus" } else { "cruS" };
         run_ar(self.archive.handler, &self.archive.maybe_ar_prog,
-               flags, Some(self.work_dir.path()), &args[]);
+               flags, Some(self.work_dir.path()), &args[..]);
 
         self.archive
     }
@@ -312,7 +312,7 @@ fn add_archive<F>(&mut self, archive: &Path, name: &str,
             } else {
                 filename
             };
-            let new_filename = self.work_dir.path().join(&filename[]);
+            let new_filename = self.work_dir.path().join(&filename[..]);
             try!(fs::rename(file, &new_filename));
             self.members.push(Path::new(filename));
         }
index 36bbd4b987297d020e5fe867d36b604bfbf9211f..e7419d4bec30747717d0bf68c88a3a26db383d7b 100644 (file)
@@ -40,12 +40,9 @@ pub fn get_rpath_flags<F, G>(config: RPathConfig<F, G>) -> Vec<String> where
     debug!("preparing the RPATH!");
 
     let libs = config.used_crates.clone();
-    let libs = libs.into_iter().filter_map(|(_, l)| {
-        l.map(|p| p.clone())
-    }).collect::<Vec<_>>();
-
-    let rpaths = get_rpaths(config, &libs[]);
-    flags.push_all(&rpaths_to_flags(&rpaths[])[]);
+    let libs = libs.into_iter().filter_map(|(_, l)| l).collect::<Vec<_>>();
+    let rpaths = get_rpaths(config, &libs[..]);
+    flags.push_all(&rpaths_to_flags(&rpaths[..]));
     flags
 }
 
@@ -82,14 +79,14 @@ fn log_rpaths(desc: &str, rpaths: &[String]) {
         }
     }
 
-    log_rpaths("relative", &rel_rpaths[]);
-    log_rpaths("fallback", &fallback_rpaths[]);
+    log_rpaths("relative", &rel_rpaths[..]);
+    log_rpaths("fallback", &fallback_rpaths[..]);
 
     let mut rpaths = rel_rpaths;
-    rpaths.push_all(&fallback_rpaths[]);
+    rpaths.push_all(&fallback_rpaths[..]);
 
     // Remove duplicates
-    let rpaths = minimize_rpaths(&rpaths[]);
+    let rpaths = minimize_rpaths(&rpaths[..]);
     return rpaths;
 }
 
@@ -139,7 +136,7 @@ fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
     let mut set = HashSet::new();
     let mut minimized = Vec::new();
     for rpath in rpaths {
-        if set.insert(&rpath[]) {
+        if set.insert(&rpath[..]) {
             minimized.push(rpath.clone());
         }
     }
index 692e6b474fd27b985ba55ca7eb6f7f41372ef7e3..01a5f0d6e20f881c481ad0e62f8153fdc21d3ece 100644 (file)
@@ -254,18 +254,18 @@ pub fn from_json(obj: Json) -> Target {
         macro_rules! key {
             ($key_name:ident) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
-                obj.find(&name[]).map(|o| o.as_string()
+                obj.find(&name[..]).map(|o| o.as_string()
                                     .map(|s| base.options.$key_name = s.to_string()));
             } );
             ($key_name:ident, bool) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
-                obj.find(&name[])
+                obj.find(&name[..])
                     .map(|o| o.as_boolean()
                          .map(|s| base.options.$key_name = s));
             } );
             ($key_name:ident, list) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
-                obj.find(&name[]).map(|o| o.as_array()
+                obj.find(&name[..]).map(|o| o.as_array()
                     .map(|v| base.options.$key_name = v.iter()
                         .map(|a| a.as_string().unwrap().to_string()).collect()
                         )
index a18e8b16e8baccd45f23a9b935434dce91fea653..abe01d193b4929b308f04dc3051b7cff761ccec5 100644 (file)
@@ -656,7 +656,7 @@ fn check_for_move_of_borrowed_path(&self,
                                 &self.bccx.loan_path_to_string(move_path)[])
                 };
 
-                self.bccx.span_err(span, &err_message[]);
+                self.bccx.span_err(span, &err_message[..]);
                 self.bccx.span_note(
                     loan_span,
                     &format!("borrow of `{}` occurs here",
index bee1ada28e31465dafee3e741f02b7c3a58e72a4..c873831cb0f657b6faa3fb81a16641b55211ce5c 100644 (file)
@@ -38,7 +38,7 @@ enum Fragment {
     // This represents the collection of all but one of the elements
     // from an array at the path described by the move path index.
     // Note that attached MovePathIndex should have mem_categorization
-    // of InteriorElement (i.e. array dereference `&foo[]`).
+    // of InteriorElement (i.e. array dereference `&foo[..]`).
     AllButOneFrom(MovePathIndex),
 }
 
@@ -198,11 +198,11 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) {
     // First, filter out duplicates
     moved.sort();
     moved.dedup();
-    debug!("fragments 1 moved: {:?}", path_lps(&moved[]));
+    debug!("fragments 1 moved: {:?}", path_lps(&moved[..]));
 
     assigned.sort();
     assigned.dedup();
-    debug!("fragments 1 assigned: {:?}", path_lps(&assigned[]));
+    debug!("fragments 1 assigned: {:?}", path_lps(&assigned[..]));
 
     // Second, build parents from the moved and assigned.
     for m in &moved {
@@ -222,14 +222,14 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) {
 
     parents.sort();
     parents.dedup();
-    debug!("fragments 2 parents: {:?}", path_lps(&parents[]));
+    debug!("fragments 2 parents: {:?}", path_lps(&parents[..]));
 
     // Third, filter the moved and assigned fragments down to just the non-parents
-    moved.retain(|f| non_member(*f, &parents[]));
-    debug!("fragments 3 moved: {:?}", path_lps(&moved[]));
+    moved.retain(|f| non_member(*f, &parents[..]));
+    debug!("fragments 3 moved: {:?}", path_lps(&moved[..]));
 
-    assigned.retain(|f| non_member(*f, &parents[]));
-    debug!("fragments 3 assigned: {:?}", path_lps(&assigned[]));
+    assigned.retain(|f| non_member(*f, &parents[..]));
+    debug!("fragments 3 assigned: {:?}", path_lps(&assigned[..]));
 
     // Fourth, build the leftover from the moved, assigned, and parents.
     for m in &moved {
@@ -247,16 +247,16 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) {
 
     unmoved.sort();
     unmoved.dedup();
-    debug!("fragments 4 unmoved: {:?}", frag_lps(&unmoved[]));
+    debug!("fragments 4 unmoved: {:?}", frag_lps(&unmoved[..]));
 
     // Fifth, filter the leftover fragments down to its core.
     unmoved.retain(|f| match *f {
         AllButOneFrom(_) => true,
-        Just(mpi) => non_member(mpi, &parents[]) &&
-            non_member(mpi, &moved[]) &&
-            non_member(mpi, &assigned[])
+        Just(mpi) => non_member(mpi, &parents[..]) &&
+            non_member(mpi, &moved[..]) &&
+            non_member(mpi, &assigned[..])
     });
-    debug!("fragments 5 unmoved: {:?}", frag_lps(&unmoved[]));
+    debug!("fragments 5 unmoved: {:?}", frag_lps(&unmoved[..]));
 
     // Swap contents back in.
     fragments.unmoved_fragments = unmoved;
@@ -437,7 +437,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
             let msg = format!("type {} ({:?}) is not fragmentable",
                               parent_ty.repr(tcx), sty_and_variant_info);
             let opt_span = origin_id.and_then(|id|tcx.map.opt_span(id));
-            tcx.sess.opt_span_bug(opt_span, &msg[])
+            tcx.sess.opt_span_bug(opt_span, &msg[..])
         }
     }
 }
index 93d97a054a4b3b720fcc0375b02e76d7c2a32d12..518e4bc472ca4aa6c117c8db26f9e0796ad5ce93 100644 (file)
@@ -137,7 +137,7 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
     check_loans::check_loans(this,
                              &loan_dfcx,
                              flowed_moves,
-                             &all_loans[],
+                             &all_loans[..],
                              id,
                              decl,
                              body);
index 56bf3ae7fd5a30ad536bf4d537c8465b93727a68..39c9d9ba6ad24ae5f067b893c66627c6d4e209a8 100644 (file)
@@ -89,7 +89,7 @@ fn build_set<O:DataFlowOperator, F>(&self,
                 set.push_str(", ");
             }
             let loan_str = self.borrowck_ctxt.loan_path_to_string(&*lp);
-            set.push_str(&loan_str[]);
+            set.push_str(&loan_str[..]);
             saw_some = true;
             true
         });
index c2677cc3fd0b386a27d16da3df43cec4a33fedb5..b7cfda280925701495074fcb68d1955b03b3a058 100644 (file)
@@ -20,7 +20,6 @@
 #![allow(non_camel_case_types)]
 
 #![feature(core)]
-#![feature(hash)]
 #![feature(int_uint)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
index 728ff6475999800e8300c11fece1457afb946a90..a260997f605940da7ac8d8fd6b83c9e93232af1b 100644 (file)
@@ -85,7 +85,7 @@ macro_rules! controller_entry_point{($point: ident, $make_state: expr) => ({
             let expanded_crate
                 = match phase_2_configure_and_expand(&sess,
                                                      krate,
-                                                     &id[],
+                                                     &id[..],
                                                      addl_plugins) {
                     None => return,
                     Some(k) => k
@@ -99,20 +99,20 @@ macro_rules! controller_entry_point{($point: ident, $make_state: expr) => ({
                                                                  &sess,
                                                                  outdir,
                                                                  &expanded_crate,
-                                                                 &id[]));
+                                                                 &id[..]));
 
         let mut forest = ast_map::Forest::new(expanded_crate);
         let arenas = ty::CtxtArenas::new();
         let ast_map = assign_node_ids_and_map(&sess, &mut forest);
 
-        write_out_deps(&sess, input, &outputs, &id[]);
+        write_out_deps(&sess, input, &outputs, &id[..]);
 
         controller_entry_point!(after_write_deps,
                                 CompileState::state_after_write_deps(input,
                                                                      &sess,
                                                                      outdir,
                                                                      &ast_map,
-                                                                     &id[]));
+                                                                     &id[..]));
 
         let analysis = phase_3_run_analysis_passes(sess,
                                                    ast_map,
index ac91a0098ea75bf20b7ed1f0ef633b200a2e9c14..2550432c8101adde411a3828936cb1a031eecaa0 100644 (file)
@@ -272,7 +272,7 @@ fn early_callback(&mut self,
                       -> Compilation {
         match matches.opt_str("explain") {
             Some(ref code) => {
-                match descriptions.find_description(&code[]) {
+                match descriptions.find_description(&code[..]) {
                     Some(ref description) => {
                         println!("{}", description);
                     }
@@ -582,7 +582,7 @@ fn sort_lint_groups(lints: Vec<(&'static str, Vec<lint::LintId>, bool)>)
         for lint in lints {
             let name = lint.name_lower().replace("_", "-");
             println!("    {}  {:7.7}  {}",
-                     padded(&name[]), lint.default_level.as_str(), lint.desc);
+                     padded(&name[..]), lint.default_level.as_str(), lint.desc);
         }
         println!("\n");
     };
@@ -612,7 +612,7 @@ fn sort_lint_groups(lints: Vec<(&'static str, Vec<lint::LintId>, bool)>)
             let desc = to.into_iter().map(|x| x.as_str().replace("_", "-"))
                          .collect::<Vec<String>>().connect(", ");
             println!("    {}  {}",
-                     padded(&name[]), desc);
+                     padded(&name[..]), desc);
         }
         println!("\n");
     };
@@ -678,7 +678,7 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
     }
 
     let matches =
-        match getopts::getopts(&args[], &config::optgroups()[]) {
+        match getopts::getopts(&args[..], &config::optgroups()[]) {
             Ok(m) => m,
             Err(f_stable_attempt) => {
                 // redo option parsing, including unstable options this time,
@@ -803,7 +803,7 @@ pub fn monitor<F:FnOnce()+Send+'static>(f: F) {
                     "run with `RUST_BACKTRACE=1` for a backtrace".to_string(),
                 ];
                 for note in &xs {
-                    emitter.emit(None, &note[], None, diagnostic::Note)
+                    emitter.emit(None, &note[..], None, diagnostic::Note)
                 }
 
                 match r.read_to_string() {
index 5dfef6c775e1e892a9980815aa21bd888e8b28ea..0fbfa5fd89dd7f3fdc1216ccb271332640b6fff2 100644 (file)
@@ -383,7 +383,7 @@ fn all_matching_node_ids<'a, 'ast>(&'a self, map: &'a ast_map::Map<'ast>)
             ItemViaNode(node_id) =>
                 NodesMatchingDirect(Some(node_id).into_iter()),
             ItemViaPath(ref parts) =>
-                NodesMatchingSuffix(map.nodes_matching_suffix(&parts[])),
+                NodesMatchingSuffix(map.nodes_matching_suffix(&parts[..])),
         }
     }
 
@@ -395,7 +395,7 @@ fn to_one_node_id(self, user_option: &str, sess: &Session, map: &ast_map::Map) -
                         user_option,
                         self.reconstructed_input(),
                         is_wrong_because);
-            sess.fatal(&message[])
+            sess.fatal(&message[..])
         };
 
         let mut saw_node = ast::DUMMY_NODE_ID;
@@ -522,7 +522,7 @@ pub fn pretty_print_input(sess: Session,
     let is_expanded = needs_expansion(&ppm);
     let compute_ast_map = needs_ast_map(&ppm, &opt_uii);
     let krate = if compute_ast_map {
-        match driver::phase_2_configure_and_expand(&sess, krate, &id[], None) {
+        match driver::phase_2_configure_and_expand(&sess, krate, &id[..], None) {
             None => return,
             Some(k) => k
         }
@@ -541,7 +541,7 @@ pub fn pretty_print_input(sess: Session,
     };
 
     let src_name = driver::source_name(input);
-    let src = sess.codemap().get_filemap(&src_name[])
+    let src = sess.codemap().get_filemap(&src_name[..])
                             .src.as_bytes().to_vec();
     let mut rdr = MemReader::new(src);
 
@@ -632,8 +632,8 @@ pub fn pretty_print_input(sess: Session,
                     // point to what was found, if there's an
                     // accessible span.
                     match ast_map.opt_span(nodeid) {
-                        Some(sp) => sess.span_fatal(sp, &message[]),
-                        None => sess.fatal(&message[])
+                        Some(sp) => sess.span_fatal(sp, &message[..]),
+                        None => sess.fatal(&message[..])
                     }
                 }
             }
index 7105a6cc488821e0e30460cdcc7c83329a69a0e6..fbbd72e2c76be6efd75fe6182759d3d578997c0a 100644 (file)
@@ -254,7 +254,7 @@ pub fn t_fn(&self,
                 output_ty: Ty<'tcx>)
                 -> Ty<'tcx>
     {
-        let input_args = input_tys.iter().map(|ty| *ty).collect();
+        let input_args = input_tys.iter().cloned().collect();
         ty::mk_bare_fn(self.infcx.tcx,
                        None,
                        self.infcx.tcx.mk_bare_fn(ty::BareFnTy {
@@ -278,7 +278,7 @@ pub fn t_pair(&self, ty1: Ty<'tcx>, ty2: Ty<'tcx>) -> Ty<'tcx> {
 
     pub fn t_param(&self, space: subst::ParamSpace, index: u32) -> Ty<'tcx> {
         let name = format!("T{}", index);
-        ty::mk_param(self.infcx.tcx, space, index, token::intern(&name[]))
+        ty::mk_param(self.infcx.tcx, space, index, token::intern(&name[..]))
     }
 
     pub fn re_early_bound(&self,
index d3555e4c0436354055399d04ab1cbb2f58995c97..14a99026aac8ac18c8e06b377e68981ca534f52b 100644 (file)
@@ -30,7 +30,7 @@ impl ArchiveRO {
     /// raised.
     pub fn open(dst: &Path) -> Option<ArchiveRO> {
         unsafe {
-            let s = CString::from_slice(dst.as_vec());
+            let s = CString::new(dst.as_vec()).unwrap();
             let ar = ::LLVMRustOpenArchive(s.as_ptr());
             if ar.is_null() {
                 None
@@ -44,7 +44,7 @@ pub fn open(dst: &Path) -> Option<ArchiveRO> {
     pub fn read<'a>(&'a self, file: &str) -> Option<&'a [u8]> {
         unsafe {
             let mut size = 0 as libc::size_t;
-            let file = CString::from_slice(file.as_bytes());
+            let file = CString::new(file).unwrap();
             let ptr = ::LLVMRustArchiveReadSection(self.ptr, file.as_ptr(),
                                                    &mut size);
             if ptr.is_null() {
index aa90d7c851ba62f8b6c75e9f38be8bb081dcd463..09a187befb2130ec01ccb05fb84f16265d300e86 100644 (file)
@@ -25,7 +25,6 @@
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(hash)]
 #![feature(int_uint)]
 #![feature(libc)]
 #![feature(link_args)]
@@ -2149,7 +2148,7 @@ fn drop(&mut self) {
 }
 
 pub fn mk_target_data(string_rep: &str) -> TargetData {
-    let string_rep = CString::from_slice(string_rep.as_bytes());
+    let string_rep = CString::new(string_rep).unwrap();
     TargetData {
         lltd: unsafe { LLVMCreateTargetData(string_rep.as_ptr()) }
     }
index 96e146fc894f98cddc149c6f850e45546b3519c6..5662a74a53d34d087f06eae47370427c8e01d1e0 100644 (file)
@@ -585,10 +585,10 @@ fn report_error(&self, result: CheckResult) -> bool {
         match result {
             None => true,
             Some((span, msg, note)) => {
-                self.tcx.sess.span_err(span, &msg[]);
+                self.tcx.sess.span_err(span, &msg[..]);
                 match note {
                     Some((span, msg)) => {
-                        self.tcx.sess.span_note(span, &msg[])
+                        self.tcx.sess.span_note(span, &msg[..])
                     }
                     None => {},
                 }
@@ -690,7 +690,7 @@ fn check_field(&mut self,
             UnnamedField(idx) => format!("field #{} of {} is private",
                                          idx + 1, struct_desc),
         };
-        self.tcx.sess.span_err(span, &msg[]);
+        self.tcx.sess.span_err(span, &msg[..]);
     }
 
     // Given the ID of a method, checks to ensure it's in scope.
index 874c8f2a9402df38653c04fcf0d7389fdb48ca46..333d32d76b6d5fc85c8f63ea874eec047c5a46e5 100644 (file)
@@ -20,7 +20,6 @@
 #![feature(alloc)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(hash)]
 #![feature(int_uint)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
@@ -1072,7 +1071,7 @@ fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
                                           &import_directive.module_path[],
                                           import_directive.subclass),
                                       help);
-                    self.resolve_error(span, &msg[]);
+                    self.resolve_error(span, &msg[..]);
                 }
                 Indeterminate => break, // Bail out. We'll come around next time.
                 Success(()) => () // Good. Continue.
@@ -1102,7 +1101,7 @@ fn path_names_to_string(&self, path: &Path) -> String {
                                         .iter()
                                         .map(|seg| seg.identifier.name)
                                         .collect();
-        self.names_to_string(&names[])
+        self.names_to_string(&names[..])
     }
 
     fn import_directive_subclass_to_string(&mut self,
@@ -1166,7 +1165,7 @@ fn resolve_import_for_module(&mut self,
         let module_path = &import_directive.module_path;
 
         debug!("(resolving import for module) resolving import `{}::...` in `{}`",
-               self.names_to_string(&module_path[]),
+               self.names_to_string(&module_path[..]),
                self.module_to_string(&*module_));
 
         // First, resolve the module path for the directive, if necessary.
@@ -1175,7 +1174,7 @@ fn resolve_import_for_module(&mut self,
             Some((self.graph_root.get_module(), LastMod(AllPublic)))
         } else {
             match self.resolve_module_path(module_.clone(),
-                                           &module_path[],
+                                           &module_path[..],
                                            DontUseLexicalScope,
                                            import_directive.span,
                                            ImportSearch) {
@@ -1768,7 +1767,7 @@ fn check_for_conflicting_import(&mut self,
                                     ValueNS => "value",
                                   },
                                   &token::get_name(name));
-                span_err!(self.session, import_span, E0252, "{}", &msg[]);
+                span_err!(self.session, import_span, E0252, "{}", &msg[..]);
             }
             Some(_) | None => {}
         }
@@ -1783,7 +1782,7 @@ fn check_that_import_is_importable(&mut self,
         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[]);
+            span_err!(self.session, import_span, E0253, "{}", &msg[..]);
         }
     }
 
@@ -1804,7 +1803,7 @@ fn check_for_conflicts_between_imports_and_items(&mut self,
                                        crate in this module \
                                        (maybe you meant `use {0}::*`?)",
                                       &token::get_name(name));
-                    span_err!(self.session, import_span, E0254, "{}", &msg[]);
+                    span_err!(self.session, import_span, E0254, "{}", &msg[..]);
                 }
                 Some(_) | None => {}
             }
@@ -1826,7 +1825,7 @@ fn check_for_conflicts_between_imports_and_items(&mut self,
                     let msg = format!("import `{}` conflicts with value \
                                        in this module",
                                       &token::get_name(name));
-                    span_err!(self.session, import_span, E0255, "{}", &msg[]);
+                    span_err!(self.session, import_span, E0255, "{}", &msg[..]);
                     if let Some(span) = value.value_span {
                         self.session.span_note(span,
                                                "conflicting value here");
@@ -1844,7 +1843,7 @@ fn check_for_conflicts_between_imports_and_items(&mut self,
                             let msg = format!("import `{}` conflicts with type in \
                                                this module",
                                               &token::get_name(name));
-                            span_err!(self.session, import_span, E0256, "{}", &msg[]);
+                            span_err!(self.session, import_span, E0256, "{}", &msg[..]);
                             if let Some(span) = ty.type_span {
                                 self.session.span_note(span,
                                                        "note conflicting type here")
@@ -1857,7 +1856,7 @@ fn check_for_conflicts_between_imports_and_items(&mut self,
                                         let msg = format!("inherent implementations \
                                                            are only allowed on types \
                                                            defined in the current module");
-                                        span_err!(self.session, span, E0257, "{}", &msg[]);
+                                        span_err!(self.session, span, E0257, "{}", &msg[..]);
                                         self.session.span_note(import_span,
                                                                "import from other module here")
                                     }
@@ -1866,7 +1865,7 @@ fn check_for_conflicts_between_imports_and_items(&mut self,
                                     let msg = format!("import `{}` conflicts with existing \
                                                        submodule",
                                                       &token::get_name(name));
-                                    span_err!(self.session, import_span, E0258, "{}", &msg[]);
+                                    span_err!(self.session, import_span, E0258, "{}", &msg[..]);
                                     if let Some(span) = ty.type_span {
                                         self.session.span_note(span,
                                                                "note conflicting module here")
@@ -1920,18 +1919,15 @@ fn resolve_module_path_from_root(&mut self,
                                 -> ResolveResult<(Rc<Module>, LastPrivate)> {
         fn search_parent_externals(needle: Name, module: &Rc<Module>)
                                 -> Option<Rc<Module>> {
-            module.external_module_children.borrow()
-                                            .get(&needle).cloned()
-                                            .map(|_| module.clone())
-                                            .or_else(|| {
-                match module.parent_link.clone() {
-                    ModuleParentLink(parent, _) => {
-                        search_parent_externals(needle,
-                                                &parent.upgrade().unwrap())
+            match module.external_module_children.borrow().get(&needle) {
+                Some(_) => Some(module.clone()),
+                None => match module.parent_link {
+                    ModuleParentLink(ref parent, _) => {
+                        search_parent_externals(needle, &parent.upgrade().unwrap())
                     }
                    _ => None
                 }
-            })
+            }
         }
 
         let mut search_module = module_;
@@ -1953,7 +1949,7 @@ fn search_parent_externals(needle: Name, module: &Rc<Module>)
                     let segment_name = token::get_name(name);
                     let module_name = self.module_to_string(&*search_module);
                     let mut span = span;
-                    let msg = if "???" == &module_name[] {
+                    let msg = if "???" == &module_name[..] {
                         span.hi = span.lo + Pos::from_usize(segment_name.len());
 
                         match search_parent_externals(name,
@@ -2066,7 +2062,7 @@ fn resolve_module_path(&mut self,
         match module_prefix_result {
             Failed(None) => {
                 let mpath = self.names_to_string(module_path);
-                let mpath = &mpath[];
+                let mpath = &mpath[..];
                 match mpath.rfind(':') {
                     Some(idx) => {
                         let msg = format!("Could not find `{}` in `{}`",
@@ -2369,11 +2365,11 @@ fn resolve_module_prefix(&mut self,
         let mut containing_module;
         let mut i;
         let first_module_path_string = token::get_name(module_path[0]);
-        if "self" == &first_module_path_string[] {
+        if "self" == &first_module_path_string[..] {
             containing_module =
                 self.get_nearest_normal_module_parent_or_self(module_);
             i = 1;
-        } else if "super" == &first_module_path_string[] {
+        } else if "super" == &first_module_path_string[..] {
             containing_module =
                 self.get_nearest_normal_module_parent_or_self(module_);
             i = 0;  // We'll handle `super` below.
@@ -2384,7 +2380,7 @@ fn resolve_module_prefix(&mut self,
         // Now loop through all the `super`s we find.
         while i < module_path.len() {
             let string = token::get_name(module_path[i]);
-            if "super" != &string[] {
+            if "super" != &string[..] {
                 break
             }
             debug!("(resolving module prefix) resolving `super` at {}",
@@ -2515,7 +2511,7 @@ fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
             } else {
                 let err = format!("unresolved import (maybe you meant `{}::*`?)",
                                   sn);
-                self.resolve_error((*imports)[index].span, &err[]);
+                self.resolve_error((*imports)[index].span, &err[..]);
             }
         }
 
@@ -2853,7 +2849,7 @@ fn resolve_item(&mut self, item: &Item) {
                                             generics,
                                             implemented_traits,
                                             &**self_type,
-                                            &impl_items[]);
+                                            &impl_items[..]);
             }
 
             ItemTrait(_, ref generics, ref bounds, ref trait_items) => {
@@ -3196,7 +3192,7 @@ fn resolve_trait_reference(&mut self,
                 };
 
                 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
-                self.resolve_error(trait_reference.path.span, &msg[]);
+                self.resolve_error(trait_reference.path.span, &msg[..]);
             }
             Some(def) => {
                 match def {
@@ -3624,7 +3620,7 @@ fn resolve_type(&mut self, ty: &Ty) {
                     None => {
                         let msg = format!("use of undeclared type name `{}`",
                                           self.path_names_to_string(path));
-                        self.resolve_error(ty.span, &msg[]);
+                        self.resolve_error(ty.span, &msg[..]);
                     }
                 }
             }
@@ -3825,7 +3821,7 @@ struct or enum variant",
                                     def: {:?}", result);
                             let msg = format!("`{}` does not name a structure",
                                               self.path_names_to_string(path));
-                            self.resolve_error(path.span, &msg[]);
+                            self.resolve_error(path.span, &msg[..]);
                         }
                     }
                 }
@@ -4082,7 +4078,7 @@ fn resolve_module_relative_path(&mut self,
         let last_private;
         let module = self.current_module.clone();
         match self.resolve_module_path(module,
-                                       &module_path[],
+                                       &module_path[..],
                                        UseLexicalScope,
                                        path.span,
                                        PathSearch) {
@@ -4140,7 +4136,7 @@ fn resolve_crate_relative_path(&mut self,
         let containing_module;
         let last_private;
         match self.resolve_module_path_from_root(root_module,
-                                                 &module_path[],
+                                                 &module_path[..],
                                                  0,
                                                  path.span,
                                                  PathSearch,
@@ -4150,7 +4146,7 @@ fn resolve_crate_relative_path(&mut self,
                     Some((span, msg)) => (span, msg),
                     None => {
                         let msg = format!("Use of undeclared module `::{}`",
-                                          self.names_to_string(&module_path[]));
+                                          self.names_to_string(&module_path[..]));
                         (path.span, msg)
                     }
                 };
@@ -4309,7 +4305,7 @@ fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name])
                 }
             } else {
                 match this.resolve_module_path(root,
-                                                &name_path[],
+                                                &name_path[..],
                                                 UseLexicalScope,
                                                 span,
                                                 PathSearch) {
@@ -4347,7 +4343,7 @@ fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name])
         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[]) {
+        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);
@@ -4568,7 +4564,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
                                 def: {:?}", result);
                         let msg = format!("`{}` does not name a structure",
                                           self.path_names_to_string(path));
-                        self.resolve_error(path.span, &msg[]);
+                        self.resolve_error(path.span, &msg[..]);
                     }
                 }
 
index 9f26e9182ab1e5d04e820dd4fa9bfba46f71ce46..ef849bb3dca056348147adbf6a0a154e5c9d2dd4 100644 (file)
@@ -127,7 +127,7 @@ pub fn find_crate_name(sess: Option<&Session>,
                        attrs: &[ast::Attribute],
                        input: &Input) -> String {
     let validate = |s: String, span: Option<Span>| {
-        creader::validate_crate_name(sess, &s[], span);
+        creader::validate_crate_name(sess, &s[..], span);
         s
     };
 
@@ -141,11 +141,11 @@ pub fn find_crate_name(sess: Option<&Session>,
     if let Some(sess) = sess {
         if let Some(ref s) = sess.opts.crate_name {
             if let Some((attr, ref name)) = attr_crate_name {
-                if *s != &name[] {
+                if *s != &name[..] {
                     let msg = format!("--crate-name and #[crate_name] are \
                                        required to match, but `{}` != `{}`",
                                       s, name);
-                    sess.span_err(attr.span, &msg[]);
+                    sess.span_err(attr.span, &msg[..]);
                 }
             }
             return validate(s.clone(), None);
@@ -195,7 +195,7 @@ fn symbol_hash<'tcx>(tcx: &ty::ctxt<'tcx>,
     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(&meta[..]);
     }
     symbol_hasher.input_str("-");
     symbol_hasher.input_str(&encoder::encoded_ty(tcx, t)[]);
@@ -262,7 +262,7 @@ pub fn sanitize(s: &str) -> String {
     if result.len() > 0 &&
         result.as_bytes()[0] != '_' as u8 &&
         ! (result.as_bytes()[0] as char).is_xid_start() {
-        return format!("_{}", &result[]);
+        return format!("_{}", &result[..]);
     }
 
     return result;
@@ -331,17 +331,17 @@ pub fn mangle_exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, path: PathEl
     hash.push(EXTRA_CHARS.as_bytes()[extra2] as char);
     hash.push(EXTRA_CHARS.as_bytes()[extra3] as char);
 
-    exported_name(path, &hash[])
+    exported_name(path, &hash[..])
 }
 
 pub fn mangle_internal_name_by_type_and_seq<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                                       t: Ty<'tcx>,
                                                       name: &str) -> String {
     let s = ppaux::ty_to_string(ccx.tcx(), t);
-    let path = [PathName(token::intern(&s[])),
+    let path = [PathName(token::intern(&s[..])),
                 gensym_name(name)];
     let hash = get_symbol_hash(ccx, t);
-    mangle(path.iter().cloned(), Some(&hash[]))
+    mangle(path.iter().cloned(), Some(&hash[..]))
 }
 
 pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> String {
@@ -541,7 +541,7 @@ fn link_rlib<'a>(sess: &'a Session,
     for &(ref l, kind) in &*sess.cstore.get_used_libraries().borrow() {
         match kind {
             cstore::NativeStatic => {
-                ab.add_native_library(&l[]).unwrap();
+                ab.add_native_library(&l[..]).unwrap();
             }
             cstore::NativeFramework | cstore::NativeUnknown => {}
         }
@@ -619,7 +619,7 @@ fn link_rlib<'a>(sess: &'a Session,
                                                  e)[])
                 };
 
-                let bc_data_deflated = match flate::deflate_bytes(&bc_data[]) {
+                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())[])
@@ -678,7 +678,7 @@ fn write_rlib_bytecode_object_v1<T: Writer>(writer: &mut T,
     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(&bc_data_deflated[..]) };
 
     let number_of_bytes_written_so_far =
         RLIB_BYTECODE_OBJECT_MAGIC.len() +                // magic id
@@ -733,7 +733,7 @@ fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) {
                 continue
             }
         };
-        ab.add_rlib(&p, &name[], sess.lto()).unwrap();
+        ab.add_rlib(&p, &name[..], sess.lto()).unwrap();
 
         let native_libs = csearch::get_native_libraries(&sess.cstore, cnum);
         all_native_libs.extend(native_libs.into_iter());
@@ -769,7 +769,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
 
     // The invocations of cc share some flags across platforms
     let pname = get_cc_prog(sess);
-    let mut cmd = Command::new(&pname[]);
+    let mut cmd = Command::new(&pname[..]);
 
     cmd.args(&sess.target.target.options.pre_link_args[]);
     link_args(&mut cmd, sess, dylib, tmpdir.path(),
@@ -798,7 +798,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
                 sess.note(&format!("{:?}", &cmd)[]);
                 let mut output = prog.error.clone();
                 output.push_all(&prog.output[]);
-                sess.note(str::from_utf8(&output[]).unwrap());
+                sess.note(str::from_utf8(&output[..]).unwrap());
                 sess.abort_if_errors();
             }
             debug!("linker stderr:\n{}", String::from_utf8(prog.error).unwrap());
@@ -868,7 +868,7 @@ fn link_args(cmd: &mut Command,
 
             let mut v = b"-Wl,-force_load,".to_vec();
             v.push_all(morestack.as_vec());
-            cmd.arg(&v[]);
+            cmd.arg(&v[..]);
         } else {
             cmd.args(&["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]);
         }
@@ -993,7 +993,7 @@ fn link_args(cmd: &mut Command,
             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[]);
+                cmd.arg(&v[..]);
             }
         } else {
             cmd.arg("-shared");
@@ -1029,7 +1029,7 @@ fn link_args(cmd: &mut Command,
     // 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(&used_link_args[]);
+    cmd.args(&used_link_args[..]);
 }
 
 // # Native library linking
@@ -1086,14 +1086,14 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
         } else {
             // -force_load is the OSX equivalent of --whole-archive, but it
             // involves passing the full path to the library to link.
-            let lib = archive::find_library(&l[],
+            let lib = archive::find_library(&l[..],
                                             &sess.target.target.options.staticlib_prefix,
                                             &sess.target.target.options.staticlib_suffix,
-                                            &search_path[],
+                                            &search_path[..],
                                             &sess.diagnostic().handler);
             let mut v = b"-Wl,-force_load,".to_vec();
             v.push_all(lib.as_vec());
-            cmd.arg(&v[]);
+            cmd.arg(&v[..]);
         }
     }
     if takes_hints {
@@ -1106,7 +1106,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
                 cmd.arg(format!("-l{}", l));
             }
             cstore::NativeFramework => {
-                cmd.arg("-framework").arg(&l[]);
+                cmd.arg("-framework").arg(&l[..]);
             }
             cstore::NativeStatic => unreachable!(),
         }
@@ -1248,7 +1248,7 @@ fn add_dynamic_crate(cmd: &mut Command, sess: &Session, cratepath: Path) {
 
         let mut v = "-l".as_bytes().to_vec();
         v.push_all(unlib(&sess.target, cratepath.filestem().unwrap()));
-        cmd.arg(&v[]);
+        cmd.arg(&v[..]);
     }
 }
 
@@ -1290,7 +1290,7 @@ fn add_upstream_native_libraries(cmd: &mut Command, sess: &Session) {
                 }
                 cstore::NativeFramework => {
                     cmd.arg("-framework");
-                    cmd.arg(&lib[]);
+                    cmd.arg(&lib[..]);
                 }
                 cstore::NativeStatic => {
                     sess.bug("statics shouldn't be propagated");
index 0331b6171f36ca15f503b08d1cb3f492fc8b9120..0a0f2a9c18627adeb821ca15e03c7f21b881119d 100644 (file)
@@ -132,7 +132,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
                                                         bc_decoded.len() as libc::size_t) {
                     write::llvm_err(sess.diagnostic().handler(),
                                     format!("failed to load bc of `{}`",
-                                            &name[]));
+                                            &name[..]));
                 }
             });
         }
@@ -140,7 +140,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
 
     // Internalize everything but the reachable symbols of the current module
     let cstrs: Vec<CString> = reachable.iter().map(|s| {
-        CString::from_slice(s.as_bytes())
+        CString::new(s.clone()).unwrap()
     }).collect();
     let arr: Vec<*const libc::c_char> = cstrs.iter().map(|c| c.as_ptr()).collect();
     let ptr = arr.as_ptr();
index 9934d9993d61df0b2b95e6bacc048fd181aa616d..86b720d3fc171191f451bb9bc31a32e4eedef4ef 100644 (file)
@@ -22,7 +22,7 @@
 use syntax::diagnostic;
 use syntax::diagnostic::{Emitter, Handler, Level, mk_handler};
 
-use std::ffi::{self, CString};
+use std::ffi::{CStr, CString};
 use std::old_io::Command;
 use std::old_io::fs;
 use std::iter::Unfold;
@@ -47,14 +47,14 @@ pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! {
     unsafe {
         let cstr = llvm::LLVMRustGetLastError();
         if cstr == ptr::null() {
-            handler.fatal(&msg[]);
+            handler.fatal(&msg[..]);
         } else {
-            let err = ffi::c_str_to_bytes(&cstr);
+            let err = CStr::from_ptr(cstr).to_bytes();
             let err = String::from_utf8_lossy(err).to_string();
             libc::free(cstr as *mut _);
             handler.fatal(&format!("{}: {}",
-                                  &msg[],
-                                  &err[])[]);
+                                  &msg[..],
+                                  &err[..])[]);
         }
     }
 }
@@ -67,7 +67,7 @@ pub fn write_output_file(
         output: &Path,
         file_type: llvm::FileType) {
     unsafe {
-        let output_c = CString::from_slice(output.as_vec());
+        let output_c = CString::new(output.as_vec()).unwrap();
         let result = llvm::LLVMRustWriteOutputFile(
                 target, pm, m, output_c.as_ptr(), file_type);
         if !result {
@@ -105,7 +105,7 @@ fn dump(&mut self, handler: &Handler) {
                 Some(ref code) => {
                     handler.emit_with_code(None,
                                            &diag.msg[],
-                                           &code[],
+                                           &code[..],
                                            diag.lvl);
                 },
                 None => {
@@ -165,7 +165,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[],
+        Some(ref s) => &s[..],
         None => &sess.target.target.options.relocation_model[]
     };
     let reloc_model = match reloc_model_arg {
@@ -198,7 +198,7 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
     let fdata_sections = ffunction_sections;
 
     let code_model_arg = match sess.opts.cg.code_model {
-        Some(ref s) => &s[],
+        Some(ref s) => &s[..],
         None => &sess.target.target.options.code_model[]
     };
 
@@ -221,13 +221,13 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
     let triple = &sess.target.target.llvm_target[];
 
     let tm = unsafe {
-        let triple = CString::from_slice(triple.as_bytes());
+        let triple = CString::new(triple.as_bytes()).unwrap();
         let cpu = match sess.opts.cg.target_cpu {
             Some(ref s) => &**s,
             None => &*sess.target.target.options.cpu
         };
-        let cpu = CString::from_slice(cpu.as_bytes());
-        let features = CString::from_slice(target_feature(sess).as_bytes());
+        let cpu = CString::new(cpu.as_bytes()).unwrap();
+        let features = CString::new(target_feature(sess).as_bytes()).unwrap();
         llvm::LLVMRustCreateTargetMachine(
             triple.as_ptr(), cpu.as_ptr(), features.as_ptr(),
             code_model,
@@ -365,7 +365,7 @@ struct HandlerFreeVars<'a> {
     let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s))
         .expect("non-UTF8 SMDiagnostic");
 
-    report_inline_asm(cgcx, &msg[], cookie);
+    report_inline_asm(cgcx, &msg[..], cookie);
 }
 
 unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) {
@@ -380,7 +380,7 @@ struct HandlerFreeVars<'a> {
         }
 
         llvm::diagnostic::Optimization(opt) => {
-            let pass_name = str::from_utf8(ffi::c_str_to_bytes(&opt.pass_name))
+            let pass_name = str::from_utf8(CStr::from_ptr(opt.pass_name).to_bytes())
                                 .ok()
                                 .expect("got a non-UTF8 pass name from LLVM");
             let enabled = match cgcx.remark {
@@ -424,7 +424,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::from_slice(out.as_vec());
+        let out = CString::new(out.as_vec()).unwrap();
         llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
     }
 
@@ -440,7 +440,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
             // If we're verifying or linting, add them to the function pass
             // manager.
             let addpass = |pass: &str| {
-                let pass = CString::from_slice(pass.as_bytes());
+                let pass = CString::new(pass).unwrap();
                 llvm::LLVMRustAddPass(fpm, pass.as_ptr())
             };
             if !config.no_verify { assert!(addpass("verify")); }
@@ -453,7 +453,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
             }
 
             for pass in &config.passes {
-                let pass = CString::from_slice(pass.as_bytes());
+                let pass = CString::new(pass.clone()).unwrap();
                 if !llvm::LLVMRustAddPass(mpm, pass.as_ptr()) {
                     cgcx.handler.warn(&format!("unknown pass {:?}, ignoring", pass));
                 }
@@ -477,7 +477,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::from_slice(out.as_vec());
+                        let out = CString::new(out.as_vec()).unwrap();
                         llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
                     }
                 },
@@ -511,7 +511,7 @@ unsafe fn with_codegen<F>(tm: TargetMachineRef,
     if config.emit_bc {
         let ext = format!("{}.bc", name_extra);
         let out = output_names.with_extension(&ext);
-        let out = CString::from_slice(out.as_vec());
+        let out = CString::new(out.as_vec()).unwrap();
         llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
     }
 
@@ -519,7 +519,7 @@ unsafe fn with_codegen<F>(tm: TargetMachineRef,
         if config.emit_ir {
             let ext = format!("{}.ll", name_extra);
             let out = output_names.with_extension(&ext);
-            let out = CString::from_slice(out.as_vec());
+            let out = CString::new(out.as_vec()).unwrap();
             with_codegen(tm, llmod, config.no_builtins, |cpm| {
                 llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr());
             })
@@ -711,7 +711,7 @@ pub fn run_passes(sess: &Session,
             };
 
         let pname = get_cc_prog(sess);
-        let mut cmd = Command::new(&pname[]);
+        let mut cmd = Command::new(&pname[..]);
 
         cmd.args(&sess.target.target.options.pre_link_args[]);
         cmd.arg("-nostdlib");
@@ -829,12 +829,12 @@ pub fn run_passes(sess: &Session,
         for i in 0..trans.modules.len() {
             if modules_config.emit_obj {
                 let ext = format!("{}.o", i);
-                remove(sess, &crate_output.with_extension(&ext[]));
+                remove(sess, &crate_output.with_extension(&ext[..]));
             }
 
             if modules_config.emit_bc && !keep_numbered_bitcode {
                 let ext = format!("{}.bc", i);
-                remove(sess, &crate_output.with_extension(&ext[]));
+                remove(sess, &crate_output.with_extension(&ext[..]));
             }
         }
 
@@ -960,7 +960,7 @@ fn run_work_multithreaded(sess: &Session,
 
 pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
     let pname = get_cc_prog(sess);
-    let mut cmd = Command::new(&pname[]);
+    let mut cmd = Command::new(&pname[..]);
 
     cmd.arg("-c").arg("-o").arg(outputs.path(config::OutputTypeObject))
                            .arg(outputs.temp_path(config::OutputTypeAssembly));
@@ -975,7 +975,7 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
                 sess.note(&format!("{:?}", &cmd)[]);
                 let mut note = prog.error.clone();
                 note.push_all(&prog.output[]);
-                sess.note(str::from_utf8(&note[]).unwrap());
+                sess.note(str::from_utf8(&note[..]).unwrap());
                 sess.abort_if_errors();
             }
         },
@@ -1004,7 +1004,7 @@ unsafe fn configure_llvm(sess: &Session) {
     let mut llvm_args = Vec::new();
     {
         let mut add = |arg: &str| {
-            let s = CString::from_slice(arg.as_bytes());
+            let s = CString::new(arg).unwrap();
             llvm_args.push(s.as_ptr());
             llvm_c_strs.push(s);
         };
index 4606200d058c6e06d43d8fe19a6f1217c4658352..3deca436a1f903be1c63edf3aaed4cfe1639fc79 100644 (file)
@@ -28,7 +28,6 @@
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(hash)]
 #![feature(int_uint)]
 #![feature(old_io)]
 #![feature(env)]
index cdcd917ee5eb408db88228e3e14ad9bc86428728..8d2a2d51ee42366b6f78d8262abf701d8966481a 100644 (file)
@@ -155,7 +155,7 @@ fn write_sub_paths(&mut self, path: &ast::Path, global: bool) {
             };
             self.fmt.sub_mod_ref_str(path.span,
                                      *span,
-                                     &qualname[],
+                                     &qualname[..],
                                      self.cur_scope);
         }
     }
@@ -178,7 +178,7 @@ fn write_sub_paths_truncated(&mut self, path: &ast::Path, global: bool) {
             };
             self.fmt.sub_mod_ref_str(path.span,
                                      *span,
-                                     &qualname[],
+                                     &qualname[..],
                                      self.cur_scope);
         }
     }
@@ -197,7 +197,7 @@ fn write_sub_path_trait_truncated(&mut self, path: &ast::Path) {
         let (ref span, ref qualname) = sub_paths[len-2];
         self.fmt.sub_type_ref_str(path.span,
                                   *span,
-                                  &qualname[]);
+                                  &qualname[..]);
 
         // write the other sub-paths
         if len <= 2 {
@@ -207,7 +207,7 @@ fn write_sub_path_trait_truncated(&mut self, path: &ast::Path) {
         for &(ref span, ref qualname) in sub_paths {
             self.fmt.sub_mod_ref_str(path.span,
                                      *span,
-                                     &qualname[],
+                                     &qualname[..],
                                      self.cur_scope);
         }
     }
@@ -280,7 +280,7 @@ fn process_formals(&mut self, formals: &Vec<ast::Arg>, qualname: &str) {
                                     id,
                                     qualname,
                                     &path_to_string(p)[],
-                                    &typ[]);
+                                    &typ[..]);
             }
             self.collected_paths.clear();
         }
@@ -356,7 +356,7 @@ fn process_method(&mut self, method: &ast::Method) {
         };
 
         let qualname = format!("{}::{}", qualname, &get_ident(method.pe_ident()));
-        let qualname = &qualname[];
+        let qualname = &qualname[..];
 
         // record the decl for this def (if it has one)
         let decl_id = ty::trait_item_of_item(&self.analysis.ty_cx,
@@ -436,9 +436,9 @@ fn process_struct_field_def(&mut self,
                     Some(sub_span) => self.fmt.field_str(field.span,
                                                          Some(sub_span),
                                                          field.node.id,
-                                                         &name[],
-                                                         &qualname[],
-                                                         &typ[],
+                                                         &name[..],
+                                                         &qualname[..],
+                                                         &typ[..],
                                                          scope_id),
                     None => self.sess.span_bug(field.span,
                                                &format!("Could not find sub-span for field {}",
@@ -470,7 +470,7 @@ fn process_generic_params(&mut self,
             self.fmt.typedef_str(full_span,
                                  Some(*param_ss),
                                  param.id,
-                                 &name[],
+                                 &name[..],
                                  "");
         }
         self.visit_generics(generics);
@@ -487,10 +487,10 @@ fn process_fn(&mut self,
         self.fmt.fn_str(item.span,
                         sub_span,
                         item.id,
-                        &qualname[],
+                        &qualname[..],
                         self.cur_scope);
 
-        self.process_formals(&decl.inputs, &qualname[]);
+        self.process_formals(&decl.inputs, &qualname[..]);
 
         // walk arg and return types
         for arg in &decl.inputs {
@@ -504,7 +504,7 @@ fn process_fn(&mut self,
         // walk the body
         self.nest(item.id, |v| v.visit_block(&*body));
 
-        self.process_generic_params(ty_params, item.span, &qualname[], item.id);
+        self.process_generic_params(ty_params, item.span, &qualname[..], item.id);
     }
 
     fn process_static(&mut self,
@@ -526,8 +526,8 @@ fn process_static(&mut self,
                             sub_span,
                             item.id,
                             &get_ident(item.ident),
-                            &qualname[],
-                            &value[],
+                            &qualname[..],
+                            &value[..],
                             &ty_to_string(&*typ)[],
                             self.cur_scope);
 
@@ -549,7 +549,7 @@ fn process_const(&mut self,
                             sub_span,
                             item.id,
                             &get_ident(item.ident),
-                            &qualname[],
+                            &qualname[..],
                             "",
                             &ty_to_string(&*typ)[],
                             self.cur_scope);
@@ -575,17 +575,17 @@ fn process_struct(&mut self,
                             sub_span,
                             item.id,
                             ctor_id,
-                            &qualname[],
+                            &qualname[..],
                             self.cur_scope,
-                            &val[]);
+                            &val[..]);
 
         // fields
         for field in &def.fields {
-            self.process_struct_field_def(field, &qualname[], item.id);
+            self.process_struct_field_def(field, &qualname[..], item.id);
             self.visit_ty(&*field.node.ty);
         }
 
-        self.process_generic_params(ty_params, item.span, &qualname[], item.id);
+        self.process_generic_params(ty_params, item.span, &qualname[..], item.id);
     }
 
     fn process_enum(&mut self,
@@ -598,9 +598,9 @@ fn process_enum(&mut self,
             Some(sub_span) => self.fmt.enum_str(item.span,
                                                 Some(sub_span),
                                                 item.id,
-                                                &enum_name[],
+                                                &enum_name[..],
                                                 self.cur_scope,
-                                                &val[]),
+                                                &val[..]),
             None => self.sess.span_bug(item.span,
                                        &format!("Could not find subspan for enum {}",
                                                enum_name)[]),
@@ -619,9 +619,9 @@ fn process_enum(&mut self,
                                                self.span.span_for_first_ident(variant.span),
                                                variant.node.id,
                                                name,
-                                               &qualname[],
-                                               &enum_name[],
-                                               &val[],
+                                               &qualname[..],
+                                               &enum_name[..],
+                                               &val[..],
                                                item.id);
                     for arg in args {
                         self.visit_ty(&*arg.ty);
@@ -637,9 +637,9 @@ fn process_enum(&mut self,
                         self.span.span_for_first_ident(variant.span),
                         variant.node.id,
                         ctor_id,
-                        &qualname[],
-                        &enum_name[],
-                        &val[],
+                        &qualname[..],
+                        &enum_name[..],
+                        &val[..],
                         item.id);
 
                     for field in &struct_def.fields {
@@ -650,7 +650,7 @@ fn process_enum(&mut self,
             }
         }
 
-        self.process_generic_params(ty_params, item.span, &enum_name[], item.id);
+        self.process_generic_params(ty_params, item.span, &enum_name[..], item.id);
     }
 
     fn process_impl(&mut self,
@@ -724,9 +724,9 @@ fn process_trait(&mut self,
         self.fmt.trait_str(item.span,
                            sub_span,
                            item.id,
-                           &qualname[],
+                           &qualname[..],
                            self.cur_scope,
-                           &val[]);
+                           &val[..]);
 
         // super-traits
         for super_bound in &**trait_refs {
@@ -758,7 +758,7 @@ fn process_trait(&mut self,
         }
 
         // walk generics and methods
-        self.process_generic_params(generics, item.span, &qualname[], item.id);
+        self.process_generic_params(generics, item.span, &qualname[..], item.id);
         for method in methods {
             self.visit_trait_item(method)
         }
@@ -776,9 +776,9 @@ fn process_mod(&mut self,
         self.fmt.mod_str(item.span,
                          sub_span,
                          item.id,
-                         &qualname[],
+                         &qualname[..],
                          self.cur_scope,
-                         &filename[]);
+                         &filename[..]);
 
         self.nest(item.id, |v| visit::walk_mod(v, m));
     }
@@ -990,7 +990,7 @@ fn process_method_call(&mut self,
                                self.cur_scope);
 
         // walk receiver and args
-        visit::walk_exprs(self, &args[]);
+        visit::walk_exprs(self, &args[..]);
     }
 
     fn process_pat(&mut self, p:&ast::Pat) {
@@ -1164,7 +1164,7 @@ fn visit_item(&mut self, item: &ast::Item) {
                                           item.id,
                                           cnum,
                                           name,
-                                          &location[],
+                                          &location[..],
                                           self.cur_scope);
             }
             ast::ItemFn(ref decl, _, _, ref ty_params, ref body) =>
@@ -1196,8 +1196,8 @@ fn visit_item(&mut self, item: &ast::Item) {
                 self.fmt.typedef_str(item.span,
                                      sub_span,
                                      item.id,
-                                     &qualname[],
-                                     &value[]);
+                                     &qualname[..],
+                                     &value[..]);
 
                 self.visit_ty(&**ty);
                 self.process_generic_params(ty_params, item.span, &qualname, item.id);
@@ -1260,7 +1260,7 @@ fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
                 };
 
                 qualname.push_str(&get_ident(method_type.ident));
-                let qualname = &qualname[];
+                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,
@@ -1401,7 +1401,7 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
 
                 let mut id = String::from_str("$");
                 id.push_str(&ex.id.to_string()[]);
-                self.process_formals(&decl.inputs, &id[]);
+                self.process_formals(&decl.inputs, &id[..]);
 
                 // walk arg and return types
                 for arg in &decl.inputs {
@@ -1464,7 +1464,7 @@ fn visit_arm(&mut self, arm: &ast::Arm) {
                                           Some(p.span),
                                           id,
                                           &path_to_string(p)[],
-                                          &value[],
+                                          &value[..],
                                           "")
                 }
                 def::DefVariant(..) | def::DefTy(..) | def::DefStruct(..) => {
@@ -1520,8 +1520,8 @@ fn visit_local(&mut self, l: &ast::Local) {
                                   sub_span,
                                   id,
                                   &path_to_string(p)[],
-                                  &value[],
-                                  &typ[]);
+                                  &value[..],
+                                  &typ[..]);
         }
         self.collected_paths.clear();
 
@@ -1603,7 +1603,7 @@ pub fn process_crate(sess: &Session,
         cur_scope: 0
     };
 
-    visitor.dump_crate_info(&cratename[], krate);
+    visitor.dump_crate_info(&cratename[..], krate);
 
     visit::walk_crate(&mut visitor, krate);
 }
index 3bd04ed29d4a1139a2a3bc502a6241793931c616..08e36bb1d85bb3eefc504b5c81b7244c7fff5ba5 100644 (file)
@@ -43,7 +43,7 @@ pub fn dump_span(&mut self,
         assert!(self.dump_spans);
         let result = format!("span,kind,{},{},text,\"{}\"\n",
                              kind, su.extent_str(span), escape(su.snippet(span)));
-        self.record(&result[]);
+        self.record(&result[..]);
     }
 }
 
@@ -170,14 +170,14 @@ pub fn make_values_str(&self,
             if s.len() > 1020 {
                 &s[..1020]
             } else {
-                &s[]
+                &s[..]
             }
         });
 
         let pairs = fields.iter().zip(values);
         let strs = pairs.map(|(f, v)| format!(",{},\"{}\"", f, escape(String::from_str(v))));
         Some(strs.fold(String::new(), |mut s, ss| {
-            s.push_str(&ss[]);
+            s.push_str(&ss[..]);
             s
         }))
     }
@@ -205,9 +205,9 @@ pub fn record_without_span(&mut self,
         };
 
         let mut result = String::from_str(label);
-        result.push_str(&values_str[]);
+        result.push_str(&values_str[..]);
         result.push_str("\n");
-        self.recorder.record(&result[]);
+        self.recorder.record(&result[..]);
     }
 
     pub fn record_with_span(&mut self,
@@ -238,7 +238,7 @@ pub fn record_with_span(&mut self,
             None => return,
         };
         let result = format!("{},{}{}\n", label, self.span.extent_str(sub_span), values_str);
-        self.recorder.record(&result[]);
+        self.recorder.record(&result[..]);
     }
 
     pub fn check_and_record(&mut self,
index b0ed6f9e727a2fdf5f64b3050df0b12bf1a66f98..2826afb71a2c23cfcc945a66c908b6c806a7a3c3 100644 (file)
@@ -566,7 +566,7 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>(
         param_env: param_env,
     };
     enter_match(bcx, dm, m, col, val, |pats|
-        check_match::specialize(&mcx, &pats[], &ctor, col, variant_size)
+        check_match::specialize(&mcx, &pats[..], &ctor, col, variant_size)
     )
 }
 
@@ -987,7 +987,7 @@ fn compile_submatch<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             if has_nested_bindings(m, col) {
                 let expanded = expand_nested_bindings(bcx, m, col, val);
                 compile_submatch_continue(bcx,
-                                          &expanded[],
+                                          &expanded[..],
                                           vals,
                                           chk,
                                           col,
@@ -1233,10 +1233,10 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         }
         let opt_ms = enter_opt(opt_cx, pat_id, dm, m, opt, col, size, val);
         let mut opt_vals = unpacked;
-        opt_vals.push_all(&vals_left[]);
+        opt_vals.push_all(&vals_left[..]);
         compile_submatch(opt_cx,
-                         &opt_ms[],
-                         &opt_vals[],
+                         &opt_ms[..],
+                         &opt_vals[..],
                          branch_chk.as_ref().unwrap_or(chk),
                          has_genuine_default);
     }
@@ -1255,8 +1255,8 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             }
             _ => {
                 compile_submatch(else_cx,
-                                 &defaults[],
-                                 &vals_left[],
+                                 &defaults[..],
+                                 &vals_left[..],
                                  chk,
                                  has_genuine_default);
             }
@@ -1468,7 +1468,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
         && arm.pats.last().unwrap().node == ast::PatWild(ast::PatWildSingle)
     });
 
-    compile_submatch(bcx, &matches[], &[discr_datum.val], &chk, has_default);
+    compile_submatch(bcx, &matches[..], &[discr_datum.val], &chk, has_default);
 
     let mut arm_cxs = Vec::new();
     for arm_data in &arm_datas {
@@ -1482,7 +1482,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
         arm_cxs.push(bcx);
     }
 
-    bcx = scope_cx.fcx.join_blocks(match_id, &arm_cxs[]);
+    bcx = scope_cx.fcx.join_blocks(match_id, &arm_cxs[..]);
     return bcx;
 }
 
index ddd720f1e84a8600313b9856dd04a8398c5b7660..eaf6eaa2f089d1273bec3b9f574fa24be70d68dc 100644 (file)
@@ -155,7 +155,7 @@ 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), false)
         }
         ty::ty_struct(def_id, substs) => {
             let fields = ty::lookup_struct_fields(cx.tcx(), def_id);
@@ -167,13 +167,13 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let dtor = ty::ty_dtor(cx.tcx(), def_id).has_drop_flag();
             if dtor { ftys.push(cx.tcx().types.bool); }
 
-            Univariant(mk_struct(cx, &ftys[], packed, t), dtor)
+            Univariant(mk_struct(cx, &ftys[..], packed, t), dtor)
         }
         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), false)
         }
         ty::ty_enum(def_id, substs) => {
             let cases = get_cases(cx.tcx(), def_id, substs);
@@ -187,7 +187,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 // (Typechecking will reject discriminant-sizing attrs.)
                 assert_eq!(hint, attr::ReprAny);
                 let ftys = if dtor { vec!(cx.tcx().types.bool) } else { vec!() };
-                return Univariant(mk_struct(cx, &ftys[], false, t),
+                return Univariant(mk_struct(cx, &ftys[..], false, t),
                                   dtor);
             }
 
@@ -219,7 +219,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 assert_eq!(hint, attr::ReprAny);
                 let mut ftys = cases[0].tys.clone();
                 if dtor { ftys.push(cx.tcx().types.bool); }
-                return Univariant(mk_struct(cx, &ftys[], false, t),
+                return Univariant(mk_struct(cx, &ftys[..], false, t),
                                   dtor);
             }
 
@@ -320,10 +320,10 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 let mut ftys = vec!(ty_of_inttype(cx.tcx(), ity));
                 ftys.push_all(&c.tys[]);
                 if dtor { ftys.push(cx.tcx().types.bool); }
-                mk_struct(cx, &ftys[], false, t)
+                mk_struct(cx, &ftys[..], false, t)
             }).collect();
 
-            ensure_enum_fits_in_address_space(cx, &fields[], t);
+            ensure_enum_fits_in_address_space(cx, &fields[..], t);
 
             General(ity, fields, dtor)
         }
@@ -453,9 +453,9 @@ fn mk_struct<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
            .map(|&ty| type_of::sizing_type_of(cx, ty)).collect()
     };
 
-    ensure_struct_fits_in_address_space(cx, &lltys[], packed, scapegoat);
+    ensure_struct_fits_in_address_space(cx, &lltys[..], packed, scapegoat);
 
-    let llty_rec = Type::struct_(cx, &lltys[], packed);
+    let llty_rec = Type::struct_(cx, &lltys[..], packed);
     Struct {
         size: machine::llsize_of_alloc(cx, llty_rec),
         align: machine::llalign_of_min(cx, llty_rec),
@@ -659,7 +659,7 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             // of the size.
             //
             // FIXME #10604: this breaks when vector types are present.
-            let (size, align) = union_size_and_align(&sts[]);
+            let (size, align) = union_size_and_align(&sts[..]);
             let align_s = align as u64;
             assert_eq!(size % align_s, 0);
             let align_units = size / align_s - 1;
@@ -682,10 +682,10 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                           Type::array(&discr_ty, align_s / discr_size - 1),
                           fill_ty];
             match name {
-                None => Type::struct_(cx, &fields[], false),
+                None => Type::struct_(cx, &fields[..], false),
                 Some(name) => {
                     let mut llty = Type::named_struct(cx, name);
-                    llty.set_struct_body(&fields[], false);
+                    llty.set_struct_body(&fields[..], false);
                     llty
                 }
             }
@@ -763,7 +763,7 @@ pub fn trans_get_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
 
 fn struct_wrapped_nullable_bitdiscr(bcx: Block, nndiscr: Disr, discrfield: &DiscrField,
                                     scrutinee: ValueRef) -> ValueRef {
-    let llptrptr = GEPi(bcx, scrutinee, &discrfield[]);
+    let llptrptr = GEPi(bcx, scrutinee, &discrfield[..]);
     let llptr = Load(bcx, llptrptr);
     let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
     ICmp(bcx, cmp, llptr, C_null(val_ty(llptr)), DebugLoc::None)
@@ -851,7 +851,7 @@ pub fn trans_set_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
         }
         StructWrappedNullablePointer { nndiscr, ref discrfield, .. } => {
             if discr != nndiscr {
-                let llptrptr = GEPi(bcx, val, &discrfield[]);
+                let llptrptr = GEPi(bcx, val, &discrfield[..]);
                 let llptrty = val_ty(llptrptr).element_type();
                 Store(bcx, C_null(llptrty), llptrptr)
             }
@@ -933,7 +933,7 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v
     let val = if needs_cast {
         let ccx = bcx.ccx();
         let fields = st.fields.iter().map(|&ty| type_of::type_of(ccx, ty)).collect::<Vec<_>>();
-        let real_ty = Type::struct_(ccx, &fields[], st.packed);
+        let real_ty = Type::struct_(ccx, &fields[..], st.packed);
         PointerCast(bcx, val, real_ty.ptr_to())
     } else {
         val
@@ -972,7 +972,7 @@ pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
 
                 let fields = case.fields.iter().map(|&ty|
                     type_of::type_of(bcx.ccx(), ty)).collect::<Vec<_>>();
-                let real_ty = Type::struct_(ccx, &fields[], case.packed);
+                let real_ty = Type::struct_(ccx, &fields[..], case.packed);
                 let variant_value = PointerCast(variant_cx, value, real_ty.ptr_to());
 
                 variant_cx = f(variant_cx, case, variant_value);
@@ -1045,18 +1045,18 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, r: &Repr<'tcx>, discr
         }
         General(ity, ref cases, _) => {
             let case = &cases[discr as uint];
-            let (max_sz, _) = union_size_and_align(&cases[]);
+            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];
             f.push_all(vals);
-            let mut contents = build_const_struct(ccx, case, &f[]);
+            let mut contents = build_const_struct(ccx, case, &f[..]);
             contents.push_all(&[padding(ccx, max_sz - case.size)]);
-            C_struct(ccx, &contents[], false)
+            C_struct(ccx, &contents[..], false)
         }
         Univariant(ref st, _dro) => {
             assert!(discr == 0);
             let contents = build_const_struct(ccx, st, vals);
-            C_struct(ccx, &contents[], st.packed)
+            C_struct(ccx, &contents[..], st.packed)
         }
         RawNullablePointer { nndiscr, nnty, .. } => {
             if discr == nndiscr {
@@ -1080,7 +1080,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)
             }
         }
index e419be65fc4cc33f1a141aff8bf5e2dbf775d8c1..a3bd0cf6b1a623bac1cf719408aa45f7d1696859 100644 (file)
@@ -71,7 +71,7 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
                                     callee::DontAutorefArg)
         })
     }).collect::<Vec<_>>();
-    inputs.push_all(&ext_inputs[]);
+    inputs.push_all(&ext_inputs[..]);
 
     // no failure occurred preparing operands, no need to cleanup
     fcx.pop_custom_cleanup_scope(temp_scope);
@@ -91,18 +91,18 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
         if !clobbers.is_empty() {
             clobbers.push(',');
         }
-        clobbers.push_str(&more_clobbers[]);
+        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[]);
+        constraints.push_str(&clobbers[..]);
     } else {
-        constraints.push_str(&clobbers[]);
+        constraints.push_str(&clobbers[..]);
     }
 
-    debug!("Asm Constraints: {}", &constraints[]);
+    debug!("Asm Constraints: {}", &constraints[..]);
 
     let num_outputs = outputs.len();
 
@@ -112,7 +112,7 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
     } else if num_outputs == 1 {
         output_types[0]
     } else {
-        Type::struct_(bcx.ccx(), &output_types[], false)
+        Type::struct_(bcx.ccx(), &output_types[..], false)
     };
 
     let dialect = match ia.dialect {
@@ -120,8 +120,8 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
         ast::AsmIntel => llvm::AD_Intel
     };
 
-    let asm = CString::from_slice(ia.asm.as_bytes());
-    let constraints = CString::from_slice(constraints.as_bytes());
+    let asm = CString::new(ia.asm.as_bytes()).unwrap();
+    let constraints = CString::new(constraints).unwrap();
     let r = InlineAsmCall(bcx,
                           asm.as_ptr(),
                           constraints.as_ptr(),
index 7f7b5cd800660abd835bd50e5b458d674cbab961..3091c852f5587baa80a11f567d4cc31104f72f43 100644 (file)
@@ -86,7 +86,7 @@
 
 use arena::TypedArena;
 use libc::{c_uint, uint64_t};
-use std::ffi::{self, CString};
+use std::ffi::{CStr, CString};
 use std::cell::{Cell, RefCell};
 use std::collections::HashSet;
 use std::mem;
@@ -186,7 +186,7 @@ fn drop(&mut self) {
 pub fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
                ty: Type, output: ty::FnOutput) -> ValueRef {
 
-    let buf = CString::from_slice(name.as_bytes());
+    let buf = CString::new(name).unwrap();
     let llfn: ValueRef = unsafe {
         llvm::LLVMGetOrInsertFunction(ccx.llmod(), buf.as_ptr(), ty.to_ref())
     };
@@ -247,7 +247,7 @@ fn get_extern_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<'tcx>,
     let f = decl_rust_fn(ccx, fn_ty, name);
 
     let attrs = csearch::get_item_attrs(&ccx.sess().cstore, did);
-    set_llvm_fn_attrs(ccx, &attrs[], f);
+    set_llvm_fn_attrs(ccx, &attrs[..], f);
 
     ccx.externs().borrow_mut().insert(name.to_string(), f);
     f
@@ -340,7 +340,7 @@ pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: ast::DefId,
         None => ()
     }
     unsafe {
-        let buf = CString::from_slice(name.as_bytes());
+        let buf = CString::new(name.clone()).unwrap();
         let c = llvm::LLVMAddGlobal(ccx.llmod(), ty.to_ref(), buf.as_ptr());
         // Thread-local statics in some other crate need to *always* be linked
         // against in a thread-local fashion, so we need to be sure to apply the
@@ -523,7 +523,7 @@ pub fn get_res_dtor<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                      ty::mk_nil(ccx.tcx()));
         get_extern_fn(ccx,
                       &mut *ccx.externs().borrow_mut(),
-                      &name[],
+                      &name[..],
                       llvm::CCallConv,
                       llty,
                       dtor_ty)
@@ -898,14 +898,14 @@ pub fn trans_external_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         ty::ty_bare_fn(_, ref fn_ty) => {
             match ccx.sess().target.target.adjust_abi(fn_ty.abi) {
                 Rust | RustCall => {
-                    get_extern_rust_fn(ccx, t, &name[], did)
+                    get_extern_rust_fn(ccx, t, &name[..], did)
                 }
                 RustIntrinsic => {
                     ccx.sess().bug("unexpected intrinsic in trans_external_path")
                 }
                 _ => {
                     foreign::register_foreign_item_fn(ccx, fn_ty.abi, t,
-                                                      &name[])
+                                                      &name[..])
                 }
             }
         }
@@ -947,7 +947,7 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
         let llresult = Invoke(bcx,
                               llfn,
-                              &llargs[],
+                              &llargs[..],
                               normal_bcx.llbb,
                               landing_pad,
                               Some(attributes),
@@ -961,7 +961,7 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
         let llresult = Call(bcx,
                             llfn,
-                            &llargs[],
+                            &llargs[..],
                             Some(attributes),
                             debug_loc);
         return (llresult, bcx);
@@ -1219,19 +1219,6 @@ pub fn alloca_zeroed<'blk, 'tcx>(cx: Block<'blk, 'tcx>, ty: Ty<'tcx>,
     p
 }
 
-pub fn arrayalloca(cx: Block, ty: Type, v: ValueRef) -> ValueRef {
-    let _icx = push_ctxt("arrayalloca");
-    if cx.unreachable.get() {
-        unsafe {
-            return llvm::LLVMGetUndef(ty.to_ref());
-        }
-    }
-    debuginfo::clear_source_location(cx.fcx);
-    let p = ArrayAlloca(cx, ty, v);
-    call_lifetime_start(cx, p);
-    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 {
@@ -1646,7 +1633,7 @@ fn copy_closure_args_to_allocas<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                                                          "argtuple",
                                                          arg_scope_id));
     let untupled_arg_types = match monomorphized_arg_types[0].sty {
-        ty::ty_tup(ref types) => &types[],
+        ty::ty_tup(ref types) => &types[..],
         _ => {
             bcx.tcx().sess.span_bug(args[0].pat.span,
                                     "first arg to `rust-call` ABI function \
@@ -1834,12 +1821,12 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     let arg_datums = if abi != RustCall {
         create_datums_for_fn_args(&fcx,
-                                  &monomorphized_arg_types[])
+                                  &monomorphized_arg_types[..])
     } else {
         create_datums_for_fn_args_under_call_abi(
             bcx,
             arg_scope,
-            &monomorphized_arg_types[])
+            &monomorphized_arg_types[..])
     };
 
     bcx = match closure_env {
@@ -1855,7 +1842,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                 arg_scope,
                 &decl.inputs[],
                 arg_datums,
-                &monomorphized_arg_types[])
+                &monomorphized_arg_types[..])
         }
     };
 
@@ -2000,7 +1987,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                 bcx = expr::trans_adt(bcx,
                                       result_ty,
                                       disr,
-                                      &fields[],
+                                      &fields[..],
                                       None,
                                       expr::SaveIn(llresult),
                                       debug_loc);
@@ -2070,7 +2057,7 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx
         ty::erase_late_bound_regions(
             ccx.tcx(), &ty::ty_fn_args(ctor_ty));
 
-    let arg_datums = create_datums_for_fn_args(&fcx, &arg_tys[]);
+    let arg_datums = create_datums_for_fn_args(&fcx, &arg_tys[..]);
 
     if !type_is_zero_size(fcx.ccx, result_ty.unwrap()) {
         let dest = fcx.get_ret_slot(bcx, result_ty, "eret_slot");
@@ -2315,7 +2302,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
       ast::ItemImpl(_, _, ref generics, _, _, ref impl_items) => {
         meth::trans_impl(ccx,
                          item.ident,
-                         &impl_items[],
+                         &impl_items[..],
                          generics,
                          item.id);
       }
@@ -2430,7 +2417,7 @@ fn register_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         _ => panic!("expected bare rust fn")
     };
 
-    let llfn = decl_rust_fn(ccx, node_type, &sym[]);
+    let llfn = decl_rust_fn(ccx, node_type, &sym[..]);
     finish_register_fn(ccx, sp, sym, node_id, llfn);
     llfn
 }
@@ -2475,7 +2462,7 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
 
             match fn_sig.inputs[1].sty {
                 ty::ty_tup(ref t_in) => {
-                    inputs.push_all(&t_in[]);
+                    inputs.push_all(&t_in[..]);
                     inputs
                 }
                 _ => ccx.sess().bug("expected tuple'd inputs")
@@ -2611,7 +2598,7 @@ pub fn register_fn_llvmty(ccx: &CrateContext,
     debug!("register_fn_llvmty id={} sym={}", node_id, sym);
 
     let llfn = decl_fn(ccx,
-                       &sym[],
+                       &sym[..],
                        cc,
                        llfty,
                        ty::FnConverging(ty::mk_nil(ccx.tcx())));
@@ -2667,7 +2654,7 @@ fn create_entry_fn(ccx: &CrateContext,
             let (start_fn, args) = if use_start_lang_item {
                 let start_def_id = match ccx.tcx().lang_items.require(StartFnLangItem) {
                     Ok(id) => id,
-                    Err(s) => { ccx.sess().fatal(&s[]); }
+                    Err(s) => { ccx.sess().fatal(&s[..]); }
                 };
                 let start_fn = if start_def_id.krate == ast::LOCAL_CRATE {
                     get_item_val(ccx, start_def_id.node)
@@ -2783,12 +2770,12 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                         } else {
                             llvm::LLVMTypeOf(v)
                         };
-                        if contains_null(&sym[]) {
+                        if contains_null(&sym[..]) {
                             ccx.sess().fatal(
                                 &format!("Illegal null byte in export_name \
                                          value: `{}`", sym)[]);
                         }
-                        let buf = CString::from_slice(sym.as_bytes());
+                        let buf = CString::new(sym.clone()).unwrap();
                         let g = llvm::LLVMAddGlobal(ccx.llmod(), llty,
                                                     buf.as_ptr());
 
@@ -2826,7 +2813,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                                                  &sect)[]);
                     }
                     unsafe {
-                        let buf = CString::from_slice(sect.as_bytes());
+                        let buf = CString::new(sect.as_bytes()).unwrap();
                         llvm::LLVMSetSection(v, buf.as_ptr());
                     }
                 },
@@ -2988,12 +2975,12 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec<u8> {
         Some(compressed) => compressed,
         None => cx.sess().fatal("failed to compress metadata"),
     });
-    let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed[]);
+    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_{}_{}",
                        cx.link_meta().crate_name,
                        cx.link_meta().crate_hash);
-    let buf = CString::from_vec(name.into_bytes());
+    let buf = CString::new(name).unwrap();
     let llglobal = unsafe {
         llvm::LLVMAddGlobal(cx.metadata_llmod(), val_ty(llconst).to_ref(),
                             buf.as_ptr())
@@ -3001,7 +2988,7 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec<u8> {
     unsafe {
         llvm::LLVMSetInitializer(llglobal, llconst);
         let name = loader::meta_section_name(cx.sess().target.target.options.is_like_osx);
-        let name = CString::from_slice(name.as_bytes());
+        let name = CString::new(name).unwrap();
         llvm::LLVMSetSection(llglobal, name.as_ptr())
     }
     return metadata;
@@ -3039,8 +3026,8 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
                     continue
                 }
 
-                let name = ffi::c_str_to_bytes(&llvm::LLVMGetValueName(val))
-                               .to_vec();
+                let name = CStr::from_ptr(llvm::LLVMGetValueName(val))
+                                .to_bytes().to_vec();
                 declared.insert(name);
             }
         }
@@ -3056,8 +3043,8 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
                     continue
                 }
 
-                let name = ffi::c_str_to_bytes(&llvm::LLVMGetValueName(val))
-                               .to_vec();
+                let name = CStr::from_ptr(llvm::LLVMGetValueName(val))
+                                .to_bytes().to_vec();
                 if !declared.contains(&name) &&
                    !reachable.contains(str::from_utf8(&name).unwrap()) {
                     llvm::SetLinkage(val, llvm::InternalLinkage);
@@ -3211,7 +3198,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
     reachable.push("rust_eh_personality_catch".to_string());
 
     if codegen_units > 1 {
-        internalize_symbols(&shared_ccx, &reachable.iter().map(|x| x.clone()).collect());
+        internalize_symbols(&shared_ccx, &reachable.iter().cloned().collect());
     }
 
     let metadata_module = ModuleTranslation {
index e268c2f0d5cc2b1dc766d7aab821f62e41894fe3..8199e6189c93b495c926ac1d9715ee29b1ddb90f 100644 (file)
@@ -431,7 +431,7 @@ pub fn alloca(&self, ty: Type, name: &str) -> ValueRef {
             if name.is_empty() {
                 llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname())
             } else {
-                let name = CString::from_slice(name.as_bytes());
+                let name = CString::new(name).unwrap();
                 llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(),
                                       name.as_ptr())
             }
@@ -567,7 +567,7 @@ pub fn gepi(&self, base: ValueRef, ixs: &[uint]) -> ValueRef {
         } else {
             let v = ixs.iter().map(|i| C_i32(self.ccx, *i as i32)).collect::<Vec<ValueRef>>();
             self.count_insn("gepi");
-            self.inbounds_gep(base, &v[])
+            self.inbounds_gep(base, &v[..])
         }
     }
 
@@ -775,8 +775,8 @@ pub fn add_span_comment(&self, sp: Span, text: &str) {
             let s = format!("{} ({})",
                             text,
                             self.ccx.sess().codemap().span_to_string(sp));
-            debug!("{}", &s[]);
-            self.add_comment(&s[]);
+            debug!("{}", &s[..]);
+            self.add_comment(&s[..]);
         }
     }
 
@@ -786,7 +786,7 @@ pub fn add_comment(&self, text: &str) {
             let comment_text = format!("{} {}", "#",
                                        sanitized.replace("\n", "\n\t# "));
             self.count_insn("inlineasm");
-            let comment_text = CString::from_vec(comment_text.into_bytes());
+            let comment_text = CString::new(comment_text).unwrap();
             let asm = unsafe {
                 llvm::LLVMConstInlineAsm(Type::func(&[], &Type::void(self.ccx)).to_ref(),
                                          comment_text.as_ptr(), noname(), False,
@@ -813,7 +813,7 @@ pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
         }).collect::<Vec<_>>();
 
         debug!("Asm Output Type: {}", self.ccx.tn().type_to_string(output));
-        let fty = Type::func(&argtys[], &output);
+        let fty = Type::func(&argtys[..], &output);
         unsafe {
             let v = llvm::LLVMInlineAsm(
                 fty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint);
index bda8b8938b76cb623b023a1afe7c3db7a7b0be0c..3d3e35cd776f0fd311affbe03d9188f46312d44c 100644 (file)
@@ -323,7 +323,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
     let llfn =
         decl_internal_rust_fn(ccx,
                               tuple_fn_ty,
-                              &function_name[]);
+                              &function_name[..]);
 
     //
     let empty_substs = tcx.mk_substs(Substs::trans_empty());
@@ -359,7 +359,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
                            DebugLoc::None,
                            bare_fn_ty,
                            |bcx, _| Callee { bcx: bcx, data: Fn(llfnpointer) },
-                           ArgVals(&llargs[]),
+                           ArgVals(&llargs[..]),
                            dest).bcx;
 
     finish_fn(&fcx, bcx, sig.output, DebugLoc::None);
@@ -792,7 +792,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
         // Invoke the actual rust fn and update bcx/llresult.
         let (llret, b) = base::invoke(bcx,
                                       llfn,
-                                      &llargs[],
+                                      &llargs[..],
                                       callee_ty,
                                       debug_loc);
         bcx = b;
@@ -833,7 +833,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
                                          callee_ty,
                                          llfn,
                                          opt_llretslot.unwrap(),
-                                         &llargs[],
+                                         &llargs[..],
                                          arg_tys,
                                          debug_loc);
     }
index 1c831090e3eaf0e04e07780f2200ca8462b4227e..85e53618f6da9c7ed664b3a0e1643664d59eaab8 100644 (file)
@@ -764,7 +764,7 @@ fn trans_cleanups_to_exit_scope(&'blk self,
                 let name = scope.block_name("clean");
                 debug!("generating cleanups for {}", name);
                 let bcx_in = self.new_block(label.is_unwind(),
-                                            &name[],
+                                            &name[..],
                                             None);
                 let mut bcx_out = bcx_in;
                 for cleanup in scope.cleanups.iter().rev() {
@@ -811,7 +811,7 @@ fn get_or_create_landing_pad(&'blk self) -> BasicBlockRef {
                 Some(llbb) => { return llbb; }
                 None => {
                     let name = last_scope.block_name("unwind");
-                    pad_bcx = self.new_block(true, &name[], None);
+                    pad_bcx = self.new_block(true, &name[..], None);
                     last_scope.cached_landing_pad = Some(pad_bcx.llbb);
                 }
             }
index f92df999e6049a3da4c189da516a2cbe925c98d4..1d4bbd79d71057baecdc624201e5d7a367355068 100644 (file)
@@ -158,7 +158,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc
         mangle_internal_name_by_path_and_seq(path, "closure")
     });
 
-    let llfn = decl_internal_rust_fn(ccx, function_type, &symbol[]);
+    let llfn = decl_internal_rust_fn(ccx, function_type, &symbol[..]);
 
     // set an inline hint for all closures
     set_inline_hint(llfn);
@@ -208,7 +208,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
     let function_type = typer.closure_type(closure_id, param_substs);
 
     let freevars: Vec<ty::Freevar> =
-        ty::with_freevars(tcx, id, |fv| fv.iter().map(|&fv| fv).collect());
+        ty::with_freevars(tcx, id, |fv| fv.iter().cloned().collect());
 
     let sig = ty::erase_late_bound_regions(tcx, &function_type.sig);
 
@@ -221,7 +221,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
                   &[],
                   sig.output,
                   function_type.abi,
-                  ClosureEnv::Closure(&freevars[]));
+                  ClosureEnv::Closure(&freevars[..]));
 
     // Don't hoist this to the top of the function. It's perfectly legitimate
     // to have a zero-size closure (in which case dest will be `Ignore`) and
index ac9a982f2983f58899068d188eedcd003079ad75..a9cda94bebac52513d98848c30cf01ca6a7262d5 100644 (file)
@@ -488,7 +488,7 @@ pub fn new_block(&'a self,
                      opt_node_id: Option<ast::NodeId>)
                      -> Block<'a, 'tcx> {
         unsafe {
-            let name = CString::from_slice(name.as_bytes());
+            let name = CString::new(name).unwrap();
             let llbb = llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(),
                                                            self.llfn,
                                                            name.as_ptr());
@@ -757,7 +757,7 @@ pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef {
 
 pub fn C_floating(s: &str, t: Type) -> ValueRef {
     unsafe {
-        let s = CString::from_slice(s.as_bytes());
+        let s = CString::new(s).unwrap();
         llvm::LLVMConstRealOfString(t.to_ref(), s.as_ptr())
     }
 }
@@ -835,7 +835,8 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va
                                                 !null_terminated as Bool);
 
         let gsym = token::gensym("str");
-        let buf = CString::from_vec(format!("str{}", gsym.usize()).into_bytes());
+        let buf = CString::new(format!("str{}", gsym.usize()));
+        let buf = buf.unwrap();
         let g = llvm::LLVMAddGlobal(cx.llmod(), val_ty(sc).to_ref(), buf.as_ptr());
         llvm::LLVMSetInitializer(g, sc);
         llvm::LLVMSetGlobalConstant(g, True);
@@ -1161,8 +1162,8 @@ pub fn langcall(bcx: Block,
         Err(s) => {
             let msg = format!("{} {}", msg, s);
             match span {
-                Some(span) => bcx.tcx().sess.span_fatal(span, &msg[]),
-                None => bcx.tcx().sess.fatal(&msg[]),
+                Some(span) => bcx.tcx().sess.span_fatal(span, &msg[..]),
+                None => bcx.tcx().sess.fatal(&msg[..]),
             }
         }
     }
index 86f5589556a78c86805cbb95693b823d4a3e50f4..7705b53ee38c69ad7a4c74254666fc3901776dbe 100644 (file)
@@ -75,7 +75,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 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);
@@ -611,8 +611,8 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
           }
           ast::ExprTup(ref es) => {
               let repr = adt::represent_type(cx, ety);
-              let vals = map_list(&es[]);
-              adt::trans_const(cx, &*repr, 0, &vals[])
+              let vals = map_list(&es[..]);
+              adt::trans_const(cx, &*repr, 0, &vals[..])
           }
           ast::ExprStruct(_, ref fs, ref base_opt) => {
               let repr = adt::represent_type(cx, ety);
@@ -642,9 +642,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                       }
                   }).collect::<Vec<_>>();
                   if ty::type_is_simd(cx.tcx(), ety) {
-                      C_vector(&cs[])
+                      C_vector(&cs[..])
                   } else {
-                      adt::trans_const(cx, &*repr, discr, &cs[])
+                      adt::trans_const(cx, &*repr, discr, &cs[..])
                   }
               })
           }
@@ -655,9 +655,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                               .collect::<Vec<_>>();
             // If the vector contains enums, an LLVM array won't work.
             if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
-                C_struct(cx, &vs[], false)
+                C_struct(cx, &vs[..], false)
             } else {
-                C_array(llunitty, &vs[])
+                C_array(llunitty, &vs[..])
             }
           }
           ast::ExprRepeat(ref elem, ref count) => {
@@ -671,9 +671,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             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 {
-                C_struct(cx, &vs[], false)
+                C_struct(cx, &vs[..], false)
             } else {
-                C_array(llunitty, &vs[])
+                C_array(llunitty, &vs[..])
             }
           }
           ast::ExprPath(_) | ast::ExprQPath(_) => {
@@ -715,14 +715,14 @@ 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 arg_vals = map_list(&args[]);
+              let arg_vals = map_list(&args[..]);
               match opt_def {
                   Some(def::DefStruct(_)) => {
                       if ty::type_is_simd(cx.tcx(), ety) {
-                          C_vector(&arg_vals[])
+                          C_vector(&arg_vals[..])
                       } else {
                           let repr = adt::represent_type(cx, ety);
-                          adt::trans_const(cx, &*repr, 0, &arg_vals[])
+                          adt::trans_const(cx, &*repr, 0, &arg_vals[..])
                       }
                   }
                   Some(def::DefVariant(enum_did, variant_did, _)) => {
@@ -733,7 +733,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                       adt::trans_const(cx,
                                        &*repr,
                                        vinfo.disr_val,
-                                       &arg_vals[])
+                                       &arg_vals[..])
                   }
                   _ => cx.sess().span_bug(e.span, "expected a struct or variant def")
               }
index 96506291b5aae65e22e4db7c30f60f2abeb3c8e4..eb07bdb7ba11bb6a860a2c71a1b462f440d196e5 100644 (file)
@@ -225,15 +225,15 @@ fn next(&mut self) -> Option<(CrateContext<'a, 'tcx>, bool)> {
 
 unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) {
     let llcx = llvm::LLVMContextCreate();
-    let mod_name = CString::from_slice(mod_name.as_bytes());
+    let mod_name = CString::new(mod_name).unwrap();
     let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
 
-    let data_layout = &*sess.target.target.data_layout;
-    let data_layout = CString::from_slice(data_layout.as_bytes());
+    let data_layout = sess.target.target.data_layout.as_bytes();
+    let data_layout = CString::new(data_layout).unwrap();
     llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
 
-    let llvm_target = &*sess.target.target.llvm_target;
-    let llvm_target = CString::from_slice(llvm_target.as_bytes());
+    let llvm_target = sess.target.target.llvm_target.as_bytes();
+    let llvm_target = CString::new(llvm_target).unwrap();
     llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
     (llcx, llmod)
 }
@@ -288,7 +288,7 @@ pub fn new(crate_name: &str,
             // such as a function name in the module.
             // 1. http://llvm.org/bugs/show_bug.cgi?id=11479
             let llmod_id = format!("{}.{}.rs", crate_name, i);
-            let local_ccx = LocalCrateContext::new(&shared_ccx, &llmod_id[]);
+            let local_ccx = LocalCrateContext::new(&shared_ccx, &llmod_id[..]);
             shared_ccx.local_ccxs.push(local_ccx);
         }
 
index e6cd44676cefb6a11dca91a98c3277d369739163..26e12a1af403dac45981d8bd2e4751c9f60fec69 100644 (file)
@@ -177,7 +177,7 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 
     let name = format!("then-block-{}-", thn.id);
-    let then_bcx_in = bcx.fcx.new_id_block(&name[], thn.id);
+    let then_bcx_in = bcx.fcx.new_id_block(&name[..], thn.id);
     let then_bcx_out = trans_block(then_bcx_in, &*thn, dest);
     trans::debuginfo::clear_source_location(bcx.fcx);
 
@@ -378,7 +378,7 @@ pub fn trans_fail<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let did = langcall(bcx, Some(call_info.span), "", PanicFnLangItem);
     let bcx = callee::trans_lang_call(bcx,
                                       did,
-                                      &args[],
+                                      &args[..],
                                       Some(expr::Ignore),
                                       call_info.debug_loc()).bcx;
     Unreachable(bcx);
@@ -407,7 +407,7 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let did = langcall(bcx, Some(call_info.span), "", PanicBoundsCheckFnLangItem);
     let bcx = callee::trans_lang_call(bcx,
                                       did,
-                                      &args[],
+                                      &args[..],
                                       Some(expr::Ignore),
                                       call_info.debug_loc()).bcx;
     Unreachable(bcx);
index 23498089c5839cc2aad225b5acbb7f99ff5aa853..fc0129239aac7e9b316749ef013d818c528b7602 100644 (file)
@@ -299,7 +299,7 @@ fn register_unique_id_with_metadata(&mut self,
         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[..])[]);
         }
     }
 
@@ -380,14 +380,14 @@ fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>,
                         self.get_unique_type_id_of_type(cx, component_type);
                     let component_type_id =
                         self.get_unique_type_id_as_string(component_type_id);
-                    unique_type_id.push_str(&component_type_id[]);
+                    unique_type_id.push_str(&component_type_id[..]);
                 }
             },
             ty::ty_uniq(inner_type) => {
                 unique_type_id.push('~');
                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
-                unique_type_id.push_str(&inner_type_id[]);
+                unique_type_id.push_str(&inner_type_id[..]);
             },
             ty::ty_ptr(ty::mt { ty: inner_type, mutbl } ) => {
                 unique_type_id.push('*');
@@ -397,7 +397,7 @@ fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>,
 
                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
-                unique_type_id.push_str(&inner_type_id[]);
+                unique_type_id.push_str(&inner_type_id[..]);
             },
             ty::ty_rptr(_, ty::mt { ty: inner_type, mutbl }) => {
                 unique_type_id.push('&');
@@ -407,7 +407,7 @@ fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>,
 
                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
-                unique_type_id.push_str(&inner_type_id[]);
+                unique_type_id.push_str(&inner_type_id[..]);
             },
             ty::ty_vec(inner_type, optional_length) => {
                 match optional_length {
@@ -421,7 +421,7 @@ fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>,
 
                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
-                unique_type_id.push_str(&inner_type_id[]);
+                unique_type_id.push_str(&inner_type_id[..]);
             },
             ty::ty_trait(ref trait_data) => {
                 unique_type_id.push_str("trait ");
@@ -452,7 +452,7 @@ fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>,
                         self.get_unique_type_id_of_type(cx, parameter_type);
                     let parameter_type_id =
                         self.get_unique_type_id_as_string(parameter_type_id);
-                    unique_type_id.push_str(&parameter_type_id[]);
+                    unique_type_id.push_str(&parameter_type_id[..]);
                     unique_type_id.push(',');
                 }
 
@@ -465,7 +465,7 @@ fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>,
                     ty::FnConverging(ret_ty) => {
                         let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty);
                         let return_type_id = self.get_unique_type_id_as_string(return_type_id);
-                        unique_type_id.push_str(&return_type_id[]);
+                        unique_type_id.push_str(&return_type_id[..]);
                     }
                     ty::FnDiverging => {
                         unique_type_id.push_str("!");
@@ -538,7 +538,7 @@ fn from_def_id_and_substs<'a, 'tcx>(type_map: &mut TypeMap<'tcx>,
                         type_map.get_unique_type_id_of_type(cx, type_parameter);
                     let param_type_id =
                         type_map.get_unique_type_id_as_string(param_type_id);
-                    output.push_str(&param_type_id[]);
+                    output.push_str(&param_type_id[..]);
                     output.push(',');
                 }
 
@@ -568,7 +568,7 @@ fn get_unique_type_id_of_closure_type<'a>(&mut self,
                 self.get_unique_type_id_of_type(cx, parameter_type);
             let parameter_type_id =
                 self.get_unique_type_id_as_string(parameter_type_id);
-            unique_type_id.push_str(&parameter_type_id[]);
+            unique_type_id.push_str(&parameter_type_id[..]);
             unique_type_id.push(',');
         }
 
@@ -582,7 +582,7 @@ fn get_unique_type_id_of_closure_type<'a>(&mut self,
             ty::FnConverging(ret_ty) => {
                 let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty);
                 let return_type_id = self.get_unique_type_id_as_string(return_type_id);
-                unique_type_id.push_str(&return_type_id[]);
+                unique_type_id.push_str(&return_type_id[..]);
             }
             ty::FnDiverging => {
                 unique_type_id.push_str("!");
@@ -806,11 +806,11 @@ pub fn create_global_var_metadata(cx: &CrateContext,
     let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
     let var_name = token::get_ident(ident).to_string();
     let linkage_name =
-        namespace_node.mangled_name_of_contained_item(&var_name[]);
+        namespace_node.mangled_name_of_contained_item(&var_name[..]);
     let var_scope = namespace_node.scope;
 
-    let var_name = CString::from_slice(var_name.as_bytes());
-    let linkage_name = CString::from_slice(linkage_name.as_bytes());
+    let var_name = CString::new(var_name).unwrap();
+    let linkage_name = CString::new(linkage_name).unwrap();
     unsafe {
         llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
                                                 var_scope,
@@ -1287,7 +1287,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             match expr.node {
                 ast::ExprClosure(_, ref fn_decl, ref top_level_block) => {
                     let name = format!("fn{}", token::gensym("fn"));
-                    let name = token::str_to_ident(&name[]);
+                    let name = token::str_to_ident(&name[..]);
                     (name, &**fn_decl,
                         // This is not quite right. It should actually inherit
                         // the generics of the enclosing function.
@@ -1366,7 +1366,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let (linkage_name, containing_scope) = if has_path {
         let namespace_node = namespace_for_item(cx, ast_util::local_def(fn_ast_id));
         let linkage_name = namespace_node.mangled_name_of_contained_item(
-            &function_name[]);
+            &function_name[..]);
         let containing_scope = namespace_node.scope;
         (linkage_name, containing_scope)
     } else {
@@ -1379,8 +1379,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let is_local_to_unit = is_node_local_to_unit(cx, fn_ast_id);
 
-    let function_name = CString::from_slice(function_name.as_bytes());
-    let linkage_name = CString::from_slice(linkage_name.as_bytes());
+    let function_name = CString::new(function_name).unwrap();
+    let linkage_name = CString::new(linkage_name).unwrap();
     let fn_metadata = unsafe {
         llvm::LLVMDIBuilderCreateFunction(
             DIB(cx),
@@ -1451,7 +1451,7 @@ fn get_function_signature<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             signature.push(type_metadata(cx, arg_type, codemap::DUMMY_SP));
         }
 
-        return create_DIArray(DIB(cx), &signature[]);
+        return create_DIArray(DIB(cx), &signature[..]);
     }
 
     fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
@@ -1486,7 +1486,7 @@ fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 actual_self_type,
                 true);
 
-            name_to_append_suffix_to.push_str(&actual_self_type_name[]);
+            name_to_append_suffix_to.push_str(&actual_self_type_name[..]);
 
             if generics.is_type_parameterized() {
                 name_to_append_suffix_to.push_str(",");
@@ -1501,7 +1501,7 @@ fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 let ident = special_idents::type_self;
 
                 let ident = token::get_ident(ident);
-                let name = CString::from_slice(ident.as_bytes());
+                let name = CString::new(ident.as_bytes()).unwrap();
                 let param_metadata = unsafe {
                     llvm::LLVMDIBuilderCreateTemplateTypeParameter(
                         DIB(cx),
@@ -1525,7 +1525,7 @@ fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let actual_type_name = compute_debuginfo_type_name(cx,
                                                                actual_type,
                                                                true);
-            name_to_append_suffix_to.push_str(&actual_type_name[]);
+            name_to_append_suffix_to.push_str(&actual_type_name[..]);
 
             if index != generics.ty_params.len() - 1 {
                 name_to_append_suffix_to.push_str(",");
@@ -1535,7 +1535,7 @@ fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             if cx.sess().opts.debuginfo == FullDebugInfo {
                 let actual_type_metadata = type_metadata(cx, actual_type, codemap::DUMMY_SP);
                 let ident = token::get_ident(ident);
-                let name = CString::from_slice(ident.as_bytes());
+                let name = CString::new(ident.as_bytes()).unwrap();
                 let param_metadata = unsafe {
                     llvm::LLVMDIBuilderCreateTemplateTypeParameter(
                         DIB(cx),
@@ -1552,7 +1552,7 @@ fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
         name_to_append_suffix_to.push('>');
 
-        return create_DIArray(DIB(cx), &template_params[]);
+        return create_DIArray(DIB(cx), &template_params[..]);
     }
 }
 
@@ -1601,7 +1601,7 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
                             path_bytes.insert(1, prefix[1]);
                         }
 
-                        CString::from_vec(path_bytes)
+                        CString::new(path_bytes).unwrap()
                     }
                     _ => fallback_path(cx)
                 }
@@ -1614,8 +1614,8 @@ 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::from_slice(work_dir.as_vec());
-    let producer = CString::from_slice(producer.as_bytes());
+    let work_dir = CString::new(work_dir.as_vec()).unwrap();
+    let producer = CString::new(producer).unwrap();
     let flags = "\0";
     let split_name = "\0";
     return unsafe {
@@ -1632,7 +1632,7 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
     };
 
     fn fallback_path(cx: &CrateContext) -> CString {
-        CString::from_slice(cx.link_meta().crate_name.as_bytes())
+        CString::new(cx.link_meta().crate_name.clone()).unwrap()
     }
 }
 
@@ -1646,7 +1646,7 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let cx: &CrateContext = bcx.ccx();
 
     let filename = span_start(cx, span).file.name.clone();
-    let file_metadata = file_metadata(cx, &filename[]);
+    let file_metadata = file_metadata(cx, &filename[..]);
 
     let name = token::get_ident(variable_ident);
     let loc = span_start(cx, span);
@@ -1658,7 +1658,7 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         CapturedVariable => (0, DW_TAG_auto_variable)
     };
 
-    let name = CString::from_slice(name.as_bytes());
+    let name = CString::new(name.as_bytes()).unwrap();
     match (variable_access, [].as_slice()) {
         (DirectVariable { alloca }, address_operations) |
         (IndirectVariable {alloca, address_operations}, _) => {
@@ -1724,8 +1724,8 @@ fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
             full_path
         };
 
-    let file_name = CString::from_slice(file_name.as_bytes());
-    let work_dir = CString::from_slice(work_dir.as_bytes());
+    let file_name = CString::new(file_name).unwrap();
+    let work_dir = CString::new(work_dir).unwrap();
     let file_metadata = unsafe {
         llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name.as_ptr(),
                                       work_dir.as_ptr())
@@ -1800,7 +1800,7 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let llvm_type = type_of::type_of(cx, t);
     let (size, align) = size_and_align_of(cx, llvm_type);
-    let name = CString::from_slice(name.as_bytes());
+    let name = CString::new(name).unwrap();
     let ty_metadata = unsafe {
         llvm::LLVMDIBuilderCreateBasicType(
             DIB(cx),
@@ -1820,7 +1820,7 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let pointer_llvm_type = type_of::type_of(cx, pointer_type);
     let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
     let name = compute_debuginfo_type_name(cx, pointer_type, false);
-    let name = CString::from_slice(name.as_bytes());
+    let name = CString::new(name).unwrap();
     let ptr_metadata = unsafe {
         llvm::LLVMDIBuilderCreatePointerType(
             DIB(cx),
@@ -1959,7 +1959,7 @@ fn finalize<'a>(&self, cx: &CrateContext<'a, 'tcx>) -> MetadataCreationResult {
                 set_members_of_composite_type(cx,
                                               metadata_stub,
                                               llvm_type,
-                                              &member_descriptions[]);
+                                              &member_descriptions[..]);
                 return MetadataCreationResult::new(metadata_stub, true);
             }
         }
@@ -2031,7 +2031,7 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let struct_metadata_stub = create_struct_stub(cx,
                                                   struct_llvm_type,
-                                                  &struct_name[],
+                                                  &struct_name[..],
                                                   unique_type_id,
                                                   containing_scope);
 
@@ -2098,7 +2098,7 @@ fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         unique_type_id,
         create_struct_stub(cx,
                            tuple_llvm_type,
-                           &tuple_name[],
+                           &tuple_name[..],
                            unique_type_id,
                            UNKNOWN_SCOPE_METADATA),
         tuple_llvm_type,
@@ -2158,7 +2158,7 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
                         set_members_of_composite_type(cx,
                                                       variant_type_metadata,
                                                       variant_llvm_type,
-                                                      &member_descriptions[]);
+                                                      &member_descriptions[..]);
                         MemberDescription {
                             name: "".to_string(),
                             llvm_type: variant_llvm_type,
@@ -2191,7 +2191,7 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
                     set_members_of_composite_type(cx,
                                                   variant_type_metadata,
                                                   variant_llvm_type,
-                                                  &member_descriptions[]);
+                                                  &member_descriptions[..]);
                     vec![
                         MemberDescription {
                             name: "".to_string(),
@@ -2291,7 +2291,7 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
                 set_members_of_composite_type(cx,
                                               variant_type_metadata,
                                               variant_llvm_type,
-                                              &variant_member_descriptions[]);
+                                              &variant_member_descriptions[..]);
 
                 // Encode the information about the null variant in the union
                 // member's name.
@@ -2445,7 +2445,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         .iter()
         .map(|v| {
             let token = token::get_name(v.name);
-            let name = CString::from_slice(token.as_bytes());
+            let name = CString::new(token.as_bytes()).unwrap();
             unsafe {
                 llvm::LLVMDIBuilderCreateEnumerator(
                     DIB(cx),
@@ -2475,7 +2475,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                   codemap::DUMMY_SP);
                 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
 
-                let name = CString::from_slice(discriminant_name.as_bytes());
+                let name = CString::new(discriminant_name.as_bytes()).unwrap();
                 let discriminant_type_metadata = unsafe {
                     llvm::LLVMDIBuilderCreateEnumerationType(
                         DIB(cx),
@@ -2518,8 +2518,8 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                              .borrow()
                              .get_unique_type_id_as_string(unique_type_id);
 
-    let enum_name = CString::from_slice(enum_name.as_bytes());
-    let unique_type_id_str = CString::from_slice(unique_type_id_str.as_bytes());
+    let enum_name = CString::new(enum_name).unwrap();
+    let unique_type_id_str = CString::new(unique_type_id_str.as_bytes()).unwrap();
     let enum_metadata = unsafe {
         llvm::LLVMDIBuilderCreateUnionType(
         DIB(cx),
@@ -2644,7 +2644,8 @@ fn set_members_of_composite_type(cx: &CrateContext,
                 ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i)
             };
 
-            let member_name = CString::from_slice(member_description.name.as_bytes());
+            let member_name = member_description.name.as_bytes();
+            let member_name = CString::new(member_name).unwrap();
             unsafe {
                 llvm::LLVMDIBuilderCreateMemberType(
                     DIB(cx),
@@ -2662,7 +2663,7 @@ fn set_members_of_composite_type(cx: &CrateContext,
         .collect();
 
     unsafe {
-        let type_array = create_DIArray(DIB(cx), &member_metadata[]);
+        let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
         llvm::LLVMDICompositeTypeSetTypeArray(DIB(cx), composite_type_metadata, type_array);
     }
 }
@@ -2681,8 +2682,8 @@ fn create_struct_stub(cx: &CrateContext,
     let unique_type_id_str = debug_context(cx).type_map
                                               .borrow()
                                               .get_unique_type_id_as_string(unique_type_id);
-    let name = CString::from_slice(struct_type_name.as_bytes());
-    let unique_type_id = CString::from_slice(unique_type_id_str.as_bytes());
+    let name = CString::new(struct_type_name).unwrap();
+    let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap();
     let metadata_stub = unsafe {
         // LLVMDIBuilderCreateStructType() wants an empty array. A null
         // pointer will lead to hard to trace and debug LLVM assertions
@@ -2763,7 +2764,7 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let member_llvm_types = slice_llvm_type.field_types();
     assert!(slice_layout_is_correct(cx,
-                                    &member_llvm_types[],
+                                    &member_llvm_types[..],
                                     element_type));
     let member_descriptions = [
         MemberDescription {
@@ -2789,7 +2790,7 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let metadata = composite_type_metadata(cx,
                                            slice_llvm_type,
-                                           &slice_type_name[],
+                                           &slice_type_name[..],
                                            unique_type_id,
                                            &member_descriptions,
                                            UNKNOWN_SCOPE_METADATA,
@@ -2838,7 +2839,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             llvm::LLVMDIBuilderCreateSubroutineType(
                 DIB(cx),
                 UNKNOWN_FILE_METADATA,
-                create_DIArray(DIB(cx), &signature_metadata[]))
+                create_DIArray(DIB(cx), &signature_metadata[..]))
         },
         false);
 }
@@ -2864,7 +2865,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[..])[]);
         }
     };
 
@@ -2878,7 +2879,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     composite_type_metadata(cx,
                             trait_llvm_type,
-                            &trait_type_name[],
+                            &trait_type_name[..],
                             unique_type_id,
                             &[],
                             containing_scope,
@@ -2998,7 +2999,7 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         ty::ty_tup(ref elements) => {
             prepare_tuple_metadata(cx,
                                    t,
-                                   &elements[],
+                                   &elements[..],
                                    unique_type_id,
                                    usage_site_span).finalize(cx)
         }
@@ -3022,9 +3023,9 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                                  type id '{}' to already be in \
                                                  the debuginfo::TypeMap but it \
                                                  was not. (Ty = {})",
-                                                &unique_type_id_str[],
+                                                &unique_type_id_str[..],
                                                 ppaux::ty_to_string(cx.tcx(), t));
-                    cx.sess().span_bug(usage_site_span, &error_message[]);
+                    cx.sess().span_bug(usage_site_span, &error_message[..]);
                 }
             };
 
@@ -3037,9 +3038,9 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                                      UniqueTypeId maps in \
                                                      debuginfo::TypeMap. \
                                                      UniqueTypeId={}, Ty={}",
-                            &unique_type_id_str[],
+                            &unique_type_id_str[..],
                             ppaux::ty_to_string(cx.tcx(), t));
-                        cx.sess().span_bug(usage_site_span, &error_message[]);
+                        cx.sess().span_bug(usage_site_span, &error_message[..]);
                     }
                 }
                 None => {
@@ -3128,7 +3129,7 @@ fn contains_nodebug_attribute(attributes: &[ast::Attribute]) -> bool {
     attributes.iter().any(|attr| {
         let meta_item: &ast::MetaItem = &*attr.node.value;
         match meta_item.node {
-            ast::MetaWord(ref value) => &value[] == "no_debug",
+            ast::MetaWord(ref value) => &value[..] == "no_debug",
             _ => false
         }
     })
@@ -3971,8 +3972,7 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTree
                         None => ptr::null_mut()
                     };
                     let namespace_name = token::get_name(name);
-                    let namespace_name = CString::from_slice(namespace_name
-                                                                .as_bytes());
+                    let namespace_name = CString::new(namespace_name.as_bytes()).unwrap();
                     let scope = unsafe {
                         llvm::LLVMDIBuilderCreateNameSpace(
                             DIB(cx),
@@ -4020,7 +4020,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::from_slice(b"");
+        let empty = CString::new(b"").unwrap();
         let gdb_debug_scripts_section_global =
             get_or_insert_gdb_debug_scripts_section_global(ccx);
         unsafe {
index 861a218e0f1b92d3cede63a010392142baa7e28f..1af9fa87c6b7d2f6fd7bf31ce2877ebe46ecb36c 100644 (file)
@@ -1046,14 +1046,14 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             controlflow::trans_if(bcx, expr.id, &**cond, &**thn, els.as_ref().map(|e| &**e), dest)
         }
         ast::ExprMatch(ref discr, ref arms, _) => {
-            _match::trans_match(bcx, expr, &**discr, &arms[], dest)
+            _match::trans_match(bcx, expr, &**discr, &arms[..], dest)
         }
         ast::ExprBlock(ref blk) => {
             controlflow::trans_block(bcx, &**blk, dest)
         }
         ast::ExprStruct(_, ref fields, ref base) => {
             trans_struct(bcx,
-                         &fields[],
+                         &fields[..],
                          base.as_ref().map(|e| &**e),
                          expr.span,
                          expr.id,
@@ -1118,7 +1118,7 @@ fn make_field(field_name: &str, expr: P<ast::Expr>) -> ast::Field {
             trans_adt(bcx,
                       expr_ty(bcx, expr),
                       0,
-                      &numbered_fields[],
+                      &numbered_fields[..],
                       None,
                       dest,
                       expr.debug_loc())
@@ -1153,13 +1153,13 @@ fn make_field(field_name: &str, expr: P<ast::Expr>) -> ast::Field {
                 trans_overloaded_call(bcx,
                                       expr,
                                       &**f,
-                                      &args[],
+                                      &args[..],
                                       Some(dest))
             } else {
                 callee::trans_call(bcx,
                                    expr,
                                    &**f,
-                                   callee::ArgExprs(&args[]),
+                                   callee::ArgExprs(&args[..]),
                                    dest)
             }
         }
@@ -1167,7 +1167,7 @@ fn make_field(field_name: &str, expr: P<ast::Expr>) -> ast::Field {
             callee::trans_method_call(bcx,
                                       expr,
                                       &*args[0],
-                                      callee::ArgExprs(&args[]),
+                                      callee::ArgExprs(&args[..]),
                                       dest)
         }
         ast::ExprBinary(op, ref lhs, ref rhs) => {
@@ -1197,7 +1197,7 @@ fn make_field(field_name: &str, expr: P<ast::Expr>) -> ast::Field {
                 let trait_ref =
                     bcx.tcx().object_cast_map.borrow()
                                              .get(&expr.id)
-                                             .map(|t| (*t).clone())
+                                             .cloned()
                                              .unwrap();
                 let trait_ref = bcx.monomorphize(&trait_ref);
                 let datum = unpack_datum!(bcx, trans(bcx, &**val));
@@ -1354,11 +1354,11 @@ pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>,
         ty::ty_struct(did, substs) => {
             let fields = struct_fields(tcx, did, substs);
             let fields = monomorphize::normalize_associated_type(tcx, &fields);
-            op(0, &fields[])
+            op(0, &fields[..])
         }
 
         ty::ty_tup(ref v) => {
-            op(0, &tup_fields(&v[])[])
+            op(0, &tup_fields(&v[..])[])
         }
 
         ty::ty_enum(_, substs) => {
@@ -1378,7 +1378,7 @@ pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>,
                                 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[])
+                            op(variant_info.disr_val, &fields[..])
                         }
                         _ => {
                             tcx.sess.bug("resolve didn't map this expr to a \
index 8f0e4e647b5b3d1c8cceb646416d418b027ec037..4508fe21a65fadb90abcf37975190fd609b13139 100644 (file)
@@ -135,7 +135,7 @@ pub fn register_static(ccx: &CrateContext,
             };
             unsafe {
                 // Declare a symbol `foo` with the desired linkage.
-                let buf = CString::from_slice(ident.as_bytes());
+                let buf = CString::new(ident.as_bytes()).unwrap();
                 let g1 = llvm::LLVMAddGlobal(ccx.llmod(), llty2.to_ref(),
                                              buf.as_ptr());
                 llvm::SetLinkage(g1, linkage);
@@ -148,7 +148,7 @@ pub fn register_static(ccx: &CrateContext,
                 // zero.
                 let mut real_name = "_rust_extern_with_linkage_".to_string();
                 real_name.push_str(&ident);
-                let real_name = CString::from_vec(real_name.into_bytes());
+                let real_name = CString::new(real_name).unwrap();
                 let g2 = llvm::LLVMAddGlobal(ccx.llmod(), llty.to_ref(),
                                              real_name.as_ptr());
                 llvm::SetLinkage(g2, llvm::InternalLinkage);
@@ -158,7 +158,7 @@ pub fn register_static(ccx: &CrateContext,
         }
         None => unsafe {
             // Generate an external declaration.
-            let buf = CString::from_slice(ident.as_bytes());
+            let buf = CString::new(ident.as_bytes()).unwrap();
             llvm::LLVMAddGlobal(ccx.llmod(), llty.to_ref(), buf.as_ptr())
         }
     }
@@ -238,7 +238,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         _ => ccx.sess().bug("trans_native_call called on non-function type")
     };
     let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig);
-    let llsig = foreign_signature(ccx, &fn_sig, &passed_arg_tys[]);
+    let llsig = foreign_signature(ccx, &fn_sig, &passed_arg_tys[..]);
     let fn_type = cabi::compute_abi_info(ccx,
                                          &llsig.llarg_tys[],
                                          llsig.llret_ty,
@@ -370,7 +370,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     let llforeign_retval = CallWithConv(bcx,
                                         llfn,
-                                        &llargs_foreign[],
+                                        &llargs_foreign[..],
                                         cc,
                                         Some(attrs),
                                         call_debug_loc);
@@ -611,7 +611,7 @@ fn build_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                ccx.tcx().map.path_to_string(id),
                id, t.repr(tcx));
 
-        let llfn = base::decl_internal_rust_fn(ccx, t, &ps[]);
+        let llfn = base::decl_internal_rust_fn(ccx, t, &ps[..]);
         base::set_llvm_fn_attrs(ccx, attrs, llfn);
         base::trans_fn(ccx, decl, body, llfn, param_substs, id, &[]);
         llfn
@@ -974,7 +974,7 @@ fn lltype_for_fn_from_foreign_types(ccx: &CrateContext, tys: &ForeignTypes) -> T
     if tys.fn_sig.variadic {
         Type::variadic_func(&llargument_tys, &llreturn_ty)
     } else {
-        Type::func(&llargument_tys[], &llreturn_ty)
+        Type::func(&llargument_tys[..], &llreturn_ty)
     }
 }
 
index af90e1ec5c5dd47cb85ee6c152386f2c4eb06bea..268b65c6ceb30c14f9af1889c890a870712e7fd8 100644 (file)
@@ -170,7 +170,7 @@ pub fn get_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Val
 
     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()));
+            let glue = decl_cdecl_fn(ccx, &old_sym[..], llfnty, ty::mk_nil(ccx.tcx()));
             (glue, None)
         },
         None => {
@@ -304,7 +304,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                      class_did,
                                      &[get_drop_glue_type(bcx.ccx(), t)],
                                      ty::mk_nil(bcx.tcx()));
-        let (_, variant_cx) = invoke(variant_cx, dtor_addr, &args[], dtor_ty, DebugLoc::None);
+        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
@@ -513,7 +513,7 @@ pub fn declare_tydesc<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>)
     let llalign = llalign_of(ccx, llty);
     let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc");
     debug!("+++ declare_tydesc {} {}", ppaux::ty_to_string(ccx.tcx(), t), name);
-    let buf = CString::from_slice(name.as_bytes());
+    let buf = CString::new(name.clone()).unwrap();
     let gvar = unsafe {
         llvm::LLVMAddGlobal(ccx.llmod(), ccx.tydesc_type().to_ref(),
                             buf.as_ptr())
@@ -541,7 +541,7 @@ fn declare_generic_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>,
         ccx,
         t,
         &format!("glue_{}", name)[]);
-    let llfn = decl_cdecl_fn(ccx, &fn_nm[], llfnty, ty::mk_nil(ccx.tcx()));
+    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);
 }
index 5687247561e9cfe13f6e1b4bfb47031e7b6c2aec..a1b66ed94f06bc8dfed134ea44cace4fd76e274d 100644 (file)
@@ -166,7 +166,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     let name = token::get_ident(foreign_item.ident);
 
     // For `transmute` we can just trans the input expr directly into dest
-    if &name[] == "transmute" {
+    if &name[..] == "transmute" {
         let llret_ty = type_of::type_of(ccx, ret_ty.unwrap());
         match args {
             callee::ArgExprs(arg_exprs) => {
@@ -274,13 +274,13 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     let call_debug_location = DebugLoc::At(call_info.id, call_info.span);
 
     // These are the only intrinsic functions that diverge.
-    if &name[] == "abort" {
+    if &name[..] == "abort" {
         let llfn = ccx.get_intrinsic(&("llvm.trap"));
         Call(bcx, llfn, &[], None, call_debug_location);
         fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope);
         Unreachable(bcx);
         return Result::new(bcx, C_undef(Type::nil(ccx).ptr_to()));
-    } else if &name[] == "unreachable" {
+    } else if &name[..] == "unreachable" {
         fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope);
         Unreachable(bcx);
         return Result::new(bcx, C_nil(ccx));
@@ -307,7 +307,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     };
 
     let simple = get_simple_intrinsic(ccx, &*foreign_item);
-    let llval = match (simple, &name[]) {
+    let llval = match (simple, &name[..]) {
         (Some(llfn), _) => {
             Call(bcx, llfn, &llargs, None, call_debug_location)
         }
index 30797344da810889e235e2f761ae876a60c3d795..ec48ab0d34a06b60d84d5312084649225a4816bd 100644 (file)
@@ -131,7 +131,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
         hash = format!("h{}", state.finish());
         ccx.tcx().map.with_path(fn_id.node, |path| {
-            exported_name(path, &hash[])
+            exported_name(path, &hash[..])
         })
     };
 
@@ -141,9 +141,9 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     let mut hash_id = Some(hash_id);
     let mut mk_lldecl = |abi: abi::Abi| {
         let lldecl = if abi != abi::Rust {
-            foreign::decl_rust_fn_with_foreign_abi(ccx, mono_ty, &s[])
+            foreign::decl_rust_fn_with_foreign_abi(ccx, mono_ty, &s[..])
         } else {
-            decl_internal_rust_fn(ccx, mono_ty, &s[])
+            decl_internal_rust_fn(ccx, mono_ty, &s[..])
         };
 
         ccx.monomorphized().borrow_mut().insert(hash_id.take().unwrap(), lldecl);
@@ -182,7 +182,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                       if abi != abi::Rust {
                           foreign::trans_rust_fn_with_foreign_abi(
                               ccx, &**decl, &**body, &[], d, psubsts, fn_id.node,
-                              Some(&hash[]));
+                              Some(&hash[..]));
                       } else {
                           trans_fn(ccx, &**decl, &**body, d, psubsts, fn_id.node, &[]);
                       }
@@ -206,7 +206,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                     trans_enum_variant(ccx,
                                        parent,
                                        &*v,
-                                       &args[],
+                                       &args[..],
                                        this_tv.disr_val,
                                        psubsts,
                                        d);
index 456e27967f5a67fa374c1bf70de434f5aaad5dd2..7b59e0258ee224c4ec6cdd91e4c012afa800c072 100644 (file)
@@ -171,33 +171,27 @@ pub fn trans_slice_vec<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let vt = vec_types_from_expr(bcx, content_expr);
     let count = elements_required(bcx, content_expr);
     debug!("    vt={}, count={}", vt.to_string(ccx), count);
-    let llcount = C_uint(ccx, count);
 
     let fixed_ty = ty::mk_vec(bcx.tcx(),
                               vt.unit_ty,
                               Some(count));
-    let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty).ptr_to();
+    let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty);
 
-    let llfixed = if count == 0 {
-        // Just create a zero-sized alloca to preserve
-        // the non-null invariant of the inner slice ptr
-        let llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
-        BitCast(bcx, llfixed, llfixed_ty)
-    } else {
-        // Make a fixed-length backing array and allocate it on the stack.
-        let llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
+    // Always create an alloca even if zero-sized, to preserve
+    // the non-null invariant of the inner slice ptr
+    let llfixed = base::alloca(bcx, llfixed_ty, "");
 
+    if count > 0 {
         // Arrange for the backing array to be cleaned up.
-        let llfixed_casted = BitCast(bcx, llfixed, llfixed_ty);
         let cleanup_scope = cleanup::temporary_scope(bcx.tcx(), content_expr.id);
-        fcx.schedule_lifetime_end(cleanup_scope, llfixed_casted);
-        fcx.schedule_drop_mem(cleanup_scope, llfixed_casted, fixed_ty);
+        fcx.schedule_lifetime_end(cleanup_scope, llfixed);
+        fcx.schedule_drop_mem(cleanup_scope, llfixed, fixed_ty);
 
         // Generate the content into the backing array.
-        bcx = write_content(bcx, &vt, slice_expr,
-                            content_expr, SaveIn(llfixed));
-
-        llfixed_casted
+        // llfixed has type *[T x N], but we want the type *T,
+        // so use GEP to convert
+        bcx = write_content(bcx, &vt, slice_expr, content_expr,
+                            SaveIn(GEPi(bcx, llfixed, &[0, 0])));
     };
 
     immediate_rvalue_bcx(bcx, llfixed, vec_ty).to_expr_datumblock()
@@ -426,49 +420,27 @@ pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
     let _icx = push_ctxt("tvec::iter_vec_loop");
     let fcx = bcx.fcx;
 
-    let next_bcx = fcx.new_temp_block("expr_repeat: while next");
     let loop_bcx = fcx.new_temp_block("expr_repeat");
-    let cond_bcx = fcx.new_temp_block("expr_repeat: loop cond");
-    let body_bcx = fcx.new_temp_block("expr_repeat: body: set");
-    let inc_bcx = fcx.new_temp_block("expr_repeat: body: inc");
-    Br(bcx, loop_bcx.llbb, DebugLoc::None);
-
-    let loop_counter = {
-        // i = 0
-        let i = alloca(loop_bcx, bcx.ccx().int_type(), "__i");
-        Store(loop_bcx, C_uint(bcx.ccx(), 0_u32), i);
+    let next_bcx = fcx.new_temp_block("expr_repeat: next");
 
-        Br(loop_bcx, cond_bcx.llbb, DebugLoc::None);
-        i
-    };
-
-    { // i < count
-        let lhs = Load(cond_bcx, loop_counter);
-        let rhs = count;
-        let cond_val = ICmp(cond_bcx, llvm::IntULT, lhs, rhs, DebugLoc::None);
-
-        CondBr(cond_bcx, cond_val, body_bcx.llbb, next_bcx.llbb, DebugLoc::None);
-    }
+    Br(bcx, loop_bcx.llbb, DebugLoc::None);
 
-    { // loop body
-        let i = Load(body_bcx, loop_counter);
-        let lleltptr = if vt.llunit_alloc_size == 0 {
-            data_ptr
-        } else {
-            InBoundsGEP(body_bcx, data_ptr, &[i])
-        };
-        let body_bcx = f(body_bcx, lleltptr, vt.unit_ty);
+    let loop_counter = Phi(loop_bcx, bcx.ccx().int_type(),
+                           &[C_uint(bcx.ccx(), 0 as usize)], &[bcx.llbb]);
 
-        Br(body_bcx, inc_bcx.llbb, DebugLoc::None);
-    }
+    let bcx = loop_bcx;
 
-    { // i += 1
-        let i = Load(inc_bcx, loop_counter);
-        let plusone = Add(inc_bcx, i, C_uint(bcx.ccx(), 1_u32), DebugLoc::None);
-        Store(inc_bcx, plusone, loop_counter);
+    let lleltptr = if vt.llunit_alloc_size == 0 {
+        data_ptr
+    } else {
+        InBoundsGEP(bcx, data_ptr, &[loop_counter])
+    };
+    let bcx = f(bcx, lleltptr, vt.unit_ty);
+    let plusone = Add(bcx, loop_counter, C_uint(bcx.ccx(), 1us), DebugLoc::None);
+    AddIncomingToPhi(loop_counter, plusone, bcx.llbb);
 
-        Br(inc_bcx, cond_bcx.llbb, DebugLoc::None);
-    }
+    let cond_val = ICmp(bcx, llvm::IntULT, plusone, count, DebugLoc::None);
+    CondBr(bcx, cond_val, loop_bcx.llbb, next_bcx.llbb, DebugLoc::None);
 
     next_bcx
 }
index e3e4ca62c262f0f4931fd4691a4062f9ed3f2f41..ad83135a0d46fa3681df8b6f4d6bc2cb8b7d7d64 100644 (file)
@@ -163,7 +163,7 @@ pub fn struct_(ccx: &CrateContext, els: &[Type], packed: bool) -> Type {
     }
 
     pub fn named_struct(ccx: &CrateContext, name: &str) -> Type {
-        let name = CString::from_slice(name.as_bytes());
+        let name = CString::new(name).unwrap();
         ty!(llvm::LLVMStructCreateNamed(ccx.llcx(), name.as_ptr()))
     }
 
index 9d1c0fadefcd22718ca1dac09debc1fb7cb9e3fc..489b56bbe6825f567968c2bc802549a21fcaf34b 100644 (file)
@@ -67,7 +67,7 @@ pub fn untuple_arguments_if_necessary<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                                 abi: abi::Abi)
                                                 -> Vec<Ty<'tcx>> {
     if abi != abi::RustCall {
-        return inputs.iter().map(|x| (*x).clone()).collect()
+        return inputs.iter().cloned().collect()
     }
 
     if inputs.len() == 0 {
@@ -144,7 +144,7 @@ pub fn type_of_rust_fn<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let input_tys = inputs.iter().map(|&arg_ty| type_of_explicit_arg(cx, arg_ty));
     atys.extend(input_tys);
 
-    Type::func(&atys[], &lloutputtype)
+    Type::func(&atys[..], &lloutputtype)
 }
 
 // Given a function type and a count of ty params, construct an llvm type
@@ -332,7 +332,7 @@ fn type_of_unsize_info<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Ty
           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);
-          adt::incomplete_type_of(cx, &*repr, &name[])
+          adt::incomplete_type_of(cx, &*repr, &name[..])
       }
       ty::ty_closure(did, _, ref substs) => {
           // Only create the named struct, but don't fill it in. We
@@ -343,7 +343,7 @@ fn type_of_unsize_info<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Ty
           // 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, &name[..])
       }
 
       ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) | ty::ty_ptr(ty::mt{ty, ..}) => {
@@ -399,7 +399,7 @@ fn type_of_unsize_info<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Ty
               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);
-              adt::incomplete_type_of(cx, &*repr, &name[])
+              adt::incomplete_type_of(cx, &*repr, &name[..])
           }
       }
 
index 0183b3474a509c8b41266d7123dcba67c8c51401..e3c1c66f78c9c47774ee1740b52a42a538f45c37 100644 (file)
@@ -404,17 +404,30 @@ fn create_substs_for_ast_path<'tcx>(
 
     let actual_supplied_ty_param_count = substs.types.len(TypeSpace);
     for param in &ty_param_defs[actual_supplied_ty_param_count..] {
-        match param.default {
-            Some(default) => {
+        if let Some(default) = param.default {
+            // If we are converting an object type, then the
+            // `Self` parameter is unknown. However, some of the
+            // other type parameters may reference `Self` in their
+            // defaults. This will lead to an ICE if we are not
+            // careful!
+            if self_ty.is_none() && ty::type_has_self(default) {
+                tcx.sess.span_err(
+                    span,
+                    &format!("the type parameter `{}` must be explicitly specified \
+                              in an object type because its default value `{}` references \
+                              the type `Self`",
+                             param.name.user_string(tcx),
+                             default.user_string(tcx)));
+                substs.types.push(TypeSpace, tcx.types.err);
+            } else {
                 // This is a default type parameter.
                 let default = default.subst_spanned(tcx,
                                                     &substs,
                                                     Some(span));
                 substs.types.push(TypeSpace, default);
             }
-            None => {
-                tcx.sess.span_bug(span, "extra parameter without default");
-            }
+        } else {
+            tcx.sess.span_bug(span, "extra parameter without default");
         }
     }
 
@@ -1139,14 +1152,14 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
                 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[]) {
+                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[])
+                                                 &bounds[..])
                     }
                     Err(ErrorReported) => {
                         this.tcx().types.err
@@ -1185,7 +1198,7 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
                 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[])
+                conv_ty_poly_trait_ref(this, rscope, ast_ty.span, &bounds[..])
             }
             ast::TyPath(ref path, id) => {
                 let a_def = match tcx.def_map.borrow().get(&id) {
@@ -1424,7 +1437,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>,
             // Skip the first argument if `self` is present.
             &self_and_input_tys[1..]
         } else {
-            &self_and_input_tys[]
+            &self_and_input_tys[..]
         };
 
         let (ior, lfp) = find_implied_output_region(input_tys, input_pats);
@@ -1623,7 +1636,7 @@ fn conv_ty_poly_trait_ref<'tcx>(
     ast_bounds: &[ast::TyParamBound])
     -> Ty<'tcx>
 {
-    let mut partitioned_bounds = partition_bounds(this.tcx(), span, &ast_bounds[]);
+    let mut partitioned_bounds = partition_bounds(this.tcx(), span, &ast_bounds[..]);
 
     let mut projection_bounds = Vec::new();
     let main_trait_bound = if !partitioned_bounds.trait_bounds.is_empty() {
index 0d30741978a5a5c109a285b04bbf142045ac3509..34c52981b794dff838208073f38a0d048a9cb59f 100644 (file)
@@ -162,7 +162,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
             check_pat_enum(pcx, pat, &path, Some(&[]), expected);
         }
         ast::PatEnum(ref path, ref subpats) => {
-            let subpats = subpats.as_ref().map(|v| &v[]);
+            let subpats = subpats.as_ref().map(|v| &v[..]);
             check_pat_enum(pcx, pat, path, subpats, expected);
         }
         ast::PatStruct(ref path, ref fields, etc) => {
index 7354ea7377c36126f40d9e22d25e83177ae2d09c..0ad15456df98f16daab554c59b289287426b0523 100644 (file)
@@ -256,7 +256,7 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
     check_argument_types(fcx,
                          call_expr.span,
                          &fn_sig.inputs,
-                         &expected_arg_tys[],
+                         &expected_arg_tys[..],
                          arg_exprs,
                          AutorefArgs::No,
                          fn_sig.variadic,
index da25719baaa4ab3f06e67dec3adfcb5420b94465..4aaaf4ffe5ab3028aa982a204df157ec4d289670 100644 (file)
@@ -329,6 +329,9 @@ fn accumulate_from_adt(&mut self,
     fn accumulate_from_assoc_types_transitive(&mut self,
                                               data: &ty::PolyTraitPredicate<'tcx>)
     {
+        debug!("accumulate_from_assoc_types_transitive({})",
+               data.repr(self.tcx()));
+
         for poly_trait_ref in traits::supertraits(self.tcx(), data.to_poly_trait_ref()) {
             match ty::no_late_bound_regions(self.tcx(), &poly_trait_ref) {
                 Some(trait_ref) => { self.accumulate_from_assoc_types(trait_ref); }
@@ -340,6 +343,9 @@ fn accumulate_from_assoc_types_transitive(&mut self,
     fn accumulate_from_assoc_types(&mut self,
                                    trait_ref: Rc<ty::TraitRef<'tcx>>)
     {
+        debug!("accumulate_from_assoc_types({})",
+               trait_ref.repr(self.tcx()));
+
         let trait_def_id = trait_ref.def_id;
         let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
         let assoc_type_projections: Vec<_> =
@@ -347,6 +353,8 @@ fn accumulate_from_assoc_types(&mut self,
                      .iter()
                      .map(|&name| ty::mk_projection(self.tcx(), trait_ref.clone(), name))
                      .collect();
+        debug!("accumulate_from_assoc_types: assoc_type_projections={}",
+               assoc_type_projections.repr(self.tcx()));
         let tys = match self.fully_normalize(&assoc_type_projections) {
             Ok(tys) => { tys }
             Err(ErrorReported) => { return; }
index 82bd4ae87ffae8d9cecefac8af626982caa1c848..978fbbbcffc33e7dfec2e527fb4bc9dff9e8a030 100644 (file)
@@ -901,7 +901,7 @@ fn consider_candidates(&self,
         debug!("applicable_candidates: {}", applicable_candidates.repr(self.tcx()));
 
         if applicable_candidates.len() > 1 {
-            match self.collapse_candidates_to_trait_pick(&applicable_candidates[]) {
+            match self.collapse_candidates_to_trait_pick(&applicable_candidates[..]) {
                 Some(pick) => { return Some(Ok(pick)); }
                 None => { }
             }
index 063300a1d72803778be778f1febfaf6036da028a..1639772103b7aef5f95e7c5b6a6674d99b083152 100644 (file)
@@ -172,7 +172,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             traits_are = if candidates.len() == 1 {"trait is"} else {"traits are"},
             one_of_them = if candidates.len() == 1 {"it"} else {"one of them"});
 
-        fcx.sess().fileline_help(span, &msg[]);
+        fcx.sess().fileline_help(span, &msg[..]);
 
         for (i, trait_did) in candidates.iter().enumerate() {
             fcx.sess().fileline_help(span,
@@ -218,7 +218,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             one_of_them = if candidates.len() == 1 {"it"} else {"one of them"},
             name = method_ustring);
 
-        fcx.sess().fileline_help(span, &msg[]);
+        fcx.sess().fileline_help(span, &msg[..]);
 
         for (i, trait_info) in candidates.iter().enumerate() {
             fcx.sess().fileline_help(span,
@@ -306,10 +306,10 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> {
         // Crate-local:
         //
         // meh.
-        struct Visitor<'a, 'b: 'a, 'tcx: 'a + 'b> {
+        struct Visitor<'a> {
             traits: &'a mut AllTraitsVec,
         }
-        impl<'v,'a, 'b, 'tcx> visit::Visitor<'v> for Visitor<'a, 'b, 'tcx> {
+        impl<'v, 'a> visit::Visitor<'v> for Visitor<'a> {
             fn visit_item(&mut self, i: &'v ast::Item) {
                 match i.node {
                     ast::ItemTrait(..) => {
index 3c2888e227803cead4903225fd156d7729fa58fe..e443b4d0e606abd082e45a8fdd9f8b4e8efec526 100644 (file)
@@ -638,7 +638,7 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
     // Remember return type so that regionck can access it later.
     let mut fn_sig_tys: Vec<Ty> =
         arg_tys.iter()
-        .map(|&ty| ty)
+        .cloned()
         .collect();
 
     if let ty::FnConverging(ret_ty) = ret_ty {
@@ -2208,7 +2208,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 
         check_argument_types(fcx,
                              sp,
-                             &err_inputs[],
+                             &err_inputs[..],
                              &[],
                              args_no_rcvr,
                              autoref_args,
@@ -2227,7 +2227,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 check_argument_types(fcx,
                                      sp,
                                      &fty.sig.0.inputs[1..],
-                                     &expected_arg_tys[],
+                                     &expected_arg_tys[..],
                                      args_no_rcvr,
                                      autoref_args,
                                      fty.sig.0.variadic,
@@ -3054,7 +3054,7 @@ fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                     ty::ty_struct(base_id, substs) => {
                         debug!("struct named {}", ppaux::ty_to_string(tcx, base_t));
                         let fields = ty::lookup_struct_fields(tcx, base_id);
-                        fcx.lookup_field_ty(expr.span, base_id, &fields[],
+                        fcx.lookup_field_ty(expr.span, base_id, &fields[..],
                                             field.node.name, &(*substs))
                     }
                     _ => None
@@ -3154,7 +3154,7 @@ fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                         if tuple_like {
                             debug!("tuple struct named {}", ppaux::ty_to_string(tcx, base_t));
                             let fields = ty::lookup_struct_fields(tcx, base_id);
-                            fcx.lookup_tup_field_ty(expr.span, base_id, &fields[],
+                            fcx.lookup_tup_field_ty(expr.span, base_id, &fields[..],
                                                     idx.node, &(*substs))
                         } else {
                             None
@@ -3219,7 +3219,7 @@ fn check_struct_or_variant_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         for field in ast_fields {
             let mut expected_field_type = tcx.types.err;
 
-            let pair = class_field_map.get(&field.ident.node.name).map(|x| *x);
+            let pair = class_field_map.get(&field.ident.node.name).cloned();
             match pair {
                 None => {
                     fcx.type_error_message(
@@ -3327,7 +3327,7 @@ fn check_struct_constructor<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                                        class_id,
                                        id,
                                        fcx.ccx.tcx.mk_substs(struct_substs),
-                                       &class_fields[],
+                                       &class_fields[..],
                                        fields,
                                        base_expr.is_none(),
                                        None);
@@ -3370,7 +3370,7 @@ fn check_struct_enum_variant<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                                        variant_id,
                                        id,
                                        fcx.ccx.tcx.mk_substs(substitutions),
-                                       &variant_fields[],
+                                       &variant_fields[..],
                                        fields,
                                        true,
                                        Some(enum_id));
@@ -3731,10 +3731,10 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
         fcx.write_ty(id, fcx.node_ty(b.id));
       }
       ast::ExprCall(ref callee, ref args) => {
-          callee::check_call(fcx, expr, &**callee, &args[], expected);
+          callee::check_call(fcx, expr, &**callee, &args[..], expected);
       }
       ast::ExprMethodCall(ident, ref tps, ref args) => {
-        check_method_call(fcx, expr, ident, &args[], &tps[], expected, lvalue_pref);
+        check_method_call(fcx, expr, ident, &args[..], &tps[..], expected, lvalue_pref);
         let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
         let  args_err = arg_tys.fold(false,
              |rest_err, a| {
@@ -3821,7 +3821,7 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
       ast::ExprTup(ref elts) => {
         let flds = expected.only_has_type(fcx).and_then(|ty| {
             match ty.sty {
-                ty::ty_tup(ref flds) => Some(&flds[]),
+                ty::ty_tup(ref flds) => Some(&flds[..]),
                 _ => None
             }
         });
@@ -3851,11 +3851,11 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
       }
       ast::ExprStruct(ref path, ref fields, ref base_expr) => {
         // Resolve the path.
-        let def = tcx.def_map.borrow().get(&id).map(|i| *i);
+        let def = tcx.def_map.borrow().get(&id).cloned();
         let struct_id = match def {
             Some(def::DefVariant(enum_id, variant_id, true)) => {
                 check_struct_enum_variant(fcx, id, expr.span, enum_id,
-                                          variant_id, &fields[]);
+                                          variant_id, &fields[..]);
                 enum_id
             }
             Some(def::DefTrait(def_id)) => {
@@ -3864,7 +3864,7 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                     pprust::path_to_string(path));
                 check_struct_fields_on_error(fcx,
                                              id,
-                                             &fields[],
+                                             &fields[..],
                                              base_expr);
                 def_id
             },
@@ -3877,7 +3877,7 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                                                  id,
                                                  expr.span,
                                                  struct_did,
-                                                 &fields[],
+                                                 &fields[..],
                                                  base_expr.as_ref().map(|e| &**e));
                     }
                     _ => {
@@ -3886,7 +3886,7 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                             pprust::path_to_string(path));
                         check_struct_fields_on_error(fcx,
                                                      id,
-                                                     &fields[],
+                                                     &fields[..],
                                                      base_expr);
                     }
                 }
@@ -5231,10 +5231,10 @@ fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> {
             }
         };
         (n_tps, inputs, ty::FnConverging(output))
-    } else if &name[] == "abort" || &name[] == "unreachable" {
+    } else if &name[..] == "abort" || &name[..] == "unreachable" {
         (0, Vec::new(), ty::FnDiverging)
     } else {
-        let (n_tps, inputs, output) = match &name[] {
+        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),
@@ -5259,7 +5259,7 @@ fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> {
             "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[]); }
+                  Err(s) => { span_fatal!(tcx.sess, it.span, E0240, "{}", &s[..]); }
               };
               let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
                   ty: tydesc_ty,
index 4e5550a2106a98aa64cc38dfc118e1e97af829b8..82abff8c425f42c5aca7d2aa62f73ac9c85a78de 100644 (file)
@@ -294,8 +294,8 @@ fn visit_fn_body(&mut self,
 
         let len = self.region_bound_pairs.len();
         let old_body_id = self.set_body_id(body.id);
-        self.relate_free_regions(&fn_sig[], body.id, span);
-        link_fn_args(self, CodeExtent::from_node_id(body.id), &fn_decl.inputs[]);
+        self.relate_free_regions(&fn_sig[..], body.id, span);
+        link_fn_args(self, CodeExtent::from_node_id(body.id), &fn_decl.inputs[..]);
         self.visit_block(body);
         self.visit_region_obligations(body.id);
         self.region_bound_pairs.truncate(len);
@@ -626,6 +626,20 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             visit::walk_expr(rcx, expr);
         }
 
+        ast::ExprBinary(_, ref lhs, ref rhs) => {
+            // If you do `x OP y`, then the types of `x` and `y` must
+            // outlive the operation you are performing.
+            let lhs_ty = rcx.resolve_expr_type_adjusted(&**lhs);
+            let rhs_ty = rcx.resolve_expr_type_adjusted(&**rhs);
+            for &ty in [lhs_ty, rhs_ty].iter() {
+                type_must_outlive(rcx,
+                                  infer::Operand(expr.span),
+                                  ty,
+                                  ty::ReScope(CodeExtent::from_node_id(expr.id)));
+            }
+            visit::walk_expr(rcx, expr);
+        }
+
         ast::ExprUnary(op, ref lhs) if has_method_map => {
             let implicitly_ref_args = !ast_util::is_by_value_unop(op);
 
@@ -690,7 +704,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
         }
 
         ast::ExprMatch(ref discr, ref arms, _) => {
-            link_match(rcx, &**discr, &arms[]);
+            link_match(rcx, &**discr, &arms[..]);
 
             visit::walk_expr(rcx, expr);
         }
index 2e7eff68bd509cbda58695fac27b13b0da799dfe..3666b69d1c678ac4cc6a64d60118b794f4bdf449 100644 (file)
@@ -126,6 +126,13 @@ pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>,
                     "the trait cannot require that `Self : Sized`");
             }
 
+            ObjectSafetyViolation::SupertraitSelf => {
+                tcx.sess.span_note(
+                    span,
+                    "the trait cannot use `Self` as a type parameter \
+                     in the supertrait listing");
+            }
+
             ObjectSafetyViolation::Method(method, MethodViolationCode::ByValueSelf) => {
                 tcx.sess.span_note(
                     span,
index d124282d391281c65137ec6c2a1cccad466a3ecc..2601c4d275291d144762ff46ac1484aee3e3b5eb 100644 (file)
 
 use astconv::AstConv;
 use check::{FnCtxt, Inherited, blank_fn_ctxt, vtable, regionck};
+use constrained_type_params::identify_constrained_type_params;
 use CrateCtxt;
 use middle::region;
-use middle::subst;
+use middle::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace};
 use middle::traits;
 use middle::ty::{self, Ty};
 use middle::ty::liberate_late_bound_regions;
 use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty};
-use util::ppaux::Repr;
+use util::ppaux::{Repr, UserString};
 
 use std::collections::HashSet;
 use syntax::ast;
 use syntax::ast_util::{local_def};
 use syntax::attr;
 use syntax::codemap::Span;
-use syntax::parse::token;
+use syntax::parse::token::{self, special_idents};
 use syntax::visit;
 use syntax::visit::Visitor;
 
@@ -38,6 +39,10 @@ pub fn new(ccx: &'ccx CrateCtxt<'ccx, 'tcx>) -> CheckTypeWellFormedVisitor<'ccx,
         CheckTypeWellFormedVisitor { ccx: ccx, cache: HashSet::new() }
     }
 
+    fn tcx(&self) -> &ty::ctxt<'tcx> {
+        self.ccx.tcx
+    }
+
     /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
     /// well-formed, meaning that they do not require any constraints not declared in the struct
     /// definition itself. For example, this definition would be illegal:
@@ -96,19 +101,29 @@ fn check_item_well_formed(&mut self, item: &ast::Item) {
             ast::ItemConst(..) => {
                 self.check_item_type(item);
             }
-            ast::ItemStruct(ref struct_def, _) => {
-                self.check_type_defn(item, |fcx| vec![struct_variant(fcx, &**struct_def)]);
+            ast::ItemStruct(ref struct_def, ref ast_generics) => {
+                self.check_type_defn(item, |fcx| {
+                    vec![struct_variant(fcx, &**struct_def)]
+                });
+
+                self.check_variances_for_type_defn(item, ast_generics);
             }
-            ast::ItemEnum(ref enum_def, _) => {
-                self.check_type_defn(item, |fcx| enum_variants(fcx, enum_def));
+            ast::ItemEnum(ref enum_def, ref ast_generics) => {
+                self.check_type_defn(item, |fcx| {
+                    enum_variants(fcx, enum_def)
+                });
+
+                self.check_variances_for_type_defn(item, ast_generics);
             }
-            ast::ItemTrait(..) => {
+            ast::ItemTrait(_, ref ast_generics, _, _) => {
                 let trait_predicates =
                     ty::lookup_predicates(ccx.tcx, local_def(item.id));
                 reject_non_type_param_bounds(
                     ccx.tcx,
                     item.span,
                     &trait_predicates);
+                self.check_variances(item, ast_generics, &trait_predicates,
+                                     self.tcx().lang_items.phantom_fn());
             }
             _ => {}
         }
@@ -276,6 +291,123 @@ fn check_impl(&mut self,
             }
         });
     }
+
+    fn check_variances_for_type_defn(&self,
+                                     item: &ast::Item,
+                                     ast_generics: &ast::Generics)
+    {
+        let item_def_id = local_def(item.id);
+        let predicates = ty::lookup_predicates(self.tcx(), item_def_id);
+        self.check_variances(item,
+                             ast_generics,
+                             &predicates,
+                             self.tcx().lang_items.phantom_data());
+    }
+
+    fn check_variances(&self,
+                       item: &ast::Item,
+                       ast_generics: &ast::Generics,
+                       ty_predicates: &ty::GenericPredicates<'tcx>,
+                       suggested_marker_id: Option<ast::DefId>)
+    {
+        let variance_lang_items = &[
+            self.tcx().lang_items.phantom_fn(),
+            self.tcx().lang_items.phantom_data(),
+        ];
+
+        let item_def_id = local_def(item.id);
+        let is_lang_item = variance_lang_items.iter().any(|n| *n == Some(item_def_id));
+        if is_lang_item {
+            return;
+        }
+
+        let variances = ty::item_variances(self.tcx(), item_def_id);
+
+        let mut constrained_parameters: HashSet<_> =
+            variances.types
+            .iter_enumerated()
+            .filter(|&(_, _, &variance)| variance != ty::Bivariant)
+            .map(|(space, index, _)| self.param_ty(ast_generics, space, index))
+            .collect();
+
+        identify_constrained_type_params(self.tcx(),
+                                         ty_predicates.predicates.as_slice(),
+                                         None,
+                                         &mut constrained_parameters);
+
+        for (space, index, _) in variances.types.iter_enumerated() {
+            let param_ty = self.param_ty(ast_generics, space, index);
+            if constrained_parameters.contains(&param_ty) {
+                continue;
+            }
+            let span = self.ty_param_span(ast_generics, item, space, index);
+            self.report_bivariance(span, param_ty.name, suggested_marker_id);
+        }
+
+        for (space, index, &variance) in variances.regions.iter_enumerated() {
+            if variance != ty::Bivariant {
+                continue;
+            }
+
+            assert_eq!(space, TypeSpace);
+            let span = ast_generics.lifetimes[index].lifetime.span;
+            let name = ast_generics.lifetimes[index].lifetime.name;
+            self.report_bivariance(span, name, suggested_marker_id);
+        }
+    }
+
+    fn param_ty(&self,
+                ast_generics: &ast::Generics,
+                space: ParamSpace,
+                index: usize)
+                -> ty::ParamTy
+    {
+        let name = match space {
+            TypeSpace => ast_generics.ty_params[index].ident.name,
+            SelfSpace => special_idents::type_self.name,
+            FnSpace => self.tcx().sess.bug("Fn space occupied?"),
+        };
+
+        ty::ParamTy { space: space, idx: index as u32, name: name }
+    }
+
+    fn ty_param_span(&self,
+                     ast_generics: &ast::Generics,
+                     item: &ast::Item,
+                     space: ParamSpace,
+                     index: usize)
+                     -> Span
+    {
+        match space {
+            TypeSpace => ast_generics.ty_params[index].span,
+            SelfSpace => item.span,
+            FnSpace => self.tcx().sess.span_bug(item.span, "Fn space occupied?"),
+        }
+    }
+
+    fn report_bivariance(&self,
+                         span: Span,
+                         param_name: ast::Name,
+                         suggested_marker_id: Option<ast::DefId>)
+    {
+        self.tcx().sess.span_err(
+            span,
+            &format!("parameter `{}` is never used",
+                     param_name.user_string(self.tcx()))[]);
+
+        match suggested_marker_id {
+            Some(def_id) => {
+                self.tcx().sess.span_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());
+            }
+            None => {
+                // no lang items, no help!
+            }
+        }
+    }
 }
 
 // Reject any predicates that do not involve a type parameter.
@@ -343,9 +475,9 @@ fn visit_fn(&mut self,
         match fk {
             visit::FkFnBlock | visit::FkItemFn(..) => {}
             visit::FkMethod(..) => {
-                match ty::impl_or_trait_item(self.ccx.tcx, local_def(id)) {
+                match ty::impl_or_trait_item(self.tcx(), local_def(id)) {
                     ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
-                        reject_shadowing_type_parameters(self.ccx.tcx, span, &ty_method.generics)
+                        reject_shadowing_type_parameters(self.tcx(), span, &ty_method.generics)
                     }
                     _ => {}
                 }
@@ -359,14 +491,14 @@ fn visit_trait_item(&mut self, t: &'v ast::TraitItem) {
             &ast::TraitItem::ProvidedMethod(_) |
             &ast::TraitItem::TypeTraitItem(_) => {},
             &ast::TraitItem::RequiredMethod(ref method) => {
-                match ty::impl_or_trait_item(self.ccx.tcx, local_def(method.id)) {
+                match ty::impl_or_trait_item(self.tcx(), local_def(method.id)) {
                     ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
                         reject_non_type_param_bounds(
-                            self.ccx.tcx,
+                            self.tcx(),
                             method.span,
                             &ty_method.predicates);
                         reject_shadowing_type_parameters(
-                            self.ccx.tcx,
+                            self.tcx(),
                             method.span,
                             &ty_method.generics);
                     }
index 44e850a0738001e71c081dd2d6a66b29010a12a1..0b78af18e2617b2869bba2d8431488275e11f620 100644 (file)
@@ -87,6 +87,7 @@ trait hierarchy is only necessary for shorthands like `T::X` or
 
 use astconv::{self, AstConv, ty_of_arg, ast_ty_to_ty, ast_region_to_region};
 use middle::def;
+use constrained_type_params::identify_constrained_type_params;
 use middle::lang_items::SizedTraitLangItem;
 use middle::region;
 use middle::resolve_lifetime;
@@ -268,7 +269,7 @@ fn get_enum_variant_types<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
             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)
+                ty::mk_ctor_fn(tcx, variant_def_id, &input_tys[..], enum_scheme.ty)
             }
 
             ast::TupleVariantKind(_) => {
@@ -313,7 +314,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
                                     trait_id,
                                     &trait_def.generics,
                                     &trait_predicates,
-                                    &trait_items[],
+                                    &trait_items[..],
                                     &m.id,
                                     &m.ident.name,
                                     &m.explicit_self,
@@ -328,7 +329,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
                                     trait_id,
                                     &trait_def.generics,
                                     &trait_predicates,
-                                    &trait_items[],
+                                    &trait_items[..],
                                     &m.id,
                                     &m.pe_ident().name,
                                     m.pe_explicit_self(),
@@ -871,7 +872,7 @@ fn convert_struct<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
                             local_def(field.node.id)].ty).collect();
                 let ctor_fn_ty = ty::mk_ctor_fn(tcx,
                                                 local_def(ctor_id),
-                                                &inputs[],
+                                                &inputs[..],
                                                 selfty);
                 write_ty_to_tcx(tcx, ctor_id, ctor_fn_ty);
                 tcx.tcache.borrow_mut().insert(local_def(ctor_id),
@@ -1358,7 +1359,7 @@ fn ty_generics_for_fn_or_method<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
     let early_lifetimes = resolve_lifetime::early_bound_lifetimes(generics);
     ty_generics(ccx,
                 subst::FnSpace,
-                &early_lifetimes[],
+                &early_lifetimes[..],
                 &generics.ty_params[],
                 &generics.where_clause,
                 base_generics)
@@ -1960,51 +1961,15 @@ fn enforce_impl_ty_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
     let mut input_parameters: HashSet<_> =
         impl_trait_ref.iter()
                       .flat_map(|t| t.input_types().iter()) // Types in trait ref, if any
-                      .chain(Some(impl_scheme.ty).iter())  // Self type, always
+                      .chain(Some(impl_scheme.ty).iter())   // Self type, always
                       .flat_map(|t| t.walk())
-                      .filter_map(to_opt_param_ty)
+                      .filter_map(|t| t.as_opt_param_ty())
                       .collect();
 
-    loop {
-        let num_inputs = input_parameters.len();
-
-        let projection_predicates =
-            impl_predicates.predicates
-                           .iter()
-                           .filter_map(|predicate| {
-                               match *predicate {
-                                   // Ignore higher-ranked binders. For the purposes
-                                   // of this check, they don't matter because they
-                                   // only affect named regions, and we're just
-                                   // concerned about type parameters here.
-                                   ty::Predicate::Projection(ref data) => Some(data.0.clone()),
-                                   _ => None,
-                               }
-                           });
-
-        for projection in projection_predicates {
-            // Special case: watch out for some kind of sneaky attempt
-            // to project out an associated type defined by this very trait.
-            if Some(projection.projection_ty.trait_ref.clone()) == impl_trait_ref {
-                continue;
-            }
-
-            let relies_only_on_inputs =
-                projection.projection_ty.trait_ref.input_types().iter()
-                .flat_map(|t| t.walk())
-                .filter_map(to_opt_param_ty)
-                .all(|t| input_parameters.contains(&t));
-
-            if relies_only_on_inputs {
-                input_parameters.extend(
-                    projection.ty.walk().filter_map(to_opt_param_ty));
-            }
-        }
-
-        if input_parameters.len() == num_inputs {
-            break;
-        }
-    }
+    identify_constrained_type_params(tcx,
+                                     impl_predicates.predicates.as_slice(),
+                                     impl_trait_ref,
+                                     &mut input_parameters);
 
     for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
         let param_ty = ty::ParamTy { space: TypeSpace,
@@ -2025,11 +1990,4 @@ impl trait, self type, or predicates",
             }
         }
     }
-
-    fn to_opt_param_ty<'tcx>(ty: Ty<'tcx>) -> Option<ty::ParamTy> {
-        match ty.sty {
-            ty::ty_param(ref d) => Some(d.clone()),
-            _ => None,
-        }
-    }
 }
diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs
new file mode 100644 (file)
index 0000000..83d7e98
--- /dev/null
@@ -0,0 +1,61 @@
+// 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 middle::ty::{self};
+
+use std::collections::HashSet;
+use std::rc::Rc;
+
+pub fn identify_constrained_type_params<'tcx>(_tcx: &ty::ctxt<'tcx>,
+                                              predicates: &[ty::Predicate<'tcx>],
+                                              impl_trait_ref: Option<Rc<ty::TraitRef<'tcx>>>,
+                                              input_parameters: &mut HashSet<ty::ParamTy>)
+{
+    loop {
+        let num_inputs = input_parameters.len();
+
+        let projection_predicates =
+            predicates.iter()
+                      .filter_map(|predicate| {
+                          match *predicate {
+                              // Ignore higher-ranked binders. For the purposes
+                              // of this check, they don't matter because they
+                              // only affect named regions, and we're just
+                              // concerned about type parameters here.
+                              ty::Predicate::Projection(ref data) => Some(data.0.clone()),
+                              _ => None,
+                          }
+                      });
+
+        for projection in projection_predicates {
+            // Special case: watch out for some kind of sneaky attempt
+            // to project out an associated type defined by this very trait.
+            if Some(projection.projection_ty.trait_ref.clone()) == impl_trait_ref {
+                continue;
+            }
+
+            let relies_only_on_inputs =
+                projection.projection_ty.trait_ref.input_types()
+                                                  .iter()
+                                                  .flat_map(|t| t.walk())
+                                                  .filter_map(|t| t.as_opt_param_ty())
+                                                  .all(|t| input_parameters.contains(&t));
+
+            if relies_only_on_inputs {
+                input_parameters.extend(
+                    projection.ty.walk().filter_map(|t| t.as_opt_param_ty()));
+            }
+        }
+
+        if input_parameters.len() == num_inputs {
+            break;
+        }
+    }
+}
index 7498dc8179d751915c6f21f84877d72bb3e23643..b5dca0bd4f6f42348e2981d23bf079541b91986b 100644 (file)
 mod rscope;
 mod astconv;
 mod collect;
+mod constrained_type_params;
 mod coherence;
 mod variance;
 
index d5883d8bf864bc3f386b3dfa4f3c763d11939a52..1adcf133bf3e0788490204a73c62a4e120497526 100644 (file)
 //!   and the definition-site variance of the [corresponding] type parameter
 //!   of a class `C` is `V1`, then the variance of `X` in the type expression
 //!   `C<E>` is `V3 = V1.xform(V2)`.
+//!
+//! ### Constraints
+//!
+//! If I have a struct or enum with where clauses:
+//!
+//!     struct Foo<T:Bar> { ... }
+//!
+//! you might wonder whether the variance of `T` with respect to `Bar`
+//! affects the variance `T` with respect to `Foo`. I claim no.  The
+//! reason: assume that `T` is invariant w/r/t `Bar` but covariant w/r/t
+//! `Foo`. And then we have a `Foo<X>` that is upcast to `Foo<Y>`, where
+//! `X <: Y`. However, while `X : Bar`, `Y : Bar` does not hold.  In that
+//! case, the upcast will be illegal, but not because of a variance
+//! 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.
 
 use self::VarianceTerm::*;
 use self::ParamKind::*;
 use middle::ty::{self, Ty};
 use std::fmt;
 use std::rc::Rc;
-use std::iter::repeat;
 use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util;
@@ -258,6 +273,11 @@ struct TermsContext<'a, 'tcx: 'a> {
 
     empty_variances: Rc<ty::ItemVariances>,
 
+    // For marker types, UnsafeCell, and other lang items where
+    // variance is hardcoded, records the item-id and the hardcoded
+    // variance.
+    lang_items: Vec<(ast::NodeId, Vec<ty::Variance>)>,
+
     // Maps from the node id of a type/generic parameter to the
     // corresponding inferred index.
     inferred_map: NodeMap<InferredIndex>,
@@ -269,7 +289,7 @@ struct TermsContext<'a, 'tcx: 'a> {
 #[derive(Copy, Debug, PartialEq)]
 enum ParamKind {
     TypeParam,
-    RegionParam
+    RegionParam,
 }
 
 struct InferredInfo<'a> {
@@ -279,6 +299,11 @@ struct InferredInfo<'a> {
     index: uint,
     param_id: ast::NodeId,
     term: VarianceTermPtr<'a>,
+
+    // Initial value to use for this parameter when inferring
+    // variance. For most parameters, this is Bivariant. But for lang
+    // items and input type parameters on traits, it is different.
+    initial_variance: ty::Variance,
 }
 
 fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
@@ -291,6 +316,8 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
         inferred_map: NodeMap(),
         inferred_infos: Vec::new(),
 
+        lang_items: lang_items(tcx),
+
         // cache and share the variance struct used for items with
         // no type/region parameters
         empty_variances: Rc::new(ty::ItemVariances {
@@ -304,7 +331,78 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
     terms_cx
 }
 
+fn lang_items(tcx: &ty::ctxt) -> Vec<(ast::NodeId,Vec<ty::Variance>)> {
+    let all = vec![
+        (tcx.lang_items.phantom_fn(), vec![ty::Contravariant, ty::Covariant]),
+        (tcx.lang_items.phantom_data(), vec![ty::Covariant]),
+        (tcx.lang_items.unsafe_cell_type(), vec![ty::Invariant]),
+
+        // Deprecated:
+        (tcx.lang_items.covariant_type(), vec![ty::Covariant]),
+        (tcx.lang_items.contravariant_type(), vec![ty::Contravariant]),
+        (tcx.lang_items.invariant_type(), vec![ty::Invariant]),
+        (tcx.lang_items.covariant_lifetime(), vec![ty::Covariant]),
+        (tcx.lang_items.contravariant_lifetime(), vec![ty::Contravariant]),
+        (tcx.lang_items.invariant_lifetime(), vec![ty::Invariant]),
+
+        ];
+
+    all.into_iter()
+       .filter(|&(ref d,_)| d.is_some())
+       .filter(|&(ref d,_)| d.as_ref().unwrap().krate == ast::LOCAL_CRATE)
+       .map(|(d, v)| (d.unwrap().node, v))
+       .collect()
+}
+
 impl<'a, 'tcx> TermsContext<'a, 'tcx> {
+    fn add_inferreds_for_item(&mut self,
+                              item_id: ast::NodeId,
+                              has_self: bool,
+                              generics: &ast::Generics)
+    {
+        /*!
+         * Add "inferreds" for the generic parameters declared on this
+         * item. This has a lot of annoying parameters because we are
+         * trying to drive this from the AST, rather than the
+         * ty::Generics, so that we can get span info -- but this
+         * means we must accommodate syntactic distinctions.
+         */
+
+        // NB: In the code below for writing the results back into the
+        // tcx, we rely on the fact that all inferreds for a particular
+        // item are assigned continuous indices.
+
+        let inferreds_on_entry = self.num_inferred();
+
+        if has_self {
+            self.add_inferred(item_id, TypeParam, SelfSpace, 0, item_id);
+        }
+
+        for (i, p) in generics.lifetimes.iter().enumerate() {
+            let id = p.lifetime.id;
+            self.add_inferred(item_id, RegionParam, TypeSpace, i, id);
+        }
+
+        for (i, p) in generics.ty_params.iter().enumerate() {
+            self.add_inferred(item_id, TypeParam, TypeSpace, i, p.id);
+        }
+
+        // If this item has no type or lifetime parameters,
+        // then there are no variances to infer, so just
+        // insert an empty entry into the variance map.
+        // Arguably we could just leave the map empty in this
+        // case but it seems cleaner to be able to distinguish
+        // "invalid item id" from "item id with no
+        // parameters".
+        if self.num_inferred() == inferreds_on_entry {
+            let newly_added =
+                self.tcx.item_variance_map.borrow_mut().insert(
+                    ast_util::local_def(item_id),
+                    self.empty_variances.clone()).is_none();
+            assert!(newly_added);
+        }
+    }
+
     fn add_inferred(&mut self,
                     item_id: ast::NodeId,
                     kind: ParamKind,
@@ -313,21 +411,48 @@ fn add_inferred(&mut self,
                     param_id: ast::NodeId) {
         let inf_index = InferredIndex(self.inferred_infos.len());
         let term = self.arena.alloc(InferredTerm(inf_index));
+        let initial_variance = self.pick_initial_variance(item_id, space, index);
         self.inferred_infos.push(InferredInfo { item_id: item_id,
                                                 kind: kind,
                                                 space: space,
                                                 index: index,
                                                 param_id: param_id,
-                                                term: term });
+                                                term: term,
+                                                initial_variance: initial_variance });
         let newly_added = self.inferred_map.insert(param_id, inf_index).is_none();
         assert!(newly_added);
 
-        debug!("add_inferred(item_id={}, \
+        debug!("add_inferred(item_path={}, \
+                item_id={}, \
                 kind={:?}, \
+                space={:?}, \
                 index={}, \
-                param_id={},
-                inf_index={:?})",
-                item_id, kind, index, param_id, inf_index);
+                param_id={}, \
+                inf_index={:?}, \
+                initial_variance={:?})",
+               ty::item_path_str(self.tcx, ast_util::local_def(item_id)),
+               item_id, kind, space, index, param_id, inf_index,
+               initial_variance);
+    }
+
+    fn pick_initial_variance(&self,
+                             item_id: ast::NodeId,
+                             space: ParamSpace,
+                             index: uint)
+                             -> ty::Variance
+    {
+        match space {
+            SelfSpace | FnSpace => {
+                ty::Bivariant
+            }
+
+            TypeSpace => {
+                match self.lang_items.iter().find(|&&(n, _)| n == item_id) {
+                    Some(&(_, ref variances)) => variances[index],
+                    None => ty::Bivariant
+                }
+            }
+        }
     }
 
     fn num_inferred(&self) -> uint {
@@ -339,44 +464,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
     fn visit_item(&mut self, item: &ast::Item) {
         debug!("add_inferreds for item {}", item.repr(self.tcx));
 
-        let inferreds_on_entry = self.num_inferred();
-
-        // NB: In the code below for writing the results back into the
-        // tcx, we rely on the fact that all inferreds for a particular
-        // item are assigned continuous indices.
-        match item.node {
-            ast::ItemTrait(..) => {
-                self.add_inferred(item.id, TypeParam, SelfSpace, 0, item.id);
-            }
-            _ => { }
-        }
-
         match item.node {
             ast::ItemEnum(_, ref generics) |
-            ast::ItemStruct(_, ref generics) |
+            ast::ItemStruct(_, ref generics) => {
+                self.add_inferreds_for_item(item.id, false, generics);
+            }
             ast::ItemTrait(_, ref generics, _, _) => {
-                for (i, p) in generics.lifetimes.iter().enumerate() {
-                    let id = p.lifetime.id;
-                    self.add_inferred(item.id, RegionParam, TypeSpace, i, id);
-                }
-                for (i, p) in generics.ty_params.iter().enumerate() {
-                    self.add_inferred(item.id, TypeParam, TypeSpace, i, p.id);
-                }
-
-                // If this item has no type or lifetime parameters,
-                // then there are no variances to infer, so just
-                // insert an empty entry into the variance map.
-                // Arguably we could just leave the map empty in this
-                // case but it seems cleaner to be able to distinguish
-                // "invalid item id" from "item id with no
-                // parameters".
-                if self.num_inferred() == inferreds_on_entry {
-                    let newly_added = self.tcx.item_variance_map.borrow_mut().insert(
-                        ast_util::local_def(item.id),
-                        self.empty_variances.clone()).is_none();
-                    assert!(newly_added);
-                }
-
+                self.add_inferreds_for_item(item.id, true, generics);
                 visit::walk_item(self, item);
             }
 
@@ -404,16 +498,6 @@ fn visit_item(&mut self, item: &ast::Item) {
 struct ConstraintContext<'a, 'tcx: 'a> {
     terms_cx: TermsContext<'a, 'tcx>,
 
-    // These are the def-id of the std::marker::InvariantType,
-    // std::marker::InvariantLifetime, and so on. The arrays
-    // are indexed by the `ParamKind` (type, lifetime, self). Note
-    // that there are no marker types for self, so the entries for
-    // self are always None.
-    invariant_lang_items: [Option<ast::DefId>; 2],
-    covariant_lang_items: [Option<ast::DefId>; 2],
-    contravariant_lang_items: [Option<ast::DefId>; 2],
-    unsafe_cell_lang_item: Option<ast::DefId>,
-
     // These are pointers to common `ConstantTerm` instances
     covariant: VarianceTermPtr<'a>,
     contravariant: VarianceTermPtr<'a>,
@@ -433,40 +517,14 @@ struct Constraint<'a> {
 
 fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>,
                                         krate: &ast::Crate)
-                                        -> ConstraintContext<'a, 'tcx> {
-    let mut invariant_lang_items = [None; 2];
-    let mut covariant_lang_items = [None; 2];
-    let mut contravariant_lang_items = [None; 2];
-
-    covariant_lang_items[TypeParam as uint] =
-        terms_cx.tcx.lang_items.covariant_type();
-    covariant_lang_items[RegionParam as uint] =
-        terms_cx.tcx.lang_items.covariant_lifetime();
-
-    contravariant_lang_items[TypeParam as uint] =
-        terms_cx.tcx.lang_items.contravariant_type();
-    contravariant_lang_items[RegionParam as uint] =
-        terms_cx.tcx.lang_items.contravariant_lifetime();
-
-    invariant_lang_items[TypeParam as uint] =
-        terms_cx.tcx.lang_items.invariant_type();
-    invariant_lang_items[RegionParam as uint] =
-        terms_cx.tcx.lang_items.invariant_lifetime();
-
-    let unsafe_cell_lang_item = terms_cx.tcx.lang_items.unsafe_cell_type();
-
+                                        -> ConstraintContext<'a, 'tcx>
+{
     let covariant = terms_cx.arena.alloc(ConstantTerm(ty::Covariant));
     let contravariant = terms_cx.arena.alloc(ConstantTerm(ty::Contravariant));
     let invariant = terms_cx.arena.alloc(ConstantTerm(ty::Invariant));
     let bivariant = terms_cx.arena.alloc(ConstantTerm(ty::Bivariant));
     let mut constraint_cx = ConstraintContext {
         terms_cx: terms_cx,
-
-        invariant_lang_items: invariant_lang_items,
-        covariant_lang_items: covariant_lang_items,
-        contravariant_lang_items: contravariant_lang_items,
-        unsafe_cell_lang_item: unsafe_cell_lang_item,
-
         covariant: covariant,
         contravariant: contravariant,
         invariant: invariant,
@@ -487,7 +545,13 @@ fn visit_item(&mut self, item: &ast::Item) {
 
         match item.node {
             ast::ItemEnum(ref enum_definition, _) => {
-                let generics = &ty::lookup_item_type(tcx, did).generics;
+                let scheme = ty::lookup_item_type(tcx, did);
+
+                // Not entirely obvious: constraints on structs/enums do not
+                // affect the variance of their type parameters. See discussion
+                // in comment at top of module.
+                //
+                // self.add_constraints_from_generics(&scheme.generics);
 
                 // Hack: If we directly call `ty::enum_variants`, it
                 // annoyingly takes it upon itself to run off and
@@ -505,29 +569,48 @@ fn visit_item(&mut self, item: &ast::Item) {
                                                           &**ast_variant,
                                                           /*discriminant*/ 0);
                     for arg_ty in &variant.args {
-                        self.add_constraints_from_ty(generics, *arg_ty, self.covariant);
+                        self.add_constraints_from_ty(&scheme.generics, *arg_ty, self.covariant);
                     }
                 }
             }
 
             ast::ItemStruct(..) => {
-                let generics = &ty::lookup_item_type(tcx, did).generics;
+                let scheme = ty::lookup_item_type(tcx, did);
+
+                // Not entirely obvious: constraints on structs/enums do not
+                // affect the variance of their type parameters. See discussion
+                // in comment at top of module.
+                //
+                // self.add_constraints_from_generics(&scheme.generics);
+
                 let struct_fields = ty::lookup_struct_fields(tcx, did);
                 for field_info in &struct_fields {
                     assert_eq!(field_info.id.krate, ast::LOCAL_CRATE);
                     let field_ty = ty::node_id_to_type(tcx, field_info.id.node);
-                    self.add_constraints_from_ty(generics, field_ty, self.covariant);
+                    self.add_constraints_from_ty(&scheme.generics, field_ty, self.covariant);
                 }
             }
 
             ast::ItemTrait(..) => {
+                let trait_def = ty::lookup_trait_def(tcx, did);
+                let predicates = ty::predicates(tcx, ty::mk_self_type(tcx), &trait_def.bounds);
+                self.add_constraints_from_predicates(&trait_def.generics,
+                                                     &predicates[],
+                                                     self.covariant);
+
                 let trait_items = ty::trait_items(tcx, did);
                 for trait_item in &*trait_items {
                     match *trait_item {
                         ty::MethodTraitItem(ref method) => {
-                            self.add_constraints_from_sig(&method.generics,
-                                                          &method.fty.sig,
-                                                          self.covariant);
+                            self.add_constraints_from_predicates(
+                                &method.generics,
+                                method.predicates.predicates.get_slice(FnSpace),
+                                self.contravariant);
+
+                            self.add_constraints_from_sig(
+                                &method.generics,
+                                &method.fty.sig,
+                                self.covariant);
                         }
                         ty::TypeTraitItem(_) => {}
                     }
@@ -544,9 +627,10 @@ fn visit_item(&mut self, item: &ast::Item) {
             ast::ItemTy(..) |
             ast::ItemImpl(..) |
             ast::ItemMac(..) => {
-                visit::walk_item(self, item);
             }
         }
+
+        visit::walk_item(self, item);
     }
 }
 
@@ -648,15 +732,7 @@ fn declared_variance(&self,
                          -> VarianceTermPtr<'a> {
         assert_eq!(param_def_id.krate, item_def_id.krate);
 
-        if self.invariant_lang_items[kind as uint] == Some(item_def_id) {
-            self.invariant
-        } else if self.covariant_lang_items[kind as uint] == Some(item_def_id) {
-            self.covariant
-        } else if self.contravariant_lang_items[kind as uint] == Some(item_def_id) {
-            self.contravariant
-        } else if kind == TypeParam && Some(item_def_id) == self.unsafe_cell_lang_item {
-            self.invariant
-        } else if param_def_id.krate == ast::LOCAL_CRATE {
+        if param_def_id.krate == ast::LOCAL_CRATE {
             // Parameter on an item defined within current crate:
             // variance not yet inferred, so return a symbolic
             // variance.
@@ -724,6 +800,25 @@ fn xform(&mut self,
         }
     }
 
+    fn add_constraints_from_trait_ref(&mut self,
+                                      generics: &ty::Generics<'tcx>,
+                                      trait_ref: &ty::TraitRef<'tcx>,
+                                      variance: VarianceTermPtr<'a>) {
+        debug!("add_constraints_from_trait_ref: trait_ref={} variance={:?}",
+               trait_ref.repr(self.tcx()),
+               variance);
+
+        let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id);
+
+        self.add_constraints_from_substs(
+            generics,
+            trait_ref.def_id,
+            trait_def.generics.types.as_slice(),
+            trait_def.generics.regions.as_slice(),
+            trait_ref.substs,
+            variance);
+    }
+
     /// Adds constraints appropriate for an instance of `ty` appearing
     /// in a context with the generics defined in `generics` and
     /// ambient variance `variance`
@@ -731,7 +826,9 @@ fn add_constraints_from_ty(&mut self,
                                generics: &ty::Generics<'tcx>,
                                ty: Ty<'tcx>,
                                variance: VarianceTermPtr<'a>) {
-        debug!("add_constraints_from_ty(ty={})", ty.repr(self.tcx()));
+        debug!("add_constraints_from_ty(ty={}, variance={:?})",
+               ty.repr(self.tcx()),
+               variance);
 
         match ty.sty {
             ty::ty_bool |
@@ -754,6 +851,7 @@ fn add_constraints_from_ty(&mut self,
                 self.add_constraints_from_ty(generics, typ, variance);
             }
 
+
             ty::ty_ptr(ref mt) => {
                 self.add_constraints_from_mt(generics, mt, variance);
             }
@@ -797,27 +895,16 @@ fn add_constraints_from_ty(&mut self,
             }
 
             ty::ty_trait(ref data) => {
-                let trait_ref = data.principal_trait_ref_with_self_ty(self.tcx(),
-                                                                      self.tcx().types.err);
-                let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id());
-
-                // Traits never declare region parameters in the self
-                // space nor anything in the fn space.
-                assert!(trait_def.generics.regions.is_empty_in(subst::SelfSpace));
-                assert!(trait_def.generics.types.is_empty_in(subst::FnSpace));
-                assert!(trait_def.generics.regions.is_empty_in(subst::FnSpace));
+                let poly_trait_ref =
+                    data.principal_trait_ref_with_self_ty(self.tcx(),
+                                                          self.tcx().types.err);
 
                 // The type `Foo<T+'a>` is contravariant w/r/t `'a`:
                 let contra = self.contravariant(variance);
                 self.add_constraints_from_region(generics, data.bounds.region_bound, contra);
 
-                self.add_constraints_from_substs(
-                    generics,
-                    trait_ref.def_id(),
-                    trait_def.generics.types.get_slice(subst::TypeSpace),
-                    trait_def.generics.regions.get_slice(subst::TypeSpace),
-                    trait_ref.substs(),
-                    variance);
+                // Ignore the SelfSpace, it is erased.
+                self.add_constraints_from_trait_ref(generics, &*poly_trait_ref.0, variance);
 
                 let projections = data.projection_bounds_with_self_ty(self.tcx(),
                                                                       self.tcx().types.err);
@@ -845,7 +932,12 @@ fn add_constraints_from_ty(&mut self,
                 self.add_constraints_from_sig(generics, sig, variance);
             }
 
-            ty::ty_infer(..) | ty::ty_err => {
+            ty::ty_err => {
+                // we encounter this when walking the trait references for object
+                // types, where we use ty_err as the Self type
+            }
+
+            ty::ty_infer(..) => {
                 self.tcx().sess.bug(
                     &format!("unexpected type encountered in \
                             variance inference: {}",
@@ -864,7 +956,10 @@ fn add_constraints_from_substs(&mut self,
                                    region_param_defs: &[ty::RegionParameterDef],
                                    substs: &subst::Substs<'tcx>,
                                    variance: VarianceTermPtr<'a>) {
-        debug!("add_constraints_from_substs(def_id={:?})", def_id);
+        debug!("add_constraints_from_substs(def_id={}, substs={}, variance={:?})",
+               def_id.repr(self.tcx()),
+               substs.repr(self.tcx()),
+               variance);
 
         for p in type_param_defs {
             let variance_decl =
@@ -872,6 +967,8 @@ fn add_constraints_from_substs(&mut self,
                                        p.space, p.index as uint);
             let variance_i = self.xform(variance, variance_decl);
             let substs_ty = *substs.types.get(p.space, p.index as uint);
+            debug!("add_constraints_from_substs: variance_decl={:?} variance_i={:?}",
+                   variance_decl, variance_i);
             self.add_constraints_from_ty(generics, substs_ty, variance_i);
         }
 
@@ -885,6 +982,51 @@ fn add_constraints_from_substs(&mut self,
         }
     }
 
+    fn add_constraints_from_predicates(&mut self,
+                                       generics: &ty::Generics<'tcx>,
+                                       predicates: &[ty::Predicate<'tcx>],
+                                       variance: VarianceTermPtr<'a>) {
+        debug!("add_constraints_from_generics({})",
+               generics.repr(self.tcx()));
+
+        for predicate in predicates.iter() {
+            match *predicate {
+                ty::Predicate::Trait(ty::Binder(ref data)) => {
+                    self.add_constraints_from_trait_ref(generics, &*data.trait_ref, variance);
+                }
+
+                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);
+                }
+
+                ty::Predicate::TypeOutlives(ty::Binder(ref data)) => {
+                    self.add_constraints_from_ty(generics, data.0, variance);
+
+                    let variance_r = self.xform(variance, self.contravariant);
+                    self.add_constraints_from_region(generics, data.1, variance_r);
+                }
+
+                ty::Predicate::RegionOutlives(ty::Binder(ref data)) => {
+                    // `'a : 'b` is still true if 'a gets bigger
+                    self.add_constraints_from_region(generics, data.0, variance);
+
+                    // `'a : 'b` is still true if 'b gets smaller
+                    let variance_r = self.xform(variance, self.contravariant);
+                    self.add_constraints_from_region(generics, data.1, variance_r);
+                }
+
+                ty::Predicate::Projection(ty::Binder(ref data)) => {
+                    self.add_constraints_from_trait_ref(generics,
+                                                        &*data.projection_ty.trait_ref,
+                                                        variance);
+
+                    self.add_constraints_from_ty(generics, data.ty, self.invariant);
+                }
+            }
+        }
+    }
+
     /// Adds constraints appropriate for a function with signature
     /// `sig` appearing in a context with ambient variance `variance`
     fn add_constraints_from_sig(&mut self,
@@ -969,7 +1111,12 @@ struct SolveContext<'a, 'tcx: 'a> {
 
 fn solve_constraints(constraints_cx: ConstraintContext) {
     let ConstraintContext { terms_cx, constraints, .. } = constraints_cx;
-    let solutions: Vec<_> = repeat(ty::Bivariant).take(terms_cx.num_inferred()).collect();
+
+    let solutions =
+        terms_cx.inferred_infos.iter()
+                               .map(|ii| ii.initial_variance)
+                               .collect();
+
     let mut solutions_cx = SolveContext {
         terms_cx: terms_cx,
         constraints: constraints,
@@ -1034,20 +1181,16 @@ fn write(&self) {
             let mut types = VecPerParamSpace::empty();
             let mut regions = VecPerParamSpace::empty();
 
-            while index < num_inferred &&
-                  inferred_infos[index].item_id == item_id {
+            while index < num_inferred && inferred_infos[index].item_id == item_id {
                 let info = &inferred_infos[index];
                 let variance = solutions[index];
                 debug!("Index {} Info {} / {:?} / {:?} Variance {:?}",
                        index, info.index, info.kind, info.space, variance);
                 match info.kind {
-                    TypeParam => {
-                        types.push(info.space, variance);
-                    }
-                    RegionParam => {
-                        regions.push(info.space, variance);
-                    }
+                    TypeParam => { types.push(info.space, variance); }
+                    RegionParam => { regions.push(info.space, variance); }
                 }
+
                 index += 1;
             }
 
@@ -1065,7 +1208,7 @@ fn write(&self) {
             // attribute and report an error with various results if found.
             if ty::has_attr(tcx, item_def_id, "rustc_variance") {
                 let found = item_variances.repr(tcx);
-                span_err!(tcx.sess, tcx.map.span(item_id), E0208, "{}", &found[]);
+                span_err!(tcx.sess, tcx.map.span(item_id), E0208, "{}", &found[..]);
             }
 
             let newly_added = tcx.item_variance_map.borrow_mut()
@@ -1144,3 +1287,4 @@ fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance {
         (x, ty::Bivariant) | (ty::Bivariant, x) => x,
     }
 }
+
index a7cf5eb89187f2a99ac4b6133e33fea74d710062..ad91c3cb2c35b60e4b023c655ef8486403ebfd12 100644 (file)
@@ -112,7 +112,7 @@ pub struct Lock {
 
     impl Lock {
         pub fn new(p: &Path) -> Lock {
-            let buf = CString::from_slice(p.as_vec());
+            let buf = CString::new(p.as_vec()).unwrap();
             let fd = unsafe {
                 libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT,
                            libc::S_IRWXU)
index 6acd15379461cfbafcc91f9f2fb9cb56b7c16822..44c0acda66fba8e8c3c0384ae763d970b488fadd 100644 (file)
@@ -34,7 +34,7 @@ pub fn highlight(src: &str, class: Option<&str>, id: Option<&str>) -> String {
          class,
          id,
          &mut out).unwrap();
-    String::from_utf8_lossy(&out[]).into_owned()
+    String::from_utf8_lossy(&out[..]).into_owned()
 }
 
 /// Exhausts the `lexer` writing the output into `out`.
index c513fe2e8eb3cf2b44056a6d1395cf5669aa1cd2..7ea5bd569e1996df853eeccd1e550b3a6309e49e 100644 (file)
@@ -236,7 +236,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
                 s.push_str(&highlight::highlight(&text,
                                                  None,
                                                  Some("rust-example-rendered")));
-                let output = CString::from_vec(s.into_bytes());
+                let output = CString::new(s).unwrap();
                 hoedown_buffer_puts(ob, output.as_ptr());
             })
         }
@@ -293,7 +293,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
                                format!("{} ", sec)
                            });
 
-        let text = CString::from_vec(text.into_bytes());
+        let text = CString::new(text).unwrap();
         unsafe { hoedown_buffer_puts(ob, text.as_ptr()) }
     }
 
index 95994af7dc8deecd325711d0d617eee65d6acebc..fc3c87389917abebacff1d984cebd20078a43e3a 100644 (file)
@@ -1404,8 +1404,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 
         try!(write!(fmt,
         r##"<span id='render-detail'>
-            <a id="collapse-all" href="#">[-]
-            </a>&nbsp;<a id="expand-all" href="#">[+]</a>
+            <a id="collapse-all" href="#">[-]</a>&nbsp;<a id="expand-all" href="#">[+]</a>
         </span>"##));
 
         // Write `src` tag
index a4263badb013660ab6e28f95a92f1d353e09bf96..2f0755ecb898a0bf17b04cdd9b3641eb6b21f752 100644 (file)
@@ -374,8 +374,8 @@ a {
     color: #000;
     background: transparent;
 }
-p a { color: #4e8bca; }
-p 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; }
index bab734db126505efa94ec072d6bd92d91fb2f6de..f9e0948d7bc8a0ee6d707bb349d71d3592bf32f4 100644 (file)
@@ -23,7 +23,6 @@
 #![feature(collections)]
 #![feature(core)]
 #![feature(env)]
-#![feature(hash)]
 #![feature(int_uint)]
 #![feature(old_io)]
 #![feature(libc)]
index abd73fcfb70289981213f7ef579fc4f657ab7268..722f14fa6d4c7b0dcff44ad75f8d7f7bfa8686c2 100644 (file)
@@ -293,7 +293,7 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
             let mut a: Vec<clean::Attribute> = i.attrs.iter().filter(|&a| match a {
                 &clean::NameValue(ref x, _) if "doc" == *x => false,
                 _ => true
-            }).map(|x| x.clone()).collect();
+            }).cloned().collect();
             if docstr.len() > 0 {
                 a.push(clean::NameValue("doc".to_string(), docstr));
             }
index ac1a02854124afda82d3183550ebd9e7c63a6933..c52b0bab1fa8b800129e3688e7423bca40dba82d 100644 (file)
@@ -333,7 +333,7 @@ pub fn visit_item(&mut self, item: &ast::Item,
                     name: name,
                     items: items.clone(),
                     generics: gen.clone(),
-                    bounds: b.iter().map(|x| (*x).clone()).collect(),
+                    bounds: b.iter().cloned().collect(),
                     id: item.id,
                     attrs: item.attrs.clone(),
                     whence: item.span,
index f81edca837198ade2545b56f86a1d8d1115d6b1d..10cf02f85e818579e5ed811acaa424ee4e65b251 100644 (file)
 
 use std::usize;
 use std::default::Default;
-use std::hash::{Hash, Hasher};
+use std::hash::Hash;
+#[cfg(stage0)] use std::hash::Hasher;
 use std::collections::hash_state::HashState;
 
 use {Decodable, Encodable, Decoder, Encoder};
-use std::collections::{DList, RingBuf, BTreeMap, BTreeSet, HashMap, HashSet, VecMap};
+use std::collections::{LinkedList, VecDeque, BTreeMap, BTreeSet, HashMap, HashSet, VecMap};
 use collections::enum_set::{EnumSet, CLike};
 
 impl<
     T: Encodable
-> Encodable for DList<T> {
+> Encodable for LinkedList<T> {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
@@ -32,10 +33,10 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
     }
 }
 
-impl<T:Decodable> Decodable for DList<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<DList<T>, D::Error> {
+impl<T:Decodable> Decodable for LinkedList<T> {
+    fn decode<D: Decoder>(d: &mut D) -> Result<LinkedList<T>, D::Error> {
         d.read_seq(|d, len| {
-            let mut list = DList::new();
+            let mut list = LinkedList::new();
             for i in 0..len {
                 list.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
             }
@@ -44,7 +45,7 @@ fn decode<D: Decoder>(d: &mut D) -> Result<DList<T>, D::Error> {
     }
 }
 
-impl<T: Encodable> Encodable for RingBuf<T> {
+impl<T: Encodable> Encodable for VecDeque<T> {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
@@ -55,10 +56,10 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
     }
 }
 
-impl<T:Decodable> Decodable for RingBuf<T> {
-    fn decode<D: Decoder>(d: &mut D) -> Result<RingBuf<T>, D::Error> {
+impl<T:Decodable> Decodable for VecDeque<T> {
+    fn decode<D: Decoder>(d: &mut D) -> Result<VecDeque<T>, D::Error> {
         d.read_seq(|d, len| {
-            let mut deque: RingBuf<T> = RingBuf::new();
+            let mut deque: VecDeque<T> = VecDeque::new();
             for i in 0..len {
                 deque.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
             }
@@ -157,6 +158,7 @@ fn decode<D: Decoder>(d: &mut D) -> Result<EnumSet<T>, D::Error> {
     }
 }
 
+#[cfg(stage0)]
 impl<K, V, S> Encodable for HashMap<K, V, S>
     where K: Encodable + Hash< <S as HashState>::Hasher> + Eq,
           V: Encodable,
@@ -175,7 +177,26 @@ fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
         })
     }
 }
+#[cfg(not(stage0))]
+impl<K, V, S> Encodable for HashMap<K, V, S>
+    where K: Encodable + Hash + Eq,
+          V: Encodable,
+          S: HashState,
+{
+    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(stage0)]
 impl<K, V, S> Decodable for HashMap<K, V, S>
     where K: Decodable + Hash< <S as HashState>::Hasher> + Eq,
           V: Decodable,
@@ -195,7 +216,27 @@ fn decode<D: Decoder>(d: &mut D) -> Result<HashMap<K, V, S>, D::Error> {
         })
     }
 }
+#[cfg(not(stage0))]
+impl<K, V, S> Decodable for HashMap<K, V, S>
+    where K: Decodable + Hash + Eq,
+          V: Decodable,
+          S: HashState + Default,
+{
+    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(stage0)]
 impl<T, S> Encodable for HashSet<T, S>
     where T: Encodable + Hash< <S as HashState>::Hasher> + Eq,
           S: HashState,
@@ -212,7 +253,24 @@ fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
         })
     }
 }
+#[cfg(not(stage0))]
+impl<T, S> Encodable for HashSet<T, S>
+    where T: Encodable + Hash + Eq,
+          S: HashState,
+{
+    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(stage0)]
 impl<T, S> Decodable for HashSet<T, S>
     where T: Decodable + Hash< <S as HashState>::Hasher> + Eq,
           S: HashState + Default,
@@ -229,6 +287,22 @@ fn decode<D: Decoder>(d: &mut D) -> Result<HashSet<T, S>, D::Error> {
         })
     }
 }
+#[cfg(not(stage0))]
+impl<T, S> Decodable for HashSet<T, S>
+    where T: Decodable + Hash + Eq,
+          S: HashState + Default,
+{
+    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)
+        })
+    }
+}
 
 impl<V: Encodable> Encodable for VecMap<V> {
     fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
index 68b28784b4254de9460c6048e62a1460503513a2..a0f42815b439611b61fd1e07a748b69adaa2cef4 100644 (file)
@@ -1120,7 +1120,7 @@ pub fn is_string<'a>(&'a self) -> bool {
     /// Returns None otherwise.
     pub fn as_string<'a>(&'a self) -> Option<&'a str> {
         match *self {
-            Json::String(ref s) => Some(&s[]),
+            Json::String(ref s) => Some(&s[..]),
             _ => None
         }
     }
@@ -2237,7 +2237,7 @@ fn read_enum_variant<T, F>(&mut self, names: &[&str],
                 return Err(ExpectedError("String or Object".to_string(), format!("{}", json)))
             }
         };
-        let idx = match names.iter().position(|n| *n == &name[]) {
+        let idx = match names.iter().position(|n| *n == &name[..]) {
             Some(idx) => idx,
             None => return Err(UnknownVariantError(name))
         };
@@ -3461,7 +3461,7 @@ fn test_encode_hashmap_with_numeric_key() {
         hm.insert(1, true);
         let mut mem_buf = Vec::new();
         write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap();
-        let json_str = from_utf8(&mem_buf[]).unwrap();
+        let json_str = from_utf8(&mem_buf[..]).unwrap();
         match from_str(json_str) {
             Err(_) => panic!("Unable to parse json_str: {:?}", json_str),
             _ => {} // it parsed and we are good to go
@@ -3477,7 +3477,7 @@ fn test_prettyencode_hashmap_with_numeric_key() {
         hm.insert(1, true);
         let mut mem_buf = Vec::new();
         write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap();
-        let json_str = from_utf8(&mem_buf[]).unwrap();
+        let json_str = from_utf8(&mem_buf[..]).unwrap();
         match from_str(json_str) {
             Err(_) => panic!("Unable to parse json_str: {:?}", json_str),
             _ => {} // it parsed and we are good to go
@@ -3517,7 +3517,7 @@ fn indents(source: &str) -> uint {
             write!(&mut writer, "{}",
                    super::as_pretty_json(&json).indent(i)).unwrap();
 
-            let printed = from_utf8(&writer[]).unwrap();
+            let printed = from_utf8(&writer[..]).unwrap();
 
             // Check for indents at each line
             let lines: Vec<&str> = printed.lines().collect();
@@ -3549,7 +3549,7 @@ enum Enum {
         let mut map = HashMap::new();
         map.insert(Enum::Foo, 0);
         let result = json::encode(&map).unwrap();
-        assert_eq!(&result[], r#"{"Foo":0}"#);
+        assert_eq!(&result[..], r#"{"Foo":0}"#);
         let decoded: HashMap<Enum, _> = json::decode(&result).unwrap();
         assert_eq!(map, decoded);
     }
index 853da598ab5be8aebeaa86bf8718e4c9882b0eab..d476fd72abc3b03ea2f8cc8b729f8182fa78fad6 100644 (file)
@@ -31,7 +31,6 @@
 #![feature(int_uint)]
 #![feature(old_io)]
 #![feature(old_path)]
-#![feature(hash)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(std_misc)]
index 517907bcf58e347c3e94b7f876e66026a7aef97d..70f0ba4bb23af013d1429e4d5fcdb2e882a85bac 100644 (file)
@@ -326,7 +326,7 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
 
 impl Encodable for String {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_str(&self[])
+        s.emit_str(&self[..])
     }
 }
 
index 1b9f8b9901723af27cffd7df2a72aed7c93794d9..ade4f1f0533ee73abdb388bab488ac4a9a2d0452 100644 (file)
 use self::SearchResult::*;
 use self::VacantEntryState::*;
 
-use borrow::BorrowFrom;
+use borrow::Borrow;
 use clone::Clone;
 use cmp::{max, Eq, PartialEq};
 use default::Default;
 use fmt::{self, Debug};
-use hash::{self, Hash, SipHasher};
+use hash::{Hash, SipHasher};
 use iter::{self, Iterator, ExactSizeIterator, IntoIterator, IteratorExt, FromIterator, Extend, Map};
 use marker::Sized;
 use mem::{self, replace};
@@ -440,12 +440,10 @@ fn into_option(self) -> Option<FullBucket<K, V, M>> {
     }
 }
 
-impl<K, V, S, H> HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<K, V, S> HashMap<K, V, S>
+    where K: Eq + Hash, S: HashState
 {
-    fn make_hash<X: ?Sized>(&self, x: &X) -> SafeHash where X: Hash<H> {
+    fn make_hash<X: ?Sized>(&self, x: &X) -> SafeHash where X: Hash {
         table::make_hash(&self.hash_state, x)
     }
 
@@ -453,18 +451,18 @@ fn make_hash<X: ?Sized>(&self, x: &X) -> SafeHash where X: Hash<H> {
     /// 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 Q: BorrowFrom<K> + Eq + Hash<H>
+        where K: Borrow<Q>, Q: Eq + Hash
     {
         let hash = self.make_hash(q);
-        search_hashed(&self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k)))
+        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 Q: BorrowFrom<K> + Eq + Hash<H>
+        where K: Borrow<Q>, Q: Eq + Hash
     {
         let hash = self.make_hash(q);
-        search_hashed(&mut self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k)))
+        search_hashed(&mut self.table, hash, |k| q.eq(k.borrow()))
             .into_option()
     }
 
@@ -490,7 +488,7 @@ fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) {
     }
 }
 
-impl<K: Hash<Hasher> + Eq, V> HashMap<K, V, RandomState> {
+impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
     /// Create an empty HashMap.
     ///
     /// # Example
@@ -520,10 +518,8 @@ pub fn with_capacity(capacity: usize) -> HashMap<K, V, RandomState> {
     }
 }
 
-impl<K, V, S, H> HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<K, V, S> HashMap<K, V, S>
+    where K: Eq + Hash, S: HashState
 {
     /// Creates an empty hashmap which will use the given hasher to hash keys.
     ///
@@ -1037,7 +1033,7 @@ pub fn clear(&mut self) {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
-        where Q: Hash<H> + Eq + BorrowFrom<K>
+        where K: Borrow<Q>, Q: Hash + Eq
     {
         self.search(k).map(|bucket| bucket.into_refs().1)
     }
@@ -1060,7 +1056,7 @@ pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
-        where Q: Hash<H> + Eq + BorrowFrom<K>
+        where K: Borrow<Q>, Q: Hash + Eq
     {
         self.search(k).is_some()
     }
@@ -1086,7 +1082,7 @@ pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
-        where Q: Hash<H> + Eq + BorrowFrom<K>
+        where K: Borrow<Q>, Q: Hash + Eq
     {
         self.search_mut(k).map(|bucket| bucket.into_mut_refs().1)
     }
@@ -1138,7 +1134,7 @@ pub fn insert(&mut self, k: K, v: V) -> Option<V> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
-        where Q: Hash<H> + Eq + BorrowFrom<K>
+        where K: Borrow<Q>, Q: Hash + Eq
     {
         if self.table.size() == 0 {
             return None
@@ -1195,10 +1191,8 @@ fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable<K,V>, hash: SafeHas
     }
 }
 
-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>
+impl<K, V, S> PartialEq for HashMap<K, V, S>
+    where K: Eq + Hash, V: PartialEq, S: HashState
 {
     fn eq(&self, other: &HashMap<K, V, S>) -> bool {
         if self.len() != other.len() { return false; }
@@ -1210,17 +1204,13 @@ fn eq(&self, other: &HashMap<K, V, S>) -> bool {
 }
 
 #[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>
+impl<K, V, S> Eq for HashMap<K, V, S>
+    where K: Eq + Hash, V: Eq, S: HashState
 {}
 
 #[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>
+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 {{"));
@@ -1235,10 +1225,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 #[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>
+impl<K, V, S> Default for HashMap<K, V, S>
+    where K: Eq + Hash,
+          S: HashState + Default,
 {
     fn default() -> HashMap<K, V, S> {
         HashMap::with_hash_state(Default::default())
@@ -1246,11 +1235,10 @@ fn default() -> HashMap<K, V, S> {
 }
 
 #[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>,
-          Q: Eq + Hash<H> + BorrowFrom<K>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<K, Q: ?Sized, V, S> Index<Q> for HashMap<K, V, S>
+    where K: Eq + Hash + Borrow<Q>,
+          Q: Eq + Hash,
+          S: HashState,
 {
     type Output = V;
 
@@ -1261,11 +1249,10 @@ fn index<'a>(&'a self, index: &Q) -> &'a V {
 }
 
 #[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>,
-          Q: Eq + Hash<H> + BorrowFrom<K>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+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 {
@@ -1373,10 +1360,8 @@ enum VacantEntryState<K, V, M> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-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>
+impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S>
+    where K: Eq + Hash, S: HashState
 {
     type Item = (&'a K, &'a V);
     type IntoIter = Iter<'a, K, V>;
@@ -1387,10 +1372,8 @@ fn into_iter(self) -> Iter<'a, K, V> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-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>
+impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S>
+    where K: Eq + Hash, S: HashState
 {
     type Item = (&'a K, &'a mut V);
     type IntoIter = IterMut<'a, K, V>;
@@ -1401,10 +1384,8 @@ fn into_iter(mut self) -> IterMut<'a, K, V> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-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>
+impl<K, V, S> IntoIterator for HashMap<K, V, S>
+    where K: Eq + Hash, S: HashState
 {
     type Item = (K, V);
     type IntoIter = IntoIter<K, V>;
@@ -1550,12 +1531,11 @@ pub fn insert(self, value: V) -> &'a mut V {
 }
 
 #[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>
+impl<K, V, S> FromIterator<(K, V)> for HashMap<K, V, S>
+    where K: Eq + Hash, S: HashState + Default
 {
-    fn from_iter<T: Iterator<Item=(K, V)>>(iter: T) -> HashMap<K, V, S> {
+    fn from_iter<T: IntoIterator<Item=(K, V)>>(iterable: T) -> HashMap<K, V, S> {
+        let iter = iterable.into_iter();
         let lower = iter.size_hint().0;
         let mut map = HashMap::with_capacity_and_hash_state(lower,
                                                             Default::default());
@@ -1565,12 +1545,10 @@ fn from_iter<T: Iterator<Item=(K, V)>>(iter: T) -> HashMap<K, V, S> {
 }
 
 #[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>
+impl<K, V, S> Extend<(K, V)> for HashMap<K, V, S>
+    where K: Eq + Hash, S: HashState
 {
-    fn extend<T: Iterator<Item=(K, V)>>(&mut self, iter: T) {
+    fn extend<T: IntoIterator<Item=(K, V)>>(&mut self, iter: T) {
         for (k, v) in iter {
             self.insert(k, v);
         }
@@ -1606,9 +1584,9 @@ pub fn new() -> RandomState {
 #[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) }
+    type Hasher = SipHasher;
+    fn hasher(&self) -> SipHasher {
+        SipHasher::new_with_keys(self.k0, self.k1)
     }
 }
 
@@ -1621,25 +1599,6 @@ fn default() -> RandomState {
     }
 }
 
-/// 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]) { self.inner.write(data) }
-}
-
-impl hash::Hasher for Hasher {
-    type Output = u64;
-    fn reset(&mut self) { self.inner.reset() }
-    fn finish(&self) -> u64 { self.inner.finish() }
-}
-
 #[cfg(test)]
 mod test_map {
     use prelude::v1::*;
diff --git a/src/libstd/collections/hash/map_stage0.rs b/src/libstd/collections/hash/map_stage0.rs
new file mode 100644 (file)
index 0000000..f9e5044
--- /dev/null
@@ -0,0 +1,2330 @@
+// 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 47e300af26981da7cd395a6b361bf63704358cb6..39c1458b720019cd84f52245f7e7204f085cfe88 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 5fbbcb3b347afefdeba9ac386a0d62e16c5b6a0b..e0631a64d44b127048402f0667195daed7e4ffc6 100644 (file)
 //
 // ignore-lexer-test FIXME #15883
 
-use borrow::BorrowFrom;
+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 hash::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::map::{self, HashMap, Keys, INITIAL_CAPACITY, RandomState};
 use super::state::HashState;
 
 // Future Optimization (FIXME!)
@@ -97,7 +97,7 @@ pub struct HashSet<T, S = RandomState> {
     map: HashMap<T, (), S>
 }
 
-impl<T: Hash<Hasher> + Eq> HashSet<T, RandomState> {
+impl<T: Hash + Eq> HashSet<T, RandomState> {
     /// Create an empty HashSet.
     ///
     /// # Example
@@ -128,10 +128,8 @@ pub fn with_capacity(capacity: usize) -> HashSet<T, RandomState> {
     }
 }
 
-impl<T, S, H> HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<T, S> HashSet<T, S>
+    where T: Eq + Hash, S: HashState
 {
     /// Creates a new empty hash set which will use the given hasher to hash
     /// keys.
@@ -462,7 +460,7 @@ pub fn clear(&mut self) { self.map.clear() }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
-        where Q: BorrowFrom<T> + Hash<H> + Eq
+        where T: Borrow<Q>, Q: Hash + Eq
     {
         self.map.contains_key(value)
     }
@@ -572,17 +570,15 @@ pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none(
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
-        where Q: BorrowFrom<T> + Hash<H> + Eq
+        where T: Borrow<Q>, Q: Hash + 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>
+impl<T, S> PartialEq for HashSet<T, S>
+    where T: Eq + Hash, S: HashState
 {
     fn eq(&self, other: &HashSet<T, S>) -> bool {
         if self.len() != other.len() { return false; }
@@ -592,17 +588,14 @@ fn eq(&self, other: &HashSet<T, S>) -> bool {
 }
 
 #[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>
+impl<T, S> Eq for HashSet<T, S>
+    where T: Eq + Hash, S: HashState
 {}
 
 #[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>
+impl<T, S> fmt::Debug for HashSet<T, S>
+    where T: Eq + Hash + fmt::Debug,
+          S: HashState
 {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(f, "HashSet {{"));
@@ -617,12 +610,12 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 #[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>
+impl<T, S> FromIterator<T> for HashSet<T, S>
+    where T: Eq + Hash,
+          S: HashState + Default,
 {
-    fn from_iter<I: Iterator<Item=T>>(iter: I) -> HashSet<T, S> {
+    fn from_iter<I: IntoIterator<Item=T>>(iterable: I) -> HashSet<T, S> {
+        let iter = iterable.into_iter();
         let lower = iter.size_hint().0;
         let mut set = HashSet::with_capacity_and_hash_state(lower, Default::default());
         set.extend(iter);
@@ -631,12 +624,11 @@ fn from_iter<I: Iterator<Item=T>>(iter: I) -> HashSet<T, S> {
 }
 
 #[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>
+impl<T, S> Extend<T> for HashSet<T, S>
+    where T: Eq + Hash,
+          S: HashState,
 {
-    fn extend<I: Iterator<Item=T>>(&mut self, iter: I) {
+    fn extend<I: IntoIterator<Item=T>>(&mut self, iter: I) {
         for k in iter {
             self.insert(k);
         }
@@ -644,10 +636,9 @@ fn extend<I: Iterator<Item=T>>(&mut self, iter: I) {
 }
 
 #[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>
+impl<T, S> Default for HashSet<T, S>
+    where T: Eq + Hash,
+          S: HashState + Default,
 {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn default() -> HashSet<T, S> {
@@ -656,10 +647,9 @@ fn default() -> HashSet<T, S> {
 }
 
 #[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>
+impl<'a, 'b, T, S> BitOr<&'b HashSet<T, S>> for &'a HashSet<T, S>
+    where T: Eq + Hash + Clone,
+          S: HashState + Default,
 {
     type Output = HashSet<T, S>;
 
@@ -689,10 +679,9 @@ fn bitor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
 }
 
 #[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>
+impl<'a, 'b, T, S> BitAnd<&'b HashSet<T, S>> for &'a HashSet<T, S>
+    where T: Eq + Hash + Clone,
+          S: HashState + Default,
 {
     type Output = HashSet<T, S>;
 
@@ -722,10 +711,9 @@ fn bitand(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
 }
 
 #[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>
+impl<'a, 'b, T, S> BitXor<&'b HashSet<T, S>> for &'a HashSet<T, S>
+    where T: Eq + Hash + Clone,
+          S: HashState + Default,
 {
     type Output = HashSet<T, S>;
 
@@ -755,10 +743,9 @@ fn bitxor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
 }
 
 #[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>
+impl<'a, 'b, T, S> Sub<&'b HashSet<T, S>> for &'a HashSet<T, S>
+    where T: Eq + Hash + Clone,
+          S: HashState + Default,
 {
     type Output = HashSet<T, S>;
 
@@ -836,10 +823,8 @@ pub struct Union<'a, T: 'a, S: 'a> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-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>
+impl<'a, T, S> IntoIterator for &'a HashSet<T, S>
+    where T: Eq + Hash, S: HashState
 {
     type Item = &'a T;
     type IntoIter = Iter<'a, T>;
@@ -850,10 +835,9 @@ fn into_iter(self) -> Iter<'a, T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, S, H> IntoIterator for HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
+impl<T, S> IntoIterator for HashSet<T, S>
+    where T: Eq + Hash,
+          S: HashState
 {
     type Item = T;
     type IntoIter = IntoIter<T>;
@@ -900,10 +884,8 @@ 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>
+impl<'a, T, S> Iterator for Intersection<'a, T, S>
+    where T: Eq + Hash, S: HashState
 {
     type Item = &'a T;
 
@@ -925,10 +907,8 @@ fn size_hint(&self) -> (usize, Option<usize>) {
 }
 
 #[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>
+impl<'a, T, S> Iterator for Difference<'a, T, S>
+    where T: Eq + Hash, S: HashState
 {
     type Item = &'a T;
 
@@ -950,10 +930,8 @@ fn size_hint(&self) -> (usize, Option<usize>) {
 }
 
 #[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>
+impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S>
+    where T: Eq + Hash, S: HashState
 {
     type Item = &'a T;
 
@@ -962,10 +940,8 @@ 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>
+impl<'a, T, S> Iterator for Union<'a, T, S>
+    where T: Eq + Hash, S: HashState
 {
     type Item = &'a T;
 
diff --git a/src/libstd/collections/hash/set_stage0.rs b/src/libstd/collections/hash/set_stage0.rs
new file mode 100644 (file)
index 0000000..68c9e02
--- /dev/null
@@ -0,0 +1,1252 @@
+// 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 79e01304fb8c0807a9bf5face1810a69f6a24861..7e6dd45b51e48f69f553388787dc490f1f843e03 100644 (file)
@@ -11,6 +11,7 @@
 use clone::Clone;
 use default::Default;
 use hash;
+use marker;
 
 /// A trait representing stateful hashes which can be used to hash keys in a
 /// `HashMap`.
@@ -37,7 +38,7 @@ pub trait HashState {
 ///
 /// This struct has is 0-sized and does not need construction.
 #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")]
-pub struct DefaultState<H>;
+pub struct DefaultState<H>(marker::PhantomData<H>);
 
 impl<H: Default + hash::Hasher> HashState for DefaultState<H> {
     type Hasher = H;
@@ -45,9 +46,9 @@ fn hasher(&self) -> H { Default::default() }
 }
 
 impl<H> Clone for DefaultState<H> {
-    fn clone(&self) -> DefaultState<H> { DefaultState }
+    fn clone(&self) -> DefaultState<H> { DefaultState(marker::PhantomData) }
 }
 
 impl<H> Default for DefaultState<H> {
-    fn default() -> DefaultState<H> { DefaultState }
+    fn default() -> DefaultState<H> { DefaultState(marker::PhantomData) }
 }
index 0bb6bd4cf356a24c93cdcc388068a0d41900a1c5..f301f6db92f96a7bf96d2ee545128212db7c9de7 100644 (file)
@@ -23,8 +23,8 @@
 use ops::{Deref, DerefMut, Drop};
 use option::Option;
 use option::Option::{Some, None};
-use ptr::{self, PtrExt, copy_nonoverlapping_memory, zero_memory};
-use rt::heap::{allocate, deallocate};
+use ptr::{self, PtrExt, copy_nonoverlapping_memory, Unique, zero_memory};
+use rt::heap::{allocate, deallocate, EMPTY};
 use collections::hash_state::HashState;
 
 const EMPTY_BUCKET: u64 = 0u64;
 pub struct RawTable<K, V> {
     capacity: usize,
     size:     usize,
-    hashes:   *mut u64,
+    hashes:   Unique<u64>,
+
     // Because K/V do not appear directly in any of the types in the struct,
     // inform rustc that in fact instances of K and V are reachable from here.
-    marker:   marker::CovariantType<(K,V)>,
+    marker:   marker::PhantomData<(K,V)>,
 }
 
 unsafe impl<K: Send, V: Send> Send for RawTable<K, V> {}
@@ -81,7 +82,8 @@ unsafe impl<K: Sync, V: Sync> Sync for RawTable<K, V> {}
 struct RawBucket<K, V> {
     hash: *mut u64,
     key:  *mut K,
-    val:  *mut V
+    val:  *mut V,
+    _marker: marker::PhantomData<(K,V)>,
 }
 
 impl<K,V> Copy for RawBucket<K,V> {}
@@ -141,6 +143,7 @@ pub fn inspect(&self) -> u64 { self.hash }
 /// 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>,
@@ -155,6 +158,22 @@ pub fn make_hash<T: ?Sized, S, H>(hash_state: &S, t: &T) -> SafeHash
     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
+    // 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() }
+}
+
 // `replace` casts a `*u64` to a `*SafeHash`. Since we statically
 // ensure that a `FullBucket` points to an index with a non-zero hash,
 // and a `SafeHash` is just a `u64` with a different name, this is
@@ -170,11 +189,12 @@ fn can_alias_safehash_as_u64() {
 }
 
 impl<K, V> RawBucket<K, V> {
-    unsafe fn offset(self, count: int) -> RawBucket<K, V> {
+    unsafe fn offset(self, count: isize) -> RawBucket<K, V> {
         RawBucket {
             hash: self.hash.offset(count),
             key:  self.key.offset(count),
             val:  self.val.offset(count),
+            _marker: marker::PhantomData,
         }
     }
 }
@@ -567,10 +587,11 @@ unsafe fn new_uninitialized(capacity: usize) -> RawTable<K, V> {
             return RawTable {
                 size: 0,
                 capacity: 0,
-                hashes: ptr::null_mut(),
-                marker: marker::CovariantType,
+                hashes: Unique::new(EMPTY as *mut u64),
+                marker: marker::PhantomData,
             };
         }
+
         // No need for `checked_mul` before a more restrictive check performed
         // later in this method.
         let hashes_size = capacity * size_of::<u64>();
@@ -606,8 +627,8 @@ unsafe fn new_uninitialized(capacity: usize) -> RawTable<K, V> {
         RawTable {
             capacity: capacity,
             size:     0,
-            hashes:   hashes,
-            marker:   marker::CovariantType,
+            hashes:   Unique::new(hashes),
+            marker:   marker::PhantomData,
         }
     }
 
@@ -615,16 +636,17 @@ fn first_bucket_raw(&self) -> RawBucket<K, V> {
         let hashes_size = self.capacity * size_of::<u64>();
         let keys_size = self.capacity * size_of::<K>();
 
-        let buffer = self.hashes as *mut u8;
+        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>());
 
         unsafe {
             RawBucket {
-                hash: self.hashes,
+                hash: *self.hashes,
                 key:  buffer.offset(keys_offset as isize) as *mut K,
-                val:  buffer.offset(vals_offset as isize) as *mut V
+                val:  buffer.offset(vals_offset as isize) as *mut V,
+                _marker: marker::PhantomData,
             }
         }
     }
@@ -634,7 +656,7 @@ fn first_bucket_raw(&self) -> RawBucket<K, V> {
     pub fn new(capacity: usize) -> RawTable<K, V> {
         unsafe {
             let ret = RawTable::new_uninitialized(capacity);
-            zero_memory(ret.hashes, capacity);
+            zero_memory(*ret.hashes, capacity);
             ret
         }
     }
@@ -656,7 +678,7 @@ fn raw_buckets(&self) -> RawBuckets<K, V> {
             hashes_end: unsafe {
                 self.hashes.offset(self.capacity as isize)
             },
-            marker: marker::ContravariantLifetime,
+            marker: marker::PhantomData,
         }
     }
 
@@ -681,7 +703,7 @@ pub fn into_iter(self) -> IntoIter<K, V> {
             iter: RawBuckets {
                 raw: raw,
                 hashes_end: hashes_end,
-                marker: marker::ContravariantLifetime,
+                marker: marker::PhantomData,
             },
             table: self,
         }
@@ -694,7 +716,7 @@ pub fn drain(&mut self) -> Drain<K, V> {
             iter: RawBuckets {
                 raw: raw,
                 hashes_end: hashes_end,
-                marker: marker::ContravariantLifetime::<'static>,
+                marker: marker::PhantomData,
             },
             table: self,
         }
@@ -708,7 +730,7 @@ unsafe fn rev_move_buckets(&mut self) -> RevMoveBuckets<K, V> {
             raw: raw_bucket.offset(self.capacity as isize),
             hashes_end: raw_bucket.hash,
             elems_left: self.size,
-            marker:     marker::ContravariantLifetime,
+            marker:     marker::PhantomData,
         }
     }
 }
@@ -718,7 +740,13 @@ unsafe fn rev_move_buckets(&mut self) -> RevMoveBuckets<K, V> {
 struct RawBuckets<'a, K, V> {
     raw: RawBucket<K, V>,
     hashes_end: *mut u64,
-    marker: marker::ContravariantLifetime<'a>,
+
+    // Strictly speaking, this should be &'a (K,V), but that would
+    // require that K:'a, and we often use RawBuckets<'static...> for
+    // move iterations, so that messes up a lot of other things. So
+    // just use `&'a (K,V)` as this is not a publicly exposed type
+    // anyway.
+    marker: marker::PhantomData<&'a ()>,
 }
 
 // FIXME(#19839) Remove in favor of `#[derive(Clone)]`
@@ -727,7 +755,7 @@ fn clone(&self) -> RawBuckets<'a, K, V> {
         RawBuckets {
             raw: self.raw,
             hashes_end: self.hashes_end,
-            marker: marker::ContravariantLifetime,
+            marker: marker::PhantomData,
         }
     }
 }
@@ -759,7 +787,11 @@ struct RevMoveBuckets<'a, K, V> {
     raw: RawBucket<K, V>,
     hashes_end: *mut u64,
     elems_left: usize,
-    marker: marker::ContravariantLifetime<'a>,
+
+    // As above, `&'a (K,V)` would seem better, but we often use
+    // 'static for the lifetime, and this is not a publicly exposed
+    // type.
+    marker: marker::PhantomData<&'a ()>,
 }
 
 impl<'a, K, V> Iterator for RevMoveBuckets<'a, K, V> {
@@ -966,9 +998,10 @@ fn clone(&self) -> RawTable<K, V> {
 #[unsafe_destructor]
 impl<K, V> Drop for RawTable<K, V> {
     fn drop(&mut self) {
-        if self.hashes.is_null() {
+        if self.capacity == 0 {
             return;
         }
+
         // This is done in reverse because we've likely partially taken
         // some elements out with `.into_iter()` from the front.
         // Check if the size is 0, so we don't do a useless scan when
@@ -986,7 +1019,7 @@ fn drop(&mut self) {
                                                     vals_size, min_align_of::<V>());
 
         unsafe {
-            deallocate(self.hashes as *mut u8, size, align);
+            deallocate(*self.hashes as *mut u8, size, align);
             // Remember how everything was allocated out of one buffer
             // during initialization? We only need one call to free here.
         }
index be441bfec886500b1f850557f79d593e5d7b9b1a..0e64370df60ecbdc8b24ff51abc1a506ba83b8a2 100644 (file)
@@ -23,7 +23,7 @@
 //!
 //! Rust's collections can be grouped into four major categories:
 //!
-//! * Sequences: `Vec`, `RingBuf`, `DList`, `BitV`
+//! * Sequences: `Vec`, `VecDeque`, `LinkedList`, `BitV`
 //! * Maps: `HashMap`, `BTreeMap`, `VecMap`
 //! * Sets: `HashSet`, `BTreeSet`, `BitVSet`
 //! * Misc: `BinaryHeap`
 //! * You want a resizable array.
 //! * You want a heap-allocated array.
 //!
-//! ### Use a `RingBuf` when:
+//! ### Use a `VecDeque` when:
 //! * You want a `Vec` that supports efficient insertion at both ends of the sequence.
 //! * You want a queue.
 //! * You want a double-ended queue (deque).
 //!
-//! ### Use a `DList` when:
-//! * You want a `Vec` or `RingBuf` of unknown size, and can't tolerate amortization.
+//! ### Use a `LinkedList` when:
+//! * You want a `Vec` or `VecDeque` of unknown size, and can't tolerate amortization.
 //! * You want to efficiently split and append lists.
 //! * You are *absolutely* certain you *really*, *truly*, want a doubly linked list.
 //!
@@ -75,7 +75,7 @@
 //!
 //! ### Use a `BitV` when:
 //! * You want to store an unbounded number of booleans in a small space.
-//! * You want a bitvector.
+//! * You want a bit vector.
 //!
 //! ### Use a `BitVSet` when:
 //! * You want a `VecSet`.
 //!
 //! ## Sequences
 //!
-//! |         | get(i)         | insert(i)       | remove(i)      | append | split_off(i)   |
-//! |---------|----------------|-----------------|----------------|--------|----------------|
-//! | Vec     | O(1)           | O(n-i)*         | O(n-i)         | O(m)*  | O(n-i)         |
-//! | RingBuf | O(1)           | O(min(i, n-i))* | O(min(i, n-i)) | O(m)*  | O(min(i, n-i)) |
-//! | DList   | O(min(i, n-i)) | O(min(i, n-i))  | O(min(i, n-i)) | O(1)   | O(min(i, n-i)) |
-//! | Bitv    | O(1)           | O(n-i)*         | O(n-i)         | O(m)*  | O(n-i)         |
+//! |              | get(i)         | insert(i)       | remove(i)      | append | split_off(i)   |
+//! |--------------|----------------|-----------------|----------------|--------|----------------|
+//! | Vec          | O(1)           | O(n-i)*         | O(n-i)         | O(m)*  | O(n-i)         |
+//! | VecDeque     | O(1)           | O(min(i, n-i))* | O(min(i, n-i)) | O(m)*  | O(min(i, n-i)) |
+//! | LinkedList   | O(min(i, n-i)) | O(min(i, n-i))  | O(min(i, n-i)) | O(1)   | O(min(i, n-i)) |
+//! | BitVec       | O(1)           | O(n-i)*         | O(n-i)         | O(m)*  | O(n-i)         |
 //!
-//! Note that where ties occur, Vec is generally going to be faster than RingBuf, and RingBuf
-//! is generally going to be faster than DList. Bitv is not a general purpose collection, and
+//! Note that where ties occur, Vec is generally going to be faster than VecDeque, and VecDeque
+//! is generally going to be faster than LinkedList. BitVec is not a general purpose collection, and
 //! therefore cannot reasonably be compared.
 //!
 //! ## Maps
 //!
-//! For Sets, all operations have the cost of the equivalent Map operation. For BitvSet,
+//! For Sets, all operations have the cost of the equivalent Map operation. For BitSet,
 //! refer to VecMap.
 //!
 //! |          | get       | insert   | remove   | predecessor |
 //!
 //! Any `with_capacity` constructor will instruct the collection to allocate enough space
 //! for the specified number of elements. Ideally this will be for exactly that many
-//! elements, but some implementation details may prevent this. `Vec` and `RingBuf` can
+//! elements, but some implementation details may prevent this. `Vec` and `VecDeque` can
 //! be relied on to allocate exactly the requested amount, though. Use `with_capacity`
 //! when you know exactly how many elements will be inserted, or at least have a
 //! reasonable upper-bound on that number.
 //! ```
 //!
 //! ```
-//! use std::collections::RingBuf;
+//! use std::collections::VecDeque;
 //!
 //! let vec = vec![1, 2, 3, 4];
-//! let buf: RingBuf<_> = vec.into_iter().collect();
+//! let buf: VecDeque<_> = vec.into_iter().collect();
 //! ```
 //!
 //! Iterators also provide a series of *adapter* methods for performing common tasks to
 #![stable(feature = "rust1", since = "1.0.0")]
 
 pub use core_collections::Bound;
-pub use core_collections::{BinaryHeap, Bitv, BitvSet, BTreeMap, BTreeSet};
-pub use core_collections::{DList, RingBuf, VecMap};
+pub use core_collections::{BinaryHeap, BitVec, BitSet, BTreeMap, BTreeSet};
+pub use core_collections::{LinkedList, VecDeque, VecMap};
 
-pub use core_collections::{binary_heap, bitv, bitv_set, btree_map, btree_set};
-pub use core_collections::{dlist, ring_buf, vec_map};
+pub use core_collections::{binary_heap, bit_vec, bit_set, btree_map, btree_set};
+pub use core_collections::{linked_list, vec_deque, vec_map};
 
 pub use self::hash_map::HashMap;
 pub use self::hash_set::HashSet;
index c5dd66630b4201d908aacf9159743dddd9f23a17..b0fb9c29403511d13e42b274030523c50efbbf67 100644 (file)
@@ -112,7 +112,7 @@ pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String> {
         // This function should have a lifetime constraint of 'a on
         // T but that feature is still unimplemented
 
-        let raw_string = CString::from_slice(symbol.as_bytes());
+        let raw_string = CString::new(symbol).unwrap();
         let maybe_symbol_value = dl::check_for_errors_in(|| {
             dl::symbol(self.handle, raw_string.as_ptr())
         });
@@ -187,7 +187,7 @@ fn test_errors_do_not_crash() {
 mod dl {
     use prelude::v1::*;
 
-    use ffi::{self, CString};
+    use ffi::{CString, CStr};
     use str;
     use libc;
     use ptr;
@@ -206,7 +206,7 @@ pub fn open(filename: Option<&[u8]>) -> Result<*mut u8, String> {
     const LAZY: libc::c_int = 1;
 
     unsafe fn open_external(filename: &[u8]) -> *mut u8 {
-        let s = CString::from_slice(filename);
+        let s = CString::new(filename).unwrap();
         dlopen(s.as_ptr(), LAZY) as *mut u8
     }
 
@@ -231,7 +231,7 @@ pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
             let ret = if ptr::null() == last_error {
                 Ok(result)
             } else {
-                let s = ffi::c_str_to_bytes(&last_error);
+                let s = CStr::from_ptr(last_error).to_bytes();
                 Err(str::from_utf8(s).unwrap().to_string())
             };
 
index 93dc3efe2c4fc7a1186811dc4e346c20db8fba85..8676586e7dc2a7e32971773e026af9537bdbea25 100644 (file)
@@ -926,7 +926,7 @@ fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
     #[cfg(unix)]
     fn join_paths_unix() {
         fn test_eq(input: &[&str], output: &str) -> bool {
-            &*join_paths(input.iter().map(|s| *s)).unwrap() ==
+            &*join_paths(input.iter().cloned()).unwrap() ==
                 OsStr::from_str(output)
         }
 
@@ -935,14 +935,14 @@ fn test_eq(input: &[&str], output: &str) -> bool {
                          "/bin:/usr/bin:/usr/local/bin"));
         assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""],
                          ":/bin:::/usr/bin:"));
-        assert!(join_paths(["/te:st"].iter().map(|s| *s)).is_err());
+        assert!(join_paths(["/te:st"].iter().cloned()).is_err());
     }
 
     #[test]
     #[cfg(windows)]
     fn join_paths_windows() {
         fn test_eq(input: &[&str], output: &str) -> bool {
-            &*join_paths(input.iter().map(|s| *s)).unwrap() ==
+            &*join_paths(input.iter().cloned()).unwrap() ==
                 OsStr::from_str(output)
         }
 
@@ -953,6 +953,6 @@ fn test_eq(input: &[&str], output: &str) -> bool {
                         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"#].iter().map(|s| *s)).is_err());
+        assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err());
     }
     }
index 45089176cba961b97e285456ad2346e2e4787b9d..8976813d3f91e9681a84f48d8ca552733319ff6c 100644 (file)
@@ -8,18 +8,25 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
+use error::{Error, FromError};
 use fmt;
+use io;
 use iter::IteratorExt;
 use libc;
 use mem;
+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 string::String;
 use vec::Vec;
 
-/// A type representing a C-compatible string
+/// A type representing an owned C-compatible string
 ///
-/// This type serves the primary purpose of being able to generate a
+/// This type serves the primary purpose of being able to safely generate a
 /// C-compatible string from a Rust byte slice or vector. An instance of this
 /// type is a static guarantee that the underlying bytes contain no interior 0
 /// bytes and the final byte is 0.
@@ -44,8 +51,8 @@
 ///     fn my_printer(s: *const libc::c_char);
 /// }
 ///
-/// let to_print = "Hello, world!";
-/// let c_to_print = CString::from_slice(to_print.as_bytes());
+/// let to_print = b"Hello, world!";
+/// let c_to_print = CString::new(to_print).unwrap();
 /// unsafe {
 ///     my_printer(c_to_print.as_ptr());
 /// }
 /// ```
 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
 pub struct CString {
-    inner: Vec<libc::c_char>,
+    inner: Vec<u8>,
+}
+
+/// Representation of a borrowed C string.
+///
+/// This dynamically sized type is only safely constructed via a borrowed
+/// version of an instance of `CString`. This type can be constructed from a raw
+/// C string as well and represents a C string borrowed from another location.
+///
+/// Note that this structure is **not** `repr(C)` and is not recommended to be
+/// placed in the signatures of FFI functions. Instead safe wrappers of FFI
+/// functions may leverage the unsafe `from_ptr` constructor to provide a safe
+/// interface to other consumers.
+///
+/// # Examples
+///
+/// Inspecting a foreign C string
+///
+/// ```no_run
+/// extern crate libc;
+/// use std::ffi::CStr;
+///
+/// extern { fn my_string() -> *const libc::c_char; }
+///
+/// fn main() {
+///     unsafe {
+///         let slice = CStr::from_ptr(my_string());
+///         println!("string length: {}", slice.to_bytes().len());
+///     }
+/// }
+/// ```
+///
+/// Passing a Rust-originating C string
+///
+/// ```no_run
+/// extern crate libc;
+/// use std::ffi::{CString, CStr};
+///
+/// fn work(data: &CStr) {
+///     extern { fn work_with(data: *const libc::c_char); }
+///
+///     unsafe { work_with(data.as_ptr()) }
+/// }
+///
+/// fn main() {
+///     let s = CString::new("data data data data").unwrap();
+///     work(&s);
+/// }
+/// ```
+#[derive(Hash)]
+pub struct CStr {
+    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)]
+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.
+    ///
+    /// This method will consume the provided data and use the underlying bytes
+    /// to construct a new string, 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());
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// # Errors
+    ///
+    /// 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();
+        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 there are any 0 bytes already in the slice
-    /// provided.
+    /// 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())
     }
@@ -77,11 +200,15 @@ pub fn from_slice(v: &[u8]) -> CString {
     ///
     /// # Panics
     ///
-    /// This function will panic if there are any 0 bytes already in the vector
-    /// provided.
+    /// 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 {
-        assert!(!v.iter().any(|&x| x == 0));
-        unsafe { CString::from_vec_unchecked(v) }
+        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
@@ -91,31 +218,29 @@ pub fn from_vec(v: Vec<u8>) -> CString {
     /// is made that `v` contains no 0 bytes.
     pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
         v.push(0);
-        CString { inner: mem::transmute(v) }
+        CString { inner: v }
     }
 
-    /// Create a view into this C string which includes the trailing nul
-    /// terminator at the end of the string.
-    pub fn as_slice_with_nul(&self) -> &[libc::c_char] { &self.inner }
-
-    /// Similar to the `as_slice` method, but returns a `u8` slice instead of a
-    /// `libc::c_char` slice.
+    /// 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.
     pub fn as_bytes(&self) -> &[u8] {
-        unsafe { mem::transmute(&**self) }
+        &self.inner[..self.inner.len() - 1]
     }
 
-    /// Equivalent to `as_slice_with_nul` except that the type returned is a
-    /// `u8` slice instead of a `libc::c_char` slice.
+    /// Equivalent to the `as_bytes` function except that the returned slice
+    /// includes the trailing nul byte.
     pub fn as_bytes_with_nul(&self) -> &[u8] {
-        unsafe { mem::transmute(self.as_slice_with_nul()) }
+        &self.inner
     }
 }
 
 impl Deref for CString {
-    type Target = [libc::c_char];
+    type Target = CStr;
 
-    fn deref(&self) -> &[libc::c_char] {
-        &self.inner[..(self.inner.len() - 1)]
+    fn deref(&self) -> &CStr {
+        unsafe { mem::transmute(self.as_bytes_with_nul()) }
     }
 }
 
@@ -126,54 +251,172 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-/// Interpret a C string as a byte slice.
-///
-/// This function will calculate the length of the C string provided, and it
-/// will then return a corresponding slice for the contents of the C string not
-/// including the nul terminator.
-///
-/// This function will tie the lifetime of the returned slice to the lifetime of
-/// the pointer provided. This is done to help prevent the slice from escaping
-/// the lifetime of the pointer itself. If a longer lifetime is needed, then
-/// `mem::copy_lifetime` should be used.
-///
-/// This function is unsafe because there is no guarantee of the validity of the
-/// pointer `raw` or a guarantee that a nul terminator will be found.
-///
-/// # Example
-///
-/// ```no_run
-/// # extern crate libc;
-/// # fn main() {
-/// use std::ffi;
-/// use std::str;
-/// use libc;
-///
-/// extern {
-///     fn my_string() -> *const libc::c_char;
-/// }
-///
-/// unsafe {
-///     let to_print = my_string();
-///     let slice = ffi::c_str_to_bytes(&to_print);
-///     println!("string returned: {}", str::from_utf8(slice).unwrap());
-/// }
-/// # }
-/// ```
+impl NulError {
+    /// Returns the position of the nul byte in the slice that was provided to
+    /// `CString::from_vec`.
+    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.
+    pub fn into_vec(self) -> Vec<u8> { self.1 }
+}
+
+impl Error for NulError {
+    fn description(&self) -> &str { "nul byte found in data" }
+}
+
+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 {
+        io::Error::new(io::ErrorKind::InvalidInput,
+                       "data provided contains a nul byte", None)
+    }
+}
+
+impl FromError<NulError> for old_io::IoError {
+    fn from_error(_: NulError) -> old_io::IoError {
+        old_io::IoError {
+            kind: old_io::IoErrorKind::InvalidInput,
+            desc: "data provided contains a nul byte",
+            detail: None
+        }
+    }
+}
+
+impl CStr {
+    /// Cast a raw C string to a safe C string wrapper.
+    ///
+    /// This function will cast the provided `ptr` to the `CStr` wrapper which
+    /// allows inspection and interoperation of non-owned C strings. This method
+    /// is unsafe for a number of reasons:
+    ///
+    /// * There is no guarantee to the validity of `ptr`
+    /// * The returned lifetime is not guaranteed to be the actual lifetime of
+    ///   `ptr`
+    /// * There is no guarantee that the memory pointed to by `ptr` contains a
+    ///   valid nul terminator byte at the end of the string.
+    ///
+    /// > **Note**: This operation is intended to be a 0-cost cast but it is
+    /// > currently implemented with an up-front calculation of the length of
+    /// > the string. This is not guaranteed to always be the case.
+    ///
+    /// # Example
+    ///
+    /// ```no_run
+    /// # extern crate libc;
+    /// # fn main() {
+    /// use std::ffi::CStr;
+    /// use std::str;
+    /// use libc;
+    ///
+    /// extern {
+    ///     fn my_string() -> *const libc::c_char;
+    /// }
+    ///
+    /// unsafe {
+    ///     let slice = CStr::from_ptr(my_string());
+    ///     println!("string returned: {}",
+    ///              str::from_utf8(slice.to_bytes()).unwrap());
+    /// }
+    /// # }
+    /// ```
+    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))
+    }
+
+    /// 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
+    /// the end of the string.
+    pub fn as_ptr(&self) -> *const libc::c_char {
+        self.inner.as_ptr()
+    }
+
+    /// Convert this C string to a byte slice.
+    ///
+    /// This function will calculate the length of this string (which normally
+    /// requires a linear amount of work to be done) and then return the
+    /// resulting slice of `u8` elements.
+    ///
+    /// The returned slice will **not** contain the trailing nul that this C
+    /// string has.
+    ///
+    /// > **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.
+    pub fn to_bytes(&self) -> &[u8] {
+        let bytes = self.to_bytes_with_nul();
+        &bytes[..bytes.len() - 1]
+    }
+
+    /// Convert this C string to a byte slice containing the trailing 0 byte.
+    ///
+    /// This function is the equivalent of `to_bytes` except that it will retain
+    /// the trailing nul instead of chopping it off.
+    ///
+    /// > **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.
+    pub fn to_bytes_with_nul(&self) -> &[u8] {
+        unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.inner) }
+    }
+}
+
+impl PartialEq for CStr {
+    fn eq(&self, other: &CStr) -> bool {
+        self.to_bytes().eq(&other.to_bytes())
+    }
+}
+impl Eq for CStr {}
+impl PartialOrd for CStr {
+    fn partial_cmp(&self, other: &CStr) -> Option<Ordering> {
+        self.to_bytes().partial_cmp(&other.to_bytes())
+    }
+}
+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)
 }
 
-/// Interpret a C string as a byte slice with the nul terminator.
-///
-/// This function is identical to `from_raw_buf` except that the returned slice
-/// will include the nul terminator of the string.
-pub unsafe fn c_str_to_bytes_with_nul<'a>(raw: &'a *const libc::c_char) -> &'a [u8] {
+/// 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::*;
@@ -193,21 +436,19 @@ fn c_to_rust() {
 
     #[test]
     fn simple() {
-        let s = CString::from_slice(b"1234");
+        let s = CString::new(b"1234").unwrap();
         assert_eq!(s.as_bytes(), b"1234");
         assert_eq!(s.as_bytes_with_nul(), b"1234\0");
-        unsafe {
-            assert_eq!(&*s,
-                       mem::transmute::<_, &[libc::c_char]>(b"1234"));
-            assert_eq!(s.as_slice_with_nul(),
-                       mem::transmute::<_, &[libc::c_char]>(b"1234\0"));
-        }
     }
 
-    #[should_fail] #[test]
-    fn build_with_zero1() { CString::from_slice(b"\0"); }
-    #[should_fail] #[test]
-    fn build_with_zero2() { CString::from_vec(vec![0]); }
+    #[test]
+    fn build_with_zero1() {
+        assert!(CString::new(b"\0").is_err());
+    }
+    #[test]
+    fn build_with_zero2() {
+        assert!(CString::new(vec![0]).is_err());
+    }
 
     #[test]
     fn build_with_zero3() {
@@ -219,7 +460,16 @@ fn build_with_zero3() {
 
     #[test]
     fn formatted() {
-        let s = CString::from_slice(b"12");
+        let s = CString::new(b"12").unwrap();
         assert_eq!(format!("{:?}", s), "\"12\"");
     }
+
+    #[test]
+    fn borrowed() {
+        unsafe {
+            let s = CStr::from_ptr(b"12\0".as_ptr() as *const _);
+            assert_eq!(s.to_bytes(), b"12");
+            assert_eq!(s.to_bytes_with_nul(), b"12\0");
+        }
+    }
 }
index 07a4f17796c4994f14638ac3258ee15a0da40b4e..1bff6afb776079b0e5102ad2b0e92541d089263c 100644 (file)
             reason = "module just underwent fairly large reorganization and the dust \
                       still needs to settle")]
 
-pub use self::c_str::CString;
+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;
 
 pub use self::os_str::OsString;
index 1d14b141778f052bf7dcbbd0db326df151f9c400..84149a2eb8e43353a1d9857c8a19cdecd65f379e 100644 (file)
 
 use core::prelude::*;
 
-use core::borrow::{BorrowFrom, ToOwned};
+use borrow::{Borrow, ToOwned};
 use fmt::{self, Debug};
 use mem;
 use string::{String, CowString};
 use ops;
 use cmp;
-use hash::{Hash, Hasher, Writer};
+use hash::{Hash, Hasher};
+#[cfg(stage0)] use hash::Writer;
 use old_path::{Path, GenericPath};
 
 use sys::os_str::{Buf, Slice};
@@ -103,7 +104,7 @@ impl ops::Deref for OsString {
 
     #[inline]
     fn deref(&self) -> &OsStr {
-        &self[]
+        &self[..]
     }
 }
 
@@ -162,12 +163,21 @@ fn cmp(&self, other: &OsString) -> cmp::Ordering {
     }
 }
 
+#[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]
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        (&**self).hash(state)
+    }
+}
 
 impl OsStr {
     /// Coerce directly from a `&str` slice to a `&OsStr` slice.
@@ -253,12 +263,21 @@ impl Ord for OsStr {
     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]
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.bytes().hash(state)
+    }
+}
 
 impl Debug for OsStr {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
@@ -266,11 +285,12 @@ fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
     }
 }
 
-impl BorrowFrom<OsString> for OsStr {
-    fn borrow_from(owned: &OsString) -> &OsStr { &owned[] }
+impl Borrow<OsStr> for OsString {
+    fn borrow(&self) -> &OsStr { &self[..] }
 }
 
-impl ToOwned<OsString> for OsStr {
+impl ToOwned for OsStr {
+    type Owned = OsString;
     fn to_owned(&self) -> OsString { self.to_os_string() }
 }
 
@@ -288,7 +308,7 @@ fn as_os_str(&self) -> &OsStr {
 
 impl AsOsStr for OsString {
     fn as_os_str(&self) -> &OsStr {
-        &self[]
+        &self[..]
     }
 }
 
@@ -300,7 +320,7 @@ fn as_os_str(&self) -> &OsStr {
 
 impl AsOsStr for String {
     fn as_os_str(&self) -> &OsStr {
-        OsStr::from_str(&self[])
+        OsStr::from_str(&self[..])
     }
 }
 
index 2fd6631ecc4371fec61b516fab453d9cf05c8d7f..e9a8dbb4098afb3f15340725b35894ae409cf20b 100644 (file)
@@ -618,14 +618,14 @@ fn test_short_reads() {
     #[test]
     fn read_char_buffered() {
         let buf = [195u8, 159u8];
-        let mut reader = BufReader::with_capacity(1, &buf[]);
+        let mut reader = BufReader::with_capacity(1, &buf[..]);
         assert_eq!(reader.chars().next(), Some(Ok('ß')));
     }
 
     #[test]
     fn test_chars() {
         let buf = [195u8, 159u8, b'a'];
-        let mut reader = BufReader::with_capacity(1, &buf[]);
+        let mut reader = BufReader::with_capacity(1, &buf[..]);
         let mut it = reader.chars();
         assert_eq!(it.next(), Some(Ok('ß')));
         assert_eq!(it.next(), Some(Ok('a')));
index 9f3655de20fc245c91bbd9b79527bdc58bc6b5bc..f6cb4a8c9f36988f3b834b55261f1394eda32e70 100644 (file)
@@ -180,7 +180,7 @@ fn test_mem_writer() {
     fn test_buf_writer() {
         let mut buf = [0 as u8; 9];
         {
-            let mut writer = Cursor::new(&mut buf[]);
+            let mut writer = Cursor::new(&mut buf[..]);
             assert_eq!(writer.position(), 0);
             assert_eq!(writer.write(&[0]), Ok(1));
             assert_eq!(writer.position(), 1);
@@ -201,7 +201,7 @@ fn test_buf_writer() {
     fn test_buf_writer_seek() {
         let mut buf = [0 as u8; 8];
         {
-            let mut writer = Cursor::new(&mut buf[]);
+            let mut writer = Cursor::new(&mut buf[..]);
             assert_eq!(writer.position(), 0);
             assert_eq!(writer.write(&[1]), Ok(1));
             assert_eq!(writer.position(), 1);
@@ -229,7 +229,7 @@ fn test_buf_writer_seek() {
     #[test]
     fn test_buf_writer_error() {
         let mut buf = [0 as u8; 2];
-        let mut writer = Cursor::new(&mut buf[]);
+        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));
@@ -331,7 +331,7 @@ fn test_read_bad_char() {
     #[test]
     fn seek_past_end() {
         let buf = [0xff];
-        let mut r = Cursor::new(&buf[]);
+        let mut r = Cursor::new(&buf[..]);
         assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10));
         assert_eq!(r.read(&mut [0]), Ok(0));
 
@@ -340,7 +340,7 @@ fn seek_past_end() {
         assert_eq!(r.read(&mut [0]), Ok(0));
 
         let mut buf = [0];
-        let mut r = Cursor::new(&mut buf[]);
+        let mut r = Cursor::new(&mut buf[..]);
         assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10));
         assert_eq!(r.write(&[3]), Ok(0));
     }
@@ -348,14 +348,14 @@ fn seek_past_end() {
     #[test]
     fn seek_before_0() {
         let buf = [0xff_u8];
-        let mut r = Cursor::new(&buf[]);
+        let mut r = Cursor::new(&buf[..]);
         assert!(r.seek(SeekFrom::End(-2)).is_err());
 
         let mut r = Cursor::new(vec!(10u8));
         assert!(r.seek(SeekFrom::End(-2)).is_err());
 
         let mut buf = [0];
-        let mut r = Cursor::new(&mut buf[]);
+        let mut r = Cursor::new(&mut buf[..]);
         assert!(r.seek(SeekFrom::End(-2)).is_err());
     }
 
index 7c9a8a7b4b5ad2a8bef03bb3337ae19d7c3346c4..fbd403ea593b8a970b0218f876a193d4cc71f778 100644 (file)
 // NB: These reexports are in the order they should be listed in rustdoc
 
 pub use core::any;
-pub use core::borrow;
 pub use core::cell;
 pub use core::clone;
 #[cfg(not(test))] pub use core::cmp;
 #[cfg(not(test))] pub use alloc::boxed;
 pub use alloc::rc;
 
+pub use core_collections::borrow;
 pub use core_collections::fmt;
 pub use core_collections::slice;
 pub use core_collections::str;
index 66d4d34f8eb54a56de61c0f7d14e6ec3ccd75f39..51944adf3b40395f7adb88b57943ce2fb21a5b3d 100644 (file)
@@ -147,6 +147,7 @@ fn eq(&self, other: &Repr) -> bool {
 }
 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 {
@@ -160,6 +161,21 @@ fn hash(&self, s: &mut S) {
         }
     }
 }
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl hash::Hash for Repr {
+    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)
+            }
+        }
+    }
+}
 
 /// A trait for objects which can be converted or resolved to one or more
 /// `SocketAddr` values.
index 08f7a6e2e963663421229951fce8a63d80724db4..571a1b03ef07fbd879a1e98c7caafe1838506d87 100644 (file)
@@ -189,11 +189,19 @@ fn eq(&self, other: &Ipv4Addr) -> bool {
 }
 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) {
+        self.inner.s_addr.hash(s)
+    }
+}
 
 impl PartialOrd for Ipv4Addr {
     fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> {
@@ -421,11 +429,19 @@ fn eq(&self, other: &Ipv6Addr) -> bool {
 }
 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) {
+        self.inner.s6_addr.hash(s)
+    }
+}
 
 impl PartialOrd for Ipv6Addr {
     fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
index 59a437ad916537e23c47992b91b0b72bab8e6464..2d2d0d8b33a4c9e68ef0bf00e7f2511b878d7b22 100644 (file)
@@ -546,7 +546,7 @@ fn test_buffered_writer_inner_flushes() {
         assert_eq!(a, &w.get_ref()[]);
         let w = w.into_inner();
         let a: &[_] = &[0, 1];
-        assert_eq!(a, &w[]);
+        assert_eq!(a, &w[..]);
     }
 
     // This is just here to make sure that we don't infinite loop in the
@@ -643,14 +643,14 @@ fn test_short_reads() {
     #[test]
     fn read_char_buffered() {
         let buf = [195u8, 159u8];
-        let mut reader = BufferedReader::with_capacity(1, &buf[]);
+        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 mut reader = BufferedReader::with_capacity(1, &buf[]);
+        let mut reader = BufferedReader::with_capacity(1, &buf[..]);
         let mut it = reader.chars();
         assert_eq!(it.next(), Some(Ok('ß')));
         assert_eq!(it.next(), Some(Ok('a')));
index 21282a0c28abb79db5c7762986428f9262228c90..fc3deb67f41ec97148e6a2639964129193006150 100644 (file)
 use fmt;
 use isize;
 use iter::{Iterator, IteratorExt};
-use marker::Sized;
+use marker::{PhantomFn, Sized};
 use mem::transmute;
 use ops::FnOnce;
 use option::Option;
@@ -433,7 +433,7 @@ pub enum IoErrorKind {
 }
 
 /// A trait that lets you add a `detail` to an IoError easily
-trait UpdateIoError<T> {
+trait UpdateIoError {
     /// Returns an IoError with updated description and detail
     fn update_err<D>(self, desc: &'static str, detail: D) -> Self where
         D: FnOnce(&IoError) -> String;
@@ -446,7 +446,7 @@ fn update_detail<D>(self, detail: D) -> Self where
     fn update_desc(self, desc: &'static str) -> Self;
 }
 
-impl<T> UpdateIoError<T> for IoResult<T> {
+impl<T> UpdateIoError for IoResult<T> {
     fn update_err<D>(self, desc: &'static str, detail: D) -> IoResult<T> where
         D: FnOnce(&IoError) -> String,
     {
@@ -1572,7 +1572,9 @@ pub trait Seek {
 /// connections.
 ///
 /// Doing so produces some sort of Acceptor.
-pub trait Listener<T, A: Acceptor<T>> {
+pub trait Listener<T, A: Acceptor<T>>
+    : PhantomFn<T,T> // FIXME should be an assoc type anyhow
+{
     /// Spin up the listener and start queuing incoming connections
     ///
     /// # Error
index 8a4e8668b1092f1a878b788bbfbf6b444e7ec4f9..d05669d32b8cfc0d7f3b8b411b2bce5adc0cb471 100644 (file)
@@ -55,7 +55,7 @@ impl UnixStream {
     /// stream.write(&[1, 2, 3]);
     /// ```
     pub fn connect<P: BytesContainer>(path: P) -> IoResult<UnixStream> {
-        let path = CString::from_slice(path.container_as_bytes());
+        let path = try!(CString::new(path.container_as_bytes()));
         UnixStreamImp::connect(&path, None)
             .map(|inner| UnixStream { inner: inner })
     }
@@ -77,7 +77,7 @@ pub fn connect_timeout<P>(path: P, timeout: Duration)
             return Err(standard_error(TimedOut));
         }
 
-        let path = CString::from_slice(path.container_as_bytes());
+        let path = try!(CString::new(path.container_as_bytes()));
         UnixStreamImp::connect(&path, Some(timeout.num_milliseconds() as u64))
             .map(|inner| UnixStream { inner: inner })
     }
@@ -184,7 +184,7 @@ impl UnixListener {
     /// # }
     /// ```
     pub fn bind<P: BytesContainer>(path: P) -> IoResult<UnixListener> {
-        let path = CString::from_slice(path.container_as_bytes());
+        let path = try!(CString::new(path.container_as_bytes()));
         UnixListenerImp::bind(&path)
             .map(|inner| UnixListener { inner: inner })
     }
index ea6510c61b76be626372d567d9c4818d43228f0c..c803cfbcb7d85db2b9a77b33955b1ebce56c67a8 100644 (file)
@@ -104,7 +104,7 @@ pub struct Process {
 #[derive(Eq, Clone, Debug)]
 struct EnvKey(CString);
 
-#[cfg(windows)]
+#[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;
@@ -116,6 +116,18 @@ fn hash(&self, state: &mut H) {
         }
     }
 }
+#[cfg(all(windows, not(stage0)))]
+impl hash::Hash for EnvKey {
+    fn hash<H: hash::Hasher>(&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(windows)]
 impl PartialEq for EnvKey {
@@ -204,7 +216,7 @@ impl Command {
     /// otherwise configure the process.
     pub fn new<T: BytesContainer>(program: T) -> Command {
         Command {
-            program: CString::from_slice(program.container_as_bytes()),
+            program: CString::new(program.container_as_bytes()).unwrap(),
             args: Vec::new(),
             env: None,
             cwd: None,
@@ -219,14 +231,14 @@ pub fn new<T: BytesContainer>(program: T) -> Command {
 
     /// Add an argument to pass to the program.
     pub fn arg<'a, T: BytesContainer>(&'a mut self, arg: T) -> &'a mut Command {
-        self.args.push(CString::from_slice(arg.container_as_bytes()));
+        self.args.push(CString::new(arg.container_as_bytes()).unwrap());
         self
     }
 
     /// Add multiple arguments to pass to the program.
     pub fn args<'a, T: BytesContainer>(&'a mut self, args: &[T]) -> &'a mut Command {
         self.args.extend(args.iter().map(|arg| {
-            CString::from_slice(arg.container_as_bytes())
+            CString::new(arg.container_as_bytes()).unwrap()
         }));
         self
     }
@@ -239,8 +251,8 @@ fn get_env_map<'a>(&'a mut self) -> &'a mut EnvMap {
                 // if the env is currently just inheriting from the parent's,
                 // materialize the parent's env into a hashtable.
                 self.env = Some(os::env_as_bytes().into_iter().map(|(k, v)| {
-                    (EnvKey(CString::from_slice(&k)),
-                     CString::from_slice(&v))
+                    (EnvKey(CString::new(k).unwrap()),
+                     CString::new(v).unwrap())
                 }).collect());
                 self.env.as_mut().unwrap()
             }
@@ -254,8 +266,8 @@ fn get_env_map<'a>(&'a mut self) -> &'a mut EnvMap {
     pub fn env<'a, T, U>(&'a mut self, key: T, val: U)
                          -> &'a mut Command
                          where T: BytesContainer, U: BytesContainer {
-        let key = EnvKey(CString::from_slice(key.container_as_bytes()));
-        let val = CString::from_slice(val.container_as_bytes());
+        let key = EnvKey(CString::new(key.container_as_bytes()).unwrap());
+        let val = CString::new(val.container_as_bytes()).unwrap();
         self.get_env_map().insert(key, val);
         self
     }
@@ -263,7 +275,7 @@ pub fn env<'a, T, U>(&'a mut self, key: T, val: U)
     /// Removes an environment variable mapping.
     pub fn env_remove<'a, T>(&'a mut self, key: T) -> &'a mut Command
                              where T: BytesContainer {
-        let key = EnvKey(CString::from_slice(key.container_as_bytes()));
+        let key = EnvKey(CString::new(key.container_as_bytes()).unwrap());
         self.get_env_map().remove(&key);
         self
     }
@@ -276,15 +288,15 @@ pub fn env_set_all<'a, T, U>(&'a mut self, env: &[(T,U)])
                                  -> &'a mut Command
                                  where T: BytesContainer, U: BytesContainer {
         self.env = Some(env.iter().map(|&(ref k, ref v)| {
-            (EnvKey(CString::from_slice(k.container_as_bytes())),
-             CString::from_slice(v.container_as_bytes()))
+            (EnvKey(CString::new(k.container_as_bytes()).unwrap()),
+             CString::new(v.container_as_bytes()).unwrap())
         }).collect());
         self
     }
 
     /// Set the working directory for the child process.
     pub fn cwd<'a>(&'a mut self, dir: &Path) -> &'a mut Command {
-        self.cwd = Some(CString::from_slice(dir.as_vec()));
+        self.cwd = Some(CString::new(dir.as_vec()).unwrap());
         self
     }
 
@@ -1226,7 +1238,7 @@ fn env_map_keys_ci() {
         cmd.env("path", "foo");
         cmd.env("Path", "bar");
         let env = &cmd.env.unwrap();
-        let val = env.get(&EnvKey(CString::from_slice(b"PATH")));
-        assert!(val.unwrap() == &CString::from_slice(b"bar"));
+        let val = env.get(&EnvKey(CString::new(b"PATH").unwrap()));
+        assert!(val.unwrap() == &CString::new(b"bar").unwrap());
     }
 }
index 37de2993c4d0f77ed22f01d7544f750aaedd123b..e9005aa22bcfbebc37cbb051a1bcde0c412d3180 100644 (file)
@@ -877,7 +877,7 @@ fn container_as_bytes(&self) -> &[u8] {
     }
     #[inline]
     fn container_as_str(&self) -> Option<&str> {
-        Some(&self[])
+        Some(&self[..])
     }
     #[inline]
     fn is_str(_: Option<&String>) -> bool { true }
@@ -893,7 +893,7 @@ fn container_as_bytes(&self) -> &[u8] {
 impl BytesContainer for Vec<u8> {
     #[inline]
     fn container_as_bytes(&self) -> &[u8] {
-        &self[]
+        &self[..]
     }
 }
 
index 0a184a01a1d03650522c0c86584afe7d20424970..15eee9e4a0c02d3c2fa0360319a9cab81dec737c 100644 (file)
@@ -100,12 +100,21 @@ fn from_str(s: &str) -> Result<Path, ParsePathError> {
 #[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]
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        self.repr.hash(state)
+    }
+}
 
 impl BytesContainer for Path {
     #[inline]
@@ -1172,7 +1181,7 @@ macro_rules! t {
                     let exp: &[&[u8]] = &[$($exp),*];
                     assert_eq!(comps, exp);
                     let comps = path.components().rev().collect::<Vec<&[u8]>>();
-                    let exp = exp.iter().rev().map(|&x|x).collect::<Vec<&[u8]>>();
+                    let exp = exp.iter().rev().cloned().collect::<Vec<&[u8]>>();
                     assert_eq!(comps, exp)
                 }
             )
@@ -1204,7 +1213,7 @@ macro_rules! t {
                     let exp: &[Option<&str>] = &$exp;
                     assert_eq!(comps, exp);
                     let comps = path.str_components().rev().collect::<Vec<Option<&str>>>();
-                    let exp = exp.iter().rev().map(|&x|x).collect::<Vec<Option<&str>>>();
+                    let exp = exp.iter().rev().cloned().collect::<Vec<Option<&str>>>();
                     assert_eq!(comps, exp);
                 }
             )
index 02a21321c4cb9ce0b22d9b2e3e31dd6178c71eb6..887dc804c7af3da57949f4ea87c1fa249c46e751 100644 (file)
@@ -127,6 +127,7 @@ fn from_str(s: &str) -> Result<Path, ParsePathError> {
 #[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]
@@ -140,6 +141,21 @@ 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))]
+    #[inline]
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        self.repr.hash(state)
+    }
+
+    #[cfg(test)]
+    #[inline]
+    fn hash<H: hash::Hasher>(&self, _: &mut H) {
+        // No-op because the `hash` implementation will be wrong.
+    }
+}
 
 impl BytesContainer for Path {
     #[inline]
@@ -182,7 +198,7 @@ unsafe fn set_filename_unchecked<T: BytesContainer>(&mut self, filename: T) {
                 s.push_str("..");
                 s.push(SEP);
                 s.push_str(filename);
-                self.update_normalized(&s[]);
+                self.update_normalized(&s[..]);
             }
             None => {
                 self.update_normalized(filename);
@@ -192,20 +208,20 @@ unsafe fn set_filename_unchecked<T: BytesContainer>(&mut self, filename: T) {
                 s.push_str(&self.repr[..end]);
                 s.push(SEP);
                 s.push_str(filename);
-                self.update_normalized(&s[]);
+                self.update_normalized(&s[..]);
             }
             Some((idxb,idxa,_)) if self.prefix == Some(DiskPrefix) && idxa == self.prefix_len() => {
                 let mut s = String::with_capacity(idxb + filename.len());
                 s.push_str(&self.repr[..idxb]);
                 s.push_str(filename);
-                self.update_normalized(&s[]);
+                self.update_normalized(&s[..]);
             }
             Some((idxb,_,_)) => {
                 let mut s = String::with_capacity(idxb + 1 + filename.len());
                 s.push_str(&self.repr[..idxb]);
                 s.push(SEP);
                 s.push_str(filename);
-                self.update_normalized(&s[]);
+                self.update_normalized(&s[..]);
             }
         }
     }
@@ -229,7 +245,7 @@ fn is_vol_abs(path: &str, prefix: Option<PathPrefix>) -> bool {
         }
         fn shares_volume(me: &Path, path: &str) -> bool {
             // path is assumed to have a prefix of Some(DiskPrefix)
-            let repr = &me.repr[];
+            let repr = &me.repr[..];
             match me.prefix {
                 Some(DiskPrefix) => {
                     repr.as_bytes()[0] == path.as_bytes()[0].to_ascii_uppercase()
@@ -261,7 +277,7 @@ fn append_path(me: &mut Path, path: &str) {
                         else { None };
             let pathlen = path_.as_ref().map_or(path.len(), |p| p.len());
             let mut s = String::with_capacity(me.repr.len() + 1 + pathlen);
-            s.push_str(&me.repr[]);
+            s.push_str(&me.repr[..]);
             let plen = me.prefix_len();
             // if me is "C:" we don't want to add a path separator
             match me.prefix {
@@ -273,9 +289,9 @@ fn append_path(me: &mut Path, path: &str) {
             }
             match path_ {
                 None => s.push_str(path),
-                Some(p) => s.push_str(&p[]),
+                Some(p) => s.push_str(&p[..]),
             };
-            me.update_normalized(&s[])
+            me.update_normalized(&s[..])
         }
 
         if !path.is_empty() {
@@ -329,7 +345,7 @@ fn new_opt<T: BytesContainer>(path: T) -> Option<Path> {
     /// Always returns a `Some` value.
     #[inline]
     fn as_str<'a>(&'a self) -> Option<&'a str> {
-        Some(&self.repr[])
+        Some(&self.repr[..])
     }
 
     #[inline]
@@ -351,13 +367,13 @@ fn dirname<'a>(&'a self) -> &'a [u8] {
     /// Always returns a `Some` value.
     fn dirname_str<'a>(&'a self) -> Option<&'a str> {
         Some(match self.sepidx_or_prefix_len() {
-            None if ".." == self.repr => &self.repr[],
+            None if ".." == self.repr => &self.repr[..],
             None => ".",
             Some((_,idxa,end)) if &self.repr[idxa..end] == ".." => {
-                &self.repr[]
+                &self.repr[..]
             }
             Some((idxb,_,end)) if &self.repr[idxb..end] == "\\" => {
-                &self.repr[]
+                &self.repr[..]
             }
             Some((0,idxa,_)) => &self.repr[..idxa],
             Some((idxb,idxa,_)) => {
@@ -379,7 +395,7 @@ fn filename<'a>(&'a self) -> Option<&'a [u8]> {
     /// See `GenericPath::filename_str` for info.
     /// Always returns a `Some` value if `filename` returns a `Some` value.
     fn filename_str<'a>(&'a self) -> Option<&'a str> {
-        let repr = &self.repr[];
+        let repr = &self.repr[..];
         match self.sepidx_or_prefix_len() {
             None if "." == repr || ".." == repr => None,
             None => Some(repr),
@@ -639,7 +655,7 @@ pub fn new_opt<T: BytesContainer>(path: T) -> Option<Path> {
     /// Does not distinguish between absolute and cwd-relative paths, e.g.
     /// C:\foo and C:foo.
     pub fn str_components<'a>(&'a self) -> StrComponents<'a> {
-        let repr = &self.repr[];
+        let repr = &self.repr[..];
         let s = match self.prefix {
             Some(_) => {
                 let plen = self.prefix_len();
@@ -667,8 +683,8 @@ fn convert<'a>(x: Option<&'a str>) -> &'a [u8] {
     }
 
     fn equiv_prefix(&self, other: &Path) -> bool {
-        let s_repr = &self.repr[];
-        let o_repr = &other.repr[];
+        let s_repr = &self.repr[..];
+        let o_repr = &other.repr[..];
         match (self.prefix, other.prefix) {
             (Some(DiskPrefix), Some(VerbatimDiskPrefix)) => {
                 self.is_absolute() &&
@@ -823,7 +839,7 @@ fn normalize__(s: &str, prefix: Option<PathPrefix>) -> Option<String> {
     fn update_sepidx(&mut self) {
         let s = if self.has_nonsemantic_trailing_slash() {
                     &self.repr[..self.repr.len()-1]
-                } else { &self.repr[] };
+                } else { &self.repr[..] };
         let sep_test: fn(char) -> bool = if !prefix_is_verbatim(self.prefix) {
             is_sep
         } else {
@@ -902,7 +918,7 @@ pub fn is_verbatim(path: &Path) -> bool {
 /// non-verbatim, the non-verbatim version is returned.
 /// Otherwise, None is returned.
 pub fn make_non_verbatim(path: &Path) -> Option<Path> {
-    let repr = &path.repr[];
+    let repr = &path.repr[..];
     let new_path = match path.prefix {
         Some(VerbatimPrefix(_)) | Some(DeviceNSPrefix(_)) => return None,
         Some(UNCPrefix(_,_)) | Some(DiskPrefix) | None => return Some(path.clone()),
@@ -2226,7 +2242,7 @@ macro_rules! t {
                     assert_eq!(comps, exp);
                     let comps = path.str_components().rev().map(|x|x.unwrap())
                                 .collect::<Vec<&str>>();
-                    let exp = exp.iter().rev().map(|&x|x).collect::<Vec<&str>>();
+                    let exp = exp.iter().rev().cloned().collect::<Vec<&str>>();
                     assert_eq!(comps, exp);
                 }
             );
@@ -2282,7 +2298,7 @@ macro_rules! t {
                     let exp: &[&[u8]] = &$exp;
                     assert_eq!(comps, exp);
                     let comps = path.components().rev().collect::<Vec<&[u8]>>();
-                    let exp = exp.iter().rev().map(|&x|x).collect::<Vec<&[u8]>>();
+                    let exp = exp.iter().rev().cloned().collect::<Vec<&[u8]>>();
                     assert_eq!(comps, exp);
                 }
             )
index a4213e7373b1e0077579aa764ba492bf77a94fc9..f181fc5df5759b557ae5f9099ff12fd6061754b7 100644 (file)
@@ -561,10 +561,11 @@ pub fn get_exit_status() -> int {
 #[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 as uint).map(|i| {
-        ffi::c_str_to_bytes(&*argv.offset(i as int)).to_vec()
+    (0..argc).map(|i| {
+        CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec()
     }).collect()
 }
 
index 35221a7e647cc728fd5896b284669567533ceb2e..2e05f6d974e3ed9492917d5e8335413261e9c6bc 100644 (file)
@@ -37,7 +37,7 @@ pub fn on_panic(obj: &(Any+Send), file: &'static str, line: uint) {
     let msg = match obj.downcast_ref::<&'static str>() {
         Some(s) => *s,
         None => match obj.downcast_ref::<String>() {
-            Some(s) => &s[],
+            Some(s) => &s[..],
             None => "Box<Any>",
         }
     };
index 1d992668900f05b4fb8c49b189ec23951131552a..49a5efec7c2e48095a9bdc282b5274d7b24a5410 100755 (executable)
 use core::prelude::*;
 
 use ascii::*;
-use borrow::BorrowFrom;
+use borrow::{Borrow, ToOwned, Cow};
 use cmp;
-use iter;
+use iter::{self, IntoIterator};
 use mem;
 use ops::{self, Deref};
-use string::CowString;
 use vec::Vec;
 use fmt;
 
@@ -953,7 +952,7 @@ pub fn into_os_string(self) -> OsString {
 }
 
 impl<'a, P: ?Sized + 'a> iter::FromIterator<&'a P> for PathBuf where P: AsPath {
-    fn from_iter<I: Iterator<Item = &'a P>>(iter: I) -> PathBuf {
+    fn from_iter<I: IntoIterator<Item = &'a P>>(iter: I) -> PathBuf {
         let mut buf = PathBuf::new("");
         buf.extend(iter);
         buf
@@ -961,7 +960,7 @@ fn from_iter<I: Iterator<Item = &'a P>>(iter: I) -> PathBuf {
 }
 
 impl<'a, P: ?Sized + 'a> iter::Extend<&'a P> for PathBuf where P: AsPath {
-    fn extend<I: Iterator<Item = &'a P>>(&mut self, iter: I) {
+    fn extend<I: IntoIterator<Item = &'a P>>(&mut self, iter: I) {
         for p in iter {
             self.push(p)
         }
@@ -978,16 +977,21 @@ impl ops::Deref for PathBuf {
     type Target = Path;
 
     fn deref(&self) -> &Path {
-        unsafe { mem::transmute(&self.inner[]) }
+        unsafe { mem::transmute(&self.inner[..]) }
     }
 }
 
-impl BorrowFrom<PathBuf> for Path {
-    fn borrow_from(owned: &PathBuf) -> &Path {
-        owned.deref()
+impl Borrow<Path> for PathBuf {
+    fn borrow(&self) -> &Path {
+        self.deref()
     }
 }
 
+impl ToOwned for Path {
+    type Owned = PathBuf;
+    fn to_owned(&self) -> PathBuf { self.to_path_buf() }
+}
+
 impl cmp::PartialEq for PathBuf {
     fn eq(&self, other: &PathBuf) -> bool {
         self.components() == other.components()
@@ -1010,7 +1014,7 @@ fn cmp(&self, other: &PathBuf) -> cmp::Ordering {
 
 impl AsOsStr for PathBuf {
     fn as_os_str(&self) -> &OsStr {
-        &self.inner[]
+        &self.inner[..]
     }
 }
 
@@ -1066,10 +1070,10 @@ pub fn to_str(&self) -> Option<&str> {
         self.inner.to_str()
     }
 
-    /// Convert a `Path` to a `CowString`.
+    /// Convert a `Path` to a `Cow<str>`.
     ///
     /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
-    pub fn to_string_lossy(&self) -> CowString {
+    pub fn to_string_lossy(&self) -> Cow<str> {
         self.inner.to_string_lossy()
     }
 
index 25d372b406f76fc11fd2b314540d31e9a1ff92f7..5c891441198039940cab0e08776a06379d9bf860 100644 (file)
@@ -547,7 +547,7 @@ fn test_gen_vec() {
     #[test]
     fn test_choose() {
         let mut r = thread_rng();
-        assert_eq!(r.choose(&[1, 1, 1]).map(|&x|x), Some(1));
+        assert_eq!(r.choose(&[1, 1, 1]).cloned(), Some(1));
 
         let v: &[int] = &[];
         assert_eq!(r.choose(v), None);
index c2f5133eaf3fe5547a3fd450274d0948d127cee4..61f5bd0f013606f37f2e4476acf3b155c5f7f6af 100644 (file)
@@ -49,7 +49,7 @@ mod imp {
 
     use libc;
     use mem;
-    use ffi;
+    use ffi::CStr;
 
     use sync::{StaticMutex, MUTEX_INIT};
 
@@ -96,10 +96,11 @@ fn get_global_ptr() -> *mut Option<Box<Vec<Vec<u8>>>> {
         unsafe { mem::transmute(&GLOBAL_ARGS_PTR) }
     }
 
-    unsafe fn load_argc_and_argv(argc: int, argv: *const *const u8) -> Vec<Vec<u8>> {
+    unsafe fn load_argc_and_argv(argc: isize,
+                                 argv: *const *const u8) -> Vec<Vec<u8>> {
         let argv = argv as *const *const libc::c_char;
-        (0..argc as uint).map(|i| {
-            ffi::c_str_to_bytes(&*argv.offset(i as int)).to_vec()
+        (0..argc).map(|i| {
+            CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec()
         }).collect()
     }
 
index 7325e0a5ac8ddfaeb3726aeca06be0c723b5d987..e2ac5ac24f89ec01269f0eb545a58d381e296b46 100644 (file)
@@ -12,8 +12,7 @@
 use self::SocketStatus::*;
 use self::InAddr::*;
 
-use ffi::CString;
-use ffi;
+use ffi::{CString, CStr};
 use old_io::net::addrinfo;
 use old_io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr};
 use old_io::{IoResult, IoError};
@@ -235,9 +234,15 @@ pub fn get_host_addresses(host: Option<&str>, servname: Option<&str>,
 
     assert!(host.is_some() || servname.is_some());
 
-    let c_host = host.map(|x| CString::from_slice(x.as_bytes()));
+    let c_host = match host {
+        Some(x) => Some(try!(CString::new(x))),
+        None => None,
+    };
     let c_host = c_host.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
-    let c_serv = servname.map(|x| CString::from_slice(x.as_bytes()));
+    let c_serv = match servname {
+        Some(x) => Some(try!(CString::new(x))),
+        None => None,
+    };
     let c_serv = c_serv.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
 
     let hint = hint.map(|hint| {
@@ -325,8 +330,8 @@ pub fn get_address_name(addr: IpAddr) -> Result<String, IoError> {
     }
 
     unsafe {
-        Ok(str::from_utf8(ffi::c_str_to_bytes(&hostbuf.as_ptr()))
-               .unwrap().to_string())
+        let data = CStr::from_ptr(hostbuf.as_ptr());
+        Ok(str::from_utf8(data.to_bytes()).unwrap().to_string())
     }
 }
 
index 5af59ec6d2b1473ae3b513bf420c0eff0400eb96..713f79c5d0814d29b64d0936779ce547cd3ce29c 100644 (file)
@@ -121,7 +121,7 @@ fn drop(&mut self) {
 pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
     init();
 
-    let c_host = CString::from_slice(host.as_bytes());
+    let c_host = try!(CString::new(host));
     let mut res = 0 as *mut _;
     unsafe {
         try!(cvt_gai(getaddrinfo(c_host.as_ptr(), 0 as *const _, 0 as *const _,
index b610f6c370bb3bcfcc99db2c47e99180f538cc8c..ca3ae1a7a34360fa158012705feba28fbba07b83 100644 (file)
@@ -31,8 +31,9 @@
 use borrow::Cow;
 use cmp;
 use fmt;
-use hash::{Hash, Writer, Hasher};
-use iter::FromIterator;
+use hash::{Hash, Hasher};
+#[cfg(stage0)] use hash::Writer;
+use iter::{FromIterator, IntoIterator};
 use mem;
 use num::Int;
 use ops;
@@ -356,9 +357,9 @@ pub fn into_string_lossy(mut self) -> String {
 /// This replaces surrogate code point pairs with supplementary code points,
 /// like concatenating ill-formed UTF-16 strings effectively would.
 impl FromIterator<CodePoint> for Wtf8Buf {
-    fn from_iter<T: Iterator<Item=CodePoint>>(iterator: T) -> Wtf8Buf {
+    fn from_iter<T: IntoIterator<Item=CodePoint>>(iter: T) -> Wtf8Buf {
         let mut string = Wtf8Buf::new();
-        string.extend(iterator);
+        string.extend(iter);
         string
     }
 }
@@ -368,7 +369,8 @@ fn from_iter<T: Iterator<Item=CodePoint>>(iterator: T) -> Wtf8Buf {
 /// This replaces surrogate code point pairs with supplementary code points,
 /// like concatenating ill-formed UTF-16 strings effectively would.
 impl Extend<CodePoint> for Wtf8Buf {
-    fn extend<T: Iterator<Item=CodePoint>>(&mut self, iterator: T) {
+    fn extend<T: IntoIterator<Item=CodePoint>>(&mut self, iterable: T) {
+        let iterator = iterable.into_iter();
         let (low, _high) = iterator.size_hint();
         // Lower bound of one byte per code point (ASCII only)
         self.bytes.reserve(low);
@@ -794,13 +796,22 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[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) {
+        self.value.hash(state)
+    }
+}
 
+#[cfg(stage0)]
 impl<S: Writer + Hasher> Hash<S> for Wtf8Buf {
     #[inline]
     fn hash(&self, state: &mut S) {
@@ -808,7 +819,16 @@ fn hash(&self, state: &mut S) {
         0xfeu8.hash(state)
     }
 }
+#[cfg(not(stage0))]
+impl Hash for Wtf8Buf {
+    #[inline]
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        state.write(&self.bytes);
+        0xfeu8.hash(state)
+    }
+}
 
+#[cfg(stage0)]
 impl<'a, S: Writer + Hasher> Hash<S> for Wtf8 {
     #[inline]
     fn hash(&self, state: &mut S) {
@@ -816,6 +836,14 @@ fn hash(&self, state: &mut S) {
         0xfeu8.hash(state)
     }
 }
+#[cfg(not(stage0))]
+impl Hash for Wtf8 {
+    #[inline]
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        state.write(&self.bytes);
+        0xfeu8.hash(state)
+    }
+}
 
 impl AsciiExt for Wtf8 {
     type Owned = Wtf8Buf;
index 5e512e9261b1dfe475ec84ecad7adcb36c608c44..8b560339f304474c6cb67d523d69a138f7c2341f 100644 (file)
@@ -85,7 +85,7 @@
 
 use prelude::v1::*;
 
-use ffi;
+use ffi::CStr;
 use old_io::IoResult;
 use libc;
 use mem;
@@ -233,7 +233,7 @@ fn dladdr(addr: *const libc::c_void,
         output(w, idx,addr, None)
     } else {
         output(w, idx, addr, Some(unsafe {
-            ffi::c_str_to_bytes(&info.dli_sname)
+            CStr::from_ptr(info.dli_sname).to_bytes()
         }))
     }
 }
@@ -364,7 +364,7 @@ unsafe fn init_state() -> *mut backtrace_state {
     if ret == 0 || data.is_null() {
         output(w, idx, addr, None)
     } else {
-        output(w, idx, addr, Some(unsafe { ffi::c_str_to_bytes(&data) }))
+        output(w, idx, addr, Some(unsafe { CStr::from_ptr(data).to_bytes() }))
     }
 }
 
index bbbe022fbaf619ce9c5cbef9dd978aa97888e2b0..b8b9dcfb3c68920b2602ed2e1e22072ac5d106be 100644 (file)
@@ -33,7 +33,7 @@
 
 use prelude::v1::*;
 
-use ffi::{CString, OsStr, OsString};
+use ffi::{CString, NulError, OsStr, OsString};
 use fs::{self, Permissions, OpenOptions};
 use net;
 use mem;
@@ -155,7 +155,7 @@ pub trait OsStrExt {
     fn as_bytes(&self) -> &[u8];
 
     /// Convert the `OsStr` slice into a `CString`.
-    fn to_cstring(&self) -> CString;
+    fn to_cstring(&self) -> Result<CString, NulError>;
 }
 
 impl OsStrExt for OsStr {
@@ -166,8 +166,8 @@ fn as_bytes(&self) -> &[u8] {
         &self.as_inner().inner
     }
 
-    fn to_cstring(&self) -> CString {
-        CString::from_slice(self.as_bytes())
+    fn to_cstring(&self) -> Result<CString, NulError> {
+        CString::new(self.as_bytes())
     }
 }
 
@@ -249,5 +249,7 @@ fn signal(&self) -> Option<i32> {
 /// Includes all extension traits, and some important type definitions.
 pub mod prelude {
     #[doc(no_inline)]
-    pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt, CommandExt, ExitStatusExt};
+    pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt};
+    #[doc(no_inline)]
+    pub use super::{CommandExt, ExitStatusExt};
 }
index 0ee2b5b68090ede1123950edbb95c94059d8ed8a..5c847002d2394f35c1f4d7cb9c142f40edbe2de6 100644 (file)
@@ -12,7 +12,7 @@
 
 use prelude::v1::*;
 
-use ffi::{self, CString};
+use ffi::{CString, CStr};
 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};
@@ -151,8 +151,8 @@ fn drop(&mut self) {
     }
 }
 
-fn cstr(path: &Path) -> CString {
-    CString::from_slice(path.as_vec())
+fn cstr(path: &Path) -> IoResult<CString> {
+    Ok(try!(CString::new(path.as_vec())))
 }
 
 pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
@@ -170,7 +170,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
                             libc::S_IRUSR | libc::S_IWUSR),
     };
 
-    let path = cstr(path);
+    let path = try!(cstr(path));
     match retry(|| unsafe { libc::open(path.as_ptr(), flags, mode) }) {
         -1 => Err(super::last_error()),
         fd => Ok(FileDesc::new(fd, true)),
@@ -178,7 +178,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
 }
 
 pub fn mkdir(p: &Path, mode: uint) -> IoResult<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     mkerr_libc(unsafe { libc::mkdir(p.as_ptr(), mode as libc::mode_t) })
 }
 
@@ -203,7 +203,7 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<Path> {
     let mut buf = Vec::<u8>::with_capacity(size as uint);
     let ptr = buf.as_mut_ptr() as *mut dirent_t;
 
-    let p = CString::from_slice(p.as_vec());
+    let p = try!(CString::new(p.as_vec()));
     let dir_ptr = unsafe {opendir(p.as_ptr())};
 
     if dir_ptr as uint != 0 {
@@ -212,7 +212,7 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<Path> {
         while unsafe { readdir_r(dir_ptr, ptr, &mut entry_ptr) == 0 } {
             if entry_ptr.is_null() { break }
             paths.push(unsafe {
-                Path::new(ffi::c_str_to_bytes(&rust_list_dir_val(entry_ptr)))
+                Path::new(CStr::from_ptr(rust_list_dir_val(entry_ptr)).to_bytes())
             });
         }
         assert_eq!(unsafe { closedir(dir_ptr) }, 0);
@@ -223,39 +223,39 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<Path> {
 }
 
 pub fn unlink(p: &Path) -> IoResult<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     mkerr_libc(unsafe { libc::unlink(p.as_ptr()) })
 }
 
 pub fn rename(old: &Path, new: &Path) -> IoResult<()> {
-    let old = cstr(old);
-    let new = cstr(new);
+    let old = try!(cstr(old));
+    let new = try!(cstr(new));
     mkerr_libc(unsafe {
         libc::rename(old.as_ptr(), new.as_ptr())
     })
 }
 
 pub fn chmod(p: &Path, mode: uint) -> IoResult<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     mkerr_libc(retry(|| unsafe {
         libc::chmod(p.as_ptr(), mode as libc::mode_t)
     }))
 }
 
 pub fn rmdir(p: &Path) -> IoResult<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     mkerr_libc(unsafe { libc::rmdir(p.as_ptr()) })
 }
 
 pub fn chown(p: &Path, uid: int, gid: int) -> IoResult<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     mkerr_libc(retry(|| unsafe {
         libc::chown(p.as_ptr(), uid as libc::uid_t, gid as libc::gid_t)
     }))
 }
 
 pub fn readlink(p: &Path) -> IoResult<Path> {
-    let c_path = cstr(p);
+    let c_path = try!(cstr(p));
     let p = c_path.as_ptr();
     let mut len = unsafe { libc::pathconf(p as *mut _, libc::_PC_NAME_MAX) };
     if len == -1 {
@@ -276,14 +276,14 @@ pub fn readlink(p: &Path) -> IoResult<Path> {
 }
 
 pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
-    let src = cstr(src);
-    let dst = cstr(dst);
+    let src = try!(cstr(src));
+    let dst = try!(cstr(dst));
     mkerr_libc(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) })
 }
 
 pub fn link(src: &Path, dst: &Path) -> IoResult<()> {
-    let src = cstr(src);
-    let dst = cstr(dst);
+    let src = try!(cstr(src));
+    let dst = try!(cstr(dst));
     mkerr_libc(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) })
 }
 
@@ -331,7 +331,7 @@ fn gen(_stat: &libc::stat) -> u64 { 0 }
 }
 
 pub fn stat(p: &Path) -> IoResult<FileStat> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     let mut stat: libc::stat = unsafe { mem::zeroed() };
     match unsafe { libc::stat(p.as_ptr(), &mut stat) } {
         0 => Ok(mkstat(&stat)),
@@ -340,7 +340,7 @@ pub fn stat(p: &Path) -> IoResult<FileStat> {
 }
 
 pub fn lstat(p: &Path) -> IoResult<FileStat> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     let mut stat: libc::stat = unsafe { mem::zeroed() };
     match unsafe { libc::lstat(p.as_ptr(), &mut stat) } {
         0 => Ok(mkstat(&stat)),
@@ -349,7 +349,7 @@ pub fn lstat(p: &Path) -> IoResult<FileStat> {
 }
 
 pub fn utime(p: &Path, atime: u64, mtime: u64) -> IoResult<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     let buf = libc::utimbuf {
         actime: (atime / 1000) as libc::time_t,
         modtime: (mtime / 1000) as libc::time_t,
index e5904b074bcb980cc3fe502b2671de8daf52c4d3..92a47c6c3850df3a34b3ac132e83f72314db86d6 100644 (file)
@@ -12,7 +12,7 @@
 use io::prelude::*;
 use os::unix::prelude::*;
 
-use ffi::{self, CString, OsString, AsOsStr, OsStr};
+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 mem;
@@ -147,8 +147,7 @@ fn name_bytes(&self) -> &[u8] {
             fn rust_list_dir_val(ptr: *mut libc::dirent_t) -> *const c_char;
         }
         unsafe {
-            let ptr = rust_list_dir_val(self.dirent);
-            ffi::c_str_to_bytes(mem::copy_lifetime(self, &ptr))
+            CStr::from_ptr(rust_list_dir_val(self.dirent)).to_bytes()
         }
     }
 }
@@ -204,7 +203,7 @@ pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
             (true, false) |
             (false, false) => libc::O_RDONLY,
         };
-        let path = cstr(path);
+        let path = try!(cstr(path));
         let fd = try!(cvt_r(|| unsafe {
             libc::open(path.as_ptr(), flags, opts.mode)
         }));
@@ -268,19 +267,20 @@ pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
     pub fn fd(&self) -> &FileDesc { &self.0 }
 }
 
-fn cstr(path: &Path) -> CString {
-    CString::from_slice(path.as_os_str().as_bytes())
+fn cstr(path: &Path) -> io::Result<CString> {
+    let cstring = try!(path.as_os_str().to_cstring());
+    Ok(cstring)
 }
 
 pub fn mkdir(p: &Path) -> io::Result<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     try!(cvt(unsafe { libc::mkdir(p.as_ptr(), 0o777) }));
     Ok(())
 }
 
 pub fn readdir(p: &Path) -> io::Result<ReadDir> {
     let root = Rc::new(p.to_path_buf());
-    let p = cstr(p);
+    let p = try!(cstr(p));
     unsafe {
         let ptr = libc::opendir(p.as_ptr());
         if ptr.is_null() {
@@ -292,32 +292,32 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
 }
 
 pub fn unlink(p: &Path) -> io::Result<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     try!(cvt(unsafe { libc::unlink(p.as_ptr()) }));
     Ok(())
 }
 
 pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
-    let old = cstr(old);
-    let new = cstr(new);
+    let old = try!(cstr(old));
+    let new = try!(cstr(new));
     try!(cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) }));
     Ok(())
 }
 
 pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     try!(cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) }));
     Ok(())
 }
 
 pub fn rmdir(p: &Path) -> io::Result<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     try!(cvt(unsafe { libc::rmdir(p.as_ptr()) }));
     Ok(())
 }
 
 pub fn chown(p: &Path, uid: isize, gid: isize) -> io::Result<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     try!(cvt_r(|| unsafe {
         libc::chown(p.as_ptr(), uid as libc::uid_t, gid as libc::gid_t)
     }));
@@ -325,7 +325,7 @@ pub fn chown(p: &Path, uid: isize, gid: isize) -> io::Result<()> {
 }
 
 pub fn readlink(p: &Path) -> io::Result<PathBuf> {
-    let c_path = cstr(p);
+    let c_path = try!(cstr(p));
     let p = c_path.as_ptr();
     let mut len = unsafe { libc::pathconf(p as *mut _, libc::_PC_NAME_MAX) };
     if len < 0 {
@@ -343,35 +343,35 @@ pub fn readlink(p: &Path) -> io::Result<PathBuf> {
 }
 
 pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
-    let src = cstr(src);
-    let dst = cstr(dst);
+    let src = try!(cstr(src));
+    let dst = try!(cstr(dst));
     try!(cvt(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) }));
     Ok(())
 }
 
 pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
-    let src = cstr(src);
-    let dst = cstr(dst);
+    let src = try!(cstr(src));
+    let dst = try!(cstr(dst));
     try!(cvt(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) }));
     Ok(())
 }
 
 pub fn stat(p: &Path) -> io::Result<FileAttr> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     let mut stat: libc::stat = unsafe { mem::zeroed() };
     try!(cvt(unsafe { libc::stat(p.as_ptr(), &mut stat) }));
     Ok(FileAttr { stat: stat })
 }
 
 pub fn lstat(p: &Path) -> io::Result<FileAttr> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     let mut stat: libc::stat = unsafe { mem::zeroed() };
     try!(cvt(unsafe { libc::lstat(p.as_ptr(), &mut stat) }));
     Ok(FileAttr { stat: stat })
 }
 
 pub fn utimes(p: &Path, atime: u64, mtime: u64) -> io::Result<()> {
-    let p = cstr(p);
+    let p = try!(cstr(p));
     let buf = [super::ms_to_timeval(atime), super::ms_to_timeval(mtime)];
     try!(cvt(unsafe { c::utimes(p.as_ptr(), buf.as_ptr()) }));
     Ok(())
index 850189140d1eb494ff9717159d1602779b0d87dd..b79ad7031fa48dc31dcc208036ae5f5bf353eaf1 100644 (file)
@@ -17,7 +17,7 @@
 
 use prelude::v1::*;
 
-use ffi;
+use ffi::CStr;
 use io::{self, ErrorKind};
 use libc;
 use num::{Int, SignedInt};
@@ -91,7 +91,8 @@ pub fn last_gai_error(s: libc::c_int) -> IoError {
 
     let mut err = decode_error(s);
     err.detail = Some(unsafe {
-        str::from_utf8(ffi::c_str_to_bytes(&gai_strerror(s))).unwrap().to_string()
+        let data = CStr::from_ptr(gai_strerror(s));
+        str::from_utf8(data.to_bytes()).unwrap().to_string()
     });
     err
 }
index 54aec7cf4b193a9b25cea06d4062969752ac5ebc..83b6a14b78d95fd3f1ed4d8c385ec550bbb63d11 100644 (file)
@@ -10,7 +10,7 @@
 
 use prelude::v1::*;
 
-use ffi;
+use ffi::CStr;
 use io;
 use libc::{self, c_int, size_t};
 use str;
@@ -31,7 +31,7 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
     if err == 0 { return Ok(()) }
 
     let detail = unsafe {
-        str::from_utf8(ffi::c_str_to_bytes(&c::gai_strerror(err))).unwrap()
+        str::from_utf8(CStr::from_ptr(c::gai_strerror(err)).to_bytes()).unwrap()
             .to_string()
     };
     Err(io::Error::new(io::ErrorKind::Other,
index 5fe84cafb71e2cd6f51b4f8aec3bb5940b7130c0..3d1ef3a2c37f7e8267dfb65d84f79ba4e0e55bc1 100644 (file)
@@ -14,7 +14,7 @@
 use os::unix::*;
 
 use error::Error as StdError;
-use ffi::{self, CString, OsString, OsStr, AsOsStr};
+use ffi::{CString, CStr, OsString, OsStr, AsOsStr};
 use fmt;
 use iter;
 use libc::{self, c_int, c_char, c_void};
@@ -88,7 +88,7 @@ fn strerror_r(errnum: c_int, buf: *mut c_char,
         }
 
         let p = p as *const _;
-        str::from_utf8(ffi::c_str_to_bytes(&p)).unwrap().to_string()
+        str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_string()
     }
 }
 
@@ -98,13 +98,13 @@ pub fn getcwd() -> IoResult<Path> {
         if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() {
             Err(IoError::last_error())
         } else {
-            Ok(Path::new(ffi::c_str_to_bytes(&buf.as_ptr())))
+            Ok(Path::new(CStr::from_ptr(buf.as_ptr()).to_bytes()))
         }
     }
 }
 
 pub fn chdir(p: &Path) -> IoResult<()> {
-    let p = CString::from_slice(p.as_vec());
+    let p = CString::new(p.as_vec()).unwrap();
     unsafe {
         match libc::chdir(p.as_ptr()) == (0 as c_int) {
             true => Ok(()),
@@ -211,7 +211,7 @@ pub fn current_exe() -> IoResult<Path> {
         if v.is_null() {
             Err(IoError::last_error())
         } else {
-            Ok(Path::new(ffi::c_str_to_bytes(&v).to_vec()))
+            Ok(Path::new(CStr::from_ptr(&v).to_bytes().to_vec()))
         }
     }
 }
@@ -266,7 +266,7 @@ pub fn args() -> Args {
         let (argc, argv) = (*_NSGetArgc() as isize,
                             *_NSGetArgv() as *const *const c_char);
         range(0, argc as isize).map(|i| {
-            let bytes = ffi::c_str_to_bytes(&*argv.offset(i)).to_vec();
+            let bytes = CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec();
             OsStringExt::from_vec(bytes)
         }).collect::<Vec<_>>()
     };
@@ -324,7 +324,7 @@ pub fn args() -> Args {
             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 = ffi::c_str_to_bytes(&utf_c_str);
+            let bytes = CStr::from_ptr(utf_c_str).to_bytes();
             res.push(OsString::from_str(str::from_utf8(bytes).unwrap()))
         }
     }
@@ -380,7 +380,7 @@ pub fn env() -> Env {
         }
         let mut result = Vec::new();
         while *environ != ptr::null() {
-            result.push(parse(ffi::c_str_to_bytes(&*environ)));
+            result.push(parse(CStr::from_ptr(*environ).to_bytes()));
             environ = environ.offset(1);
         }
         Env { iter: result.into_iter(), _dont_send_or_sync_me: 0 as *mut _ }
@@ -397,20 +397,20 @@ fn parse(input: &[u8]) -> (OsString, OsString) {
 
 pub fn getenv(k: &OsStr) -> Option<OsString> {
     unsafe {
-        let s = CString::from_slice(k.as_bytes());
+        let s = k.to_cstring().unwrap();
         let s = libc::getenv(s.as_ptr()) as *const _;
         if s.is_null() {
             None
         } else {
-            Some(OsStringExt::from_vec(ffi::c_str_to_bytes(&s).to_vec()))
+            Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
         }
     }
 }
 
 pub fn setenv(k: &OsStr, v: &OsStr) {
     unsafe {
-        let k = CString::from_slice(k.as_bytes());
-        let v = CString::from_slice(v.as_bytes());
+        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());
         }
@@ -419,7 +419,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) {
 
 pub fn unsetenv(n: &OsStr) {
     unsafe {
-        let nbuf = CString::from_slice(n.as_bytes());
+        let nbuf = n.to_cstring().unwrap();
         if libc::funcs::posix01::unistd::unsetenv(nbuf.as_ptr()) != 0 {
             panic!("failed unsetenv: {}", IoError::last_error());
         }
@@ -480,7 +480,7 @@ unsafe fn fallback() -> Option<OsString> {
                 _ => return None
             }
             let ptr = passwd.pw_dir as *const _;
-            let bytes = ffi::c_str_to_bytes(&ptr).to_vec();
+            let bytes = CStr::from_ptr(ptr).to_bytes().to_vec();
             return Some(OsStringExt::from_vec(bytes))
         }
     }
index 45d5b1506c3aaf13145740f055c5f78075b2d0d3..3c9cdc65975f6f9f5e1b7027774b2a7dd0fa564f 100644 (file)
@@ -38,7 +38,7 @@ fn addr_to_sockaddr_un(addr: &CString,
             mem::size_of::<libc::sockaddr_un>());
     let s = unsafe { &mut *(storage as *mut _ as *mut libc::sockaddr_un) };
 
-    let len = addr.len();
+    let len = addr.as_bytes().len();
     if len > s.sun_path.len() - 1 {
         return Err(IoError {
             kind: old_io::InvalidInput,
@@ -47,8 +47,8 @@ fn addr_to_sockaddr_un(addr: &CString,
         })
     }
     s.sun_family = libc::AF_UNIX as libc::sa_family_t;
-    for (slot, value) in s.sun_path.iter_mut().zip(addr.iter()) {
-        *slot = *value;
+    for (slot, value) in s.sun_path.iter_mut().zip(addr.as_bytes().iter()) {
+        *slot = *value as libc::c_char;
     }
 
     // count the null terminator
index f954024b0e9e3450f8461da4a1f7a9e2da918098..b30ac889120c229343f6d48938c50658c24d891f 100644 (file)
@@ -12,6 +12,7 @@
 use self::Req::*;
 
 use collections::HashMap;
+#[cfg(stage0)]
 use collections::hash_map::Hasher;
 use ffi::CString;
 use hash::Hash;
@@ -63,6 +64,7 @@ pub unsafe fn killpid(pid: pid_t, signal: int) -> IoResult<()> {
         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>
@@ -278,6 +280,214 @@ fn setgroups(ngroups: libc::c_int,
             })
         })
     }
+    #[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
+        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);
+            })
+        })
+    }
 
     pub fn wait(&self, deadline: u64) -> IoResult<ProcessExit> {
         use cmp;
@@ -556,6 +766,7 @@ 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
@@ -593,6 +804,44 @@ fn with_envp<K,V,T,F>(env: Option<&HashMap<K, V>>,
         _ => cb(ptr::null())
     }
 }
+#[cfg(not(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,
+          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())
+    }
+}
 
 fn translate_status(status: c_int) -> ProcessExit {
     #![allow(non_snake_case)]
index 5e2c207f3756ae545c9e184a52f56ce64e1189ef..06fa5c4bba7253d66f4a3b45c00a6e3097168b8f 100644 (file)
@@ -11,7 +11,6 @@
 use prelude::v1::*;
 
 use collections::HashMap;
-use collections::hash_map::Hasher;
 use env;
 use ffi::{OsString, OsStr, CString};
 use fmt;
@@ -46,7 +45,7 @@ pub struct Command {
 impl Command {
     pub fn new(program: &OsStr) -> Command {
         Command {
-            program: program.to_cstring(),
+            program: program.to_cstring().unwrap(),
             args: Vec::new(),
             env: None,
             cwd: None,
@@ -57,10 +56,10 @@ pub fn new(program: &OsStr) -> Command {
     }
 
     pub fn arg(&mut self, arg: &OsStr) {
-        self.args.push(arg.to_cstring())
+        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(OsStrExt::to_cstring))
+        self.args.extend(args.map(|s| OsStrExt::to_cstring(s).unwrap()))
     }
     fn init_env_map(&mut self) {
         if self.env.is_none() {
@@ -79,7 +78,7 @@ pub fn env_clear(&mut self) {
         self.env = Some(HashMap::new())
     }
     pub fn cwd(&mut self, dir: &OsStr) {
-        self.cwd = Some(dir.to_cstring())
+        self.cwd = Some(dir.to_cstring().unwrap())
     }
 }
 
index 82c52471d109719ef99d0e5aab5a6fa4103a434f..c90ba7645feb4b29f14a6b6854804c6d79d617e9 100644 (file)
@@ -237,7 +237,7 @@ pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> {
 pub unsafe fn set_name(name: &str) {
     // pthread_setname_np() since glibc 2.12
     // availability autodetected via weak linkage
-    let cname = CString::from_slice(name.as_bytes());
+    let cname = CString::new(name).unwrap();
     type F = unsafe extern "C" fn(libc::pthread_t, *const libc::c_char) -> libc::c_int;
     extern {
         #[linkage = "extern_weak"]
@@ -255,14 +255,14 @@ pub unsafe fn set_name(name: &str) {
           target_os = "openbsd"))]
 pub unsafe fn set_name(name: &str) {
     // pthread_set_name_np() since almost forever on all BSDs
-    let cname = CString::from_slice(name.as_bytes());
+    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
-    let cname = CString::from_slice(name.as_bytes());
+    let cname = CString::new(name).unwrap();
     pthread_setname_np(cname.as_ptr());
 }
 
index 92e309da34bef34029745a3618743be2d7227e0f..51cf30324233c772cfaa66185365640db174b275 100644 (file)
@@ -25,7 +25,7 @@
 #![allow(dead_code)]
 
 use dynamic_lib::DynamicLibrary;
-use ffi;
+use ffi::CStr;
 use intrinsics;
 use old_io::{IoResult, Writer};
 use libc;
@@ -362,7 +362,7 @@ macro_rules! sym{ ($e:expr, $t:ident) => (unsafe {
         if ret == libc::TRUE {
             try!(write!(w, " - "));
             let ptr = info.Name.as_ptr() as *const libc::c_char;
-            let bytes = unsafe { ffi::c_str_to_bytes(&ptr) };
+            let bytes = unsafe { CStr::from_ptr(ptr).to_bytes() };
             match str::from_utf8(bytes) {
                 Ok(s) => try!(demangle(w, s)),
                 Err(..) => try!(w.write_all(&bytes[..bytes.len()-1])),
index f861255a00a14959e93a8cd4be43f1491661f06a..2d1a5e10bd63f73a6e815452f8ea9abb41e35cf6 100644 (file)
@@ -283,7 +283,7 @@ fn store_func(ptr: &AtomicUsize, module: &str, symbol: &str,
                   fallback: usize) -> usize {
         let mut module: Vec<u16> = module.utf16_units().collect();
         module.push(0);
-        let symbol = CString::from_slice(symbol.as_bytes());
+        let symbol = CString::new(symbol).unwrap();
         let func = unsafe {
             let handle = GetModuleHandleW(module.as_ptr());
             GetProcAddress(handle, symbol.as_ptr()) as usize
index 4d6d033deee1475cdd12b6d9d399f4b5ce0fe7db..a756fb29f81aeb5f32c4d446efb633cf6220b2b9 100644 (file)
@@ -265,12 +265,12 @@ fn fill_utf16_buf_base<F1, F2, T>(mut f1: F1, f2: F2) -> Result<T, ()>
         let mut n = stack_buf.len();
         loop {
             let buf = if n <= stack_buf.len() {
-                &mut stack_buf[]
+                &mut stack_buf[..]
             } else {
                 let extra = n - heap_buf.len();
                 heap_buf.reserve(extra);
                 heap_buf.set_len(n);
-                &mut heap_buf[]
+                &mut heap_buf[..]
             };
 
             // This function is typically called on windows API functions which
index 502d70d4e1a16f297464b5f08b09eb202fc5dd19..6520d30487c76d978e6d5441370214c0332402c3 100644 (file)
@@ -114,7 +114,7 @@ fn next(&mut self) -> Option<(OsString, OsString)> {
 
             let (k, v) = match s.iter().position(|&b| b == '=' as u16) {
                 Some(n) => (&s[..n], &s[n+1..]),
-                None => (s, &[][]),
+                None => (s, &[][..]),
             };
             Some((OsStringExt::from_wide(k), OsStringExt::from_wide(v)))
         }
@@ -186,7 +186,7 @@ fn next(&mut self) -> Option<Path> {
         if !must_yield && in_progress.is_empty() {
             None
         } else {
-            Some(super::os2path(&in_progress[]))
+            Some(super::os2path(&in_progress[..]))
         }
     }
 }
@@ -208,14 +208,14 @@ pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
             return Err(JoinPathsError)
         } else if v.contains(&sep) {
             joined.push(b'"' as u16);
-            joined.push_all(&v[]);
+            joined.push_all(&v[..]);
             joined.push(b'"' as u16);
         } else {
-            joined.push_all(&v[]);
+            joined.push_all(&v[..]);
         }
     }
 
-    Ok(OsStringExt::from_wide(&joined[]))
+    Ok(OsStringExt::from_wide(&joined[..]))
 }
 
 impl fmt::Display for JoinPathsError {
index 96ffc4daddd4eda3e9f9e6e115eed6a4914a0455..60d24e6174fd757a5cd949443ebc803ae1a6b61e 100644 (file)
@@ -10,7 +10,7 @@
 
 use prelude::v1::*;
 
-use collections::hash_map::Hasher;
+#[cfg(stage0)] use collections::hash_map::Hasher;
 use collections;
 use env;
 use ffi::CString;
@@ -106,6 +106,7 @@ pub unsafe fn killpid(pid: pid_t, signal: int) -> IoResult<()> {
     }
 
     #[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>
@@ -267,6 +268,169 @@ pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
             })
         }
     }
+    #[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>
+        where C: ProcessConfig<K, V>, P: AsInner<FileDesc>,
+              K: BytesContainer + Eq + Hash, 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 ()
+            })
+        }
+    }
 
     /// Waits for a process to exit and returns the exit code, failing
     /// if there is no process with the specified id.
@@ -425,6 +589,7 @@ fn backslash_run_ends_in_quote(s: &[char], mut i: uint) -> bool {
     }
 }
 
+#[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,
@@ -452,6 +617,34 @@ fn with_envp<K, V, T, F>(env: Option<&collections::HashMap<K, V>>, cb: F) -> T
         _ => 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,
+          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())
+    }
+}
 
 fn with_dirp<T, F>(d: Option<&CString>, cb: F) -> T where
     F: FnOnce(*const u16) -> T,
index 3137d779c4071c24cee2bfe723f79de99713b3f4..3653e7e31d5c6df556132b437f9ea107f16547a4 100644 (file)
 use cell::UnsafeCell;
 use fmt;
 use io;
-use marker;
+use marker::PhantomData;
 use old_io::stdio;
 use rt::{self, unwind};
 use sync::{Mutex, Condvar, Arc};
@@ -260,7 +260,7 @@ 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: marker::CovariantType }
+            JoinGuard { inner: inner, _marker: PhantomData }
         })
     }
 
@@ -642,7 +642,7 @@ fn drop(&mut self) {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct JoinGuard<'a, T: 'a> {
     inner: JoinInner<T>,
-    _marker: marker::CovariantType<&'a T>,
+    _marker: PhantomData<&'a T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
index d6778be553e8b2ec3655853a51a862bb3a0cfc25..140e21b5d04b756cb0a1abcf4e838f74a56e3231 100644 (file)
@@ -198,7 +198,7 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
 
 impl Decodable for Ident {
     fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
-        Ok(str_to_ident(&try!(d.read_str())[]))
+        Ok(str_to_ident(&try!(d.read_str())[..]))
     }
 }
 
index 5535e5911e0c2fd5e85ae763a14dcaef7e18915a..ba08f61b5575ccef6c7817b9ddc712605b296a1e 100644 (file)
@@ -86,7 +86,7 @@ pub fn path_to_string<PI: Iterator<Item=PathElem>>(path: PI) -> String {
         if !s.is_empty() {
             s.push_str("::");
         }
-        s.push_str(&e[]);
+        s.push_str(&e[..]);
         s
     })
 }
@@ -251,7 +251,7 @@ fn entry_count(&self) -> usize {
     }
 
     fn find_entry(&self, id: NodeId) -> Option<MapEntry<'ast>> {
-        self.map.borrow().get(id as usize).map(|e| *e)
+        self.map.borrow().get(id as usize).cloned()
     }
 
     pub fn krate(&self) -> &'ast Crate {
@@ -463,20 +463,20 @@ 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[]),
+            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[]),
+                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[]),
+                    MethodImplItem(ref m) => Some(&m.attrs[..]),
+                    TypeImplItem(ref t) => Some(&t.attrs[..]),
                 }
             }
-            NodeVariant(ref v) => Some(&v.node.attrs[]),
+            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).
@@ -577,7 +577,7 @@ fn suffix_matches(&self, parent: NodeId) -> bool {
                 None => return false,
                 Some((node_id, name)) => (node_id, name),
             };
-            if &part[] != mod_name.as_str() {
+            if &part[..] != mod_name.as_str() {
                 return false;
             }
             cursor = self.map.get_parent(mod_id);
@@ -615,7 +615,7 @@ fn item_is_mod(item: &Item) -> bool {
     // We are looking at some node `n` with a given name and parent
     // id; do their names match what I am seeking?
     fn matches_names(&self, parent_of_n: NodeId, name: Name) -> bool {
-        name.as_str() == &self.item_name[] &&
+        name.as_str() == &self.item_name[..] &&
             self.suffix_matches(parent_of_n)
     }
 }
@@ -1026,7 +1026,7 @@ fn print_node(&mut self, node: &Node) -> IoResult<()> {
 
 fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
     let id_str = format!(" (id={})", id);
-    let id_str = if include_id { &id_str[] } else { "" };
+    let id_str = if include_id { &id_str[..] } else { "" };
 
     match map.find(id) {
         Some(NodeItem(item)) => {
index 117507ad8b7e83a3ac77128f8dabe2f0cca894df..f660296fcd7b6c72892ac064bf3c0963376256a0 100644 (file)
@@ -257,11 +257,11 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
     match *trait_ref {
         Some(ref trait_ref) => {
             pretty.push('.');
-            pretty.push_str(&pprust::path_to_string(&trait_ref.path)[]);
+            pretty.push_str(&pprust::path_to_string(&trait_ref.path));
         }
         None => {}
     }
-    token::gensym_ident(&pretty[])
+    token::gensym_ident(&pretty[..])
 }
 
 pub fn trait_method_to_ty_method(method: &Method) -> TypeMethod {
@@ -673,7 +673,7 @@ pub fn pat_is_ident(pat: P<ast::Pat>) -> bool {
 pub fn path_name_eq(a : &ast::Path, b : &ast::Path) -> bool {
     (a.span == b.span)
     && (a.global == b.global)
-    && (segments_name_eq(&a.segments[], &b.segments[]))
+    && (segments_name_eq(&a.segments[..], &b.segments[..]))
 }
 
 // are two arrays of segments equal when compared unhygienically?
index a3afe5780d0d509cf7109e2b4e20bb56f2cf2215..62e676891a0e6c349fc6581cacf302c8de2484e5 100644 (file)
 use ptr::P;
 
 use std::cell::{RefCell, Cell};
-use std::collections::BitvSet;
+use std::collections::BitSet;
 use std::collections::HashSet;
 use std::fmt;
 
-thread_local! { static USED_ATTRS: RefCell<BitvSet> = RefCell::new(BitvSet::new()) }
+thread_local! { static USED_ATTRS: RefCell<BitSet> = RefCell::new(BitSet::new()) }
 
 pub fn mark_used(attr: &Attribute) {
     let AttrId(id) = attr.node.id;
@@ -44,7 +44,7 @@ pub fn is_used(attr: &Attribute) -> bool {
 
 pub trait AttrMetaMethods {
     fn check_name(&self, name: &str) -> bool {
-        name == &self.name()[]
+        name == &self.name()[..]
     }
 
     /// Retrieve the name of the meta item, e.g. `foo` in `#[foo]`,
@@ -62,7 +62,7 @@ fn check_name(&self, name: &str) -> bool {
 
 impl AttrMetaMethods for Attribute {
     fn check_name(&self, name: &str) -> bool {
-        let matches = name == &self.name()[];
+        let matches = name == &self.name()[..];
         if matches {
             mark_used(self);
         }
@@ -101,7 +101,7 @@ fn value_str(&self) -> Option<InternedString> {
 
     fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]> {
         match self.node {
-            MetaList(_, ref l) => Some(&l[]),
+            MetaList(_, ref l) => Some(&l[..]),
             _ => None
         }
     }
@@ -142,7 +142,7 @@ fn with_desugared_doc<T, F>(&self, f: F) -> T where
             let meta = mk_name_value_item_str(
                 InternedString::new("doc"),
                 token::intern_and_get_ident(&strip_doc_comment_decoration(
-                        &comment)[]));
+                        &comment)));
             if self.node.style == ast::AttrOuter {
                 f(&mk_attr_outer(self.node.id, meta))
             } else {
@@ -302,9 +302,9 @@ pub fn find_inline_attr(attrs: &[Attribute]) -> InlineAttr {
             }
             MetaList(ref n, ref items) if *n == "inline" => {
                 mark_used(attr);
-                if contains_name(&items[], "always") {
+                if contains_name(&items[..], "always") {
                     InlineAlways
-                } else if contains_name(&items[], "never") {
+                } else if contains_name(&items[..], "never") {
                     InlineNever
                 } else {
                     InlineHint
@@ -326,11 +326,11 @@ pub fn requests_inline(attrs: &[Attribute]) -> bool {
 /// Tests if a cfg-pattern matches the cfg set
 pub fn cfg_matches(diagnostic: &SpanHandler, cfgs: &[P<MetaItem>], cfg: &ast::MetaItem) -> bool {
     match cfg.node {
-        ast::MetaList(ref pred, ref mis) if &pred[] == "any" =>
+        ast::MetaList(ref pred, ref mis) if &pred[..] == "any" =>
             mis.iter().any(|mi| cfg_matches(diagnostic, cfgs, &**mi)),
-        ast::MetaList(ref pred, ref mis) if &pred[] == "all" =>
+        ast::MetaList(ref pred, ref mis) if &pred[..] == "all" =>
             mis.iter().all(|mi| cfg_matches(diagnostic, cfgs, &**mi)),
-        ast::MetaList(ref pred, ref mis) if &pred[] == "not" => {
+        ast::MetaList(ref pred, ref mis) if &pred[..] == "not" => {
             if mis.len() != 1 {
                 diagnostic.span_err(cfg.span, "expected 1 cfg-pattern");
                 return false;
@@ -382,7 +382,7 @@ fn find_stability_generic<'a,
 
     'outer: for attr in attrs {
         let tag = attr.name();
-        let tag = &tag[];
+        let tag = &tag[..];
         if tag != "deprecated" && tag != "unstable" && tag != "stable" {
             continue // not a stability level
         }
@@ -404,7 +404,7 @@ fn find_stability_generic<'a,
                             }
                         }
                     }
-                    if &meta.name()[] == "since" {
+                    if &meta.name()[..] == "since" {
                         match meta.value_str() {
                             Some(v) => since = Some(v),
                             None => {
@@ -413,7 +413,7 @@ fn find_stability_generic<'a,
                             }
                         }
                     }
-                    if &meta.name()[] == "reason" {
+                    if &meta.name()[..] == "reason" {
                         match meta.value_str() {
                             Some(v) => reason = Some(v),
                             None => {
@@ -501,7 +501,7 @@ pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[P<MetaItem>]) {
 
         if !set.insert(name.clone()) {
             diagnostic.span_fatal(meta.span,
-                                  &format!("duplicate meta item `{}`", name)[]);
+                                  &format!("duplicate meta item `{}`", name));
         }
     }
 }
@@ -521,7 +521,7 @@ pub fn find_repr_attrs(diagnostic: &SpanHandler, attr: &Attribute) -> Vec<ReprAt
             for item in items {
                 match item.node {
                     ast::MetaWord(ref word) => {
-                        let hint = match &word[] {
+                        let hint = match &word[..] {
                             // Can't use "extern" because it's not a lexical identifier.
                             "C" => Some(ReprExtern),
                             "packed" => Some(ReprPacked),
index 3231342cb50c8f37524ca7d44ee66fb163d56344..099f646294235d175dcdf47b59ac0daa419f7024 100644 (file)
@@ -360,7 +360,7 @@ pub fn new_filemap(&self, filename: FileName, src: String) -> Rc<FileMap> {
         let mut src = if src.starts_with("\u{feff}") {
             String::from_str(&src[3..])
         } else {
-            String::from_str(&src[])
+            String::from_str(&src[..])
         };
 
         // Append '\n' in case it's not already there.
index 7ca0591be5064e9e78745463dcdc29f4b1ac5aa7..dfe3477bddc3bba2eaafb7a92479e2c1e013a6d9 100644 (file)
@@ -311,7 +311,7 @@ fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
             }
         };
 
-        if attr::cfg_matches(self.diag, &self.config[], &cfg) {
+        if attr::cfg_matches(self.diag, &self.config[..], &cfg) {
             Some(respan(mi.span, ast::Attribute_ {
                 id: attr::mk_attr_id(),
                 style: attr.node.style,
index 83a4d938bb5d5567ef9af4fc4fea835aa4e2d2e8..27219774cf148c52f68f8e009fc8d7130691fdd8 100644 (file)
@@ -129,7 +129,7 @@ pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
         panic!(ExplicitBug);
     }
     pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! {
-        self.span_bug(sp, &format!("unimplemented {}", msg)[]);
+        self.span_bug(sp, &format!("unimplemented {}", msg));
     }
     pub fn handler<'a>(&'a self) -> &'a Handler {
         &self.handler
@@ -173,7 +173,7 @@ pub fn abort_if_errors(&self) {
                         self.err_count.get());
           }
         }
-        self.fatal(&s[]);
+        self.fatal(&s[..]);
     }
     pub fn warn(&self, msg: &str) {
         self.emit.borrow_mut().emit(None, msg, None, Warning);
@@ -189,7 +189,7 @@ pub fn bug(&self, msg: &str) -> ! {
         panic!(ExplicitBug);
     }
     pub fn unimpl(&self, msg: &str) -> ! {
-        self.bug(&format!("unimplemented {}", msg)[]);
+        self.bug(&format!("unimplemented {}", msg));
     }
     pub fn emit(&self,
                 cmsp: Option<(&codemap::CodeMap, Span)>,
@@ -311,16 +311,16 @@ fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level,
     }
 
     try!(print_maybe_styled(dst,
-                            &format!("{}: ", lvl.to_string())[],
+                            &format!("{}: ", lvl.to_string()),
                             term::attr::ForegroundColor(lvl.color())));
     try!(print_maybe_styled(dst,
-                            &format!("{}", msg)[],
+                            &format!("{}", msg),
                             term::attr::Bold));
 
     match code {
         Some(code) => {
             let style = term::attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
-            try!(print_maybe_styled(dst, &format!(" [{}]", code.clone())[], style));
+            try!(print_maybe_styled(dst, &format!(" [{}]", code.clone()), style));
         }
         None => ()
     }
@@ -419,12 +419,12 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
         // the span)
         let span_end = Span { lo: sp.hi, hi: sp.hi, expn_id: sp.expn_id};
         let ses = cm.span_to_string(span_end);
-        try!(print_diagnostic(dst, &ses[], lvl, msg, code));
+        try!(print_diagnostic(dst, &ses[..], lvl, msg, code));
         if rsp.is_full_span() {
             try!(custom_highlight_lines(dst, cm, sp, lvl, cm.span_to_lines(sp)));
         }
     } else {
-        try!(print_diagnostic(dst, &ss[], lvl, msg, code));
+        try!(print_diagnostic(dst, &ss[..], lvl, msg, code));
         if rsp.is_full_span() {
             try!(highlight_lines(dst, cm, sp, lvl, cm.span_to_lines(sp)));
         }
@@ -436,9 +436,9 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
         Some(code) =>
             match dst.registry.as_ref().and_then(|registry| registry.find_description(code)) {
                 Some(_) => {
-                    try!(print_diagnostic(dst, &ss[], Help,
+                    try!(print_diagnostic(dst, &ss[..], Help,
                                           &format!("pass `--explain {}` to see a detailed \
-                                                   explanation", code)[], None));
+                                                   explanation", code), None));
                 }
                 None => ()
             },
@@ -455,7 +455,7 @@ fn highlight_lines(err: &mut EmitterWriter,
     let fm = &*lines.file;
 
     let mut elided = false;
-    let mut display_lines = &lines.lines[];
+    let mut display_lines = &lines.lines[..];
     if display_lines.len() > MAX_LINES {
         display_lines = &display_lines[0..MAX_LINES];
         elided = true;
@@ -542,7 +542,7 @@ fn highlight_lines(err: &mut EmitterWriter,
             }
 
             try!(print_maybe_styled(err,
-                                    &format!("{}\n", s)[],
+                                    &format!("{}\n", s),
                                     term::attr::ForegroundColor(lvl.color())));
         }
     }
@@ -563,7 +563,7 @@ fn custom_highlight_lines(w: &mut EmitterWriter,
                           -> old_io::IoResult<()> {
     let fm = &*lines.file;
 
-    let lines = &lines.lines[];
+    let lines = &lines.lines[..];
     if lines.len() > MAX_LINES {
         if let Some(line) = fm.get_line(lines[0]) {
             try!(write!(&mut w.dst, "{}:{} {}\n", fm.name,
@@ -610,7 +610,7 @@ fn custom_highlight_lines(w: &mut EmitterWriter,
     s.push('^');
     s.push('\n');
     print_maybe_styled(w,
-                       &s[],
+                       &s[..],
                        term::attr::ForegroundColor(lvl.color()))
 }
 
@@ -618,22 +618,25 @@ 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| match expn_info {
-        Some(ei) => {
-            let ss = ei.callee.span.map_or(String::new(), |span| cm.span_to_string(span));
-            let (pre, post) = match ei.callee.format {
-                codemap::MacroAttribute => ("#[", "]"),
-                codemap::MacroBang => ("", "!")
-            };
-            try!(print_diagnostic(w, &ss[], Note,
-                                  &format!("in expansion of {}{}{}", pre,
-                                          ei.callee.name,
-                                          post)[], None));
-            let ss = cm.span_to_string(ei.call_site);
-            try!(print_diagnostic(w, &ss[], Note, "expansion site", None));
-            Ok(Some(ei.call_site))
-        }
-        None => Ok(None)
+    let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| -> old_io::IoResult<_> {
+        match expn_info {
+            Some(ei) => {
+                let ss = ei.callee.span.map_or(String::new(),
+                                               |span| cm.span_to_string(span));
+                let (pre, post) = match ei.callee.format {
+                    codemap::MacroAttribute => ("#[", "]"),
+                    codemap::MacroBang => ("", "!")
+                };
+                try!(print_diagnostic(w, &ss, Note,
+                                      &format!("in expansion of {}{}{}", pre,
+                                              ei.callee.name,
+                                              post), None));
+                let ss = cm.span_to_string(ei.call_site);
+                try!(print_diagnostic(w, &ss, Note, "expansion site", None));
+                Ok(Some(ei.call_site))
+            }
+            None => Ok(None)
+    }
     }));
     cs.map_or(Ok(()), |call_site| print_macro_backtrace(w, cm, call_site))
 }
@@ -643,6 +646,6 @@ pub fn expect<T, M>(diag: &SpanHandler, opt: Option<T>, msg: M) -> T where
 {
     match opt {
         Some(t) => t,
-        None => diag.handler().bug(&msg()[]),
+        None => diag.handler().bug(&msg()),
     }
 }
index 833a6d52acb9798ef77c766aa69ee65535b298e6..b3afc3fc4dd13399d7ff542496a0850279f22e22 100644 (file)
@@ -59,7 +59,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
             Some(previous_span) => {
                 ecx.span_warn(span, &format!(
                     "diagnostic code {} already used", &token::get_ident(code)
-                )[]);
+                ));
                 ecx.span_note(previous_span, "previous invocation");
             },
             None => ()
@@ -70,7 +70,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
         if !diagnostics.contains_key(&code.name) {
             ecx.span_err(span, &format!(
                 "used diagnostic code {} not registered", &token::get_ident(code)
-            )[]);
+            ));
         }
     });
     MacExpr::new(quote_expr!(ecx, ()))
@@ -95,12 +95,12 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
         if diagnostics.insert(code.name, description).is_some() {
             ecx.span_err(span, &format!(
                 "diagnostic code {} already registered", &token::get_ident(*code)
-            )[]);
+            ));
         }
     });
     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())
 }
 
index 62d48189c43475149b013f223bb2079af97e0199..a6cfd1a5a9ac3c1e612b02995457433ee344987d 100644 (file)
@@ -17,10 +17,10 @@ pub struct Registry {
 
 impl Registry {
     pub fn new(descriptions: &[(&'static str, &'static str)]) -> Registry {
-        Registry { descriptions: descriptions.iter().map(|&tuple| tuple).collect() }
+        Registry { descriptions: descriptions.iter().cloned().collect() }
     }
 
     pub fn find_description(&self, code: &str) -> Option<&'static str> {
-        self.descriptions.get(code).map(|desc| *desc)
+        self.descriptions.get(code).cloned()
     }
 }
index 8800ffd1e9b5f2eaea8611f8d8301dfdfdf9f693..d4ccabbd63b4a2edfb5f411a13b06b317e27440c 100644 (file)
@@ -640,7 +640,7 @@ pub fn original_span_in_file(&self) -> Span {
     pub fn mod_path(&self) -> Vec<ast::Ident> {
         let mut v = Vec::new();
         v.push(token::str_to_ident(&self.ecfg.crate_name[]));
-        v.extend(self.mod_path.iter().map(|a| *a));
+        v.extend(self.mod_path.iter().cloned());
         return v;
     }
     pub fn bt_push(&mut self, ei: ExpnInfo) {
index 80d128959eaf3a652632f6748fdddb330a68a4cb..38098e50dee83750ef905ce8309433f51f5c021e 100644 (file)
@@ -62,5 +62,5 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
     }
     base::MacExpr::new(cx.expr_str(
             sp,
-            token::intern_and_get_ident(&accumulator[])))
+            token::intern_and_get_ident(&accumulator[..])))
 }
index 63a8bd9ddf1b39972868aeba18fe19fbe52117fa..9410a51e7a5f660a368534d275fa651d7d5e13e1 100644 (file)
@@ -49,7 +49,7 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]
             }
         }
     }
-    let res = str_to_ident(&res_str[]);
+    let res = str_to_ident(&res_str[..]);
 
     let e = P(ast::Expr {
         id: ast::DUMMY_NODE_ID,
index 879718a6399f5b21f2e3bb024b35527bd1aa7752..93098484ae01343de6df460a61db1d43048e0916 100644 (file)
@@ -24,7 +24,7 @@ pub fn expand_deriving_bound<F>(cx: &mut ExtCtxt,
 {
     let name = match mitem.node {
         MetaWord(ref tname) => {
-            match &tname[] {
+            match &tname[..] {
                 "Copy" => "Copy",
                 "Send" | "Sync" => {
                     return cx.span_err(span,
index f878cb5ca8b78ff74377b6817bf6311a392b7885..b912ed34ae0ad19c780be51cbd640736a7020053 100644 (file)
@@ -367,7 +367,7 @@ pub fn expand<F>(&self,
                 "allow" | "warn" | "deny" | "forbid" => true,
                 _ => false,
             }
-        }).map(|a| a.clone()));
+        }).cloned());
         push(P(ast::Item {
             attrs: attrs,
             ..(*newitem).clone()
@@ -410,7 +410,7 @@ fn create_derived_impl(&self,
         let mut ty_params = ty_params.into_vec();
 
         // Copy the lifetimes
-        lifetimes.extend(generics.lifetimes.iter().map(|l| (*l).clone()));
+        lifetimes.extend(generics.lifetimes.iter().cloned());
 
         // Create the type parameters.
         ty_params.extend(generics.ty_params.iter().map(|ty_param| {
@@ -445,14 +445,14 @@ fn create_derived_impl(&self,
                         span: self.span,
                         bound_lifetimes: wb.bound_lifetimes.clone(),
                         bounded_ty: wb.bounded_ty.clone(),
-                        bounds: OwnedSlice::from_vec(wb.bounds.iter().map(|b| b.clone()).collect())
+                        bounds: OwnedSlice::from_vec(wb.bounds.iter().cloned().collect())
                     })
                 }
                 ast::WherePredicate::RegionPredicate(ref rb) => {
                     ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
                         span: self.span,
                         lifetime: rb.lifetime,
-                        bounds: rb.bounds.iter().map(|b| b.clone()).collect()
+                        bounds: rb.bounds.iter().cloned().collect()
                     })
                 }
                 ast::WherePredicate::EqPredicate(ref we) => {
@@ -500,7 +500,7 @@ fn create_derived_impl(&self,
         let opt_trait_ref = Some(trait_ref);
         let ident = ast_util::impl_pretty_name(&opt_trait_ref, &*self_type);
         let mut a = vec![attr];
-        a.extend(self.attributes.iter().map(|a| a.clone()));
+        a.extend(self.attributes.iter().cloned());
         cx.item(
             self.span,
             ident,
@@ -536,15 +536,15 @@ fn expand_struct_def(&self,
                     self,
                     struct_def,
                     type_ident,
-                    &self_args[],
-                    &nonself_args[])
+                    &self_args[..],
+                    &nonself_args[..])
             } else {
                 method_def.expand_struct_method_body(cx,
                                                      self,
                                                      struct_def,
                                                      type_ident,
-                                                     &self_args[],
-                                                     &nonself_args[])
+                                                     &self_args[..],
+                                                     &nonself_args[..])
             };
 
             method_def.create_method(cx,
@@ -576,15 +576,15 @@ fn expand_enum_def(&self,
                     self,
                     enum_def,
                     type_ident,
-                    &self_args[],
-                    &nonself_args[])
+                    &self_args[..],
+                    &nonself_args[..])
             } else {
                 method_def.expand_enum_method_body(cx,
                                                    self,
                                                    enum_def,
                                                    type_ident,
                                                    self_args,
-                                                   &nonself_args[])
+                                                   &nonself_args[..])
             };
 
             method_def.create_method(cx,
@@ -934,22 +934,22 @@ fn build_enum_match_tuple(
             .collect::<Vec<String>>();
 
         let self_arg_idents = self_arg_names.iter()
-            .map(|name|cx.ident_of(&name[]))
+            .map(|name|cx.ident_of(&name[..]))
             .collect::<Vec<ast::Ident>>();
 
         // The `vi_idents` will be bound, solely in the catch-all, to
         // a series of let statements mapping each self_arg to a usize
         // corresponding to its variant index.
         let vi_idents: Vec<ast::Ident> = self_arg_names.iter()
-            .map(|name| { let vi_suffix = format!("{}_vi", &name[]);
-                          cx.ident_of(&vi_suffix[]) })
+            .map(|name| { let vi_suffix = format!("{}_vi", &name[..]);
+                          cx.ident_of(&vi_suffix[..]) })
             .collect::<Vec<ast::Ident>>();
 
         // Builds, via callback to call_substructure_method, the
         // delegated expression that handles the catch-all case,
         // using `__variants_tuple` to drive logic if necessary.
         let catch_all_substructure = EnumNonMatchingCollapsed(
-            self_arg_idents, &variants[], &vi_idents[]);
+            self_arg_idents, &variants[..], &vi_idents[..]);
 
         // These arms are of the form:
         // (Variant1, Variant1, ...) => Body1
@@ -976,7 +976,7 @@ fn build_enum_match_tuple(
                     idents
                 };
                 for self_arg_name in self_arg_names.tail() {
-                    let (p, idents) = mk_self_pat(cx, &self_arg_name[]);
+                    let (p, idents) = mk_self_pat(cx, &self_arg_name[..]);
                     subpats.push(p);
                     self_pats_idents.push(idents);
                 }
@@ -1032,7 +1032,7 @@ fn build_enum_match_tuple(
                                                 &**variant,
                                                 field_tuples);
                 let arm_expr = self.call_substructure_method(
-                    cx, trait_, type_ident, &self_args[], nonself_args,
+                    cx, trait_, type_ident, &self_args[..], nonself_args,
                     &substructure);
 
                 cx.arm(sp, vec![single_pat], arm_expr)
@@ -1085,7 +1085,7 @@ fn build_enum_match_tuple(
             }
 
             let arm_expr = self.call_substructure_method(
-                cx, trait_, type_ident, &self_args[], nonself_args,
+                cx, trait_, type_ident, &self_args[..], nonself_args,
                 &catch_all_substructure);
 
             // Builds the expression:
@@ -1391,7 +1391,7 @@ pub fn cs_fold<F>(use_foldl: bool,
             }
         },
         EnumNonMatchingCollapsed(ref all_args, _, tuple) =>
-            enum_nonmatch_f(cx, trait_span, (&all_args[], tuple),
+            enum_nonmatch_f(cx, trait_span, (&all_args[..], tuple),
                             substructure.nonself_args),
         StaticEnum(..) | StaticStruct(..) => {
             cx.span_bug(trait_span, "static function in `derive`")
@@ -1431,7 +1431,7 @@ pub fn cs_same_method<F>(f: F,
             f(cx, trait_span, called)
         },
         EnumNonMatchingCollapsed(ref all_self_args, _, tuple) =>
-            enum_nonmatch_f(cx, trait_span, (&all_self_args[], tuple),
+            enum_nonmatch_f(cx, trait_span, (&all_self_args[..], tuple),
                             substructure.nonself_args),
         StaticEnum(..) | StaticStruct(..) => {
             cx.span_bug(trait_span, "static function in `derive`")
index 5aa9f9a0c3e761f163b476caeeabd61a5f4cc588..2149c7a7f77a7da72d86848fd952f24a415865ca 100644 (file)
@@ -14,7 +14,6 @@
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
-use parse::token::InternedString;
 use ptr::P;
 
 pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt,
@@ -26,30 +25,26 @@ pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt,
 {
 
     let path = Path::new_(pathvec_std!(cx, core::hash::Hash), None,
-                          vec!(box Literal(Path::new_local("__S"))), true);
-    let generics = LifetimeBounds {
-        lifetimes: Vec::new(),
-        bounds: vec!(("__S",
-                      vec!(path_std!(cx, core::hash::Writer),
-                           path_std!(cx, core::hash::Hasher)))),
-    };
-    let args = Path::new_local("__S");
-    let inline = cx.meta_word(span, InternedString::new("inline"));
-    let attrs = vec!(cx.attribute(span, inline));
+                          vec!(), true);
+    let arg = Path::new_local("__H");
     let hash_trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
         path: path,
         additional_bounds: Vec::new(),
-        generics: generics,
+        generics: LifetimeBounds::empty(),
         methods: vec!(
             MethodDef {
                 name: "hash",
-                generics: LifetimeBounds::empty(),
+                generics: LifetimeBounds {
+                    lifetimes: Vec::new(),
+                    bounds: vec![("__H",
+                                  vec![path_std!(cx, core::hash::Hasher)])],
+                },
                 explicit_self: borrowed_explicit_self(),
-                args: vec!(Ptr(box Literal(args), Borrowed(None, MutMutable))),
+                args: vec!(Ptr(box Literal(arg), Borrowed(None, MutMutable))),
                 ret_ty: nil_ty(),
-                attributes: attrs,
+                attributes: vec![],
                 combine_substructure: combine_substructure(box |a, b, c| {
                     hash_substructure(a, b, c)
                 })
index 0ed9e85e57677a19f52fbf890d003032e078a41c..f8bc331bfcfe7697a13bc4a0df84e03229f57075 100644 (file)
@@ -102,7 +102,7 @@ macro_rules! expand {
                                                    |i| push(i)))
                         }
 
-                        match &tname[] {
+                        match &tname[..] {
                             "Clone" => expand!(clone::expand_deriving_clone),
 
                             "Hash" => expand!(hash::expand_deriving_hash),
index 3f5947672e022ce67971f031b5e88827b701882b..281f23f9e61e8b232d2c083348bdaa90b873b790 100644 (file)
@@ -128,7 +128,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
     let formatter = substr.nonself_args[0].clone();
 
     let meth = cx.ident_of("write_fmt");
-    let s = token::intern_and_get_ident(&format_string[]);
+    let s = token::intern_and_get_ident(&format_string[..]);
     let format_string = cx.expr_str(span, s);
 
     // phew, not our responsibility any more!
index 5d56707c87a47b6c7b2bc9d55b3cb2ece4b5c6f6..9c04d1e928295d42c387eb8d3748b1e91d301c4d 100644 (file)
@@ -30,7 +30,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
         Some(v) => v
     };
 
-    let e = match env::var(&var[]) {
+    let e = match env::var(&var[..]) {
       Err(..) => {
           cx.expr_path(cx.path_all(sp,
                                    true,
@@ -56,7 +56,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
                                    cx.ident_of("Some")),
                               vec!(cx.expr_str(sp,
                                                token::intern_and_get_ident(
-                                          &s[]))))
+                                          &s[..]))))
       }
     };
     MacExpr::new(e)
@@ -101,7 +101,7 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         }
     }
 
-    let e = match env::var(&var[]) {
+    let e = match env::var(&var[..]) {
         Err(_) => {
             cx.span_err(sp, &msg);
             cx.expr_usize(sp, 0)
index 6b7cecee815765f3bebd2e83f0090a5d0a1c0660..d4dda7390a52f7788dae1cc2e2d7fcf25de6ccf0 100644 (file)
@@ -405,7 +405,7 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac, span: codemap::Span,
                                 },
                             });
                         let fm = fresh_mark();
-                        let marked_before = mark_tts(&tts[], fm);
+                        let marked_before = mark_tts(&tts[..], fm);
 
                         // The span that we pass to the expanders we want to
                         // be the root of the call stack. That's the most
@@ -416,7 +416,7 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac, span: codemap::Span,
                         let opt_parsed = {
                             let expanded = expandfun.expand(fld.cx,
                                                             mac_span,
-                                                            &marked_before[]);
+                                                            &marked_before[..]);
                             parse_thunk(expanded)
                         };
                         let parsed = match opt_parsed {
@@ -425,7 +425,7 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac, span: codemap::Span,
                                 fld.cx.span_err(
                                     pth.span,
                                     &format!("non-expression macro in expression position: {}",
-                                            &extnamestr[]
+                                            &extnamestr[..]
                                             )[]);
                                 return None;
                             }
@@ -633,8 +633,8 @@ pub fn expand_item_mac(it: P<ast::Item>,
                         }
                     });
                     // mark before expansion:
-                    let marked_before = mark_tts(&tts[], fm);
-                    expander.expand(fld.cx, it.span, &marked_before[])
+                    let marked_before = mark_tts(&tts[..], fm);
+                    expander.expand(fld.cx, it.span, &marked_before[..])
                 }
                 IdentTT(ref expander, span) => {
                     if it.ident.name == parse::token::special_idents::invalid.name {
@@ -652,7 +652,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
                         }
                     });
                     // mark before expansion:
-                    let marked_tts = mark_tts(&tts[], fm);
+                    let marked_tts = mark_tts(&tts[..], fm);
                     expander.expand(fld.cx, it.span, it.ident, marked_tts)
                 }
                 MacroRulesTT => {
@@ -971,11 +971,11 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> {
                     });
 
                     let fm = fresh_mark();
-                    let marked_before = mark_tts(&tts[], fm);
+                    let marked_before = mark_tts(&tts[..], fm);
                     let mac_span = fld.cx.original_span();
                     let expanded = match expander.expand(fld.cx,
                                         mac_span,
-                                        &marked_before[]).make_pat() {
+                                        &marked_before[..]).make_pat() {
                         Some(e) => e,
                         None => {
                             fld.cx.span_err(
@@ -1128,7 +1128,7 @@ fn expand_annotatable(a: Annotatable,
                 if valid_ident {
                     fld.cx.mod_push(it.ident);
                 }
-                let macro_use = contains_macro_use(fld, &new_attrs[]);
+                let macro_use = contains_macro_use(fld, &new_attrs[..]);
                 let result = with_exts_frame!(fld.cx.syntax_env,
                                               macro_use,
                                               noop_fold_item(it, fld));
@@ -1508,7 +1508,7 @@ fn fold_mac(&mut self, Spanned {node, span}: ast::Mac) -> ast::Mac {
             node: match node {
                 MacInvocTT(path, tts, ctxt) => {
                     MacInvocTT(self.fold_path(path),
-                               self.fold_tts(&tts[]),
+                               self.fold_tts(&tts[..]),
                                mtwt::apply_mark(self.mark, ctxt))
                 }
             },
@@ -1914,7 +1914,7 @@ fn run_renaming_test(t: &RenamingTest, test_idx: usize) {
                         .collect();
                     println!("varref #{}: {:?}, resolves to {}",idx, varref_idents, varref_name);
                     let string = token::get_ident(final_varref_ident);
-                    println!("varref's first segment's string: \"{}\"", &string[]);
+                    println!("varref's first segment's string: \"{}\"", &string[..]);
                     println!("binding #{}: {}, resolves to {}",
                              binding_idx, bindings[binding_idx], binding_name);
                     mtwt::with_sctable(|x| mtwt::display_sctable(x));
@@ -1967,10 +1967,10 @@ fn run_renaming_test(t: &RenamingTest, test_idx: usize) {
         let cxbinds: Vec<&ast::Ident> =
             bindings.iter().filter(|b| {
                 let ident = token::get_ident(**b);
-                let string = &ident[];
+                let string = &ident[..];
                 "xx" == string
             }).collect();
-        let cxbinds: &[&ast::Ident] = &cxbinds[];
+        let cxbinds: &[&ast::Ident] = &cxbinds[..];
         let cxbind = match cxbinds {
             [b] => b,
             _ => panic!("expected just one binding for ext_cx")
index 170a455a9132610d3658d0fd3786f6dd0e152222..e17329d7d33002b96f85c9060a1962a82330b7fe 100644 (file)
@@ -118,7 +118,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                 }
             };
             let interned_name = token::get_ident(ident);
-            let name = &interned_name[];
+            let name = &interned_name[..];
 
             p.expect(&token::Eq);
             let e = p.parse_expr();
@@ -218,7 +218,7 @@ fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
                     let msg = format!("invalid reference to argument `{}` ({})",
                                       arg, self.describe_num_args());
 
-                    self.ecx.span_err(self.fmtsp, &msg[]);
+                    self.ecx.span_err(self.fmtsp, &msg[..]);
                     return;
                 }
                 {
@@ -238,7 +238,7 @@ fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
                     Some(e) => e.span,
                     None => {
                         let msg = format!("there is no argument named `{}`", name);
-                        self.ecx.span_err(self.fmtsp, &msg[]);
+                        self.ecx.span_err(self.fmtsp, &msg[..]);
                         return;
                     }
                 };
@@ -587,7 +587,7 @@ fn format_arg(ecx: &ExtCtxt, sp: Span,
                   -> P<ast::Expr> {
         let trait_ = match *ty {
             Known(ref tyname) => {
-                match &tyname[] {
+                match &tyname[..] {
                     ""  => "Display",
                     "?" => "Debug",
                     "e" => "LowerExp",
index 67990895d071affa20ed0b129ef4b395e0adc9ec..2c7bf713aad85d67728d2abaddaa95906c5e9dac 100644 (file)
@@ -668,7 +668,7 @@ fn mk_tt(cx: &ExtCtxt, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> {
             for i in 0..tt.len() {
                 seq.push(tt.get_tt(i));
             }
-            mk_tts(cx, &seq[])
+            mk_tts(cx, &seq[..])
         }
         ast::TtToken(sp, ref tok) => {
             let e_sp = cx.expr_ident(sp, id_ext("_sp"));
@@ -757,7 +757,7 @@ 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());
+    vector.extend(mk_tts(cx, &tts[..]).into_iter());
     let block = cx.expr_block(
         cx.block_all(sp,
                      vector,
index 7a3a3562bdfdcbd9ede0d2597241449c74371470..c8d48750c75093259d428d491914075dd202b827 100644 (file)
@@ -65,7 +65,7 @@ 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,
-                                   token::intern_and_get_ident(&s[])))
+                                   token::intern_and_get_ident(&s[..])))
 }
 
 pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
@@ -78,7 +78,7 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                    .connect("::");
     base::MacExpr::new(cx.expr_str(
             sp,
-            token::intern_and_get_ident(&string[])))
+            token::intern_and_get_ident(&string[..])))
 }
 
 /// include! : parse the given file as an expr
@@ -117,7 +117,7 @@ fn make_items(mut self: Box<ExpandResult<'a>>)
                     None => self.p.span_fatal(
                         self.p.span,
                         &format!("expected item, found `{}`",
-                                 self.p.this_token_to_string())[]
+                                 self.p.this_token_to_string())
                     )
                 }
             }
@@ -141,7 +141,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             cx.span_err(sp,
                         &format!("couldn't read {}: {}",
                                 file.display(),
-                                e)[]);
+                                e));
             return DummyResult::expr(sp);
         }
         Ok(bytes) => bytes,
@@ -151,7 +151,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             // Add this input file to the code map to make it available as
             // dependency information
             let filename = format!("{}", file.display());
-            let interned = token::intern_and_get_ident(&src[]);
+            let interned = token::intern_and_get_ident(&src[..]);
             cx.codemap().new_filemap(filename, src);
 
             base::MacExpr::new(cx.expr_str(sp, interned))
@@ -159,7 +159,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         Err(_) => {
             cx.span_err(sp,
                         &format!("{} wasn't a utf-8 file",
-                                file.display())[]);
+                                file.display()));
             return DummyResult::expr(sp);
         }
     }
@@ -175,11 +175,11 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     match File::open(&file).read_to_end() {
         Err(e) => {
             cx.span_err(sp,
-                        &format!("couldn't read {}: {}", file.display(), e)[]);
+                        &format!("couldn't read {}: {}", file.display(), e));
             return DummyResult::expr(sp);
         }
         Ok(bytes) => {
-            let bytes = bytes.iter().map(|x| *x).collect();
+            let bytes = bytes.iter().cloned().collect();
             base::MacExpr::new(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes))))
         }
     }
index d649e497ef71a871f90a5ea32caa72c0bdb9f3a6..664f7b3e088480e2a55ef7e6a93cba00eab2a9f1 100644 (file)
@@ -165,7 +165,7 @@ pub fn count_names(ms: &[TokenTree]) -> usize {
 
 pub fn initial_matcher_pos(ms: Rc<Vec<TokenTree>>, sep: Option<Token>, lo: BytePos)
                            -> Box<MatcherPos> {
-    let match_idx_hi = count_names(&ms[]);
+    let match_idx_hi = count_names(&ms[..]);
     let matches: Vec<_> = (0..match_idx_hi).map(|_| Vec::new()).collect();
     box MatcherPos {
         stack: vec![],
@@ -229,7 +229,7 @@ fn n_rec(p_s: &ParseSess, m: &TokenTree, res: &[Rc<NamedMatch>],
                         p_s.span_diagnostic
                            .span_fatal(sp,
                                        &format!("duplicated bind name: {}",
-                                               &string)[])
+                                               &string))
                     }
                 }
             }
@@ -254,13 +254,13 @@ pub fn parse_or_else(sess: &ParseSess,
                      rdr: TtReader,
                      ms: Vec<TokenTree> )
                      -> HashMap<Ident, Rc<NamedMatch>> {
-    match parse(sess, cfg, rdr, &ms[]) {
+    match parse(sess, cfg, rdr, &ms[..]) {
         Success(m) => m,
         Failure(sp, str) => {
-            sess.span_diagnostic.span_fatal(sp, &str[])
+            sess.span_diagnostic.span_fatal(sp, &str[..])
         }
         Error(sp, str) => {
-            sess.span_diagnostic.span_fatal(sp, &str[])
+            sess.span_diagnostic.span_fatal(sp, &str[..])
         }
     }
 }
@@ -283,7 +283,7 @@ pub fn parse(sess: &ParseSess,
              -> ParseResult {
     let mut cur_eis = Vec::new();
     cur_eis.push(initial_matcher_pos(Rc::new(ms.iter()
-                                                .map(|x| (*x).clone())
+                                                .cloned()
                                                 .collect()),
                                      None,
                                      rdr.peek().sp.lo));
@@ -447,7 +447,7 @@ pub fn parse(sess: &ParseSess,
                 for dv in &mut (&mut eof_eis[0]).matches {
                     v.push(dv.pop().unwrap());
                 }
-                return Success(nameize(sess, ms, &v[]));
+                return Success(nameize(sess, ms, &v[..]));
             } else if eof_eis.len() > 1 {
                 return Error(sp, "ambiguity: multiple successful parses".to_string());
             } else {
@@ -533,7 +533,7 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
         _ => {
             let token_str = pprust::token_to_string(&p.token);
             p.fatal(&format!("expected ident, found {}",
-                             &token_str[])[])
+                             &token_str[..]))
         }
       },
       "path" => {
@@ -542,7 +542,7 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
       "meta" => token::NtMeta(p.parse_meta_item()),
       _ => {
           p.span_fatal_help(sp,
-                            &format!("invalid fragment specifier `{}`", name)[],
+                            &format!("invalid fragment specifier `{}`", name),
                             "valid fragment specifiers are `ident`, `block`, \
                              `stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \
                              and `item`")
index f322cf8bad09cc103cdf627353b297be0dddd0d6..fa6d934a4575581561476a177af7bb8872cdf195 100644 (file)
@@ -50,7 +50,7 @@ fn ensure_complete_parse(&self, allow_semi: bool) {
                                following",
                               token_str);
             let span = parser.span;
-            parser.span_err(span, &msg[]);
+            parser.span_err(span, &msg[..]);
         }
     }
 }
@@ -123,8 +123,8 @@ fn expand<'cx>(&self,
                           self.name,
                           self.imported_from,
                           arg,
-                          &self.lhses[],
-                          &self.rhses[])
+                          &self.lhses,
+                          &self.rhses)
     }
 }
 
@@ -151,7 +151,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
         match **lhs {
           MatchedNonterminal(NtTT(ref lhs_tt)) => {
             let lhs_tt = match **lhs_tt {
-                TtDelimited(_, ref delim) => &delim.tts[],
+                TtDelimited(_, ref delim) => &delim.tts[..],
                 _ => cx.span_fatal(sp, "malformed macro lhs")
             };
             // `None` is because we're not interpolating
@@ -159,7 +159,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                                                       None,
                                                       None,
                                                       arg.iter()
-                                                         .map(|x| (*x).clone())
+                                                         .cloned()
                                                          .collect(),
                                                       true);
             match parse(cx.parse_sess(), cx.cfg(), arg_rdr, lhs_tt) {
@@ -192,13 +192,13 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                 best_fail_spot = sp;
                 best_fail_msg = (*msg).clone();
               },
-              Error(sp, ref msg) => cx.span_fatal(sp, &msg[])
+              Error(sp, ref msg) => cx.span_fatal(sp, &msg[..])
             }
           }
           _ => cx.bug("non-matcher found in parsed lhses")
         }
     }
-    cx.span_fatal(best_fail_spot, &best_fail_msg[]);
+    cx.span_fatal(best_fail_spot, &best_fail_msg[..]);
 }
 
 // Note that macro-by-example's input is also matched against a token tree:
index 83234e3b7a5d8468b55ff442a74c6df9f3e92cfe..0d92bd761b418e28e4ecd2d17817a983245a660e 100644 (file)
@@ -255,7 +255,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
                     }
                     LisContradiction(ref msg) => {
                         // FIXME #2887 blame macro invoker instead
-                        r.sp_diag.span_fatal(sp.clone(), &msg[]);
+                        r.sp_diag.span_fatal(sp.clone(), &msg[..]);
                     }
                     LisConstraint(len, _) => {
                         if len == 0 {
@@ -309,7 +309,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
                                 r.sp_diag.span_fatal(
                                     r.cur_span, /* blame the macro writer */
                                     &format!("variable '{:?}' is still repeating at this depth",
-                                            token::get_ident(ident))[]);
+                                            token::get_ident(ident)));
                             }
                         }
                     }
index 0110823ae98c1df2ffa9fc69437d55e09d7cd88d..071158fcebb5cf32da776b2e98394450dbf47108 100644 (file)
@@ -356,7 +356,7 @@ pub fn emit_feature_err(diag: &SpanHandler, feature: &str, span: Span, explain:
     diag.span_err(span, explain);
     diag.span_help(span, &format!("add #![feature({})] to the \
                                    crate attributes to enable",
-                                  feature)[]);
+                                  feature));
 }
 
 pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain: &str) {
@@ -364,7 +364,7 @@ pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain:
     if diag.handler.can_emit_warnings {
         diag.span_help(span, &format!("add #![feature({})] to the \
                                        crate attributes to silence this warning",
-                                      feature)[]);
+                                      feature));
     }
 }
 
@@ -438,7 +438,7 @@ fn visit_name(&mut self, sp: Span, name: ast::Name) {
     fn visit_item(&mut self, i: &ast::Item) {
         match i.node {
             ast::ItemExternCrate(_) => {
-                if attr::contains_name(&i.attrs[], "macro_reexport") {
+                if attr::contains_name(&i.attrs[..], "macro_reexport") {
                     self.gate_feature("macro_reexport", i.span,
                                       "macros reexports are experimental \
                                        and possibly buggy");
@@ -446,7 +446,7 @@ fn visit_item(&mut self, i: &ast::Item) {
             }
 
             ast::ItemForeignMod(ref foreign_module) => {
-                if attr::contains_name(&i.attrs[], "link_args") {
+                if attr::contains_name(&i.attrs[..], "link_args") {
                     self.gate_feature("link_args", i.span,
                                       "the `link_args` attribute is not portable \
                                        across platforms, it is recommended to \
@@ -460,17 +460,17 @@ fn visit_item(&mut self, i: &ast::Item) {
             }
 
             ast::ItemFn(..) => {
-                if attr::contains_name(&i.attrs[], "plugin_registrar") {
+                if attr::contains_name(&i.attrs[..], "plugin_registrar") {
                     self.gate_feature("plugin_registrar", i.span,
                                       "compiler plugins are experimental and possibly buggy");
                 }
-                if attr::contains_name(&i.attrs[], "start") {
+                if attr::contains_name(&i.attrs[..], "start") {
                     self.gate_feature("start", i.span,
                                       "a #[start] function is an experimental \
                                        feature whose signature may change \
                                        over time");
                 }
-                if attr::contains_name(&i.attrs[], "main") {
+                if attr::contains_name(&i.attrs[..], "main") {
                     self.gate_feature("main", i.span,
                                       "declaration of a nonstandard #[main] \
                                        function may change over time, for now \
@@ -479,7 +479,7 @@ fn visit_item(&mut self, i: &ast::Item) {
             }
 
             ast::ItemStruct(..) => {
-                if attr::contains_name(&i.attrs[], "simd") {
+                if attr::contains_name(&i.attrs[..], "simd") {
                     self.gate_feature("simd", i.span,
                                       "SIMD types are experimental and possibly buggy");
                 }
@@ -505,7 +505,7 @@ fn visit_item(&mut self, i: &ast::Item) {
                                        removed in the future");
                 }
 
-                if attr::contains_name(&i.attrs[],
+                if attr::contains_name(&i.attrs[..],
                                        "old_orphan_check") {
                     self.gate_feature(
                         "old_orphan_check",
@@ -513,7 +513,7 @@ fn visit_item(&mut self, i: &ast::Item) {
                         "the new orphan check rules will eventually be strictly enforced");
                 }
 
-                if attr::contains_name(&i.attrs[],
+                if attr::contains_name(&i.attrs[..],
                                        "old_impl_check") {
                     self.gate_feature("old_impl_check",
                                       i.span,
@@ -528,7 +528,7 @@ fn visit_item(&mut self, i: &ast::Item) {
     }
 
     fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
-        if attr::contains_name(&i.attrs[], "linkage") {
+        if attr::contains_name(&i.attrs, "linkage") {
             self.gate_feature("linkage", i.span,
                               "the `linkage` attribute is experimental \
                                and not portable across platforms")
index e8bdcd62b588bbc3672a8435bf49353842829053..3a7fa54edbdd772ab633557e8962b8041340846a 100644 (file)
@@ -28,7 +28,6 @@
 #![feature(collections)]
 #![feature(core)]
 #![feature(env)]
-#![feature(hash)]
 #![feature(int_uint)]
 #![feature(old_io)]
 #![feature(libc)]
index 0f9a56baa170bc43b4d646f92241d35720cd067c..f5201d4a8bc68f73ea9f46c07e6bca61330a561e 100644 (file)
@@ -10,7 +10,7 @@
 
 use std::default::Default;
 use std::fmt;
-use std::iter::FromIterator;
+use std::iter::{IntoIterator, FromIterator};
 use std::ops::Deref;
 use std::vec;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
@@ -77,8 +77,8 @@ fn clone(&self) -> OwnedSlice<T> {
 }
 
 impl<T> FromIterator<T> for OwnedSlice<T> {
-    fn from_iter<I: Iterator<Item=T>>(iter: I) -> OwnedSlice<T> {
-        OwnedSlice::from_vec(iter.collect())
+    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> OwnedSlice<T> {
+        OwnedSlice::from_vec(iter.into_iter().collect())
     }
 }
 
index b17fc7fe82e6c66b09da7c36c0b9cd80b239fb34..1f06db600278b4162c807fcc83d8f36bae593d2d 100644 (file)
@@ -61,7 +61,7 @@ pub fn doc_comment_style(comment: &str) -> ast::AttrStyle {
 
 pub fn strip_doc_comment_decoration(comment: &str) -> String {
     /// remove whitespace-only lines from the start/end of lines
-    fn vertical_trim(lines: Vec<String> ) -> Vec<String> {
+    fn vertical_trim(lines: Vec<String>) -> Vec<String> {
         let mut i = 0;
         let mut j = lines.len();
         // first line of all-stars should be omitted
@@ -82,7 +82,7 @@ fn vertical_trim(lines: Vec<String> ) -> Vec<String> {
         while j > i && lines[j - 1].trim().is_empty() {
             j -= 1;
         }
-        return lines[i..j].iter().map(|x| (*x).clone()).collect();
+        lines[i..j].iter().cloned().collect()
     }
 
     /// remove a "[ \t]*\*" block from each line, if possible
@@ -187,7 +187,7 @@ fn read_line_comments(rdr: &mut StringReader, code_to_the_left: bool,
         let line = rdr.read_one_line_comment();
         debug!("{}", line);
         // Doc comments are not put in comments.
-        if is_doc_comment(&line[]) {
+        if is_doc_comment(&line[..]) {
             break;
         }
         lines.push(line);
@@ -224,7 +224,7 @@ fn all_whitespace(s: &str, col: CharPos) -> Option<usize> {
 fn trim_whitespace_prefix_and_push_line(lines: &mut Vec<String> ,
                                         s: String, col: CharPos) {
     let len = s.len();
-    let s1 = match all_whitespace(&s[], col) {
+    let s1 = match all_whitespace(&s[..], col) {
         Some(col) => {
             if col < len {
                 (&s[col..len]).to_string()
@@ -261,7 +261,7 @@ fn read_block_comment(rdr: &mut StringReader,
             rdr.bump();
             rdr.bump();
         }
-        if is_block_doc_comment(&curr_line[]) {
+        if is_block_doc_comment(&curr_line[..]) {
             return
         }
         assert!(!curr_line.contains_char('\n'));
index 38ba0b38df5a7a6f8c51a8aa3859b6a7da56ccfa..fd08cbd161bfe3db302137e480539c2b3de8d6ff 100644 (file)
 use parse::token;
 use parse::token::{str_to_ident};
 
-use std::borrow::IntoCow;
+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;
-use std::string::CowString;
 
 pub use ext::tt::transcribe::{TtReader, new_tt_reader, new_tt_reader_with_doc_flag};
 
@@ -196,7 +195,7 @@ fn fatal_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char)
         let mut m = m.to_string();
         m.push_str(": ");
         for c in c.escape_default() { m.push(c) }
-        self.fatal_span_(from_pos, to_pos, &m[]);
+        self.fatal_span_(from_pos, to_pos, &m[..]);
     }
 
     /// Report a lexical error spanning [`from_pos`, `to_pos`), appending an
@@ -205,7 +204,7 @@ fn err_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) {
         let mut m = m.to_string();
         m.push_str(": ");
         for c in c.escape_default() { m.push(c) }
-        self.err_span_(from_pos, to_pos, &m[]);
+        self.err_span_(from_pos, to_pos, &m[..]);
     }
 
     /// Report a lexical error spanning [`from_pos`, `to_pos`), appending the
@@ -215,7 +214,7 @@ fn fatal_span_verbose(&self, from_pos: BytePos, to_pos: BytePos, mut m: String)
         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]);
-        self.fatal_span_(from_pos, to_pos, &m[]);
+        self.fatal_span_(from_pos, to_pos, &m[..]);
     }
 
     /// Advance peek_tok and peek_span to refer to the next token, and
@@ -278,7 +277,7 @@ fn with_str_from_to<T, F>(&self, start: BytePos, end: BytePos, f: F) -> T where
 
     /// Converts CRLF to LF in the given string, raising an error on bare CR.
     fn translate_crlf<'b>(&self, start: BytePos,
-                          s: &'b str, errmsg: &'b str) -> CowString<'b> {
+                          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);
@@ -556,7 +555,7 @@ fn scan_block_comment(&mut self) -> Option<TokenAndSpan> {
                     self.translate_crlf(start_bpos, string,
                                         "bare CR not allowed in block doc-comment")
                 } else { string.into_cow() };
-                token::DocComment(token::intern(&string[]))
+                token::DocComment(token::intern(&string[..]))
             } else {
                 token::Comment
             };
index 6ea23cf3f04a5791410a1cc54fdcfa8dd90c84ce..7ed48bdbb928dc9ace647ea772f902f3c1228e96 100644 (file)
@@ -258,7 +258,7 @@ pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
             unreachable!()
         }
     };
-    match str::from_utf8(&bytes[]).ok() {
+    match str::from_utf8(&bytes[..]).ok() {
         Some(s) => {
             return string_to_filemap(sess, s.to_string(),
                                      path.as_str().unwrap().to_string())
@@ -398,7 +398,7 @@ pub fn char_lit(lit: &str) -> (char, isize) {
     }
 
     let msg = format!("lexer should have rejected a bad character escape {}", lit);
-    let msg2 = &msg[];
+    let msg2 = &msg[..];
 
     fn esc(len: usize, lit: &str) -> Option<(char, isize)> {
         num::from_str_radix(&lit[2..len], 16).ok()
@@ -662,7 +662,7 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) ->
     // s can only be ascii, byte indexing is fine
 
     let s2 = s.chars().filter(|&c| c != '_').collect::<String>();
-    let mut s = &s2[];
+    let mut s = &s2[..];
 
     debug!("integer_lit: {}, {:?}", s, suffix);
 
@@ -819,7 +819,7 @@ fn sp(a: u32, b: u32) -> Span {
     #[test]
     fn string_to_tts_macro () {
         let tts = string_to_tts("macro_rules! zip (($a)=>($a))".to_string());
-        let tts: &[ast::TokenTree] = &tts[];
+        let tts: &[ast::TokenTree] = &tts[..];
         match tts {
             [ast::TtToken(_, token::Ident(name_macro_rules, token::Plain)),
              ast::TtToken(_, token::Not),
@@ -1114,24 +1114,24 @@ fn parser_done(p: Parser){
         let use_s = "use foo::bar::baz;";
         let vitem = string_to_item(use_s.to_string()).unwrap();
         let vitem_s = item_to_string(&*vitem);
-        assert_eq!(&vitem_s[], use_s);
+        assert_eq!(&vitem_s[..], use_s);
 
         let use_s = "use foo::bar as baz;";
         let vitem = string_to_item(use_s.to_string()).unwrap();
         let vitem_s = item_to_string(&*vitem);
-        assert_eq!(&vitem_s[], use_s);
+        assert_eq!(&vitem_s[..], use_s);
     }
 
     #[test] fn parse_extern_crate() {
         let ex_s = "extern crate foo;";
         let vitem = string_to_item(ex_s.to_string()).unwrap();
         let vitem_s = item_to_string(&*vitem);
-        assert_eq!(&vitem_s[], ex_s);
+        assert_eq!(&vitem_s[..], ex_s);
 
         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);
+        assert_eq!(&vitem_s[..], ex_s);
     }
 
     fn get_spans_of_pat_idents(src: &str) -> Vec<Span> {
@@ -1203,19 +1203,19 @@ fn wb() -> c_int { O_WRONLY as c_int }
         let source = "/// doc comment\r\nfn foo() {}".to_string();
         let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess).unwrap();
         let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
-        assert_eq!(&doc[], "/// doc comment");
+        assert_eq!(&doc[..], "/// doc comment");
 
         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")
                     .map(|a| a.value_str().unwrap().to_string()).collect::<Vec<_>>();
         let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()];
-        assert_eq!(&docs[], b);
+        assert_eq!(&docs[..], b);
 
         let source = "/** doc comment\r\n *  with CRLF */\r\nfn foo() {}".to_string();
         let item = parse_item_from_source_str(name, source, Vec::new(), &sess).unwrap();
         let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
-        assert_eq!(&doc[], "/** doc comment\n *  with CRLF */");
+        assert_eq!(&doc[..], "/** doc comment\n *  with CRLF */");
     }
 
     #[test]
@@ -1235,7 +1235,7 @@ fn ttdelim_span() {
         let span = tts.iter().rev().next().unwrap().get_span();
 
         match sess.span_diagnostic.cm.span_to_snippet(span) {
-            Ok(s) => assert_eq!(&s[], "{ body }"),
+            Ok(s) => assert_eq!(&s[..], "{ body }"),
             Err(_) => panic!("could not get snippet"),
         }
     }
index 1df2e762ee748de0177a9778f3caef2f2c64fd52..8480772ce6c1ad1b7c1528031800a9bafb06327f 100644 (file)
@@ -28,6 +28,7 @@ pub enum ObsoleteSyntax {
     ProcExpr,
     ClosureType,
     ClosureKind,
+    EmptyIndex,
 }
 
 pub trait ParserObsoleteMethods {
@@ -40,7 +41,8 @@ fn report(&mut self,
               sp: Span,
               kind: ObsoleteSyntax,
               kind_str: &str,
-              desc: &str);
+              desc: &str,
+              error: bool);
     fn is_obsolete_ident(&mut self, ident: &str) -> bool;
     fn eat_obsolete_ident(&mut self, ident: &str) -> bool;
 }
@@ -48,35 +50,46 @@ fn report(&mut self,
 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) = match kind {
+        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"
+                "use unboxed closures instead, no type annotation needed",
+                true,
             ),
             ObsoleteSyntax::ClosureKind => (
                 "`:`, `&mut:`, or `&:`",
-                "rely on inference instead"
+                "rely on inference instead",
+                true,
             ),
             ObsoleteSyntax::Sized => (
                 "`Sized? T` for removing the `Sized` bound",
-                "write `T: ?Sized` instead"
+                "write `T: ?Sized` instead",
+                true,
+            ),
+            ObsoleteSyntax::EmptyIndex => (
+                "[]",
+                "write `[..]` instead",
+                false, // warning for now
             ),
         };
 
-        self.report(sp, kind, kind_str, desc);
+        self.report(sp, kind, kind_str, desc, error);
     }
 
     /// Reports an obsolete syntax non-fatal error, and returns
@@ -90,9 +103,13 @@ fn report(&mut self,
               sp: Span,
               kind: ObsoleteSyntax,
               kind_str: &str,
-              desc: &str) {
-        self.span_err(sp,
-                      &format!("obsolete syntax: {}", kind_str)[]);
+              desc: &str,
+              error: bool) {
+        if error {
+            self.span_err(sp, &format!("obsolete syntax: {}", kind_str)[]);
+        } else {
+            self.span_warn(sp, &format!("obsolete syntax: {}", kind_str)[]);
+        }
 
         if !self.obsolete_set.contains(&kind) {
             self.sess
index 407740e580d2e30eff0e5d720d78dfc7490ee62a..370201e53825efef69f01d9c7313127f3a436cef 100644 (file)
@@ -240,9 +240,8 @@ macro_rules! maybe_whole {
 
 fn maybe_append(mut lhs: Vec<Attribute>, rhs: Option<Vec<Attribute>>)
                 -> Vec<Attribute> {
-    match rhs {
-        Some(ref attrs) => lhs.extend(attrs.iter().map(|a| a.clone())),
-        None => {}
+    if let Some(ref attrs) = rhs {
+        lhs.extend(attrs.iter().cloned())
     }
     lhs
 }
@@ -362,7 +361,7 @@ pub fn unexpected_last(&self, t: &token::Token) -> ! {
         let token_str = Parser::token_to_string(t);
         let last_span = self.last_span;
         self.span_fatal(last_span, &format!("unexpected token: `{}`",
-                                                token_str)[]);
+                                                token_str));
     }
 
     pub fn unexpected(&mut self) -> ! {
@@ -381,7 +380,7 @@ pub fn expect(&mut self, t: &token::Token) {
                 let this_token_str = self.this_token_to_string();
                 self.fatal(&format!("expected `{}`, found `{}`",
                                    token_str,
-                                   this_token_str)[])
+                                   this_token_str))
             }
         } else {
             self.expect_one_of(slice::ref_slice(t), &[]);
@@ -422,7 +421,7 @@ fn tokens_to_string(tokens: &[TokenType]) -> String {
             expected.push_all(&*self.expected_tokens);
             expected.sort_by(|a, b| a.to_string().cmp(&b.to_string()));
             expected.dedup();
-            let expect = tokens_to_string(&expected[]);
+            let expect = tokens_to_string(&expected[..]);
             let actual = self.this_token_to_string();
             self.fatal(
                 &(if expected.len() > 1 {
@@ -436,7 +435,7 @@ fn tokens_to_string(tokens: &[TokenType]) -> String {
                     (format!("expected {}, found `{}`",
                              expect,
                              actual))
-                }[])
+                })[..]
             )
         }
     }
@@ -467,9 +466,9 @@ pub fn commit_expr(&mut self, e: &Expr, edible: &[token::Token], inedible: &[tok
         debug!("commit_expr {:?}", e);
         if let ExprPath(..) = e.node {
             // might be unit-struct construction; check for recoverableinput error.
-            let mut expected = edible.iter().map(|x| x.clone()).collect::<Vec<_>>();
+            let mut expected = edible.iter().cloned().collect::<Vec<_>>();
             expected.push_all(inedible);
-            self.check_for_erroneous_unit_struct_expecting(&expected[]);
+            self.check_for_erroneous_unit_struct_expecting(&expected[..]);
         }
         self.expect_one_of(edible, inedible)
     }
@@ -485,10 +484,9 @@ pub fn commit_stmt(&mut self, edible: &[token::Token], inedible: &[token::Token]
         if self.last_token
                .as_ref()
                .map_or(false, |t| t.is_ident() || t.is_path()) {
-            let mut expected = edible.iter().map(|x| x.clone()).collect::<Vec<_>>();
-            expected.push_all(&inedible[]);
-            self.check_for_erroneous_unit_struct_expecting(
-                &expected[]);
+            let mut expected = edible.iter().cloned().collect::<Vec<_>>();
+            expected.push_all(&inedible);
+            self.check_for_erroneous_unit_struct_expecting(&expected);
         }
         self.expect_one_of(edible, inedible)
     }
@@ -511,7 +509,7 @@ pub fn parse_ident(&mut self) -> ast::Ident {
             _ => {
                 let token_str = self.this_token_to_string();
                 self.fatal(&format!("expected ident, found `{}`",
-                                    token_str)[])
+                                    token_str))
             }
         }
     }
@@ -599,7 +597,7 @@ pub fn check_strict_keywords(&mut self) {
             let span = self.span;
             self.span_err(span,
                           &format!("expected identifier, found keyword `{}`",
-                                  token_str)[]);
+                                  token_str));
         }
     }
 
@@ -608,7 +606,7 @@ pub fn check_reserved_keywords(&mut self) {
         if self.token.is_reserved_keyword() {
             let token_str = self.this_token_to_string();
             self.fatal(&format!("`{}` is a reserved keyword",
-                               token_str)[])
+                               token_str))
         }
     }
 
@@ -734,7 +732,7 @@ pub fn expect_gt(&mut self) {
                 let this_token_str = self.this_token_to_string();
                 self.fatal(&format!("expected `{}`, found `{}`",
                                    gt_str,
-                                   this_token_str)[])
+                                   this_token_str))
             }
         }
     }
@@ -1364,7 +1362,7 @@ pub fn parse_trait_items(&mut self) -> Vec<TraitItem> {
                     let (inner_attrs, body) =
                         p.parse_inner_attrs_and_block();
                     let mut attrs = attrs;
-                    attrs.push_all(&inner_attrs[]);
+                    attrs.push_all(&inner_attrs[..]);
                     ProvidedMethod(P(ast::Method {
                         attrs: attrs,
                         id: ast::DUMMY_NODE_ID,
@@ -1383,7 +1381,7 @@ pub fn parse_trait_items(&mut self) -> Vec<TraitItem> {
                   _ => {
                       let token_str = p.this_token_to_string();
                       p.fatal(&format!("expected `;` or `{{`, found `{}`",
-                                       token_str)[])
+                                       token_str)[..])
                   }
                 }
             }
@@ -1551,7 +1549,7 @@ pub fn parse_ty(&mut self) -> P<Ty> {
         } else {
             let this_token_str = self.this_token_to_string();
             let msg = format!("expected type, found `{}`", this_token_str);
-            self.fatal(&msg[]);
+            self.fatal(&msg[..]);
         };
 
         let sp = mk_sp(lo, self.last_span.hi);
@@ -1699,14 +1697,14 @@ pub fn lit_from_token(&self, tok: &token::Token) -> Lit_ {
                     token::StrRaw(s, n) => {
                         (true,
                          LitStr(
-                            token::intern_and_get_ident(&parse::raw_str_lit(s.as_str())[]),
+                            token::intern_and_get_ident(&parse::raw_str_lit(s.as_str())),
                             ast::RawStr(n)))
                     }
                     token::Binary(i) =>
                         (true, LitBinary(parse::binary_lit(i.as_str()))),
                     token::BinaryRaw(i, _) =>
                         (true,
-                         LitBinary(Rc::new(i.as_str().as_bytes().iter().map(|&x| x).collect()))),
+                         LitBinary(Rc::new(i.as_str().as_bytes().iter().cloned().collect()))),
                 };
 
                 if suffix_illegal {
@@ -1944,7 +1942,7 @@ pub fn parse_lifetime(&mut self) -> ast::Lifetime {
                 };
             }
             _ => {
-                self.fatal(&format!("expected a lifetime name")[]);
+                self.fatal(&format!("expected a lifetime name"));
             }
         }
     }
@@ -1982,7 +1980,7 @@ pub fn parse_lifetime_defs(&mut self) -> Vec<ast::LifetimeDef> {
                     let msg = format!("expected `,` or `>` after lifetime \
                                       name, found `{}`",
                                       this_token_str);
-                    self.fatal(&msg[]);
+                    self.fatal(&msg[..]);
                 }
             }
         }
@@ -2497,7 +2495,7 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
                     let last_span = self.last_span;
                     let fstr = n.as_str();
                     self.span_err(last_span,
-                                  &format!("unexpected token: `{}`", n.as_str())[]);
+                                  &format!("unexpected token: `{}`", n.as_str()));
                     if fstr.chars().all(|x| "0123456789.".contains_char(x)) {
                         let float = match fstr.parse::<f64>().ok() {
                             Some(f) => f,
@@ -2506,7 +2504,7 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
                         self.span_help(last_span,
                             &format!("try parenthesizing the first index; e.g., `(foo.{}){}`",
                                     float.trunc() as usize,
-                                    &float.fract().to_string()[1..])[]);
+                                    &float.fract().to_string()[1..]));
                     }
                     self.abort_if_errors();
 
@@ -2552,8 +2550,9 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
                             parameters: ast::PathParameters::none(),
                         }
                     }).collect();
+                    let span = mk_sp(lo, hi);
                     let path = ast::Path {
-                        span: mk_sp(lo, hi),
+                        span: span,
                         global: true,
                         segments: segments,
                     };
@@ -2562,10 +2561,8 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: P<Expr>) -> P<Expr> {
                     let ix = self.mk_expr(bracket_pos, hi, range);
                     let index = self.mk_index(e, ix);
                     e = self.mk_expr(lo, hi, index);
-                    // Enable after snapshot.
-                    // self.span_warn(e.span, "deprecated slicing syntax: `[]`");
-                    // self.span_note(e.span,
-                    //               "use `&expr[..]` to construct a slice of the whole of expr");
+
+                    self.obsolete(span, ObsoleteSyntax::EmptyIndex);
                 } else {
                     let ix = self.parse_expr();
                     hi = self.span.hi;
@@ -2639,7 +2636,7 @@ pub fn check_unknown_macro_variable(&mut self) {
             match self.token {
                 token::SubstNt(name, _) =>
                     self.fatal(&format!("unknown macro variable `{}`",
-                                       token::get_ident(name))[]),
+                                       token::get_ident(name))),
                 _ => {}
             }
         }
@@ -2701,7 +2698,7 @@ fn parse_non_delim_tt_tok(p: &mut Parser) -> TokenTree {
                     };
                     let token_str = p.this_token_to_string();
                     p.fatal(&format!("incorrect close delimiter: `{}`",
-                                    token_str)[])
+                                    token_str))
                 },
                 /* we ought to allow different depths of unquotation */
                 token::Dollar | token::SubstNt(..) if p.quote_depth > 0 => {
@@ -2822,7 +2819,7 @@ pub fn parse_prefix_expr(&mut self) -> P<Expr> {
                         let this_token_to_string = self.this_token_to_string();
                         self.span_err(span,
                                       &format!("expected expression, found `{}`",
-                                              this_token_to_string)[]);
+                                              this_token_to_string));
                         let box_span = mk_sp(lo, self.last_span.hi);
                         self.span_help(box_span,
                                        "perhaps you meant `box() (foo)` instead?");
@@ -3275,7 +3272,7 @@ fn parse_pat_fields(&mut self) -> (Vec<codemap::Spanned<ast::FieldPat>> , bool)
                 if self.token != token::CloseDelim(token::Brace) {
                     let token_str = self.this_token_to_string();
                     self.fatal(&format!("expected `{}`, found `{}`", "}",
-                                       token_str)[])
+                                       token_str))
                 }
                 etc = true;
                 break;
@@ -3576,7 +3573,7 @@ fn parse_pat_ident(&mut self,
             let span = self.span;
             let tok_str = self.this_token_to_string();
             self.span_fatal(span,
-                            &format!("expected identifier, found `{}`", tok_str)[]);
+                            &format!("expected identifier, found `{}`", tok_str));
         }
         let ident = self.parse_ident();
         let last_span = self.last_span;
@@ -3673,7 +3670,7 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
 
         let lo = self.span.lo;
         if self.check_keyword(keywords::Let) {
-            check_expected_item(self, &item_attrs[]);
+            check_expected_item(self, &item_attrs[..]);
             self.expect_keyword(keywords::Let);
             let decl = self.parse_let();
             P(spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
@@ -3682,7 +3679,7 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
             && self.look_ahead(1, |t| *t == token::Not) {
             // it's a macro invocation:
 
-            check_expected_item(self, &item_attrs[]);
+            check_expected_item(self, &item_attrs[..]);
 
             // Potential trouble: if we allow macros with paths instead of
             // idents, we'd need to look ahead past the whole path here...
@@ -3710,7 +3707,7 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
                     let tok_str = self.this_token_to_string();
                     self.fatal(&format!("expected {}`(` or `{{`, found `{}`",
                                        ident_str,
-                                       tok_str)[])
+                                       tok_str))
                 },
             };
 
@@ -3758,7 +3755,7 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
             }
         } else {
             let found_attrs = !item_attrs.is_empty();
-            let item_err = Parser::expected_item_err(&item_attrs[]);
+            let item_err = Parser::expected_item_err(&item_attrs[..]);
             match self.parse_item_(item_attrs, false) {
                 Ok(i) => {
                     let hi = i.span.hi;
@@ -3795,7 +3792,7 @@ pub fn parse_block(&mut self) -> P<Block> {
             let sp = self.span;
             let tok = self.this_token_to_string();
             self.span_fatal_help(sp,
-                                 &format!("expected `{{`, found `{}`", tok)[],
+                                 &format!("expected `{{`, found `{}`", tok),
                                  "place this code inside a block");
         }
 
@@ -3830,13 +3827,13 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
         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()[]);
+            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[]));
+                                      Parser::expected_item_err(&attributes_box[..]));
                         attributes_box = Vec::new();
                     }
                     self.bump(); // empty
@@ -3928,7 +3925,7 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
         if !attributes_box.is_empty() {
             let last_span = self.last_span;
             self.span_err(last_span,
-                          Parser::expected_item_err(&attributes_box[]));
+                          Parser::expected_item_err(&attributes_box[..]));
         }
 
         let hi = self.span.hi;
@@ -4383,7 +4380,7 @@ fn expect_self_ident(&mut self) -> ast::Ident {
             _ => {
                 let token_str = self.this_token_to_string();
                 self.fatal(&format!("expected `self`, found `{}`",
-                                   token_str)[])
+                                   token_str))
             }
         }
     }
@@ -4404,7 +4401,7 @@ fn expect_self_type_ident(&mut self) -> ast::Ident {
             _ => {
                 let token_str = self.this_token_to_string();
                 self.fatal(&format!("expected `Self`, found `{}`",
-                                   token_str)[])
+                                   token_str))
             }
         }
     }
@@ -4539,7 +4536,7 @@ macro_rules! parse_remaining_arguments {
                 _ => {
                     let token_str = self.this_token_to_string();
                     self.fatal(&format!("expected `,` or `)`, found `{}`",
-                                       token_str)[])
+                                       token_str))
                 }
             }
             }
@@ -4712,7 +4709,7 @@ pub fn parse_method(&mut self,
                 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[]);
+                new_attrs.push_all(&inner_attrs[..]);
                 (ast::MethDecl(ident,
                                generics,
                                abi,
@@ -4942,7 +4939,7 @@ pub fn parse_record_struct_body(&mut self, class_name: &ast::Ident) -> Vec<Struc
             if fields.len() == 0 {
                 self.fatal(&format!("unit-like struct definition should be \
                     written as `struct {};`",
-                    token::get_ident(class_name.clone()))[]);
+                    token::get_ident(class_name.clone())));
             }
 
             self.bump();
@@ -4950,7 +4947,7 @@ pub fn parse_record_struct_body(&mut self, class_name: &ast::Ident) -> Vec<Struc
             let token_str = self.this_token_to_string();
             self.fatal(&format!("expected `where`, or `{}` after struct \
                                 name, found `{}`", "{",
-                                token_str)[]);
+                                token_str));
         }
 
         fields
@@ -4981,7 +4978,7 @@ pub fn parse_tuple_struct_body(&mut self,
             if fields.len() == 0 {
                 self.fatal(&format!("unit-like struct definition should be \
                     written as `struct {};`",
-                    token::get_ident(class_name.clone()))[]);
+                    token::get_ident(class_name.clone())));
             }
 
             self.parse_where_clause(generics);
@@ -4996,7 +4993,7 @@ pub fn parse_tuple_struct_body(&mut self,
         } else {
             let token_str = self.this_token_to_string();
             self.fatal(&format!("expected `where`, `{}`, `(`, or `;` after struct \
-                name, found `{}`", "{", token_str)[]);
+                name, found `{}`", "{", token_str));
         }
     }
 
@@ -5016,7 +5013,7 @@ pub fn parse_single_struct_field(&mut self,
                 let token_str = self.this_token_to_string();
                 self.span_fatal_help(span,
                                      &format!("expected `,`, or `}}`, found `{}`",
-                                             token_str)[],
+                                             token_str),
                                      "struct fields should be separated by commas")
             }
         }
@@ -5088,7 +5085,7 @@ fn parse_mod_items(&mut self,
         // Parse all of the items up to closing or an attribute.
 
         let mut attrs = first_item_attrs;
-        attrs.push_all(&self.parse_outer_attributes()[]);
+        attrs.push_all(&self.parse_outer_attributes());
         let mut items = vec![];
 
         loop {
@@ -5108,14 +5105,14 @@ fn parse_mod_items(&mut self,
 
         while self.token != term {
             let mut attrs = mem::replace(&mut attrs, vec![]);
-            attrs.push_all(&self.parse_outer_attributes()[]);
+            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)[])
+                                     token_str))
               }
             }
         }
@@ -5124,7 +5121,7 @@ fn parse_mod_items(&mut self,
             // 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[]));
+                          Parser::expected_item_err(&attrs[..]));
         }
 
         ast::Mod {
@@ -5203,8 +5200,8 @@ fn eval_src_mod(&mut self,
                 let mod_name = mod_string.to_string();
                 let default_path_str = format!("{}.rs", mod_name);
                 let secondary_path_str = format!("{}/mod.rs", mod_name);
-                let default_path = dir_path.join(&default_path_str[]);
-                let secondary_path = dir_path.join(&secondary_path_str[]);
+                let default_path = dir_path.join(&default_path_str[..]);
+                let secondary_path = dir_path.join(&secondary_path_str[..]);
                 let default_exists = default_path.exists();
                 let secondary_exists = secondary_path.exists();
 
@@ -5219,13 +5216,13 @@ fn eval_src_mod(&mut self,
                                    &format!("maybe move this module `{0}` \
                                             to its own directory via \
                                             `{0}/mod.rs`",
-                                           this_module)[]);
+                                           this_module));
                     if default_exists || secondary_exists {
                         self.span_note(id_sp,
                                        &format!("... or maybe `use` the module \
                                                 `{}` instead of possibly \
                                                 redeclaring it",
-                                               mod_name)[]);
+                                               mod_name));
                     }
                     self.abort_if_errors();
                 }
@@ -5236,12 +5233,12 @@ fn eval_src_mod(&mut self,
                     (false, false) => {
                         self.span_fatal_help(id_sp,
                                              &format!("file not found for module `{}`",
-                                                     mod_name)[],
+                                                     mod_name),
                                              &format!("name the file either {} or {} inside \
                                                      the directory {:?}",
                                                      default_path_str,
                                                      secondary_path_str,
-                                                     dir_path.display())[]);
+                                                     dir_path.display()));
                     }
                     (true, true) => {
                         self.span_fatal_help(
@@ -5250,7 +5247,7 @@ fn eval_src_mod(&mut self,
                                      and {}",
                                     mod_name,
                                     default_path_str,
-                                    secondary_path_str)[],
+                                    secondary_path_str),
                             "delete or rename one of them to remove the ambiguity");
                     }
                 }
@@ -5272,11 +5269,11 @@ fn eval_src_mod_from_path(&mut self,
                 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.display().as_cow());
                     err.push_str(" -> ");
                 }
-                err.push_str(&path.display().as_cow()[]);
-                self.span_fatal(id_sp, &err[]);
+                err.push_str(&path.display().as_cow());
+                self.span_fatal(id_sp, &err[..]);
             }
             None => ()
         }
@@ -5381,7 +5378,7 @@ fn parse_item_extern_crate(&mut self,
                     self.span_help(span,
                                    &format!("perhaps you meant to enclose the crate name `{}` in \
                                            a string?",
-                                          the_ident.as_str())[]);
+                                          the_ident.as_str()));
                     None
                 } else {
                     None
@@ -5407,7 +5404,7 @@ fn parse_item_extern_crate(&mut self,
                 self.span_fatal(span,
                                 &format!("expected extern crate name but \
                                          found `{}`",
-                                        token_str)[]);
+                                        token_str));
             }
         };
 
@@ -5505,7 +5502,7 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> EnumDef {
                     self.span_err(start_span,
                         &format!("unit-like struct variant should be written \
                                  without braces, as `{},`",
-                                token::get_ident(ident))[]);
+                                token::get_ident(ident)));
                 }
                 kind = StructVariantKind(struct_def);
             } else if self.check(&token::OpenDelim(token::Paren)) {
@@ -5583,7 +5580,7 @@ fn parse_opt_abi(&mut self) -> Option<abi::Abi> {
                             &format!("illegal ABI: expected one of [{}], \
                                      found `{}`",
                                     abi::all_names().connect(", "),
-                                    the_string)[]);
+                                    the_string));
                         None
                     }
                 }
@@ -5663,7 +5660,7 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
             let token_str = self.this_token_to_string();
             self.span_fatal(span,
                             &format!("expected `{}` or `fn`, found `{}`", "{",
-                                    token_str)[]);
+                                    token_str));
         }
 
         if self.eat_keyword_noexpect(keywords::Virtual) {
@@ -5772,7 +5769,7 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
         if self.eat_keyword(keywords::Mod) {
             // MODULE ITEM
             let (ident, item_, extra_attrs) =
-                self.parse_item_mod(&attrs[]);
+                self.parse_item_mod(&attrs[..]);
             let last_span = self.last_span;
             let item = self.mk_item(lo,
                                     last_span.hi,
@@ -6057,7 +6054,7 @@ fn parse_view_path(&mut self) -> P<ViewPath> {
     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()[]);
+        attrs.push_all(&self.parse_outer_attributes());
         let mut foreign_items = Vec::new();
         loop {
             match self.parse_foreign_item(attrs) {
@@ -6078,7 +6075,7 @@ fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute>)
         if !attrs.is_empty() {
             let last_span = self.last_span;
             self.span_err(last_span,
-                          Parser::expected_item_err(&attrs[]));
+                          Parser::expected_item_err(&attrs[..]));
         }
 
         foreign_items
index 0747a97fa37cc0312e5e17f6ebc965de4fad7179..433c013591c2d1557b84fcbb3c7a01d69b03d506 100644 (file)
@@ -482,7 +482,7 @@ fn mk_fresh_ident_interner() -> IdentInterner {
         $(init_vec.push($si_str);)*
         $(init_vec.push($sk_str);)*
         $(init_vec.push($rk_str);)*
-        interner::StrInterner::prefill(&init_vec[])
+        interner::StrInterner::prefill(&init_vec[..])
     }
 }}
 
@@ -644,7 +644,7 @@ fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
         // of `BytesContainer`, which is itself a workaround for the lack of
         // DST.
         unsafe {
-            let this = &self[];
+            let this = &self[..];
             mem::transmute::<&[u8],&[u8]>(this.container_as_bytes())
         }
     }
index 6c6cf186e70ae79b10a37529e5c7fd4646c0b080..1593bfb97fe1da755ff08f1697d05c65e85d9eb1 100644 (file)
@@ -539,8 +539,8 @@ pub fn print_str(&mut self, s: &str) -> old_io::IoResult<()> {
     pub fn print(&mut self, token: Token, l: isize) -> old_io::IoResult<()> {
         debug!("print {} {} (remaining line space={})", tok_str(&token), l,
                self.space);
-        debug!("{}", buf_str(&self.token[],
-                             &self.size[],
+        debug!("{}", buf_str(&self.token,
+                             &self.size,
                              self.left,
                              self.right,
                              6));
@@ -607,7 +607,7 @@ pub fn print(&mut self, token: Token, l: isize) -> old_io::IoResult<()> {
             assert_eq!(l, len);
             // assert!(l <= space);
             self.space -= len;
-            self.print_str(&s[])
+            self.print_str(&s[..])
           }
           Token::Eof => {
             // Eof should never get here.
index 4b021f2434f054d8a45ab599a13d67a287ad48ce..f26578e740120d8f33695834534ac2a6c6d15d1d 100644 (file)
@@ -134,7 +134,7 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
         try!(s.print_attribute(&fake_attr));
     }
 
-    try!(s.print_mod(&krate.module, &krate.attrs[]));
+    try!(s.print_mod(&krate.module, &krate.attrs));
     try!(s.print_remaining_comments());
     eof(&mut s.s)
 }
@@ -602,7 +602,7 @@ pub fn break_offset_if_not_bol(&mut self, n: usize,
     pub fn synth_comment(&mut self, text: String) -> IoResult<()> {
         try!(word(&mut self.s, "/*"));
         try!(space(&mut self.s));
-        try!(word(&mut self.s, &text[]));
+        try!(word(&mut self.s, &text[..]));
         try!(space(&mut self.s));
         word(&mut self.s, "*/")
     }
@@ -701,7 +701,7 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
             }
             ast::TyTup(ref elts) => {
                 try!(self.popen());
-                try!(self.commasep(Inconsistent, &elts[],
+                try!(self.commasep(Inconsistent, &elts[..],
                                    |s, ty| s.print_type(&**ty)));
                 if elts.len() == 1 {
                     try!(word(&mut self.s, ","));
@@ -734,10 +734,10 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
             }
             ast::TyObjectSum(ref ty, ref bounds) => {
                 try!(self.print_type(&**ty));
-                try!(self.print_bounds("+", &bounds[]));
+                try!(self.print_bounds("+", &bounds[..]));
             }
             ast::TyPolyTraitRef(ref bounds) => {
-                try!(self.print_bounds("", &bounds[]));
+                try!(self.print_bounds("", &bounds[..]));
             }
             ast::TyQPath(ref qpath) => {
                 try!(self.print_qpath(&**qpath, false))
@@ -765,7 +765,7 @@ pub fn print_foreign_item(&mut self,
                               item: &ast::ForeignItem) -> IoResult<()> {
         try!(self.hardbreak_if_not_bol());
         try!(self.maybe_print_comment(item.span.lo));
-        try!(self.print_outer_attributes(&item.attrs[]));
+        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,
@@ -776,7 +776,7 @@ pub fn print_foreign_item(&mut self,
             }
             ast::ForeignItemStatic(ref t, m) => {
                 try!(self.head(&visibility_qualified(item.vis,
-                                                    "static")[]));
+                                                    "static")));
                 if m {
                     try!(self.word_space("mut"));
                 }
@@ -793,7 +793,7 @@ pub fn print_foreign_item(&mut self,
     fn print_associated_type(&mut self, typedef: &ast::AssociatedType)
                              -> IoResult<()>
     {
-        try!(self.print_outer_attributes(&typedef.attrs[]));
+        try!(self.print_outer_attributes(&typedef.attrs));
         try!(self.word_space("type"));
         try!(self.print_ty_param(&typedef.ty_param));
         word(&mut self.s, ";")
@@ -812,12 +812,12 @@ fn print_typedef(&mut self, typedef: &ast::Typedef) -> IoResult<()> {
     pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
         try!(self.hardbreak_if_not_bol());
         try!(self.maybe_print_comment(item.span.lo));
-        try!(self.print_outer_attributes(&item.attrs[]));
+        try!(self.print_outer_attributes(&item.attrs));
         try!(self.ann.pre(self, NodeItem(item)));
         match item.node {
             ast::ItemExternCrate(ref optional_path) => {
                 try!(self.head(&visibility_qualified(item.vis,
-                                                     "extern crate")[]));
+                                                     "extern crate")));
                 if let Some((ref p, style)) = *optional_path {
                     try!(self.print_string(p, style));
                     try!(space(&mut self.s));
@@ -831,7 +831,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
             }
             ast::ItemUse(ref vp) => {
                 try!(self.head(&visibility_qualified(item.vis,
-                                                     "use")[]));
+                                                     "use")));
                 try!(self.print_view_path(&**vp));
                 try!(word(&mut self.s, ";"));
                 try!(self.end()); // end inner head-block
@@ -839,7 +839,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
             }
             ast::ItemStatic(ref ty, m, ref expr) => {
                 try!(self.head(&visibility_qualified(item.vis,
-                                                    "static")[]));
+                                                    "static")));
                 if m == ast::MutMutable {
                     try!(self.word_space("mut"));
                 }
@@ -856,7 +856,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
             }
             ast::ItemConst(ref ty, ref expr) => {
                 try!(self.head(&visibility_qualified(item.vis,
-                                                    "const")[]));
+                                                    "const")));
                 try!(self.print_ident(item.ident));
                 try!(self.word_space(":"));
                 try!(self.print_type(&**ty));
@@ -879,28 +879,28 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
                     item.vis
                 ));
                 try!(word(&mut self.s, " "));
-                try!(self.print_block_with_attrs(&**body, &item.attrs[]));
+                try!(self.print_block_with_attrs(&**body, &item.attrs));
             }
             ast::ItemMod(ref _mod) => {
                 try!(self.head(&visibility_qualified(item.vis,
-                                                    "mod")[]));
+                                                    "mod")));
                 try!(self.print_ident(item.ident));
                 try!(self.nbsp());
                 try!(self.bopen());
-                try!(self.print_mod(_mod, &item.attrs[]));
+                try!(self.print_mod(_mod, &item.attrs));
                 try!(self.bclose(item.span));
             }
             ast::ItemForeignMod(ref nmod) => {
                 try!(self.head("extern"));
-                try!(self.word_nbsp(&nmod.abi.to_string()[]));
+                try!(self.word_nbsp(&nmod.abi.to_string()));
                 try!(self.bopen());
-                try!(self.print_foreign_mod(nmod, &item.attrs[]));
+                try!(self.print_foreign_mod(nmod, &item.attrs));
                 try!(self.bclose(item.span));
             }
             ast::ItemTy(ref ty, ref params) => {
                 try!(self.ibox(indent_unit));
                 try!(self.ibox(0));
-                try!(self.word_nbsp(&visibility_qualified(item.vis, "type")[]));
+                try!(self.word_nbsp(&visibility_qualified(item.vis, "type")));
                 try!(self.print_ident(item.ident));
                 try!(self.print_generics(params));
                 try!(self.end()); // end the inner ibox
@@ -922,7 +922,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
                 ));
             }
             ast::ItemStruct(ref struct_def, ref generics) => {
-                try!(self.head(&visibility_qualified(item.vis,"struct")[]));
+                try!(self.head(&visibility_qualified(item.vis,"struct")));
                 try!(self.print_struct(&**struct_def, generics, item.ident, item.span));
             }
 
@@ -963,7 +963,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
 
                 try!(space(&mut self.s));
                 try!(self.bopen());
-                try!(self.print_inner_attributes(&item.attrs[]));
+                try!(self.print_inner_attributes(&item.attrs));
                 for impl_item in impl_items {
                     match *impl_item {
                         ast::MethodImplItem(ref meth) => {
@@ -983,18 +983,17 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
                 try!(self.word_nbsp("trait"));
                 try!(self.print_ident(item.ident));
                 try!(self.print_generics(generics));
-                let bounds: Vec<_> = bounds.iter().map(|b| b.clone()).collect();
                 let mut real_bounds = Vec::with_capacity(bounds.len());
-                for b in bounds {
-                    if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = b {
+                for b in bounds.iter() {
+                    if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
                         try!(space(&mut self.s));
                         try!(self.word_space("for ?"));
                         try!(self.print_trait_ref(&ptr.trait_ref));
                     } else {
-                        real_bounds.push(b);
+                        real_bounds.push(b.clone());
                     }
                 }
-                try!(self.print_bounds(":", &real_bounds[]));
+                try!(self.print_bounds(":", &real_bounds[..]));
                 try!(self.print_where_clause(generics));
                 try!(word(&mut self.s, " "));
                 try!(self.bopen());
@@ -1012,7 +1011,7 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
                 try!(self.print_ident(item.ident));
                 try!(self.cbox(indent_unit));
                 try!(self.popen());
-                try!(self.print_tts(&tts[]));
+                try!(self.print_tts(&tts[..]));
                 try!(self.pclose());
                 try!(word(&mut self.s, ";"));
                 try!(self.end());
@@ -1050,12 +1049,12 @@ pub fn print_enum_def(&mut self, enum_definition: &ast::EnumDef,
                           generics: &ast::Generics, ident: ast::Ident,
                           span: codemap::Span,
                           visibility: ast::Visibility) -> IoResult<()> {
-        try!(self.head(&visibility_qualified(visibility, "enum")[]));
+        try!(self.head(&visibility_qualified(visibility, "enum")));
         try!(self.print_ident(ident));
         try!(self.print_generics(generics));
         try!(self.print_where_clause(generics));
         try!(space(&mut self.s));
-        self.print_variants(&enum_definition.variants[], span)
+        self.print_variants(&enum_definition.variants, span)
     }
 
     pub fn print_variants(&mut self,
@@ -1065,7 +1064,7 @@ pub fn print_variants(&mut self,
         for v in variants {
             try!(self.space_if_not_bol());
             try!(self.maybe_print_comment(v.span.lo));
-            try!(self.print_outer_attributes(&v.node.attrs[]));
+            try!(self.print_outer_attributes(&v.node.attrs));
             try!(self.ibox(indent_unit));
             try!(self.print_variant(&**v));
             try!(word(&mut self.s, ","));
@@ -1093,7 +1092,7 @@ pub fn print_struct(&mut self,
             if !struct_def.fields.is_empty() {
                 try!(self.popen());
                 try!(self.commasep(
-                    Inconsistent, &struct_def.fields[],
+                    Inconsistent, &struct_def.fields,
                     |s, field| {
                         match field.node.kind {
                             ast::NamedField(..) => panic!("unexpected named field"),
@@ -1123,7 +1122,7 @@ pub fn print_struct(&mut self,
                     ast::NamedField(ident, visibility) => {
                         try!(self.hardbreak_if_not_bol());
                         try!(self.maybe_print_comment(field.span.lo));
-                        try!(self.print_outer_attributes(&field.node.attrs[]));
+                        try!(self.print_outer_attributes(&field.node.attrs));
                         try!(self.print_visibility(visibility));
                         try!(self.print_ident(ident));
                         try!(self.word_nbsp(":"));
@@ -1147,7 +1146,7 @@ pub fn print_struct(&mut self,
     pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> {
         match *tt {
             ast::TtToken(_, ref tk) => {
-                try!(word(&mut self.s, &token_to_string(tk)[]));
+                try!(word(&mut self.s, &token_to_string(tk)));
                 match *tk {
                     parse::token::DocComment(..) => {
                         hardbreak(&mut self.s)
@@ -1156,11 +1155,11 @@ pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> {
                 }
             }
             ast::TtDelimited(_, ref delimed) => {
-                try!(word(&mut self.s, &token_to_string(&delimed.open_token())[]));
+                try!(word(&mut self.s, &token_to_string(&delimed.open_token())));
                 try!(space(&mut self.s));
-                try!(self.print_tts(&delimed.tts[]));
+                try!(self.print_tts(&delimed.tts));
                 try!(space(&mut self.s));
-                word(&mut self.s, &token_to_string(&delimed.close_token())[])
+                word(&mut self.s, &token_to_string(&delimed.close_token()))
             },
             ast::TtSequence(_, ref seq) => {
                 try!(word(&mut self.s, "$("));
@@ -1170,7 +1169,7 @@ pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> {
                 try!(word(&mut self.s, ")"));
                 match seq.separator {
                     Some(ref tk) => {
-                        try!(word(&mut self.s, &token_to_string(tk)[]));
+                        try!(word(&mut self.s, &token_to_string(tk)));
                     }
                     None => {},
                 }
@@ -1210,7 +1209,7 @@ pub fn print_variant(&mut self, v: &ast::Variant) -> IoResult<()> {
                 if !args.is_empty() {
                     try!(self.popen());
                     try!(self.commasep(Consistent,
-                                       &args[],
+                                       &args[..],
                                        |s, arg| s.print_type(&*arg.ty)));
                     try!(self.pclose());
                 }
@@ -1234,7 +1233,7 @@ pub fn print_variant(&mut self, v: &ast::Variant) -> IoResult<()> {
     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_outer_attributes(&m.attrs));
         try!(self.print_ty_fn(m.abi,
                               m.unsafety,
                               &*m.decl,
@@ -1263,7 +1262,7 @@ pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> IoResult<()> {
     pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> {
         try!(self.hardbreak_if_not_bol());
         try!(self.maybe_print_comment(meth.span.lo));
-        try!(self.print_outer_attributes(&meth.attrs[]));
+        try!(self.print_outer_attributes(&meth.attrs));
         match meth.node {
             ast::MethDecl(ident,
                           ref generics,
@@ -1281,7 +1280,7 @@ pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> {
                                    Some(&explicit_self.node),
                                    vis));
                 try!(word(&mut self.s, " "));
-                self.print_block_with_attrs(&**body, &meth.attrs[])
+                self.print_block_with_attrs(&**body, &meth.attrs)
             },
             ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
                                             ..}) => {
@@ -1290,7 +1289,7 @@ pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> {
                 try!(word(&mut self.s, "! "));
                 try!(self.cbox(indent_unit));
                 try!(self.popen());
-                try!(self.print_tts(&tts[]));
+                try!(self.print_tts(&tts[..]));
                 try!(self.pclose());
                 try!(word(&mut self.s, ";"));
                 self.end()
@@ -1552,7 +1551,7 @@ fn print_expr_box(&mut self,
     fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> {
         try!(self.ibox(indent_unit));
         try!(word(&mut self.s, "["));
-        try!(self.commasep_exprs(Inconsistent, &exprs[]));
+        try!(self.commasep_exprs(Inconsistent, &exprs[..]));
         try!(word(&mut self.s, "]"));
         self.end()
     }
@@ -1578,7 +1577,7 @@ fn print_expr_struct(&mut self,
             try!(word(&mut self.s, "{"));
             try!(self.commasep_cmnt(
                 Consistent,
-                &fields[],
+                &fields[..],
                 |s, field| {
                     try!(s.ibox(indent_unit));
                     try!(s.print_ident(field.ident.node));
@@ -1607,7 +1606,7 @@ fn print_expr_struct(&mut self,
 
     fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> {
         try!(self.popen());
-        try!(self.commasep_exprs(Inconsistent, &exprs[]));
+        try!(self.commasep_exprs(Inconsistent, &exprs[..]));
         if exprs.len() == 1 {
             try!(word(&mut self.s, ","));
         }
@@ -1672,22 +1671,22 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
                 try!(self.print_expr_box(place, &**expr));
             }
             ast::ExprVec(ref exprs) => {
-                try!(self.print_expr_vec(&exprs[]));
+                try!(self.print_expr_vec(&exprs[..]));
             }
             ast::ExprRepeat(ref element, ref count) => {
                 try!(self.print_expr_repeat(&**element, &**count));
             }
             ast::ExprStruct(ref path, ref fields, ref wth) => {
-                try!(self.print_expr_struct(path, &fields[], wth));
+                try!(self.print_expr_struct(path, &fields[..], wth));
             }
             ast::ExprTup(ref exprs) => {
-                try!(self.print_expr_tup(&exprs[]));
+                try!(self.print_expr_tup(&exprs[..]));
             }
             ast::ExprCall(ref func, ref args) => {
-                try!(self.print_expr_call(&**func, &args[]));
+                try!(self.print_expr_call(&**func, &args[..]));
             }
             ast::ExprMethodCall(ident, ref tys, ref args) => {
-                try!(self.print_expr_method_call(ident, &tys[], &args[]));
+                try!(self.print_expr_method_call(ident, &tys[..], &args[..]));
             }
             ast::ExprBinary(op, ref lhs, ref rhs) => {
                 try!(self.print_expr_binary(op, &**lhs, &**rhs));
@@ -1875,11 +1874,11 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
                 try!(self.print_string(&a.asm, a.asm_str_style));
                 try!(self.word_space(":"));
 
-                try!(self.commasep(Inconsistent, &a.outputs[],
+                try!(self.commasep(Inconsistent, &a.outputs,
                                    |s, &(ref co, ref o, is_rw)| {
                     match co.slice_shift_char() {
                         Some(('=', operand)) if is_rw => {
-                            try!(s.print_string(&format!("+{}", operand)[],
+                            try!(s.print_string(&format!("+{}", operand),
                                                 ast::CookedStr))
                         }
                         _ => try!(s.print_string(&co, ast::CookedStr))
@@ -1892,7 +1891,7 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
                 try!(space(&mut self.s));
                 try!(self.word_space(":"));
 
-                try!(self.commasep(Inconsistent, &a.inputs[],
+                try!(self.commasep(Inconsistent, &a.inputs,
                                    |s, &(ref co, ref o)| {
                     try!(s.print_string(&co, ast::CookedStr));
                     try!(s.popen());
@@ -1903,7 +1902,7 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
                 try!(space(&mut self.s));
                 try!(self.word_space(":"));
 
-                try!(self.commasep(Inconsistent, &a.clobbers[],
+                try!(self.commasep(Inconsistent, &a.clobbers,
                                    |s, co| {
                     try!(s.print_string(&co, ast::CookedStr));
                     Ok(())
@@ -1977,7 +1976,7 @@ pub fn print_decl(&mut self, decl: &ast::Decl) -> IoResult<()> {
     pub fn print_ident(&mut self, ident: ast::Ident) -> IoResult<()> {
         if self.encode_idents_with_hygiene {
             let encoded = ident.encode_with_hygiene();
-            try!(word(&mut self.s, &encoded[]))
+            try!(word(&mut self.s, &encoded[..]))
         } else {
             try!(word(&mut self.s, &token::get_ident(ident)))
         }
@@ -1985,7 +1984,7 @@ pub fn print_ident(&mut self, ident: ast::Ident) -> IoResult<()> {
     }
 
     pub fn print_usize(&mut self, i: usize) -> IoResult<()> {
-        word(&mut self.s, &i.to_string()[])
+        word(&mut self.s, &i.to_string())
     }
 
     pub fn print_name(&mut self, name: ast::Name) -> IoResult<()> {
@@ -2075,7 +2074,7 @@ fn print_path_parameters(&mut self,
                     }
                     try!(self.commasep(
                         Inconsistent,
-                        &data.types[],
+                        &data.types,
                         |s, ty| s.print_type(&**ty)));
                         comma = true;
                 }
@@ -2098,7 +2097,7 @@ fn print_path_parameters(&mut self,
                 try!(word(&mut self.s, "("));
                 try!(self.commasep(
                     Inconsistent,
-                    &data.inputs[],
+                    &data.inputs,
                     |s, ty| s.print_type(&**ty)));
                 try!(word(&mut self.s, ")"));
 
@@ -2151,7 +2150,7 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
                     Some(ref args) => {
                         if !args.is_empty() {
                             try!(self.popen());
-                            try!(self.commasep(Inconsistent, &args[],
+                            try!(self.commasep(Inconsistent, &args[..],
                                               |s, p| s.print_pat(&**p)));
                             try!(self.pclose());
                         }
@@ -2163,7 +2162,7 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
                 try!(self.nbsp());
                 try!(self.word_space("{"));
                 try!(self.commasep_cmnt(
-                    Consistent, &fields[],
+                    Consistent, &fields[..],
                     |s, f| {
                         try!(s.cbox(indent_unit));
                         if !f.node.is_shorthand {
@@ -2184,7 +2183,7 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
             ast::PatTup(ref elts) => {
                 try!(self.popen());
                 try!(self.commasep(Inconsistent,
-                                   &elts[],
+                                   &elts[..],
                                    |s, p| s.print_pat(&**p)));
                 if elts.len() == 1 {
                     try!(word(&mut self.s, ","));
@@ -2212,7 +2211,7 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
             ast::PatVec(ref before, ref slice, ref after) => {
                 try!(word(&mut self.s, "["));
                 try!(self.commasep(Inconsistent,
-                                   &before[],
+                                   &before[..],
                                    |s, p| s.print_pat(&**p)));
                 if let Some(ref p) = *slice {
                     if !before.is_empty() { try!(self.word_space(",")); }
@@ -2226,7 +2225,7 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
                     if !after.is_empty() { try!(self.word_space(",")); }
                 }
                 try!(self.commasep(Inconsistent,
-                                   &after[],
+                                   &after[..],
                                    |s, p| s.print_pat(&**p)));
                 try!(word(&mut self.s, "]"));
             }
@@ -2243,7 +2242,7 @@ fn print_arm(&mut self, arm: &ast::Arm) -> IoResult<()> {
         }
         try!(self.cbox(indent_unit));
         try!(self.ibox(0));
-        try!(self.print_outer_attributes(&arm.attrs[]));
+        try!(self.print_outer_attributes(&arm.attrs));
         let mut first = true;
         for p in &arm.pats {
             if first {
@@ -2475,7 +2474,7 @@ pub fn print_generics(&mut self,
             ints.push(i);
         }
 
-        try!(self.commasep(Inconsistent, &ints[], |s, &idx| {
+        try!(self.commasep(Inconsistent, &ints[..], |s, &idx| {
             if idx < generics.lifetimes.len() {
                 let lifetime = &generics.lifetimes[idx];
                 s.print_lifetime_def(lifetime)
@@ -2492,7 +2491,7 @@ pub fn print_generics(&mut self,
 
     pub fn print_ty_param(&mut self, param: &ast::TyParam) -> IoResult<()> {
         try!(self.print_ident(param.ident));
-        try!(self.print_bounds(":", &param.bounds[]));
+        try!(self.print_bounds(":", &param.bounds));
         match param.default {
             Some(ref default) => {
                 try!(space(&mut self.s));
@@ -2562,7 +2561,7 @@ pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> IoResult<()> {
                 try!(word(&mut self.s, &name));
             }
             ast::MetaNameValue(ref name, ref value) => {
-                try!(self.word_space(&name[]));
+                try!(self.word_space(&name[..]));
                 try!(self.word_space("="));
                 try!(self.print_literal(value));
             }
@@ -2570,7 +2569,7 @@ pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> IoResult<()> {
                 try!(word(&mut self.s, &name));
                 try!(self.popen());
                 try!(self.commasep(Consistent,
-                                   &items[],
+                                   &items[..],
                                    |s, i| s.print_meta_item(&**i)));
                 try!(self.pclose());
             }
@@ -2606,7 +2605,7 @@ pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> IoResult<()> {
                     try!(self.print_path(path, false));
                     try!(word(&mut self.s, "::{"));
                 }
-                try!(self.commasep(Inconsistent, &idents[], |s, w| {
+                try!(self.commasep(Inconsistent, &idents[..], |s, w| {
                     match w.node {
                         ast::PathListIdent { name, .. } => {
                             s.print_ident(name)
@@ -2753,7 +2752,7 @@ pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
         try!(self.maybe_print_comment(lit.span.lo));
         match self.next_lit(lit.span.lo) {
             Some(ref ltrl) => {
-                return word(&mut self.s, &(*ltrl).lit[]);
+                return word(&mut self.s, &(*ltrl).lit);
             }
             _ => ()
         }
@@ -2763,33 +2762,33 @@ pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
                 let mut res = String::from_str("b'");
                 res.extend(ascii::escape_default(byte).map(|c| c as char));
                 res.push('\'');
-                word(&mut self.s, &res[])
+                word(&mut self.s, &res[..])
             }
             ast::LitChar(ch) => {
                 let mut res = String::from_str("'");
                 res.extend(ch.escape_default());
                 res.push('\'');
-                word(&mut self.s, &res[])
+                word(&mut self.s, &res[..])
             }
             ast::LitInt(i, t) => {
                 match t {
                     ast::SignedIntLit(st, ast::Plus) => {
                         word(&mut self.s,
-                             &ast_util::int_ty_to_string(st, Some(i as i64))[])
+                             &ast_util::int_ty_to_string(st, Some(i as i64)))
                     }
                     ast::SignedIntLit(st, ast::Minus) => {
                         let istr = ast_util::int_ty_to_string(st, Some(-(i as i64)));
                         word(&mut self.s,
-                             &format!("-{}", istr)[])
+                             &format!("-{}", istr))
                     }
                     ast::UnsignedIntLit(ut) => {
                         word(&mut self.s, &ast_util::uint_ty_to_string(ut, Some(i)))
                     }
                     ast::UnsuffixedIntLit(ast::Plus) => {
-                        word(&mut self.s, &format!("{}", i)[])
+                        word(&mut self.s, &format!("{}", i))
                     }
                     ast::UnsuffixedIntLit(ast::Minus) => {
-                        word(&mut self.s, &format!("-{}", i)[])
+                        word(&mut self.s, &format!("-{}", i))
                     }
                 }
             }
@@ -2798,9 +2797,9 @@ pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
                      &format!(
                          "{}{}",
                          &f,
-                         &ast_util::float_ty_to_string(t)[])[])
+                         &ast_util::float_ty_to_string(t)))
             }
-            ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, &f[]),
+            ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, &f[..]),
             ast::LitBool(val) => {
                 if val { word(&mut self.s, "true") } else { word(&mut self.s, "false") }
             }
@@ -2810,7 +2809,7 @@ pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
                     escaped.extend(ascii::escape_default(ch as u8)
                                          .map(|c| c as char));
                 }
-                word(&mut self.s, &format!("b\"{}\"", escaped)[])
+                word(&mut self.s, &format!("b\"{}\"", escaped))
             }
         }
     }
@@ -2851,7 +2850,7 @@ pub fn print_comment(&mut self,
             comments::Mixed => {
                 assert_eq!(cmnt.lines.len(), 1);
                 try!(zerobreak(&mut self.s));
-                try!(word(&mut self.s, &cmnt.lines[0][]));
+                try!(word(&mut self.s, &cmnt.lines[0]));
                 zerobreak(&mut self.s)
             }
             comments::Isolated => {
@@ -2860,7 +2859,7 @@ pub fn print_comment(&mut self,
                     // Don't print empty lines because they will end up as trailing
                     // whitespace
                     if !line.is_empty() {
-                        try!(word(&mut self.s, &line[]));
+                        try!(word(&mut self.s, &line[..]));
                     }
                     try!(hardbreak(&mut self.s));
                 }
@@ -2869,13 +2868,13 @@ pub fn print_comment(&mut self,
             comments::Trailing => {
                 try!(word(&mut self.s, " "));
                 if cmnt.lines.len() == 1 {
-                    try!(word(&mut self.s, &cmnt.lines[0][]));
+                    try!(word(&mut self.s, &cmnt.lines[0]));
                     hardbreak(&mut self.s)
                 } else {
                     try!(self.ibox(0));
                     for line in &cmnt.lines {
                         if !line.is_empty() {
-                            try!(word(&mut self.s, &line[]));
+                            try!(word(&mut self.s, &line[..]));
                         }
                         try!(hardbreak(&mut self.s));
                     }
@@ -2908,7 +2907,7 @@ pub fn print_string(&mut self, st: &str,
                          string=st))
             }
         };
-        word(&mut self.s, &st[])
+        word(&mut self.s, &st[..])
     }
 
     pub fn next_comment(&mut self) -> Option<comments::Comment> {
@@ -2939,7 +2938,7 @@ pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
             Some(abi::Rust) => Ok(()),
             Some(abi) => {
                 try!(self.word_nbsp("extern"));
-                self.word_nbsp(&abi.to_string()[])
+                self.word_nbsp(&abi.to_string())
             }
             None => Ok(())
         }
@@ -2950,7 +2949,7 @@ pub fn print_extern_opt_abi(&mut self,
         match opt_abi {
             Some(abi) => {
                 try!(self.word_nbsp("extern"));
-                self.word_nbsp(&abi.to_string()[])
+                self.word_nbsp(&abi.to_string())
             }
             None => Ok(())
         }
@@ -2965,7 +2964,7 @@ pub fn print_fn_header_info(&mut self,
 
         if abi != abi::Rust {
             try!(self.word_nbsp("extern"));
-            try!(self.word_nbsp(&abi.to_string()[]));
+            try!(self.word_nbsp(&abi.to_string()));
         }
 
         word(&mut self.s, "fn")
index 01f3839b0390ef3a2293af2198bbac377c08201c..adb5383a8fd544d0f666dbf74d92e2fb729f20d5 100644 (file)
@@ -111,11 +111,18 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[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);
+    }
+}
 
 impl<T: 'static + Decodable> Decodable for P<T> {
     fn decode<D: Decoder>(d: &mut D) -> Result<P<T>, D::Error> {
index 98c193c7e6b850b1bfc90d6d39d8b8d7537b27ea..4e4a571ede7b864af3b797be5784fb6fc582e7b9 100644 (file)
@@ -45,16 +45,16 @@ fn no_prelude(attrs: &[ast::Attribute]) -> bool {
     attr::contains_name(attrs, "no_implicit_prelude")
 }
 
-struct StandardLibraryInjector<'a> {
-    alt_std_name: Option<String>
+struct StandardLibraryInjector {
+    alt_std_name: Option<String>,
 }
 
-impl<'a> fold::Folder for StandardLibraryInjector<'a> {
+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;`
         let actual_crate_name = match self.alt_std_name {
-            Some(ref s) => token::intern_and_get_ident(&s[]),
+            Some(ref s) => token::intern_and_get_ident(&s[..]),
             None => token::intern_and_get_ident("std"),
         };
 
@@ -80,9 +80,10 @@ fn inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>) -> ast::Cr
     fold.fold_crate(krate)
 }
 
-struct PreludeInjector<'a>;
+struct PreludeInjector;
 
-impl<'a> fold::Folder for PreludeInjector<'a> {
+
+impl fold::Folder for PreludeInjector {
     fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
         // only add `use std::prelude::*;` if there wasn't a
         // `#![no_implicit_prelude]` at the crate level.
index 6511dffa6bf8bbc1d944785a5f54151205eba7c1..7b1fc91e45b5bb3547841faf5f7505210a03b5f0 100644 (file)
@@ -119,7 +119,7 @@ fn fold_item(&mut self, i: P<ast::Item>) -> SmallVector<P<ast::Item>> {
             self.cx.path.push(ident);
         }
         debug!("current path: {}",
-               ast_util::path_name_i(&self.cx.path[]));
+               ast_util::path_name_i(&self.cx.path));
 
         if is_test_fn(&self.cx, &*i) || is_bench_fn(&self.cx, &*i) {
             match i.node {
@@ -274,8 +274,8 @@ fn strip_test_functions(krate: ast::Crate) -> ast::Crate {
     // When not compiling with --test we should not compile the
     // #[test] functions
     config::strip_items(krate, |attrs| {
-        !attr::contains_name(&attrs[], "test") &&
-        !attr::contains_name(&attrs[], "bench")
+        !attr::contains_name(&attrs[..], "test") &&
+        !attr::contains_name(&attrs[..], "bench")
     })
 }
 
@@ -563,7 +563,7 @@ fn mk_tests(cx: &TestCtxt) -> P<ast::Item> {
 
 fn is_test_crate(krate: &ast::Crate) -> bool {
     match attr::find_crate_name(&krate.attrs[]) {
-        Some(ref s) if "test" == &s[] => true,
+        Some(ref s) if "test" == &s[..] => true,
         _ => false
     }
 }
@@ -603,11 +603,11 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
     // creates $name: $expr
     let field = |name, expr| ecx.field_imm(span, ecx.ident_of(name), expr);
 
-    debug!("encoding {}", ast_util::path_name_i(&path[]));
+    debug!("encoding {}", ast_util::path_name_i(&path[..]));
 
     // path to the #[test] function: "foo::bar::baz"
-    let path_string = ast_util::path_name_i(&path[]);
-    let name_expr = ecx.expr_str(span, token::intern_and_get_ident(&path_string[]));
+    let path_string = ast_util::path_name_i(&path[..]);
+    let name_expr = ecx.expr_str(span, token::intern_and_get_ident(&path_string[..]));
 
     // self::test::StaticTestName($name_expr)
     let name_expr = ecx.expr_call(span,
index 511442675194e77661b4a167bdfcddf67e247bfc..dffeac6f3f7938df88ae352309b3a9fb068c42f3 100644 (file)
 
 use ast::Name;
 
-use std::borrow::BorrowFrom;
+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::collections::hash_map::Hasher;
 use std::ops::Deref;
 use std::rc::Rc;
 
@@ -30,6 +30,7 @@ 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 {
@@ -79,7 +80,71 @@ pub fn len(&self) -> usize {
     }
 
     pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name>
-    where Q: BorrowFrom<T> + Eq + Hash<Hasher> {
+    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 {
+            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 {
         let map = self.map.borrow();
         match (*map).get(val) {
             Some(v) => Some(*v),
@@ -110,34 +175,34 @@ impl Eq for RcStr {}
 
 impl Ord for RcStr {
     fn cmp(&self, other: &RcStr) -> Ordering {
-        self[].cmp(&other[])
+        self[..].cmp(&other[..])
     }
 }
 
 impl fmt::Debug for RcStr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         use std::fmt::Debug;
-        self[].fmt(f)
+        self[..].fmt(f)
     }
 }
 
 impl fmt::Display for RcStr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         use std::fmt::Display;
-        self[].fmt(f)
+        self[..].fmt(f)
     }
 }
 
-impl BorrowFrom<RcStr> for str {
-    fn borrow_from(owned: &RcStr) -> &str {
-        &owned.string[]
+impl Borrow<str> for RcStr {
+    fn borrow(&self) -> &str {
+        &self.string[..]
     }
 }
 
 impl Deref for RcStr {
     type Target = str;
 
-    fn deref(&self) -> &str { &self.string[] }
+    fn deref(&self) -> &str { &self.string[..] }
 }
 
 /// A StrInterner differs from Interner<String> in that it accepts
@@ -210,8 +275,17 @@ pub fn len(&self) -> usize {
         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 Q: BorrowFrom<RcStr> + Eq + Hash<Hasher> {
+    where RcStr: Borrow<Q>, Q: Eq + Hash {
         match (*self.map.borrow()).get(val) {
             Some(v) => Some(*v),
             None => None,
index b2009a7e8485480c00f418968c9f54c730a26f73..0a39d3809045a2e56f745255e6b204bc5d43f8d0 100644 (file)
@@ -11,7 +11,7 @@
 use self::SmallVectorRepr::*;
 use self::IntoIterRepr::*;
 
-use std::iter::FromIterator;
+use std::iter::{IntoIterator, FromIterator};
 use std::mem;
 use std::slice;
 use std::vec;
@@ -30,7 +30,7 @@ enum SmallVectorRepr<T> {
 }
 
 impl<T> FromIterator<T> for SmallVector<T> {
-    fn from_iter<I: Iterator<Item=T>>(iter: I) -> SmallVector<T> {
+    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> SmallVector<T> {
         let mut v = SmallVector::zero();
         v.extend(iter);
         v
@@ -38,7 +38,7 @@ fn from_iter<I: Iterator<Item=T>>(iter: I) -> SmallVector<T> {
 }
 
 impl<T> Extend<T> for SmallVector<T> {
-    fn extend<I: Iterator<Item=T>>(&mut self, iter: I) {
+    fn extend<I: IntoIterator<Item=T>>(&mut self, iter: I) {
         for val in iter {
             self.push(val);
         }
index 304f370a1993e0b44284401793c4389f98774d01..5418533aff1d918129f9bae1f6f5059dd603fe55 100644 (file)
@@ -50,7 +50,6 @@
        html_playground_url = "http://play.rust-lang.org/")]
 #![deny(missing_docs)]
 
-#![feature(core)]
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(int_uint)]
index b978d2d8054e566212eb33868777ad3d9d1924ea..be1c623c8590512c1f699aed09e7bc496039bd57 100644 (file)
@@ -180,7 +180,7 @@ pub fn new(out: T) -> Option<Box<Terminal<T>+Send+'static>> {
             }
         };
 
-        let entry = open(&term[]);
+        let entry = open(&term[..]);
         if entry.is_err() {
             if env::var("MSYSCON").ok().map_or(false, |s| {
                     "mintty.exe" == s
index 82b5ec11d95d1dd8aef5c9f990ade25c9a950d27..0b577f8de74c2a9b2e8178584173c29e8d134b7a 100644 (file)
@@ -608,7 +608,7 @@ fn get_res(fmt: &str, cap: &str, params: &[Param], vars: &mut Variables) ->
             Result<Vec<u8>, String>
         {
             let mut u8v: Vec<_> = fmt.bytes().collect();
-            u8v.extend(cap.as_bytes().iter().map(|&b| b));
+            u8v.extend(cap.bytes());
             expand(&u8v, params, vars)
         }
 
index fd6e6a843e1f3581586160c02ce402f8706ce781..c40a5534efbbb4e8d3d6146c6c513a124a420c62 100644 (file)
@@ -60,13 +60,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_many(&[&f[..], 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 newp = p.join_many(&[&f[..], term]);
             if newp.exists() {
                 return Some(box newp);
             }
index 2cb30ad9804c6de074bbec45e5b29a19c909eb2e..82c1a4b1195ce06ca1f948e39c13fe01f613991f 100644 (file)
@@ -37,7 +37,6 @@
 #![feature(collections)]
 #![feature(core)]
 #![feature(env)]
-#![feature(hash)]
 #![feature(int_uint)]
 #![feature(old_io)]
 #![feature(old_path)]
@@ -721,7 +720,7 @@ fn should_sort_failures_before_printing_them() {
 
     st.write_failures().unwrap();
     let s = match st.out {
-        Raw(ref m) => String::from_utf8_lossy(&m[]),
+        Raw(ref m) => String::from_utf8_lossy(&m[..]),
         Pretty(_) => unreachable!()
     };
 
@@ -834,7 +833,7 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescA
         None => filtered,
         Some(ref filter) => {
             filtered.into_iter().filter(|test| {
-                test.desc.name.as_slice().contains(&filter[])
+                test.desc.name.as_slice().contains(&filter[..])
             }).collect()
         }
     };
index 31ce3e91a7717a1a84a324210b43c7249a0c77a9..4e94be59ade0dd540f2f743138df9cae9ae52dd1 100644 (file)
@@ -12,7 +12,7 @@
 
 use std::cmp::Ordering::{self, Less, Greater, Equal};
 use std::collections::hash_map::Entry::{Occupied, Vacant};
-use std::collections::hash_map::{self, Hasher};
+use std::collections::hash_map;
 use std::hash::Hash;
 use std::mem;
 use std::num::{Float, FromPrimitive};
@@ -333,7 +333,7 @@ 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<Hasher>
+  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 {
index 2089cab13e7f92b487ba0dc1df9f6c05116b004a..4891e6382e3e8aa89d530aa18427836428c47157 160000 (submodule)
--- a/src/llvm
+++ b/src/llvm
@@ -1 +1 @@
-Subproject commit 2089cab13e7f92b487ba0dc1df9f6c05116b004a
+Subproject commit 4891e6382e3e8aa89d530aa18427836428c47157
index 6f5fc5c1969f0a8704e0f5b8fabb27b6610877c4..224f1ef1a8b9b6feaaa5e559b6bbfea5f2c953e5 100644 (file)
@@ -92,7 +92,7 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> {
         {
             let urls = markdown_data.replace(".md)", ".html)");
             try!(File::create(&preprocessed_path)
-                      .write_str(&urls[]));
+                      .write_str(&urls[..]));
         }
 
         // write the prelude to a temporary HTML file for rustdoc inclusion
index 1c10a270acc6c9ff1d2e708967ca0a8e5ca4a4f4..43c882c7d5b8a69c1c660049f7abf6f969fe8764 100644 (file)
@@ -52,7 +52,7 @@ fn description<'b>(&'b self) -> &'b str {
 
 impl Error for String {
     fn description<'a>(&'a self) -> &'a str {
-        &self[]
+        &self[..]
     }
 }
 
@@ -75,7 +75,7 @@ fn description(&self) -> &str {
         self.desc
     }
     fn detail(&self) -> Option<&str> {
-        self.detail.as_ref().map(|s| &s[])
+        self.detail.as_ref().map(|s| &s[..])
     }
 }
 
index d3cb8a7316e8640178eb2c8fb7d726f0c66e857b..c5d4875423ae1ee62893be77b7183018ff35ccf4 100644 (file)
@@ -65,7 +65,7 @@ fn execute(&mut self, term: &mut Term) -> CommandResult<()> {
             }
             Err(errors) => {
                 for err in errors {
-                    term.err(&err[]);
+                    term.err(&err[..]);
                 }
                 return Err(box "There was an error." as Box<Error>);
             }
index 2e5d18b58f22f4bbf9aa81c9f75018f625419b44..cc42b288e6638a0f7c36e385dbf25012c8ac791c 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait TheTrait<T> {
+pub trait TheTrait<T> : ::std::marker::PhantomFn<T> {
     fn the_fn(&self);
 }
 
index d12f716decf9925dfe4e53cb1e58f034dab283f8..0a65174911ec7149b473c4e9216bb35e2c173a27 100644 (file)
@@ -12,4 +12,5 @@
 
 pub struct FakeHeap;
 
-pub struct FakeVec<T, A = FakeHeap>;
+pub struct FakeVec<T, A = FakeHeap> { pub f: Option<(T,A)> }
+
index 94acea06618385a83e54a6a30afcaba468b474b8..ca5c6072cb371b98bd9ea096807f65abbb570944 100644 (file)
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub struct A<T>;
-pub struct B<T>;
+pub struct A<T> { pub v: T }
+pub struct B<T> { pub v: T }
 
 pub mod test {
-    pub struct A<T>;
+    pub struct A<T> { pub v: T }
 
     impl<T> A<T> {
         pub fn foo(&self) -> int {
@@ -52,9 +52,9 @@ pub fn bar(&self) -> int {
 }
 
 pub fn foo() -> int {
-    let a = A::<()>;
-    let b = B::<()>;
-    let c = test::A::<()>;
+    let a = A { v: () };
+    let b = B { v: () };
+    let c = test::A { v: () };
     return a.foo() + a.bar() +
            b.foo() + b.bar() +
            c.foo() + c.bar();
index 7c69cba179ca19bacabffc1a6e04b97fd7d909e0..a48088609f982ca7565fccde0828912430998f4c 100644 (file)
@@ -10,6 +10,7 @@
 
 #![crate_type="lib"]
 #![deny(warnings)]
+#![allow(dead_code)]
 
 pub use src::aliases::B;
 pub use src::hidden_core::make;
@@ -23,9 +24,9 @@ pub mod aliases {
     pub mod hidden_core {
         use super::aliases::B;
 
-        pub struct A<T>;
+        pub struct A<T> { t: T }
 
-        pub fn make() -> B { A }
+        pub fn make() -> B { A { t: 1.0 } }
 
         impl<T> A<T> {
             pub fn foo(&mut self) { println!("called foo"); }
index c5b3fceaf4a5febc01773f6a43254baf8f587e42..b590160a0c2ab5d8c1c467660a26dbc4818081a8 100644 (file)
@@ -10,7 +10,7 @@
 
 #![crate_type = "lib"]
 
-pub struct TreeBuilder<H>;
+pub struct TreeBuilder<H> { pub h: H }
 
 impl<H> TreeBuilder<H> {
     pub fn process_token(&mut self) {
index be10ca1dd8fd82c9cf00a8389bff6d3c45741629..fb55a077005eb8d9662a02f4e24f1b2f67900784 100644 (file)
@@ -11,7 +11,7 @@
 #![crate_type = "lib"]
 
 pub trait Foo<'a, T> {
-    fn foo(&self) -> T;
+    fn foo(&'a self) -> T;
 }
 
 pub fn foo<'a, T>(x: &'a Foo<'a, T>) -> T {
index 8eb6cd6e263182e9e48502566d0e0464804439fa..96f33f97a696973c891a36bbe0e0a742f5598bf9 100644 (file)
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-pub trait i<T> { }
+pub trait i<T>
+{
+    fn dummy(&self, t: T) -> T { panic!() }
+}
 
 pub fn f<T>() -> Box<i<T>+'static> {
     impl<T> i<T> for () { }
index e3ce4e8f6565a942f1d6ab4239cb4aa508d01dfa..89b3b56121a1614961297566eb8088c21a5808ef 100644 (file)
 
 #![feature(unsafe_destructor)]
 
+use std::marker;
+
 struct arc_destruct<T> {
-  _data: int,
+    _data: int,
+    _marker: marker::PhantomData<T>
 }
 
 #[unsafe_destructor]
@@ -24,7 +27,8 @@ fn drop(&mut self) {}
 
 fn arc_destruct<T: Sync>(data: int) -> arc_destruct<T> {
     arc_destruct {
-        _data: data
+        _data: data,
+        _marker: marker::PhantomData
     }
 }
 
index 7a378b06df9e175ceac52066671a93b94ce8825e..4ce7e3079e330a0a82f8b445076d55bf51ff4c92 100644 (file)
@@ -10,4 +10,5 @@
 
 pub trait T {
     type C;
+    fn dummy(&self) { }
 }
index 2e254e5431d53d8f9cfb7e79639b618c9106d0fd..545e15fe1664d657ef941e983f72dd1b6c66b4d9 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait Foo {
+use std::marker::MarkerTrait;
+
+pub trait Foo : MarkerTrait {
     fn bar();
 }
 
index 0831993119ae829b2b5c7959a2b3669741767b19..9006a5d1775f764eb7f569fa7f491b09dd7b27da 100644 (file)
@@ -12,7 +12,9 @@
 
 use std::mem;
 
-trait A {}
+trait A {
+    fn dummy(&self) { }
+}
 struct B;
 impl A for B {}
 
index 000cc100a12f32ffb4b519420a73717f8f3cca72..4f2792aebcd2408639256271ae4254015e744f07 100644 (file)
@@ -15,5 +15,6 @@ fn x() {
         fn f() { }
         f();
     }
+    fn dummy(&self) { }
 }
 
index 834667968c85bdd3cb623701249d3cf5bc6df2bc..b9cc20b63cc5640258ac6bc70afde33440a6d24a 100644 (file)
 #![no_std]
 #![feature(lang_items)]
 
+#[lang="phantom_fn"]
+pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
+
 #[lang="sized"]
-pub trait Sized {}
+pub trait Sized : PhantomFn<Self> {}
 
 #[lang="panic"]
 fn panic(_: &(&'static str, &'static str, uint)) -> ! { loop {} }
@@ -25,6 +29,8 @@ fn panic(_: &(&'static str, &'static str, uint)) -> ! { loop {} }
 extern fn eh_personality() {}
 
 #[lang="copy"]
-pub trait Copy {}
+pub trait Copy : PhantomFn<Self> {
+    // Empty.
+}
 
 
index 36b3091852bce5c4e52f5a7e4588d791f6ca3f3b..e9d98889ff854062f3434ea105b5b91f401fca81 100644 (file)
@@ -37,9 +37,9 @@ fn get_lints(&self) -> LintArray {
 
     fn check_item(&mut self, cx: &Context, it: &ast::Item) {
         let name = token::get_ident(it.ident);
-        if &name[] == "lintme" {
+        if &name[..] == "lintme" {
             cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
-        } else if &name[] == "pleaselintme" {
+        } else if &name[..] == "pleaselintme" {
             cx.span_lint(PLEASE_LINT, it.span, "item is named 'pleaselintme'");
         }
     }
index 9020bb7b0fb2ebd6fb0637c2ce76813f87d57bdf..ffb234f70c8e754ec7f4d86411101598ac100118 100644 (file)
@@ -35,7 +35,7 @@ fn get_lints(&self) -> LintArray {
 
     fn check_item(&mut self, cx: &Context, it: &ast::Item) {
         let name = token::get_ident(it.ident);
-        if &name[] == "lintme" {
+        if &name[..] == "lintme" {
             cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
         }
     }
index 01b2b748ba9d83910105567c020b3fb8fd52d311..fb535eb8336f9b2df90d027c61cef3fb9f731097 100644 (file)
@@ -96,7 +96,7 @@ fn trait_stable_text(&self) {}
 impl Trait for MethodTester {}
 
 #[unstable(feature = "test_feature")]
-pub trait UnstableTrait {}
+pub trait UnstableTrait { fn dummy(&self) { } }
 
 #[stable(feature = "test_feature", since = "1.0.0")]
 #[deprecated(since = "1.0.0")]
index 21784bda27a8f14e5e3a0e37a4c8529548d257e4..fc1bea5a9fd41128c88b9a1b2506ed398cdb9477 100644 (file)
@@ -25,7 +25,7 @@ pub fn foo<T>(&self) {
 }
 
 // issue 8134
-pub struct Parser<T>;
+pub struct Parser<T>(T);
 impl<T: std::iter::Iterator<Item=char>> Parser<T> {
     fn in_doctype(&mut self) {
         static DOCTYPEPattern: [char; 6] = ['O', 'C', 'T', 'Y', 'P', 'E'];
index 7647f159401a74412b0590625e37d5102536f7d0..cf3e9903b5ad001e2bef688a792cfe8c5e630d07 100644 (file)
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait RemoteTrait {}
+pub trait RemoteTrait { fn dummy(&self) { } }
index caa9bbe5736e4adb55d0c7620dfe996b0feef5dc..3c8cba13ae73d07296407009850cd94adca716ed 100644 (file)
@@ -11,7 +11,8 @@
 use std::ops::Deref;
 
 struct DerefWithHelper<H, T> {
-    pub helper: H
+    pub helper: H,
+    pub value: Option<T>
 }
 
 trait Helper<T> {
@@ -34,6 +35,6 @@ fn deref(&self) -> &T {
 
 // Test cross-crate autoderef + vtable.
 pub fn check<T: PartialEq>(x: T, y: T) -> bool {
-    let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x) };
+    let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x), value: None };
     d.eq(&y)
 }
index 907d80b50db82729f77d4a5329e9e5018db18757..d0ab944813a0ac7c025de01bc2a3d0811825abac 100644 (file)
@@ -37,7 +37,7 @@ fn expand<'cx>(&self,
                    _: &[ast::TokenTree]) -> Box<MacResult+'cx> {
         let args = self.args.iter().map(|i| pprust::meta_item_to_string(&*i))
             .collect::<Vec<_>>().connect(", ");
-        let interned = token::intern_and_get_ident(&args[]);
+        let interned = token::intern_and_get_ident(&args[..]);
         MacExpr::new(ecx.expr_str(sp, interned))
     }
 }
index 37ee10c8d37333ec6e64793919ab8a1f504e14ca..42691579491bbfb7e7abb069fd995bf62288e8f0 100644 (file)
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {}
+trait Foo : ::std::marker::MarkerTrait {}
index 12833daf6045854990ba64e416c6670832e64876..04f1062c16f02a572e8f97c9345b2f6b99469983 100644 (file)
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
index 9e74bf281358faa1e582d81080183fb0fc38f392..fabd2289e9a44ea61c62f41c56fb5c41a7b2be99 100644 (file)
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
index c900550041b5c82a58d243ce64e67c18a1cf72d4..3fdb861bd40c178d430e26c4b51059b55debb0d8 100644 (file)
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
index 04f8eb3cf9bc0fd4121230931631fa66da136818..3116d24673d4847bef21ac198e648c5f098a4257 100644 (file)
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
index c7e0a18768a3d36ae7271d56bd00fd5bcd3ee9fb..b49a1533628f6f526225f062d21e06987dca295b 100644 (file)
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
index 5100af323183b18726535987931245f269798ed0..6562a93135f39740c5210eaa7824ed37668ffdd5 100644 (file)
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
index 077c33cb90d756f3555b64c1aa81c2b1f4a7b2a0..c7b392c6ee82b07b942cd7188a9fe316b8ad7579 100644 (file)
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
index d481fa5a1fa3b033d65967408d0f13e7209e53d2..450f61020260dd49416c27ea402223efd0c20157 100644 (file)
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
index 9e99a355ac1ee2a17df3d10d77ed5bb798e93a6d..c000737c854c6a85b1264f8a87c251ac718a9d40 100644 (file)
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
index b8dd497ac99c8e6fae182d27dd29d4a40d0491df..1e12659dc4b92f15dff148558217b6eb28ba4446 100644 (file)
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
index 12833daf6045854990ba64e416c6670832e64876..04f1062c16f02a572e8f97c9345b2f6b99469983 100644 (file)
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
index 690ddc670f5fa57bb919d670d9bf31c4b1d45a33..1e82b74f1ef2e5cd6240b735add8776a5a0d025f 100644 (file)
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
index 216e8e997f22de643e86f712dd718888965dd7a1..3c3dac9cdab96209dc789d35c42546ffd90ec6ef 100644 (file)
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
index 1695e474de9998c07dfda2d0b5c6849d4c29c7e0..a7c469fccaa5abbcba151be4cb6e579771fd3cae 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait Trait {}
+pub trait Trait {
+    fn dummy(&self) { }
+}
 
 pub struct Foo<T:Trait> {
     pub x: T,
index 990bc21604959366ab95ba497385fdf522085d1e..0982efbdbf47e4d8770a7adc1aa0aa4a78ac5071 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait Foo {
+pub trait Foo : ::std::marker::MarkerTrait {
 }
 
 impl Foo for int {
index 22e0d3168cadc69b5697fc43e0d66aacdfc701fb..56fb40bc0a469af3021f8e4a9346fb0a3161b197 100644 (file)
@@ -11,7 +11,7 @@
 pub use self::sub::{Bar, Baz};
 
 pub trait Trait {
-    fn foo();
+    fn foo(&self);
 }
 
 struct Foo;
index 1d440c4540ca3e9a1110ac2fe01646659dd372c1..994c9605fc375ccbaec7c386c6612f9a951b62b5 100644 (file)
@@ -16,9 +16,8 @@
 extern crate rand;
 
 use std::collections::BTreeSet;
-use std::collections::BitvSet;
+use std::collections::BitSet;
 use std::collections::HashSet;
-use std::collections::hash_map::Hasher;
 use std::hash::Hash;
 use std::env;
 use std::time::Duration;
@@ -43,7 +42,7 @@ trait MutableSet<T> {
     fn contains(&self, k: &T) -> bool;
 }
 
-impl<T: Hash<Hasher> + Eq> MutableSet<T> for HashSet<T> {
+impl<T: Hash + Eq> MutableSet<T> for HashSet<T> {
     fn insert(&mut self, k: T) { self.insert(k); }
     fn remove(&mut self, k: &T) -> bool { self.remove(k) }
     fn contains(&self, k: &T) -> bool { self.contains(k) }
@@ -53,7 +52,7 @@ impl<T: Ord> MutableSet<T> for BTreeSet<T> {
     fn remove(&mut self, k: &T) -> bool { self.remove(k) }
     fn contains(&self, k: &T) -> bool { self.contains(k) }
 }
-impl MutableSet<usize> for BitvSet {
+impl MutableSet<usize> for BitSet {
     fn insert(&mut self, k: usize) { self.insert(k); }
     fn remove(&mut self, k: &usize) -> bool { self.remove(k) }
     fn contains(&self, k: &usize) -> bool { self.contains(k) }
@@ -222,7 +221,7 @@ fn main() {
     {
         let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed);
         let mut results = empty_results();
-        results.bench_int(&mut rng, num_keys, max, || BitvSet::new());
-        write_results("collections::bitv::BitvSet", &results);
+        results.bench_int(&mut rng, num_keys, max, || BitSet::new());
+        write_results("collections::bit_vec::BitSet", &results);
     }
 }
index fd559608011afdcbb851eb7643b30e74386abf86..2c640c4b092556cab96df76819b992575a0fbf66 100644 (file)
@@ -132,7 +132,7 @@ fn run<W: Writer>(writer: &mut W) -> std::old_io::IoResult<()> {
                         ('t', 0.3015094502008)];
 
     try!(make_fasta(writer, ">ONE Homo sapiens alu\n",
-                    alu.as_bytes().iter().cycle().map(|c| *c), n * 2));
+                    alu.as_bytes().iter().cycle().cloned(), n * 2));
     try!(make_fasta(writer, ">TWO IUB ambiguity codes\n",
                     AAGen::new(rng, iub), n * 3));
     try!(make_fasta(writer, ">THREE Homo sapiens frequency\n",
index 73dce2910c9b4913260e26cb02ed235f19a04c50..a94fe0ccd959848a364d890eef0a1058128ad958 100644 (file)
@@ -202,7 +202,7 @@ fn filter_masks(masks: &mut Vec<Vec<Vec<u64>>>) {
     for i in 0..masks.len() {
         for j in 0..(*masks)[i].len() {
             masks[i][j] =
-                (*masks)[i][j].iter().map(|&m| m)
+                (*masks)[i][j].iter().cloned()
                 .filter(|&m| !is_board_unfeasible(m, masks))
                 .collect();
         }
@@ -270,7 +270,7 @@ fn handle_sol(raw_sol: &List<u64>, data: &mut Data) {
     // reverse order, i.e. the board rotated by half a turn.
     data.nb += 2;
     let sol1 = to_vec(raw_sol);
-    let sol2: Vec<u8> = sol1.iter().rev().map(|x| *x).collect();
+    let sol2: Vec<u8> = sol1.iter().rev().cloned().collect();
 
     if data.nb == 2 {
         data.min = sol1.clone();
diff --git a/src/test/compile-fail/ascii-only-character-escape.rs b/src/test/compile-fail/ascii-only-character-escape.rs
deleted file mode 100644 (file)
index 1ba25a8..0000000
+++ /dev/null
@@ -1,17 +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.
-
-fn main() {
-    let x = "\x80"; //~ ERROR may only be used
-    let y = "\xff"; //~ ERROR may only be used
-    let z = "\xe2"; //~ ERROR may only be used
-    let a = b"\x00e2";  // ok because byte literal
-}
-
index 621f5ec9660fca6aff50caf0bf144f62f0b0b008..edd1b8255ccdc38e6a4b1f7459443f0f0bda90e9 100644 (file)
 #![feature(no_std)]
 #![no_std]
 
+#[lang="phantom_fn"]
+pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
+
 #[lang="sized"]
-pub trait Sized {
+pub trait Sized : PhantomFn<Self> {
     // Empty.
 }
 
index 95a68dd66983672dfe537bf4f1bfc8bcee5c8d2d..b7a16c68a34e1a43fdbb1548dc903a80a3e740b8 100644 (file)
 // Test that coherence detects overlap when some of the types in the
 // impls are projections of associated type. Issue #20624.
 
+use std::marker::PhantomData;
 use std::ops::Deref;
 
-pub struct Cow<'a, B: ?Sized>;
+pub struct Cow<'a, B: ?Sized>(PhantomData<(&'a (),B)>);
 
 /// Trait for moving into a `Cow`
 pub trait IntoCow<'a, B: ?Sized> {
index 9baa7f1ad5a6901237f64cb4f1777590e47d638d..c48f9972ebc18765fca88e164449f57bb5a9ea11 100644 (file)
@@ -10,7 +10,7 @@
 
 // Check that an associated type cannot be bound in an expression path.
 
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
     type A;
     fn bar() -> isize;
 }
index fa09ae793bf632c75198a0fad1b8d7056838040c..625f4cdb8ef3dbc3af68abee2124f51eefb1a5b2 100644 (file)
@@ -11,7 +11,7 @@
 // Test that we do not ICE when an impl is missing an associated type (and that we report
 // a useful error, of course).
 
-trait Trait {
+trait Trait : ::std::marker::MarkerTrait {
     type Type;
 }
 
index 9436f825de89dd4b95a51cc7e6f7ce4ad320bcdd..5632f148da67ce2e1d00f4f0738c07406c00f88d 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
     type X;
     type Y;
 }
index a3f2850b29464589d86e4c28f38112be3065f0f2..2b84c38f80b542b309443d17c13a2f122383de9d 100644 (file)
@@ -11,7 +11,7 @@
 // Check that we get an error when you use `<Self as Get>::Value` in
 // the trait definition but `Self` does not, in fact, implement `Get`.
 
-trait Get {
+trait Get : ::std::marker::MarkerTrait {
     type Value;
 }
 
index 51a37b517ddebfb120ec63147dfa19829aaa3a79..b9a62ff4e417afd9d3840bdc836bb69ff8c53cd7 100644 (file)
@@ -12,6 +12,8 @@
 
 pub trait Foo {
     type A;
+
+    fn dummy(&self) { }
 }
 
 impl Foo for i32 {
index aecbf217a5b25e916155829b81188bf7401049ac..8832028f9aba1e87781545bb2426653882439b3c 100644 (file)
@@ -10,7 +10,7 @@
 
 // Check that an associated type cannot be bound in an expression path.
 
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
     type A;
     fn bar() -> isize;
 }
diff --git a/src/test/compile-fail/attr-before-eof.rs b/src/test/compile-fail/attr-before-eof.rs
deleted file mode 100644 (file)
index e347562..0000000
+++ /dev/null
@@ -1,11 +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.
-
-#[derive(Debug)] //~ERROR expected item after attributes
diff --git a/src/test/compile-fail/attr-before-ext.rs b/src/test/compile-fail/attr-before-ext.rs
deleted file mode 100644 (file)
index 098c5aa..0000000
+++ /dev/null
@@ -1,14 +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 main() {
-    #[attr] //~ ERROR expected item after attributes
-    println!("hi");
-}
diff --git a/src/test/compile-fail/attr-before-let.rs b/src/test/compile-fail/attr-before-let.rs
deleted file mode 100644 (file)
index b4a90e3..0000000
+++ /dev/null
@@ -1,14 +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 main() {
-    #[attr] //~ ERROR expected item
-    let __isize = 0;
-}
diff --git a/src/test/compile-fail/attr-before-stmt.rs b/src/test/compile-fail/attr-before-stmt.rs
deleted file mode 100644 (file)
index ec837cd..0000000
+++ /dev/null
@@ -1,19 +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.
-
-// error-pattern:expected item
-
-fn f() {
-  #[foo = "bar"]
-  let x = 10;
-}
-
-fn main() {
-}
diff --git a/src/test/compile-fail/attr-dangling-in-fn.rs b/src/test/compile-fail/attr-dangling-in-fn.rs
deleted file mode 100644 (file)
index 384622f..0000000
+++ /dev/null
@@ -1,18 +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.
-
-// error-pattern:expected item
-
-fn f() {
-  #[foo = "bar"]
-}
-
-fn main() {
-}
diff --git a/src/test/compile-fail/attr-dangling-in-mod.rs b/src/test/compile-fail/attr-dangling-in-mod.rs
deleted file mode 100644 (file)
index 59a922e..0000000
+++ /dev/null
@@ -1,16 +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.
-
-// error-pattern:expected item
-
-fn main() {
-}
-
-#[foo = "bar"]
diff --git a/src/test/compile-fail/attr.rs b/src/test/compile-fail/attr.rs
deleted file mode 100644 (file)
index 4bd6141..0000000
+++ /dev/null
@@ -1,16 +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(lang_items)]
-
-fn main() {}
-
-#![lang(foo)] //~ ERROR an inner attribute is not permitted in this context
-fn foo() {}
diff --git a/src/test/compile-fail/attrs-after-extern-mod.rs b/src/test/compile-fail/attrs-after-extern-mod.rs
deleted file mode 100644 (file)
index df74761..0000000
+++ /dev/null
@@ -1,23 +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.
-
-// Constants (static variables) can be used to match in patterns, but mutable
-// statics cannot. This ensures that there's some form of error if this is
-// attempted.
-
-extern crate libc;
-
-extern {
-    static mut rust_dbg_static_mut: libc::c_int;
-    pub fn rust_dbg_static_mut_check_four();
-    #[cfg(stage37)] //~ ERROR expected item after attributes
-}
-
-pub fn main() {}
diff --git a/src/test/compile-fail/bad-char-literals.rs b/src/test/compile-fail/bad-char-literals.rs
deleted file mode 100644 (file)
index 2a358ae..0000000
+++ /dev/null
@@ -1,29 +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.
-
-// ignore-tidy-cr
-// ignore-tidy-tab
-fn main() {
-    // these literals are just silly.
-    ''';
-    //~^ ERROR: character constant must be escaped: \'
-
-    // note that this is a literal "\n" byte
-    '
-';
-    //~^^ ERROR: character constant must be escaped: \n
-
-    // note that this is a literal "\r" byte
-    '\r'; //~ ERROR: character constant must be escaped: \r
-
-    // note that this is a literal tab character here
-    '  ';
-    //~^ ERROR: character constant must be escaped: \t
-}
diff --git a/src/test/compile-fail/bad-lit-suffixes.rs b/src/test/compile-fail/bad-lit-suffixes.rs
deleted file mode 100644 (file)
index d10337e..0000000
+++ /dev/null
@@ -1,41 +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
-    "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() {}
-
-extern
-    "C"suffix //~ ERROR ABI spec with a suffix is illegal
-{}
-
-fn main() {
-    ""suffix; //~ ERROR str literal with a suffix is illegal
-    b""suffix; //~ ERROR binary str literal with a suffix is illegal
-    r#""#suffix; //~ ERROR str literal with a suffix is illegal
-    br#""#suffix; //~ ERROR binary str literal with a suffix is illegal
-    'a'suffix; //~ ERROR char literal with a suffix is illegal
-    b'a'suffix; //~ ERROR byte literal with a suffix is illegal
-
-    1234u1024; //~ ERROR illegal width `1024` for integer literal
-    1234i1024; //~ ERROR illegal width `1024` for integer literal
-    1234f1024; //~ ERROR illegal width `1024` for float literal
-    1234.5f1024; //~ ERROR illegal width `1024` for float literal
-
-    1234suffix; //~ ERROR illegal suffix `suffix` for numeric literal
-    0b101suffix; //~ ERROR illegal suffix `suffix` for numeric literal
-    1.0suffix; //~ ERROR illegal suffix `suffix` for float literal
-    1.0e10suffix; //~ ERROR illegal suffix `suffix` for float literal
-}
index c91849ca53e1a780f2cba3bfafcf960ecc0a4ca5..3e02a11c378bd5a2292e8824c149cc4792479098 100644 (file)
 
 // ignore-tidy-linelength
 
-#![feature(no_std)]
-#![no_std]
-#![feature(lang_items)]
-
-#[lang="sized"]
-pub trait Sized {}
-
 struct S<T> {
     contents: T,
 }
index 69be6414e4c90e09657aba9d102e4dbf8f3ad69c..1944acbe1f34560115eb28ee004e6424d2e866de 100644 (file)
@@ -12,7 +12,7 @@
 
 use std::cell::RefCell;
 
-trait Trait {}
+trait Trait : ::std::marker::MarkerTrait {}
 
 pub fn main() {
     let x: Vec<Trait + Sized> = Vec::new();
diff --git a/src/test/compile-fail/bad-value-ident-false.rs b/src/test/compile-fail/bad-value-ident-false.rs
deleted file mode 100644 (file)
index ca10bdd..0000000
+++ /dev/null
@@ -1,12 +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 false() { } //~ ERROR expected identifier, found keyword `false`
-fn main() { }
diff --git a/src/test/compile-fail/bad-value-ident-true.rs b/src/test/compile-fail/bad-value-ident-true.rs
deleted file mode 100644 (file)
index 4508d52..0000000
+++ /dev/null
@@ -1,12 +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 true() { } //~ ERROR expected identifier, found keyword `true`
-fn main() { }
index 27d97d18c949f16f0935f92de930368030e7f0f5..d4decb713498df2e3e35eff101178d59b87af488 100644 (file)
@@ -10,6 +10,7 @@
 
 use std::fmt::Show;
 use std::default::Default;
+use std::marker::MarkerTrait;
 
 // Test that two blanket impls conflict (at least without negative
 // bounds).  After all, some other crate could implement Even or Odd
@@ -19,9 +20,9 @@ trait MyTrait {
     fn get(&self) -> usize;
 }
 
-trait Even { }
+trait Even : MarkerTrait { }
 
-trait Odd { }
+trait Odd : MarkerTrait { }
 
 impl Even for isize { }
 
index 0f233b78c72160b2bc833bac871dba077622281d..b1ee1762b6e71ab2d9c722de3564acc3da722821 100644 (file)
@@ -19,9 +19,9 @@ trait MyTrait {
     fn get(&self) -> usize;
 }
 
-trait Even { }
+trait Even : ::std::marker::MarkerTrait { }
 
-trait Odd { }
+trait Odd : ::std::marker::MarkerTrait { }
 
 impl<T:Even> MyTrait for T { //~ ERROR E0119
     fn get(&self) -> usize { 0 }
index c9dfb8201a98acb968382bb4d87dfb7b35406436..a225f6cf473041387b09124fbe54803d4f65f645 100644 (file)
 
 #![feature(optin_builtin_traits)]
 
-trait MyTrait {}
+trait MyTrait : ::std::marker::MarkerTrait {}
 
-struct TestType<T>;
+struct TestType<T>(::std::marker::PhantomData<T>);
 
-unsafe impl<T: MyTrait> Send for TestType<T> {}
+unsafe impl<T: MyTrait+'static> Send for TestType<T> {}
 //~^ ERROR conflicting implementations for trait `core::marker::Send`
 //~^^ ERROR conflicting implementations for trait `core::marker::Send`
 
 impl<T: MyTrait> !Send for TestType<T> {}
 //~^ ERROR conflicting implementations for trait `core::marker::Send`
 
-unsafe impl<T> Send for TestType<T> {}
+unsafe impl<T:'static> Send for TestType<T> {}
 //~^ ERROR error: conflicting implementations for trait `core::marker::Send`
 
 impl !Send for TestType<i32> {}
diff --git a/src/test/compile-fail/coherence-subtyping.rs b/src/test/compile-fail/coherence-subtyping.rs
new file mode 100644 (file)
index 0000000..897cb08
--- /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 two distinct impls which match subtypes of one another
+// yield coherence errors (or not) depending on the variance.
+
+trait Contravariant {
+    fn foo(&self) { }
+}
+
+impl Contravariant for for<'a,'b> fn(&'a u8, &'b u8) {
+    //~^ ERROR E0119
+}
+
+impl Contravariant for for<'a> fn(&'a u8, &'a u8) {
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+trait Covariant {
+    fn foo(&self) { }
+}
+
+impl Covariant for for<'a,'b> fn(&'a u8, &'b u8) {
+    //~^ ERROR E0119
+}
+
+impl Covariant for for<'a> fn(&'a u8, &'a u8) {
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+trait Invariant {
+    fn foo(&self) -> Self { }
+}
+
+impl Invariant for for<'a,'b> fn(&'a u8, &'b u8) {
+}
+
+impl Invariant for for<'a> fn(&'a u8, &'a u8) {
+}
+
+fn main() { }
index 86b7a8c89184abcbcd51e4bfe711360c61694f68..6bd21101a609df402b94dd01bb93a5a36892a5d7 100644 (file)
@@ -14,7 +14,7 @@
 #![feature(box_syntax)]
 
 struct Foo;
-trait Trait {}
+trait Trait { fn foo(&self) {} }
 impl Trait for Foo {}
 
 pub fn main() {
index f2e068cc4ff1b7d6856ceba972e3c1a92b1bab8d..4161cce2843b690fb65d53e86371f3f5cb5daaf9 100644 (file)
@@ -14,7 +14,7 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 
-trait T {}
+trait T { fn foo(&self) {} }
 impl T for isize {}
 
 fn main() {
diff --git a/src/test/compile-fail/doc-before-attr.rs b/src/test/compile-fail/doc-before-attr.rs
deleted file mode 100644 (file)
index bb44a6a..0000000
+++ /dev/null
@@ -1,12 +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.
-
-/// hi
-#[derive(Debug)] //~ERROR expected item after attributes
diff --git a/src/test/compile-fail/doc-before-eof.rs b/src/test/compile-fail/doc-before-eof.rs
deleted file mode 100644 (file)
index e6dd410..0000000
+++ /dev/null
@@ -1,11 +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.
-
-/// hi //~ERROR expected item after doc comment
diff --git a/src/test/compile-fail/doc-before-extern-rbrace.rs b/src/test/compile-fail/doc-before-extern-rbrace.rs
deleted file mode 100644 (file)
index 5afd1b2..0000000
+++ /dev/null
@@ -1,14 +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 {
-    /// hi
-}
-//~^^ ERROR expected item after doc comment
diff --git a/src/test/compile-fail/doc-before-macro.rs b/src/test/compile-fail/doc-before-macro.rs
deleted file mode 100644 (file)
index 8dc6c54..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.
-
-fn main() {
-    /// hi
-    println!("hi");
-    //~^^ ERROR expected item after doc comment
-}
diff --git a/src/test/compile-fail/doc-before-rbrace.rs b/src/test/compile-fail/doc-before-rbrace.rs
deleted file mode 100644 (file)
index 6d05064..0000000
+++ /dev/null
@@ -1,14 +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 main() {
-    println!("Hi"); /// hi
-    //~^ ERROR expected item after doc comment
-}
diff --git a/src/test/compile-fail/doc-before-semi.rs b/src/test/compile-fail/doc-before-semi.rs
deleted file mode 100644 (file)
index 8b0300e..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.
-
-fn main() {
-    /// hi
-    ;
-    //~^^ ERROR expected item after doc comment
-}
index 2b96c5ebe1284c1647e9aa991ecb03d651ddbb25..ddc929017718d02b6729740f3386812063fef3bd 100644 (file)
@@ -15,7 +15,7 @@ struct Fat<T: ?Sized> {
 }
 
 struct Foo;
-trait Bar {}
+trait Bar { fn bar(&self) {} }
 
 pub fn main() {
     // With a vec of isize.
index 160197368d6d983c673f924eb1508fbd62e1a3b1..aa687266acb8f701c9bae3461bb8b71c1c63c3e8 100644 (file)
@@ -15,7 +15,7 @@ struct Fat<T: ?Sized> {
 }
 
 struct Foo;
-trait Bar {}
+trait Bar : ::std::marker::MarkerTrait {}
 impl Bar for Foo {}
 
 pub fn main() {
index 347a2d2ecbe68599cff25e0f6804a01c110d28eb..7bad3bd69d3b01cbfe3a8cecbac6959bbf1deb7b 100644 (file)
@@ -15,7 +15,7 @@ struct Fat<T: ?Sized> {
 }
 
 struct Foo;
-trait Bar {}
+trait Bar { fn bar(&self) {} }
 impl Bar for Foo {}
 
 fn baz<'a>() {
index b30eada162b84707134573888de917956f8ca50c..8ec1034bc4d28abda4abda17968fad6296a7f160 100644 (file)
 
 // Test implicit coercions involving DSTs and raw pointers.
 
+use std::marker::MarkerTrait;
+
 struct S;
-trait T {}
+trait T : MarkerTrait {}
 impl T for S {}
 
 struct Foo<T: ?Sized> {
index 87ff4291f50e2d8f3ad951f338b8452508f189e1..b4fd45845f7a024da42365a2a0639b0927cda1be 100644 (file)
@@ -10,7 +10,7 @@
 
 // Test that we cannot create objects from unsized types.
 
-trait Foo {}
+trait Foo { fn foo(&self) {} }
 impl Foo for str {}
 
 fn test1<T: ?Sized + Foo>(t: &T) {
index 17453bc677f2bc0a61004533b39c432f3f98b654..f47f14d587992f83c2a95790130da77cf6651fdc 100644 (file)
@@ -20,7 +20,7 @@ fn drop(&mut self) {}
 }
 
 #[derive(Copy)] //~ ERROR the trait `Copy` may not be implemented
-struct Bar<T>;
+struct Bar<T>(::std::marker::PhantomData<T>);
 
 #[unsafe_destructor]
 impl<T> Drop for Bar<T> {
diff --git a/src/test/compile-fail/extern-crate-as-no-string-help.rs b/src/test/compile-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 02f09749d614d359b49e2ac85093762bed9136a5..9fea5e609d1f4807812476ea8b2e53c5da09fcdf 100644 (file)
@@ -8,10 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<A, B, C = (A, B)>;
+use std::marker;
+
+struct Foo<A, B, C = (A, B)>(
+    marker::PhantomData<(A,B,C)>);
 
 impl<A, B, C = (A, B)> Foo<A, B, C> {
-    fn new() -> Foo<A, B, C> {Foo}
+    fn new() -> Foo<A, B, C> {Foo(marker::PhantomData)}
 }
 
 fn main() {
index d88da2625c187cba2fc872afec0620f37ce028ed..73c19aa012dcf67dd0d39d97f8a748f9cb1a436c 100644 (file)
@@ -8,12 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 struct Heap;
 
-struct Vec<T, A = Heap>;
+struct Vec<T, A = Heap>(
+    marker::PhantomData<(T,A)>);
 
 impl<T, A = Heap> Vec<T, A> {
-    fn new() -> Vec<T, A> {Vec}
+    fn new() -> Vec<T, A> {Vec(marker::PhantomData)}
 }
 
 fn main() {
index fc54002820e012081807c43c78a6654c4284f6a1..9b9f09f47775741bc19a7cd3855678833983c8b6 100644 (file)
 //
 // Regression test for issue #16218.
 
-trait Bar<'a> {}
+trait Bar<'a> {
+    fn dummy(&'a self);
+}
 
 trait Foo<'a> {
+    fn dummy(&'a self) { }
     fn bar<'b, T: Bar<'b>>(self) -> &'b str;
 }
 
diff --git a/src/test/compile-fail/generic-non-trailing-defaults.rs b/src/test/compile-fail/generic-non-trailing-defaults.rs
deleted file mode 100644 (file)
index 0cfb05b..0000000
+++ /dev/null
@@ -1,17 +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 Heap;
-
-struct Vec<A = Heap, T>; //~ ERROR type parameters with a default must be trailing
-
-struct Foo<A, B = Vec<C>, C>; //~ ERROR type parameters with a default must be trailing
-
-fn main() {}
index f25d8f99b8d5449d45dcfa1c5734662a212ed92c..37737fda4749e5004ce1e666560e0da343143158 100644 (file)
@@ -8,9 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 struct Heap;
 
-struct Vec<T, A = Heap>;
+struct Vec<T, A = Heap>(
+    marker::PhantomData<(T,A)>);
 
 fn main() {
     let _: Vec; //~ ERROR wrong number of type arguments: expected at least 1, found 0
index 19d303488acb0f6d077d56da7a8e4ba76af184c8..ad7e4f190c5b9df7fe358c88f9b51461e8024479 100644 (file)
@@ -8,9 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 struct Heap;
 
-struct Vec<T, A = Heap>;
+struct Vec<T, A = Heap>(
+    marker::PhantomData<(T,A)>);
 
 fn main() {
     let _: Vec<isize, Heap, bool>;
index 3e34344d78b9dfbf9bd3da56caeefb116649af03..a452cd35f943fc4484b588d121e2ca9cb5538f29 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 struct A;
 struct B;
 struct C;
-struct Foo<T = A, U = B, V = C>;
+struct Foo<T = A, U = B, V = C>(marker::PhantomData<(T,U,V)>);
 
-struct Hash<T>;
-struct HashMap<K, V, H = Hash<K>>;
+struct Hash<T>(marker::PhantomData<T>);
+struct HashMap<K, V, H = Hash<K>>(marker::PhantomData<(K,V,H)>);
 
 fn main() {
     // Ensure that the printed type doesn't include the default type params...
diff --git a/src/test/compile-fail/int-literal-too-large-span.rs b/src/test/compile-fail/int-literal-too-large-span.rs
deleted file mode 100644 (file)
index 8a496c9..0000000
+++ /dev/null
@@ -1,17 +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.
-
-// issue #17123
-
-fn main() {
-    100000000000000000000000000000000 //~ ERROR int literal is too large
-
-        ; // the span shouldn't point to this.
-}
diff --git a/src/test/compile-fail/issue-10412.rs b/src/test/compile-fail/issue-10412.rs
deleted file mode 100644 (file)
index 8a99633..0000000
+++ /dev/null
@@ -1,32 +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.
-
-
-trait Serializable<'self, T> { //~ ERROR no longer a special lifetime
-    fn serialize(val : &'self T) -> Vec<u8> ; //~ ERROR no longer a special lifetime
-    fn deserialize(repr : &[u8]) -> &'self T; //~ ERROR no longer a special lifetime
-}
-
-impl<'self> Serializable<str> for &'self str { //~ ERROR no longer a special lifetime
-    //~^ ERROR no longer a special lifetime
-    fn serialize(val : &'self str) -> Vec<u8> { //~ ERROR no longer a special lifetime
-        vec!(1)
-    }
-    fn deserialize(repr: &[u8]) -> &'self str { //~ ERROR no longer a special lifetime
-        "hi"
-    }
-}
-
-fn main() {
-    println!("hello");
-    let x = "foo".to_string();
-    let y = x;
-    println!("{}", y);
-}
index f0089b0ae5b348f91e0643fa64a3d11c7363d505..4ff574e939df649794a2b31bdd4f49a374ed3c05 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(box_syntax)]
 
-struct Test<'s> {
+struct Test {
     func: Box<FnMut()+'static>
 }
 
diff --git a/src/test/compile-fail/issue-12560-1.rs b/src/test/compile-fail/issue-12560-1.rs
deleted file mode 100644 (file)
index ea2043e..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.
-
-// For style and consistency reasons, non-parametrized enum variants must
-// be used simply as `ident` instead of `ident ()`.
-// This test-case covers enum declaration.
-
-enum Foo {
-    Bar(), //~ ERROR nullary enum variants are written with no trailing `( )`
-    Baz(), //~ ERROR nullary enum variants are written with no trailing `( )`
-    Bazar
-}
-
-fn main() {
-    println!("{}", match Bar { Bar => 1, Baz => 2, Bazar => 3 })
-}
index ea0d880f4a1cc6a04f9da5415257a3a780e97379..dc697e4784f854e1cc113e75d91ae1d3362bb818 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait FromStructReader<'a> { }
+use std::marker::PhantomFn;
+
+trait FromStructReader<'a> : PhantomFn<(Self,&'a ())> { }
 trait ResponseHook {
      fn get<'a, T: FromStructReader<'a>>(&'a self);
 }
index f10c47b594ea2c9edaa98b1f2191578d7256e583..7ca158c3e32045c31cbe5cb70ebaf94e1709845d 100644 (file)
@@ -10,6 +10,8 @@
 
 #![crate_type = "lib"]
 
+use std::marker::PhantomData;
+
 enum NodeContents<'a> {
     Children(Vec<Node<'a>>),
 }
@@ -22,11 +24,12 @@ 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,}
+        Node { contents: contents, marker: PhantomData }
     }
 }
 
index 251da2c6b3ee979c020bf7e21c55d490c5a4dadd..cd3f337c4ab658e2194dc2ab8686eaaac2105eb7 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Node {
+use std::marker::MarkerTrait;
+
+trait Node : MarkerTrait {
     fn zomg();
 }
 
diff --git a/src/test/compile-fail/issue-14182.rs b/src/test/compile-fail/issue-14182.rs
deleted file mode 100644 (file)
index 364951a..0000000
+++ /dev/null
@@ -1,27 +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-test FIXME(japari) remove test
-
-struct Foo {
-    f: for <'b> |&'b isize|:
-      'b -> &'b isize //~ ERROR use of undeclared lifetime name `'b`
-}
-
-fn main() {
-    let mut x: Vec< for <'a> ||
-       :'a //~ ERROR use of undeclared lifetime name `'a`
-    > = Vec::new();
-    x.push(|| {});
-
-    let foo = Foo {
-        f: |x| x
-    };
-}
index cbf4412a81df286d23ef2da9f2bb817e797adc63..3a5df9e805bdb7e3c066ea9123f96fb55afca95f 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {}
+trait Foo {
+    fn dummy(&self) { }
+}
 
 struct A;
 
index 51deb99a4f2cda7747feae6e2df16f83c0f80e9e..0b846651acf46dbf0e51056e8d31742859ddeb4c 100644 (file)
@@ -9,8 +9,9 @@
 // except according to those terms.
 
 use std::fmt::Debug;
+use std::marker::MarkerTrait;
 
-trait Str {}
+trait Str : MarkerTrait {}
 
 trait Something {
     fn yay<T: Debug>(_: Option<Self>, thing: &[T]);
index 814b885e3aafc5c81f85e1b107076758fd50f19d..a213234b89b0ff247c73f9ac27cf1fc0dfce01d3 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait ListItem<'a> {
+use std::marker::MarkerTrait;
+
+trait ListItem<'a> : MarkerTrait {
     fn list_name() -> &'a str;
 }
 
diff --git a/src/test/compile-fail/issue-17383.rs b/src/test/compile-fail/issue-17383.rs
deleted file mode 100644 (file)
index c71e0ec..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.
-
-enum X {
-    A =
-        b'a' //~ ERROR discriminator values can only be used with a c-like enum
-    ,
-    B(isize)
-}
-
-fn main() {}
index 1e27f02556470cccff1e6e1d01b0f57ecfc5abc8..22aaa796ad0f4a0d62186527181140e6d98c7f60 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<T> { foo: Option<Option<Foo<T>>> }
+use std::marker;
+
+struct Foo<T> { foo: Option<Option<Foo<T>>>, marker: marker::PhantomData<T> }
 //~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
 
 impl<T> Foo<T> { fn bar(&self) {} }
index d22d79ecaa5508d87ffbda69f54d8d6fa7017d57..cc9cc2e3c035c7ae6e4adb14e7ad9be7bb08414d 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 struct Foo { foo: Bar<Foo> }
-struct Bar<T> { x: Bar<Foo> }
+struct Bar<T> { x: Bar<Foo> , marker: marker::PhantomData<T> }
 //~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
 
 impl Foo { fn foo(&self) {} }
index e037ba92b4a6a02e749552bfb6b37b559e06be1f..5781cb74117438b628b074ca5a8a5a428733957b 100644 (file)
 
 #![feature(unboxed_closures)]
 
-struct B<T>;
+use std::marker;
+
+struct B<T>(marker::PhantomData<T>);
 
 fn main() {
-    let foo = B; //~ ERROR: unable to infer enough type information
+    let foo = B(marker::PhantomData); //~ ERROR unable to infer enough type information
     let closure = || foo;
 }
diff --git a/src/test/compile-fail/issue-17718-const-mut.rs b/src/test/compile-fail/issue-17718-const-mut.rs
deleted file mode 100644 (file)
index 5177ebb..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.
-
-const
-mut //~ ERROR: const globals cannot be mutable
-//~^ HELP did you mean to declare a static?
-FOO: usize = 3;
-
-fn main() {
-}
-
diff --git a/src/test/compile-fail/issue-17904-2.rs b/src/test/compile-fail/issue-17904-2.rs
new file mode 100644 (file)
index 0000000..a33ec23
--- /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 can parse a unit struct with a where clause, even if
+// it leads to a error later on since `T` is unused.
+
+struct Foo<T> where T: Copy; //~ ERROR parameter `T` is never used
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-1802-2.rs b/src/test/compile-fail/issue-1802-2.rs
deleted file mode 100644 (file)
index f6da2fc..0000000
+++ /dev/null
@@ -1,14 +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.
-
-// error-pattern:no valid digits found for number
-fn main() {
-    log(error, 0b_usize);
-}
index 91689988f583ddc3337dfcb77f20133e60a12479..d5fb22bdebdb477d5c03cb68f3abdf80e40aaf01 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker::MarkerTrait;
 
-
-pub trait AbstractRenderer {}
+pub trait AbstractRenderer : MarkerTrait {}
 
 fn _create_render(_: &()) ->
     AbstractRenderer
index a662e9ca98ee812086e338e874234fd0a00a1f91..e81a576fa63d50d9267acf4e1eb82d70ba183fd0 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker::MarkerTrait;
+
 fn add_state(op: <isize as HasState>::State) {
 //~^ ERROR the trait `HasState` is not implemented for the type `isize`
 }
 
-trait HasState {
+trait HasState : MarkerTrait {
     type State;
 }
 
index 5ddf06add9d3e280656d55bf6bebc21b4069c9b2..13908bda9d83bf1e2d61f8d3304cc8144db12f97 100644 (file)
@@ -26,6 +26,7 @@ fn ufcs() {
 
     Push::push(&c, box || y = 0);
     Push::push(&c, box || y = 0);
+//~^ ERROR cannot borrow `y` as mutable more than once at a time
 }
 
 trait Push<'c> {
index 3a9de74104364156b4279f01008e421ff32ae11f..951d78410b814602391a7e0376bc1c20e83388c4 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait {
     type Item;
 }
 
index 14601e67a77c1c77a86391940ab74a47eb0e8820..77aba7335bdf996cc9165263e73c13d2073254cf 100644 (file)
 #![feature(lang_items, start, no_std)]
 #![no_std]
 
+#[lang="phantom_fn"]
+trait PhantomFn<A:?Sized,R:?Sized=()> { }
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
+
 #[lang = "sized"]
-trait Sized {}
+trait Sized : PhantomFn<Self> {}
 
 #[start]
 fn main(_: int, _: *const *const u8) -> int {
index 00607f850347cc54c5b1c201d5c098e375470506..aed395d17ea9ce803da2803395b76ec21549c098 100644 (file)
 // cause compiler to loop.  Note that no instances
 // of such a type could ever be constructed.
 
+use std::marker::MarkerTrait;
 
 struct t(Box<t>); //~ ERROR this type cannot be instantiated
 
-trait to_str_2 {
+trait to_str_2 : MarkerTrait {
     fn my_to_string() -> String;
 }
 
index aaf45f27398914cdc84574b3c91c73fbb0ec22ac..5b623ac377b21260948f9ddbbb34a95dab1998f5 100644 (file)
 // below. Note that changing to a named lifetime made the problem go
 // away.
 
-use std::ops::{Shl, Shr};
 use std::cell::RefCell;
+use std::marker::MarkerTrait;
+use std::ops::{Shl, Shr};
 
-pub trait Subscriber {
+pub trait Subscriber : MarkerTrait {
     type Input;
 }
 
index 45b7fbbd0b46a614b28d85b0292ea34911616d5e..557bf518a3cfbee46c02c4d65970a6c1df316a2f 100644 (file)
@@ -16,6 +16,6 @@ fn hash<T>(&self, _: T) {}
 
 #[derive(Hash)]
 struct Foo(Bar);
-//~^ error: the trait `core::hash::Hash<_>` is not implemented for the type `Bar`
+//~^ error: the trait `core::hash::Hash` is not implemented for the type `Bar`
 
 fn main() {}
index 31796e5e20c4492e683642701852db9bc439bfdf..24cc0099b89a522a1b7ae2441dabc6663ba3ce1d 100644 (file)
@@ -12,7 +12,7 @@
 // than the trait method it's implementing
 
 trait A {
-  fn b<C,D>(x: C) -> C;
+  fn b<C,D>(&self, x: C) -> C;
 }
 
 struct E {
@@ -20,7 +20,7 @@ struct E {
 }
 
 impl A for E {
-    fn b<F: Sync, G>(_x: F) -> F { panic!() }
+    fn b<F: Sync, G>(&self, _x: F) -> F { panic!() }
     //~^ ERROR `F : core::marker::Sync` appears on the impl method
 }
 
index a338a01690dea0d8f412bbab471ef2adbc243d3e..af6cee1f10749f4aeb366fdfb7f6f6a04fedaed4 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 enum E1 { V1(E2<E1>), }
-enum E2<T> { V2(E2<E1>), }
+enum E2<T> { V2(E2<E1>, marker::PhantomData<T>), }
 //~^ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable
 
 impl E1 { fn foo(&self) {} }
index 9a398796d2abf5cfb7dd7b5be7898ebe98839ebe..f384dba7c9e3d69d2738df91b8bd5809713edcf7 100644 (file)
@@ -11,7 +11,9 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 
-trait MyTrait { }
+trait MyTrait {
+    fn dummy(&self) {}
+}
 
 pub enum TraitWrapper {
     A(Box<MyTrait+'static>),
index 9e324cdd61eb0e82f40308131b51c72d1d1ce360..d316b44794ad6e38c1a6749aad984e84060b8ace 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait I {}
+use std::marker::MarkerTrait;
+
+trait I : MarkerTrait {}
 type K = I+'static;
 
 fn foo(_x: K) {} //~ ERROR: the trait `core::marker::Sized` is not implemented
index cf98f1572e56049aaa48ae32626acb14e482228a..4d721ad76666dab6c2482a1e207cb0ce31542522 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(box_syntax)]
 
-trait Foo {}
+trait Foo { fn foo(&self) {} }
 impl Foo for u8 {}
 
 fn main() {
diff --git a/src/test/compile-fail/issue-5544-a.rs b/src/test/compile-fail/issue-5544-a.rs
deleted file mode 100644 (file)
index 95a4f36..0000000
+++ /dev/null
@@ -1,14 +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 main() {
-    let __isize = 18446744073709551616; // 2^64
-    //~^ ERROR int literal is too large
-}
diff --git a/src/test/compile-fail/issue-5544-b.rs b/src/test/compile-fail/issue-5544-b.rs
deleted file mode 100644 (file)
index afff598..0000000
+++ /dev/null
@@ -1,14 +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 main() {
-    let __isize = 0xff_ffff_ffff_ffff_ffff__isize;
-    //~^ ERROR int literal is too large
-}
index 9ff957b6e6deac4904d0d5066390bd4dd53e2803..b0db990619535534dc4bf8b7c5baebef9bab6203 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait A {}
+use std::marker::MarkerTrait;
+
+trait A : MarkerTrait {}
 
 struct Struct {
     r: A+'static
@@ -20,6 +22,6 @@ fn new_struct(r: A+'static)
     Struct { r: r }
 }
 
-trait Curve {}
+trait Curve : MarkerTrait {}
 enum E {X(Curve+'static)}
 fn main() {}
index efa3100360b5c0e0c4c000ad09a1cd785ca22407..0bf9a3c2d4867e365bd57b9d560383f10c6d5406 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub struct TypeWithState<State>;
+use std::marker;
+
+pub struct TypeWithState<State>(marker::PhantomData<State>);
 pub struct MyState;
 
 pub fn foo<State>(_: TypeWithState<State>) {}
 
 pub fn bar() {
-   foo(TypeWithState);  //~ ERROR type annotations required
+   foo(TypeWithState(marker::PhantomData));  //~ ERROR type annotations required
 }
 
 fn main() {
index 9e6000c050a5145d89094f38ddf1bfd6a74374bc..b6643f439529b2a76c6b62a73ea4676dce30dc17 100644 (file)
 
 // Test the mechanism for warning about possible missing `self` declarations.
 
+use std::marker::MarkerTrait;
+
 trait CtxtFn {
     fn f8(self, usize) -> usize;
     fn f9(usize) -> usize; //~ NOTE candidate
 }
 
-trait OtherTrait {
+trait OtherTrait : MarkerTrait {
     fn f9(usize) -> usize; //~ NOTE candidate
 }
 
@@ -24,7 +26,7 @@ trait OtherTrait {
 // declaration to match against, so we wind up prisizeing it as a
 // candidate. This seems not unreasonable -- perhaps the user meant to
 // implement it, after all.
-trait UnusedTrait {
+trait UnusedTrait : MarkerTrait {
     fn f9(usize) -> usize; //~ NOTE candidate
 }
 
@@ -52,7 +54,7 @@ fn fff(i: isize) -> isize { //~ NOTE candidate
     }
 }
 
-trait ManyImplTrait {
+trait ManyImplTrait : MarkerTrait {
     fn is_str() -> bool { //~ NOTE candidate
         false
     }
diff --git a/src/test/compile-fail/issue-8537.rs b/src/test/compile-fail/issue-8537.rs
deleted file mode 100644 (file)
index 52cf420..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.
-
-pub extern
-  "invalid-ab_isize" //~ ERROR illegal ABI
-fn foo() {}
-
-fn main() {}
index d1a86d334cb44e631c7705f20fb61a0cf8570878..72da6dcaa6c45a22e76a62a97282c958d6273838 100644 (file)
 // Verify the compiler fails with an error on infinite function
 // recursions.
 
-struct Data(Box<Option<Data>>);
-
-fn generic<T>( _ : Vec<(Data,T)> ) {
-    let rec : Vec<(Data,(bool,T))> = Vec::new();
-    generic( rec );
+fn generic<T>() {
+    generic::<Option<T>>();
 }
 
 
 fn main () {
     // Use generic<T> at least once to trigger instantiation.
-    let input : Vec<(Data,())> = Vec::new();
-    generic(input);
+    generic::<i32>();
 }
diff --git a/src/test/compile-fail/keyword-as-as-identifier.rs b/src/test/compile-fail/keyword-as-as-identifier.rs
deleted file mode 100644 (file)
index f307b12..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py as'
-
-fn main() {
-    let as = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-break-as-identifier.rs b/src/test/compile-fail/keyword-break-as-identifier.rs
deleted file mode 100644 (file)
index 1e2725e..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py break'
-
-fn main() {
-    let break = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-else-as-identifier.rs b/src/test/compile-fail/keyword-else-as-identifier.rs
deleted file mode 100644 (file)
index 101fd93..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py else'
-
-fn main() {
-    let else = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-enum-as-identifier.rs b/src/test/compile-fail/keyword-enum-as-identifier.rs
deleted file mode 100644 (file)
index ed504cc..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py enum'
-
-fn main() {
-    let enum = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-extern-as-identifier.rs b/src/test/compile-fail/keyword-extern-as-identifier.rs
deleted file mode 100644 (file)
index 3260506..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py extern'
-
-fn main() {
-    let extern = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-fn-as-identifier.rs b/src/test/compile-fail/keyword-fn-as-identifier.rs
deleted file mode 100644 (file)
index 8c98da2..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py fn'
-
-fn main() {
-    let fn = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-for-as-identifier.rs b/src/test/compile-fail/keyword-for-as-identifier.rs
deleted file mode 100644 (file)
index 196a339..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py for'
-
-fn main() {
-    let for = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-if-as-identifier.rs b/src/test/compile-fail/keyword-if-as-identifier.rs
deleted file mode 100644 (file)
index 05f82ec..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py if'
-
-fn main() {
-    let if = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-impl-as-identifier.rs b/src/test/compile-fail/keyword-impl-as-identifier.rs
deleted file mode 100644 (file)
index 1dd2180..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py impl'
-
-fn main() {
-    let impl = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-let-as-identifier.rs b/src/test/compile-fail/keyword-let-as-identifier.rs
deleted file mode 100644 (file)
index 0069a26..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py let'
-
-fn main() {
-    let let = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-loop-as-identifier.rs b/src/test/compile-fail/keyword-loop-as-identifier.rs
deleted file mode 100644 (file)
index 6e469e8..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py loop'
-
-fn main() {
-    let loop = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-match-as-identifier.rs b/src/test/compile-fail/keyword-match-as-identifier.rs
deleted file mode 100644 (file)
index 9155ebc..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py match'
-
-fn main() {
-    let match = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-mod-as-identifier.rs b/src/test/compile-fail/keyword-mod-as-identifier.rs
deleted file mode 100644 (file)
index 02f57e9..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py mod'
-
-fn main() {
-    let mod = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-pub-as-identifier.rs b/src/test/compile-fail/keyword-pub-as-identifier.rs
deleted file mode 100644 (file)
index aa67974..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py pub'
-
-fn main() {
-    let pub = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-return-as-identifier.rs b/src/test/compile-fail/keyword-return-as-identifier.rs
deleted file mode 100644 (file)
index c567644..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py return'
-
-fn main() {
-    let return = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-self-as-identifier.rs b/src/test/compile-fail/keyword-self-as-identifier.rs
deleted file mode 100644 (file)
index 8bb5214..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py self'
-
-fn main() {
-    let self = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-static-as-identifier.rs b/src/test/compile-fail/keyword-static-as-identifier.rs
deleted file mode 100644 (file)
index 7268c4f..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py static'
-
-fn main() {
-    let static = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-struct-as-identifier.rs b/src/test/compile-fail/keyword-struct-as-identifier.rs
deleted file mode 100644 (file)
index bd42eac..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py struct'
-
-fn main() {
-    let struct = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-super-as-identifier.rs b/src/test/compile-fail/keyword-super-as-identifier.rs
deleted file mode 100644 (file)
index 0378c32..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py super'
-
-fn main() {
-    let super = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-super.rs b/src/test/compile-fail/keyword-super.rs
deleted file mode 100644 (file)
index 0c94f76..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.
-
-fn main() {
-    let super: isize; //~ ERROR expected identifier, found keyword `super`
-}
diff --git a/src/test/compile-fail/keyword-trait-as-identifier.rs b/src/test/compile-fail/keyword-trait-as-identifier.rs
deleted file mode 100644 (file)
index 95c0d17..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py trait'
-
-fn main() {
-    let trait = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-type-as-identifier.rs b/src/test/compile-fail/keyword-type-as-identifier.rs
deleted file mode 100644 (file)
index 0aaa2a6..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py type'
-
-fn main() {
-    let type = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-unsafe-as-identifier.rs b/src/test/compile-fail/keyword-unsafe-as-identifier.rs
deleted file mode 100644 (file)
index 1b631eb..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py unsafe'
-
-fn main() {
-    let unsafe = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-use-as-identifier.rs b/src/test/compile-fail/keyword-use-as-identifier.rs
deleted file mode 100644 (file)
index e82afd5..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py use'
-
-fn main() {
-    let use = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-while-as-identifier.rs b/src/test/compile-fail/keyword-while-as-identifier.rs
deleted file mode 100644 (file)
index 95cea65..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py while'
-
-fn main() {
-    let while = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword.rs b/src/test/compile-fail/keyword.rs
deleted file mode 100644 (file)
index 64eac47..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.
-
-pub mod break {
-    //~^ ERROR expected identifier, found keyword `break`
-}
diff --git a/src/test/compile-fail/keywords-followed-by-double-colon.rs b/src/test/compile-fail/keywords-followed-by-double-colon.rs
deleted file mode 100644 (file)
index f69b041..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.
-
-fn main() {
-    struct::foo();  //~ ERROR expected identifier
-    mut::baz(); //~ ERROR expected identifier
-}
-
index 56f83d9300861b353d2a0dd61196e0eebf8ce847..74e372e41eb0a1100821ef7fcaa9667a66932971 100644 (file)
 
 // Test which of the builtin types are considered POD.
 
-
+use std::marker::MarkerTrait;
 use std::rc::Rc;
 
 fn assert_copy<T:Copy>() { }
 
-trait Dummy { }
+trait Dummy : MarkerTrait { }
 
 #[derive(Copy)]
 struct MyStruct {
index 2731be7308a4a54de5ca5b38ec81be06dc219cbb..b575144f637f1e73629df653cb0ae1ea8a3974c2 100644 (file)
@@ -10,7 +10,9 @@
 
 #![feature(box_syntax)]
 
-trait Foo {
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait {
 }
 
 impl<T:Copy> Foo for T {
index d5276efa8be9812649f978f8ee7da58e6238faa3..dffc8fa2abd70d95def12e4df2eb40fdf247cea3 100644 (file)
 
 #![feature(box_syntax)]
 
-struct S<T>;
+use std::marker;
 
-trait Gettable<T> {}
+struct S<T>(marker::PhantomData<T>);
+
+trait Gettable<T> {
+    fn get(&self) -> T { panic!() }
+}
 
 impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
 
 fn f<T>(val: T) {
-    let t: S<T> = S;
+    let t: S<T> = S(marker::PhantomData);
     let a = &t as &Gettable<T>;
     //~^ ERROR the trait `core::marker::Send` is not implemented
     //~^^ ERROR the trait `core::marker::Copy` is not implemented
 }
 
 fn g<T>(val: T) {
-    let t: S<T> = S;
+    let t: S<T> = S(marker::PhantomData);
     let a: &Gettable<T> = &t;
     //~^ ERROR the trait `core::marker::Send` is not implemented
     //~^^ ERROR the trait `core::marker::Copy` is not implemented
 }
 
 fn foo<'a>() {
-    let t: S<&'a isize> = S;
+    let t: S<&'a isize> = S(marker::PhantomData);
     let a = &t as &Gettable<&'a isize>;
-    //~^ ERROR the type `&'a isize` does not fulfill the required lifetime
+    //~^ ERROR cannot infer
 }
 
 fn foo2<'a>() {
-    let t: Box<S<String>> = box S;
+    let t: Box<S<String>> = box S(marker::PhantomData);
     let a = t as Box<Gettable<String>>;
     //~^ ERROR the trait `core::marker::Copy` is not implemented
 }
 
 fn foo3<'a>() {
-    let t: Box<S<String>> = box S;
+    let t: Box<S<String>> = box S(marker::PhantomData);
     let a: Box<Gettable<String>> = t;
     //~^ ERROR the trait `core::marker::Copy` is not implemented
 }
index e146cac21a31c46692fb5c8ab48ad19e843c615d..0072b1228af486d49b47c8e20f3c41c8dd8b83bc 100644 (file)
@@ -15,6 +15,7 @@
 use std::any::Any;
 
 trait Foo : Copy {
+    fn foo(&self) {}
 }
 
 impl<T:Copy> Foo for T {
index 570f7ad7fe3bf214adae00a7ac6644053305dd6c..0c68401bb2b955222bbd712a92ee02f8603ae50e 100644 (file)
 // in this file all test the "kind" violates detected during kindck.
 // See all `regions-bounded-by-send.rs`
 
+use std::marker::MarkerTrait;
+
 fn assert_send<T:Send>() { }
-trait Dummy { }
+trait Dummy : MarkerTrait { }
 trait Message : Send { }
 
 // careful with object types, who knows what they close over...
index 48d5215b7085be78f389d72df0139f2efa25130e..f86eac8b16bd2bcfdb158fbb58315b6dd1d4c2d8 100644 (file)
 // is broken into two parts because some errors occur in distinct
 // phases in the compiler. See kindck-send-object2.rs as well!
 
+use std::marker::MarkerTrait;
+
 fn assert_send<T:Send+'static>() { }
-trait Dummy { }
+trait Dummy : MarkerTrait { }
 
 // careful with object types, who knows what they close over...
 fn test51<'a>() {
index d3d166e2a6916181d24c32984ed212bca92a07e6..08516e67318ce2b5ff0e31efd4a9ef16a0eb8445 100644 (file)
 
 // Continue kindck-send-object1.rs.
 
+use std::marker::MarkerTrait;
+
 fn assert_send<T:Send>() { }
-trait Dummy { }
+trait Dummy : MarkerTrait { }
 
 fn test50() {
     assert_send::<&'static Dummy>(); //~ ERROR the trait `core::marker::Sync` is not implemented
diff --git a/src/test/compile-fail/lex-bad-numeric-literals.rs b/src/test/compile-fail/lex-bad-numeric-literals.rs
deleted file mode 100644 (file)
index 9a490be..0000000
+++ /dev/null
@@ -1,35 +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.
-
-fn main() {
-    0o1.0; //~ ERROR: octal float literal is not supported
-    0o2f32; //~ ERROR: octal float literal is not supported
-    0o3.0f32; //~ ERROR: octal float literal is not supported
-    0o4e4; //~ ERROR: octal float literal is not supported
-    0o5.0e5; //~ ERROR: octal float literal is not supported
-    0o6e6f32; //~ ERROR: octal float literal is not supported
-    0o7.0e7f64; //~ ERROR: octal float literal is not supported
-    0x8.0e+9; //~ ERROR: hexadecimal float literal is not supported
-    0x9.0e-9; //~ ERROR: hexadecimal float literal is not supported
-    0o; //~ ERROR: no valid digits
-    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
-    0x; //~ ERROR: no valid digits
-    0xu32; //~ ERROR: no valid digits
-    0ou32; //~ ERROR: no valid digits
-    0bu32; //~ ERROR: no valid digits
-    0b; //~ ERROR: no valid digits
-    0o123f64; //~ ERROR: octal float literal is not supported
-    0o123.456; //~ ERROR: octal float literal is not supported
-    0b101f64; //~ ERROR: binary float literal is not supported
-    0b111.101; //~ ERROR: binary float literal is not supported
-}
diff --git a/src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs b/src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs
deleted file mode 100644 (file)
index c1e5121..0000000
+++ /dev/null
@@ -1,30 +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-tidy-cr
-
-/// doc comment with bare CR: '\r'
-pub fn foo() {}
-//~^^ ERROR: bare CR not allowed in doc-comment
-
-/** block doc comment with bare CR: '\r' */
-pub fn bar() {}
-//~^^ ERROR: bare CR not allowed in block doc-comment
-
-fn main() {
-    // the following string literal has a bare CR in it
-    let _s = "foo\rbar"; //~ ERROR: bare CR not allowed in string
-
-    // the following string literal has a bare CR in it
-    let _s = r"bar\rfoo"; //~ ERROR: bare CR not allowed in raw string
-
-    // the following string literal has a bare CR in it
-    let _s = "foo\\rbar"; //~ ERROR: unknown character escape: \r
-}
index 04c5b223cb875a76fa10771a7c1cce51999fb032..66d8927ee51b7096b6cfa3826d1b6202dfe6b723 100644 (file)
@@ -10,7 +10,9 @@
 
 // ignore-tidy-linelength
 
-struct Bar<'x, 'y, 'z> { bar: &'y i32, baz: i32 }
+use std::marker::PhantomData;
+
+struct Bar<'x, 'y, 'z> { bar: &'y i32, baz: i32, marker: PhantomData<(&'x(),&'y(),&'z())> }
 fn bar1<'a>(x: &Bar) -> (&'a i32, &'a i32, &'a i32) {
 //~^ HELP: consider using an explicit lifetime parameter as shown: fn bar1<'b, 'c, 'a>(x: &'a Bar<'b, 'a, 'c>) -> (&'a i32, &'a i32, &'a i32)
     (x.bar, &x.baz, &x.baz)
index c60e321219bd266884261ff5034d01d6bd03d90c..a85776a938b44f189ab62db91ba6c9980175899d 100644 (file)
@@ -10,7 +10,9 @@
 
 // ignore-tidy-linelength
 
-struct Foo<'x> { bar: isize }
+use std::marker::PhantomData;
+
+struct Foo<'x> { bar: isize, marker: PhantomData<&'x ()> }
 fn foo1<'a>(x: &Foo) -> &'a isize {
 //~^ HELP: consider using an explicit lifetime parameter as shown: fn foo1<'a>(x: &'a Foo) -> &'a isize
     &x.bar //~ ERROR: cannot infer
diff --git a/src/test/compile-fail/lifetime-no-keyword.rs b/src/test/compile-fail/lifetime-no-keyword.rs
deleted file mode 100644 (file)
index 8ffbcd9..0000000
+++ /dev/null
@@ -1,15 +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<'a>(a: &'a isize) { }
-fn bar(a: &'static isize) { }
-fn baz(a: &'let isize) { } //~ ERROR invalid lifetime name
-
-fn main() { }
diff --git a/src/test/compile-fail/lifetime-obsoleted-self.rs b/src/test/compile-fail/lifetime-obsoleted-self.rs
deleted file mode 100644 (file)
index 766922f..0000000
+++ /dev/null
@@ -1,13 +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 baz(a: &'self isize) { } //~ ERROR invalid lifetime name: 'self is no longer a special lifetime
-
-fn main() { }
index 3b96fd64fa200e8f3d397bd69e6283a4f066fdfc..73a58741bbbbc42ddbcf7efa384d9d578f86fed4 100644 (file)
@@ -47,20 +47,26 @@ fn foo3() {}
 /// dox
 pub trait A {
     /// dox
-    fn foo();
+    fn foo(&self);
     /// dox
-    fn foo_with_impl() {}
+    fn foo_with_impl(&self) {}
 }
+
 #[allow(missing_docs)]
 trait B {
-    fn foo();
-    fn foo_with_impl() {}
+    fn foo(&self);
+    fn foo_with_impl(&self) {}
 }
+
 pub trait C { //~ ERROR: missing documentation
-    fn foo(); //~ ERROR: missing documentation
-    fn foo_with_impl() {} //~ ERROR: missing documentation
+    fn foo(&self); //~ ERROR: missing documentation
+    fn foo_with_impl(&self) {} //~ ERROR: missing documentation
+}
+
+#[allow(missing_docs)]
+pub trait D {
+    fn dummy(&self) { }
 }
-#[allow(missing_docs)] pub trait D {}
 
 impl Foo {
     pub fn foo() {}
index 70d6b240985b041d739ec542b2be5d30ba04a80b..9f58d5791cb0bcbb07e14ad3ad0a2c1c93cc87e8 100644 (file)
@@ -30,6 +30,7 @@ enum Foo5 {
 }
 
 trait foo6 { //~ ERROR trait `foo6` should have a camel case name such as `Foo6`
+    fn dummy(&self) { }
 }
 
 fn f<ty>(_: ty) {} //~ ERROR type parameter `ty` should have a camel case name such as `Ty`
index f9cdfa4f7d685356f7b7d14f17494f796c7ca26b..88f2cbdea6d7bf81332f15efb3caf5e1dc4e6d47 100644 (file)
@@ -341,7 +341,9 @@ fn fn_in_body() {}
 
     #[unstable(feature = "test_feature")]
     #[deprecated(since = "1.0.0")]
-    pub trait DeprecatedTrait {}
+    pub trait DeprecatedTrait {
+        fn dummy(&self) { }
+    }
 
     struct S;
 
index 8cf375f80fbb1c092cf9ea06dea733257f120e15..918b4ee209ca7ac6106a3fcd18d3b7d17e7185ea 100644 (file)
 #![allow(dead_code)]
 #![crate_type="lib"]
 
-struct Private<T>;
-pub struct Public<T>;
+use std::marker;
+
+struct Private<T>(marker::PhantomData<T>);
+pub struct Public<T>(marker::PhantomData<T>);
 
 impl Private<Public<isize>> {
     pub fn a(&self) -> Private<isize> { panic!() }
@@ -103,7 +105,7 @@ impl PrivTrait for (Private<isize>,) {
     fn bar(&self) -> Private<isize> { panic!() }
 }
 
-pub trait ParamTrait<T> {
+pub trait ParamTrait<T> : marker::MarkerTrait {
     fn foo() -> T;
 }
 
index a49339ecd7f2811e169e2316856af749a233b84c..03d8d62e0b4d5c24aae817a0b9691dfb62b22de1 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 fn send<T:Send + std::fmt::Debug>(ch: _chan<T>, data: T) {
     println!("{:?}", ch);
     println!("{:?}", data);
@@ -15,7 +17,7 @@ fn send<T:Send + std::fmt::Debug>(ch: _chan<T>, data: T) {
 }
 
 #[derive(Debug)]
-struct _chan<T>(isize);
+struct _chan<T>(isize, marker::PhantomData<T>);
 
 // Tests that "log(debug, message);" is flagged as using
 // message after the send deinitializes it
diff --git a/src/test/compile-fail/macros-no-semicolon-items.rs b/src/test/compile-fail/macros-no-semicolon-items.rs
deleted file mode 100644 (file)
index 3142920..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.
-
-macro_rules! foo()  //~ ERROR semicolon
-
-fn main() {
-}
index ba2205f5868d4ccb22f09b8addaba1e9845110b6..6e8719eeaceda58e6ffce825b5805468cdc8f542 100644 (file)
 
 use std::collections::HashMap;
 
-trait Map<K, V> {}
+trait Map<K, V>
+{
+    fn get(&self, k: K) -> V { panic!() }
+}
 
 impl<K, V> Map<K, V> for HashMap<K, V> {}
 
diff --git a/src/test/compile-fail/method-ambig-one-trait-coerce.rs b/src/test/compile-fail/method-ambig-one-trait-coerce.rs
deleted file mode 100644 (file)
index cb5da4b..0000000
+++ /dev/null
@@ -1,50 +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.
-
-// Test that when we pick a trait based on coercion, versus subtyping,
-// we consider all possible coercions equivalent and don't try to pick
-// a best one.
-
-trait Object { }
-
-trait foo {
-    fn foo(self) -> isize;
-}
-
-impl foo for Box<Object+'static> {
-    fn foo(self) -> isize {1}
-}
-
-impl foo for Box<Object+Send> {
-    fn foo(self) -> isize {2}
-}
-
-fn test1(x: Box<Object+Send+Sync>) {
-    // FIXME(#18737) -- we ought to consider this to be ambiguous,
-    // since we could coerce to either impl. However, what actually
-    // happens is that we consider both impls applicable because of
-    // incorrect subtyping relation. We then decide to call this a
-    // call to the `foo` trait, leading to the following error
-    // message.
-
-    x.foo(); //~ ERROR `foo` is not implemented
-}
-
-fn test2(x: Box<Object+Send>) {
-    // Not ambiguous because it is a precise match:
-    x.foo();
-}
-
-fn test3(x: Box<Object+'static>) {
-    // Not ambiguous because it is a precise match:
-    x.foo();
-}
-
-fn main() { }
diff --git a/src/test/compile-fail/mod_file_disambig.rs b/src/test/compile-fail/mod_file_disambig.rs
new file mode 100644 (file)
index 0000000..48bd00a
--- /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 mod_file_disambig_aux; //~ ERROR file for module `mod_file_disambig_aux` found at both
+
+fn main() {
+    assert_eq!(mod_file_aux::bar(), 10);
+}
diff --git a/src/test/compile-fail/mod_file_not_owning.rs b/src/test/compile-fail/mod_file_not_owning.rs
new file mode 100644 (file)
index 0000000..adbcedd
--- /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.
+
+// error-pattern: cannot declare a new module at this location
+
+mod mod_file_not_owning_aux1;
+
+fn main() {}
diff --git a/src/test/compile-fail/no-binary-float-literal.rs b/src/test/compile-fail/no-binary-float-literal.rs
deleted file mode 100644 (file)
index 2e207f9..0000000
+++ /dev/null
@@ -1,17 +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.
-
-// error-pattern:binary float literal is not supported
-
-fn main() {
-    0b101010f64;
-    0b101.010;
-    0b101p4f64;
-}
diff --git a/src/test/compile-fail/no-hex-float-literal.rs b/src/test/compile-fail/no-hex-float-literal.rs
deleted file mode 100644 (file)
index 4abb609..0000000
+++ /dev/null
@@ -1,17 +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.
-
-// error-pattern:hexadecimal float literal is not supported
-
-fn main() {
-    0xABC.Df;
-    0x567.89;
-    0xDEAD.BEEFp-2f;
-}
diff --git a/src/test/compile-fail/no-unsafe-self.rs b/src/test/compile-fail/no-unsafe-self.rs
deleted file mode 100644 (file)
index 0bf73bb..0000000
+++ /dev/null
@@ -1,22 +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.
-
-trait A {
-    fn foo(*mut self); //~ ERROR cannot pass self by unsafe pointer
-    fn bar(*self); //~ ERROR cannot pass self by unsafe pointer
-}
-
-struct X;
-impl A for X {
-    fn foo(*mut self) { } //~ ERROR cannot pass self by unsafe pointer
-    fn bar(*self) { } //~ ERROR cannot pass self by unsafe pointer
-}
-
-fn main() { }
diff --git a/src/test/compile-fail/non-str-meta.rs b/src/test/compile-fail/non-str-meta.rs
deleted file mode 100644 (file)
index 752f72f..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.
-
-// Issue #623 - non-string meta items are not serialized correctly;
-// for now just forbid them
-
-#[foo = 1] //~ ERROR: non-string literals are not allowed in meta-items
-fn main() { }
index cfaf149a49cac6f4d4d2b2f45897e4d63688dd0a..607ab13d122015d6f8ff42e92c56a5a3d5ed8062 100644 (file)
@@ -11,8 +11,9 @@
 // Test that an object type `Box<Foo>` is not considered to implement the
 // trait `Foo`. Issue #5087.
 
+use std::marker::MarkerTrait;
 
-trait Foo {}
+trait Foo : MarkerTrait {}
 fn take_foo<F:Foo>(f: F) {}
 fn take_object(f: Box<Foo>) { take_foo(f); }
 //~^ ERROR the trait `Foo` is not implemented
index c107c8d131d3a8f01672639bbfda0d7f810d0636..23ddea4499a728c51b1fa08bb416cb6a0de71b2c 100644 (file)
@@ -37,7 +37,6 @@ fn load1<'a,'b>(a: &'a MyBox<SomeTrait>,
     a
       //~^ ERROR cannot infer
       //~| ERROR mismatched types
-      //~| ERROR mismatched types
 }
 
 fn main() {
diff --git a/src/test/compile-fail/object-safety-issue-22040.rs b/src/test/compile-fail/object-safety-issue-22040.rs
new file mode 100644 (file)
index 0000000..edf3213
--- /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.
+
+// Regression test for #22040.
+
+use std::fmt::Debug;
+
+trait Expr: Debug + PartialEq {
+    fn print_element_count(&self);
+}
+
+//#[derive(PartialEq)]
+#[derive(Debug)]
+struct SExpr<'x> {
+    elements: Vec<Box<Expr+ 'x>>,
+}
+
+impl<'x> PartialEq for SExpr<'x> {
+    fn eq(&self, other:&SExpr<'x>) -> bool {
+        println!("L1: {} L2: {}", self.elements.len(), other.elements.len());
+        let result = self.elements.len() == other.elements.len();
+
+        println!("Got compare {}", result);
+        return result;
+    }
+}
+
+impl <'x> SExpr<'x> {
+    fn new() -> SExpr<'x> { return SExpr{elements: Vec::new(),}; }
+}
+
+impl <'x> Expr for SExpr<'x> {
+    fn print_element_count(&self) {
+        println!("element count: {}", self.elements.len());
+    }
+}
+
+fn main() {
+    let a: Box<Expr> = Box::new(SExpr::new()); //~ ERROR trait `Expr` is not object-safe
+    let b: Box<Expr> = Box::new(SExpr::new()); //~ ERROR trait `Expr` is not object-safe
+
+    assert_eq!(a , b);
+}
index 6a010d49692d26450a4d95225eb3695c4509b0cd..aae829ec7b5636c124b55bd953b59f78cbcff1fe 100644 (file)
@@ -11,7 +11,7 @@
 // Check that we correctly prevent users from making trait objects
 // from traits with static methods.
 
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
     fn foo();
 }
 
diff --git a/src/test/compile-fail/object-safety-phantom-fn.rs b/src/test/compile-fail/object-safety-phantom-fn.rs
new file mode 100644 (file)
index 0000000..1c95ee4
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Check that `Self` appearing in a phantom fn does not make a trait not object safe.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+use std::marker::PhantomFn;
+
+trait Baz : PhantomFn<Self> {
+}
+
+trait Bar<T> : PhantomFn<(Self, T)> {
+}
+
+fn make_bar<T:Bar<u32>>(t: &T) -> &Bar<u32> {
+    t
+}
+
+fn make_baz<T:Baz>(t: &T) -> &Baz {
+    t
+}
+
+#[rustc_error]
+fn main() { //~ ERROR compilation successful
+}
diff --git a/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs b/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs
new file mode 100644 (file)
index 0000000..d3f9dc7
--- /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.
+
+// Check that we correctly prevent users from making trait objects
+// form traits that make use of `Self` in an argument or return position.
+
+trait Bar<T> {
+    fn bar(&self, x: &T);
+}
+
+trait Baz : Bar<Self> {
+}
+
+fn make_bar<T:Bar<u32>>(t: &T) -> &Bar<u32> {
+    t
+}
+
+fn make_baz<T:Baz>(t: &T) -> &Baz {
+    t
+        //~^ ERROR `Baz` is not object-safe
+        //~| NOTE the trait cannot use `Self` as a type parameter in the supertrait listing
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/obsolete-for-sized.rs b/src/test/compile-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() { }
diff --git a/src/test/compile-fail/obsolete-proc.rs b/src/test/compile-fail/obsolete-proc.rs
deleted file mode 100644 (file)
index 5208cdb..0000000
+++ /dev/null
@@ -1,17 +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 we generate obsolete syntax errors around usages of `proc`.
-
-fn foo(p: proc()) { } //~ ERROR obsolete syntax: the `proc` type
-
-fn bar() { proc() 1; } //~ ERROR obsolete syntax: `proc` expression
-
-fn main() { }
index dda534cc489b522e12db13c208f11545abc0fc5c..7538b1c85e533fe610462dbf172433b8ef90442d 100644 (file)
 
 #![allow(unused)]
 
+use std::marker;
+
 #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"]
-trait Foo<Bar, Baz, Quux>{}
+trait Foo<Bar, Baz, Quux>
+    : marker::PhantomFn<(Self,Bar,Baz,Quux)>
+{}
 
 #[rustc_on_unimplemented="a collection of type `{Self}` cannot be built from an iterator over elements of type `{A}`"]
 trait MyFromIterator<A> {
@@ -23,15 +27,21 @@ trait MyFromIterator<A> {
 }
 
 #[rustc_on_unimplemented] //~ ERROR this attribute must have a value
-trait BadAnnotation1 {}
+trait BadAnnotation1
+    : marker::MarkerTrait
+{}
 
 #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
 //~^ ERROR there is no type parameter C on trait BadAnnotation2
-trait BadAnnotation2<A,B> {}
+trait BadAnnotation2<A,B>
+    : marker::PhantomFn<(Self,A,B)>
+{}
 
 #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"]
 //~^ only named substitution parameters are allowed
-trait BadAnnotation3<A,B> {}
+trait BadAnnotation3<A,B>
+    : marker::PhantomFn<(Self,A,B)>
+{}
 
 pub fn main() {
 }
index 7b406afcf1f5832dcd79890388076ff26b09da29..2447d0864226aee75dd0decae2bf692b5032104e 100644 (file)
 
 #![feature(on_unimplemented)]
 
+use std::marker;
+
 #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"]
-trait Foo<Bar, Baz, Quux>{}
+trait Foo<Bar, Baz, Quux>
+    : marker::PhantomFn<(Self,Bar,Baz,Quux)>
+{}
 
 fn foobar<U: Clone, T: Foo<u8, U, u32>>() -> T {
 
index ff5c101b9178f60a5998d9e0fffb0142017fb1a9..8201565c3318dce282c41bbb57dcc458f34836b9 100644 (file)
@@ -15,7 +15,7 @@
 
 use orphan_check_diagnostics::RemoteTrait;
 
-trait LocalTrait {}
+trait LocalTrait { fn dummy(&self) { } }
 
 impl<T> RemoteTrait for T where T: LocalTrait {}
 //~^ ERROR type parameter `T` must be used as the type parameter for some local type
index db649ed0cc60632cbbbe59f49b624ed56b3d5b43..43d112b8aa0043aee7937ee05d0ecebc23d185e3 100644 (file)
@@ -14,7 +14,7 @@
 }
 
 trait A {
-    fn foo() {}
+    fn foo(&self) {}
 }
 
 struct B;
@@ -22,7 +22,7 @@ fn foo() {}
 pub impl B {} //~ ERROR: unnecessary visibility
 
 pub impl A for B { //~ ERROR: unnecessary visibility
-    pub fn foo() {} //~ ERROR: unnecessary visibility
+    pub fn foo(&self) {} //~ ERROR: unnecessary visibility
 }
 
 pub fn main() {}
index 7fe0574ab7d9a663902dd9433fcc6a01145f3b4c..67bb566ea682c07b1568202a6c213156d3a92d46 100644 (file)
@@ -17,7 +17,9 @@
 
 // public type, private value
 pub mod foo1 {
-    pub trait Bar {
+    use std::marker::MarkerTrait;
+
+    pub trait Bar : MarkerTrait {
     }
     pub struct Baz;
 
@@ -39,7 +41,7 @@ fn test_list1() {
 
 // private type, public value
 pub mod foo2 {
-    trait Bar {
+    trait Bar : ::std::marker::MarkerTrait {
     }
     pub struct Baz;
 
@@ -60,7 +62,7 @@ fn test_list2() {
 
 // neither public
 pub mod foo3 {
-    trait Bar {
+    trait Bar : ::std::marker::MarkerTrait {
     }
     pub struct Baz;
 
index 7ebbcc2809a5802a42cfc4d598ed1171c2038703..1ae79adbad76ae953da4cf7aa0045da158c03de5 100644 (file)
 #![feature(lang_items, start, no_std)]
 #![no_std] // makes debugging this test *a lot* easier (during resolve)
 
+#[lang="phantom_fn"]
+pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
+
 #[lang="sized"]
-pub trait Sized {}
+pub trait Sized : PhantomFn<Self> {}
 
 #[lang="copy"]
-pub trait Copy {}
+pub trait Copy : PhantomFn<Self> {}
 
 mod bar {
     // shouldn't bring in too much
index bcb46663aa849da96e36e45d9275453948cdbff0..adce93af0794f9a0f5d8cf0eae6aa95f6ec5f467 100644 (file)
 #![feature(lang_items, start, no_std)]
 #![no_std] // makes debugging this test *a lot* easier (during resolve)
 
-#[lang = "sized"] pub trait Sized {}
-#[lang="copy"] pub trait Copy {}
+#[lang="phantom_fn"]
+pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
+
+#[lang = "sized"] pub trait Sized : PhantomFn<Self> {}
+#[lang="copy"] pub trait Copy : PhantomFn<Self> {}
 
 // Test to make sure that private items imported through globs remain private
 // when  they're used.
diff --git a/src/test/compile-fail/qquote-1.rs b/src/test/compile-fail/qquote-1.rs
deleted file mode 100644 (file)
index deae9a8..0000000
+++ /dev/null
@@ -1,68 +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.
-
-// ignore-test Can't use syntax crate here
-
-#![feature(quote)]
-
-extern crate syntax;
-
-use io::*;
-
-use syntax::diagnostic;
-use syntax::ast;
-use syntax::codemap;
-use syntax::parse;
-use syntax::print::*;
-
-
-trait fake_ext_ctxt {
-    fn cfg() -> ast::CrateConfig;
-    fn parse_sess() -> parse::parse_sess;
-    fn call_site() -> span;
-    fn ident_of(st: &str) -> ast::ident;
-}
-
-type fake_session = parse::parse_sess;
-
-impl fake_ext_ctxt for fake_session {
-    fn cfg() -> ast::CrateConfig { Vec::new() }
-    fn parse_sess() -> parse::parse_sess { self }
-    fn call_site() -> span {
-        codemap::span {
-            lo: codemap::BytePos(0),
-            hi: codemap::BytePos(0),
-            expn_id: NO_EXPANSION
-        }
-    }
-    fn ident_of(st: &str) -> ast::ident {
-        self.interner.intern(st)
-    }
-}
-
-fn mk_ctxt() -> fake_ext_ctxt {
-    parse::new_parse_sess(None) as fake_ext_ctxt
-}
-
-
-
-fn main() {
-    let cx = mk_ctxt();
-
-    let abc = quote_expr!(cx, 23);
-    check_pp(abc,  pprust::print_expr, "23");
-
-    let expr3 = quote_expr!(cx, 2 - $abcd + 7); //~ ERROR unresolved name: abcd
-    check_pp(expr3,  pprust::print_expr, "2 - 23 + 7");
-}
-
-fn check_pp<T>(expr: T, f: |pprust::ps, T|, expect: str) {
-    panic!();
-}
diff --git a/src/test/compile-fail/qquote-2.rs b/src/test/compile-fail/qquote-2.rs
deleted file mode 100644 (file)
index 978287a..0000000
+++ /dev/null
@@ -1,61 +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.
-
-// ignore-test Can't use syntax crate here
-
-#![feature(quote)]
-
-extern crate syntax;
-
-use syntax::diagnostic;
-use syntax::ast;
-use syntax::codemap;
-use syntax::parse::parser;
-use syntax::print::*;
-
-trait fake_ext_ctxt {
-    fn cfg() -> ast::CrateConfig;
-    fn parse_sess() -> parse::parse_sess;
-    fn call_site() -> span;
-    fn ident_of(st: &str) -> ast::ident;
-}
-
-type fake_session = parse::parse_sess;
-
-impl fake_ext_ctxt for fake_session {
-    fn cfg() -> ast::CrateConfig { Vec::new() }
-    fn parse_sess() -> parse::parse_sess { self }
-    fn call_site() -> span {
-        codemap::span {
-            lo: codemap::BytePos(0),
-            hi: codemap::BytePos(0),
-            expn_id: codemap::NO_EXPANSION
-        }
-    }
-    fn ident_of(st: &str) -> ast::ident {
-        self.interner.intern(st)
-    }
-}
-
-fn mk_ctxt() -> fake_ext_ctxt {
-    parse::new_parse_sess(None) as fake_ext_ctxt
-}
-
-
-fn main() {
-    let cx = mk_ctxt();
-
-    let stmt = quote_stmt!(cx, let x isize = 20;); //~ ERROR expected end-of-string
-    check_pp(*stmt,  pprust::print_stmt, "");
-}
-
-fn check_pp<T>(expr: T, f: |pprust::ps, T|, expect: str) {
-    panic!();
-}
index 20cc624ab19040aa421c7c8fdaab78562f247d8d..2da414befd8979312cc7b1c3e18466197d5f9f7a 100644 (file)
@@ -13,7 +13,7 @@
 
 #![feature(box_syntax)]
 
-trait Foo {}
+trait Foo : ::std::marker::MarkerTrait {}
 impl<'a> Foo for &'a [u8] {}
 
 fn a(v: &[u8]) -> Box<Foo + 'static> {
index fa26c9c54c8f4c2a6450a8ba435f8e4f8cf64b94..6aa0cc003ce64253ee1505700c5fd05bb7381999 100644 (file)
 
 #![allow(dead_code)]
 
-use std::mem::transmute;
-use std::ops::Deref;
+use std::marker::PhantomFn;
 
 ///////////////////////////////////////////////////////////////////////////
 
-pub trait TheTrait {
+pub trait TheTrait: PhantomFn<Self, Self> {
     type TheAssocType;
-
-    fn dummy(&self) { }
 }
 
 pub trait TheSubTrait : TheTrait {
index 7d955065ff45519a3af62c32a58fe8c0d95bd44e..9736910d7b5fe5425b4b7c0b4113df5a788fcbe1 100644 (file)
 #![allow(dead_code)]
 #![feature(rustc_attrs)]
 
+use std::marker::PhantomFn;
+
 ///////////////////////////////////////////////////////////////////////////
 
-pub trait TheTrait<'b> {
+pub trait TheTrait<'b> : PhantomFn<&'b Self,Self> {
     type TheAssocType;
-
-    fn dummy(&'b self) { }
 }
 
 pub struct TheType<'b> {
index 6ee65fbdf919bb97ac37c44d9ae93fd520d1bccc..da7546ce21c60ef6563fd3b02bf2cc92b2b610bf 100644 (file)
 
 #![allow(dead_code)]
 
-use std::mem::transmute;
-use std::ops::Deref;
+use std::marker::PhantomFn;
 
 ///////////////////////////////////////////////////////////////////////////
 
-pub trait TheTrait {
+pub trait TheTrait: PhantomFn<Self, Self> {
     type TheAssocType;
-
-    fn dummy(&self) { }
 }
 
 pub struct TheType<'b> {
index 49a0726fa3b7be3acca1abefcf42f53c29ec2966..e1e72e6f56e93108393b221311815a27975593c0 100644 (file)
 // outlive the location in which the type appears. Issue #22246.
 
 #![allow(dead_code)]
+#![feature(rustc_attrs)]
 
-use std::mem::transmute;
-use std::ops::Deref;
+use std::marker::PhantomFn;
 
 ///////////////////////////////////////////////////////////////////////////
 
-pub trait TheTrait {
+pub trait TheTrait: PhantomFn<Self, Self> {
     type TheAssocType;
-
-    fn dummy(&self) { }
 }
 
 pub struct TheType<'b> {
index f833361e3b505cc136f093ab56db2ae7b99419b0..f921eccef1f8cdc713d340b54f15251f4dadb40f 100644 (file)
 // Test that the compiler checks that arbitrary region bounds declared
 // in the trait must be satisfied on the impl. Issue #20890.
 
-trait Foo<'a> { type Value: 'a; }
+trait Foo<'a> {
+    type Value: 'a;
+    fn dummy(&'a self) { }
+}
 
 impl<'a> Foo<'a> for &'a i16 {
     // OK.
index 0871d8b01f6e49e324481cf3677fd5d4d16c25eb..1cf83b8ac585f75f2833480bb0535eb975fa4d54 100644 (file)
 // Test that the compiler checks that the 'static bound declared in
 // the trait must be satisfied on the impl. Issue #20890.
 
-trait Foo { type Value: 'static; }
+trait Foo {
+    type Value: 'static;
+    fn dummy(&self) { }
+}
 
 impl<'a> Foo for &'a i32 {
     //~^ ERROR cannot infer
index a3c38dff6b0f62f73275240d21286e2a1fdcc758..278ccd3c11936f3b931d0cd2ce64912ec55cc0c5 100644 (file)
@@ -21,10 +21,9 @@ pub trait Foo<'a, 't> {
     fn has_bound<'b:'a>(self, b: Inv<'b>);
     fn wrong_bound1<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
     fn okay_bound<'b,'c,'d:'a+'b+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
-    fn another_bound<'x: 'a>(self, x: Inv<'x>);
+    fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>);
 }
 
-
 impl<'a, 't> Foo<'a, 't> for &'a isize {
     fn no_bound<'b:'a>(self, b: Inv<'b>) {
         //~^ ERROR lifetime parameters or bounds on method `no_bound` do not match
@@ -51,7 +50,7 @@ fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
     fn okay_bound<'b,'c,'e:'b+'c>(self, b: Inv<'b>, c: Inv<'c>, e: Inv<'e>) {
     }
 
-    fn another_bound<'x: 't>(self, x: Inv<'x>) {}
+    fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) {}
 }
 
 fn main() { }
index 74c2c6e584b437184c642b1d46e9d25b87dcc165..f13d8a60894cb6b7ae9e3f4162cd52b427e49167 100644 (file)
@@ -8,16 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(lang_items, no_std)]
-#![no_std]
-
 // Check that explicit region bounds are allowed on the various
 // nominal types (but not on other types) and that they are type
 // checked.
 
-#[lang="sized"]
-trait Sized { }
-
 struct Inv<'a> { // invariant w/r/t 'a
     x: &'a mut &'a isize
 }
index 8a03f36972dd187f96a7df753aa1562f7a7ead57..979c1e997d03c8b694c2bcb78605f5fcade1e610 100644 (file)
@@ -10,7 +10,9 @@
 
 #![feature(box_syntax)]
 
-trait X {}
+use std::marker::MarkerTrait;
+
+trait X : MarkerTrait {}
 
 trait Iter {
     type Item: X;
index 7a0e3cf4611c7156e0ef22218d2b3023a3449d2d..7bbce7dad530db4fc9a21ab9a947009c486d8b8a 100644 (file)
 #![feature(box_syntax)]
 #![allow(warnings)]
 
-trait A<T> {}
+use std::marker::PhantomFn;
+
+trait A<T> : PhantomFn<(Self,T)> { }
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X {}
+trait X : ::std::marker::MarkerTrait {}
+
 impl<'a, T> X for B<'a, T> {}
 
-fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
+fn f<'a, T:'static, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
     box B(&*v) as Box<X> //~ ERROR `*v` does not live long enough
 }
 
index 7861fb95fef666d315e46f2b989199eea7a8038c..6de49020a6fbbaff0d6b2b0d584d28deffcd5512 100644 (file)
 
 #![feature(box_syntax)]
 
-trait A<T> {}
+use std::marker::PhantomFn;
+
+trait A<T> : PhantomFn<(Self,T)> { }
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X {}
+trait X : PhantomFn<Self> {}
 impl<'a, T> X for B<'a, T> {}
 
 fn g<'a, T: 'static>(v: Box<A<T>+'a>) -> Box<X+'static> {
index 31354de2a27df7aac0a0ac73c4dbf7130a6daf46..e22d0c7d0a4f51bc9b14f95c53c90d077c3609b2 100644 (file)
 #![feature(box_syntax)]
 #![allow(warnings)]
 
-trait A<T> {}
+use std::marker::PhantomFn;
+
+trait A<T> : PhantomFn<(Self,T)> {}
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X {}
+trait X : PhantomFn<Self> {}
 impl<'a, T> X for B<'a, T> {}
 
 fn h<'a, T, U>(v: Box<A<U>+'static>) -> Box<X+'static> {
index c60975f97e13d5dd07e24c03ec7cfc542fc994f9..147a575d38caca1ce10c1e18d4925efa308b7236 100644 (file)
 
 #![feature(box_syntax)]
 
-trait A<T> {}
+use std::marker::PhantomFn;
+
+trait A<T> : PhantomFn<(Self,T)> {}
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X {}
+trait X : PhantomFn<Self> {}
 impl<'a, T> X for B<'a, T> {}
 
 fn i<'a, T, U>(v: Box<A<U>+'a>) -> Box<X+'static> {
diff --git a/src/test/compile-fail/regions-close-object-into-object-5.rs b/src/test/compile-fail/regions-close-object-into-object-5.rs
new file mode 100644 (file)
index 0000000..bdc52ec
--- /dev/null
@@ -0,0 +1,30 @@
+// 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)]
+#![allow(warnings)]
+
+trait A<T>
+{
+    fn get(&self) -> T { panic!() }
+}
+
+struct B<'a, T>(&'a (A<T>+'a));
+
+trait X { fn foo(&self) {} }
+
+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
+}
+
+fn main() {}
+
index 25b8137d29cade512868ecfdaa54e2a228611ea8..2341d2397c9b04d5f635fe6ade7e86c675ae5853 100644 (file)
@@ -10,7 +10,9 @@
 
 #![feature(box_syntax)]
 
-trait Foo { }
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait { }
 
 impl<'a> Foo for &'a isize { }
 
index 74b36958c92f1166790972f6d80f7d7a0b6b6814..655ac6f66c97db2ac173069431fcb36ce6203896 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(box_syntax)]
 
-trait X {}
+trait X { fn foo(&self) {} }
 
 fn p1<T>(v: T) -> Box<X+'static>
     where T : X
diff --git a/src/test/compile-fail/regions-fn-bound.rs b/src/test/compile-fail/regions-fn-bound.rs
deleted file mode 100644 (file)
index c2b52b7..0000000
+++ /dev/null
@@ -1,46 +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-test
-// ignored because the first error does not show up.
-
-// 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 of<T>() -> |T| { panic!(); }
-fn subtype<T>(x: |T|) { panic!(); }
-
-fn test_fn<'x, 'y, 'z, T>(_x: &'x T, _y: &'y T, _z: &'z T) {
-    // Here, x, y, and z are free.  Other letters
-    // are bound.  Note that the arrangement
-    // subtype::<T1>(of::<T2>()) will typecheck
-    // iff T1 <: T2.
-
-    // should be the default:
-    subtype::< ||:'static>(of::<||>());
-    subtype::<||>(of::< ||:'static>());
-
-    //
-    subtype::< <'x> ||>(of::<||>());    //~ ERROR mismatched types
-    subtype::< <'x> ||>(of::< <'y> ||>());  //~ ERROR mismatched types
-
-    subtype::< <'x> ||>(of::< ||:'static>()); //~ ERROR mismatched types
-    subtype::< ||:'static>(of::< <'x> ||>());
-
-}
-
-fn main() {}
index 6c5e90a54de2b72ce5f319e52c2042e8e1d9377e..b7ef19d1e3bfc11be9c557cfc157ace2b5c160f8 100644 (file)
@@ -20,7 +20,7 @@
 // Contravariant<'foo> <: Contravariant<'static> because
 // 'foo <= 'static
 struct Contravariant<'a> {
-    marker: marker::ContravariantLifetime<'a>
+    marker: marker::PhantomData<&'a()>
 }
 
 fn use_<'short,'long>(c: Contravariant<'short>,
index d8e31fa1374a8ae07a4848b97d1baddbd08d37ab..0d3d9dacbd6f6c0a3517aed2045a09155c1b1931 100644 (file)
@@ -17,7 +17,7 @@
 use std::marker;
 
 struct Covariant<'a> {
-    marker: marker::CovariantLifetime<'a>
+    marker: marker::PhantomData<fn(&'a ())>
 }
 
 fn use_<'short,'long>(c: Covariant<'long>,
index e88c96de9e4ea3f369492872317b830afe7fef84..8c191fbd5bbe7ea86b0be74ae4e4d1403bd659d0 100644 (file)
@@ -11,7 +11,7 @@
 use std::marker;
 
 struct invariant<'a> {
-    marker: marker::InvariantLifetime<'a>
+    marker: marker::PhantomData<*mut &'a()>
 }
 
 fn to_same_lifetime<'r>(b_isize: invariant<'r>) {
diff --git a/src/test/compile-fail/require-parens-for-chained-comparison.rs b/src/test/compile-fail/require-parens-for-chained-comparison.rs
deleted file mode 100644 (file)
index f2705f5..0000000
+++ /dev/null
@@ -1,23 +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.
-
-fn f<T>() {}
-
-fn main() {
-    false == false == false;
-    //~^ ERROR: chained comparison operators require parentheses
-
-    false == 0 < 2;
-    //~^ ERROR: chained comparison operators require parentheses
-
-    f<X>();
-    //~^ ERROR: chained comparison operators require parentheses
-    //~^^ HELP: use `::<...>` instead of `<...>`
-}
index 7d252604883d6e12eb185e249389150a8c93ea2a..1b749faf1b8b92a50b0f86af687899ddceb4f40f 100644 (file)
 #![feature(lang_items, no_std)]
 #![no_std]
 
-#[lang="sized"] pub trait Sized {}
+#[lang="phantom_fn"]
+pub trait PhantomFn<T:?Sized> { }
+impl<T:?Sized, U:?Sized> PhantomFn<T> for U { }
+
+#[lang="sized"] pub trait Sized : PhantomFn<Self> {}
 
 // error-pattern:requires `start` lang_item
 
index 1a3d7821159c3fc5874697724a42866f31e72deb..1f72db1e894faa3d081728bc7505f3d6f10e0070 100644 (file)
 
 #![feature(box_syntax)]
 
-struct Foo<T>;
+struct Foo<T>(T);
 
 impl<T> Foo<T> {
     fn shadow_in_method<T>(&self) {}
     //~^ ERROR type parameter `T` shadows another type parameter
 
     fn not_shadow_in_item<U>(&self) {
-        struct Bar<T, U>; // not a shadow, separate item
+        struct Bar<T, U>(T,U); // not a shadow, separate item
         fn foo<T, U>() {} // same
     }
 }
 
 trait Bar<T> {
+    fn dummy(&self) -> T;
+
     fn shadow_in_required<T>(&self);
     //~^ ERROR type parameter `T` shadows another type parameter
 
index 23ad5b09950effba47277fc56bf1533bb6b3f49e..3b992e3bcc321001aae1fd9e694717400c7685ea 100644 (file)
@@ -9,14 +9,12 @@
 // except according to those terms.
 
 // Test slicing &expr[] is deprecated and gives a helpful error message.
-//
-// ignore-test
 
 struct Foo;
 
 fn main() {
     let x = Foo;
-    &x[]; //~ WARNING deprecated slicing syntax: `[]`
-          //~^ NOTE use `&expr[..]` to construct a slice of the whole of expr
-          //~^^ ERROR cannot index a value of type `Foo`
+    &x[];
+    //~^ WARN obsolete syntax
+    //~| ERROR cannot index
 }
index 1203d622348998d7044f724511726ec6d1456ed2..3c1c3796a246f172baef08c48c056dc541f0a923 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<T,U>(T);
+use std::marker;
+
+struct Foo<T,U>(T, marker::PhantomData<U>);
 
 fn main() {
-    match Foo(1.1) {
+    match Foo(1.1, marker::PhantomData) {
         1 => {}
     //~^ ERROR mismatched types
     //~| expected `Foo<_, _>`
index bf4e46cace304dce9a5e62570046efbd44d34385..2dfc9b79ee20aca1e9a01a7b7307ed1cbb94634c 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 trait foo {
+    fn dummy(&self) { }
     fn bar();
 }
 
diff --git a/src/test/compile-fail/struct-no-fields-2.rs b/src/test/compile-fail/struct-no-fields-2.rs
deleted file mode 100644 (file)
index 4f973f8..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.
-
-struct Foo;
-
-fn f2() {
-    let _end_stmt     = Foo { };
-    //~^ ERROR: structure literal must either have at least one field
-}
-
-fn main() {}
diff --git a/src/test/compile-fail/struct-no-fields-3.rs b/src/test/compile-fail/struct-no-fields-3.rs
deleted file mode 100644 (file)
index e594683..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.
-
-struct Foo;
-
-fn g3() {
-    let _mid_tuple    = (Foo { }, 2);
-    //~^ ERROR: structure literal must either have at least one field
-}
-
-fn main() {}
diff --git a/src/test/compile-fail/struct-no-fields-4.rs b/src/test/compile-fail/struct-no-fields-4.rs
deleted file mode 100644 (file)
index 60a0a85..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.
-
-struct Foo;
-
-fn h4() {
-    let _end_of_tuple = (3, Foo { });
-    //~^ ERROR: structure literal must either have at least one field
-}
-
-fn main() {}
diff --git a/src/test/compile-fail/struct-no-fields-5.rs b/src/test/compile-fail/struct-no-fields-5.rs
deleted file mode 100644 (file)
index 940fa9c..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.
-
-struct Foo;
-
-fn i5() {
-    let _end_of_block = { Foo { } };
-    //~^ ERROR: structure literal must either have at least one field
-}
-
-fn main() {}
diff --git a/src/test/compile-fail/struct-variant-no-fields.rs b/src/test/compile-fail/struct-variant-no-fields.rs
deleted file mode 100644 (file)
index 41dbbee..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.
-
-enum Foo {
-    Bar {} //~ ERROR unit-like struct variant should be written without braces, as `Bar,`
-}
diff --git a/src/test/compile-fail/struct-variant-no-pub.rs b/src/test/compile-fail/struct-variant-no-pub.rs
deleted file mode 100644 (file)
index e62b39a..0000000
+++ /dev/null
@@ -1,17 +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 {
-        pub a: isize //~ ERROR: `pub` is not allowed here
-    }
-}
-
-fn main() {}
diff --git a/src/test/compile-fail/syntax-trait-polarity.rs b/src/test/compile-fail/syntax-trait-polarity.rs
deleted file mode 100644 (file)
index 1ab79f5..0000000
+++ /dev/null
@@ -1,33 +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(optin_builtin_traits)]
-
-use std::marker::Send;
-
-struct TestType;
-
-impl !TestType {}
-//~^ ERROR inherent implementation can't be negated
-
-trait TestTrait {}
-
-unsafe impl !Send for TestType {}
-impl !TestTrait for TestType {}
-
-struct TestType2<T>;
-
-impl<T> !TestType2<T> {}
-//~^ ERROR inherent implementation can't be negated
-
-unsafe impl<T> !Send for TestType2<T> {}
-impl<T> !TestTrait for TestType2<T> {}
-
-fn main() {}
diff --git a/src/test/compile-fail/tag-variant-disr-non-nullary.rs b/src/test/compile-fail/tag-variant-disr-non-nullary.rs
deleted file mode 100644 (file)
index 207bbe9..0000000
+++ /dev/null
@@ -1,20 +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.
-
-//error-pattern: discriminator values can only be used with a c-like enum
-
-enum color {
-    red = 0xff0000,
-    green = 0x00ff00,
-    blue = 0x0000ff,
-    black = 0x000000,
-    white = 0xffffff,
-    other (str),
-}
diff --git a/src/test/compile-fail/trailing-carriage-return-in-string.rs b/src/test/compile-fail/trailing-carriage-return-in-string.rs
deleted file mode 100644 (file)
index 8109833..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.
-
-// ignore-tidy-cr
-// Issue #11669
-
-fn main() {
-    // \r\n
-    let ok = "This is \
- a test";
-    // \r only
-    let bad = "This is \\r a test";
-    //~^ ERROR unknown character escape: \r
-    //~^^ HELP this is an isolated carriage return
-
-}
diff --git a/src/test/compile-fail/trailing-plus-in-bounds.rs b/src/test/compile-fail/trailing-plus-in-bounds.rs
deleted file mode 100644 (file)
index e8f9ed4..0000000
+++ /dev/null
@@ -1,18 +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::fmt::Show;
-
-fn main() {
-    let x: Box<Show+> = box 3 as Box<Show+>;
-    //~^ ERROR at least one type parameter bound must be specified
-    //~^^ ERROR at least one type parameter bound must be specified
-}
-
index a1fcab002e138ccca33f3e6da65fb06cc35a08f2..fff144140947a11307157513cc8d4900e26444a0 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait TraitNotAStruct { }
+trait TraitNotAStruct : ::std::marker::MarkerTrait { }
 
 fn main() {
     TraitNotAStruct{ value: 0 };
index 79174552ae09c36f5ba136754f7a95cd7d6b6bc0..3129dceffbb664c3d2471ba61e3a38b7df2562b1 100644 (file)
@@ -10,6 +10,7 @@
 
 
 trait Foo {
+    fn dummy(&self) { }
 }
 
 fn a(_x: Box<Foo+Send>) {
index 477bd4f5be9a1a8a942acc1fd2b625b82c1fb5c6..34e06cc93658aedd3b0d4e4f22bfa79158710ef5 100644 (file)
 // Make sure rustc checks the type parameter bounds in implementations of traits,
 // see #2687
 
-trait A {}
+use std::marker;
+
+trait A : marker::PhantomFn<Self> {
+}
 
 trait B: A {}
 
@@ -62,15 +65,16 @@ fn test_error8_fn<T: C>(&self) {}
     //~^ ERROR the requirement `T : C` appears on the impl
 }
 
-
-trait Getter<T> { }
+trait Getter<T> {
+    fn get(&self) -> T { loop { } }
+}
 
 trait Trait {
-    fn method<G:Getter<isize>>();
+    fn method<G:Getter<isize>>(&self);
 }
 
 impl Trait for usize {
-    fn method<G: Getter<usize>>() {}
+    fn method<G: Getter<usize>>(&self) {}
     //~^ G : Getter<usize>` appears on the impl method but not on the corresponding trait method
 }
 
index 8ad19116e7bb13ba2b11af89f5121e45441c9949..284c4fac953f2302b81fcc9b9efa6a0ba7d9ead5 100644 (file)
@@ -14,7 +14,9 @@ trait Iterator<A> {
     fn next(&mut self) -> Option<A>;
 }
 
-trait IteratorUtil<A> {
+trait IteratorUtil<A>
+    : ::std::marker::PhantomFn<(),A>
+{
     fn zip<B, U: Iterator<U>>(self, other: U) -> ZipIterator<Self, U>;
 }
 
index 434d803d718e7bcc143339e29bdfcbfeb069b473..448b186f6a5c6de1cff16451a9ff6db965d8cb7e 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 trait Foo {
+    fn dummy(&self) { }
 }
 
 // This should emit the less confusing error, not the more confusing one.
diff --git a/src/test/compile-fail/trait-bounds-not-on-impl.rs b/src/test/compile-fail/trait-bounds-not-on-impl.rs
deleted file mode 100644 (file)
index a034352..0000000
+++ /dev/null
@@ -1,19 +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.
-
-trait Foo {
-}
-
-struct Bar;
-
-impl Foo + Owned for Bar { //~ ERROR not a trait
-}
-
-fn main() { }
index 118dfeb37c2516d7845af0799312bde338eb43f4..df44e847c50fd5ffca5d96fbad2edc875444fd8c 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Trait {}
+trait Trait {
+    fn dummy(&self) { }
+}
 
 struct Foo<T:Trait> {
     x: T,
index d5369817e9ac189aac608c37d2d47255866bc023..18871d0d386d77ec178838299a0861bbb8e7e338 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Trait {}
+trait Trait {
+    fn dummy(&self) { }
+}
 
 struct Foo<T:Trait> {
     x: T,
index 490ee0e8ad6f3fcae09e62e057a9b958a500a8b8..8dfdb2f205d6f27d7e423e7ea2cb471485d812f7 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Trait {}
+use std::marker::MarkerTrait;
+
+trait Trait : MarkerTrait {}
 
 struct Foo<T:Trait> {
     x: T,
@@ -51,15 +53,15 @@ enum MoreBadness<V> {
     EvenMoreBadness(Bar<V>),
 }
 
-trait PolyTrait<T> {
-    fn whatever() {}
+trait PolyTrait<T>
+{
+    fn whatever(&self, t: T) {}
 }
 
 struct Struct;
 
 impl PolyTrait<Foo<usize>> for Struct {
 //~^ ERROR not implemented
-    fn whatever() {}
 }
 
 fn main() {
index 3d264e681a3d25c6b0ea5d7f88e24068dcecdf38..e4058a0943aadb770f92e4edfe031b2fd91c18f7 100644 (file)
@@ -10,8 +10,9 @@
 
 // Tests for "default" bounds inferred for traits with no bounds list.
 
+use std::marker::MarkerTrait;
 
-trait Foo {}
+trait Foo : MarkerTrait {}
 
 fn a(_x: Box<Foo+Send>) {
 }
index dadcbd5bce710291c706ad4a4209374352549d1b..2f4793b4d888f094ea5eaf8fa4594608d640def9 100644 (file)
@@ -12,7 +12,9 @@
 // trait impl is only applied to a trait object, not concrete types which implement
 // the trait.
 
-trait T {}
+use std::marker::MarkerTrait;
+
+trait T : MarkerTrait {}
 
 impl<'a> T+'a {
     fn foo(&self) {}
index 761bcd4968abfba2459f2d06e6f40bd9df33091a..d45d13556e12188b91d70f2a21cca6aa1a057c5b 100644 (file)
@@ -12,6 +12,7 @@
 
 trait Tr {
     fn foo();
+    fn bar(&self) { }
 }
 
 struct St;
index 651f663fc991343fe35c2ec64877b5fba854f698..0e357d9d4d53147a0b3037fe8adc66cca0be36b8 100644 (file)
@@ -16,6 +16,7 @@
 mod base {
     pub trait HasNew<T> {
         fn new() -> T;
+        fn dummy(&self) { }
     }
 
     pub struct Foo {
diff --git a/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs b/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs
new file mode 100644 (file)
index 0000000..8ff514e
--- /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 a default that references `Self` which is then used in an
+// object type. Issue #18956. In this case, the value is supplied by
+// the user, but pretty-printing the type during the error message
+// caused an ICE.
+
+trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; }
+
+impl MyAdd for i32 {
+    fn add(&self, other: &i32) -> i32 { *self + *other }
+}
+
+fn main() {
+    let x = 5;
+    let y = x as MyAdd<i32>;
+    //~^ ERROR as `MyAdd<i32>`
+}
diff --git a/src/test/compile-fail/type-parameter-defaults-referencing-Self.rs b/src/test/compile-fail/type-parameter-defaults-referencing-Self.rs
new file mode 100644 (file)
index 0000000..9982d48
--- /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 a default that references `Self` which is then used in an object type.
+// Issue #18956.
+
+#![feature(default_type_params)]
+
+trait Foo<T=Self> {
+    fn method(&self);
+}
+
+fn foo(x: &Foo) { }
+//~^ ERROR the type parameter `T` must be explicitly specified
+
+fn main() { }
diff --git a/src/test/compile-fail/type-parameters-in-field-exprs.rs b/src/test/compile-fail/type-parameters-in-field-exprs.rs
deleted file mode 100644 (file)
index 54ddb3e..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.
-
-struct Foo {
-    x: isize,
-    y: isize,
-}
-
-fn main() {
-    let f = Foo {
-        x: 1,
-        y: 2,
-    };
-    f.x::<isize>;
-    //~^ ERROR field expressions may not have type parameters
-}
-
index 9da79b11cf0b7f1229e6bcab83fc2a1c47920fbd..557fb2f4f8833ff18f775a5c654841ebf9760fcf 100644 (file)
@@ -12,7 +12,9 @@
 
 struct TestType;
 
-trait TestTrait {}
+trait TestTrait {
+    fn dummy(&self) { }
+}
 
 impl !TestTrait for TestType {}
 //~^ ERROR  negative impls are currently allowed just for `Send` and `Sync`
index a34be63ba6b3c906d5c54063b845999a78bee622..1daea8f915b3f192000223342b02f915492c35f3 100644 (file)
 // This test checks that genuine type errors with partial
 // type hints are understandable.
 
-struct Foo<T>;
-struct Bar<U>;
+use std::marker::PhantomData;
+
+struct Foo<T>(PhantomData<T>);
+struct Bar<U>(PhantomData<U>);
 
 pub fn main() {
 }
 
 fn test1() {
-    let x: Foo<_> = Bar::<usize>;
+    let x: Foo<_> = Bar::<usize>(PhantomData);
     //~^ ERROR mismatched types
     //~| expected `Foo<_>`
     //~| found `Bar<usize>`
@@ -28,7 +30,7 @@ fn test1() {
 }
 
 fn test2() {
-    let x: Foo<_> = Bar::<usize>;
+    let x: Foo<_> = Bar::<usize>(PhantomData);
     //~^ ERROR mismatched types
     //~| expected `Foo<_>`
     //~| found `Bar<usize>`
index 5fa66eb98e1af47f33625facccae8107559e1f47..f4e18265fd9901b528653a777f77ea31f6a55226 100644 (file)
@@ -12,6 +12,5 @@
 
 fn main() {
     <String as IntoCow>::into_cow("foo".to_string());
-    //~^ ERROR wrong number of type arguments: expected 2, found 0
+    //~^ ERROR wrong number of type arguments: expected 1, found 0
 }
-
index 3536244f011654d482dc5f8544e5f01fa7e1a796..74a6f869f63fb78850c834566b6d9f3c26bd6e83 100644 (file)
 // Check that parenthetical notation is feature-gated except with the
 // `Fn` traits.
 
+use std::marker;
+
 trait Foo<A> {
     type Output;
+
+    fn dummy(&self, a: A) { }
 }
 
 fn main() {
index 870377bc1add760e811680f0e3e4740bbe549d6d..831db98941c6dc2ac9165eab6e987b3168dfdcd1 100644 (file)
@@ -19,7 +19,7 @@ trait Foo<T,V=T> {
     fn dummy(&self, t: T, v: V);
 }
 
-trait Eq<X: ?Sized> { }
+trait Eq<X: ?Sized> { fn same_types(&self, x: &X) -> bool { true } }
 impl<X: ?Sized> Eq<X> for X { }
 fn eq<A: ?Sized,B: ?Sized>() where A : Eq<B> { }
 
index dc5576aee650a56ed814b9bbcd9abc09d5f24723..6d315c1b7a99617828fe1fe084202f00944fccef 100644 (file)
 #![feature(unboxed_closures)]
 #![allow(dead_code)]
 
+use std::marker::PhantomFn;
+
 trait Foo<T> {
     type Output;
     fn dummy(&self, t: T, u: Self::Output);
 }
 
-trait Eq<X: ?Sized> { }
+trait Eq<X: ?Sized> : PhantomFn<(Self,X)> { }
 impl<X: ?Sized> Eq<X> for X { }
 fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
 
index d2f781bba11eaa3d30d8c5121d05480a90540425..bd3530e6e3026414b6df8b46c3c4361a47e2f15b 100644 (file)
 #![feature(unboxed_closures)]
 #![allow(dead_code)]
 
+use std::marker;
+
 trait Foo<T> {
     type Output;
     fn dummy(&self, t: T);
 }
 
-trait Eq<X: ?Sized> { }
+trait Eq<X: ?Sized> : marker::PhantomFn<(Self, X)> { }
 impl<X: ?Sized> Eq<X> for X { }
 fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
 
index 75688e44e80761c2758012316a6cb6e655602c8f..057b496bd43ebead9d4f321fd67692275a10cdd7 100644 (file)
@@ -22,7 +22,7 @@ trait Foo<'a,T> {
     fn dummy(&'a self) -> &'a (T,Self::Output);
 }
 
-trait Eq<X: ?Sized> { }
+trait Eq<X: ?Sized> { fn is_of_eq_type(&self, x: &X) -> bool { true } }
 impl<X: ?Sized> Eq<X> for X { }
 fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
 
index 215b2c6798e40c80f30333dd4edbc1a34120b3b6..713b64b1349fcc5893ac455a2755aa9449a203ef 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(core,unboxed_closures)]
 
-use std::marker::CovariantType;
+use std::marker::PhantomData;
 
 // A erroneous variant of `run-pass/unboxed_closures-infer-recursive-fn.rs`
 // where we attempt to perform mutation in the recursive function. This fails to compile
 
 struct YCombinator<F,A,R> {
     func: F,
-    marker: CovariantType<(A,R)>,
+    marker: PhantomData<(A,R)>,
 }
 
 impl<F,A,R> YCombinator<F,A,R> {
     fn new(f: F) -> YCombinator<F,A,R> {
-        YCombinator { func: f, marker: CovariantType }
+        YCombinator { func: f, marker: PhantomData }
     }
 }
 
index e3707292f2495e979f7029539de36b622ac34e13..964db6e9a4546bfb8b8ad18cfd80dc5af26110eb 100644 (file)
@@ -13,10 +13,10 @@ fn main() {
     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() {} //~ ERROR: visibility has no effect
+        pub fn foo(&self) {} //~ ERROR: visibility has no effect
     }
     impl A {
-        pub fn foo() {} //~ ERROR: visibility has no effect
+        pub fn foo(&self) {} //~ ERROR: visibility has no effect
     }
 
     struct D {
index 8740346a21750c8918af9545e4ceda6d20a0286b..a03c76b12dd8ea141dce5ddd1171b815590c3157 100644 (file)
@@ -12,7 +12,7 @@
 
 // impl - struct
 
-struct S5<Y>;
+struct S5<Y>(Y);
 
 impl<X: ?Sized> S5<X> { //~ ERROR not implemented
 }
index 3dd55b0ba7d23401d7c75e5922efd5c2f23038b5..08df1d9b7b8fb8a384912f0258e7bcbdfadb2b53 100644 (file)
 
 // impl - struct
 trait T3<Z: ?Sized> {
+    fn foo(&self, z: &Z);
 }
 
-struct S5<Y>;
+struct S5<Y>(Y);
 
 impl<X: ?Sized> T3<X> for S5<X> { //~ ERROR not implemented
 }
index ac8043d6852a9b37927cc1e5c787c502c6cfe14f..4723dfeaeb988393150e30af3cc515eef3806778 100644 (file)
@@ -12,8 +12,9 @@
 
 // impl - unbounded
 trait T2<Z> {
+    fn foo(&self, z: Z);
 }
-struct S4<Y: ?Sized>;
+struct S4<Y: ?Sized>(Box<Y>);
 impl<X: ?Sized> T2<X> for S4<X> {
     //~^ ERROR `core::marker::Sized` is not implemented for the type `X`
 }
diff --git a/src/test/compile-fail/unsized2.rs b/src/test/compile-fail/unsized2.rs
deleted file mode 100644 (file)
index b2eb206..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 syntax checks for `type` keyword.
-
-fn f<X>() {}
-
-pub fn main() {
-    f<type>();
-    //~^ ERROR expected identifier, found keyword `type`
-    //~^^ ERROR: chained comparison
-    //~^^^ HELP: use `::<
-}
index 4fc76c99c60b7ed737ba123696807a7893c4b2b9..de1cbab82b281e373002a1b2d4177a1ab1cd6791 100644 (file)
@@ -10,6 +10,7 @@
 
 // Test sized-ness checking in substitution within fn bodies..
 
+use std::marker;
 
 // Unbounded.
 fn f1<X: ?Sized>(x: &X) {
@@ -20,7 +21,9 @@ fn f2<X>(x: &X) {
 }
 
 // Bounded.
-trait T {}
+trait T {
+    fn foo(&self) { }
+}
 fn f3<X: ?Sized + T>(x: &X) {
     f4::<X>(x);
     //~^ ERROR the trait `core::marker::Sized` is not implemented
index 217d1f44d84613f9270ef4334b5cd62918c09c5f..f31a6ffdc0d7caed0084f23af4f661bd4df45f64 100644 (file)
@@ -10,8 +10,9 @@
 
 // Test `?Sized` local variables.
 
+use std::marker;
 
-trait T {}
+trait T : marker::MarkerTrait { }
 
 fn f1<X: ?Sized>(x: &X) {
     let _: X; // <-- this is OK, no bindings created, no initializer.
index 6fc547c0b8e8610b2c2d073fcf58182525b8fec9..6ea3d0720eeeb716e3ae07325963865ce5d70b0e 100644 (file)
 
 // Test sized-ness checking in substitution in impls.
 
-trait T {}
+use std::marker::MarkerTrait;
+
+trait T : MarkerTrait {}
 
 // I would like these to fail eventually.
 // impl - bounded
 trait T1<Z: T> {
+    fn dummy(&self) -> Z;
 }
-struct S3<Y: ?Sized>;
+
+struct S3<Y: ?Sized>(Box<Y>);
 impl<X: ?Sized + T> T1<X> for S3<X> {
     //~^ ERROR `core::marker::Sized` is not implemented for the type `X`
 }
index 2d4bc0c857a9a7ad7f8c77f05e77300e3346b644..af242b96a84a160d464c01a5176a3c4e6c2f0393 100644 (file)
@@ -52,9 +52,9 @@ struct Foo {
 #[foo] //~ ERROR unused attribute
 trait Baz {
     #[foo] //~ ERROR unused attribute
-    fn blah();
+    fn blah(&self);
     #[foo] //~ ERROR unused attribute
-    fn blah2() {}
+    fn blah2(&self) {}
 }
 
 fn main() {}
index d8531f4543dffad390dd3f855ca4c361a6ea72a0..b1120e54434eb1861c96d8459b449e7d49ddf708 100644 (file)
@@ -12,12 +12,14 @@ struct A { pub i: isize }
 pub enum C { pub Variant }      //~ ERROR: unnecessary `pub`
 
 pub trait E {
-    pub fn foo() {}             //~ ERROR: unnecessary visibility
+    pub fn foo(&self) {}         //~ ERROR: unnecessary visibility
+}
+trait F {
+    pub fn foo(&self) {}     //~ ERROR: unnecessary visibility
 }
-trait F { pub fn foo() {} }     //~ ERROR: unnecessary visibility
 
 impl E for A {
-    pub fn foo() {}             //~ ERROR: unnecessary visibility
+    pub fn foo(&self) {}             //~ ERROR: unnecessary visibility
 }
 
 fn main() {}
index 7125a66b294cee888ea7dbb62cb5fd12949db262..a404d09248f0192a8ed54268f3c960df4636b8e4 100644 (file)
@@ -9,8 +9,10 @@
 // except according to those terms.
 
 pub trait E {
-    pub fn foo();               //~ ERROR: unnecessary visibility
+    pub fn foo(&self);               //~ ERROR: unnecessary visibility
+}
+trait F {
+    pub fn foo(&self);               //~ ERROR: unnecessary visibility
 }
-trait F { pub fn foo(); }       //~ ERROR: unnecessary visibility
 
 fn main() {}
diff --git a/src/test/compile-fail/variance-contravariant-arg-object.rs b/src/test/compile-fail/variance-contravariant-arg-object.rs
new file mode 100644 (file)
index 0000000..3330e1d
--- /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.
+
+#![allow(dead_code)]
+
+trait Get<T> : 'static {
+    fn get(&self, t: T);
+}
+
+fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
+                                -> Box<Get<&'min i32>>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
+                                   -> Box<Get<&'max i32>>
+    where 'max : 'min
+{
+    v
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-contravariant-arg-trait-match.rs b/src/test/compile-fail/variance-contravariant-arg-trait-match.rs
new file mode 100644 (file)
index 0000000..caaad40
--- /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.
+
+#![allow(dead_code)]
+
+trait Get<T> {
+    fn get(&self, t: T);
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'max i32>
+{
+    impls_get::<G,&'min i32>() //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'min i32>
+{
+    impls_get::<G,&'max i32>()
+}
+
+fn impls_get<G,T>() where G : Get<T> { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-contravariant-self-trait-match.rs b/src/test/compile-fail/variance-contravariant-self-trait-match.rs
new file mode 100644 (file)
index 0000000..013511e
--- /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.
+
+#![allow(dead_code)]
+
+trait Get {
+    fn get(&self);
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, G : 'max, &'max G : Get
+{
+    impls_get::<&'min G>(); //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, G : 'max, &'min G : Get
+{
+    impls_get::<&'max G>();
+}
+
+fn impls_get<G>() where G : Get { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-covariant-arg-object.rs b/src/test/compile-fail/variance-covariant-arg-object.rs
new file mode 100644 (file)
index 0000000..828c987
--- /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.
+
+#![allow(dead_code)]
+
+trait Get<T> : 'static {
+    fn get(&self) -> T;
+}
+
+fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
+                                -> Box<Get<&'min i32>>
+    where 'max : 'min
+{
+    v
+}
+
+fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
+                                   -> Box<Get<&'max i32>>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-covariant-arg-trait-match.rs b/src/test/compile-fail/variance-covariant-arg-trait-match.rs
new file mode 100644 (file)
index 0000000..17761b9
--- /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.
+
+#![allow(dead_code)]
+
+trait Get<T> {
+    fn get(&self) -> T;
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'max i32>
+{
+    impls_get::<G,&'min i32>()
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'min i32>
+{
+    impls_get::<G,&'max i32>() //~ ERROR mismatched types
+}
+
+fn impls_get<G,T>() where G : Get<T> { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-covariant-self-trait-match.rs b/src/test/compile-fail/variance-covariant-self-trait-match.rs
new file mode 100644 (file)
index 0000000..4e94a3e
--- /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.
+
+#![allow(dead_code)]
+
+trait Get {
+    fn get() -> Self;
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, G : 'max, &'max G : Get
+{
+    impls_get::<&'min G>();
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, G : 'max, &'min G : Get
+{
+    impls_get::<&'max G>(); //~ ERROR mismatched types
+}
+
+fn impls_get<G>() where G : Get { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-deprecated-markers.rs b/src/test/compile-fail/variance-deprecated-markers.rs
new file mode 100644 (file)
index 0000000..8f9d24c
--- /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 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() { }
diff --git a/src/test/compile-fail/variance-invariant-arg-object.rs b/src/test/compile-fail/variance-invariant-arg-object.rs
new file mode 100644 (file)
index 0000000..9edb510
--- /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.
+
+#![allow(dead_code)]
+
+trait Get<T> : 'static {
+    fn get(&self, t: T) -> T;
+}
+
+fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
+                                -> Box<Get<&'min i32>>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
+                                   -> Box<Get<&'max i32>>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-invariant-arg-trait-match.rs b/src/test/compile-fail/variance-invariant-arg-trait-match.rs
new file mode 100644 (file)
index 0000000..45fed0b
--- /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.
+
+#![allow(dead_code)]
+
+trait Get<T> {
+    fn get(&self, t: T) -> T;
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'max i32>
+{
+    impls_get::<G,&'min i32>() //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'min i32>
+{
+    impls_get::<G,&'max i32>() //~ ERROR mismatched types
+}
+
+fn impls_get<G,T>() where G : Get<T> { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-invariant-self-trait-match.rs b/src/test/compile-fail/variance-invariant-self-trait-match.rs
new file mode 100644 (file)
index 0000000..b46cd30
--- /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.
+
+#![allow(dead_code)]
+
+trait Get {
+    fn get(&self) -> Self;
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, &'max G : Get
+{
+    impls_get::<&'min G>(); //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, &'min G : Get
+{
+    impls_get::<&'max G>(); //~ ERROR mismatched types
+}
+
+fn impls_get<G>() where G : Get { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-issue-20533.rs b/src/test/compile-fail/variance-issue-20533.rs
new file mode 100644 (file)
index 0000000..0254f56
--- /dev/null
@@ -0,0 +1,54 @@
+// 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 #20533. At some point, only 1 out of the
+// 3 errors below were being reported.
+
+use std::marker::PhantomData;
+
+fn foo<'a, T>(_x: &'a T) -> PhantomData<&'a ()> {
+    PhantomData
+}
+
+struct Wrap<T>(T);
+
+fn bar<'a, T>(_x: &'a T) -> Wrap<PhantomData<&'a ()>> {
+    Wrap(PhantomData)
+}
+
+struct Baked<'a>(PhantomData<&'a ()>);
+
+fn baz<'a, T>(_x: &'a T) -> Baked<'a> {
+    Baked(PhantomData)
+}
+
+struct AffineU32(u32);
+
+fn main() {
+    {
+        let a = AffineU32(1_u32);
+        let x = foo(&a);
+        drop(a); //~ ERROR cannot move out of `a`
+        drop(x);
+    }
+    {
+        let a = AffineU32(1_u32);
+        let x = bar(&a);
+        drop(a); //~ ERROR cannot move out of `a`
+        drop(x);
+    }
+    {
+        let a = AffineU32(1_u32);
+        let x = baz(&a);
+        drop(a); //~ ERROR cannot move out of `a`
+        drop(x);
+    }
+}
+
index d70305d1106ecd64c8a1535fddea6449fad35320..da4d6c75227fc609bba453dd222f52638b945fe2 100644 (file)
@@ -60,6 +60,7 @@
 
 #[rustc_variance]
 struct Test7<'a> { //~ ERROR regions=[[*];[];[]]
+    //~^ ERROR parameter `'a` is never used
     x: isize
 }
 
index 4bb329d6304cf3ec1333f980bde394d063ff5f16..9beb90d0b24835777550fc03adbda379e34faf9f 100644 (file)
@@ -16,6 +16,7 @@
 
 #[rustc_variance]
 enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[];[]]
+    //~^ ERROR parameter `'d` is never used
     Test8A(extern "Rust" fn(&'a isize)),
     Test8B(&'b [isize]),
     Test8C(&'b mut &'c str),
 
 #[rustc_variance]
 struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[[*, o, -, +];[];[]]
+    //~^ ERROR parameter `'w` is never used
     f: Base<'z, 'y, 'x, 'w>
 }
 
 #[rustc_variance] // Combine - and + to yield o
 struct Derived2<'a, 'b:'a, 'c> { //~ ERROR regions=[[o, o, *];[];[]]
+    //~^ ERROR parameter `'c` is never used
     f: Base<'a, 'a, 'b, 'c>
 }
 
 #[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here)
 struct Derived3<'a:'b, 'b, 'c> { //~ ERROR regions=[[o, -, *];[];[]]
+    //~^ ERROR parameter `'c` is never used
     f: Base<'a, 'b, 'a, 'c>
 }
 
diff --git a/src/test/compile-fail/variance-regions-unused-direct.rs b/src/test/compile-fail/variance-regions-unused-direct.rs
new file mode 100644 (file)
index 0000000..396e776
--- /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.
+
+// Test that disallow lifetime parameters that are unused.
+
+use std::marker;
+
+struct Bivariant<'a>; //~ ERROR parameter `'a` is never used
+
+struct Struct<'a, 'd> { //~ ERROR parameter `'d` is never used
+    field: &'a [i32]
+}
+
+trait Trait<'a, 'd> { //~ ERROR parameter `'d` is never used
+    fn method(&'a self);
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/variance-regions-unused-indirect.rs b/src/test/compile-fail/variance-regions-unused-indirect.rs
new file mode 100644 (file)
index 0000000..2d234ed
--- /dev/null
@@ -0,0 +1,21 @@
+// 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.
+
+// Test that disallow lifetime parameters that are unused.
+
+enum Foo<'a> { //~ ERROR parameter `'a` is never used
+    Foo1(Bar<'a>)
+}
+
+enum Bar<'a> { //~ ERROR parameter `'a` is never used
+    Bar1(Foo<'a>)
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/variance-trait-bounds.rs b/src/test/compile-fail/variance-trait-bounds.rs
new file mode 100644 (file)
index 0000000..88b5005
--- /dev/null
@@ -0,0 +1,65 @@
+// 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.
+
+#![deny(bivariance)]
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+
+// Check that bounds on type parameters (other than `Self`) do not
+// influence variance.
+
+#[rustc_variance]
+trait Getter<T> { //~ ERROR types=[[+];[-];[]]
+    fn get(&self) -> T;
+}
+
+#[rustc_variance]
+trait Setter<T> { //~ ERROR types=[[-];[-];[]]
+    fn get(&self, T);
+}
+
+#[rustc_variance]
+struct TestStruct<U,T:Setter<U>> { //~ ERROR types=[[+, +];[];[]]
+    t: T, u: U
+}
+
+#[rustc_variance]
+enum TestEnum<U,T:Setter<U>> {//~ ERROR types=[[*, +];[];[]]
+    //~^ ERROR parameter `U` is never used
+    Foo(T)
+}
+
+#[rustc_variance]
+trait TestTrait<U,T:Setter<U>> { //~ ERROR types=[[-, +];[-];[]]
+    fn getter(&self, u: U) -> T;
+}
+
+#[rustc_variance]
+trait TestTrait2<U> : Getter<U> { //~ ERROR types=[[+];[-];[]]
+}
+
+#[rustc_variance]
+trait TestTrait3<U> { //~ ERROR types=[[-];[-];[]]
+    fn getter<T:Getter<U>>(&self);
+}
+
+#[rustc_variance]
+struct TestContraStruct<U,T:Setter<U>> { //~ ERROR types=[[*, +];[];[]]
+    //~^ ERROR parameter `U` is never used
+    t: T
+}
+
+#[rustc_variance]
+struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR types=[[*, +];[];[]]
+    //~^ ERROR parameter `U` is never used
+    t: T
+}
+
+pub fn main() { }
index 965b9430a5e2d44095266a7b08abf700728e2147..f0ca1edd5638718c50ace55b5dfb97571f520f39 100644 (file)
@@ -18,7 +18,7 @@
 
 use std::mem;
 
-trait T { fn foo(); }
+trait T { fn foo(&self); }
 
 #[rustc_variance]
 struct TOption<'a> { //~ ERROR regions=[[-];[];[]]
diff --git a/src/test/compile-fail/variance-types-bounds.rs b/src/test/compile-fail/variance-types-bounds.rs
new file mode 100644 (file)
index 0000000..d53e4cd
--- /dev/null
@@ -0,0 +1,76 @@
+// 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.
+
+// Test that we correctly infer variance for type parameters in
+// various types and traits.
+
+#![feature(rustc_attrs)]
+
+#[rustc_variance]
+struct TestImm<A, B> { //~ ERROR types=[[+, +];[];[]]
+    x: A,
+    y: B,
+}
+
+#[rustc_variance]
+struct TestMut<A, B:'static> { //~ ERROR types=[[+, o];[];[]]
+    x: A,
+    y: &'static mut B,
+}
+
+#[rustc_variance]
+struct TestIndirect<A:'static, B:'static> { //~ ERROR types=[[+, o];[];[]]
+    m: TestMut<A, B>
+}
+
+#[rustc_variance]
+struct TestIndirect2<A:'static, B:'static> { //~ ERROR types=[[o, o];[];[]]
+    n: TestMut<A, B>,
+    m: TestMut<B, A>
+}
+
+#[rustc_variance]
+trait Getter<A> { //~ ERROR types=[[+];[-];[]]
+    fn get(&self) -> A;
+}
+
+#[rustc_variance]
+trait Setter<A> { //~ ERROR types=[[-];[o];[]]
+    fn set(&mut self, a: A);
+}
+
+#[rustc_variance]
+trait GetterSetter<A> { //~ ERROR types=[[o];[o];[]]
+    fn get(&self) -> A;
+    fn set(&mut self, a: A);
+}
+
+#[rustc_variance]
+trait GetterInTypeBound<A> { //~ ERROR types=[[-];[-];[]]
+    // Here, the use of `A` in the method bound *does* affect
+    // variance.  Think of it as if the method requested a dictionary
+    // for `T:Getter<A>`.  Since this dictionary is an input, it is
+    // contravariant, and the Getter is covariant w/r/t A, yielding an
+    // overall contravariant result.
+    fn do_it<T:Getter<A>>(&self);
+}
+
+#[rustc_variance]
+trait SetterInTypeBound<A> { //~ ERROR types=[[+];[-];[]]
+    fn do_it<T:Setter<A>>(&self);
+}
+
+#[rustc_variance]
+struct TestObject<A, R> { //~ ERROR types=[[-, +];[];[]]
+    n: Box<Setter<A>+Send>,
+    m: Box<Getter<R>+Send>,
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/variance-types.rs b/src/test/compile-fail/variance-types.rs
new file mode 100644 (file)
index 0000000..e407ebe
--- /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.
+
+#![deny(bivariance)]
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+
+use std::cell::Cell;
+
+// Check that a type parameter which is only used in a trait bound is
+// not considered bivariant.
+
+#[rustc_variance]
+struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR types=[[o, o];[];[]], regions=[[-];[];[]]
+    t: &'a mut (A,B)
+}
+
+#[rustc_variance]
+struct InvariantCell<A> { //~ ERROR types=[[o];[];[]]
+    t: Cell<A>
+}
+
+#[rustc_variance]
+struct InvariantIndirect<A> { //~ ERROR types=[[o];[];[]]
+    t: InvariantCell<A>
+}
+
+#[rustc_variance]
+struct Covariant<A> { //~ ERROR types=[[+];[];[]]
+    t: A, u: fn() -> A
+}
+
+#[rustc_variance]
+struct Contravariant<A> { //~ ERROR types=[[-];[];[]]
+    t: fn(A)
+}
+
+#[rustc_variance]
+enum Enum<A,B,C> { //~ ERROR types=[[+, -, o];[];[]]
+    Foo(Covariant<A>),
+    Bar(Contravariant<B>),
+    Zed(Covariant<C>,Contravariant<C>)
+}
+
+pub fn main() { }
diff --git a/src/test/compile-fail/variance-unused-region-param.rs b/src/test/compile-fail/variance-unused-region-param.rs
new file mode 100644 (file)
index 0000000..5f50422
--- /dev/null
@@ -0,0 +1,17 @@
+// 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.
+
+// Test that we report an error for unused type parameters in types.
+
+struct SomeStruct<'a> { x: u32 } //~ ERROR parameter `'a` is never used
+enum SomeEnum<'a> { Nothing } //~ ERROR parameter `'a` is never used
+trait SomeTrait<'a> { fn foo(&self); } //~ ERROR parameter `'a` is never used
+
+fn main() {}
diff --git a/src/test/compile-fail/variance-unused-type-param.rs b/src/test/compile-fail/variance-unused-type-param.rs
new file mode 100644 (file)
index 0000000..2e867ec
--- /dev/null
@@ -0,0 +1,36 @@
+// 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.
+
+#![allow(dead_code)]
+
+// Test that we report an error for unused type parameters in types and traits,
+// and that we offer a helpful suggestion.
+
+struct SomeStruct<A> { x: u32 }
+//~^ ERROR parameter `A` is never used
+//~| HELP PhantomData
+
+enum SomeEnum<A> { Nothing }
+//~^ ERROR parameter `A` is never used
+//~| HELP PhantomData
+
+trait SomeTrait<A> { fn foo(&self); }
+//~^ ERROR parameter `A` is never used
+//~| HELP PhantomFn
+
+// Here T might *appear* used, but in fact it isn't.
+enum ListCell<T> {
+//~^ ERROR parameter `T` is never used
+//~| HELP PhantomData
+    Cons(Box<ListCell<T>>),
+    Nil
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/variance-use-contravariant-struct-1.rs b/src/test/compile-fail/variance-use-contravariant-struct-1.rs
new file mode 100644 (file)
index 0000000..d2fd297
--- /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 various uses of structs with distint variances to make sure
+// they permit lifetimes to be approximated as expected.
+
+#![feature(rustc_attrs)]
+
+struct SomeStruct<T>(fn(T));
+
+fn foo<'min,'max>(v: SomeStruct<&'max ()>)
+                  -> SomeStruct<&'min ()>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+#[rustc_error]
+fn main() { }
diff --git a/src/test/compile-fail/variance-use-contravariant-struct-2.rs b/src/test/compile-fail/variance-use-contravariant-struct-2.rs
new file mode 100644 (file)
index 0000000..b38fd0e
--- /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 various uses of structs with distint variances to make sure
+// they permit lifetimes to be approximated as expected.
+
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+
+struct SomeStruct<T>(fn(T));
+
+fn bar<'min,'max>(v: SomeStruct<&'min ()>)
+                  -> SomeStruct<&'max ()>
+    where 'max : 'min
+{
+    v
+}
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/variance-use-covariant-struct-1.rs b/src/test/compile-fail/variance-use-covariant-struct-1.rs
new file mode 100644 (file)
index 0000000..2631cfc
--- /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 a covariant struct does not permit the lifetime of a
+// reference to be enlarged.
+
+struct SomeStruct<T>(T);
+
+fn foo<'min,'max>(v: SomeStruct<&'min ()>)
+                  -> SomeStruct<&'max ()>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-use-covariant-struct-2.rs b/src/test/compile-fail/variance-use-covariant-struct-2.rs
new file mode 100644 (file)
index 0000000..d8e1a5f
--- /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 that a covariant struct permits the lifetime of a reference to
+// be shortened.
+
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+
+struct SomeStruct<T>(T);
+
+fn foo<'min,'max>(v: SomeStruct<&'max ()>)
+                  -> SomeStruct<&'min ()>
+    where 'max : 'min
+{
+    v
+}
+
+#[rustc_error] fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/variance-use-invariant-struct-1.rs b/src/test/compile-fail/variance-use-invariant-struct-1.rs
new file mode 100644 (file)
index 0000000..c89436b
--- /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 various uses of structs with distint variances to make sure
+// they permit lifetimes to be approximated as expected.
+
+#![feature(rustc_attrs)]
+
+struct SomeStruct<T>(*mut T);
+
+fn foo<'min,'max>(v: SomeStruct<&'max ()>)
+                  -> SomeStruct<&'min ()>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn bar<'min,'max>(v: SomeStruct<&'min ()>)
+                  -> SomeStruct<&'max ()>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+#[rustc_error]
+fn main() { }
diff --git a/src/test/compile-fail/virtual-structs.rs b/src/test/compile-fail/virtual-structs.rs
deleted file mode 100644 (file)
index 3b3c7d5..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 diagnostics for the removed struct inheritance feature.
-#![feature(struct_inherit)]
-
-virtual struct SuperStruct { //~ ERROR `virtual` structs have been removed from the language
-    f1: isize,
-}
-
-struct Struct : SuperStruct; //~ ERROR `virtual` structs have been removed from the language
-
-pub fn main() {}
index 7ff18f8e0886c1d5826a5142228b9b872e610db2..1f2205b5c71983ee67a847d32b053c8365d15779 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {}
+trait Foo {
+    fn dummy(&self) { }
+}
 
 pub fn f<
     T
index dc6d446154ac75b4045c7006e98b7a6f07134495..9d9eae4a0759bb7bdbcaa311e85e6e2614c2378f 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {}
+trait Foo {
+    fn dummy(&self) { }
+}
 
 pub trait Bar : Foo {} //~ ERROR private trait in exported type
 
index a5108f005dc0e10533d7b4cddc830102f8235adc..bf614e6eb512bab429c2c5530e833fdc1f464c35 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo<T> {}
+trait Foo<T> {
+    fn dummy(&self, t: T) { }
+}
 
 trait Bar<A> {
     fn method<B>(&self) where A: Foo<B>;
diff --git a/src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs b/src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs
deleted file mode 100644 (file)
index b96c7c2..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.
-
-fn equal1<T>(_: &T, _: &T) -> bool where {
-//~^ ERROR a `where` clause must have at least one predicate in it
-    true
-}
-
-fn equal2<T>(_: &T, _: &T) -> bool where T: {
-//~^ ERROR each predicate in a `where` clause must have at least one bound
-    true
-}
-
-fn main() {
-}
-
index 313ae273c07fe94fd58f2affbf98454f0efc3b40..7968cc37090acffe1d09cc411bdd1c2fe813c5af 100644 (file)
@@ -21,7 +21,7 @@ fn test2() -> bool where Option<isize> : Eq {}
 
 #[derive(PartialEq)]
 //~^ ERROR cannot bound type `isize`, where clause bounds
-enum Foo<T> where isize : Eq { MkFoo }
+enum Foo<T> where isize : Eq { MkFoo(T) }
 //~^ ERROR cannot bound type `isize`, where clause bounds
 
 fn test3<T: Eq>() -> bool where Option<Foo<T>> : Eq {}
@@ -31,7 +31,7 @@ fn test4() -> bool where Option<Foo<isize>> : Eq {}
 
 trait Baz<T> where isize : Eq {
     //~^ ERROR cannot bound type `isize`, where clause bounds may only
-    fn baz() where String : Eq; //~ ERROR cannot bound type `collections::string::String`
+    fn baz(&self, t: T) where String : Eq; //~ ERROR cannot bound type `collections::string::String`
     //~^ ERROR cannot bound type `isize`, where clause
 }
 
index a592484f1a4c66510785d438b3eb17b1ad9a1aa8..bf26fc23d3c16a1607af005ebe04e6cb26aad378 100644 (file)
 #![omit_gdb_pretty_printer_section]
 
 use self::Enum1::{Variant1_1, Variant1_2};
+use std::marker::PhantomData;
 use std::ptr;
 
 struct Struct1;
-struct GenericStruct<T1, T2>;
+struct GenericStruct<T1, T2>(PhantomData<(T1,T2)>);
 
 enum Enum1 {
     Variant1_1,
@@ -207,8 +208,8 @@ pub enum Enum3<T> {
     }
 }
 
-trait Trait1 { }
-trait Trait2<T1, T2> { }
+trait Trait1 { fn dummy(&self) { } }
+trait Trait2<T1, T2> { fn dummy(&self, _: T1, _:T2) { } }
 
 impl Trait1 for isize {}
 impl<T1, T2> Trait2<T1, T2> for isize {}
@@ -240,8 +241,10 @@ fn main() {
 
     // Structs
     let simple_struct = Struct1;
-    let generic_struct1: GenericStruct<Mod1::Struct2, Mod1::Mod2::Struct3> = GenericStruct;
-    let generic_struct2: GenericStruct<Struct1, extern "fastcall" fn(isize) -> usize> = GenericStruct;
+    let generic_struct1: GenericStruct<Mod1::Struct2, Mod1::Mod2::Struct3> =
+        GenericStruct(PhantomData);
+    let generic_struct2: GenericStruct<Struct1, extern "fastcall" fn(isize) -> usize> =
+        GenericStruct(PhantomData);
     let mod_struct = Mod1::Struct2;
 
     // Enums
@@ -262,10 +265,10 @@ fn main() {
 
     // References
     let ref1 = (&Struct1, 0i32);
-    let ref2 = (&GenericStruct::<char, Struct1>, 0i32);
+    let ref2 = (&GenericStruct::<char, Struct1>(PhantomData), 0i32);
 
     let mut mut_struct1 = Struct1;
-    let mut mut_generic_struct = GenericStruct::<Mod1::Enum2, f64>;
+    let mut mut_generic_struct = GenericStruct::<Mod1::Enum2, f64>(PhantomData);
     let mut_ref1 = (&mut mut_struct1, 0i32);
     let mut_ref2 = (&mut mut_generic_struct, 0i32);
 
diff --git a/src/test/parse-fail/ascii-only-character-escape.rs b/src/test/parse-fail/ascii-only-character-escape.rs
new file mode 100644 (file)
index 0000000..1ba25a8
--- /dev/null
@@ -0,0 +1,17 @@
+// 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() {
+    let x = "\x80"; //~ ERROR may only be used
+    let y = "\xff"; //~ ERROR may only be used
+    let z = "\xe2"; //~ ERROR may only be used
+    let a = b"\x00e2";  // ok because byte literal
+}
+
diff --git a/src/test/parse-fail/attr-before-eof.rs b/src/test/parse-fail/attr-before-eof.rs
new file mode 100644 (file)
index 0000000..e347562
--- /dev/null
@@ -0,0 +1,11 @@
+// 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.
+
+#[derive(Debug)] //~ERROR expected item after attributes
diff --git a/src/test/parse-fail/attr-before-ext.rs b/src/test/parse-fail/attr-before-ext.rs
new file mode 100644 (file)
index 0000000..098c5aa
--- /dev/null
@@ -0,0 +1,14 @@
+// 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 main() {
+    #[attr] //~ ERROR expected item after attributes
+    println!("hi");
+}
diff --git a/src/test/parse-fail/attr-before-let.rs b/src/test/parse-fail/attr-before-let.rs
new file mode 100644 (file)
index 0000000..b4a90e3
--- /dev/null
@@ -0,0 +1,14 @@
+// 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 main() {
+    #[attr] //~ ERROR expected item
+    let __isize = 0;
+}
diff --git a/src/test/parse-fail/attr-before-stmt.rs b/src/test/parse-fail/attr-before-stmt.rs
new file mode 100644 (file)
index 0000000..ec837cd
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+// error-pattern:expected item
+
+fn f() {
+  #[foo = "bar"]
+  let x = 10;
+}
+
+fn main() {
+}
diff --git a/src/test/parse-fail/attr-dangling-in-fn.rs b/src/test/parse-fail/attr-dangling-in-fn.rs
new file mode 100644 (file)
index 0000000..384622f
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+
+// error-pattern:expected item
+
+fn f() {
+  #[foo = "bar"]
+}
+
+fn main() {
+}
diff --git a/src/test/parse-fail/attr-dangling-in-mod.rs b/src/test/parse-fail/attr-dangling-in-mod.rs
new file mode 100644 (file)
index 0000000..59a922e
--- /dev/null
@@ -0,0 +1,16 @@
+// 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.
+
+// error-pattern:expected item
+
+fn main() {
+}
+
+#[foo = "bar"]
diff --git a/src/test/parse-fail/attr.rs b/src/test/parse-fail/attr.rs
new file mode 100644 (file)
index 0000000..4bd6141
--- /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.
+
+#![feature(lang_items)]
+
+fn main() {}
+
+#![lang(foo)] //~ ERROR an inner attribute is not permitted in this context
+fn foo() {}
diff --git a/src/test/parse-fail/attrs-after-extern-mod.rs b/src/test/parse-fail/attrs-after-extern-mod.rs
new file mode 100644 (file)
index 0000000..df74761
--- /dev/null
@@ -0,0 +1,23 @@
+// 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.
+
+// Constants (static variables) can be used to match in patterns, but mutable
+// statics cannot. This ensures that there's some form of error if this is
+// attempted.
+
+extern crate libc;
+
+extern {
+    static mut rust_dbg_static_mut: libc::c_int;
+    pub fn rust_dbg_static_mut_check_four();
+    #[cfg(stage37)] //~ ERROR expected item after attributes
+}
+
+pub fn main() {}
diff --git a/src/test/parse-fail/bad-char-literals.rs b/src/test/parse-fail/bad-char-literals.rs
new file mode 100644 (file)
index 0000000..2a358ae
--- /dev/null
@@ -0,0 +1,29 @@
+// 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-tidy-cr
+// ignore-tidy-tab
+fn main() {
+    // these literals are just silly.
+    ''';
+    //~^ ERROR: character constant must be escaped: \'
+
+    // note that this is a literal "\n" byte
+    '
+';
+    //~^^ ERROR: character constant must be escaped: \n
+
+    // note that this is a literal "\r" byte
+    '\r'; //~ ERROR: character constant must be escaped: \r
+
+    // note that this is a literal tab character here
+    '  ';
+    //~^ ERROR: character constant must be escaped: \t
+}
diff --git a/src/test/parse-fail/bad-lit-suffixes.rs b/src/test/parse-fail/bad-lit-suffixes.rs
new file mode 100644 (file)
index 0000000..d10337e
--- /dev/null
@@ -0,0 +1,41 @@
+// 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
+    "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() {}
+
+extern
+    "C"suffix //~ ERROR ABI spec with a suffix is illegal
+{}
+
+fn main() {
+    ""suffix; //~ ERROR str literal with a suffix is illegal
+    b""suffix; //~ ERROR binary str literal with a suffix is illegal
+    r#""#suffix; //~ ERROR str literal with a suffix is illegal
+    br#""#suffix; //~ ERROR binary str literal with a suffix is illegal
+    'a'suffix; //~ ERROR char literal with a suffix is illegal
+    b'a'suffix; //~ ERROR byte literal with a suffix is illegal
+
+    1234u1024; //~ ERROR illegal width `1024` for integer literal
+    1234i1024; //~ ERROR illegal width `1024` for integer literal
+    1234f1024; //~ ERROR illegal width `1024` for float literal
+    1234.5f1024; //~ ERROR illegal width `1024` for float literal
+
+    1234suffix; //~ ERROR illegal suffix `suffix` for numeric literal
+    0b101suffix; //~ ERROR illegal suffix `suffix` for numeric literal
+    1.0suffix; //~ ERROR illegal suffix `suffix` for float literal
+    1.0e10suffix; //~ ERROR illegal suffix `suffix` for float literal
+}
diff --git a/src/test/parse-fail/bad-value-ident-false.rs b/src/test/parse-fail/bad-value-ident-false.rs
new file mode 100644 (file)
index 0000000..ca10bdd
--- /dev/null
@@ -0,0 +1,12 @@
+// 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 false() { } //~ ERROR expected identifier, found keyword `false`
+fn main() { }
diff --git a/src/test/parse-fail/bad-value-ident-true.rs b/src/test/parse-fail/bad-value-ident-true.rs
new file mode 100644 (file)
index 0000000..4508d52
--- /dev/null
@@ -0,0 +1,12 @@
+// 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 true() { } //~ ERROR expected identifier, found keyword `true`
+fn main() { }
diff --git a/src/test/parse-fail/doc-before-attr.rs b/src/test/parse-fail/doc-before-attr.rs
new file mode 100644 (file)
index 0000000..bb44a6a
--- /dev/null
@@ -0,0 +1,12 @@
+// 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.
+
+/// hi
+#[derive(Debug)] //~ERROR expected item after attributes
diff --git a/src/test/parse-fail/doc-before-eof.rs b/src/test/parse-fail/doc-before-eof.rs
new file mode 100644 (file)
index 0000000..e6dd410
--- /dev/null
@@ -0,0 +1,11 @@
+// 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.
+
+/// hi //~ERROR expected item after doc comment
diff --git a/src/test/parse-fail/doc-before-extern-rbrace.rs b/src/test/parse-fail/doc-before-extern-rbrace.rs
new file mode 100644 (file)
index 0000000..5afd1b2
--- /dev/null
@@ -0,0 +1,14 @@
+// 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 {
+    /// hi
+}
+//~^^ ERROR expected item after doc comment
diff --git a/src/test/parse-fail/doc-before-macro.rs b/src/test/parse-fail/doc-before-macro.rs
new file mode 100644 (file)
index 0000000..8dc6c54
--- /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.
+
+fn main() {
+    /// hi
+    println!("hi");
+    //~^^ ERROR expected item after doc comment
+}
diff --git a/src/test/parse-fail/doc-before-rbrace.rs b/src/test/parse-fail/doc-before-rbrace.rs
new file mode 100644 (file)
index 0000000..6d05064
--- /dev/null
@@ -0,0 +1,14 @@
+// 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 main() {
+    println!("Hi"); /// hi
+    //~^ ERROR expected item after doc comment
+}
diff --git a/src/test/parse-fail/doc-before-semi.rs b/src/test/parse-fail/doc-before-semi.rs
new file mode 100644 (file)
index 0000000..8b0300e
--- /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.
+
+fn main() {
+    /// hi
+    ;
+    //~^^ ERROR expected item after doc comment
+}
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
new file mode 100644 (file)
index 0000000..5cc52f6
--- /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.
+
+// 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?
diff --git a/src/test/parse-fail/generic-non-trailing-defaults.rs b/src/test/parse-fail/generic-non-trailing-defaults.rs
new file mode 100644 (file)
index 0000000..0cfb05b
--- /dev/null
@@ -0,0 +1,17 @@
+// 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 Heap;
+
+struct Vec<A = Heap, T>; //~ ERROR type parameters with a default must be trailing
+
+struct Foo<A, B = Vec<C>, C>; //~ ERROR type parameters with a default must be trailing
+
+fn main() {}
diff --git a/src/test/parse-fail/int-literal-too-large-span.rs b/src/test/parse-fail/int-literal-too-large-span.rs
new file mode 100644 (file)
index 0000000..8a496c9
--- /dev/null
@@ -0,0 +1,17 @@
+// 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.
+
+// issue #17123
+
+fn main() {
+    100000000000000000000000000000000 //~ ERROR int literal is too large
+
+        ; // the span shouldn't point to this.
+}
diff --git a/src/test/parse-fail/issue-10412.rs b/src/test/parse-fail/issue-10412.rs
new file mode 100644 (file)
index 0000000..8a99633
--- /dev/null
@@ -0,0 +1,32 @@
+// 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.
+
+
+trait Serializable<'self, T> { //~ ERROR no longer a special lifetime
+    fn serialize(val : &'self T) -> Vec<u8> ; //~ ERROR no longer a special lifetime
+    fn deserialize(repr : &[u8]) -> &'self T; //~ ERROR no longer a special lifetime
+}
+
+impl<'self> Serializable<str> for &'self str { //~ ERROR no longer a special lifetime
+    //~^ ERROR no longer a special lifetime
+    fn serialize(val : &'self str) -> Vec<u8> { //~ ERROR no longer a special lifetime
+        vec!(1)
+    }
+    fn deserialize(repr: &[u8]) -> &'self str { //~ ERROR no longer a special lifetime
+        "hi"
+    }
+}
+
+fn main() {
+    println!("hello");
+    let x = "foo".to_string();
+    let y = x;
+    println!("{}", y);
+}
diff --git a/src/test/parse-fail/issue-12560-1.rs b/src/test/parse-fail/issue-12560-1.rs
new file mode 100644 (file)
index 0000000..ea2043e
--- /dev/null
@@ -0,0 +1,23 @@
+// 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.
+
+// For style and consistency reasons, non-parametrized enum variants must
+// be used simply as `ident` instead of `ident ()`.
+// This test-case covers enum declaration.
+
+enum Foo {
+    Bar(), //~ ERROR nullary enum variants are written with no trailing `( )`
+    Baz(), //~ ERROR nullary enum variants are written with no trailing `( )`
+    Bazar
+}
+
+fn main() {
+    println!("{}", match Bar { Bar => 1, Baz => 2, Bazar => 3 })
+}
diff --git a/src/test/parse-fail/issue-14182.rs b/src/test/parse-fail/issue-14182.rs
new file mode 100644 (file)
index 0000000..364951a
--- /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.
+
+// ignore-test FIXME(japari) remove test
+
+struct Foo {
+    f: for <'b> |&'b isize|:
+      'b -> &'b isize //~ ERROR use of undeclared lifetime name `'b`
+}
+
+fn main() {
+    let mut x: Vec< for <'a> ||
+       :'a //~ ERROR use of undeclared lifetime name `'a`
+    > = Vec::new();
+    x.push(|| {});
+
+    let foo = Foo {
+        f: |x| x
+    };
+}
diff --git a/src/test/parse-fail/issue-17383.rs b/src/test/parse-fail/issue-17383.rs
new file mode 100644 (file)
index 0000000..c71e0ec
--- /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.
+
+enum X {
+    A =
+        b'a' //~ ERROR discriminator values can only be used with a c-like enum
+    ,
+    B(isize)
+}
+
+fn main() {}
diff --git a/src/test/parse-fail/issue-17718-const-mut.rs b/src/test/parse-fail/issue-17718-const-mut.rs
new file mode 100644 (file)
index 0000000..5177ebb
--- /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.
+
+const
+mut //~ ERROR: const globals cannot be mutable
+//~^ HELP did you mean to declare a static?
+FOO: usize = 3;
+
+fn main() {
+}
+
diff --git a/src/test/parse-fail/issue-1802-2.rs b/src/test/parse-fail/issue-1802-2.rs
new file mode 100644 (file)
index 0000000..f6da2fc
--- /dev/null
@@ -0,0 +1,14 @@
+// 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.
+
+// error-pattern:no valid digits found for number
+fn main() {
+    log(error, 0b_usize);
+}
diff --git a/src/test/parse-fail/issue-5544-a.rs b/src/test/parse-fail/issue-5544-a.rs
new file mode 100644 (file)
index 0000000..95a4f36
--- /dev/null
@@ -0,0 +1,14 @@
+// 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 main() {
+    let __isize = 18446744073709551616; // 2^64
+    //~^ ERROR int literal is too large
+}
diff --git a/src/test/parse-fail/issue-5544-b.rs b/src/test/parse-fail/issue-5544-b.rs
new file mode 100644 (file)
index 0000000..afff598
--- /dev/null
@@ -0,0 +1,14 @@
+// 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 main() {
+    let __isize = 0xff_ffff_ffff_ffff_ffff__isize;
+    //~^ ERROR int literal is too large
+}
diff --git a/src/test/parse-fail/issue-8537.rs b/src/test/parse-fail/issue-8537.rs
new file mode 100644 (file)
index 0000000..52cf420
--- /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.
+
+pub extern
+  "invalid-ab_isize" //~ ERROR illegal ABI
+fn foo() {}
+
+fn main() {}
diff --git a/src/test/parse-fail/keyword-as-as-identifier.rs b/src/test/parse-fail/keyword-as-as-identifier.rs
new file mode 100644 (file)
index 0000000..f307b12
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py as'
+
+fn main() {
+    let as = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-break-as-identifier.rs b/src/test/parse-fail/keyword-break-as-identifier.rs
new file mode 100644 (file)
index 0000000..1e2725e
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py break'
+
+fn main() {
+    let break = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-else-as-identifier.rs b/src/test/parse-fail/keyword-else-as-identifier.rs
new file mode 100644 (file)
index 0000000..101fd93
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py else'
+
+fn main() {
+    let else = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-enum-as-identifier.rs b/src/test/parse-fail/keyword-enum-as-identifier.rs
new file mode 100644 (file)
index 0000000..ed504cc
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py enum'
+
+fn main() {
+    let enum = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-extern-as-identifier.rs b/src/test/parse-fail/keyword-extern-as-identifier.rs
new file mode 100644 (file)
index 0000000..3260506
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py extern'
+
+fn main() {
+    let extern = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-fn-as-identifier.rs b/src/test/parse-fail/keyword-fn-as-identifier.rs
new file mode 100644 (file)
index 0000000..8c98da2
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py fn'
+
+fn main() {
+    let fn = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-for-as-identifier.rs b/src/test/parse-fail/keyword-for-as-identifier.rs
new file mode 100644 (file)
index 0000000..196a339
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py for'
+
+fn main() {
+    let for = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-if-as-identifier.rs b/src/test/parse-fail/keyword-if-as-identifier.rs
new file mode 100644 (file)
index 0000000..05f82ec
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py if'
+
+fn main() {
+    let if = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-impl-as-identifier.rs b/src/test/parse-fail/keyword-impl-as-identifier.rs
new file mode 100644 (file)
index 0000000..1dd2180
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py impl'
+
+fn main() {
+    let impl = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-let-as-identifier.rs b/src/test/parse-fail/keyword-let-as-identifier.rs
new file mode 100644 (file)
index 0000000..0069a26
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py let'
+
+fn main() {
+    let let = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-loop-as-identifier.rs b/src/test/parse-fail/keyword-loop-as-identifier.rs
new file mode 100644 (file)
index 0000000..6e469e8
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py loop'
+
+fn main() {
+    let loop = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-match-as-identifier.rs b/src/test/parse-fail/keyword-match-as-identifier.rs
new file mode 100644 (file)
index 0000000..9155ebc
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py match'
+
+fn main() {
+    let match = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-mod-as-identifier.rs b/src/test/parse-fail/keyword-mod-as-identifier.rs
new file mode 100644 (file)
index 0000000..02f57e9
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py mod'
+
+fn main() {
+    let mod = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-pub-as-identifier.rs b/src/test/parse-fail/keyword-pub-as-identifier.rs
new file mode 100644 (file)
index 0000000..aa67974
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py pub'
+
+fn main() {
+    let pub = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-return-as-identifier.rs b/src/test/parse-fail/keyword-return-as-identifier.rs
new file mode 100644 (file)
index 0000000..c567644
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py return'
+
+fn main() {
+    let return = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-self-as-identifier.rs b/src/test/parse-fail/keyword-self-as-identifier.rs
new file mode 100644 (file)
index 0000000..8bb5214
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py self'
+
+fn main() {
+    let self = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-static-as-identifier.rs b/src/test/parse-fail/keyword-static-as-identifier.rs
new file mode 100644 (file)
index 0000000..7268c4f
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py static'
+
+fn main() {
+    let static = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-struct-as-identifier.rs b/src/test/parse-fail/keyword-struct-as-identifier.rs
new file mode 100644 (file)
index 0000000..bd42eac
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py struct'
+
+fn main() {
+    let struct = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-super-as-identifier.rs b/src/test/parse-fail/keyword-super-as-identifier.rs
new file mode 100644 (file)
index 0000000..0378c32
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py super'
+
+fn main() {
+    let super = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-super.rs b/src/test/parse-fail/keyword-super.rs
new file mode 100644 (file)
index 0000000..0c94f76
--- /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.
+
+fn main() {
+    let super: isize; //~ ERROR expected identifier, found keyword `super`
+}
diff --git a/src/test/parse-fail/keyword-trait-as-identifier.rs b/src/test/parse-fail/keyword-trait-as-identifier.rs
new file mode 100644 (file)
index 0000000..95c0d17
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py trait'
+
+fn main() {
+    let trait = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-type-as-identifier.rs b/src/test/parse-fail/keyword-type-as-identifier.rs
new file mode 100644 (file)
index 0000000..0aaa2a6
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py type'
+
+fn main() {
+    let type = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-unsafe-as-identifier.rs b/src/test/parse-fail/keyword-unsafe-as-identifier.rs
new file mode 100644 (file)
index 0000000..1b631eb
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py unsafe'
+
+fn main() {
+    let unsafe = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-use-as-identifier.rs b/src/test/parse-fail/keyword-use-as-identifier.rs
new file mode 100644 (file)
index 0000000..e82afd5
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py use'
+
+fn main() {
+    let use = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-while-as-identifier.rs b/src/test/parse-fail/keyword-while-as-identifier.rs
new file mode 100644 (file)
index 0000000..95cea65
--- /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.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py while'
+
+fn main() {
+    let while = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword.rs b/src/test/parse-fail/keyword.rs
new file mode 100644 (file)
index 0000000..64eac47
--- /dev/null
@@ -0,0 +1,13 @@
+// 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.
+
+pub mod break {
+    //~^ ERROR expected identifier, found keyword `break`
+}
diff --git a/src/test/parse-fail/keywords-followed-by-double-colon.rs b/src/test/parse-fail/keywords-followed-by-double-colon.rs
new file mode 100644 (file)
index 0000000..f69b041
--- /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.
+
+fn main() {
+    struct::foo();  //~ ERROR expected identifier
+    mut::baz(); //~ ERROR expected identifier
+}
+
diff --git a/src/test/parse-fail/lex-bad-numeric-literals.rs b/src/test/parse-fail/lex-bad-numeric-literals.rs
new file mode 100644 (file)
index 0000000..9a490be
--- /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.
+
+fn main() {
+    0o1.0; //~ ERROR: octal float literal is not supported
+    0o2f32; //~ ERROR: octal float literal is not supported
+    0o3.0f32; //~ ERROR: octal float literal is not supported
+    0o4e4; //~ ERROR: octal float literal is not supported
+    0o5.0e5; //~ ERROR: octal float literal is not supported
+    0o6e6f32; //~ ERROR: octal float literal is not supported
+    0o7.0e7f64; //~ ERROR: octal float literal is not supported
+    0x8.0e+9; //~ ERROR: hexadecimal float literal is not supported
+    0x9.0e-9; //~ ERROR: hexadecimal float literal is not supported
+    0o; //~ ERROR: no valid digits
+    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
+    0x; //~ ERROR: no valid digits
+    0xu32; //~ ERROR: no valid digits
+    0ou32; //~ ERROR: no valid digits
+    0bu32; //~ ERROR: no valid digits
+    0b; //~ ERROR: no valid digits
+    0o123f64; //~ ERROR: octal float literal is not supported
+    0o123.456; //~ ERROR: octal float literal is not supported
+    0b101f64; //~ ERROR: binary float literal is not supported
+    0b111.101; //~ ERROR: binary float literal is not supported
+}
diff --git a/src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs b/src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs
new file mode 100644 (file)
index 0000000..c1e5121
--- /dev/null
@@ -0,0 +1,30 @@
+// 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-tidy-cr
+
+/// doc comment with bare CR: '\r'
+pub fn foo() {}
+//~^^ ERROR: bare CR not allowed in doc-comment
+
+/** block doc comment with bare CR: '\r' */
+pub fn bar() {}
+//~^^ ERROR: bare CR not allowed in block doc-comment
+
+fn main() {
+    // the following string literal has a bare CR in it
+    let _s = "foo\rbar"; //~ ERROR: bare CR not allowed in string
+
+    // the following string literal has a bare CR in it
+    let _s = r"bar\rfoo"; //~ ERROR: bare CR not allowed in raw string
+
+    // the following string literal has a bare CR in it
+    let _s = "foo\\rbar"; //~ ERROR: unknown character escape: \r
+}
diff --git a/src/test/parse-fail/lifetime-no-keyword.rs b/src/test/parse-fail/lifetime-no-keyword.rs
new file mode 100644 (file)
index 0000000..8ffbcd9
--- /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.
+
+fn foo<'a>(a: &'a isize) { }
+fn bar(a: &'static isize) { }
+fn baz(a: &'let isize) { } //~ ERROR invalid lifetime name
+
+fn main() { }
diff --git a/src/test/parse-fail/lifetime-obsoleted-self.rs b/src/test/parse-fail/lifetime-obsoleted-self.rs
new file mode 100644 (file)
index 0000000..766922f
--- /dev/null
@@ -0,0 +1,13 @@
+// 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 baz(a: &'self isize) { } //~ ERROR invalid lifetime name: 'self is no longer a special lifetime
+
+fn main() { }
diff --git a/src/test/parse-fail/macros-no-semicolon-items.rs b/src/test/parse-fail/macros-no-semicolon-items.rs
new file mode 100644 (file)
index 0000000..3142920
--- /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.
+
+macro_rules! foo()  //~ ERROR semicolon
+
+fn main() {
+}
diff --git a/src/test/parse-fail/mod_file_disambig.rs b/src/test/parse-fail/mod_file_disambig.rs
deleted file mode 100644 (file)
index 48bd00a..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 mod_file_disambig_aux; //~ ERROR file for module `mod_file_disambig_aux` found at both
-
-fn main() {
-    assert_eq!(mod_file_aux::bar(), 10);
-}
diff --git a/src/test/parse-fail/mod_file_not_owning.rs b/src/test/parse-fail/mod_file_not_owning.rs
deleted file mode 100644 (file)
index adbcedd..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.
-
-// error-pattern: cannot declare a new module at this location
-
-mod mod_file_not_owning_aux1;
-
-fn main() {}
diff --git a/src/test/parse-fail/no-binary-float-literal.rs b/src/test/parse-fail/no-binary-float-literal.rs
new file mode 100644 (file)
index 0000000..2e207f9
--- /dev/null
@@ -0,0 +1,17 @@
+// 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:binary float literal is not supported
+
+fn main() {
+    0b101010f64;
+    0b101.010;
+    0b101p4f64;
+}
diff --git a/src/test/parse-fail/no-hex-float-literal.rs b/src/test/parse-fail/no-hex-float-literal.rs
new file mode 100644 (file)
index 0000000..4abb609
--- /dev/null
@@ -0,0 +1,17 @@
+// 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:hexadecimal float literal is not supported
+
+fn main() {
+    0xABC.Df;
+    0x567.89;
+    0xDEAD.BEEFp-2f;
+}
diff --git a/src/test/parse-fail/no-unsafe-self.rs b/src/test/parse-fail/no-unsafe-self.rs
new file mode 100644 (file)
index 0000000..0bf73bb
--- /dev/null
@@ -0,0 +1,22 @@
+// 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.
+
+trait A {
+    fn foo(*mut self); //~ ERROR cannot pass self by unsafe pointer
+    fn bar(*self); //~ ERROR cannot pass self by unsafe pointer
+}
+
+struct X;
+impl A for X {
+    fn foo(*mut self) { } //~ ERROR cannot pass self by unsafe pointer
+    fn bar(*self) { } //~ ERROR cannot pass self by unsafe pointer
+}
+
+fn main() { }
diff --git a/src/test/parse-fail/non-str-meta.rs b/src/test/parse-fail/non-str-meta.rs
new file mode 100644 (file)
index 0000000..752f72f
--- /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.
+
+// Issue #623 - non-string meta items are not serialized correctly;
+// for now just forbid them
+
+#[foo = 1] //~ ERROR: non-string literals are not allowed in meta-items
+fn main() { }
diff --git a/src/test/parse-fail/obsolete-for-sized.rs b/src/test/parse-fail/obsolete-for-sized.rs
new file mode 100644 (file)
index 0000000..1b86d08
--- /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 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() { }
diff --git a/src/test/parse-fail/obsolete-proc.rs b/src/test/parse-fail/obsolete-proc.rs
new file mode 100644 (file)
index 0000000..5208cdb
--- /dev/null
@@ -0,0 +1,17 @@
+// 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 generate obsolete syntax errors around usages of `proc`.
+
+fn foo(p: proc()) { } //~ ERROR obsolete syntax: the `proc` type
+
+fn bar() { proc() 1; } //~ ERROR obsolete syntax: `proc` expression
+
+fn main() { }
diff --git a/src/test/parse-fail/qquote-1.rs b/src/test/parse-fail/qquote-1.rs
new file mode 100644 (file)
index 0000000..deae9a8
--- /dev/null
@@ -0,0 +1,68 @@
+// 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.
+
+// ignore-test Can't use syntax crate here
+
+#![feature(quote)]
+
+extern crate syntax;
+
+use io::*;
+
+use syntax::diagnostic;
+use syntax::ast;
+use syntax::codemap;
+use syntax::parse;
+use syntax::print::*;
+
+
+trait fake_ext_ctxt {
+    fn cfg() -> ast::CrateConfig;
+    fn parse_sess() -> parse::parse_sess;
+    fn call_site() -> span;
+    fn ident_of(st: &str) -> ast::ident;
+}
+
+type fake_session = parse::parse_sess;
+
+impl fake_ext_ctxt for fake_session {
+    fn cfg() -> ast::CrateConfig { Vec::new() }
+    fn parse_sess() -> parse::parse_sess { self }
+    fn call_site() -> span {
+        codemap::span {
+            lo: codemap::BytePos(0),
+            hi: codemap::BytePos(0),
+            expn_id: NO_EXPANSION
+        }
+    }
+    fn ident_of(st: &str) -> ast::ident {
+        self.interner.intern(st)
+    }
+}
+
+fn mk_ctxt() -> fake_ext_ctxt {
+    parse::new_parse_sess(None) as fake_ext_ctxt
+}
+
+
+
+fn main() {
+    let cx = mk_ctxt();
+
+    let abc = quote_expr!(cx, 23);
+    check_pp(abc,  pprust::print_expr, "23");
+
+    let expr3 = quote_expr!(cx, 2 - $abcd + 7); //~ ERROR unresolved name: abcd
+    check_pp(expr3,  pprust::print_expr, "2 - 23 + 7");
+}
+
+fn check_pp<T>(expr: T, f: |pprust::ps, T|, expect: str) {
+    panic!();
+}
diff --git a/src/test/parse-fail/qquote-2.rs b/src/test/parse-fail/qquote-2.rs
new file mode 100644 (file)
index 0000000..978287a
--- /dev/null
@@ -0,0 +1,61 @@
+// 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.
+
+// ignore-test Can't use syntax crate here
+
+#![feature(quote)]
+
+extern crate syntax;
+
+use syntax::diagnostic;
+use syntax::ast;
+use syntax::codemap;
+use syntax::parse::parser;
+use syntax::print::*;
+
+trait fake_ext_ctxt {
+    fn cfg() -> ast::CrateConfig;
+    fn parse_sess() -> parse::parse_sess;
+    fn call_site() -> span;
+    fn ident_of(st: &str) -> ast::ident;
+}
+
+type fake_session = parse::parse_sess;
+
+impl fake_ext_ctxt for fake_session {
+    fn cfg() -> ast::CrateConfig { Vec::new() }
+    fn parse_sess() -> parse::parse_sess { self }
+    fn call_site() -> span {
+        codemap::span {
+            lo: codemap::BytePos(0),
+            hi: codemap::BytePos(0),
+            expn_id: codemap::NO_EXPANSION
+        }
+    }
+    fn ident_of(st: &str) -> ast::ident {
+        self.interner.intern(st)
+    }
+}
+
+fn mk_ctxt() -> fake_ext_ctxt {
+    parse::new_parse_sess(None) as fake_ext_ctxt
+}
+
+
+fn main() {
+    let cx = mk_ctxt();
+
+    let stmt = quote_stmt!(cx, let x isize = 20;); //~ ERROR expected end-of-string
+    check_pp(*stmt,  pprust::print_stmt, "");
+}
+
+fn check_pp<T>(expr: T, f: |pprust::ps, T|, expect: str) {
+    panic!();
+}
diff --git a/src/test/parse-fail/regions-fn-bound.rs b/src/test/parse-fail/regions-fn-bound.rs
new file mode 100644 (file)
index 0000000..c2b52b7
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-test
+// ignored because the first error does not show up.
+
+// 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 of<T>() -> |T| { panic!(); }
+fn subtype<T>(x: |T|) { panic!(); }
+
+fn test_fn<'x, 'y, 'z, T>(_x: &'x T, _y: &'y T, _z: &'z T) {
+    // Here, x, y, and z are free.  Other letters
+    // are bound.  Note that the arrangement
+    // subtype::<T1>(of::<T2>()) will typecheck
+    // iff T1 <: T2.
+
+    // should be the default:
+    subtype::< ||:'static>(of::<||>());
+    subtype::<||>(of::< ||:'static>());
+
+    //
+    subtype::< <'x> ||>(of::<||>());    //~ ERROR mismatched types
+    subtype::< <'x> ||>(of::< <'y> ||>());  //~ ERROR mismatched types
+
+    subtype::< <'x> ||>(of::< ||:'static>()); //~ ERROR mismatched types
+    subtype::< ||:'static>(of::< <'x> ||>());
+
+}
+
+fn main() {}
diff --git a/src/test/parse-fail/require-parens-for-chained-comparison.rs b/src/test/parse-fail/require-parens-for-chained-comparison.rs
new file mode 100644 (file)
index 0000000..f2705f5
--- /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.
+
+fn f<T>() {}
+
+fn main() {
+    false == false == false;
+    //~^ ERROR: chained comparison operators require parentheses
+
+    false == 0 < 2;
+    //~^ ERROR: chained comparison operators require parentheses
+
+    f<X>();
+    //~^ ERROR: chained comparison operators require parentheses
+    //~^^ HELP: use `::<...>` instead of `<...>`
+}
diff --git a/src/test/parse-fail/struct-no-fields-2.rs b/src/test/parse-fail/struct-no-fields-2.rs
new file mode 100644 (file)
index 0000000..4f973f8
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+
+struct Foo;
+
+fn f2() {
+    let _end_stmt     = Foo { };
+    //~^ ERROR: structure literal must either have at least one field
+}
+
+fn main() {}
diff --git a/src/test/parse-fail/struct-no-fields-3.rs b/src/test/parse-fail/struct-no-fields-3.rs
new file mode 100644 (file)
index 0000000..e594683
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+
+struct Foo;
+
+fn g3() {
+    let _mid_tuple    = (Foo { }, 2);
+    //~^ ERROR: structure literal must either have at least one field
+}
+
+fn main() {}
diff --git a/src/test/parse-fail/struct-no-fields-4.rs b/src/test/parse-fail/struct-no-fields-4.rs
new file mode 100644 (file)
index 0000000..60a0a85
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+
+struct Foo;
+
+fn h4() {
+    let _end_of_tuple = (3, Foo { });
+    //~^ ERROR: structure literal must either have at least one field
+}
+
+fn main() {}
diff --git a/src/test/parse-fail/struct-no-fields-5.rs b/src/test/parse-fail/struct-no-fields-5.rs
new file mode 100644 (file)
index 0000000..940fa9c
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+
+struct Foo;
+
+fn i5() {
+    let _end_of_block = { Foo { } };
+    //~^ ERROR: structure literal must either have at least one field
+}
+
+fn main() {}
diff --git a/src/test/parse-fail/struct-variant-no-fields.rs b/src/test/parse-fail/struct-variant-no-fields.rs
new file mode 100644 (file)
index 0000000..41dbbee
--- /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.
+
+enum Foo {
+    Bar {} //~ ERROR unit-like struct variant should be written without braces, as `Bar,`
+}
diff --git a/src/test/parse-fail/struct-variant-no-pub.rs b/src/test/parse-fail/struct-variant-no-pub.rs
new file mode 100644 (file)
index 0000000..e62b39a
--- /dev/null
@@ -0,0 +1,17 @@
+// 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 {
+        pub a: isize //~ ERROR: `pub` is not allowed here
+    }
+}
+
+fn main() {}
diff --git a/src/test/parse-fail/syntax-trait-polarity.rs b/src/test/parse-fail/syntax-trait-polarity.rs
new file mode 100644 (file)
index 0000000..1ab79f5
--- /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.
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::Send;
+
+struct TestType;
+
+impl !TestType {}
+//~^ ERROR inherent implementation can't be negated
+
+trait TestTrait {}
+
+unsafe impl !Send for TestType {}
+impl !TestTrait for TestType {}
+
+struct TestType2<T>;
+
+impl<T> !TestType2<T> {}
+//~^ ERROR inherent implementation can't be negated
+
+unsafe impl<T> !Send for TestType2<T> {}
+impl<T> !TestTrait for TestType2<T> {}
+
+fn main() {}
diff --git a/src/test/parse-fail/tag-variant-disr-non-nullary.rs b/src/test/parse-fail/tag-variant-disr-non-nullary.rs
new file mode 100644 (file)
index 0000000..207bbe9
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+//error-pattern: discriminator values can only be used with a c-like enum
+
+enum color {
+    red = 0xff0000,
+    green = 0x00ff00,
+    blue = 0x0000ff,
+    black = 0x000000,
+    white = 0xffffff,
+    other (str),
+}
diff --git a/src/test/parse-fail/trailing-carriage-return-in-string.rs b/src/test/parse-fail/trailing-carriage-return-in-string.rs
new file mode 100644 (file)
index 0000000..8109833
--- /dev/null
@@ -0,0 +1,23 @@
+// 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-tidy-cr
+// Issue #11669
+
+fn main() {
+    // \r\n
+    let ok = "This is \
+ a test";
+    // \r only
+    let bad = "This is \\r a test";
+    //~^ ERROR unknown character escape: \r
+    //~^^ HELP this is an isolated carriage return
+
+}
diff --git a/src/test/parse-fail/trailing-plus-in-bounds.rs b/src/test/parse-fail/trailing-plus-in-bounds.rs
new file mode 100644 (file)
index 0000000..e8f9ed4
--- /dev/null
@@ -0,0 +1,18 @@
+// 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::fmt::Show;
+
+fn main() {
+    let x: Box<Show+> = box 3 as Box<Show+>;
+    //~^ ERROR at least one type parameter bound must be specified
+    //~^^ ERROR at least one type parameter bound must be specified
+}
+
diff --git a/src/test/parse-fail/trait-bounds-not-on-impl.rs b/src/test/parse-fail/trait-bounds-not-on-impl.rs
new file mode 100644 (file)
index 0000000..a034352
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+trait Foo {
+}
+
+struct Bar;
+
+impl Foo + Owned for Bar { //~ ERROR not a trait
+}
+
+fn main() { }
diff --git a/src/test/parse-fail/type-parameters-in-field-exprs.rs b/src/test/parse-fail/type-parameters-in-field-exprs.rs
new file mode 100644 (file)
index 0000000..54ddb3e
--- /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.
+
+struct Foo {
+    x: isize,
+    y: isize,
+}
+
+fn main() {
+    let f = Foo {
+        x: 1,
+        y: 2,
+    };
+    f.x::<isize>;
+    //~^ ERROR field expressions may not have type parameters
+}
+
diff --git a/src/test/parse-fail/unsized2.rs b/src/test/parse-fail/unsized2.rs
new file mode 100644 (file)
index 0000000..b2eb206
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test syntax checks for `type` keyword.
+
+fn f<X>() {}
+
+pub fn main() {
+    f<type>();
+    //~^ ERROR expected identifier, found keyword `type`
+    //~^^ ERROR: chained comparison
+    //~^^^ HELP: use `::<
+}
diff --git a/src/test/parse-fail/virtual-structs.rs b/src/test/parse-fail/virtual-structs.rs
new file mode 100644 (file)
index 0000000..3b3c7d5
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test diagnostics for the removed struct inheritance feature.
+#![feature(struct_inherit)]
+
+virtual struct SuperStruct { //~ ERROR `virtual` structs have been removed from the language
+    f1: isize,
+}
+
+struct Struct : SuperStruct; //~ ERROR `virtual` structs have been removed from the language
+
+pub fn main() {}
diff --git a/src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs b/src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs
new file mode 100644 (file)
index 0000000..b96c7c2
--- /dev/null
@@ -0,0 +1,23 @@
+// 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 equal1<T>(_: &T, _: &T) -> bool where {
+//~^ ERROR a `where` clause must have at least one predicate in it
+    true
+}
+
+fn equal2<T>(_: &T, _: &T) -> bool where T: {
+//~^ ERROR each predicate in a `where` clause must have at least one bound
+    true
+}
+
+fn main() {
+}
+
index f22f1b409526900b3f1909221c9cf50ec1d667c0..f5205de5c1fcd3ee32661b60d821915bbd10efb7 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait X { }
+trait X { fn dummy(&self) { } }
 impl X for uint { }
 
-trait Y { }
+trait Y { fn dummy(&self) { } }
 impl Y for uint { }
index e27a3365a4105d1d7025eb002f6be59a3d14612c..9e1f2aa8bfe01e7729e5e71c30f76908082b918b 100644 (file)
@@ -11,7 +11,9 @@
 // pp-exact
 
 
-trait Tr { }
+trait Tr {
+    fn dummy(&self) { }
+}
 impl Tr for int { }
 
 fn foo<'a>(x: Box<Tr+ Sync + 'a>) -> Box<Tr+ Sync + 'a> { x }
index e46564f80760c6c62cc2b5d8ee474b65f7ea6b69..4ad81197286bb992734e8d8f24ae04fa74ad50c7 100644 (file)
@@ -9,6 +9,9 @@
 // except according to those terms.
 
 // error-pattern:quux
+
+use std::marker::PhantomData;
+
 fn test00_start(ch: chan_t<int>, message: int) { send(ch, message); }
 
 type task_id = int;
@@ -17,6 +20,7 @@
 struct chan_t<T> {
     task: task_id,
     port: port_id,
+    marker: PhantomData<*mut T>,
 }
 
 fn send<T:Send>(_ch: chan_t<T>, _data: T) { panic!(); }
index d57a7164cdbcea135ea7d41436f5d9909a8d9bc6..3bd56c14193a8524d7e4dc25cf2e474779e5181f 100644 (file)
@@ -21,5 +21,5 @@ pub fn baz() { }
     }
 
     /// *wow*
-    pub trait Doge { }
+    pub trait Doge { fn dummy(&self) { } }
 }
index b5fcbf46c5c98207eec54bd47fda67f5c2b4744d..6c56bcc9be67bc0a4817cd307e092facc44b48cd 100644 (file)
@@ -13,7 +13,7 @@
 // @matches foo/struct.Alpha.html '//pre' "pub struct Alpha"
 pub struct Alpha;
 // @matches foo/struct.Bravo.html '//pre' "pub struct Bravo<B>"
-pub struct Bravo<B>;
+pub struct Bravo<B>(B);
 
 // @matches foo/struct.Alpha.html '//*[@class="impl"]//code' "impl !Send for Alpha"
 impl !Send for Alpha {}
index dd68f2d6f1dee4c512c26d5c103e13511e1f5b88..42469a21f22d0abbf25f3bfc31e5c76e396efde7 100644 (file)
@@ -21,6 +21,6 @@ fn priv_method() {} // @!has - priv_method
     }
 
     pub trait PrivateTrait {
-        fn trait_method() {} // @!has - priv_method
+        fn trait_method(&self) {} // @!has - priv_method
     }
 }
index 0438c9aba3599f8238586fa75078f08759c15ede..f6b73021bebdfb0ffc70941642062208c65a8a9b 100644 (file)
@@ -26,7 +26,7 @@ pub fn baz() { }
 
     /// *wow*
     // @has foo/bar/trait.Doge.html
-    pub trait Doge { }
+    pub trait Doge { fn dummy(&self) { } }
 
     // @has foo/bar/struct.Foo.html
     pub struct Foo { x: int, y: uint }
index da8f73930239044a3141b7602e5e909667949019..6fd47d84c30fee93646688ba1bc1732003c46213 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub mod io {
-    pub trait Reader { }
+    pub trait Reader { fn dummy(&self) { } }
 }
 
 pub enum Maybe<A> {
index 68fde60564e2a8c96bdc25f29029eec503c42a73..91a7e1c9fd4aeb4554cdef802909b12cb4df35bb 100644 (file)
@@ -8,30 +8,33 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait MyTrait {}
+pub trait MyTrait { fn dummy(&self) { } }
 
 // @has foo/struct.Alpha.html '//pre' "pub struct Alpha<A> where A: MyTrait"
-pub struct Alpha<A> where A: MyTrait;
+pub struct Alpha<A>(A) where A: MyTrait;
 // @has foo/trait.Bravo.html '//pre' "pub trait Bravo<B> where B: MyTrait"
-pub trait Bravo<B> where B: MyTrait {}
+pub trait Bravo<B> where B: MyTrait { fn get(&self, B: B); }
 // @has foo/fn.charlie.html '//pre' "pub fn charlie<C>() where C: MyTrait"
 pub fn charlie<C>() where C: MyTrait {}
 
-pub struct Delta<D>;
+pub struct Delta<D>(D);
+
 // @has foo/struct.Delta.html '//*[@class="impl"]//code' \
 //          "impl<D> Delta<D> where D: MyTrait"
 impl<D> Delta<D> where D: MyTrait {
     pub fn delta() {}
 }
 
-pub struct Echo<E>;
+pub struct Echo<E>(E);
+
 // @has foo/struct.Echo.html '//*[@class="impl"]//code' \
 //          "impl<E> MyTrait for Echo<E> where E: MyTrait"
 // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//code' \
 //          "impl<E> MyTrait for Echo<E> where E: MyTrait"
 impl<E> MyTrait for Echo<E> where E: MyTrait {}
 
-pub enum Foxtrot<F> {}
+pub enum Foxtrot<F> { Foxtrot1(F) }
+
 // @has foo/enum.Foxtrot.html '//*[@class="impl"]//code' \
 //          "impl<F> MyTrait for Foxtrot<F> where F: MyTrait"
 // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//code' \
index db70a2452326673144a0d9c1e9b8504870096e75..38381da3670c18be3fa9e126ccb3c08e0237f031 100644 (file)
@@ -34,7 +34,7 @@
 static uni: &'static str = "Les Miséééééééérables";
 static yy: usize = 25;
 
-static bob: Option<std::vec::CowVec<'static, isize>> = None;
+static bob: Option<&'static [isize]> = None;
 
 // buglink test - see issue #1337.
 
@@ -99,6 +99,7 @@ struct some_fields {
 type SF = some_fields;
 
 trait SuperTrait {
+    fn dummy(&self) { }
 }
 
 trait SomeTrait: SuperTrait {
index 834a2adf01fd3075bfa44ef33454e2504f68f3fd..f418d5d1fb74f1435110ea0378df3f9e48ffa8ca 100755 (executable)
@@ -70,10 +70,14 @@ pub fn bar(a: i32x4, b: i32x4) -> i32x4 {
 }
 
 #[lang = "sized"]
-trait Sized {}
+pub trait Sized : PhantomFn<Self> {}
 
 #[lang = "copy"]
-trait Copy {}
+pub trait Copy : PhantomFn<Self> {}
+
+#[lang="phantom_fn"]
+pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
 
 mod core {
     pub mod marker {
index 1e0570c95ac12f75977e06f514d003b990f2d41a..e1f36ecda53e83c5daaf73456b44b6c886688baa 100644 (file)
@@ -11,7 +11,7 @@
 pub static X: &'static str = "foobarbaz";
 pub static Y: &'static [u8] = include_bytes!("lib.rs");
 
-trait Foo {}
+trait Foo { fn dummy(&self) { } }
 impl Foo for uint {}
 
 pub fn dummy() {
index 365fc039a4ec37a6f8a2f93da4d6d437ecea7dc2..acda8705b19e30e22ad6b2cb662f9e74bb59d34c 100644 (file)
 #![feature(lang_items, no_std)]
 #![no_std]
 
+#[lang="phantom_fn"]
+trait PhantomFn<A:?Sized,R:?Sized=()> { }
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
+
 #[lang="copy"]
-trait Copy { }
+trait Copy : PhantomFn<Self> { }
 
 #[lang="sized"]
-trait Sized { }
+trait Sized : PhantomFn<Self>  { }
 
 #[lang="start"]
 fn start(_main: *const u8, _argc: int, _argv: *const *const u8) -> int { 0 }
index 195055f12d1e4010aa7a6fb147a60b8f170a1036..aecec44f6fd3df0e4cd6cbdec45dbbd5dcff17b9 100644 (file)
@@ -25,7 +25,7 @@ fn drop(&mut self) {
 }
 
 
-trait Trait {}
+trait Trait { fn dummy(&self) { } }
 impl Trait for Foo {}
 
 pub fn main() {
index 47e2a18a9992a95192f3de4d5672fc535cbdd599..c49a684de945df046b3015e2cd5b0a35488b865e 100644 (file)
@@ -19,7 +19,7 @@ fn drop(&mut self) {
     }
 }
 
-trait Trait {}
+trait Trait { fn dummy(&self) { } }
 impl Trait for Foo {}
 
 struct Fat<T: ?Sized> {
index 3314b613201595442e4373c320795b189bc380ad..f5521f7da853bd025b017cac1cf7a3a4d8c463fd 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait {
     type T;
 }
 
index f21b7183d70c46c5445081f762ed18c55af6f41f..aa65b0ed10bafe93e5521d26a074cbf801a9f25d 100644 (file)
@@ -14,6 +14,7 @@
 // `Target=[A]`, then the impl marked with `(*)` is seen to conflict
 // with all the others.
 
+use std::marker::PhantomData;
 use std::ops::Deref;
 
 pub trait MyEq<U: ?Sized=Self> {
@@ -41,7 +42,8 @@ fn eq(&self, other: &[B]) -> bool {
 }
 
 struct DerefWithHelper<H, T> {
-    pub helper: H
+    pub helper: H,
+    pub marker: PhantomData<T>,
 }
 
 trait Helper<T> {
@@ -63,7 +65,8 @@ fn deref(&self) -> &T {
 }
 
 pub fn check<T: MyEq>(x: T, y: T) -> bool {
-    let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x) };
+    let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x),
+                                                             marker: PhantomData };
     d.eq(&y)
 }
 
index d35b7331d4dbfa757b68f2d072decf3dc1e0991f..40ef7f3531cb5caf17247568f52fbc1ccd8a1de0 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we are able to have an impl that defines an associated type
 // before the actual trait.
 
+use std::marker::MarkerTrait;
+
 impl X for f64 { type Y = int; }
-trait X {type Y; }
+trait X : MarkerTrait { type Y; }
 fn main() {}
index ced44250e4d3907a75fd9ce6e60147eae1825508..3c91577362a7d4a27657ff5ebb20a72fa4990478 100644 (file)
@@ -20,7 +20,8 @@ fn parse(input: <Self as Parser>::Input) {
         panic!()
     }
 }
-impl <P> Parser for P  {
+
+impl <P> Parser for P {
     type Input = ();
 }
 
index e3227613159d1a2202ae09784268d3009fd96ddb..2ee8ef0d3ddac5a51267efcc4226697cf639bb28 100644 (file)
 
 // Test that we can resolve nested projection types. Issue #20666.
 
+use std::marker::MarkerTrait;
 use std::slice;
 
-trait Bound {}
+trait Bound : MarkerTrait {}
 
-impl<'a> Bound for &'a int {}
+impl<'a> Bound for &'a i32 {}
 
 trait IntoIterator {
     type Iter: Iterator;
index dd5814f875b0886e5490fed3a64bf567dc80a10e..de96af83f59171e040223af451d43f71d59b8f0d 100644 (file)
@@ -13,7 +13,9 @@
 
 #![allow(dead_code)]
 
-pub trait Integral {
+use std::marker::MarkerTrait;
+
+pub trait Integral : MarkerTrait {
     type Opposite;
 }
 
@@ -27,6 +29,8 @@ impl Integral for u32 {
 
 pub trait FnLike<A> {
     type R;
+
+    fn dummy(&self, a: A) -> Self::R { loop { } }
 }
 
 fn foo<T>()
index 1d264655bc479b03d0b70308627e54275c7e389c..8617750ca538ea02472b33bd0e77781960fba9df 100644 (file)
 // Test that we normalize associated types that appear in bounds; if
 // we didn't, the call to `self.split2()` fails to type check.
 
-struct Splits<'a, T, P>;
-struct SplitsN<I>;
+use std::marker::PhantomData;
+
+struct Splits<'a, T:'a, P>(PhantomData<(&'a T, P)>);
+struct SplitsN<I>(PhantomData<I>);
 
 trait SliceExt2 {
     type Item;
 
     fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P>
         where P: FnMut(&Self::Item) -> bool;
-    fn splitn2<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
+    fn splitn2<'a, P>(&'a self, n: u32, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
         where P: FnMut(&Self::Item) -> bool;
 }
 
@@ -30,7 +32,7 @@ fn split2<P>(&self, pred: P) -> Splits<T, P> where P: FnMut(&T) -> bool {
         loop {}
     }
 
-    fn splitn2<P>(&self, n: uint, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
+    fn splitn2<P>(&self, n: u32, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
         SliceExt2::split2(self, pred);
         loop {}
     }
index 742bab0578e9c2a9e3d25b47480583a4ed961327..94cfcb83653812347657560b6d6654cf16b65116 100644 (file)
 // Test that we normalize associated types that appear in bounds; if
 // we didn't, the call to `self.split2()` fails to type check.
 
-struct Splits<'a, T, P>;
-struct SplitsN<I>;
+use std::marker::PhantomData;
+
+struct Splits<'a, T, P>(PhantomData<(&'a(),T,P)>);
+struct SplitsN<I>(PhantomData<I>);
 
 trait SliceExt2 {
     type Item;
 
     fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P>
         where P: FnMut(&Self::Item) -> bool;
-    fn splitn2<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
+    fn splitn2<'a, P>(&'a self, n: usize, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
         where P: FnMut(&Self::Item) -> bool;
 }
 
@@ -30,7 +32,7 @@ fn split2<P>(&self, pred: P) -> Splits<T, P> where P: FnMut(&T) -> bool {
         loop {}
     }
 
-    fn splitn2<P>(&self, n: uint, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
+    fn splitn2<P>(&self, n: usize, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
         self.split2(pred);
         loop {}
     }
index 5aafe93067c138a058072ee94f3947e8c793826c..2288e19aae0bceaaa59131547736cc9cc3653fc9 100644 (file)
 
 
 pub trait OffsetState: Sized {}
-pub trait Offset { type State: OffsetState; }
+pub trait Offset {
+    type State: OffsetState;
+    fn dummy(&self) { }
+}
 
 #[derive(Copy)] pub struct X;
 impl Offset for X { type State = Y; }
index 0a1a8589dec82b55e56357d3bbf15fd0e01de2e6..c65d2db9b0cf0f3125849028aae506a4680827af 100644 (file)
@@ -13,6 +13,8 @@
 trait Int
 {
     type T;
+
+    fn dummy(&self) { }
 }
 
 trait NonZero
index 44dd49b72976edc3aafd4b3d859844ef903f32ee..a9c34a605ce163a5f2cfb842929ad6a3a7ce249d 100644 (file)
@@ -18,6 +18,8 @@
 
 pub trait Subscriber {
     type Input;
+
+    fn dummy(&self) { }
 }
 
 pub trait Publisher<'a> {
index e6fec675b03631a9f809487b2a0ca1fe62a70c8c..4d2358fae27b183f3440d83020b21563e4ee9139 100644 (file)
@@ -14,6 +14,8 @@
 trait A
 {
     type TA;
+
+    fn dummy(&self) { }
 }
 
 trait B<TB>
index 10a459f3c366268ba6dad0a4be210524b93c5495..3f3f4fbd1d628f46489096157ad484eb17cc8642 100644 (file)
@@ -13,6 +13,8 @@
 trait Int
 {
     type T;
+
+    fn dummy(&self) { }
 }
 
 trait NonZero
index 022c8f4cd013079fa62d997a86a65a7e3f0bf7de..67fe11d8feddec9cb3bd23833826746d2ce2b96b 100644 (file)
@@ -12,6 +12,8 @@
 
 pub trait Foo {
     type Bar;
+
+    fn dummy(&self) { }
 }
 
 impl Foo for int {
index e7a8061a3467aa4f6d8479fa2788829fccce42d4..a4b0b1a6e03af4281e88164f7b91e238250438e3 100644 (file)
@@ -15,6 +15,8 @@ trait Get<T> {
 trait Trait<'a> {
     type T: 'static;
     type U: Get<&'a int>;
+
+    fn dummy(&'a self) { }
 }
 
 fn main() {}
index 1ded34ff3ffe3bb3d588145ddef48a971bece42c..8667f6c8430aba03c706a9ae8d61bf273e920a5e 100644 (file)
@@ -13,6 +13,8 @@
 
 pub trait UnifyKey {
     type Value;
+
+    fn dummy(&self) { }
 }
 
 pub struct Node<K:UnifyKey> {
index 3669dec4fbdd469c2dc6e472547576a4f14cea47..9503f78a71b908ed469cfc109a4a11f89f9151b6 100644 (file)
@@ -13,6 +13,8 @@
 
 pub trait UnifyKey {
     type Value;
+
+    fn dummy(&self) { }
 }
 
 pub struct Node<K:UnifyKey>(K, K::Value);
index 3b70e941ac50a8c17ad63d9ff52a3b6e54d1f492..c068065ac6ae7e2167636a4ae336398c1bec9b8a 100644 (file)
@@ -31,8 +31,9 @@ pub fn bar<T: Foo>(a: T, x: T::A) -> T::A {
 // Using a type via an impl.
 trait C {
     fn f();
+    fn g(&self) { }
 }
-struct B<X>;
+struct B<X>(X);
 impl<T: Foo> C for B<T> {
     fn f() {
         let x: T::A = panic!();
index b6d428924e3e966b3102aecd481406ba56b98832..7bb9f042fe891ee418b2112c7f522f82fa54bbd7 100644 (file)
 #![feature(box_syntax)]
 
 extern crate collections;
-use std::collections::Bitv;
+use std::collections::BitVec;
 
 fn bitv_test() {
-    let mut v1 = box Bitv::from_elem(31, false);
-    let v2 = box Bitv::from_elem(31, true);
+    let mut v1 = box BitVec::from_elem(31, false);
+    let v2 = box BitVec::from_elem(31, true);
     v1.union(&*v2);
 }
 
index b39f03a93c9fee75c56c9948dd5510d3ed2288fe..a2b0fa566353041f8f6bc5720cf4629a18a398a8 100644 (file)
 // to the same lifetime on a trait succeeds. See issue #10766.
 
 #![allow(dead_code)]
+
+use std::marker;
+
 fn main() {
-    trait T {}
+    trait T { fn foo(&self) {} }
 
     fn f<'a, V: T>(v: &'a V) -> &'a T {
         v as &'a T
index ea711d78dd28e0bb890693b42e0b3d696739924a..143ebfdabfacefd6ce8cd1fdc05c430860e7f5a2 100644 (file)
@@ -9,10 +9,10 @@
 // except according to those terms.
 
 pub trait Foo<T> {
-    fn func1<U>(&self, t: U);
+    fn func1<U>(&self, t: U, w: T);
 
-    fn func2<U>(&self, t: U) {
-        self.func1(t);
+    fn func2<U>(&self, t: U, w: T) {
+        self.func1(t, w);
     }
 }
 
index c115415bb9b7b1739d1d12b1bc4b493586a8d1f0..7eaed910124d91ea2b31a1134f9ceb481e1d1994 100644 (file)
@@ -16,6 +16,7 @@
 extern crate trait_superkinds_in_metadata;
 use trait_superkinds_in_metadata::{RequiresRequiresShareAndSend, RequiresShare};
 use trait_superkinds_in_metadata::{RequiresCopy};
+use std::marker;
 
 #[derive(Copy)]
 struct X<T>(T);
index 7e1b28219373bf571d00b29f3b23fb12923072df..964c28dc94517a1d5da90bee404dcf02b0e4e236 100644 (file)
 // super-builtin-kind of a trait, if the type parameter is never used,
 // the type can implement the trait anyway.
 
+use std::marker;
+
 trait Foo : Send { }
 
-struct X<T>(());
+struct X<T> { marker: marker::PhantomData<T> }
 
-impl <T> Foo for X<T> { }
+impl<T:Send> Foo for X<T> { }
 
 pub fn main() { }
index 22c322b86c97963d800c3485a482d2c7aa2d846d..6246ee9c6c41a9ad4bdcd7c94cc8c8a1dfa9c82f 100644 (file)
@@ -24,12 +24,12 @@ mod mlibc {
 }
 
 fn atol(s: String) -> int {
-    let c = CString::from_slice(s.as_bytes());
+    let c = CString::new(s).unwrap();
     unsafe { mlibc::atol(c.as_ptr()) as int }
 }
 
 fn atoll(s: String) -> i64 {
-    let c = CString::from_slice(s.as_bytes());
+    let c = CString::new(s).unwrap();
     unsafe { mlibc::atoll(c.as_ptr()) as i64 }
 }
 
index 68457095944e30535e2de4df62c6c0785ef97539..b56a749d33bb85d9fef9501a9f777ce55b7e81da 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker::PhantomData;
+
 struct cat<U> {
     meows : uint,
-
     how_hungry : int,
+    m: PhantomData<U>
 }
 
 impl<U> cat<U> {
@@ -22,7 +24,8 @@ pub fn meow_count(&mut self) -> uint { self.meows }
 fn cat<U>(in_x : uint, in_y : int) -> cat<U> {
     cat {
         meows: in_x,
-        how_hungry: in_y
+        how_hungry: in_y,
+        m: PhantomData
     }
 }
 
index f8f92a56adb1a687c65033f37c1747f13b9a74d0..dce12030f79427caa502bb9f6c8cfc072ede4c76 100644 (file)
@@ -11,7 +11,7 @@
 #![feature(macro_rules)]
 
 use std::borrow::{Cow, IntoCow};
-use std::collections::Bitv;
+use std::collections::BitVec;
 use std::default::Default;
 use std::iter::FromIterator;
 use std::ops::Add;
@@ -63,8 +63,8 @@ macro_rules! tests {
     Vec::<()>::new, fn() -> Vec<()>, ();
     Vec::with_capacity, fn(uint) -> Vec<()>, (5);
     Vec::<()>::with_capacity, fn(uint) -> Vec<()>, (5);
-    Bitv::from_fn, fn(uint, fn(uint) -> bool) -> Bitv, (5, odd);
-    Bitv::from_fn::<fn(uint) -> bool>, fn(uint, fn(uint) -> bool) -> Bitv, (5, odd);
+    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);
@@ -100,8 +100,8 @@ macro_rules! tests {
     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, String, str>,
+    <String as IntoCow<_>>::into_cow, fn(String) -> Cow<'static, str>,
         ("foo".to_string());
-    <String as IntoCow<'static, _, _>>::into_cow, fn(String) -> Cow<'static, String, str>,
+    <String as IntoCow<'static, _>>::into_cow, fn(String) -> Cow<'static, str>,
         ("foo".to_string());
 }
index 02ab7e5db5b89e06e3f6d3d063c5a96e112346c4..5fe7c8bb94b4f2487b08aa027ea42af58a66a91b 100644 (file)
@@ -17,7 +17,7 @@ struct Person {
     phone: uint,
 }
 
-fn hash<T: Hash<SipHasher>>(t: &T) -> u64 {
+fn hash<T: Hash>(t: &T) -> u64 {
     std::hash::hash::<T, SipHasher>(t)
 }
 
index f45dce9da632e40070727ff9e9f2be28e14f2f45..62ec2f8e5902d80bc3bc894a56108339bb05e1bb 100644 (file)
@@ -20,7 +20,7 @@ struct Foo {
     baz: int
 }
 
-fn hash<T: Hash<SipHasher>>(_t: &T) {}
+fn hash<T: Hash>(_t: &T) {}
 
 pub fn main() {
     let a = Foo {bar: 4, baz: -3};
index d6a2fad08ed880fdc81146c4c25d09b9980be803..82cf9db3232c0f2251c2dded55bbff40820f931b 100644 (file)
@@ -17,7 +17,7 @@ struct Foo {
     baz: int
 }
 
-fn hash<T: Hash<SipHasher>>(_t: &T) {}
+fn hash<T: Hash>(_t: &T) {}
 
 pub fn main() {
     let a = Foo {bar: 4, baz: -3};
index dbad546ce1ae3fd1a427b91afa99d06deecaed6f..30ed0b8e4024581b9f2c360208b4fb581bcd9cd2 100644 (file)
@@ -11,7 +11,7 @@
 // Test coercions involving DST and/or raw pointers
 
 struct S;
-trait T {}
+trait T { fn dummy(&self) { } }
 impl T for S {}
 
 pub fn main() {
index 797c26556aaa1aa3de97fa7521ad350764e1d73f..023376ce4736ee6833e205314e4017e885cd023e 100644 (file)
@@ -16,7 +16,7 @@
 use std::rc::Rc;
 use std::sync::Arc;
 
-trait Trait {}
+trait Trait { fn dummy(&self) { } }
 
 fn main() {
     // Functions
index 066a5f9580ac42756f3c476b9dc9621df6321d61..382c5c58e92ee70adfde48df8f9c2c248706f94b 100644 (file)
 struct LM { resize_at: uint, size: uint }
 
 enum HashMap<K,V> {
-    HashMap_(LM)
+    HashMap_(LM, Vec<(K,V)>)
 }
 
-impl<K,V> Copy for HashMap<K,V> {}
-
 fn linear_map<K,V>() -> HashMap<K,V> {
     HashMap::HashMap_(LM{
         resize_at: 32,
-        size: 0})
+        size: 0}, Vec::new())
 }
 
 impl<K,V> HashMap<K,V> {
     pub fn len(&mut self) -> uint {
         match *self {
-            HashMap::HashMap_(l) => l.size
+            HashMap::HashMap_(ref l, _) => l.size
         }
     }
 }
diff --git a/src/test/run-pass/export-non-interference.rs b/src/test/run-pass/export-non-interference.rs
deleted file mode 100644 (file)
index 94652e3..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-enum list_cell<T> { cons(Box<list_cell<T>>), nil }
-
-pub fn main() { }
index 592ab7d0e6e36a1e292ccade23cfa30e35f9b8dc..24b711328a18ab0fb5681e0de0d07b15d844f3d1 100644 (file)
@@ -24,7 +24,7 @@ mod mlibc {
 
 fn strlen(str: String) -> uint {
     // C string is terminated with a zero
-    let s = CString::from_slice(str.as_bytes());
+    let s = CString::new(str).unwrap();
     unsafe {
         mlibc::my_strlen(s.as_ptr()) as uint
     }
index ed8c6e73255bb49dba6d56d7076a1798b1d5aceb..bf02b82d1a0754d5fbc8678965a4652417296aea 100644 (file)
 
 extern crate default_type_params_xc;
 
-struct Vec<T, A = default_type_params_xc::Heap>;
+struct Vec<T, A = default_type_params_xc::Heap>(Option<(T,A)>);
 
 struct Foo;
 
 fn main() {
-    let _a = Vec::<int>;
-    let _b = Vec::<int, default_type_params_xc::FakeHeap>;
-    let _c = default_type_params_xc::FakeVec::<int>;
-    let _d = default_type_params_xc::FakeVec::<int, Foo>;
+    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 };
 }
index 9c9f95f61e9be666c88d02f8bb38a03aa73ef416..7b16bb867e79c30004a1ac777e9a0c8fc2efe591 100644 (file)
@@ -18,7 +18,7 @@
 
 #![allow(dead_code)]
 
-use std::marker;
+use std::marker::PhantomData;
 
 #[derive(Copy)]
 struct Foo<T> { x: T }
@@ -26,7 +26,7 @@ struct Foo<T> { x: T }
 type Ty<'tcx> = &'tcx TyS<'tcx>;
 
 enum TyS<'tcx> {
-    Boop(marker::InvariantLifetime<'tcx>)
+    Boop(PhantomData<*mut &'tcx ()>)
 }
 
 #[derive(Copy)]
index f9b430c1553dd7b7b4ddfbcf95392bfef70e39ff..e4026a8fd0118a7fd5ea44920cabf0072ddb4548 100644 (file)
@@ -13,9 +13,9 @@
 extern crate inner_static;
 
 pub fn main() {
-    let a = inner_static::A::<()>;
-    let b = inner_static::B::<()>;
-    let c = inner_static::test::A::<()>;
+    let a = inner_static::A::<()> { v: () };
+    let b = inner_static::B::<()> { v: () };
+    let c = inner_static::test::A::<()> { v: () };
     assert_eq!(a.bar(), 2);
     assert_eq!(b.bar(), 4);
     assert_eq!(c.bar(), 6);
index b714d87f4ef20ded4df267149e55460e946622bc..da73c4b27ac4420e8b2145fc0b0a49c0e0f108c4 100644 (file)
@@ -14,7 +14,9 @@ pub trait Bar {
     fn bar(&self);
 }
 
-pub trait Baz {}
+pub trait Baz {
+    fn baz(&self) { }
+}
 
 impl<T: Baz> Bar for T {
     fn bar(&self) {}
index de2b4c51e52a96608cfdc1592a13b1b0d5075eac..174a69e1135cdf7a766ada2f71a70984dd537e7d 100644 (file)
@@ -29,7 +29,7 @@ fn drop(&mut self) {
     }
 }
 
-trait MyTrait { }
+trait MyTrait { fn dummy(&self) { } }
 impl MyTrait for Box<DroppableStruct> {}
 impl MyTrait for Box<DroppableEnum> {}
 
index 324a1701b2febdb4f4bb38d2fa360f06a22f5403..7fab6662ee01c3d3ee02d3bca9b5e9cf55228654 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub mod two_tuple {
-    pub trait T {}
+    pub trait T { fn dummy(&self) { } }
     pub struct P<'a>(&'a (T + 'a), &'a (T + 'a));
     pub fn f<'a>(car: &'a T, cdr: &'a T) -> P<'a> {
         P(car, cdr)
@@ -17,7 +17,7 @@ pub fn f<'a>(car: &'a T, cdr: &'a T) -> P<'a> {
 }
 
 pub mod two_fields {
-    pub trait T {}
+    pub trait T { fn dummy(&self) { } }
     pub struct P<'a> { car: &'a (T + 'a), cdr: &'a (T + 'a) }
     pub fn f<'a>(car: &'a T, cdr: &'a T) -> P<'a> {
         P{ car: car, cdr: cdr }
index d7c6c1b1bb2c2b65758865026a740e177059caee..1325b51a54ff2b6a4380f38bb7d64f8d9420846f 100644 (file)
@@ -12,7 +12,7 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-trait Foo {}
+trait Foo { fn dummy(&self) { } }
 impl Foo for int {}
 fn foo(_: [&Foo; 2]) {}
 fn foos(_: &[&Foo]) {}
index a511149b05e2ace11da32cc009b34a74a4009c1d..26634fabf5a1542f51726873c768f0689c67057b 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Common {}
+trait Common { fn dummy(&self) { } }
 
 impl<'t, T> Common for (T, &'t T) {}
 
index fa25d25df054e169d3a30bf79012bf08109b1d86..3c69377b375c6597cd865aa23f5af8cdb3ef1125 100644 (file)
@@ -12,7 +12,7 @@
 // We weren't updating the auto adjustments with all the resolved
 // type information after type check.
 
-trait A {}
+trait A { fn dummy(&self) { } }
 
 struct B<'a, T:'a> {
     f: &'a T
index 6fa450586947854cd806104820ab99d754273564..7cccac4483d49da1edfed2dd0c397493dc45c16d 100644 (file)
 
 // this code used to cause an ICE
 
-trait X<T> {}
+use std::marker;
+
+trait X<T> {
+    fn dummy(&self) -> T { panic!() }
+}
 
 struct S<T> {f: Box<X<T>+'static>,
              g: Box<X<T>+'static>}
 
 struct F;
-impl X<int> for F {}
+impl X<int> for F {
+}
 
 fn main() {
   S {f: box F, g: box F};
index d9bae6886fa2e6907b59721da70bc20c2495830c..b901e95ff55edb453c6a7b8642af99e394850d67 100644 (file)
 
 extern crate collections;
 
-use std::collections::Bitv;
+use std::collections::BitVec;
 use std::num::Float;
 
 fn main() {
     // Generate sieve of Eratosthenes for n up to 1e6
     let n = 1000000_usize;
-    let mut sieve = Bitv::from_elem(n+1, true);
+    let mut sieve = BitVec::from_elem(n+1, true);
     let limit: uint = (n as f32).sqrt() as uint;
     for i in 2..limit+1 {
         if sieve[i] {
index 7fab36bd64ec7b2c6c40ab36d6ff174f267cb468..64807dc44e061002632daecc7ade4bcb8a94eb7c 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait {
     fn quux(u8) {}
 }
 
index 7e533c2cf86c116cdf8d1b01722c2335a21afe43..db7eacce9d10b007292ae09dce9b550eef54543f 100644 (file)
@@ -19,7 +19,7 @@
 #[derive(Clone)]
 struct B1;
 
-trait A {}
+trait A { fn foo(&self) {} }
 impl A for B1 {}
 
 fn main() {
index d9763baa82657e10f0ff8030428ba062ef663d28..71d88ee6215103a991f81a0a2ea904f45ad3cf16 100644 (file)
 fn main() {
     send::<Box<Foo>>(box Output(0));
     Test::<Box<Foo>>::foo(box Output(0));
-    Test::<Box<Foo>>.send(box Output(0));
+    Test::<Box<Foo>>::new().send(box Output(0));
 }
 
 fn send<T>(_: T) {}
 
-struct Test<T>;
+struct Test<T> { marker: std::marker::PhantomData<T> }
 impl<T> Test<T> {
+    fn new() -> Test<T> { Test { marker: ::std::marker::PhantomData } }
     fn foo(_: T) {}
     fn send(&self, _: T) {}
 }
 
-trait Foo {}
+trait Foo { fn dummy(&self) { }}
 struct Output(int);
 impl Foo for Output {}
index 814a743648d3f6b0534f5af80551a326816ae6b3..6335f79be6c7aae7b547f67e33baa240f352fce9 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(unboxed_closures)]
 
-trait Foo {}
+trait Foo { fn dummy(&self) { }}
 
 struct Bar;
 
index 33281d7d78ffb178b8bebb99ecf60ccab0eaaf24..53d0f7dae05773bf0c3f630d61114779c89d3c52 100644 (file)
@@ -12,8 +12,8 @@
 
 use std::ops::Fn;
 
-trait Response {}
-trait Request {}
+trait Response { fn dummy(&self) { } }
+trait Request { fn dummy(&self) { } }
 trait Ingot<R, S> {
     fn enter(&mut self, _: &mut R, _: &mut S, a: &mut Alloy) -> Status;
 }
@@ -21,7 +21,7 @@ trait Ingot<R, S> {
 #[allow(dead_code)]
 struct HelloWorld;
 
-struct SendFile<'a>;
+struct SendFile;
 struct Alloy;
 enum Status {
     Continue
@@ -33,7 +33,7 @@ fn find<T>(&self) -> Option<T> {
     }
 }
 
-impl<'a, 'b> Fn<(&'b mut (Response+'b),)> for SendFile<'a> {
+impl<'b> Fn<(&'b mut (Response+'b),)> for SendFile {
     type Output = ();
 
     extern "rust-call" fn call(&self, (_res,): (&'b mut (Response+'b),)) {}
index c75c672546125bbbbef280a344252e4cb2d45b7f..6a4f78442d149943ded6817b5663f3580dbf339c 100644 (file)
 
 static mut DROP_RAN: bool = false;
 
-trait Bar<'b> {
+trait Bar {
     fn do_something(&mut self);
 }
 
-struct BarImpl<'b>;
+struct BarImpl;
 
-impl<'b> Bar<'b> for BarImpl<'b> {
+impl Bar for BarImpl {
     fn do_something(&mut self) {}
 }
 
 
-struct Foo<B>;
+struct Foo<B>(B);
 
 #[unsafe_destructor]
-impl<'b, B: Bar<'b>> Drop for Foo<B> {
+impl<B: Bar> Drop for Foo<B> {
     fn drop(&mut self) {
         unsafe {
             DROP_RAN = true;
@@ -37,7 +37,7 @@ fn drop(&mut self) {
 
 fn main() {
     {
-       let _x: Foo<BarImpl> = Foo;
+       let _x: Foo<BarImpl> = Foo(BarImpl);
     }
     unsafe {
         assert_eq!(DROP_RAN, true);
index e01de3a3262edefbe1f725de31b0c2839ee95f18..1ba7b142e5e15c957f35d44fd3de35ebc9f36f70 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait MatrixRow {}
+trait MatrixRow { fn dummy(&self) { }}
 
 struct Mat;
 
index b118c9573cdcf751c9949b6e4ab0c603fad9d374..4e57c55c5f755fd994b1b416f79dd3c6263a8016 100644 (file)
@@ -13,5 +13,5 @@
 extern crate "issue-16643" as i;
 
 pub fn main() {
-    i::TreeBuilder::<uint>.process_token();
+    i::TreeBuilder { h: 3u }.process_token();
 }
index 45e70f59f3397715a704ee054d3bf01c55150c3a..7bd41cc5b52a2fa06453d197100c5574c0b5daa4 100644 (file)
 
 extern crate "issue-17662" as i;
 
-struct Bar<'a>;
+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 }
 }
 
 pub fn main() {
-    assert_eq!(i::foo(&Bar), 5);
+    assert_eq!(i::foo(&Bar { m: marker::PhantomData }), 5);
 }
index b4bd55da597578a8b2ca860b3eba0137406b7489..de9611f259227caf28b801016b3fec51c246774c 100644 (file)
@@ -10,8 +10,9 @@
 
 trait Person {
     type string;
+    fn dummy(&self) { }
 }
 
-struct Someone<P: Person>;
+struct Someone<P: Person>(std::marker::PhantomData<P>);
 
 fn main() {}
index 1e9550acef4cb52483ac1894494c060c0118c71f..2f1b0342b8e04ad599d56f9ee164aa53b569a6f3 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Aaa {}
+trait Aaa { fn dummy(&self) { } }
 
 impl<'a> Aaa for &'a mut (Aaa + 'a) {}
 
index f8fbd680dcb9ecfddc59a9668fb9a5be4a065d8d..a976eccf89ec4c3166d9e366d66f1c4cc6635499 100644 (file)
 
 #![feature(unboxed_closures)]
 
+use std::marker::PhantomData;
+
 fn main() {
-    struct Symbol<'a, F: Fn(Vec<&'a str>) -> &'a str> { function: F }
+    struct Symbol<'a, F: Fn(Vec<&'a str>) -> &'a str> { function: F, marker: PhantomData<&'a ()> }
     let f = |x: Vec<&str>| -> &str "foobar";
-    let sym = Symbol { function: f };
+    let sym = Symbol { function: f, marker: PhantomData };
     (sym.function)(vec![]);
 }
index 3ce347d67e3d91f173ffbe55c69a5403dbac12f5..58a0872a5719b1ee2ef54d5ab7a338d3bf35ff95 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<T> where T: Copy;
+// Test that we can parse where clauses on various forms of tuple
+// structs.
+
 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 15cf5870d40add681c7557ff6d52a0115960b9c5..67b3239d35197044725b5f79c1011e4b9ef40af5 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Cursor<'a>;
+struct Cursor<'a>(::std::marker::PhantomData<&'a ()>);
 
 trait CursorNavigator {
     fn init_cursor<'a, 'b:'a>(&'a self, cursor: &mut Cursor<'b>) -> bool;
@@ -23,7 +23,7 @@ fn init_cursor<'a, 'b: 'a>(&'a self, _cursor: &mut Cursor<'b>) -> bool {
 }
 
 fn main() {
-    let mut c = Cursor;
+    let mut c = Cursor(::std::marker::PhantomData);
     let n = SimpleNavigator;
     n.init_cursor(&mut c);
 }
index 11ffb4198dad8c6b838a3ad1f0dcab79eb4ba9d5..16dd84315ed2cdadfcd1a7300b7ef1572aca864b 100644 (file)
@@ -24,7 +24,7 @@ fn bar<K, Q>(k: &K, q: &Q) where K: Borrow<Q>, Q: Foo {
     q.foo(k.borrow())
 }
 
-struct MyTree<K>;
+struct MyTree<K>(K);
 
 impl<K> MyTree<K> {
     // This caused a failure in #18906
index d95f74ef2a2ba8217c4b5ee48e5b5253240444b5..222f67af437ef327ad3232e8a972e05ef3c67d0b 100644 (file)
@@ -13,6 +13,8 @@
 
 trait Foo {
     type A;
+
+    fn dummy(&self) { }
 }
 
 fn bar(x: &Foo) {}
index d6b3a1908b82d6cb78b2619126ac7e56191199ef..cf0f48e025a0e037dd508ee1612c3a0555300f66 100644 (file)
@@ -11,7 +11,7 @@
 trait Trait<Input> {
     type Output;
 
-    fn method() -> bool { false }
+    fn method(&self, i: Input) -> bool { false }
 }
 
 fn main() {}
index 031a63ba474c181ae7b2a81438decc4a1c6a2627..5e6dd567d63288ff4c2621fc30f5efc25d91b897 100644 (file)
 
 #![feature(unboxed_closures)]
 
+use std::marker::PhantomData;
+
 #[derive(Debug)]
-struct LifetimeStruct<'a>;
+struct LifetimeStruct<'a>(PhantomData<&'a ()>);
 
 fn main() {
     takes_hrtb_closure(|lts| println!("{:?}", lts));
 }
 
 fn takes_hrtb_closure<F: for<'a>FnMut(LifetimeStruct<'a>)>(mut f: F) {
-    f(LifetimeStruct);
+    f(LifetimeStruct(PhantomData));
 }
index ff657376ecc1f848e51ee8b79f9ad3deacce6de0..8b5269ab92f03f89848ce94021d39671c56d70e6 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Trait {}
+trait Trait { fn dummy(&self) { } }
 
 #[derive(Debug)]
 struct Foo<T: Trait> {
index 1196162568a916c75ce6f812be1ec751a28d03c3..e603167b26be0a0c41b741d9d482e521fc4a128e 100644 (file)
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 trait T {
-    unsafe extern "Rust" fn foo();
+    unsafe extern "Rust" fn foo(&self);
 }
 
 impl T for () {
-    unsafe extern "Rust" fn foo() {}
+    unsafe extern "Rust" fn foo(&self) {}
 }
 
 fn main() {}
index 91bc645b2d486a4a2bce680b492d399af05e29ab..38a7af3a69597b72b3b48412ccfc2a0e490d5358 100644 (file)
@@ -8,12 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Base {}
+trait Base {
+    fn dummy(&self) { }
+}
 trait AssocA {
     type X: Base;
+    fn dummy(&self) { }
 }
 trait AssocB {
     type Y: Base;
+    fn dummy(&self) { }
 }
 impl<T: AssocA> AssocB for T {
     type Y = <T as AssocA>::X;
index 43116f63641ded4b5e868cce3731a7fc33e0a4a3..7bb0d055b844d9279925252e47810a88588aa10e 100644 (file)
@@ -10,6 +10,7 @@
 
 trait PoolManager {
     type C;
+    fn dummy(&self) { }
 }
 
 struct InnerPool<M> {
index 01a073a6889aedf28a7fee91eaa3e1f09d4ef3a2..4339339d74c88761f865def4492e3abf71e0cc01 100644 (file)
@@ -10,6 +10,7 @@
 
 trait PoolManager {
     type C;
+    fn dummy(&self) { }
 }
 
 struct InnerPool<M: PoolManager> {
index 836e78b5b51439e279a97499b9cf01899096b959..572a0d825282e7c5425690b47ef056f02954ae8b 100644 (file)
@@ -16,7 +16,9 @@
 // whichever arm is run, and subsequently dropped at the end of the
 // statement surrounding the `match`.
 
-trait Boo { }
+trait Boo {
+    fn dummy(&self) { }
+}
 
 impl Boo for [i8; 1] { }
 impl Boo for [i8; 2] { }
index 79034a4a4a6d65590e8980a10fd2c16eda2a03a6..2f9e8feed248234be96d211da10bc540442f03f7 100644 (file)
@@ -16,7 +16,7 @@ struct B { b: u32 }
 struct C;
 struct D;
 
-trait T<A> {}
+trait T<A> { fn dummy(&self, a: A) { } }
 impl<A> T<A> for () {}
 
 impl B {
index 911ee715da2811d3088c29496d1088f62efb6013..97c06ac98265fd6a8bec89b6cf5b93eaead6c849 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait T0 { type O; }
+trait T0 {
+    type O;
+    fn dummy(&self) { }
+}
 
 struct S<A>(A);
 impl<A> T0 for S<A> { type O = A; }
index a17c7b6ade48e4111b3cacd59b40d52e5590595b..d97017635718cfbcda8e502094d2b161c79ad09d 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait T0 { type O; }
+trait T0 {
+    type O;
+    fn dummy(&self) { }
+}
 
 struct S<A>(A);
 impl<A> T0 for S<A> { type O = A; }
index 2fc1d9fd6433c4c15dcdb7be41b8a1b5f33d7ee0..71bb3d39fe1d6c01dd61832864ebea9030ad0bb7 100644 (file)
@@ -12,6 +12,7 @@
 
 trait Iterator {
     type Item;
+    fn dummy(&self) { }
 }
 
 impl<'a, T> Iterator for &'a mut (Iterator<Item=T> + 'a) {
index 5bbc90b260639e0405b2ff91dd73a9ed510e1a40..55b61dd1945566f88f5740d7de4503aaad6c3439 100644 (file)
@@ -8,11 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait A<X> {}
+trait A<X> {
+    fn dummy(&self, arg: X);
+}
 
 trait B {
     type X;
     type Y: A<Self::X>;
+
+    fn dummy(&self);
 }
 
 fn main () { }
index e0b98ab19652a40e302c4c5ef0d470aecffea249..5529d51b408c0782dde9c985ee71c364f211a5f3 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait clam<A> { }
+trait clam<A> {
+    fn get(self) -> A;
+}
+
 struct foo<A> {
     x: A,
 }
index dc873ed08d701c6603359804c971309627bc62e1..b6b3114e2a487c3a07963eb8a6a1e39bfb2b1219 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait clam<A> { }
+trait clam<A> { fn get(self) -> A; }
 trait foo<A> {
    fn bar<B,C:clam<A>>(&self, c: C) -> B;
 }
index 8c597552d75aadb81a502a9e1050c5dab682d7e9..3f273b56efd6cc4ab90cfec83fa4f28d3979e2d1 100644 (file)
@@ -10,7 +10,7 @@
 
 // Testing that the B's are resolved
 
-trait clam<A> { }
+trait clam<A> { fn get(self) -> A; }
 
 struct foo(int);
 
index b8136323df66400dc6a230f23a5dcb097b34c759..a5a05283f80fde1f97420b3d90fe724bb63f414d 100644 (file)
@@ -10,9 +10,9 @@
 // except according to those terms.
 
 extern crate collections;
-use std::collections::RingBuf;
+use std::collections::VecDeque;
 
 pub fn main() {
-    let mut q = RingBuf::new();
+    let mut q = VecDeque::new();
     q.push_front(10);
 }
index 2608c89d15567d1a6d83739150c5a250ad2209dd..c005699ce30b4f19911944ed5d64f60730a917f5 100644 (file)
@@ -12,7 +12,7 @@
 // than the traits require.
 
 trait A {
-  fn b<C:Sync,D>(x: C) -> C;
+  fn b<C:Sync,D>(&self, x: C) -> C;
 }
 
 struct E {
@@ -20,7 +20,7 @@ struct E {
 }
 
 impl A for E {
-  fn b<F,G>(_x: F) -> F { panic!() }
+  fn b<F,G>(&self, _x: F) -> F { panic!() }
   //~^ ERROR in method `b`, type parameter 0 has 1 bound, but
 }
 
index 7ca439a1a19dfa5861d5a90334c41df77e42f824..a7b53db6b0553f173988fa4b63e33ada1eac2fca 100644 (file)
@@ -11,7 +11,9 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-trait hax { }
+trait hax {
+    fn dummy(&self) { }
+}
 impl<A> hax for A { }
 
 fn perform_hax<T: 'static>(x: Box<T>) -> Box<hax+'static> {
index 962359537bf2917e492053b9d9dcdf480f8be14a..1594b94879cee099cdb31a22a7eb6bc9f1c2921d 100644 (file)
@@ -11,7 +11,9 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-trait hax { }
+trait hax {
+    fn dummy(&self) { }
+}
 impl<A> hax for A { }
 
 fn perform_hax<T: 'static>(x: Box<T>) -> Box<hax+'static> {
index 2ed662e9f2d6039ad0cbab6383550f43a2c7af20..d660f300ada99f4ac26cb4a86734966443c22d19 100644 (file)
@@ -9,14 +9,14 @@
 // except according to those terms.
 
 pub fn main() {
-    let _id: &Mat2<f64> = &Matrix::identity();
+    let _id: &Mat2<f64> = &Matrix::identity(1.0);
 }
 
-pub trait Index<Index,Result> { }
+pub trait Index<Index,Result> { fn get(&self, Index) -> Result { panic!() } }
 pub trait Dimensional<T>: Index<uint, T> { }
 
-pub struct Mat2<T> { x: () }
-pub struct Vec2<T> { x: () }
+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> { }
@@ -25,9 +25,9 @@ impl<T> Dimensional<T> for Vec2<T> { }
 impl<T> Index<uint, T> for Vec2<T> { }
 
 pub trait Matrix<T,V>: Dimensional<V> {
-    fn identity() -> Self;
+    fn identity(t:T) -> Self;
 }
 
 impl<T> Matrix<T, Vec2<T>> for Mat2<T> {
-    fn identity() -> Mat2<T> { Mat2{ x: () } }
+    fn identity(t:T) -> Mat2<T> { Mat2{ x: t } }
 }
index bb79cd4d0466744e1066cdae0c72dac22f407ea7..a6f3771bf62b450aeb9c6ab0fbdca55dd98865d3 100644 (file)
@@ -12,6 +12,7 @@
 #![feature(box_syntax)]
 
 pub trait EventLoop {
+    fn dummy(&self) { }
 }
 
 pub struct UvEventLoop {
index fd39bcc6b61216fe4fc69d6acc3de8e73b92d263..59bca87bed0b61a8432cf09be88ff86ebaf2ea17 100644 (file)
@@ -48,7 +48,9 @@ pub fn main() {
 
 
 // minimal
-pub trait MyTrait<T> { }
+pub trait MyTrait<T> {
+    fn dummy(&self, t: T) -> T { panic!() }
+}
 
 pub struct MyContainer<'a, T> {
     foos: Vec<&'a (MyTrait<T>+'a)> ,
index d96862b588f9d58b3610500f0b85af67ad5de60a..1746a6281dc2694a33144dc917a69f8b32327af9 100644 (file)
@@ -17,6 +17,7 @@
 
 trait Graph<Node, Edge> {
     fn f(&self, Edge);
+    fn g(&self, Node);
 
 }
 
@@ -24,6 +25,9 @@ impl<E> Graph<int, E> for HashMap<int, int> {
     fn f(&self, _e: E) {
         panic!();
     }
+    fn g(&self, _e: int) {
+        panic!();
+    }
 }
 
 pub fn main() {
index 1d8fe8bfce82c6a643952d6f182ab7f85190825c..6e608d34bd5781d9a4777f27fb6b37d51d007ca9 100644 (file)
@@ -15,7 +15,9 @@ pub enum Thing {
     A(Box<Foo+'static>)
 }
 
-pub trait Foo {}
+pub trait Foo {
+    fn dummy(&self) { }
+}
 
 pub struct Struct;
 
index 225213db6a4251f47c10281c5557e7d165341d07..77cfc7f0cf607dc2aa15b84089e2c1d9c11b170a 100644 (file)
@@ -10,6 +10,7 @@
 
 trait Foo {
     fn new() -> bool { false }
+    fn dummy(&self) { }
 }
 
 trait Bar {
index b6dfbb1ca42ad2a431f324761c18a5eb22e4d127..736860947f23cb0c149718be36ba0a940a6bfd2b 100644 (file)
 
 pub fn main() {}
 
-trait A {}
+trait A {
+    fn dummy(&self) { }
+}
+
 impl<T: 'static> A for T {}
 
 fn owned2<T: 'static>(a: Box<T>) { a as Box<A>; }
index 86948ebcb91e0e4dbf2de046876376d3508a3f41..3eb593708bee82e3651a74875f4ec1e418bb1e70 100644 (file)
@@ -14,7 +14,9 @@
 // with different mutability in macro in two methods
 
 #![allow(unused_variable)] // unused foobar_immut + foobar_mut
-trait FooBar {}
+trait FooBar {
+    fn dummy(&self) { }
+}
 struct Bar(i32);
 struct Foo { bar: Bar }
 
index 377b9ce262c73ab194cc140535df1fac77218e97..7bc8dbe616ff31315a38f842227f17955ba6fdac 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait A {}
+trait A {
+    fn dummy(&self) { }
+}
 struct B;
 impl A for B {}
 
index 44f07def531bced6272ef9157c3f544e4f6cdb0d..83c9e9bf4505334dd990dc3e6f6c4a81bd00cd05 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait A {}
+trait A {
+    fn dummy(&self) { }
+}
 struct B;
 impl A for B {}
 
index 8fc86eb49e769c061018198516df95ac47da65bd..aa1e65efaa41e49b87a8651caa213af1b2091278 100644 (file)
@@ -13,7 +13,9 @@ pub enum Enum<T> {
         A(T),
     }
 
-    pub trait X {}
+    pub trait X {
+        fn dummy(&self) { }
+    }
     impl X for int {}
 
     pub struct Z<'a>(Enum<&'a (X+'a)>);
@@ -21,7 +23,9 @@ impl X for int {}
 }
 
 mod b {
-    trait X {}
+    trait X {
+        fn dummy(&self) { }
+    }
     impl X for int {}
     struct Y<'a>{
         x:Option<&'a (X+'a)>,
index 2194453aac29aded856ee6917f20de869c1d6aeb..f180ffcd4e823763d6f601abb448b3d3ab640ba0 100644 (file)
@@ -15,7 +15,7 @@
 }
 
 trait A {
-    fn foo() {
+    fn foo(&self) {
         unsafe {
             rust_get_test_int();
         }
index 25ce0d774ebc1caaf5a40987412ce7dc8cead135..cec9753a2fecaed27bcb197162ed4f4fef01cde2 100644 (file)
 
 #![allow(dead_code)]
 
-struct Cursor<'a>;
+use std::marker;
+
+struct Cursor<'a> {
+    m: marker::PhantomData<&'a ()>
+}
 
 trait CursorNavigator {
     fn init_cursor<'a, 'b:'a>(&'a self, cursor: &mut Cursor<'b>) -> bool;
@@ -28,7 +32,7 @@ fn init_cursor<'a, 'b: 'a>(&'a self, _cursor: &mut Cursor<'b>) -> bool {
 }
 
 fn main() {
-    let mut c = Cursor;
+    let mut c = Cursor { m: marker::PhantomData };
     let n = SimpleNavigator;
     n.init_cursor(&mut c);
 }
index 338bd89ab5cb1e55e833fe478a790b04d849b382..15eb2ae2e4b49dbfa97f5258e67d03a9c7b1d448 100644 (file)
 
 // Note: this must be generic for the problem to show up
 trait Foo<A> {
-    fn foo(&self);
+    fn foo(&self, a: A);
 }
 
 impl Foo<u8> for [u8] {
-    fn foo(&self) {}
+    fn foo(&self, a: u8) {}
 }
 
 impl<'a, A, T> Foo<A> for &'a T where T: Foo<A> {
-    fn foo(&self) {
-        Foo::foo(*self)
+    fn foo(&self, a: A) {
+        Foo::foo(*self, a)
     }
 }
 
index eb17aa78bd9a8b75a7872b540fdab1bbc206b0cf..1164ef1a3c98e2406e83e7c0992cd2b0440c383a 100644 (file)
@@ -8,8 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker::MarkerTrait;
 
-trait Serializer {
+trait Serializer : MarkerTrait {
 }
 
 trait Serializable {
index be2b309b8217ffa78f8931ceff6925ea25c03b4b..d50f2efe0e7b4cab54f64e42ffb2c990619cfa43 100644 (file)
@@ -11,7 +11,8 @@
 use std::ops::Deref;
 
 struct DerefWithHelper<H, T> {
-    helper: H
+    helper: H,
+    value: T
 }
 
 trait Helper<T> {
@@ -39,6 +40,7 @@ fn foo(&self) -> int {self.x}
 }
 
 pub fn main() {
-    let x: DerefWithHelper<Option<Foo>, Foo> = DerefWithHelper { helper: Some(Foo {x: 5}) };
+    let x: DerefWithHelper<Option<Foo>, Foo> =
+        DerefWithHelper { helper: Some(Foo {x: 5}), value: Foo { x: 2 } };
     assert!(x.foo() == 5);
 }
index 2838909c1be625b16f102c1963932bd5f2257845..2ef9e08134cf7259fcf5dde6a4f99a59ac889bdb 100644 (file)
 
 #![feature(unboxed_closures)]
 
+use std::marker::PhantomData;
 use std::ops::Fn;
 use std::ops::Add;
 
-struct G<A>;
+struct G<A>(PhantomData<A>);
 
 impl<'a, A: Add<i32, Output=i32>> Fn<(A,)> for G<A> {
     type Output = i32;
@@ -27,5 +28,5 @@ extern "rust-call" fn call(&self, (arg,): (A,)) -> i32 {
 
 fn main() {
     // ICE trigger
-    G(1_i32);
+    (G(PhantomData))(1_i32);
 }
index 840e58848a742f59b31af183bcb70508365a05de..061c9168955a49c73db68dc7ba3700ed72b20a3d 100644 (file)
 #![allow(dead_code)]
 
 
-trait A<T> {}
-trait B<T, U> {}
-trait C<'a, U> {}
+trait A<T> { fn get(self) -> T; }
+trait B<T, U> { fn get(self) -> (T,U); }
+trait C<'a, U> { fn get(self) -> &'a U; }
 
 mod foo {
-    pub trait D<'a, T> {}
+    pub trait D<'a, T> { fn get(self) -> &'a T; }
 }
 
 fn foo1<T>(_: &(A<T> + Send)) {}
index f3380352f5fa946c96a52c215461adffebb508eb..e9b8e694d60605c3e445102a97571429b1eaada5 100644 (file)
@@ -19,6 +19,7 @@
 // public type, private value
 pub mod foo1 {
     pub trait Bar {
+        fn dummy(&self) { }
     }
     pub struct Baz;
 
@@ -50,6 +51,7 @@ fn test_glob1() {
 // private type, public value
 pub mod foo2 {
     trait Bar {
+        fn dummy(&self) { }
     }
     pub struct Baz;
 
@@ -81,6 +83,7 @@ fn test_glob2() {
 // public type, public value
 pub mod foo3 {
     pub trait Bar {
+        fn dummy(&self) { }
     }
     pub struct Baz;
 
index 6b629a9035db2538504b947f0534e9b17070e317..80ae371e5091e76638e104697a0ff63799b7a450 100644 (file)
 // Test that the compiler considers the 'static bound declared in the
 // trait. Issue #20890.
 
-trait Foo { type Value: 'static; }
+trait Foo {
+    type Value: 'static;
+    fn dummy(&self) { }
+}
 
 fn require_static<T: 'static>() {}
 
index 0a95a89d57c325a150b759fad8bb1bf3d4519030..a06e0f6da785a1c7a4dc5079bb89b605627e2b84 100644 (file)
@@ -12,7 +12,9 @@
 
 #![feature(issue_5723_bootstrap)]
 
-trait Foo { }
+trait Foo {
+    fn dummy(&self) { }
+}
 
 fn foo<'a, 'b, 'c:'a+'b, 'd>() {
 }
index c5baecf7272fae1311fb9abc3918998897c709ed..996583dc6de93eb49b1b9cfe67d7865f58636b28 100644 (file)
@@ -12,8 +12,9 @@
 
 #![feature(issue_5723_bootstrap)]
 
-
-trait Foo { }
+trait Foo {
+    fn dummy(&self) { }
+}
 
 fn foo<'a>(x: Box<Foo + 'a>) {
 }
index 978383c244780be12dd1e317258f68f37d2c2e5e..bdc0d41c94e823cdaa9777b1589aa5fb278c3f86 100644 (file)
@@ -14,6 +14,8 @@
 // lifetime parameters must be early bound in the type of the
 // associated item.
 
+use std::marker;
+
 pub enum Value<'v> {
     A(&'v str),
     B,
@@ -23,7 +25,9 @@ pub trait Decoder<'v> {
     fn read(&mut self) -> Value<'v>;
 }
 
-pub trait Decodable<'v, D: Decoder<'v>> {
+pub trait Decodable<'v, D: Decoder<'v>>
+    : marker::PhantomFn<(), &'v int>
+{
     fn decode(d: &mut D) -> Self;
 }
 
index 6fcfaf58a023b01cd5390f9db4cc11b52eed7297..3f434a4838d42bb10f720f278e4be48660b5ea11 100644 (file)
@@ -53,11 +53,11 @@ fn field_invoke2<'l, 'm, 'n>(x: &'n Struct2<'l,'m>) -> int {
     x.f.short()
 }
 
-trait MakerTrait<'o> {
+trait MakerTrait {
     fn mk() -> Self;
 }
 
-fn make_val<'p, T:MakerTrait<'p>>() -> T {
+fn make_val<T:MakerTrait>() -> T {
     MakerTrait::mk()
 }
 
@@ -80,7 +80,7 @@ fn short<'b>(&'b self) -> int {
     }
 }
 
-impl<'t> MakerTrait<'t> for Box<Trait<'t>+'static> {
+impl<'t> MakerTrait for Box<Trait<'t>+'static> {
     fn mk() -> Box<Trait<'t>+'static> { box() (4,5) as Box<Trait> }
 }
 
diff --git a/src/test/run-pass/regions-infer-bivariance.rs b/src/test/run-pass/regions-infer-bivariance.rs
deleted file mode 100644 (file)
index a3288e2..0000000
+++ /dev/null
@@ -1,28 +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.
-
-// Test that a type whose lifetime parameters is never used is
-// inferred to be bivariant.
-
-use std::marker;
-
-struct Bivariant<'a>;
-
-fn use1<'short,'long>(c: Bivariant<'short>,
-                      _where:Option<&'short &'long ()>) {
-    let _: Bivariant<'long> = c;
-}
-
-fn use2<'short,'long>(c: Bivariant<'long>,
-                      _where:Option<&'short &'long ()>) {
-    let _: Bivariant<'short> = c;
-}
-
-pub fn main() {}
diff --git a/src/test/run-pass/regions-issue-21422.rs b/src/test/run-pass/regions-issue-21422.rs
new file mode 100644 (file)
index 0000000..c59bf15
--- /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.
+
+// Regression test for issue #21422, which was related to failing to
+// add inference constraints that the operands of a binary operator
+// should outlive the binary operation itself.
+
+pub struct P<'a> {
+    _ptr: *const &'a u8,
+}
+
+impl <'a> PartialEq for P<'a> {
+    fn eq(&self, other: &P<'a>) -> bool {
+        (self as *const _) == (other as *const _)
+    }
+}
+
+fn main() {}
index d3464f01203ac5f3adb5cb24587be0eb7ff622aa..5964ac65d5f6e977dc24b1bc0c7226ab93ed3146 100644 (file)
@@ -10,7 +10,9 @@
 
 #![feature(unsafe_destructor)]
 
-pub struct Foo<T>;
+use std::marker;
+
+pub struct Foo<T>(marker::PhantomData<T>);
 
 impl<T> Iterator for Foo<T> {
     type Item = T;
index a35ab1bfc0ce6b80445161dbb2d26d66ed0e3ff2..80c478afa644f2b2b1be49301bb3fd75fef35f18 100644 (file)
@@ -12,7 +12,9 @@
 // should not upset the variance inference for actual occurrences of
 // that lifetime in type expressions.
 
-pub trait HasLife<'a> { }
+pub trait HasLife<'a> {
+    fn dummy(&'a self) { } // just to induce a variance on 'a
+}
 
 trait UseLife01 {
     fn refs<'a, H: HasLife<'a>>(&'a self) -> H;
@@ -23,7 +25,11 @@ trait UseLife02 {
 }
 
 
-pub trait HasType<T> { }
+pub trait HasType<T>
+{
+    fn dummy(&self, t: T) -> T { panic!() }
+}
+
 
 trait UseLife03<T> {
     fn refs<'a, H: HasType<&'a T>>(&'a self) -> H;
index 10c9aef7c3b1e2101bd51776f650c0fdf29827e4..a224017780e2d936419b6ca4f6ec7e235b527b9c 100644 (file)
@@ -19,7 +19,7 @@
 #[cfg(cannot_use_this_yet)]
 fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) {
     let one = [1_usize];
-    assert_eq!(map.borrow().get("one"), Some(&one[]));
+    assert_eq!(map.borrow().get("one"), Some(&one[..]));
 }
 
 #[cfg(cannot_use_this_yet_either)]
@@ -45,9 +45,9 @@ fn main() {
     let one = [1u8];
     let two = [2u8];
     let mut map = HashMap::new();
-    map.insert("zero", &zer[]);
-    map.insert("one",  &one[]);
-    map.insert("two",  &two[]);
+    map.insert("zero", &zer[..]);
+    map.insert("one",  &one[..]);
+    map.insert("two",  &two[..]);
     let map = RefCell::new(map);
     foo(map);
 }
index a21b5aa1dab6c5795b4e82c2e75d2076ccba7a27..abe6ffe7d4ccaabdbac3ef7d7bf4a63cf364ba78 100644 (file)
@@ -31,12 +31,12 @@ fn rename_directory() {
         let test_file = &old_path.join("temp.txt");
 
         /* Write the temp input file */
-        let fromp = CString::from_slice(test_file.as_vec());
-        let modebuf = CString::from_slice(b"w+b");
+        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::from_slice(b"hello");
+        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,
index 40a4dc52a70b303585832efd3aae666a5414d76b..af2b2de8ab8ba19473b9108dc5601be028ea88e9 100644 (file)
@@ -29,6 +29,7 @@ pub struct Baz<X> {
 
 trait Bar<X> {
     fn bar(x: Self, y: &Self, z: Box<Self>) -> Self;
+    fn dummy(&self, x: X) { }
 }
 
 impl Bar<int> for Box<Baz<int>> {
index c58654670d1a3f4bb4b90e9956595fb19893df48..33e4fa85bcb81003f155d1f4030e98c37b84acac 100644 (file)
@@ -13,7 +13,7 @@
 use std::collections::HashMap;
 use std::borrow::{Cow, IntoCow};
 
-type SendStr = Cow<'static, String, str>;
+type SendStr = Cow<'static, str>;
 
 pub fn main() {
     let mut map: HashMap<SendStr, uint> = HashMap::new();
index 438724a2b06bfc97ffa19d8cfe64719c18d1aa4c..3390369242d13943222cd5d9077b53712d0d9f29 100644 (file)
@@ -13,7 +13,7 @@
 use self::collections::BTreeMap;
 use std::borrow::{Cow, IntoCow};
 
-type SendStr = Cow<'static, String, str>;
+type SendStr = Cow<'static, str>;
 
 pub fn main() {
     let mut map: BTreeMap<SendStr, uint> = BTreeMap::new();
index 7ed8cb434caf5517baa963c9612f8386e8ae5f62..2217dddbd21f0884a2efa04a48e7a97fb0a8ade6 100644 (file)
@@ -8,11 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-
-enum opt<T> { none, }
+enum opt<T> { none, some(T) }
 
 pub fn main() {
     let x = opt::none::<int>;
-    match x { opt::none::<int> => { println!("hello world"); } }
+    match x {
+        opt::none::<int> => { println!("hello world"); }
+        opt::some(_) => { }
+    }
 }
index 3344844d49ff786523bf094b4af715906895e40d..340ad2a531a738188d19b7596dd5e99f859c81da 100644 (file)
 
 #![feature(optin_builtin_traits)]
 
-use std::marker::Send;
+use std::marker::{MarkerTrait, Send};
 
 struct TestType;
 
 impl TestType {}
 
-trait TestTrait {}
+trait TestTrait : MarkerTrait {}
 
 impl !Send for TestType {}
 
-struct TestType2<T>;
+struct TestType2<T>(T);
 
 impl<T> TestType2<T> {}
 
index b5ae259bc630ea523f995225d11f45a2bdf1bbf5..76c62a83e758c4cdeea93c688da99ac12992f01f 100644 (file)
@@ -12,7 +12,7 @@
 
 fn f<T,>(_: T,) {}
 
-struct Foo<T,>;
+struct Foo<T,>(T);
 
 struct Bar;
 
@@ -34,7 +34,7 @@ pub fn main() {
     let [_, _, .., _,] = [1, 1, 1, 1,];
     let [_, _, _.., _,] = [1, 1, 1, 1,];
 
-    let x: Foo<int,> = Foo::<int,>;
+    let x: Foo<int,> = Foo::<int,>(1);
 
     Bar::f(0,);
     Bar.g(0,);
index d03496403ad2a629a349cbb94f14f59f4fc801f4..ed25bf8b02e88fd6852338287eab01bc53640638 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
 }
 
 fn b(_x: Box<Foo+Send>) {
index e3234f037547b66235bae0318cd3c9cca449ced4..976120908b27ab376ebbee497f13573a3b07bca0 100644 (file)
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait U {}
-trait T<X: U> {}
+trait U : ::std::marker::MarkerTrait {}
+trait T<X: U> { fn get(self) -> X; }
 
-trait S2<Y: U> {
+trait S2<Y: U> : ::std::marker::MarkerTrait {
     fn m(x: Box<T<Y>+'static>) {}
 }
 
index 49f8999cd45e4229cd76436bfe99cb2c2beea8dd..7135dad7d190c9d96950581753986c946157c04b 100644 (file)
 
 trait I { fn i(&self) -> Self; }
 
-trait A<T:I> {
+trait A<T:I> : ::std::marker::MarkerTrait {
     fn id(x:T) -> T { x.i() }
 }
 
-trait J<T> { fn j(&self) -> Self; }
+trait J<T> { fn j(&self) -> T; }
 
-trait B<T:J<T>> {
+trait B<T:J<T>> : ::std::marker::MarkerTrait {
     fn id(x:T) -> T { x.j() }
 }
 
-trait C {
+trait C : ::std::marker::MarkerTrait {
     fn id<T:J<T>>(x:T) -> T { x.j() }
 }
 
index 3efe2507470d9dfc53d4c5d10a33d21bd662b950..383849ca51267532abe21f9b51b960caa721ff84 100644 (file)
@@ -11,6 +11,7 @@
 
 trait A<T> {
     fn g(&self, x: uint) -> uint { x }
+    fn h(&self, x: T) { }
 }
 
 impl<T> A<T> for int { }
index 16ef315c206d5689193d7bd607aa32bc06ad14ff..325fba8a0ee4288fe1852189e716733692faa59f 100644 (file)
@@ -16,7 +16,9 @@
 
 static mut COUNT: uint = 1;
 
-trait T {}
+trait T {
+    fn t(&self) {}
+}
 
 impl<'a> T+'a {
     fn foo(&self) {
index 1e6e7227a067cc5fc915a973dd9748f69cd33723..f89eea46090d07884eb8d8795a54fb2a49d2c087 100644 (file)
@@ -14,8 +14,7 @@
 use std::cmp::{PartialEq, PartialOrd};
 use std::num::NumCast;
 
-pub trait TypeExt {}
-
+pub trait TypeExt : ::std::marker::MarkerTrait { }
 
 impl TypeExt for u8 {}
 impl TypeExt for u16 {}
index 3b454aad03e480a7c00ca8ee78a8d2ceba911833..8f3b325a513fe2f739a0d28f9c7ffd433d6de06e 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait MyEq { }
+pub trait MyEq : ::std::marker::MarkerTrait { }
 
-pub trait MyNum {
+pub trait MyNum : ::std::marker::MarkerTrait {
     fn from_int(int) -> Self;
 }
 
index 76352c799a0f2728805de9e25302f04d9c0b0e3a..6f89490716f081d123628285840d0404d4c17222 100644 (file)
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
+use std::marker;
+
 pub trait Trait2<A> {
-    fn doit(&self);
+    fn doit(&self) -> A;
 }
 
 pub struct Impl<A1, A2, A3> {
+    m1: marker::PhantomData<(A1,A2,A3)>,
     /*
      * With A2 we get the ICE:
      * task <unnamed> failed at 'index out of bounds: the len is 1 but the index is 1',
@@ -28,13 +31,13 @@ pub struct Impl<A1, A2, A3> {
 
 impl<A1, A2, A3> Impl<A1, A2, A3> {
     pub fn step(&self) {
-        self.t.doit()
+        self.t.doit();
     }
 }
 
 // test for #8601
 
-enum Type<T> { Constant }
+enum Type<T> { Constant(T) }
 
 trait Trait<K,V> {
     fn method(&self,Type<(K,V)>) -> int;
@@ -46,5 +49,5 @@ fn method(&self, _x: Type<(u8,V)>) -> int { 0 }
 
 pub fn main() {
     let a = box() () as Box<Trait<u8, u8>>;
-    assert_eq!(a.method(Type::Constant), 0);
+    assert_eq!(a.method(Type::Constant((1u8, 2u8))), 0);
 }
index a8cea24db0c0c15ef051de3e62be26e6a8c5c601..10439d5c86aa35721e6bb5e8ea4b8fd3a1717d4f 100644 (file)
@@ -10,7 +10,7 @@
 // except according to those terms.
 
 mod base {
-    pub trait HasNew<T> {
+    pub trait HasNew {
         fn new() -> Self;
     }
 
@@ -18,7 +18,7 @@ pub struct Foo {
         dummy: (),
     }
 
-    impl ::base::HasNew<Foo> for Foo {
+    impl ::base::HasNew for Foo {
         fn new() -> Foo {
             println!("Foo");
             Foo { dummy: () }
@@ -29,7 +29,7 @@ pub struct Bar {
         dummy: (),
     }
 
-    impl ::base::HasNew<Bar> for Bar {
+    impl ::base::HasNew for Bar {
         fn new() -> Bar {
             println!("Bar");
             Bar { dummy: () }
@@ -38,6 +38,6 @@ fn new() -> Bar {
 }
 
 pub fn main() {
-    let _f: base::Foo = base::HasNew::<base::Foo>::new();
-    let _b: base::Bar = base::HasNew::<base::Bar>::new();
+    let _f: base::Foo = base::HasNew::new();
+    let _b: base::Bar = base::HasNew::new();
 }
index 5d3195e193708000d99dd4c2df28abeeb33bf9e4..7e0f60d55a827acb3dbfff0b0e28408c1ce8b90f 100644 (file)
 
 pub trait GraphWalk<'c, N> {
     /// Returns all the nodes in this graph.
-    fn nodes(&'c self) where [N]:ToOwned<Vec<N>>;
+    fn nodes(&'c self) where [N]:ToOwned<Owned=Vec<N>>;
 }
 
 impl<'g> GraphWalk<'g, Node<'g>> for u32
 {
-    fn nodes(&'g self) where [Node<'g>]:ToOwned<Vec<Node<'g>>>
+    fn nodes(&'g self) where [Node<'g>]:ToOwned<Owned=Vec<Node<'g>>>
     { loop { } }
 }
 
 impl<'h> GraphWalk<'h, Node<'h>> for u64
 {
-    fn nodes(&'h self) where [Node<'h>]:ToOwned<Vec<Node<'h>>>
+    fn nodes(&'h self) where [Node<'h>]:ToOwned<Owned=Vec<Node<'h>>>
     { loop { } }
 }
 
index 1f9b821178c46f43eac85ce007b66afc76a87761..2d1ba7f39b27bbd8115525bf99c077c64d635279 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(core,unboxed_closures)]
 
-use std::marker::CovariantType;
+use std::marker::PhantomData;
 
 // Test that we are able to infer a suitable kind for a "recursive"
 // closure.  As far as I can tell, coding up a recursive closure
 
 struct YCombinator<F,A,R> {
     func: F,
-    marker: CovariantType<(A,R)>,
+    marker: PhantomData<(A,R)>,
 }
 
 impl<F,A,R> YCombinator<F,A,R> {
     fn new(f: F) -> YCombinator<F,A,R> {
-        YCombinator { func: f, marker: CovariantType }
+        YCombinator { func: f, marker: PhantomData }
     }
 }
 
index cec523a06712e025f2e4d1988ffa24ad13b44a03..f01a56142e0730184635b00609050db1ce8333c6 100644 (file)
@@ -13,7 +13,7 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-pub trait EventLoop { }
+pub trait EventLoop { fn foo(&self) {} }
 
 pub struct UvEventLoop {
     uvio: int
index e6dd8d46952eb4b1627ceef0ac3d70bde9fd5d39..ae175d27b0a4ea09b08f9ae0bdbd75e7de00032a 100644 (file)
 
 // Test syntax checks for `?Sized` syntax.
 
-trait T1 {}
-pub trait T2 {}
-trait T3<X: T1> : T2 {}
-trait T4<X: ?Sized> {}
-trait T5<X: ?Sized, Y> {}
-trait T6<Y, X: ?Sized> {}
-trait T7<X: ?Sized, Y: ?Sized> {}
-trait T8<X: ?Sized+T2> {}
-trait T9<X: T2 + ?Sized> {}
-struct S1<X: ?Sized>;
-enum E<X: ?Sized> {}
+use std::marker::{PhantomData, PhantomFn};
+
+trait T1 : PhantomFn<Self> { }
+pub trait T2 : PhantomFn<Self> { }
+trait T3<X: T1> : T2 + PhantomFn<X> { }
+trait T4<X: ?Sized> : PhantomFn<(Self,X)> {}
+trait T5<X: ?Sized, Y> : PhantomFn<(Self,X,Y)> {}
+trait T6<Y, X: ?Sized> : PhantomFn<(Self,X,Y)> {}
+trait T7<X: ?Sized, Y: ?Sized> : PhantomFn<(Self,X,Y)> {}
+trait T8<X: ?Sized+T2> : PhantomFn<(Self,X)> {}
+trait T9<X: T2 + ?Sized> : PhantomFn<(Self,X)> {}
+struct S1<X: ?Sized>(PhantomData<X>);
+enum E<X: ?Sized> { E1(PhantomData<X>) }
 impl <X: ?Sized> T1 for S1<X> {}
 fn f<X: ?Sized>() {}
 type TT<T: ?Sized> = T;
index 285100dd7197cbdce2620c5b14837580ad5147cc..10b2f2fb7092423c2a2e77c772baf71b68abed31 100644 (file)
@@ -15,6 +15,8 @@
 
 // Test sized-ness checking in substitution.
 
+use std::marker;
+
 // Unbounded.
 fn f1<X: ?Sized>(x: &X) {
     f1::<X>(x);
@@ -25,7 +27,7 @@ fn f2<X>(x: &X) {
 }
 
 // Bounded.
-trait T {}
+trait T { fn dummy(&self) { } }
 fn f3<X: T+?Sized>(x: &X) {
     f3::<X>(x);
 }
@@ -66,20 +68,24 @@ fn f7<X: ?Sized+T3>(x: &X) {
 }
 
 trait T4<X> {
-    fn m1(x: &T4<X>);
-    fn m2(x: &T5<X>);
+    fn dummy(&self) { }
+    fn m1(x: &T4<X>, y: X);
+    fn m2(x: &T5<X>, y: X);
 }
 trait T5<X: ?Sized> {
+    fn dummy(&self) { }
     // not an error (for now)
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
 }
 
 trait T6<X: T> {
+    fn dummy(&self) { }
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
 }
 trait T7<X: ?Sized+T> {
+    fn dummy(&self) { }
     // not an error (for now)
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
index a729fedb27157a6d64fad9ac0aab0371141fa9a2..5a476ed9ee2f89958d02a0cbb6abd8537eace2d0 100644 (file)
@@ -29,11 +29,11 @@ pub fn main() {
 
     unsafe {
         // Call with just the named parameter
-        let c = CString::from_slice(b"Hello World\n");
+        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::from_slice(b"%d %f %c %s\n");
+        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 +44,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::from_slice(b"Hello World\n");
+            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::from_slice(b"%d %f %c %s\n");
+            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());
             });
diff --git a/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs b/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs
new file mode 100644 (file)
index 0000000..948d68e
--- /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.
+
+// Elaborated version of the opening example from RFC 738. This failed
+// to compile before variance because invariance of `Option` prevented
+// us from approximating the lifetimes of `field1` and `field2` to a
+// common intersection.
+
+#![allow(dead_code)]
+
+struct List<'l> {
+    field1: &'l i32,
+    field2: Option<&'l i32>,
+}
+
+fn foo(field1: &i32, field2: Option<&i32>) -> i32 {
+    let list = List { field1: field1, field2: field2 };
+    *list.field1 + list.field2.cloned().unwrap_or(0)
+}
+
+fn main() {
+    let x = 22;
+    let y = Some(3);
+    let z = None;
+    assert_eq!(foo(&x, y.as_ref()), 25);
+    assert_eq!(foo(&x, z.as_ref()), 22);
+}
diff --git a/src/test/run-pass/variance-trait-matching.rs b/src/test/run-pass/variance-trait-matching.rs
new file mode 100644 (file)
index 0000000..10441be
--- /dev/null
@@ -0,0 +1,49 @@
+// 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)]
+
+// Get<T> is covariant in T
+trait Get<T> {
+    fn get(&self) -> T;
+}
+
+struct Cloner<T:Clone> {
+    t: T
+}
+
+impl<T:Clone> Get<T> for Cloner<T> {
+    fn get(&self) -> T {
+        self.t.clone()
+    }
+}
+
+fn get<'a, G>(get: &G) -> i32
+    where G : Get<&'a i32>
+{
+    // This call only type checks if we can use `G : Get<&'a i32>` as
+    // evidence that `G : Get<&'b i32>` where `'a : 'b`.
+    pick(get, &22)
+}
+
+fn pick<'b, G>(get: &'b G, if_odd: &'b i32) -> i32
+    where G : Get<&'b i32>
+{
+    let v = *get.get();
+    if v % 2 != 0 { v } else { *if_odd }
+}
+
+fn main() {
+    let x = Cloner { t: &23 };
+    let y = get(&x);
+    assert_eq!(y, 23);
+}
+
+
diff --git a/src/test/run-pass/variance-vec-covariant.rs b/src/test/run-pass/variance-vec-covariant.rs
new file mode 100644 (file)
index 0000000..caec6df
--- /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 vec is now covariant in its argument type.
+
+#![allow(dead_code)]
+
+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
+}
+
+fn bar<'c>(v1: Vec<&'c i32>, v2: Vec<&'c i32>) -> Option<&'c i32> {
+    v1.get(0).cloned().or_else(|| v2.get(0).cloned())
+}
+
+fn main() {
+    let x = 22;
+    let y = 44;
+    assert_eq!(foo(vec![&x], vec![&y]), 22);
+    assert_eq!(foo(vec![&y], vec![&x]), 44);
+}
index 9518671b4799dbb472a339da794d7561575eebfd..46e93b25697bbaa00be5edb94145c3cd24d62e0f 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(visible_private_types)]
 
-trait Foo {}
+trait Foo { fn dummy(&self) { } }
 
 pub trait Bar : Foo {}
 
index a1a61127f68e05d9a6831e0812d28b018eb03545..3374f47ed5f80b8908b395b106a5cdc803fc467c 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Bound {}
+trait Bound {
+    fn dummy(&self) { }
+}
 
 trait Trait {
     fn a<T>(&self, T) where T: Bound;
index cade99b83a2fe429bf6b9e31919b408f179f37a5..4a149d4d3df44ed8050e5205dc1fcb90f682bdf8 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait TheTrait { }
+trait TheTrait { fn dummy(&self) { } }
 
 impl TheTrait for &'static int { }
 
index b391df8500bb7e65ce50ea9ae4fc2d176f7b4a65..ecc210ea579dbccb8d61f5c0d550f87e3f1c2ba9 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo<T> {}
+trait Foo<T> { fn dummy(&self, arg: T) { } }
 
 trait Bar<A> {
     fn method<B>(&self) where A: Foo<B>;
@@ -19,7 +19,7 @@ trait Bar<A> {
 
 impl Foo<S> for X {}
 
-impl Bar<X> for int {
+impl Bar<X> for i32 {
     fn method<U>(&self) where X: Foo<U> {
     }
 }
index 5d426793c2e36f9ad94c0821c9c2fad126068eee..1fd223b0dd3f6bd8c8d8ffaa83bd6a59ee8d3370 100644 (file)
 // Test that we can quantify lifetimes outside a constraint (i.e., including
 // the self type) in a where clause.
 
+use std::marker::PhantomFn;
+
 static mut COUNT: u32 = 1;
 
-trait Bar<'a> {
+trait Bar<'a>
+    : PhantomFn<&'a ()>
+{
     fn bar(&self);
 }
 
-trait Baz<'a> {
+trait Baz<'a>
+    : PhantomFn<&'a ()>
+{
     fn baz(&self);
 }