summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-02-19 18:36:59 +0000
committerbors <bors@rust-lang.org>2015-02-19 18:36:59 +0000
commit522d09dfecbeca1595f25ac58c6d0178bbd21d7d (patch)
treecc0252dd3413e5f890d0ebcfdaa096e5b002be0b
parent0b664bb8436f2cfda7f13a6f302ab486f332816f (diff)
parent49771bafa5fca16486bfd06741dac3de2c587adf (diff)
Auto merge of #22541 - Manishearth:rollup, r=Gankro1.0.0-alpha.2
Continued from #22520
-rw-r--r--README.md46
-rwxr-xr-xconfigure1
-rw-r--r--mk/tests.mk17
-rw-r--r--src/compiletest/common.rs3
-rw-r--r--src/compiletest/compiletest.rs3
-rw-r--r--src/compiletest/runtest.rs9
-rw-r--r--src/doc/reference.md12
-rw-r--r--src/doc/trpl/ffi.md6
-rw-r--r--src/doc/trpl/patterns.md2
-rw-r--r--src/liballoc/arc.rs15
-rw-r--r--src/liballoc/boxed.rs25
-rw-r--r--src/liballoc/lib.rs1
-rw-r--r--src/liballoc/rc.rs19
-rw-r--r--src/libarena/lib.rs6
-rw-r--r--src/libcollections/binary_heap.rs7
-rw-r--r--src/libcollections/bit.rs1078
-rw-r--r--src/libcollections/borrow.rs316
-rw-r--r--src/libcollections/borrow_stage0.rs313
-rw-r--r--src/libcollections/btree/map.rs57
-rw-r--r--src/libcollections/btree/node.rs93
-rw-r--r--src/libcollections/btree/set.rs10
-rw-r--r--src/libcollections/enum_set.rs32
-rw-r--r--src/libcollections/lib.rs54
-rw-r--r--src/libcollections/linked_list.rs (renamed from src/libcollections/dlist.rs)257
-rw-r--r--src/libcollections/slice.rs31
-rw-r--r--src/libcollections/str.rs113
-rw-r--r--src/libcollections/string.rs70
-rw-r--r--src/libcollections/vec.rs106
-rw-r--r--src/libcollections/vec_deque.rs (renamed from src/libcollections/ring_buf.rs)446
-rw-r--r--src/libcollections/vec_map.rs25
-rw-r--r--src/libcore/array.rs40
-rw-r--r--src/libcore/atomic.rs5
-rw-r--r--src/libcore/borrow.rs265
-rw-r--r--src/libcore/cmp.rs12
-rw-r--r--src/libcore/default.rs16
-rw-r--r--src/libcore/fmt/mod.rs7
-rw-r--r--src/libcore/hash/mod.rs471
-rw-r--r--src/libcore/hash/sip.rs45
-rw-r--r--src/libcore/intrinsics.rs24
-rw-r--r--src/libcore/iter.rs52
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libcore/marker.rs393
-rw-r--r--src/libcore/nonzero.rs9
-rw-r--r--src/libcore/option.rs6
-rw-r--r--src/libcore/ptr.rs56
-rw-r--r--src/libcore/result.rs7
-rw-r--r--src/libcore/slice.rs14
-rw-r--r--src/libcore/str/mod.rs2
-rw-r--r--src/libcoretest/hash/mod.rs24
-rw-r--r--src/libcoretest/iter.rs46
-rw-r--r--src/libcoretest/mem.rs2
-rw-r--r--src/libcoretest/ptr.rs4
-rw-r--r--src/libcoretest/slice.rs12
-rw-r--r--src/libflate/lib.rs8
-rw-r--r--src/libfmt_macros/lib.rs4
-rw-r--r--src/libgetopts/lib.rs30
-rw-r--r--src/libgraphviz/lib.rs31
-rw-r--r--src/liblog/lib.rs6
-rw-r--r--src/librand/distributions/mod.rs11
-rw-r--r--src/librand/isaac.rs4
-rw-r--r--src/librand/lib.rs4
-rw-r--r--src/librustc/lint/builtin.rs20
-rw-r--r--src/librustc/lint/context.rs34
-rw-r--r--src/librustc/lint/mod.rs8
-rw-r--r--src/librustc/metadata/creader.rs12
-rw-r--r--src/librustc/metadata/cstore.rs5
-rw-r--r--src/librustc/metadata/encoder.rs52
-rw-r--r--src/librustc/metadata/loader.rs14
-rw-r--r--src/librustc/metadata/tydecode.rs2
-rw-r--r--src/librustc/middle/astencode.rs2
-rw-r--r--src/librustc/middle/cfg/graphviz.rs2
-rw-r--r--src/librustc/middle/check_match.rs22
-rw-r--r--src/librustc/middle/const_eval.rs12
-rw-r--r--src/librustc/middle/dataflow.rs8
-rw-r--r--src/librustc/middle/dead.rs2
-rw-r--r--src/librustc/middle/dependency_format.rs2
-rw-r--r--src/librustc/middle/expr_use_visitor.rs15
-rw-r--r--src/librustc/middle/graph.rs6
-rw-r--r--src/librustc/middle/infer/bivariate.rs145
-rw-r--r--src/librustc/middle/infer/combine.rs146
-rw-r--r--src/librustc/middle/infer/equate.rs27
-rw-r--r--src/librustc/middle/infer/error_reporting.rs32
-rw-r--r--src/librustc/middle/infer/glb.rs47
-rw-r--r--src/librustc/middle/infer/higher_ranked/mod.rs4
-rw-r--r--src/librustc/middle/infer/lub.rs47
-rw-r--r--src/librustc/middle/infer/mod.rs6
-rw-r--r--src/librustc/middle/infer/region_inference/mod.rs2
-rw-r--r--src/librustc/middle/infer/sub.rs48
-rw-r--r--src/librustc/middle/infer/type_variable.rs10
-rw-r--r--src/librustc/middle/infer/unify.rs9
-rw-r--r--src/librustc/middle/lang_items.rs19
-rw-r--r--src/librustc/middle/liveness.rs8
-rw-r--r--src/librustc/middle/region.rs2
-rw-r--r--src/librustc/middle/resolve_lifetime.rs2
-rw-r--r--src/librustc/middle/subst.rs2
-rw-r--r--src/librustc/middle/traits/coherence.rs101
-rw-r--r--src/librustc/middle/traits/mod.rs11
-rw-r--r--src/librustc/middle/traits/object_safety.rs55
-rw-r--r--src/librustc/middle/traits/select.rs19
-rw-r--r--src/librustc/middle/ty.rs92
-rw-r--r--src/librustc/middle/weak_lang_items.rs2
-rw-r--r--src/librustc/plugin/load.rs6
-rw-r--r--src/librustc/session/config.rs10
-rw-r--r--src/librustc/session/mod.rs4
-rw-r--r--src/librustc/util/common.rs93
-rw-r--r--src/librustc/util/lev_distance.rs2
-rw-r--r--src/librustc/util/nodemap.rs28
-rw-r--r--src/librustc/util/ppaux.rs46
-rw-r--r--src/librustc_back/archive.rs20
-rw-r--r--src/librustc_back/rpath.rs19
-rw-r--r--src/librustc_back/target/mod.rs6
-rw-r--r--src/librustc_borrowck/borrowck/check_loans.rs2
-rw-r--r--src/librustc_borrowck/borrowck/fragments.rs28
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs2
-rw-r--r--src/librustc_borrowck/graphviz.rs2
-rw-r--r--src/librustc_borrowck/lib.rs1
-rw-r--r--src/librustc_driver/driver.rs8
-rw-r--r--src/librustc_driver/lib.rs10
-rw-r--r--src/librustc_driver/pretty.rs12
-rw-r--r--src/librustc_driver/test.rs4
-rw-r--r--src/librustc_llvm/archive_ro.rs4
-rw-r--r--src/librustc_llvm/lib.rs3
-rw-r--r--src/librustc_privacy/lib.rs6
-rw-r--r--src/librustc_resolve/lib.rs70
-rw-r--r--src/librustc_trans/back/link.rs46
-rw-r--r--src/librustc_trans/back/lto.rs4
-rw-r--r--src/librustc_trans/back/write.rs52
-rw-r--r--src/librustc_trans/lib.rs1
-rw-r--r--src/librustc_trans/save/mod.rs88
-rw-r--r--src/librustc_trans/save/recorder.rs12
-rw-r--r--src/librustc_trans/trans/_match.rs18
-rw-r--r--src/librustc_trans/trans/adt.rs42
-rw-r--r--src/librustc_trans/trans/asm.rs16
-rw-r--r--src/librustc_trans/trans/base.rs75
-rw-r--r--src/librustc_trans/trans/builder.rs12
-rw-r--r--src/librustc_trans/trans/callee.rs8
-rw-r--r--src/librustc_trans/trans/cleanup.rs4
-rw-r--r--src/librustc_trans/trans/closure.rs6
-rw-r--r--src/librustc_trans/trans/common.rs11
-rw-r--r--src/librustc_trans/trans/consts.rs26
-rw-r--r--src/librustc_trans/trans/context.rs12
-rw-r--r--src/librustc_trans/trans/controlflow.rs6
-rw-r--r--src/librustc_trans/trans/debuginfo.rs124
-rw-r--r--src/librustc_trans/trans/expr.rs20
-rw-r--r--src/librustc_trans/trans/foreign.rs14
-rw-r--r--src/librustc_trans/trans/glue.rs8
-rw-r--r--src/librustc_trans/trans/intrinsic.rs8
-rw-r--r--src/librustc_trans/trans/monomorphize.rs10
-rw-r--r--src/librustc_trans/trans/tvec.rs80
-rw-r--r--src/librustc_trans/trans/type_.rs2
-rw-r--r--src/librustc_trans/trans/type_of.rs10
-rw-r--r--src/librustc_typeck/astconv.rs33
-rw-r--r--src/librustc_typeck/check/_match.rs2
-rw-r--r--src/librustc_typeck/check/callee.rs2
-rw-r--r--src/librustc_typeck/check/implicator.rs8
-rw-r--r--src/librustc_typeck/check/method/probe.rs2
-rw-r--r--src/librustc_typeck/check/method/suggest.rs8
-rw-r--r--src/librustc_typeck/check/mod.rs38
-rw-r--r--src/librustc_typeck/check/regionck.rs20
-rw-r--r--src/librustc_typeck/check/vtable.rs7
-rw-r--r--src/librustc_typeck/check/wf.rs158
-rw-r--r--src/librustc_typeck/collect.rs66
-rw-r--r--src/librustc_typeck/constrained_type_params.rs61
-rw-r--r--src/librustc_typeck/lib.rs1
-rw-r--r--src/librustc_typeck/variance.rs396
-rw-r--r--src/librustdoc/flock.rs2
-rw-r--r--src/librustdoc/html/highlight.rs2
-rw-r--r--src/librustdoc/html/markdown.rs4
-rw-r--r--src/librustdoc/html/render.rs3
-rw-r--r--src/librustdoc/html/static/main.css4
-rw-r--r--src/librustdoc/lib.rs1
-rw-r--r--src/librustdoc/passes.rs2
-rw-r--r--src/librustdoc/visit_ast.rs2
-rw-r--r--src/libserialize/collection_impls.rs94
-rw-r--r--src/libserialize/json.rs12
-rw-r--r--src/libserialize/lib.rs1
-rw-r--r--src/libserialize/serialize.rs2
-rw-r--r--src/libstd/collections/hash/map.rs139
-rw-r--r--src/libstd/collections/hash/map_stage0.rs2330
-rw-r--r--src/libstd/collections/hash/mod.rs8
-rw-r--r--src/libstd/collections/hash/set.rs128
-rw-r--r--src/libstd/collections/hash/set_stage0.rs1252
-rw-r--r--src/libstd/collections/hash/state.rs7
-rw-r--r--src/libstd/collections/hash/table.rs79
-rw-r--r--src/libstd/collections/mod.rs42
-rw-r--r--src/libstd/dynamic_lib.rs8
-rw-r--r--src/libstd/env.rs8
-rw-r--r--src/libstd/ffi/c_str.rs402
-rw-r--r--src/libstd/ffi/mod.rs4
-rw-r--r--src/libstd/ffi/os_str.rs36
-rw-r--r--src/libstd/io/buffered.rs4
-rw-r--r--src/libstd/io/cursor.rs14
-rw-r--r--src/libstd/lib.rs2
-rw-r--r--src/libstd/net/addr.rs16
-rw-r--r--src/libstd/net/ip.rs16
-rw-r--r--src/libstd/old_io/buffered.rs6
-rw-r--r--src/libstd/old_io/mod.rs10
-rw-r--r--src/libstd/old_io/net/pipe.rs6
-rw-r--r--src/libstd/old_io/process.rs40
-rw-r--r--src/libstd/old_path/mod.rs4
-rw-r--r--src/libstd/old_path/posix.rs13
-rw-r--r--src/libstd/old_path/windows.rs56
-rw-r--r--src/libstd/os.rs5
-rw-r--r--src/libstd/panicking.rs2
-rwxr-xr-xsrc/libstd/path.rs28
-rw-r--r--src/libstd/rand/mod.rs2
-rw-r--r--src/libstd/rt/args.rs9
-rw-r--r--src/libstd/sys/common/net.rs17
-rw-r--r--src/libstd/sys/common/net2.rs2
-rw-r--r--src/libstd/sys/common/wtf8.rs38
-rw-r--r--src/libstd/sys/unix/backtrace.rs6
-rw-r--r--src/libstd/sys/unix/ext.rs12
-rw-r--r--src/libstd/sys/unix/fs.rs42
-rw-r--r--src/libstd/sys/unix/fs2.rs44
-rw-r--r--src/libstd/sys/unix/mod.rs5
-rw-r--r--src/libstd/sys/unix/net.rs4
-rw-r--r--src/libstd/sys/unix/os.rs28
-rw-r--r--src/libstd/sys/unix/pipe.rs6
-rw-r--r--src/libstd/sys/unix/process.rs249
-rw-r--r--src/libstd/sys/unix/process2.rs9
-rw-r--r--src/libstd/sys/unix/thread.rs6
-rw-r--r--src/libstd/sys/windows/backtrace.rs4
-rw-r--r--src/libstd/sys/windows/c.rs2
-rw-r--r--src/libstd/sys/windows/mod.rs4
-rw-r--r--src/libstd/sys/windows/os.rs10
-rw-r--r--src/libstd/sys/windows/process.rs195
-rw-r--r--src/libstd/thread.rs6
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/ast_map/mod.rs26
-rw-r--r--src/libsyntax/ast_util.rs6
-rw-r--r--src/libsyntax/attr.rs32
-rw-r--r--src/libsyntax/codemap.rs2
-rw-r--r--src/libsyntax/config.rs2
-rw-r--r--src/libsyntax/diagnostic.rs65
-rw-r--r--src/libsyntax/diagnostics/plugin.rs8
-rw-r--r--src/libsyntax/diagnostics/registry.rs4
-rw-r--r--src/libsyntax/ext/base.rs2
-rw-r--r--src/libsyntax/ext/concat.rs2
-rw-r--r--src/libsyntax/ext/concat_idents.rs2
-rw-r--r--src/libsyntax/ext/deriving/bounds.rs2
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs42
-rw-r--r--src/libsyntax/ext/deriving/hash.rs25
-rw-r--r--src/libsyntax/ext/deriving/mod.rs2
-rw-r--r--src/libsyntax/ext/deriving/show.rs2
-rw-r--r--src/libsyntax/ext/env.rs6
-rw-r--r--src/libsyntax/ext/expand.rs26
-rw-r--r--src/libsyntax/ext/format.rs8
-rw-r--r--src/libsyntax/ext/quote.rs4
-rw-r--r--src/libsyntax/ext/source_util.rs16
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs18
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs14
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs4
-rw-r--r--src/libsyntax/feature_gate.rs22
-rw-r--r--src/libsyntax/lib.rs1
-rw-r--r--src/libsyntax/owned_slice.rs6
-rw-r--r--src/libsyntax/parse/lexer/comments.rs10
-rw-r--r--src/libsyntax/parse/lexer/mod.rs13
-rw-r--r--src/libsyntax/parse/mod.rs24
-rw-r--r--src/libsyntax/parse/obsolete.rs35
-rw-r--r--src/libsyntax/parse/parser.rs147
-rw-r--r--src/libsyntax/parse/token.rs4
-rw-r--r--src/libsyntax/print/pp.rs6
-rw-r--r--src/libsyntax/print/pprust.rs173
-rw-r--r--src/libsyntax/ptr.rs7
-rw-r--r--src/libsyntax/std_inject.rs13
-rw-r--r--src/libsyntax/test.rs14
-rw-r--r--src/libsyntax/util/interner.rs96
-rw-r--r--src/libsyntax/util/small_vector.rs6
-rw-r--r--src/libterm/lib.rs1
-rw-r--r--src/libterm/terminfo/mod.rs2
-rw-r--r--src/libterm/terminfo/parm.rs2
-rw-r--r--src/libterm/terminfo/searcher.rs4
-rw-r--r--src/libtest/lib.rs5
-rw-r--r--src/libtest/stats.rs4
m---------src/llvm0
-rw-r--r--src/rustbook/build.rs2
-rw-r--r--src/rustbook/error.rs4
-rw-r--r--src/rustbook/test.rs2
-rw-r--r--src/test/auxiliary/coherence-orphan-lib.rs2
-rw-r--r--src/test/auxiliary/default_type_params_xc.rs3
-rw-r--r--src/test/auxiliary/inner_static.rs12
-rw-r--r--src/test/auxiliary/issue-14421.rs5
-rw-r--r--src/test/auxiliary/issue-16643.rs2
-rw-r--r--src/test/auxiliary/issue-17662.rs2
-rw-r--r--src/test/auxiliary/issue-2380.rs5
-rw-r--r--src/test/auxiliary/issue-2526.rs8
-rw-r--r--src/test/auxiliary/issue_20389.rs1
-rw-r--r--src/test/auxiliary/issue_3907.rs4
-rw-r--r--src/test/auxiliary/issue_8401.rs4
-rw-r--r--src/test/auxiliary/issue_9123.rs1
-rw-r--r--src/test/auxiliary/lang-item-public.rs10
-rw-r--r--src/test/auxiliary/lint_group_plugin_test.rs4
-rw-r--r--src/test/auxiliary/lint_plugin_test.rs2
-rw-r--r--src/test/auxiliary/lint_stability.rs2
-rw-r--r--src/test/auxiliary/nested_item.rs2
-rw-r--r--src/test/auxiliary/orphan_check_diagnostics.rs2
-rw-r--r--src/test/auxiliary/overloaded_autoderef_xc.rs5
-rw-r--r--src/test/auxiliary/plugin_args.rs2
-rw-r--r--src/test/auxiliary/private_trait_xc.rs2
-rw-r--r--src/test/auxiliary/svh-a-base.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-lit.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-significant-cfg.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-trait-bound.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-type-arg.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-type-ret.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-type-static.rs6
-rw-r--r--src/test/auxiliary/svh-a-comment.rs6
-rw-r--r--src/test/auxiliary/svh-a-doc.rs6
-rw-r--r--src/test/auxiliary/svh-a-macro.rs6
-rw-r--r--src/test/auxiliary/svh-a-no-change.rs6
-rw-r--r--src/test/auxiliary/svh-a-redundant-cfg.rs6
-rw-r--r--src/test/auxiliary/svh-a-whitespace.rs6
-rw-r--r--src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs4
-rw-r--r--src/test/auxiliary/trait_impl_conflict.rs2
-rw-r--r--src/test/auxiliary/use_from_trait_xc.rs2
-rw-r--r--src/test/bench/core-set.rs11
-rw-r--r--src/test/bench/shootout-fasta.rs2
-rw-r--r--src/test/bench/shootout-meteor.rs4
-rw-r--r--src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs6
-rw-r--r--src/test/compile-fail/associated-types-coherence-failure.rs3
-rw-r--r--src/test/compile-fail/associated-types-eq-expr-path.rs2
-rw-r--r--src/test/compile-fail/associated-types-issue-17359.rs2
-rw-r--r--src/test/compile-fail/associated-types-multiple-types-one-trait.rs2
-rw-r--r--src/test/compile-fail/associated-types-no-suitable-supertrait.rs2
-rw-r--r--src/test/compile-fail/associated-types-path-2.rs2
-rw-r--r--src/test/compile-fail/associated-types-unconstrained.rs2
-rw-r--r--src/test/compile-fail/bad-mid-path-type-params.rs7
-rw-r--r--src/test/compile-fail/bad-sized.rs2
-rw-r--r--src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs5
-rw-r--r--src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs4
-rw-r--r--src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs8
-rw-r--r--src/test/compile-fail/coherence-subtyping.rs50
-rw-r--r--src/test/compile-fail/cross-borrow-trait.rs2
-rw-r--r--src/test/compile-fail/destructure-trait-ref.rs2
-rw-r--r--src/test/compile-fail/dst-bad-coerce1.rs2
-rw-r--r--src/test/compile-fail/dst-bad-coerce2.rs2
-rw-r--r--src/test/compile-fail/dst-bad-coerce3.rs2
-rw-r--r--src/test/compile-fail/dst-bad-coercions.rs4
-rw-r--r--src/test/compile-fail/dst-object-from-unsized-type.rs2
-rw-r--r--src/test/compile-fail/exclusive-drop-and-copy.rs2
-rw-r--r--src/test/compile-fail/generic-impl-less-params-with-defaults.rs7
-rw-r--r--src/test/compile-fail/generic-impl-more-params-with-defaults.rs7
-rw-r--r--src/test/compile-fail/generic-lifetime-trait-impl.rs5
-rw-r--r--src/test/compile-fail/generic-type-less-params-with-defaults.rs5
-rw-r--r--src/test/compile-fail/generic-type-more-params-with-defaults.rs5
-rw-r--r--src/test/compile-fail/generic-type-params-name-repr.rs8
-rw-r--r--src/test/compile-fail/issue-11515.rs2
-rw-r--r--src/test/compile-fail/issue-13853-2.rs4
-rw-r--r--src/test/compile-fail/issue-13853-3.rs5
-rw-r--r--src/test/compile-fail/issue-13853.rs4
-rw-r--r--src/test/compile-fail/issue-14285.rs4
-rw-r--r--src/test/compile-fail/issue-14853.rs3
-rw-r--r--src/test/compile-fail/issue-16747.rs4
-rw-r--r--src/test/compile-fail/issue-17431-4.rs4
-rw-r--r--src/test/compile-fail/issue-17431-5.rs4
-rw-r--r--src/test/compile-fail/issue-17551.rs6
-rw-r--r--src/test/compile-fail/issue-17904-2.rs16
-rw-r--r--src/test/compile-fail/issue-18107.rs4
-rw-r--r--src/test/compile-fail/issue-18611.rs4
-rw-r--r--src/test/compile-fail/issue-18783.rs1
-rw-r--r--src/test/compile-fail/issue-18819.rs4
-rw-r--r--src/test/compile-fail/issue-19660.rs6
-rw-r--r--src/test/compile-fail/issue-2063.rs3
-rw-r--r--src/test/compile-fail/issue-20831-debruijn.rs5
-rw-r--r--src/test/compile-fail/issue-21160.rs2
-rw-r--r--src/test/compile-fail/issue-2611-4.rs4
-rw-r--r--src/test/compile-fail/issue-3008-3.rs4
-rw-r--r--src/test/compile-fail/issue-4972.rs4
-rw-r--r--src/test/compile-fail/issue-5035-2.rs4
-rw-r--r--src/test/compile-fail/issue-5543.rs2
-rw-r--r--src/test/compile-fail/issue-5883.rs6
-rw-r--r--src/test/compile-fail/issue-6458.rs6
-rw-r--r--src/test/compile-fail/issue-7575.rs8
-rw-r--r--src/test/compile-fail/issue-8727.rs10
-rw-r--r--src/test/compile-fail/kindck-copy.rs4
-rw-r--r--src/test/compile-fail/kindck-impl-type-params-2.rs4
-rw-r--r--src/test/compile-fail/kindck-impl-type-params.rs20
-rw-r--r--src/test/compile-fail/kindck-inherited-copy-bound.rs1
-rw-r--r--src/test/compile-fail/kindck-send-object.rs4
-rw-r--r--src/test/compile-fail/kindck-send-object1.rs4
-rw-r--r--src/test/compile-fail/kindck-send-object2.rs4
-rw-r--r--src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs4
-rw-r--r--src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs4
-rw-r--r--src/test/compile-fail/lint-missing-doc.rs20
-rw-r--r--src/test/compile-fail/lint-non-camel-case-types.rs1
-rw-r--r--src/test/compile-fail/lint-stability.rs4
-rw-r--r--src/test/compile-fail/lint-visible-private-types.rs8
-rw-r--r--src/test/compile-fail/liveness-use-after-send.rs4
-rw-r--r--src/test/compile-fail/map-types.rs5
-rw-r--r--src/test/compile-fail/method-ambig-one-trait-coerce.rs50
-rw-r--r--src/test/compile-fail/mod_file_disambig.rs (renamed from src/test/parse-fail/mod_file_disambig.rs)0
-rw-r--r--src/test/compile-fail/mod_file_not_owning.rs (renamed from src/test/parse-fail/mod_file_not_owning.rs)0
-rw-r--r--src/test/compile-fail/object-does-not-impl-trait.rs3
-rw-r--r--src/test/compile-fail/object-lifetime-default-mybox.rs1
-rw-r--r--src/test/compile-fail/object-safety-issue-22040.rs50
-rw-r--r--src/test/compile-fail/object-safety-no-static.rs2
-rw-r--r--src/test/compile-fail/object-safety-phantom-fn.rs34
-rw-r--r--src/test/compile-fail/object-safety-supertrait-mentions-Self.rs32
-rw-r--r--src/test/compile-fail/on-unimplemented-bad-anno.rs18
-rw-r--r--src/test/compile-fail/on-unimplemented.rs6
-rw-r--r--src/test/compile-fail/orphan-check-diagnostics.rs2
-rw-r--r--src/test/compile-fail/priv-in-bad-locations.rs4
-rw-r--r--src/test/compile-fail/privacy-ns2.rs8
-rw-r--r--src/test/compile-fail/privacy1.rs8
-rw-r--r--src/test/compile-fail/privacy4.rs8
-rw-r--r--src/test/compile-fail/region-object-lifetime-in-coercion.rs2
-rw-r--r--src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs7
-rw-r--r--src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs6
-rw-r--r--src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs7
-rw-r--r--src/test/compile-fail/regions-assoc-type-outlives-container.rs8
-rw-r--r--src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs5
-rw-r--r--src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs5
-rw-r--r--src/test/compile-fail/regions-bound-missing-bound-in-impl.rs5
-rw-r--r--src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs6
-rw-r--r--src/test/compile-fail/regions-close-associated-type-into-object.rs4
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-1.rs9
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-2.rs6
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-3.rs6
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-4.rs6
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-5.rs30
-rw-r--r--src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs4
-rw-r--r--src/test/compile-fail/regions-close-param-into-object.rs2
-rw-r--r--src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs2
-rw-r--r--src/test/compile-fail/regions-infer-covariance-due-to-decl.rs2
-rw-r--r--src/test/compile-fail/regions-infer-invariance-due-to-decl.rs2
-rw-r--r--src/test/compile-fail/required-lang-item.rs6
-rw-r--r--src/test/compile-fail/shadowed-type-parameter.rs6
-rw-r--r--src/test/compile-fail/slice-1.rs8
-rw-r--r--src/test/compile-fail/slightly-nice-generic-literal-messages.rs6
-rw-r--r--src/test/compile-fail/staticness-mismatch.rs2
-rw-r--r--src/test/compile-fail/trait-as-struct-constructor.rs2
-rw-r--r--src/test/compile-fail/trait-bounds-cant-coerce.rs1
-rw-r--r--src/test/compile-fail/trait-bounds-impl-comparison-1.rs14
-rw-r--r--src/test/compile-fail/trait-bounds-impl-comparison-2.rs4
-rw-r--r--src/test/compile-fail/trait-bounds-not-on-bare-trait.rs1
-rw-r--r--src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs4
-rw-r--r--src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs4
-rw-r--r--src/test/compile-fail/trait-bounds-on-structs-and-enums.rs10
-rw-r--r--src/test/compile-fail/trait-bounds-sugar.rs3
-rw-r--r--src/test/compile-fail/trait-impl-1.rs4
-rw-r--r--src/test/compile-fail/trait-object-safety.rs1
-rw-r--r--src/test/compile-fail/trait-static-method-generic-inference.rs1
-rw-r--r--src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs26
-rw-r--r--src/test/compile-fail/type-parameter-defaults-referencing-Self.rs23
-rw-r--r--src/test/compile-fail/typeck-negative-impls-builtin.rs4
-rw-r--r--src/test/compile-fail/typeck_type_placeholder_mismatch.rs10
-rw-r--r--src/test/compile-fail/ufcs-qpath-missing-params.rs3
-rw-r--r--src/test/compile-fail/unboxed-closure-feature-gate.rs4
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-default.rs2
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-equiv.rs4
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs4
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-region.rs2
-rw-r--r--src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs6
-rw-r--r--src/test/compile-fail/unnecessary-private.rs4
-rw-r--r--src/test/compile-fail/unsized-inherent-impl-self-type.rs2
-rw-r--r--src/test/compile-fail/unsized-trait-impl-self-type.rs3
-rw-r--r--src/test/compile-fail/unsized-trait-impl-trait-arg.rs3
-rw-r--r--src/test/compile-fail/unsized3.rs5
-rw-r--r--src/test/compile-fail/unsized6.rs3
-rw-r--r--src/test/compile-fail/unsized7.rs8
-rw-r--r--src/test/compile-fail/unused-attr.rs4
-rw-r--r--src/test/compile-fail/useless-priv.rs8
-rw-r--r--src/test/compile-fail/useless-priv2.rs6
-rw-r--r--src/test/compile-fail/variance-contravariant-arg-object.rs31
-rw-r--r--src/test/compile-fail/variance-contravariant-arg-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-contravariant-self-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-covariant-arg-object.rs31
-rw-r--r--src/test/compile-fail/variance-covariant-arg-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-covariant-self-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-deprecated-markers.rs35
-rw-r--r--src/test/compile-fail/variance-invariant-arg-object.rs31
-rw-r--r--src/test/compile-fail/variance-invariant-arg-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-invariant-self-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-issue-20533.rs54
-rw-r--r--src/test/compile-fail/variance-regions-direct.rs1
-rw-r--r--src/test/compile-fail/variance-regions-indirect.rs4
-rw-r--r--src/test/compile-fail/variance-regions-unused-direct.rs (renamed from src/test/run-pass/regions-infer-bivariance.rs)17
-rw-r--r--src/test/compile-fail/variance-regions-unused-indirect.rs (renamed from src/test/run-pass/export-non-interference.rs)11
-rw-r--r--src/test/compile-fail/variance-trait-bounds.rs65
-rw-r--r--src/test/compile-fail/variance-trait-object-bound.rs2
-rw-r--r--src/test/compile-fail/variance-types-bounds.rs76
-rw-r--r--src/test/compile-fail/variance-types.rs52
-rw-r--r--src/test/compile-fail/variance-unused-region-param.rs17
-rw-r--r--src/test/compile-fail/variance-unused-type-param.rs36
-rw-r--r--src/test/compile-fail/variance-use-contravariant-struct-1.rs26
-rw-r--r--src/test/compile-fail/variance-use-contravariant-struct-2.rs27
-rw-r--r--src/test/compile-fail/variance-use-covariant-struct-1.rs23
-rw-r--r--src/test/compile-fail/variance-use-covariant-struct-2.rs26
-rw-r--r--src/test/compile-fail/variance-use-invariant-struct-1.rs33
-rw-r--r--src/test/compile-fail/visible-private-types-generics.rs4
-rw-r--r--src/test/compile-fail/visible-private-types-supertrait.rs4
-rw-r--r--src/test/compile-fail/where-clause-method-substituion.rs4
-rw-r--r--src/test/compile-fail/where-clauses-not-parameter.rs4
-rw-r--r--src/test/debuginfo/type-names.rs17
-rw-r--r--src/test/parse-fail/ascii-only-character-escape.rs (renamed from src/test/compile-fail/ascii-only-character-escape.rs)0
-rw-r--r--src/test/parse-fail/attr-before-eof.rs (renamed from src/test/compile-fail/attr-before-eof.rs)0
-rw-r--r--src/test/parse-fail/attr-before-ext.rs (renamed from src/test/compile-fail/attr-before-ext.rs)0
-rw-r--r--src/test/parse-fail/attr-before-let.rs (renamed from src/test/compile-fail/attr-before-let.rs)0
-rw-r--r--src/test/parse-fail/attr-before-stmt.rs (renamed from src/test/compile-fail/attr-before-stmt.rs)0
-rw-r--r--src/test/parse-fail/attr-dangling-in-fn.rs (renamed from src/test/compile-fail/attr-dangling-in-fn.rs)0
-rw-r--r--src/test/parse-fail/attr-dangling-in-mod.rs (renamed from src/test/compile-fail/attr-dangling-in-mod.rs)0
-rw-r--r--src/test/parse-fail/attr.rs (renamed from src/test/compile-fail/attr.rs)0
-rw-r--r--src/test/parse-fail/attrs-after-extern-mod.rs (renamed from src/test/compile-fail/attrs-after-extern-mod.rs)0
-rw-r--r--src/test/parse-fail/bad-char-literals.rs (renamed from src/test/compile-fail/bad-char-literals.rs)0
-rw-r--r--src/test/parse-fail/bad-lit-suffixes.rs (renamed from src/test/compile-fail/bad-lit-suffixes.rs)0
-rw-r--r--src/test/parse-fail/bad-value-ident-false.rs (renamed from src/test/compile-fail/bad-value-ident-false.rs)0
-rw-r--r--src/test/parse-fail/bad-value-ident-true.rs (renamed from src/test/compile-fail/bad-value-ident-true.rs)0
-rw-r--r--src/test/parse-fail/doc-before-attr.rs (renamed from src/test/compile-fail/doc-before-attr.rs)0
-rw-r--r--src/test/parse-fail/doc-before-eof.rs (renamed from src/test/compile-fail/doc-before-eof.rs)0
-rw-r--r--src/test/parse-fail/doc-before-extern-rbrace.rs (renamed from src/test/compile-fail/doc-before-extern-rbrace.rs)0
-rw-r--r--src/test/parse-fail/doc-before-macro.rs (renamed from src/test/compile-fail/doc-before-macro.rs)0
-rw-r--r--src/test/parse-fail/doc-before-rbrace.rs (renamed from src/test/compile-fail/doc-before-rbrace.rs)0
-rw-r--r--src/test/parse-fail/doc-before-semi.rs (renamed from src/test/compile-fail/doc-before-semi.rs)0
-rw-r--r--src/test/parse-fail/extern-crate-as-no-string-help.rs (renamed from src/test/compile-fail/extern-crate-as-no-string-help.rs)0
-rw-r--r--src/test/parse-fail/generic-non-trailing-defaults.rs (renamed from src/test/compile-fail/generic-non-trailing-defaults.rs)0
-rw-r--r--src/test/parse-fail/int-literal-too-large-span.rs (renamed from src/test/compile-fail/int-literal-too-large-span.rs)0
-rw-r--r--src/test/parse-fail/issue-10412.rs (renamed from src/test/compile-fail/issue-10412.rs)0
-rw-r--r--src/test/parse-fail/issue-12560-1.rs (renamed from src/test/compile-fail/issue-12560-1.rs)0
-rw-r--r--src/test/parse-fail/issue-14182.rs (renamed from src/test/compile-fail/issue-14182.rs)0
-rw-r--r--src/test/parse-fail/issue-17383.rs (renamed from src/test/compile-fail/issue-17383.rs)0
-rw-r--r--src/test/parse-fail/issue-17718-const-mut.rs (renamed from src/test/compile-fail/issue-17718-const-mut.rs)0
-rw-r--r--src/test/parse-fail/issue-1802-2.rs (renamed from src/test/compile-fail/issue-1802-2.rs)0
-rw-r--r--src/test/parse-fail/issue-5544-a.rs (renamed from src/test/compile-fail/issue-5544-a.rs)0
-rw-r--r--src/test/parse-fail/issue-5544-b.rs (renamed from src/test/compile-fail/issue-5544-b.rs)0
-rw-r--r--src/test/parse-fail/issue-8537.rs (renamed from src/test/compile-fail/issue-8537.rs)0
-rw-r--r--src/test/parse-fail/keyword-as-as-identifier.rs (renamed from src/test/compile-fail/keyword-as-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-break-as-identifier.rs (renamed from src/test/compile-fail/keyword-break-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-else-as-identifier.rs (renamed from src/test/compile-fail/keyword-else-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-enum-as-identifier.rs (renamed from src/test/compile-fail/keyword-enum-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-extern-as-identifier.rs (renamed from src/test/compile-fail/keyword-extern-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-fn-as-identifier.rs (renamed from src/test/compile-fail/keyword-fn-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-for-as-identifier.rs (renamed from src/test/compile-fail/keyword-for-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-if-as-identifier.rs (renamed from src/test/compile-fail/keyword-if-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-impl-as-identifier.rs (renamed from src/test/compile-fail/keyword-impl-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-let-as-identifier.rs (renamed from src/test/compile-fail/keyword-let-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-loop-as-identifier.rs (renamed from src/test/compile-fail/keyword-loop-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-match-as-identifier.rs (renamed from src/test/compile-fail/keyword-match-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-mod-as-identifier.rs (renamed from src/test/compile-fail/keyword-mod-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-pub-as-identifier.rs (renamed from src/test/compile-fail/keyword-pub-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-return-as-identifier.rs (renamed from src/test/compile-fail/keyword-return-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-self-as-identifier.rs (renamed from src/test/compile-fail/keyword-self-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-static-as-identifier.rs (renamed from src/test/compile-fail/keyword-static-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-struct-as-identifier.rs (renamed from src/test/compile-fail/keyword-struct-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-super-as-identifier.rs (renamed from src/test/compile-fail/keyword-super-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-super.rs (renamed from src/test/compile-fail/keyword-super.rs)0
-rw-r--r--src/test/parse-fail/keyword-trait-as-identifier.rs (renamed from src/test/compile-fail/keyword-trait-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-type-as-identifier.rs (renamed from src/test/compile-fail/keyword-type-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-unsafe-as-identifier.rs (renamed from src/test/compile-fail/keyword-unsafe-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-use-as-identifier.rs (renamed from src/test/compile-fail/keyword-use-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword-while-as-identifier.rs (renamed from src/test/compile-fail/keyword-while-as-identifier.rs)0
-rw-r--r--src/test/parse-fail/keyword.rs (renamed from src/test/compile-fail/keyword.rs)0
-rw-r--r--src/test/parse-fail/keywords-followed-by-double-colon.rs (renamed from src/test/compile-fail/keywords-followed-by-double-colon.rs)0
-rw-r--r--src/test/parse-fail/lex-bad-numeric-literals.rs (renamed from src/test/compile-fail/lex-bad-numeric-literals.rs)0
-rw-r--r--src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs (renamed from src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs)0
-rw-r--r--src/test/parse-fail/lifetime-no-keyword.rs (renamed from src/test/compile-fail/lifetime-no-keyword.rs)0
-rw-r--r--src/test/parse-fail/lifetime-obsoleted-self.rs (renamed from src/test/compile-fail/lifetime-obsoleted-self.rs)0
-rw-r--r--src/test/parse-fail/macros-no-semicolon-items.rs (renamed from src/test/compile-fail/macros-no-semicolon-items.rs)0
-rw-r--r--src/test/parse-fail/no-binary-float-literal.rs (renamed from src/test/compile-fail/no-binary-float-literal.rs)0
-rw-r--r--src/test/parse-fail/no-hex-float-literal.rs (renamed from src/test/compile-fail/no-hex-float-literal.rs)0
-rw-r--r--src/test/parse-fail/no-unsafe-self.rs (renamed from src/test/compile-fail/no-unsafe-self.rs)0
-rw-r--r--src/test/parse-fail/non-str-meta.rs (renamed from src/test/compile-fail/non-str-meta.rs)0
-rw-r--r--src/test/parse-fail/obsolete-for-sized.rs (renamed from src/test/compile-fail/obsolete-for-sized.rs)0
-rw-r--r--src/test/parse-fail/obsolete-proc.rs (renamed from src/test/compile-fail/obsolete-proc.rs)0
-rw-r--r--src/test/parse-fail/qquote-1.rs (renamed from src/test/compile-fail/qquote-1.rs)0
-rw-r--r--src/test/parse-fail/qquote-2.rs (renamed from src/test/compile-fail/qquote-2.rs)0
-rw-r--r--src/test/parse-fail/regions-fn-bound.rs (renamed from src/test/compile-fail/regions-fn-bound.rs)0
-rw-r--r--src/test/parse-fail/require-parens-for-chained-comparison.rs (renamed from src/test/compile-fail/require-parens-for-chained-comparison.rs)0
-rw-r--r--src/test/parse-fail/struct-no-fields-2.rs (renamed from src/test/compile-fail/struct-no-fields-2.rs)0
-rw-r--r--src/test/parse-fail/struct-no-fields-3.rs (renamed from src/test/compile-fail/struct-no-fields-3.rs)0
-rw-r--r--src/test/parse-fail/struct-no-fields-4.rs (renamed from src/test/compile-fail/struct-no-fields-4.rs)0
-rw-r--r--src/test/parse-fail/struct-no-fields-5.rs (renamed from src/test/compile-fail/struct-no-fields-5.rs)0
-rw-r--r--src/test/parse-fail/struct-variant-no-fields.rs (renamed from src/test/compile-fail/struct-variant-no-fields.rs)0
-rw-r--r--src/test/parse-fail/struct-variant-no-pub.rs (renamed from src/test/compile-fail/struct-variant-no-pub.rs)0
-rw-r--r--src/test/parse-fail/syntax-trait-polarity.rs (renamed from src/test/compile-fail/syntax-trait-polarity.rs)0
-rw-r--r--src/test/parse-fail/tag-variant-disr-non-nullary.rs (renamed from src/test/compile-fail/tag-variant-disr-non-nullary.rs)0
-rw-r--r--src/test/parse-fail/trailing-carriage-return-in-string.rs (renamed from src/test/compile-fail/trailing-carriage-return-in-string.rs)0
-rw-r--r--src/test/parse-fail/trailing-plus-in-bounds.rs (renamed from src/test/compile-fail/trailing-plus-in-bounds.rs)0
-rw-r--r--src/test/parse-fail/trait-bounds-not-on-impl.rs (renamed from src/test/compile-fail/trait-bounds-not-on-impl.rs)0
-rw-r--r--src/test/parse-fail/type-parameters-in-field-exprs.rs (renamed from src/test/compile-fail/type-parameters-in-field-exprs.rs)0
-rw-r--r--src/test/parse-fail/unsized2.rs (renamed from src/test/compile-fail/unsized2.rs)0
-rw-r--r--src/test/parse-fail/virtual-structs.rs (renamed from src/test/compile-fail/virtual-structs.rs)0
-rw-r--r--src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs (renamed from src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs)0
-rw-r--r--src/test/pretty/empty-impl.rs4
-rw-r--r--src/test/pretty/path-type-bounds.rs4
-rw-r--r--src/test/run-fail/bug-811.rs4
-rw-r--r--src/test/run-make/rustdoc-json/foo.rs2
-rw-r--r--src/test/run-make/rustdoc-negative-impl/foo.rs2
-rw-r--r--src/test/run-make/rustdoc-search-index/index.rs2
-rw-r--r--src/test/run-make/rustdoc-smoke/foo.rs2
-rw-r--r--src/test/run-make/rustdoc-viewpath-self/foo.rs2
-rw-r--r--src/test/run-make/rustdoc-where/foo.rs15
-rw-r--r--src/test/run-make/save-analysis/foo.rs3
-rwxr-xr-xsrc/test/run-make/simd-ffi/simd.rs8
-rw-r--r--src/test/run-make/symbols-are-reasonable/lib.rs2
-rw-r--r--src/test/run-make/target-specs/foo.rs8
-rw-r--r--src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs2
-rw-r--r--src/test/run-pass-valgrind/dst-dtor-1.rs2
-rw-r--r--src/test/run-pass/associated-types-basic.rs4
-rw-r--r--src/test/run-pass/associated-types-conditional-dispatch.rs7
-rw-r--r--src/test/run-pass/associated-types-issue-20371.rs4
-rw-r--r--src/test/run-pass/associated-types-issue-21212.rs3
-rw-r--r--src/test/run-pass/associated-types-nested-projections.rs5
-rw-r--r--src/test/run-pass/associated-types-normalize-in-bounds-binding.rs6
-rw-r--r--src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs10
-rw-r--r--src/test/run-pass/associated-types-normalize-in-bounds.rs10
-rw-r--r--src/test/run-pass/associated-types-normalize-unifield-struct.rs5
-rw-r--r--src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs2
-rw-r--r--src/test/run-pass/associated-types-projection-in-object-type.rs2
-rw-r--r--src/test/run-pass/associated-types-projection-in-supertrait.rs2
-rw-r--r--src/test/run-pass/associated-types-projection-in-where-clause.rs2
-rw-r--r--src/test/run-pass/associated-types-ref-in-struct-literal.rs2
-rw-r--r--src/test/run-pass/associated-types-resolve-lifetime.rs2
-rw-r--r--src/test/run-pass/associated-types-struct-field-named.rs2
-rw-r--r--src/test/run-pass/associated-types-struct-field-numbered.rs2
-rw-r--r--src/test/run-pass/associated-types-sugar-path.rs3
-rw-r--r--src/test/run-pass/bitv-perf-test.rs6
-rw-r--r--src/test/run-pass/borrowck-trait-lifetime.rs5
-rw-r--r--src/test/run-pass/bug-7295.rs6
-rw-r--r--src/test/run-pass/builtin-superkinds-in-metadata.rs1
-rw-r--r--src/test/run-pass/builtin-superkinds-phantom-typaram.rs6
-rw-r--r--src/test/run-pass/c-stack-returning-int64.rs4
-rw-r--r--src/test/run-pass/class-typarams.rs7
-rw-r--r--src/test/run-pass/const-polymorphic-paths.rs10
-rw-r--r--src/test/run-pass/deriving-hash.rs2
-rw-r--r--src/test/run-pass/deriving-meta-multiple.rs2
-rw-r--r--src/test/run-pass/deriving-meta.rs2
-rw-r--r--src/test/run-pass/dst-coercions.rs2
-rw-r--r--src/test/run-pass/enum-null-pointer-opt.rs2
-rw-r--r--src/test/run-pass/explicit-self-generic.rs8
-rw-r--r--src/test/run-pass/foreign-fn-linkname.rs2
-rw-r--r--src/test/run-pass/generic-default-type-params-cross-crate.rs10
-rw-r--r--src/test/run-pass/hrtb-opt-in-copy.rs4
-rw-r--r--src/test/run-pass/inner-static.rs6
-rw-r--r--src/test/run-pass/issue-10456.rs4
-rw-r--r--src/test/run-pass/issue-10802.rs2
-rw-r--r--src/test/run-pass/issue-10902.rs4
-rw-r--r--src/test/run-pass/issue-11205.rs2
-rw-r--r--src/test/run-pass/issue-11384.rs2
-rw-r--r--src/test/run-pass/issue-11612.rs2
-rw-r--r--src/test/run-pass/issue-11677.rs9
-rw-r--r--src/test/run-pass/issue-11736.rs4
-rw-r--r--src/test/run-pass/issue-13105.rs4
-rw-r--r--src/test/run-pass/issue-14399.rs2
-rw-r--r--src/test/run-pass/issue-14589.rs7
-rw-r--r--src/test/run-pass/issue-14958.rs2
-rw-r--r--src/test/run-pass/issue-14959.rs8
-rw-r--r--src/test/run-pass/issue-15858.rs12
-rw-r--r--src/test/run-pass/issue-16596.rs2
-rw-r--r--src/test/run-pass/issue-16643.rs2
-rw-r--r--src/test/run-pass/issue-17662.rs6
-rw-r--r--src/test/run-pass/issue-17732.rs3
-rw-r--r--src/test/run-pass/issue-17771.rs2
-rw-r--r--src/test/run-pass/issue-17816.rs6
-rw-r--r--src/test/run-pass/issue-17904.rs4
-rw-r--r--src/test/run-pass/issue-18232.rs4
-rw-r--r--src/test/run-pass/issue-18906.rs2
-rw-r--r--src/test/run-pass/issue-19121.rs2
-rw-r--r--src/test/run-pass/issue-19129-2.rs2
-rw-r--r--src/test/run-pass/issue-19135.rs6
-rw-r--r--src/test/run-pass/issue-19358.rs2
-rw-r--r--src/test/run-pass/issue-19398.rs4
-rw-r--r--src/test/run-pass/issue-19479.rs6
-rw-r--r--src/test/run-pass/issue-19631.rs1
-rw-r--r--src/test/run-pass/issue-19632.rs1
-rw-r--r--src/test/run-pass/issue-20055-box-trait.rs4
-rw-r--r--src/test/run-pass/issue-20343.rs2
-rw-r--r--src/test/run-pass/issue-20763-1.rs5
-rw-r--r--src/test/run-pass/issue-20763-2.rs5
-rw-r--r--src/test/run-pass/issue-21363.rs1
-rw-r--r--src/test/run-pass/issue-21909.rs6
-rw-r--r--src/test/run-pass/issue-2311-2.rs5
-rw-r--r--src/test/run-pass/issue-2311.rs2
-rw-r--r--src/test/run-pass/issue-2312.rs2
-rw-r--r--src/test/run-pass/issue-2383.rs4
-rw-r--r--src/test/run-pass/issue-2611-3.rs4
-rw-r--r--src/test/run-pass/issue-2734.rs4
-rw-r--r--src/test/run-pass/issue-2735.rs4
-rw-r--r--src/test/run-pass/issue-4107.rs12
-rw-r--r--src/test/run-pass/issue-5192.rs1
-rw-r--r--src/test/run-pass/issue-5708.rs4
-rw-r--r--src/test/run-pass/issue-6128.rs4
-rw-r--r--src/test/run-pass/issue-6318.rs4
-rw-r--r--src/test/run-pass/issue-7575.rs1
-rw-r--r--src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs5
-rw-r--r--src/test/run-pass/issue-7911.rs4
-rw-r--r--src/test/run-pass/issue-8248.rs4
-rw-r--r--src/test/run-pass/issue-8249.rs4
-rw-r--r--src/test/run-pass/issue-9719.rs8
-rw-r--r--src/test/run-pass/lint-cstack.rs2
-rw-r--r--src/test/run-pass/method-early-bound-lifetimes-on-self.rs8
-rw-r--r--src/test/run-pass/method-recursive-blanket-impl.rs8
-rw-r--r--src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs3
-rw-r--r--src/test/run-pass/overloaded-autoderef-vtable.rs6
-rw-r--r--src/test/run-pass/overloaded-calls-param-vtables.rs5
-rw-r--r--src/test/run-pass/parameterized-trait-with-bounds.rs8
-rw-r--r--src/test/run-pass/privacy-ns.rs3
-rw-r--r--src/test/run-pass/regions-assoc-type-static-bound.rs5
-rw-r--r--src/test/run-pass/regions-bound-lists-feature-gate-2.rs4
-rw-r--r--src/test/run-pass/regions-bound-lists-feature-gate.rs5
-rw-r--r--src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs6
-rw-r--r--src/test/run-pass/regions-early-bound-trait-param.rs6
-rw-r--r--src/test/run-pass/regions-issue-21422.rs25
-rw-r--r--src/test/run-pass/regions-no-bound-in-argument-cleanup.rs4
-rw-r--r--src/test/run-pass/regions-no-variance-from-fn-generics.rs10
-rw-r--r--src/test/run-pass/regions-refcell.rs8
-rw-r--r--src/test/run-pass/rename-directory.rs6
-rw-r--r--src/test/run-pass/self-impl.rs1
-rw-r--r--src/test/run-pass/send_str_hashmap.rs2
-rw-r--r--src/test/run-pass/send_str_treemap.rs2
-rw-r--r--src/test/run-pass/simple-match-generic-tag.rs9
-rw-r--r--src/test/run-pass/syntax-trait-polarity.rs6
-rw-r--r--src/test/run-pass/trailing-comma.rs4
-rw-r--r--src/test/run-pass/trait-bounds-basic.rs2
-rw-r--r--src/test/run-pass/trait-bounds-on-structs-and-enums.rs6
-rw-r--r--src/test/run-pass/trait-bounds-recursion.rs8
-rw-r--r--src/test/run-pass/trait-default-method-bound-subst4.rs1
-rw-r--r--src/test/run-pass/trait-impl.rs4
-rw-r--r--src/test/run-pass/trait-inheritance-num2.rs3
-rw-r--r--src/test/run-pass/trait-inheritance-static2.rs4
-rw-r--r--src/test/run-pass/trait-object-generics.rs11
-rw-r--r--src/test/run-pass/trait-static-method-overwriting.rs10
-rw-r--r--src/test/run-pass/traits-issue-22019.rs6
-rw-r--r--src/test/run-pass/unboxed-closures-infer-recursive-fn.rs6
-rw-r--r--src/test/run-pass/unique-object-move.rs2
-rw-r--r--src/test/run-pass/unsized.rs24
-rw-r--r--src/test/run-pass/unsized2.rs12
-rw-r--r--src/test/run-pass/variadic-ffi.rs8
-rw-r--r--src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs34
-rw-r--r--src/test/run-pass/variance-trait-matching.rs49
-rw-r--r--src/test/run-pass/variance-vec-covariant.rs28
-rw-r--r--src/test/run-pass/visible-private-types-feature-gate.rs2
-rw-r--r--src/test/run-pass/where-clause-bounds-inconsistency.rs4
-rw-r--r--src/test/run-pass/where-clause-early-bound-lifetimes.rs2
-rw-r--r--src/test/run-pass/where-clause-method-substituion.rs4
-rw-r--r--src/test/run-pass/where-for-self.rs10
735 files changed, 12326 insertions, 4595 deletions
diff --git a/README.md b/README.md
index 065c4ed7c7b..b6a73730d35 100644
--- 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
diff --git a/configure b/configure
index ec1e741fb9c..d1b27a96f93 100755
--- 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
diff --git a/mk/tests.mk b/mk/tests.mk
index d8597724370..692d28bfad3 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -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 \
diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs
index df2981a6c83..2c046d25279 100644
--- a/src/compiletest/common.rs
+++ b/src/compiletest/common.rs
@@ -15,6 +15,7 @@ use std::str::FromStr;
#[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",
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs
index 86710d50d8a..278ce5565d9 100644
--- a/src/compiletest/compiletest.rs
+++ b/src/compiletest/compiletest.rs
@@ -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"),
diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs
index 658c0cb3f4e..1cbb8742bbc 100644
--- a/src/compiletest/runtest.rs
+++ b/src/compiletest/runtest.rs
@@ -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,
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 70baebf0d30..db940947040 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -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
diff --git a/src/doc/trpl/ffi.md b/src/doc/trpl/ffi.md
index f2b95f19edc..97e826579fd 100644
--- a/src/doc/trpl/ffi.md
+++ b/src/doc/trpl/ffi.md
@@ -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.
diff --git a/src/doc/trpl/patterns.md b/src/doc/trpl/patterns.md
index 122cffe3697..9e82e48fd18 100644
--- a/src/doc/trpl/patterns.md
+++ b/src/doc/trpl/patterns.md
@@ -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),
_ => {},
}
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 3830d7fe295..934e6ab2159 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -73,7 +73,6 @@ use core::prelude::*;
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 @@ impl<T> Clone for 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 {
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 340a8d59612..a3516bd667b 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -10,13 +10,14 @@
//! 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::ops::{Deref, DerefMut};
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 @@ impl<T: ?Sized + Ord> Ord for Box<T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + Eq> Eq for Box<T> {}
+#[cfg(stage0)]
impl<S: hash::Hasher, T: ?Sized + Hash<S>> Hash<S> for Box<T> {
#[inline]
fn hash(&self, state: &mut S) {
(**self).hash(state);
}
}
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized + Hash> Hash for Box<T> {
+ fn hash<H: hash::Hasher>(&self, state: &mut H) {
+ (**self).hash(state);
+ }
+}
/// Extension methods for an owning `Any` trait object.
#[unstable(feature = "alloc",
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index b3c2638f3ae..bc349ebebde 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -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))]
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index f361c36ec8f..9d395115431 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -144,13 +144,12 @@
#![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 @@ impl<T: Clone> Rc<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 @@ impl<T: Ord> Ord for Rc<T> {
}
// 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> {
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index 4cd3d587580..b43f9adfb26 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -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 @@ impl<'a> 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>,
diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs
index 6196d94b5a6..9f549fd7237 100644
--- a/src/libcollections/binary_heap.rs
+++ b/src/libcollections/binary_heap.rs
@@ -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 @@ impl<'a, T> IntoIterator for &'a BinaryHeap<T> where T: Ord {
#[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);
diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs
index 0b762788b20..11c576eab15 100644
--- a/src/libcollections/bit.rs
+++ b/src/libcollections/bit.rs
@@ -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.
//!
@@ -38,17 +38,17 @@
//! [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::num::Int;
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 @@ static FALSE: bool = false;
/// # 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 @@ static FALSE: bool = false;
/// ```
#[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 @@ impl Bitv {
}
/// 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 @@ impl Bitv {
}
}
- /// 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 @@ impl 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 @@ impl 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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
}
/// 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 @@ impl Bitv {
).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 @@ impl Bitv {
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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
}
/// 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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
}
/// 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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
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 @@ impl Bitv {
/// # 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 @@ impl Bitv {
}
#[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 @@ impl Extend<bool> for Bitv {
}
#[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 @@ impl fmt::Debug for Bitv {
}
#[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 @@ impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Bitv {
}
}
}
+#[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 @@ impl cmp::PartialEq for Bitv {
}
#[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 @@ impl<'a> Iterator for Iter<'a> {
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 @@ impl<'a> RandomAccessIterator for Iter<'a> {
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 @@ impl<'a> IntoIterator for &'a Bitv {
/// # 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 @@ impl<'a> IntoIterator for &'a Bitv {
/// 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 @@ impl<'a> IntoIterator for &'a Bitv {
/// 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 @@ impl 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 @@ impl 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 @@ impl BitvSet {
/// # 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 @@ impl BitvSet {
/// # 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 @@ impl BitvSet {
/// # 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 @@ impl BitvSet {
/// # 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 @@ impl BitvSet {
/// # 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 @@ impl BitvSet {
#[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 @@ impl BitvSet {
/// ```
#[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 @@ impl BitvSet {
/// # 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 @@ impl BitvSet {
/// ```
#[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 @@ impl BitvSet {
/// # 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 @@ impl BitvSet {
/// ```
#[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 @@ impl BitvSet {
/// # 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 @@ impl BitvSet {
/// ```
#[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 @@ impl BitvSet {
/// # 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 @@ impl BitvSet {
/// ```
#[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 @@ impl BitvSet {
/// # 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 @@ impl 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 @@ impl 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 @@ impl 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 @@ impl 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 @@ impl BitvSet {
}
// 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 @@ impl BitvSet {
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 @@ impl fmt::Debug for BitvSet {
}
}
-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 @@ impl<'a> Iterator for SetIter<'a> {
#[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 @@ impl<'a> Iterator for TwoBitPositions<'a> {
#[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 @@ mod tests {
#[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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
#[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 @@ mod tests {
#[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 @@ mod tests {
#[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 @@ mod tests {
#[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 @@ mod tests {
#[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 @@ mod tests {
#[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 @@ mod tests {
#[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 @@ mod tests {
#[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 @@ mod tests {
#[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 @@ mod 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 @@ mod 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 @@ mod 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 @@ mod tests {
}
#[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 @@ mod tests {
}
#[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 @@ mod tests {
#[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 @@ mod bitv_bench {
#[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 @@ mod bitv_bench {
}
#[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 @@ mod bitv_bench {
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
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 @@ mod bitv_set_test {
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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
}
#[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 @@ mod bitv_set_test {
#[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 @@ mod bitv_set_bench {
}
#[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
index 00000000000..901d7a73b51
--- /dev/null
+++ b/src/libcollections/borrow.rs
@@ -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
index 00000000000..c1d74b16ce6
--- /dev/null
+++ b/src/libcollections/borrow_stage0.rs
@@ -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
+ }
+}
diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs
index 747211e9238..7823f536c7a 100644
--- a/src/libcollections/btree/map.rs
+++ b/src/libcollections/btree/map.rs
@@ -19,7 +19,6 @@ use self::Entry::*;
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::ops::{Index, IndexMut};
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 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// 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 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// 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 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// ```
// 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 @@ impl<K: Ord, V> BTreeMap<K, 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 @@ mod stack {
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 @@ mod stack {
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 @@ mod stack {
#[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 @@ impl<K: Ord, V> FromIterator<(K, V)> for 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 @@ impl<S: Hasher, K: Hash<S>, V: Hash<S>> Hash<S> for BTreeMap<K, V> {
}
}
}
+#[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 @@ impl<K: Debug, V: Debug> Debug for BTreeMap<K, V> {
#[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 @@ impl<K: Ord, Q: ?Sized, V> Index<Q> for BTreeMap<K, 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 @@ impl<K, V> BTreeMap<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 @@ impl<K, V> BTreeMap<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;
diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs
index 24523d4dcc9..f0fc12da727 100644
--- a/src/libcollections/btree/node.rs
+++ b/src/libcollections/btree/node.rs
@@ -18,13 +18,15 @@ pub use self::TraversalItem::*;
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 @@ impl<T> Drop for RawItems<T> {
#[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 @@ impl<K, V> Drop for Node<K, V> {
self.destroy();
}
- self.keys.ptr = ptr::null_mut();
+ self.keys = unsafe { Unique::new(0 as *mut K) };
}
}
@@ -308,9 +313,9 @@ impl<K, V> 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 @@ impl<K, V> 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 @@ impl<K, V> 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 @@ impl<K, V> Node<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 @@ impl<K: Clone, V: Clone> Clone for 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 @@ impl <K, V> Node<K, V> {
/// 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 @@ impl<K, V, Type, NodeType> Handle<*mut 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 @@ impl<K, V, NodeRef: Deref<Target=Node<K, V>>, Type> Handle<NodeRef, Type, handle
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 @@ impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::Edge, NodeType> where
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 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a mut Node<K, V>, handle::KV, NodeType
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 @@ impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::KV, NodeType> where
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 @@ impl<K, V> Node<K, V> {
debug_assert!(index < self.len(), "kv_handle index out of bounds");
Handle {
node: self,
- index: index
+ index: index,
+ marker: PhantomData,
}
}
@@ -1064,7 +1085,7 @@ impl<K, V> Node<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),
diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs
index 7ef887b70cc..929b2f58043 100644
--- a/src/libcollections/btree/set.rs
+++ b/src/libcollections/btree/set.rs
@@ -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::fmt;
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 @@ impl<T: Ord> BTreeSet<T> {
/// 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 @@ impl<T: Ord> BTreeSet<T> {
/// 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 @@ impl<'a, T> IntoIterator for &'a BTreeSet<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/enum_set.rs b/src/libcollections/enum_set.rs
index d5403ca5d9b..0c957426060 100644
--- a/src/libcollections/enum_set.rs
+++ b/src/libcollections/enum_set.rs
@@ -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 @@ use core::ops::{Sub, BitOr, BitAnd, BitXor};
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 @@ impl<E:CLike> EnumSet<E> {
/// 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 @@ impl<E:CLike> BitXor for 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 @@ impl<E> Clone for 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 @@ impl<E:CLike> Iterator for Iter<E> {
}
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 @@ impl<'a, E> IntoIterator for &'a EnumSet<E> where E: CLike {
}
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);
}
}
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index cacbf3bce80..6569ab9c05a 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -26,7 +26,6 @@
#![feature(box_syntax)]
#![feature(box_patterns)]
#![feature(core)]
-#![feature(hash)]
#![feature(staged_api)]
#![feature(unboxed_closures)]
#![feature(unicode)]
@@ -49,17 +48,33 @@ extern crate alloc;
#[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;
@@ -71,27 +86,42 @@ mod macros;
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/dlist.rs b/src/libcollections/linked_list.rs
index eb1bf93c0aa..c142819a518 100644
--- a/src/libcollections/dlist.rs
+++ b/src/libcollections/linked_list.rs
@@ -10,13 +10,13 @@
//! A doubly-linked list with owned nodes.
//!
-//! The `DList` allows pushing and popping elements at either end and is thus
+//! The `LinkedList` 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`.
+// 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 DList::prev are raw pointers that form a full chain in
+// Backlinks over LinkedList::prev are raw pointers that form a full chain in
// the reverse direction.
#![stable(feature = "rust1", since = "1.0.0")]
@@ -27,14 +27,20 @@ use alloc::boxed::Box;
use core::cmp::Ordering;
use core::default::Default;
use core::fmt;
-use core::hash::{Writer, Hasher, Hash};
+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 DList<T> {
+pub struct LinkedList<T> {
length: usize,
list_head: Link<T>,
list_tail: Rawlink<Node<T>>,
@@ -56,7 +62,7 @@ struct Node<T> {
value: T,
}
-/// An iterator over references to the items of a `DList`.
+/// 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>,
@@ -76,20 +82,20 @@ impl<'a, T> Clone for Iter<'a, T> {
}
}
-/// An iterator over mutable references to the items of a `DList`.
+/// 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 DList<T>,
+ 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 `DList`.
+/// 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: DList<T>
+ list: LinkedList<T>
}
/// Rawlink is a type like Option<T> but for holding a raw pointer
@@ -147,7 +153,7 @@ fn link_with_prev<T>(mut next: Box<Node<T>>, prev: Rawlink<Node<T>>)
}
// private methods
-impl<T> DList<T> {
+impl<T> LinkedList<T> {
/// Add a Node first in the list
#[inline]
fn push_front_node(&mut self, mut new_head: Box<Node<T>>) {
@@ -207,18 +213,18 @@ impl<T> DList<T> {
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for DList<T> {
+impl<T> Default for LinkedList<T> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- fn default() -> DList<T> { DList::new() }
+ fn default() -> LinkedList<T> { LinkedList::new() }
}
-impl<T> DList<T> {
- /// Creates an empty `DList`.
+impl<T> LinkedList<T> {
+ /// Creates an empty `LinkedList`.
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn new() -> DList<T> {
- DList{list_head: None, list_tail: Rawlink::none(), length: 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.
@@ -231,10 +237,10 @@ impl<T> DList<T> {
/// # Examples
///
/// ```
- /// use std::collections::DList;
+ /// use std::collections::LinkedList;
///
- /// let mut a = DList::new();
- /// let mut b = DList::new();
+ /// let mut a = LinkedList::new();
+ /// let mut b = LinkedList::new();
/// a.push_back(1);
/// a.push_back(2);
/// b.push_back(3);
@@ -247,7 +253,7 @@ impl<T> DList<T> {
/// }
/// println!("{}", b.len()); // prints 0
/// ```
- pub fn append(&mut self, other: &mut DList<T>) {
+ pub fn append(&mut self, other: &mut LinkedList<T>) {
match self.list_tail.resolve() {
None => {
self.length = other.length;
@@ -301,16 +307,16 @@ impl<T> DList<T> {
IntoIter{list: self}
}
- /// Returns `true` if the `DList` is empty.
+ /// Returns `true` if the `LinkedList` is empty.
///
/// This operation should compute in O(1) time.
///
/// # Examples
///
/// ```
- /// use std::collections::DList;
+ /// use std::collections::LinkedList;
///
- /// let mut dl = DList::new();
+ /// let mut dl = LinkedList::new();
/// assert!(dl.is_empty());
///
/// dl.push_front("foo");
@@ -322,16 +328,16 @@ impl<T> DList<T> {
self.list_head.is_none()
}
- /// Returns the length of the `DList`.
+ /// Returns the length of the `LinkedList`.
///
/// This operation should compute in O(1) time.
///
/// # Examples
///
/// ```
- /// use std::collections::DList;
+ /// use std::collections::LinkedList;
///
- /// let mut dl = DList::new();
+ /// let mut dl = LinkedList::new();
///
/// dl.push_front(2);
/// assert_eq!(dl.len(), 1);
@@ -349,16 +355,16 @@ impl<T> DList<T> {
self.length
}
- /// Removes all elements from the `DList`.
+ /// Removes all elements from the `LinkedList`.
///
/// This operation should compute in O(n) time.
///
/// # Examples
///
/// ```
- /// use std::collections::DList;
+ /// use std::collections::LinkedList;
///
- /// let mut dl = DList::new();
+ /// let mut dl = LinkedList::new();
///
/// dl.push_front(2);
/// dl.push_front(1);
@@ -373,7 +379,7 @@ impl<T> DList<T> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn clear(&mut self) {
- *self = DList::new()
+ *self = LinkedList::new()
}
/// Provides a reference to the front element, or `None` if the list is
@@ -382,9 +388,9 @@ impl<T> DList<T> {
/// # Examples
///
/// ```
- /// use std::collections::DList;
+ /// use std::collections::LinkedList;
///
- /// let mut dl = DList::new();
+ /// let mut dl = LinkedList::new();
/// assert_eq!(dl.front(), None);
///
/// dl.push_front(1);
@@ -403,9 +409,9 @@ impl<T> DList<T> {
/// # Examples
///
/// ```
- /// use std::collections::DList;
+ /// use std::collections::LinkedList;
///
- /// let mut dl = DList::new();
+ /// let mut dl = LinkedList::new();
/// assert_eq!(dl.front(), None);
///
/// dl.push_front(1);
@@ -430,9 +436,9 @@ impl<T> DList<T> {
/// # Examples
///
/// ```
- /// use std::collections::DList;
+ /// use std::collections::LinkedList;
///
- /// let mut dl = DList::new();
+ /// let mut dl = LinkedList::new();
/// assert_eq!(dl.back(), None);
///
/// dl.push_back(1);
@@ -451,9 +457,9 @@ impl<T> DList<T> {
/// # Examples
///
/// ```
- /// use std::collections::DList;
+ /// use std::collections::LinkedList;
///
- /// let mut dl = DList::new();
+ /// let mut dl = LinkedList::new();
/// assert_eq!(dl.back(), None);
///
/// dl.push_back(1);
@@ -479,9 +485,9 @@ impl<T> DList<T> {
/// # Examples
///
/// ```
- /// use std::collections::DList;
+ /// use std::collections::LinkedList;
///
- /// let mut dl = DList::new();
+ /// let mut dl = LinkedList::new();
///
/// dl.push_front(2);
/// assert_eq!(dl.front().unwrap(), &2);
@@ -503,9 +509,9 @@ impl<T> DList<T> {
/// # Examples
///
/// ```
- /// use std::collections::DList;
+ /// use std::collections::LinkedList;
///
- /// let mut d = DList::new();
+ /// let mut d = LinkedList::new();
/// assert_eq!(d.pop_front(), None);
///
/// d.push_front(1);
@@ -526,9 +532,9 @@ impl<T> DList<T> {
/// # Examples
///
/// ```
- /// use std::collections::DList;
+ /// use std::collections::LinkedList;
///
- /// let mut d = DList::new();
+ /// let mut d = LinkedList::new();
/// d.push_back(1);
/// d.push_back(3);
/// assert_eq!(3, *d.back().unwrap());
@@ -544,9 +550,9 @@ impl<T> DList<T> {
/// # Examples
///
/// ```
- /// use std::collections::DList;
+ /// use std::collections::LinkedList;
///
- /// let mut d = DList::new();
+ /// let mut d = LinkedList::new();
/// assert_eq!(d.pop_back(), None);
/// d.push_back(1);
/// d.push_back(3);
@@ -569,9 +575,9 @@ impl<T> DList<T> {
/// # Examples
///
/// ```
- /// use std::collections::DList;
+ /// use std::collections::LinkedList;
///
- /// let mut d = DList::new();
+ /// let mut d = LinkedList::new();
///
/// d.push_front(1);
/// d.push_front(2);
@@ -583,13 +589,13 @@ impl<T> DList<T> {
/// assert_eq!(splitted.pop_front(), None);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn split_off(&mut self, at: usize) -> DList<T> {
+ 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, DList::new());
+ return mem::replace(self, LinkedList::new());
} else if at == len {
- return DList::new();
+ return LinkedList::new();
}
// Below, we iterate towards the `i-1`th node, either from the start or the end,
@@ -612,7 +618,7 @@ impl<T> DList<T> {
iter.tail
};
- let mut splitted_list = DList {
+ let mut splitted_list = LinkedList {
list_head: None,
list_tail: self.list_tail,
length: len - at
@@ -628,9 +634,9 @@ impl<T> DList<T> {
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Drop for DList<T> {
+impl<T> Drop for LinkedList<T> {
fn drop(&mut self) {
- // Dissolve the dlist in backwards direction
+ // 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;
@@ -761,9 +767,9 @@ impl<'a, A> IterMut<'a, A> {
/// # Examples
///
/// ```
- /// use std::collections::DList;
+ /// use std::collections::LinkedList;
///
- /// let mut list: DList<_> = vec![1, 3, 4].into_iter().collect();
+ /// let mut list: LinkedList<_> = vec![1, 3, 4].into_iter().collect();
///
/// {
/// let mut it = list.iter_mut();
@@ -788,9 +794,9 @@ impl<'a, A> IterMut<'a, A> {
/// # Examples
///
/// ```
- /// use std::collections::DList;
+ /// use std::collections::LinkedList;
///
- /// let mut list: DList<_> = vec![1, 2, 3].into_iter().collect();
+ /// let mut list: LinkedList<_> = vec![1, 2, 3].into_iter().collect();
///
/// let mut it = list.iter_mut();
/// assert_eq!(it.next().unwrap(), &1);
@@ -829,16 +835,16 @@ impl<A> DoubleEndedIterator for IntoIter<A> {
}
#[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> {
+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(iterator);
+ ret.extend(iter);
ret
}
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> IntoIterator for DList<T> {
+impl<T> IntoIterator for LinkedList<T> {
type Item = T;
type IntoIter = IntoIter<T>;
@@ -848,7 +854,7 @@ impl<T> IntoIterator for DList<T> {
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> IntoIterator for &'a DList<T> {
+impl<'a, T> IntoIterator for &'a LinkedList<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
@@ -857,7 +863,7 @@ impl<'a, T> IntoIterator for &'a DList<T> {
}
}
-impl<'a, T> IntoIterator for &'a mut DList<T> {
+impl<'a, T> IntoIterator for &'a mut LinkedList<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
@@ -867,54 +873,54 @@ impl<'a, T> IntoIterator for &'a mut DList<T> {
}
#[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); }
+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 DList<A> {
- fn eq(&self, other: &DList<A>) -> bool {
+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: &DList<A>) -> bool {
+ 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 DList<A> {}
+impl<A: Eq> Eq for LinkedList<A> {}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<A: PartialOrd> PartialOrd for DList<A> {
- fn partial_cmp(&self, other: &DList<A>) -> Option<Ordering> {
+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 DList<A> {
+impl<A: Ord> Ord for LinkedList<A> {
#[inline]
- fn cmp(&self, other: &DList<A>) -> Ordering {
+ 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 DList<A> {
- fn clone(&self) -> DList<A> {
- self.iter().map(|x| x.clone()).collect()
+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 DList<A> {
+impl<A: fmt::Debug> fmt::Debug for LinkedList<A> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- try!(write!(f, "DList ["));
+ try!(write!(f, "LinkedList ["));
for (i, e) in self.iter().enumerate() {
if i != 0 { try!(write!(f, ", ")); }
@@ -926,7 +932,8 @@ impl<A: fmt::Debug> fmt::Debug for DList<A> {
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<S: Writer + Hasher, A: Hash<S>> Hash<S> for DList<A> {
+#[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 {
@@ -934,6 +941,16 @@ impl<S: Writer + Hasher, A: Hash<S>> Hash<S> for DList<A> {
}
}
}
+#[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 {
@@ -944,9 +961,9 @@ mod tests {
use test::Bencher;
use test;
- use super::{DList, Node};
+ use super::{LinkedList, Node};
- pub fn check_links<T>(list: &DList<T>) {
+ 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>;
@@ -980,7 +997,7 @@ mod tests {
#[test]
fn test_basic() {
- let mut m = DList::new();
+ let mut m = LinkedList::new();
assert_eq!(m.pop_front(), None);
assert_eq!(m.pop_back(), None);
assert_eq!(m.pop_front(), None);
@@ -999,7 +1016,7 @@ mod tests {
m.push_back(box 7);
assert_eq!(m.pop_front(), Some(box 1));
- let mut n = DList::new();
+ let mut n = LinkedList::new();
n.push_front(2);
n.push_front(3);
{
@@ -1019,21 +1036,21 @@ mod tests {
}
#[cfg(test)]
- fn generate_test() -> DList<i32> {
+ fn generate_test() -> LinkedList<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()
+ fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
+ v.iter().cloned().collect()
}
#[test]
fn test_append() {
// Empty to empty
{
- let mut m = DList::<i32>::new();
- let mut n = DList::new();
+ let mut m = LinkedList::<i32>::new();
+ let mut n = LinkedList::new();
m.append(&mut n);
check_links(&m);
assert_eq!(m.len(), 0);
@@ -1041,8 +1058,8 @@ mod tests {
}
// Non-empty to empty
{
- let mut m = DList::new();
- let mut n = DList::new();
+ let mut m = LinkedList::new();
+ let mut n = LinkedList::new();
n.push_back(2);
m.append(&mut n);
check_links(&m);
@@ -1053,8 +1070,8 @@ mod tests {
}
// Empty to non-empty
{
- let mut m = DList::new();
- let mut n = DList::new();
+ let mut m = LinkedList::new();
+ let mut n = LinkedList::new();
m.push_back(2);
m.append(&mut n);
check_links(&m);
@@ -1089,7 +1106,7 @@ mod tests {
fn test_split_off() {
// singleton
{
- let mut m = DList::new();
+ let mut m = LinkedList::new();
m.push_back(1);
let p = m.split_off(0);
@@ -1130,7 +1147,7 @@ mod tests {
// no-op on the last index
{
- let mut m = DList::new();
+ let mut m = LinkedList::new();
m.push_back(1);
let p = m.split_off(1);
@@ -1148,7 +1165,7 @@ mod tests {
for (i, elt) in m.iter().enumerate() {
assert_eq!(i as i32, *elt);
}
- let mut n = DList::new();
+ let mut n = LinkedList::new();
assert_eq!(n.iter().next(), None);
n.push_front(4);
let mut it = n.iter();
@@ -1160,7 +1177,7 @@ mod tests {
#[test]
fn test_iterator_clone() {
- let mut n = DList::new();
+ let mut n = LinkedList::new();
n.push_back(2);
n.push_back(3);
n.push_back(4);
@@ -1174,7 +1191,7 @@ mod tests {
#[test]
fn test_iterator_double_end() {
- let mut n = DList::new();
+ let mut n = LinkedList::new();
assert_eq!(n.iter().next(), None);
n.push_front(4);
n.push_front(5);
@@ -1196,7 +1213,7 @@ mod tests {
for (i, elt) in m.iter().rev().enumerate() {
assert_eq!((6 - i) as i32, *elt);
}
- let mut n = DList::new();
+ let mut n = LinkedList::new();
assert_eq!(n.iter().rev().next(), None);
n.push_front(4);
let mut it = n.iter().rev();
@@ -1215,7 +1232,7 @@ mod tests {
len -= 1;
}
assert_eq!(len, 0);
- let mut n = DList::new();
+ let mut n = LinkedList::new();
assert!(n.iter_mut().next().is_none());
n.push_front(4);
n.push_back(5);
@@ -1229,7 +1246,7 @@ mod tests {
#[test]
fn test_iterator_mut_double_end() {
- let mut n = DList::new();
+ let mut n = LinkedList::new();
assert!(n.iter_mut().next_back().is_none());
n.push_front(4);
n.push_front(5);
@@ -1278,7 +1295,7 @@ mod tests {
for (i, elt) in m.iter_mut().rev().enumerate() {
assert_eq!((6 - i) as i32, *elt);
}
- let mut n = DList::new();
+ let mut n = LinkedList::new();
assert!(n.iter_mut().rev().next().is_none());
n.push_front(4);
let mut it = n.iter_mut().rev();
@@ -1313,8 +1330,8 @@ mod tests {
#[test]
fn test_hash() {
- let mut x = DList::new();
- let mut y = DList::new();
+ let mut x = LinkedList::new();
+ let mut y = LinkedList::new();
assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
@@ -1382,16 +1399,16 @@ mod tests {
#[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: LinkedList<_> = (0..10).collect();
+ assert_eq!(format!("{:?}", list), "LinkedList [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\"]");
+ 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: DList<_> = DList::new();
+ let mut m: LinkedList<_> = LinkedList::new();
let mut v = vec![];
for i in 0..sz {
check_links(&m);
@@ -1432,13 +1449,13 @@ mod tests {
fn bench_collect_into(b: &mut test::Bencher) {
let v = &[0; 64];
b.iter(|| {
- let _: DList<_> = v.iter().cloned().collect();
+ let _: LinkedList<_> = v.iter().cloned().collect();
})
}
#[bench]
fn bench_push_front(b: &mut test::Bencher) {
- let mut m: DList<_> = DList::new();
+ let mut m: LinkedList<_> = LinkedList::new();
b.iter(|| {
m.push_front(0);
})
@@ -1446,7 +1463,7 @@ mod tests {
#[bench]
fn bench_push_back(b: &mut test::Bencher) {
- let mut m: DList<_> = DList::new();
+ let mut m: LinkedList<_> = LinkedList::new();
b.iter(|| {
m.push_back(0);
})
@@ -1454,7 +1471,7 @@ mod tests {
#[bench]
fn bench_push_back_pop_back(b: &mut test::Bencher) {
- let mut m: DList<_> = DList::new();
+ let mut m: LinkedList<_> = LinkedList::new();
b.iter(|| {
m.push_back(0);
m.pop_back();
@@ -1463,7 +1480,7 @@ mod tests {
#[bench]
fn bench_push_front_pop_front(b: &mut test::Bencher) {
- let mut m: DList<_> = DList::new();
+ let mut m: LinkedList<_> = LinkedList::new();
b.iter(|| {
m.push_front(0);
m.pop_front();
@@ -1473,7 +1490,7 @@ mod tests {
#[bench]
fn bench_iter(b: &mut test::Bencher) {
let v = &[0; 128];
- let m: DList<_> = v.iter().cloned().collect();
+ let m: LinkedList<_> = v.iter().cloned().collect();
b.iter(|| {
assert!(m.iter().count() == 128);
})
@@ -1481,7 +1498,7 @@ mod tests {
#[bench]
fn bench_iter_mut(b: &mut test::Bencher) {
let v = &[0; 128];
- let mut m: DList<_> = v.iter().cloned().collect();
+ let mut m: LinkedList<_> = v.iter().cloned().collect();
b.iter(|| {
assert!(m.iter_mut().count() == 128);
})
@@ -1489,7 +1506,7 @@ mod tests {
#[bench]
fn bench_iter_rev(b: &mut test::Bencher) {
let v = &[0; 128];
- let m: DList<_> = v.iter().cloned().collect();
+ let m: LinkedList<_> = v.iter().cloned().collect();
b.iter(|| {
assert!(m.iter().rev().count() == 128);
})
@@ -1497,7 +1514,7 @@ mod tests {
#[bench]
fn bench_iter_mut_rev(b: &mut test::Bencher) {
let v = &[0; 128];
- let mut m: DList<_> = v.iter().cloned().collect();
+ let mut m: LinkedList<_> = v.iter().cloned().collect();
b.iter(|| {
assert!(m.iter_mut().rev().count() == 128);
})
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 06ae8127c00..776b8b3af14 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -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};
@@ -105,6 +104,7 @@ use core::result::Result;
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 @@ impl 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 @@ mod tests {
#[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 @@ mod tests {
#[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]
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index 2d4dc2bcf30..ec0a487acdc 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -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::slice::AsSlice;
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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
Recompositions {
iter: self.nfd_chars(),
state: Composing,
- buffer: RingBuf::new(),
+ buffer: VecDeque::new(),
composee: None,
last_ccc: None
}
@@ -511,7 +512,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
Recompositions {
iter: self.nfkd_chars(),
state: Composing,
- buffer: RingBuf::new(),
+ buffer: VecDeque::new(),
composee: None,
last_ccc: None
}
@@ -530,7 +531,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ```
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ```
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ```
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ```
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ```
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ```
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ```
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ```
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ```
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = 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 @@ pub trait StrExt: Index<RangeFull, Output = 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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ```
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ```
#[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 @@ pub trait StrExt: Index<RangeFull, Output = 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 @@ pub trait StrExt: Index<RangeFull, Output = 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 @@ pub trait StrExt: Index<RangeFull, Output = 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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ```
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ```
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ```
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[unstable(feature = "collections",
reason = "awaiting convention about comparability of arbitrary slices")]
fn subslice_offset(&self, inner: &str) -> usize {
- 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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ pub trait StrExt: Index<RangeFull, Output = str> {
#[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 @@ mod tests {
&["\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()));
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index 69fd28d1723..3b179d0b94c 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -16,12 +16,11 @@
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 core::raw::Slice as RawSlice;
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 @@ impl String {
/// 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 @@ impl Error for FromUtf16Error {
#[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 @@ impl<'a> FromIterator<&'a str> for 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 @@ impl Extend<char> for String {
#[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 @@ macro_rules! impl_eq {
}
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 @@ impl<'a, 'b> PartialEq<&'b str> for CowString<'a> {
}
#[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 @@ impl fmt::Debug for String {
}
#[unstable(feature = "collections", reason = "waiting on Hash stabilization")]
+#[cfg(stage0)]
impl<H: hash::Writer + hash::Hasher> hash::Hash<H> for String {
#[inline]
fn hash(&self, hasher: &mut H) {
(**self).hash(hasher)
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(stage0))]
+impl hash::Hash for String {
+ #[inline]
+ fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
+ (**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 @@ impl<T: fmt::Display + ?Sized> ToString for T {
}
}
-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 @@ mod tests {
#[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]);
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index bde733644b5..1cc2a5235ab 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -50,24 +50,26 @@ use core::prelude::*;
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
@@ -137,10 +139,9 @@ use core::usize;
#[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 @@ impl<T> 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 @@ impl<T> Vec<T> {
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 @@ impl<T> Vec<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 @@ impl<T> Vec<T> {
Drain {
ptr: begin,
end: end,
- marker: ContravariantLifetime,
+ marker: PhantomData,
}
}
}
@@ -871,6 +871,8 @@ impl<T> Vec<T> {
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 @@ impl<T> Vec<T> {
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 @@ impl<T> Vec<T> {
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 @@ impl<T:Clone> Clone for Vec<T> {
}
}
+#[cfg(stage0)]
impl<S: hash::Writer + hash::Hasher, T: Hash<S>> Hash<S> for Vec<T> {
#[inline]
fn hash(&self, state: &mut S) {
Hash::hash(&**self, state)
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(stage0))]
+impl<T: Hash> Hash for Vec<T> {
+ #[inline]
+ fn hash<H: hash::Hasher>(&self, state: &mut H) {
+ Hash::hash(&**self, state)
+ }
+}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Index<usize> for Vec<T> {
@@ -1407,7 +1417,8 @@ impl<T> ops::DerefMut for Vec<T> {
#[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 @@ impl<'a, T> IntoIterator for &'a mut Vec<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 @@ macro_rules! impl_eq {
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 @@ macro_rules! impl_eq_for_cowvec {
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 @@ impl<T: PartialOrd> PartialOrd for Vec<T> {
}
}
-#[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 @@ impl<T: fmt::Debug> fmt::Debug for Vec<T> {
// 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 @@ impl<T> Drop for IntoIter<T> {
#[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 @@ impl<'a, T> Drop for Drain<'a, T> {
/// 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 @@ mod tests {
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/ring_buf.rs b/src/libcollections/vec_deque.rs
index 6dcdb21f800..3ba22a41ff7 100644
--- a/src/libcollections/ring_buf.rs
+++ b/src/libcollections/vec_deque.rs
@@ -8,8 +8,8 @@
// 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.
+//! 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
@@ -28,20 +28,26 @@ use core::marker;
use core::mem;
use core::num::{Int, UnsignedInt};
use core::ops::{Index, IndexMut};
-use core::ptr;
+use core::ptr::{self, Unique};
use core::raw::Slice as RawSlice;
-use core::hash::{Writer, Hash, Hasher};
+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
-/// `RingBuf` is a circular buffer, which can be used as a double-ended queue efficiently.
+/// `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 RingBuf<T> {
+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.
@@ -51,30 +57,30 @@ pub struct RingBuf<T> {
tail: usize,
head: usize,
cap: usize,
- ptr: *mut T
+ ptr: Unique<T>,
}
#[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<T: Send> Send for RingBuf<T> {}
+unsafe impl<T: Send> Send for VecDeque<T> {}
#[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<T: Sync> Sync for RingBuf<T> {}
+unsafe impl<T: Sync> Sync for VecDeque<T> {}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Clone> Clone for RingBuf<T> {
- fn clone(&self) -> RingBuf<T> {
+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 RingBuf<T> {
+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,
+ heap::deallocate(*self.ptr as *mut u8,
self.cap * mem::size_of::<T>(),
mem::min_align_of::<T>())
}
@@ -83,22 +89,22 @@ impl<T> Drop for RingBuf<T> {
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for RingBuf<T> {
+impl<T> Default for VecDeque<T> {
#[inline]
- fn default() -> RingBuf<T> { RingBuf::new() }
+ fn default() -> VecDeque<T> { VecDeque::new() }
}
-impl<T> RingBuf<T> {
+impl<T> VecDeque<T> {
/// Turn ptr into a slice
#[inline]
unsafe fn buffer_as_slice(&self) -> &[T] {
- mem::transmute(RawSlice { data: self.ptr, len: self.cap })
+ 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, len: self.cap })
+ mem::transmute(RawSlice { data: *self.ptr as *const T, len: self.cap })
}
/// Moves an element out of the buffer
@@ -149,48 +155,48 @@ impl<T> RingBuf<T> {
}
}
-impl<T> RingBuf<T> {
- /// Creates an empty `RingBuf`.
+impl<T> VecDeque<T> {
+ /// Creates an empty `VecDeque`.
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn new() -> RingBuf<T> {
- RingBuf::with_capacity(INITIAL_CAPACITY)
+ pub fn new() -> VecDeque<T> {
+ VecDeque::with_capacity(INITIAL_CAPACITY)
}
- /// Creates an empty `RingBuf` with space for at least `n` elements.
+ /// Creates an empty `VecDeque` with space for at least `n` elements.
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn with_capacity(n: usize) -> RingBuf<T> {
+ 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 = if mem::size_of::<T>() != 0 {
- unsafe {
+ 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() }
- ptr
+ Unique::new(ptr)
+ } else {
+ Unique::new(heap::EMPTY as *mut T)
}
- } else {
- heap::EMPTY as *mut T
};
- RingBuf {
+ VecDeque {
tail: 0,
head: 0,
cap: cap,
- ptr: ptr
+ ptr: ptr,
}
}
- /// Retrieves an element in the `RingBuf` by index.
+ /// Retrieves an element in the `VecDeque` by index.
///
/// # Examples
///
/// ```rust
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf = RingBuf::new();
+ /// let mut buf = VecDeque::new();
/// buf.push_back(3);
/// buf.push_back(4);
/// buf.push_back(5);
@@ -206,14 +212,14 @@ impl<T> RingBuf<T> {
}
}
- /// Retrieves an element in the `RingBuf` mutably by index.
+ /// Retrieves an element in the `VecDeque` mutably by index.
///
/// # Examples
///
/// ```rust
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf = RingBuf::new();
+ /// let mut buf = VecDeque::new();
/// buf.push_back(3);
/// buf.push_back(4);
/// buf.push_back(5);
@@ -245,9 +251,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```rust
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf = RingBuf::new();
+ /// let mut buf = VecDeque::new();
/// buf.push_back(3);
/// buf.push_back(4);
/// buf.push_back(5);
@@ -266,15 +272,15 @@ impl<T> RingBuf<T> {
}
}
- /// Returns the number of elements the `RingBuf` can hold without
+ /// Returns the number of elements the `VecDeque` can hold without
/// reallocating.
///
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let buf: RingBuf<i32> = RingBuf::with_capacity(10);
+ /// let buf: VecDeque<i32> = VecDeque::with_capacity(10);
/// assert!(buf.capacity() >= 10);
/// ```
#[inline]
@@ -282,7 +288,7 @@ impl<T> RingBuf<T> {
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.
+ /// 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
@@ -295,9 +301,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf: RingBuf<i32> = vec![1].into_iter().collect();
+ /// let mut buf: VecDeque<i32> = vec![1].into_iter().collect();
/// buf.reserve_exact(10);
/// assert!(buf.capacity() >= 11);
/// ```
@@ -316,9 +322,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf: RingBuf<i32> = vec![1].into_iter().collect();
+ /// let mut buf: VecDeque<i32> = vec![1].into_iter().collect();
/// buf.reserve(10);
/// assert!(buf.capacity() >= 11);
/// ```
@@ -335,11 +341,12 @@ impl<T> RingBuf<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() }
+ 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);
}
}
@@ -390,9 +397,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf = RingBuf::with_capacity(15);
+ /// let mut buf = VecDeque::with_capacity(15);
/// buf.extend(0..4);
/// assert_eq!(buf.capacity(), 15);
/// buf.shrink_to_fit();
@@ -453,11 +460,12 @@ impl<T> RingBuf<T> {
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() }
+ 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;
@@ -475,9 +483,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf = RingBuf::new();
+ /// let mut buf = VecDeque::new();
/// buf.push_back(5);
/// buf.push_back(10);
/// buf.push_back(15);
@@ -498,9 +506,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```rust
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf = RingBuf::new();
+ /// let mut buf = VecDeque::new();
/// buf.push_back(5);
/// buf.push_back(3);
/// buf.push_back(4);
@@ -521,9 +529,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```rust
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf = RingBuf::new();
+ /// let mut buf = VecDeque::new();
/// buf.push_back(5);
/// buf.push_back(3);
/// buf.push_back(4);
@@ -539,8 +547,8 @@ impl<T> RingBuf<T> {
tail: self.tail,
head: self.head,
cap: self.cap,
- ptr: self.ptr,
- marker: marker::ContravariantLifetime,
+ ptr: *self.ptr,
+ marker: marker::PhantomData,
}
}
@@ -553,7 +561,7 @@ impl<T> RingBuf<T> {
}
/// Returns a pair of slices which contain, in order, the contents of the
- /// `RingBuf`.
+ /// `VecDeque`.
#[inline]
#[unstable(feature = "collections",
reason = "matches collection reform specification, waiting for dust to settle")]
@@ -573,7 +581,7 @@ impl<T> RingBuf<T> {
}
/// Returns a pair of slices which contain, in order, the contents of the
- /// `RingBuf`.
+ /// `VecDeque`.
#[inline]
#[unstable(feature = "collections",
reason = "matches collection reform specification, waiting for dust to settle")]
@@ -596,14 +604,14 @@ impl<T> RingBuf<T> {
}
}
- /// Returns the number of elements in the `RingBuf`.
+ /// Returns the number of elements in the `VecDeque`.
///
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut v = RingBuf::new();
+ /// let mut v = VecDeque::new();
/// assert_eq!(v.len(), 0);
/// v.push_back(1);
/// assert_eq!(v.len(), 1);
@@ -616,9 +624,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut v = RingBuf::new();
+ /// let mut v = VecDeque::new();
/// assert!(v.is_empty());
/// v.push_front(1);
/// assert!(!v.is_empty());
@@ -626,15 +634,15 @@ impl<T> RingBuf<T> {
#[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
+ /// Creates a draining iterator that clears the `VecDeque` and iterates over
/// the removed items from start to end.
///
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut v = RingBuf::new();
+ /// let mut v = VecDeque::new();
/// v.push_back(1);
/// assert_eq!(v.drain().next(), Some(1));
/// assert!(v.is_empty());
@@ -653,9 +661,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut v = RingBuf::new();
+ /// let mut v = VecDeque::new();
/// v.push_back(1);
/// v.clear();
/// assert!(v.is_empty());
@@ -672,9 +680,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut d = RingBuf::new();
+ /// let mut d = VecDeque::new();
/// assert_eq!(d.front(), None);
///
/// d.push_back(1);
@@ -692,9 +700,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut d = RingBuf::new();
+ /// let mut d = VecDeque::new();
/// assert_eq!(d.front_mut(), None);
///
/// d.push_back(1);
@@ -716,9 +724,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut d = RingBuf::new();
+ /// let mut d = VecDeque::new();
/// assert_eq!(d.back(), None);
///
/// d.push_back(1);
@@ -736,9 +744,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut d = RingBuf::new();
+ /// let mut d = VecDeque::new();
/// assert_eq!(d.back(), None);
///
/// d.push_back(1);
@@ -761,9 +769,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut d = RingBuf::new();
+ /// let mut d = VecDeque::new();
/// d.push_back(1);
/// d.push_back(2);
///
@@ -787,9 +795,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut d = RingBuf::new();
+ /// let mut d = VecDeque::new();
/// d.push_front(1);
/// d.push_front(2);
/// assert_eq!(d.front(), Some(&2));
@@ -811,9 +819,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```rust
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf = RingBuf::new();
+ /// let mut buf = VecDeque::new();
/// buf.push_back(1);
/// buf.push_back(3);
/// assert_eq!(3, *buf.back().unwrap());
@@ -836,9 +844,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```rust
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf = RingBuf::new();
+ /// let mut buf = VecDeque::new();
/// assert_eq!(buf.pop_back(), None);
/// buf.push_back(1);
/// buf.push_back(3);
@@ -870,9 +878,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf = RingBuf::new();
+ /// let mut buf = VecDeque::new();
/// assert_eq!(buf.swap_back_remove(0), None);
/// buf.push_back(5);
/// buf.push_back(99);
@@ -903,9 +911,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf = RingBuf::new();
+ /// let mut buf = VecDeque::new();
/// assert_eq!(buf.swap_front_remove(0), None);
/// buf.push_back(15);
/// buf.push_back(5);
@@ -936,9 +944,9 @@ impl<T> RingBuf<T> {
///
/// # Examples
/// ```rust
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf = RingBuf::new();
+ /// let mut buf = VecDeque::new();
/// buf.push_back(10);
/// buf.push_back(12);
/// buf.insert(1,11);
@@ -1138,9 +1146,9 @@ impl<T> RingBuf<T> {
///
/// # Examples
/// ```rust
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf = RingBuf::new();
+ /// let mut buf = VecDeque::new();
/// buf.push_back(5);
/// buf.push_back(10);
/// buf.push_back(12);
@@ -1309,9 +1317,9 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf: RingBuf<_> = vec![1,2,3].into_iter().collect();
+ /// 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);
@@ -1325,7 +1333,7 @@ impl<T> RingBuf<T> {
assert!(at <= len, "`at` out of bounds");
let other_len = len - at;
- let mut other = RingBuf::with_capacity(other_len);
+ let mut other = VecDeque::with_capacity(other_len);
unsafe {
let (first_half, second_half) = self.as_slices();
@@ -1336,7 +1344,7 @@ impl<T> RingBuf<T> {
// `at` lies in the first half.
let amount_in_first = first_len - at;
- ptr::copy_nonoverlapping_memory(other.ptr,
+ ptr::copy_nonoverlapping_memory(*other.ptr,
first_half.as_ptr().offset(at as isize),
amount_in_first);
@@ -1349,7 +1357,7 @@ impl<T> RingBuf<T> {
// in the first half.
let offset = at - first_len;
let amount_in_second = second_len - offset;
- ptr::copy_nonoverlapping_memory(other.ptr,
+ ptr::copy_nonoverlapping_memory(*other.ptr,
second_half.as_ptr().offset(offset as isize),
amount_in_second);
}
@@ -1371,10 +1379,10 @@ impl<T> RingBuf<T> {
/// # Examples
///
/// ```
- /// use std::collections::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf: RingBuf<_> = vec![1, 2, 3].into_iter().collect();
- /// let mut buf2: RingBuf<_> = vec![4, 5, 6].into_iter().collect();
+ /// 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);
@@ -1388,16 +1396,16 @@ impl<T> RingBuf<T> {
}
}
-impl<T: Clone> RingBuf<T> {
+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::RingBuf;
+ /// use std::collections::VecDeque;
///
- /// let mut buf = RingBuf::new();
+ /// let mut buf = VecDeque::new();
/// buf.push_back(5);
/// buf.push_back(10);
/// buf.push_back(15);
@@ -1434,7 +1442,7 @@ fn count(tail: usize, head: usize, size: usize) -> usize {
(head - tail) & (size - 1)
}
-/// `RingBuf` iterator.
+/// `VecDeque` iterator.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Iter<'a, T:'a> {
ring: &'a [T],
@@ -1511,14 +1519,14 @@ impl<'a, T> RandomAccessIterator for Iter<'a, T> {
// 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.
+/// `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::ContravariantLifetime<'a>,
+ marker: marker::PhantomData<&'a mut T>,
}
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1563,10 +1571,10 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}
-/// A by-value RingBuf iterator
+/// A by-value VecDeque iterator
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<T> {
- inner: RingBuf<T>,
+ inner: VecDeque<T>,
}
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1596,11 +1604,11 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IntoIter<T> {}
-/// A draining RingBuf iterator
+/// 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 RingBuf<T>,
+ inner: &'a mut VecDeque<T>,
}
#[unsafe_destructor]
@@ -1641,33 +1649,34 @@ impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
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 {
+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 RingBuf<A> {}
+impl<A: Eq> Eq for VecDeque<A> {}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<A: PartialOrd> PartialOrd for RingBuf<A> {
- fn partial_cmp(&self, other: &RingBuf<A>) -> Option<Ordering> {
+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 RingBuf<A> {
+impl<A: Ord> Ord for VecDeque<A> {
#[inline]
- fn cmp(&self, other: &RingBuf<A>) -> Ordering {
+ fn cmp(&self, other: &VecDeque<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> {
+#[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 {
@@ -1675,9 +1684,19 @@ impl<S: Writer + Hasher, A: Hash<S>> Hash<S> for RingBuf<A> {
}
}
}
+#[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 RingBuf<A> {
+impl<A> Index<usize> for VecDeque<A> {
type Output = A;
#[inline]
@@ -1687,7 +1706,7 @@ impl<A> Index<usize> for RingBuf<A> {
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<A> IndexMut<usize> for RingBuf<A> {
+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")
@@ -1695,17 +1714,18 @@ impl<A> IndexMut<usize> for RingBuf<A> {
}
#[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> {
+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 = RingBuf::with_capacity(lower);
+ let mut deq = VecDeque::with_capacity(lower);
deq.extend(iterator);
deq
}
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> IntoIterator for RingBuf<T> {
+impl<T> IntoIterator for VecDeque<T> {
type Item = T;
type IntoIter = IntoIter<T>;
@@ -1715,7 +1735,7 @@ impl<T> IntoIterator for RingBuf<T> {
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> IntoIterator for &'a RingBuf<T> {
+impl<'a, T> IntoIterator for &'a VecDeque<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
@@ -1725,7 +1745,7 @@ impl<'a, T> IntoIterator for &'a RingBuf<T> {
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T> IntoIterator for &'a mut RingBuf<T> {
+impl<'a, T> IntoIterator for &'a mut VecDeque<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
@@ -1735,18 +1755,18 @@ impl<'a, T> IntoIterator for &'a mut RingBuf<T> {
}
#[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 {
+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 RingBuf<T> {
+impl<T: fmt::Debug> fmt::Debug for VecDeque<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- try!(write!(f, "RingBuf ["));
+ try!(write!(f, "VecDeque ["));
for (i, e) in self.iter().enumerate() {
if i != 0 { try!(write!(f, ", ")); }
@@ -1768,12 +1788,12 @@ mod tests {
use test::Bencher;
use test;
- use super::RingBuf;
+ use super::VecDeque;
#[test]
#[allow(deprecated)]
fn test_simple() {
- let mut d = RingBuf::new();
+ let mut d = VecDeque::new();
assert_eq!(d.len(), 0);
d.push_front(17);
d.push_front(42);
@@ -1812,7 +1832,7 @@ mod tests {
#[cfg(test)]
fn test_parameterized<T:Clone + PartialEq + Debug>(a: T, b: T, c: T, d: T) {
- let mut deq = RingBuf::new();
+ let mut deq = VecDeque::new();
assert_eq!(deq.len(), 0);
deq.push_front(a.clone());
deq.push_front(b.clone());
@@ -1843,7 +1863,7 @@ mod tests {
#[test]
fn test_push_front_grow() {
- let mut deq = RingBuf::new();
+ let mut deq = VecDeque::new();
for i in 0..66 {
deq.push_front(i);
}
@@ -1853,7 +1873,7 @@ mod tests {
assert_eq!(deq[i], 65 - i);
}
- let mut deq = RingBuf::new();
+ let mut deq = VecDeque::new();
for i in 0..66 {
deq.push_back(i);
}
@@ -1865,7 +1885,7 @@ mod tests {
#[test]
fn test_index() {
- let mut deq = RingBuf::new();
+ let mut deq = VecDeque::new();
for i in 1..4 {
deq.push_front(i);
}
@@ -1875,7 +1895,7 @@ mod tests {
#[test]
#[should_fail]
fn test_index_out_of_bounds() {
- let mut deq = RingBuf::new();
+ let mut deq = VecDeque::new();
for i in 1..4 {
deq.push_front(i);
}
@@ -1885,14 +1905,14 @@ mod tests {
#[bench]
fn bench_new(b: &mut test::Bencher) {
b.iter(|| {
- let ring: RingBuf<i32> = RingBuf::new();
+ let ring: VecDeque<i32> = VecDeque::new();
test::black_box(ring);
})
}
#[bench]
fn bench_push_back_100(b: &mut test::Bencher) {
- let mut deq = RingBuf::with_capacity(101);
+ let mut deq = VecDeque::with_capacity(101);
b.iter(|| {
for i in 0..100 {
deq.push_back(i);
@@ -1904,7 +1924,7 @@ mod tests {
#[bench]
fn bench_push_front_100(b: &mut test::Bencher) {
- let mut deq = RingBuf::with_capacity(101);
+ let mut deq = VecDeque::with_capacity(101);
b.iter(|| {
for i in 0..100 {
deq.push_front(i);
@@ -1916,7 +1936,7 @@ mod tests {
#[bench]
fn bench_pop_back_100(b: &mut test::Bencher) {
- let mut deq= RingBuf::<i32>::with_capacity(101);
+ let mut deq= VecDeque::<i32>::with_capacity(101);
b.iter(|| {
deq.head = 100;
@@ -1929,7 +1949,7 @@ mod tests {
#[bench]
fn bench_pop_front_100(b: &mut test::Bencher) {
- let mut deq = RingBuf::<i32>::with_capacity(101);
+ let mut deq = VecDeque::<i32>::with_capacity(101);
b.iter(|| {
deq.head = 100;
@@ -1943,7 +1963,7 @@ mod tests {
#[bench]
fn bench_grow_1025(b: &mut test::Bencher) {
b.iter(|| {
- let mut deq = RingBuf::new();
+ let mut deq = VecDeque::new();
for i in 0..1025 {
deq.push_front(i);
}
@@ -1953,7 +1973,7 @@ mod tests {
#[bench]
fn bench_iter_1000(b: &mut test::Bencher) {
- let ring: RingBuf<_> = (0..1000).collect();
+ let ring: VecDeque<_> = (0..1000).collect();
b.iter(|| {
let mut sum = 0;
@@ -1966,7 +1986,7 @@ mod tests {
#[bench]
fn bench_mut_iter_1000(b: &mut test::Bencher) {
- let mut ring: RingBuf<_> = (0..1000).collect();
+ let mut ring: VecDeque<_> = (0..1000).collect();
b.iter(|| {
let mut sum = 0;
@@ -1986,9 +2006,9 @@ mod tests {
#[derive(Clone, PartialEq, Debug)]
enum Taggypar<T> {
- Onepar(i32),
- Twopar(i32, i32),
- Threepar(i32, i32, i32),
+ Onepar(T),
+ Twopar(T, T),
+ Threepar(T, T, T),
}
#[derive(Clone, PartialEq, Debug)]
@@ -2027,17 +2047,17 @@ mod tests {
#[test]
fn test_with_capacity() {
- let mut d = RingBuf::with_capacity(0);
+ let mut d = VecDeque::with_capacity(0);
d.push_back(1);
assert_eq!(d.len(), 1);
- let mut d = RingBuf::with_capacity(50);
+ 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 = RingBuf::with_capacity(3);
+ let mut d3 = VecDeque::with_capacity(3);
d3.push_back(1);
// X = None, | = lo
@@ -2062,7 +2082,7 @@ mod tests {
d3.push_back(15);
// There used to be a bug here about how the
- // RingBuf made growth assumptions about the
+ // VecDeque made growth assumptions about the
// underlying Vec which didn't hold and lead
// to corruption.
// (Vec grows to next power of two)
@@ -2078,7 +2098,7 @@ mod tests {
#[test]
fn test_reserve_exact() {
- let mut d = RingBuf::new();
+ let mut d = VecDeque::new();
d.push_back(0);
d.reserve_exact(50);
assert!(d.capacity() >= 51);
@@ -2086,7 +2106,7 @@ mod tests {
#[test]
fn test_reserve() {
- let mut d = RingBuf::new();
+ let mut d = VecDeque::new();
d.push_back(0);
d.reserve(50);
assert!(d.capacity() >= 51);
@@ -2094,7 +2114,7 @@ mod tests {
#[test]
fn test_swap() {
- let mut d: RingBuf<_> = (0..5).collect();
+ 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));
@@ -2102,7 +2122,7 @@ mod tests {
#[test]
fn test_iter() {
- let mut d = RingBuf::new();
+ let mut d = VecDeque::new();
assert_eq!(d.iter().next(), None);
assert_eq!(d.iter().size_hint(), (0, Some(0)));
@@ -2134,7 +2154,7 @@ mod tests {
#[test]
fn test_rev_iter() {
- let mut d = RingBuf::new();
+ let mut d = VecDeque::new();
assert_eq!(d.iter().rev().next(), None);
for i in 0..5 {
@@ -2154,7 +2174,7 @@ mod tests {
#[test]
fn test_mut_rev_iter_wrap() {
- let mut d = RingBuf::with_capacity(3);
+ let mut d = VecDeque::with_capacity(3);
assert!(d.iter_mut().rev().next().is_none());
d.push_back(1);
@@ -2169,7 +2189,7 @@ mod tests {
#[test]
fn test_mut_iter() {
- let mut d = RingBuf::new();
+ let mut d = VecDeque::new();
assert!(d.iter_mut().next().is_none());
for i in 0..3 {
@@ -2192,7 +2212,7 @@ mod tests {
#[test]
fn test_mut_rev_iter() {
- let mut d = RingBuf::new();
+ let mut d = VecDeque::new();
assert!(d.iter_mut().rev().next().is_none());
for i in 0..3 {
@@ -2218,7 +2238,7 @@ mod tests {
// Empty iter
{
- let d: RingBuf<i32> = RingBuf::new();
+ let d: VecDeque<i32> = VecDeque::new();
let mut iter = d.into_iter();
assert_eq!(iter.size_hint(), (0, Some(0)));
@@ -2228,7 +2248,7 @@ mod tests {
// simple iter
{
- let mut d = RingBuf::new();
+ let mut d = VecDeque::new();
for i in 0..5 {
d.push_back(i);
}
@@ -2239,7 +2259,7 @@ mod tests {
// wrapped iter
{
- let mut d = RingBuf::new();
+ let mut d = VecDeque::new();
for i in 0..5 {
d.push_back(i);
}
@@ -2253,7 +2273,7 @@ mod tests {
// partially used
{
- let mut d = RingBuf::new();
+ let mut d = VecDeque::new();
for i in 0..5 {
d.push_back(i);
}
@@ -2277,7 +2297,7 @@ mod tests {
// Empty iter
{
- let mut d: RingBuf<i32> = RingBuf::new();
+ let mut d: VecDeque<i32> = VecDeque::new();
{
let mut iter = d.drain();
@@ -2292,7 +2312,7 @@ mod tests {
// simple iter
{
- let mut d = RingBuf::new();
+ let mut d = VecDeque::new();
for i in 0..5 {
d.push_back(i);
}
@@ -2303,7 +2323,7 @@ mod tests {
// wrapped iter
{
- let mut d = RingBuf::new();
+ let mut d = VecDeque::new();
for i in 0..5 {
d.push_back(i);
}
@@ -2317,7 +2337,7 @@ mod tests {
// partially used
{
- let mut d: RingBuf<_> = RingBuf::new();
+ let mut d: VecDeque<_> = VecDeque::new();
for i in 0..5 {
d.push_back(i);
}
@@ -2343,12 +2363,12 @@ mod tests {
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 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: RingBuf<_> = seq.collect();
+ let deq: VecDeque<_> = seq.collect();
for (i, &x) in deq.iter().enumerate() {
assert_eq!(2*i, x);
}
@@ -2357,7 +2377,7 @@ mod tests {
#[test]
fn test_clone() {
- let mut d = RingBuf::new();
+ let mut d = VecDeque::new();
d.push_front(17);
d.push_front(42);
d.push_back(137);
@@ -2374,13 +2394,13 @@ mod tests {
#[test]
fn test_eq() {
- let mut d = RingBuf::new();
- assert!(d == RingBuf::with_capacity(0));
+ 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 = RingBuf::with_capacity(0);
+ let mut e = VecDeque::with_capacity(0);
e.push_back(42);
e.push_back(17);
e.push_back(137);
@@ -2390,13 +2410,13 @@ mod tests {
e.push_back(0);
assert!(e != d);
e.clear();
- assert!(e == RingBuf::new());
+ assert!(e == VecDeque::new());
}
#[test]
fn test_hash() {
- let mut x = RingBuf::new();
- let mut y = RingBuf::new();
+ let mut x = VecDeque::new();
+ let mut y = VecDeque::new();
x.push_back(1);
x.push_back(2);
@@ -2413,8 +2433,8 @@ mod tests {
#[test]
fn test_ord() {
- let x = RingBuf::new();
- let mut y = RingBuf::new();
+ let x = VecDeque::new();
+ let mut y = VecDeque::new();
y.push_back(1);
y.push_back(2);
y.push_back(3);
@@ -2426,13 +2446,13 @@ mod tests {
#[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: VecDeque<_> = (0..10).collect();
+ assert_eq!(format!("{:?}", ringbuf), "VecDeque [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
- let ringbuf: RingBuf<_> = vec!["just", "one", "test", "more"].iter()
+ let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"].iter()
.cloned()
.collect();
- assert_eq!(format!("{:?}", ringbuf), "RingBuf [\"just\", \"one\", \"test\", \"more\"]");
+ assert_eq!(format!("{:?}", ringbuf), "VecDeque [\"just\", \"one\", \"test\", \"more\"]");
}
#[test]
@@ -2445,7 +2465,7 @@ mod tests {
}
}
- let mut ring = RingBuf::new();
+ let mut ring = VecDeque::new();
ring.push_back(Elem);
ring.push_front(Elem);
ring.push_back(Elem);
@@ -2465,7 +2485,7 @@ mod tests {
}
}
- let mut ring = RingBuf::new();
+ let mut ring = VecDeque::new();
ring.push_back(Elem);
ring.push_front(Elem);
ring.push_back(Elem);
@@ -2489,7 +2509,7 @@ mod tests {
}
}
- let mut ring = RingBuf::new();
+ let mut ring = VecDeque::new();
ring.push_back(Elem);
ring.push_front(Elem);
ring.push_back(Elem);
@@ -2505,7 +2525,7 @@ mod tests {
fn test_reserve_grow() {
// test growth path A
// [T o o H] -> [T o o H . . . . ]
- let mut ring = RingBuf::with_capacity(4);
+ let mut ring = VecDeque::with_capacity(4);
for i in 0..3 {
ring.push_back(i);
}
@@ -2516,7 +2536,7 @@ mod tests {
// test growth path B
// [H T o o] -> [. T o o H . . . ]
- let mut ring = RingBuf::with_capacity(4);
+ let mut ring = VecDeque::with_capacity(4);
for i in 0..1 {
ring.push_back(i);
assert_eq!(ring.pop_front(), Some(i));
@@ -2531,7 +2551,7 @@ mod tests {
// test growth path C
// [o o H T] -> [o o H . . . . T ]
- let mut ring = RingBuf::with_capacity(4);
+ let mut ring = VecDeque::with_capacity(4);
for i in 0..3 {
ring.push_back(i);
assert_eq!(ring.pop_front(), Some(i));
@@ -2547,7 +2567,7 @@ mod tests {
#[test]
fn test_get() {
- let mut ring = RingBuf::new();
+ let mut ring = VecDeque::new();
ring.push_back(0);
assert_eq!(ring.get(0), Some(&0));
assert_eq!(ring.get(1), None);
@@ -2579,7 +2599,7 @@ mod tests {
#[test]
fn test_get_mut() {
- let mut ring = RingBuf::new();
+ let mut ring = VecDeque::new();
for i in 0..3 {
ring.push_back(i);
}
@@ -2605,7 +2625,7 @@ mod tests {
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 mut tester = VecDeque::with_capacity(15);
let usable_cap = tester.capacity();
let final_len = usable_cap / 2;
@@ -2649,7 +2669,7 @@ mod tests {
// 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);
+ 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
@@ -2683,7 +2703,7 @@ mod tests {
// 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);
+ 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
@@ -2720,7 +2740,7 @@ mod tests {
// 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);
+ 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
@@ -2749,7 +2769,7 @@ mod tests {
#[test]
fn test_front() {
- let mut ring = RingBuf::new();
+ let mut ring = VecDeque::new();
ring.push_back(10);
ring.push_back(20);
assert_eq!(ring.front(), Some(&10));
@@ -2761,7 +2781,7 @@ mod tests {
#[test]
fn test_as_slices() {
- let mut ring: RingBuf<i32> = RingBuf::with_capacity(127);
+ let mut ring: VecDeque<i32> = VecDeque::with_capacity(127);
let cap = ring.capacity() as i32;
let first = cap/2;
let last = cap - first;
@@ -2789,7 +2809,7 @@ mod tests {
#[test]
fn test_as_mut_slices() {
- let mut ring: RingBuf<i32> = RingBuf::with_capacity(127);
+ let mut ring: VecDeque<i32> = VecDeque::with_capacity(127);
let cap = ring.capacity() as i32;
let first = cap/2;
let last = cap - first;
@@ -2820,7 +2840,7 @@ mod tests {
// 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);
+ 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
@@ -2855,8 +2875,8 @@ mod tests {
#[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();
+ 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);
diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs
index 82ccfd0614f..54589a31423 100644
--- a/src/libcollections/vec_map.rs
+++ b/src/libcollections/vec_map.rs
@@ -20,7 +20,8 @@ use core::prelude::*;
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 @@ impl<V:Clone> Clone for VecMap<V> {
}
}
+#[cfg(stage0)]
impl<S: Writer + Hasher, V: Hash<S>> Hash<S> for VecMap<V> {
fn hash(&self, state: &mut S) {
// In order to not traverse the `VecMap` twice, count the elements
@@ -123,6 +126,20 @@ impl<S: Writer + Hasher, V: Hash<S>> Hash<S> for VecMap<V> {
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 @@ impl<V: fmt::Debug> fmt::Debug for VecMap<V> {
#[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 @@ impl<'a, T> IntoIterator for &'a mut VecMap<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)>>
diff --git a/src/libcore/array.rs b/src/libcore/array.rs
index 838ca4e478b..afb5d95c9f8 100644
--- a/src/libcore/array.rs
+++ b/src/libcore/array.rs
@@ -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 @@ macro_rules! array_impls {
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 @@ macro_rules! array_impls {
{
#[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 @@ macro_rules! array_impls {
{
#[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 @@ macro_rules! array_impls {
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 @@ macro_rules! array_impls {
impl<T:Ord> Ord for [T; $N] {
#[inline]
fn cmp(&self, other: &[T; $N]) -> Ordering {
- Ord::cmp(&&self[], &&other[])
+ Ord::cmp(&&self[..], &&other[..])
}
}
)+
diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs
index 05d864accc1..6afe5b2257d 100644
--- a/src/libcore/atomic.rs
+++ b/src/libcore/atomic.rs
@@ -76,6 +76,7 @@ use marker::Sync;
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
index 035443e9c3f..00000000000
--- a/src/libcore/borrow.rs
+++ /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),
- }
- }
-}
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 19ec245300d..b37bad5f754 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -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 @@ mod impls {
}
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 @@ mod impls {
)*)
}
- 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 @@ mod impls {
}
}
- 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 @@ mod impls {
}
}
- 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
diff --git a/src/libcore/default.rs b/src/libcore/default.rs
index d79b613f589..7f46d9cbe50 100644
--- a/src/libcore/default.rs
+++ b/src/libcore/default.rs
@@ -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 @@ default_impl! { (), () }
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 }
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 67c8c9fec09..a2c1bbc0331 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -16,7 +16,7 @@ use any;
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 @@ impl Debug for () {
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> {
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index a5d2618eff9..2e83334b937 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -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);
//! }
@@ -56,15 +56,12 @@
//! 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;
@@ -76,22 +73,123 @@ mod sip;
/// 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)
+ }
}
}
diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs
index d405d0d28be..ce8917cc205 100644
--- a/src/libcore/hash/sip.rs
+++ b/src/libcore/hash/sip.rs
@@ -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 @@ use super::{Hasher, Writer};
/// 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 @@ impl 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 @@ impl Writer for SipHasher {
}
}
+#[cfg(stage0)]
+impl Writer for SipHasher {
+ #[inline]
+ fn write(&mut self, msg: &[u8]) {
+ self.write(msg)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
impl Hasher for SipHasher {
+ #[cfg(stage0)]
type Output = u64;
+ #[cfg(stage0)]
fn reset(&mut self) {
- self.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 @@ impl Hasher for SipHasher {
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl Clone for SipHasher {
#[inline]
fn clone(&self) -> SipHasher {
@@ -216,6 +240,7 @@ impl Clone for SipHasher {
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl Default for SipHasher {
fn default() -> SipHasher {
SipHasher::new()
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 050c144b742..b2ee9596387 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -50,10 +50,10 @@ pub type GlueFn = extern "Rust" fn(*const i8);
#[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 @@ extern "rust-intrinsic" {
/// 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 @@ extern "rust-intrinsic" {
///
/// 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 @@ extern "rust-intrinsic" {
/// }
/// ```
#[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 @@ extern "rust-intrinsic" {
/// ```
///
#[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 @@ extern "rust-intrinsic" {
///
/// 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;
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index fffba1561a3..8fb10b5b2dc 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -62,6 +62,7 @@ use clone::Clone;
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 @@ impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I {
#[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 @@ impl<I: Iterator> IntoIterator for 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 @@ pub trait IteratorExt: Iterator + Sized {
///
/// ```
/// 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 @@ pub trait IteratorExt: Iterator + Sized {
///
/// 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 @@ pub trait IteratorExt: Iterator + Sized {
///
/// ```
/// 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 @@ pub trait IteratorExt: Iterator + Sized {
///
/// ```
/// 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 @@ pub trait IteratorExt: Iterator + Sized {
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 @@ pub trait IteratorExt: Iterator + Sized {
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;
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index f0c60ffe4bf..3c58480ff0c 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -126,7 +126,6 @@ pub mod default;
pub mod any;
pub mod atomic;
-pub mod borrow;
pub mod cell;
pub mod char;
pub mod panicking;
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 56e1c5dedc1..d284eb34179 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -26,6 +26,10 @@
#![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>;
diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs
index 5644f763069..230587b726f 100644
--- a/src/libcore/nonzero.rs
+++ b/src/libcore/nonzero.rs
@@ -10,15 +10,14 @@
//! 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 {}
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 9a89682127f..abfef72a5db 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -149,7 +149,7 @@ use clone::Clone;
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 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
}
}
- 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 {
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 072c60c7036..16b84dcf18e 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -91,8 +91,10 @@
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 @@ impl<T> PartialOrd for *mut T {
/// 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) }
+ }
}
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 1a874ee178b..23e936a75d7 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -230,7 +230,8 @@ use self::Result::{Ok, Err};
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 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
}
}
- 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 {
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index bbfe7e58ef4..a86da53b372 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -140,11 +140,11 @@ impl<T> SliceExt for [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 @@ impl<T> SliceExt for [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 @@ impl<'a, T> RandomAccessIterator for Iter<'a, T> {
pub struct IterMut<'a, T: 'a> {
ptr: *mut T,
end: *mut T,
- marker: marker::ContravariantLifetime<'a>,
+ _marker: marker::PhantomData<&'a mut T>,
}
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index ce26abe606d..eec997b9f10 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1280,7 +1280,7 @@ mod traits {
/// 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.
diff --git a/src/libcoretest/hash/mod.rs b/src/libcoretest/hash/mod.rs
index fd0d3c676a4..9b6af182f72 100644
--- a/src/libcoretest/hash/mod.rs
+++ b/src/libcoretest/hash/mod.rs
@@ -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 @@ impl Default for 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 @@ impl Default for 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)
}
diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs
index 7eb0fb97bed..39a590c7307 100644
--- a/src/libcoretest/iter.rs
+++ b/src/libcoretest/iter.rs
@@ -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));
diff --git a/src/libcoretest/mem.rs b/src/libcoretest/mem.rs
index 421ce76caaf..5aeb330b78b 100644
--- a/src/libcoretest/mem.rs
+++ b/src/libcoretest/mem.rs
@@ -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>;
diff --git a/src/libcoretest/ptr.rs b/src/libcoretest/ptr.rs
index 9c2e242c105..57456bfb1a7 100644
--- a/src/libcoretest/ptr.rs
+++ b/src/libcoretest/ptr.rs
@@ -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);
}
diff --git a/src/libcoretest/slice.rs b/src/libcoretest/slice.rs
index 6d5cc38ef0a..46c7730cc64 100644
--- a/src/libcoretest/slice.rs
+++ b/src/libcoretest/slice.rs
@@ -43,13 +43,13 @@ fn iterator_to_slice() {
{
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 @@ fn iterator_to_slice() {
}
{
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();
diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs
index ff6400a11df..24660b3f396 100644
--- a/src/libflate/lib.rs
+++ b/src/libflate/lib.rs
@@ -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
diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs
index 1c7e97d784c..be77622ac1d 100644
--- a/src/libfmt_macros/lib.rs
+++ b/src/libfmt_macros/lib.rs
@@ -215,11 +215,11 @@ impl<'a> Parser<'a> {
}
Some((_, other)) => {
self.err(&format!("expected `{:?}`, found `{:?}`", c,
- other)[]);
+ other));
}
None => {
self.err(&format!("expected `{:?}` but string was terminated",
- c)[]);
+ c));
}
}
}
diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs
index c743119f409..fdd7f7395c2 100644
--- a/src/libgetopts/lib.rs
+++ b/src/libgetopts/lib.rs
@@ -287,7 +287,7 @@ impl OptGroup {
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 @@ impl Matches {
/// 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
}
diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs
index 230deabee00..acd52c752e8 100644
--- a/src/libgraphviz/lib.rs
+++ b/src/libgraphviz/lib.rs
@@ -275,15 +275,12 @@
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 @@ impl<'a> Id<'a> {
&*self.name
}
- pub fn name(self) -> CowString<'a> {
+ pub fn name(self) -> Cow<'a, str> {
self.name
}
}
@@ -427,11 +424,11 @@ pub trait Labeller<'a,N,E> {
}
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 @@ impl<'a> LabelText<'a> {
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 @@ impl<'a> LabelText<'a> {
/// 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 @@ impl<'a> LabelText<'a> {
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 @@ mod tests {
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)
diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs
index 4dab07acfd2..c2c7f20ce9c 100644
--- a/src/liblog/lib.rs
+++ b/src/liblog/lib.rs
@@ -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),
};
diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs
index d1d24cea871..5a85552dc38 100644
--- a/src/librand/distributions/mod.rs
+++ b/src/librand/distributions/mod.rs
@@ -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 @@ mod tests {
#[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));
diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs
index f15523fc010..701749ff344 100644
--- a/src/librand/isaac.rs
+++ b/src/librand/isaac.rs
@@ -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;
diff --git a/src/librand/lib.rs b/src/librand/lib.rs
index 915c70bbf8c..7588bf7c515 100644
--- a/src/librand/lib.rs
+++ b/src/librand/lib.rs
@@ -41,6 +41,7 @@ extern crate core;
#[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 @@ pub trait Rng : Sized {
/// .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 @@ pub trait Rng : Sized {
/// 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> {
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index eb51046d7c9..dc81e89902b 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -37,7 +37,7 @@ use util::ppaux::{ty_to_string};
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 @@ impl BoxPointers {
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 @@ impl LintPass for UnusedResults {
}
} 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 @@ impl NonCamelCaseTypes {
} 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 @@ impl NonSnakeCase {
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 @@ impl NonUpperCaseGlobals {
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 @@ impl LintPass for UnusedImportBraces {
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 @@ impl LintPass for MissingDoc {
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 @@ impl Stability {
_ => format!("use of {} item", label)
};
- cx.span_lint(lint, span, &msg[]);
+ cx.span_lint(lint, span, &msg[..]);
}
}
}
@@ -1791,7 +1791,7 @@ impl LintPass for UnconditionalRecursion {
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();
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 42a6861f452..068c179d343 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -125,11 +125,11 @@ impl LintStore {
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 @@ impl LintStore {
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 @@ impl LintStore {
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 @@ impl LintStore {
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 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
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 @@ impl<'a, 'tcx> IdVisitingOperation for Context<'a, 'tcx> {
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[..])
}
}
}
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 5dc23d27ee1..bdcc10ebcec 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -185,12 +185,20 @@ impl PartialEq for LintId {
impl Eq for LintId { }
+#[cfg(stage0)]
impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for LintId {
fn hash(&self, state: &mut S) {
let ptr = self.lint as *const Lint;
ptr.hash(state);
}
}
+#[cfg(not(stage0))]
+impl hash::Hash for LintId {
+ fn hash<H: hash::Hasher>(&self, state: &mut H) {
+ let ptr = self.lint as *const Lint;
+ ptr.hash(state);
+ }
+}
impl LintId {
/// Get the `LintId` for a `Lint`.
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index 0871c36d892..d48a404176a 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc/metadata/creader.rs
@@ -183,7 +183,7 @@ impl<'a> CrateReader<'a> {
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 @@ impl<'a> CrateReader<'a> {
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 @@ impl<'a> CrateReader<'a> {
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 @@ impl<'a> CrateReader<'a> {
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 @@ impl<'a> CrateReader<'a> {
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
diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs
index 0a3e173b35e..a3f7d57da67 100644
--- a/src/librustc/metadata/cstore.rs
+++ b/src/librustc/metadata/cstore.rs
@@ -139,8 +139,7 @@ impl CStore {
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 @@ impl CStore {
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()
}
}
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 3123fa31abd..42a70cec5df 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -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 encode_info_for_item(ecx: &EncodeContext,
class itself */
let idx = encode_info_for_struct(ecx,
rbml_w,
- &fields[],
+ &fields[..],
index);
/* Index the class*/
@@ -1181,7 +1181,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
/* 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;
diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs
index 3158ccd0765..01d1f4e7011 100644
--- a/src/librustc/metadata/loader.rs
+++ b/src/librustc/metadata/loader.rs
@@ -322,7 +322,7 @@ impl<'a> Context<'a> {
&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 @@ impl<'a> Context<'a> {
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 @@ impl<'a> Context<'a> {
(&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 @@ impl<'a> Context<'a> {
let mut rlibs = HashMap::new();
let mut dylibs = HashMap::new();
{
- let locs = locs.iter().map(|l| Path::new(&l[])).filter(|loc| {
+ let locs = locs.iter().map(|l| 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 @@ impl<'a> Context<'a> {
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: '{}'",
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 94654b84922..5805725a8fc 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -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)
})
}
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index c3302debdfa..ae10eb686b0 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -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();
diff --git a/src/librustc/middle/cfg/graphviz.rs b/src/librustc/middle/cfg/graphviz.rs
index 1f0fe4f1aca..46b4a51c9d6 100644
--- a/src/librustc/middle/cfg/graphviz.rs
+++ b/src/librustc/middle/cfg/graphviz.rs
@@ -92,7 +92,7 @@ impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> {
let s = replace_newline_with_backslash_l(s);
label.push_str(&format!("exiting scope_{} {}",
i,
- &s[])[]);
+ &s[..])[]);
}
dot::LabelText::EscStr(label.into_cow())
}
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 03456f85290..86c59b24e3e 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -25,7 +25,7 @@ use middle::ty::*;
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 @@ impl<'a> fmt::Debug for Matrix<'a> {
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 @@ impl<'a> fmt::Debug for Matrix<'a> {
}
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
}
}
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index 3d03cd946c4..5bf7422dbc0 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -62,7 +62,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
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 lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
// 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;
}
};
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index b792a44d4d8..085d5cbc347 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -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 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
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 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
let mut changed = false;
for &node_id in &edge.data.exiting_scopes {
- let opt_cfg_idx = self.nodeid_to_index.get(&node_id).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 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
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));
}
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index b2335f91ad9..ff78deb8d12 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -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,
_ => (),
}
}
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs
index 6d35a82d153..ad9f4eade5c 100644
--- a/src/librustc/middle/dependency_format.rs
+++ b/src/librustc/middle/dependency_format.rs
@@ -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,
}
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 8dbac7f515e..e99d214742a 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -29,7 +29,6 @@ use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam};
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 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
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 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
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 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
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[..])
}
}
}
diff --git a/src/librustc/middle/graph.rs b/src/librustc/middle/graph.rs
index 4dd7a4a2266..436f04fc9e9 100644
--- a/src/librustc/middle/graph.rs
+++ b/src/librustc/middle/graph.rs
@@ -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 @@ impl<N,E> Graph<N,E> {
DepthFirstTraversal {
graph: self,
stack: vec![start],
- visited: BitvSet::new()
+ visited: BitSet::new()
}
}
}
@@ -300,7 +300,7 @@ impl<N,E> Graph<N,E> {
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
index 00000000000..93c80fb754f
--- /dev/null
+++ b/src/librustc/middle/infer/bivariate.rs
@@ -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))
+ }
+}
diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs
index daa820f43b5..0eeafb767d8 100644
--- a/src/librustc/middle/infer/combine.rs
+++ b/src/librustc/middle/infer/combine.rs
@@ -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::sub::Sub;
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::{IntType, UintType};
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;
@@ -58,41 +59,32 @@ use syntax::abi;
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 @@ pub trait Combine<'tcx> : Sized {
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 @@ pub trait Combine<'tcx> : Sized {
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 @@ pub trait Combine<'tcx> : Sized {
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 @@ pub trait Combine<'tcx> : Sized {
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 @@ pub trait Combine<'tcx> : Sized {
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 @@ pub trait Combine<'tcx> : Sized {
}
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 @@ pub trait Combine<'tcx> : Sized {
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 @@ pub trait Combine<'tcx> : Sized {
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 @@ impl<'f, 'tcx> CombineFields<'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 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> {
EqTo => {
self.generalize(a_ty, b_vid, false)
}
- SupertypeOf | SubtypeOf => {
+ BiTo | SupertypeOf | SubtypeOf => {
self.generalize(a_ty, b_vid, true)
}
});
@@ -721,6 +723,10 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> {
// 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 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> {
}
SupertypeOf => {
- try!(self.sub().contratys(a_ty, b_ty));
+ try!(self.sub().tys_with_variance(ty::Contravariant, a_ty, b_ty));
}
}
}
diff --git a/src/librustc/middle/infer/equate.rs b/src/librustc/middle/infer/equate.rs
index f0bde222864..7194e20b0cf 100644
--- a/src/librustc/middle/infer/equate.rs
+++ b/src/librustc/middle/infer/equate.rs
@@ -13,11 +13,7 @@ use middle::ty::{self, Ty};
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)
}
diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs
index 72b33613c66..53032f9b9ac 100644
--- a/src/librustc/middle/infer/error_reporting.rs
+++ b/src/librustc/middle/infer/error_reporting.rs
@@ -200,9 +200,9 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
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 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
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 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Rebuilder<'a, '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 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
}
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 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
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 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, '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 @@ impl LifeGiver {
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;
}
diff --git a/src/librustc/middle/infer/glb.rs b/src/librustc/middle/infer/glb.rs
index ff0c2d92f45..33303808e84 100644
--- a/src/librustc/middle/infer/glb.rs
+++ b/src/librustc/middle/infer/glb.rs
@@ -10,12 +10,9 @@
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 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, '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 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
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)
}
diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs
index 4469e27a5b0..a729156c88b 100644
--- a/src/librustc/middle/infer/higher_ranked/mod.rs
+++ b/src/librustc/middle/infer/higher_ranked/mod.rs
@@ -31,7 +31,7 @@ pub trait HigherRankedRelations<'tcx> {
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)
}
diff --git a/src/librustc/middle/infer/lub.rs b/src/librustc/middle/infer/lub.rs
index 204560e87ee..3570effa9fa 100644
--- a/src/librustc/middle/infer/lub.rs
+++ b/src/librustc/middle/infer/lub.rs
@@ -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 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, '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 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
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(),
diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs
index 00e377d65fe..b0576ff55ff 100644
--- a/src/librustc/middle/infer/mod.rs
+++ b/src/librustc/middle/infer/mod.rs
@@ -45,6 +45,7 @@ use self::lub::Lub;
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 @@ impl<'tcx> SubregionOrigin<'tcx> {
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 @@ impl<'tcx> Repr<'tcx> for SubregionOrigin<'tcx> {
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)),
diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs
index 5cdfdcc7c9b..b4fd34f206f 100644
--- a/src/librustc/middle/infer/region_inference/mod.rs
+++ b/src/librustc/middle/infer/region_inference/mod.rs
@@ -977,7 +977,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
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
diff --git a/src/librustc/middle/infer/sub.rs b/src/librustc/middle/infer/sub.rs
index 1e0d14544ff..33da3092b2a 100644
--- a/src/librustc/middle/infer/sub.rs
+++ b/src/librustc/middle/infer/sub.rs
@@ -10,12 +10,8 @@
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({}, {})",
diff --git a/src/librustc/middle/infer/type_variable.rs b/src/librustc/middle/infer/type_variable.rs
index 9b8a4a84412..a856137af09 100644
--- a/src/librustc/middle/infer/type_variable.rs
+++ b/src/librustc/middle/infer/type_variable.rs
@@ -14,6 +14,7 @@ use self::UndoEntry::*;
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 @@ impl 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> {
diff --git a/src/librustc/middle/infer/unify.rs b/src/librustc/middle/infer/unify.rs
index 235f3f994c6..0675cec6f69 100644
--- a/src/librustc/middle/infer/unify.rs
+++ b/src/librustc/middle/infer/unify.rs
@@ -18,6 +18,7 @@ use middle::infer::{uok, ures};
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 Delegate<K>;
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() }
}
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index e13a5672778..56c5928a132 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -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 @@ lets_do_this! {
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;
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index d4fe0979313..e58136fb3f4 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -1119,7 +1119,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
// 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 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
} 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 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
} 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) => {
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 2f0462ab8c3..e539f6ae6cb 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -407,7 +407,7 @@ impl RegionMaps {
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
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index e91d7d8c52c..3ba08c10320 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -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()
}
diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs
index 9bf35bd4284..04fd03ab342 100644
--- a/src/librustc/middle/subst.rs
+++ b/src/librustc/middle/subst.rs
@@ -113,7 +113,7 @@ impl<'tcx> Substs<'tcx> {
}
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> {
diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs
index 3a7522cafee..e199a60c370 100644
--- a/src/librustc/middle/traits/coherence.rs
+++ b/src/librustc/middle/traits/coherence.rs
@@ -10,24 +10,27 @@
//! 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> {
diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs
index 57c9fa7a4d9..a63dcfc24a1 100644
--- a/src/librustc/middle/traits/mod.rs
+++ b/src/librustc/middle/traits/mod.rs
@@ -28,6 +28,7 @@ use util::ppaux::{Repr, UserString};
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>,
diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs
index b2701ae875c..f10f7eb3951 100644
--- a/src/librustc/middle/traits/object_safety.rs
+++ b/src/librustc/middle/traits/object_safety.rs
@@ -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 @@ impl<'tcx> Repr<'tcx> for ObjectSafetyViolation<'tcx> {
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,
+ }
+}
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index 027415de998..0e298920841 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
{
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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
stack: &TraitObligationStack<'o, 'tcx>)
-> Result<SelectionCandidateSet<'tcx>, SelectionError<'tcx>>
{
- // Check for overflow.
-
let TraitObligationStack { obligation, .. } = *stack;
let mut candidates = SelectionCandidateSet {
@@ -802,6 +801,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
try!(self.confirm_builtin_candidate(obligation, builtin_bound))))
}
+ PhantomFnCandidate |
ErrorCandidate => {
Ok(VtableBuiltin(VtableBuiltinData { nested: VecPerParamSpace::empty() }))
}
@@ -2295,6 +2303,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
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)),
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index e3eda02b0a8..e9908397f97 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -68,15 +68,16 @@ use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
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 @@ impl<'tcx> PartialEq for TyS<'tcx> {
}
impl<'tcx> Eq for TyS<'tcx> {}
+#[cfg(stage0)]
impl<'tcx, S: Writer + Hasher> Hash<S> for TyS<'tcx> {
fn hash(&self, s: &mut S) {
(self as *const _).hash(s)
}
}
+#[cfg(not(stage0))]
+impl<'tcx> Hash for TyS<'tcx> {
+ fn hash<H: Hasher>(&self, s: &mut H) {
+ (self as *const _).hash(s)
+ }
+}
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
@@ -980,15 +988,22 @@ impl<'tcx> PartialEq for InternedTy<'tcx> {
impl<'tcx> Eq for InternedTy<'tcx> {}
+#[cfg(stage0)]
impl<'tcx, S: Writer + Hasher> Hash<S> for InternedTy<'tcx> {
fn hash(&self, s: &mut S) {
self.ty.sty.hash(s)
}
}
+#[cfg(not(stage0))]
+impl<'tcx> Hash for InternedTy<'tcx> {
+ fn hash<H: Hasher>(&self, s: &mut H) {
+ self.ty.sty.hash(s)
+ }
+}
-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 @@ impl<'tcx> AsPredicate<'tcx> for PolyProjectionPredicate<'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 @@ impl ClosureKind {
};
match result {
Ok(trait_did) => trait_did,
- Err(err) => cx.sess.fatal(&err[]),
+ Err(err) => cx.sess.fatal(&err[..]),
}
}
}
@@ -2665,7 +2714,7 @@ impl FlagComputation {
}
&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 @@ impl<'tcx> TyS<'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 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
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 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
}
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 @@ pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>)
-> 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 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
}
/// 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[..])
}
}
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index ee3fd681a00..60a9ffc7d2e 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -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
diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs
index 1895cbcb542..b3bc898748f 100644
--- a/src/librustc/plugin/load.rs
+++ b/src/librustc/plugin/load.rs
@@ -111,19 +111,19 @@ impl<'a> PluginLoader<'a> {
// 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[..])
}
};
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 5768539b2cd..93a25de0491 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -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 @@ mod 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
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index bd44dbe78f5..c1c55188875 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -75,13 +75,13 @@ impl Session {
}
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)
}
}
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index d3d0f56c3ce..c9d50b9cecf 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -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,6 +250,7 @@ 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,
@@ -214,6 +259,50 @@ pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) ->
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());
match result {
Some(result) => result,
diff --git a/src/librustc/util/lev_distance.rs b/src/librustc/util/lev_distance.rs
index ca1bb7d7a94..10a7b2abea8 100644
--- a/src/librustc/util/lev_distance.rs
+++ b/src/librustc/util/lev_distance.rs
@@ -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";
diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs
index f8e3defe19d..1b07ce789e7 100644
--- a/src/librustc/util/nodemap.rs
+++ b/src/librustc/util/nodemap.rs
@@ -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>>;
@@ -27,12 +28,22 @@ pub type DefIdMap<T> = FnvHashMap<ast::DefId, T>;
pub type NodeSet = FnvHashSet<ast::NodeId>;
pub type DefIdSet = FnvHashSet<ast::DefId>;
+#[cfg(stage0)]
pub fn FnvHashMap<K: Hash<FnvHasher> + Eq, V>() -> FnvHashMap<K, V> {
Default::default()
}
+#[cfg(stage0)]
pub fn FnvHashSet<V: Hash<FnvHasher> + Eq>() -> FnvHashSet<V> {
Default::default()
}
+#[cfg(not(stage0))]
+pub fn FnvHashMap<K: Hash + Eq, V>() -> FnvHashMap<K, V> {
+ Default::default()
+}
+#[cfg(not(stage0))]
+pub fn FnvHashSet<V: Hash + Eq>() -> FnvHashSet<V> {
+ Default::default()
+}
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 @@ impl Writer for FnvHasher {
*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 }
+}
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index d54199a679a..1d46c011bb3 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -28,7 +28,8 @@ use middle::ty_fold::TypeFoldable;
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 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
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 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> 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 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for [T] {
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 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for OwnedSlice<T> {
// 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 @@ impl<'tcx> UserString<'tcx> for TraitAndProjections<'tcx> {
&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 @@ impl<'tcx, T> UserString<'tcx> for ty::Binder<T>
}
})
});
- 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 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for ty::Binder<T> {
}
}
+#[cfg(stage0)]
impl<'tcx, S, K, V> Repr<'tcx> for HashMap<K, V, S>
where K: Hash<<S as HashState>::Hasher> + Eq + Repr<'tcx>,
V: Repr<'tcx>,
@@ -1435,6 +1450,21 @@ impl<'tcx, S, K, V> Repr<'tcx> for HashMap<K, V, S>
}
}
+#[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>,
diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs
index b779963a219..c45ee258342 100644
--- a/src/librustc_back/archive.rs
+++ b/src/librustc_back/archive.rs
@@ -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 @@ impl<'a> ArchiveBuilder<'a> {
// 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 @@ impl<'a> ArchiveBuilder<'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 @@ impl<'a> ArchiveBuilder<'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 @@ impl<'a> ArchiveBuilder<'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 @@ impl<'a> ArchiveBuilder<'a> {
} 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));
}
diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs
index 36bbd4b9872..e7419d4bec3 100644
--- a/src/librustc_back/rpath.rs
+++ b/src/librustc_back/rpath.rs
@@ -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 get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<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());
}
}
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index 692e6b474fd..01a5f0d6e20 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -254,18 +254,18 @@ impl 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()
)
diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs
index a18e8b16e8b..abe01d193b4 100644
--- a/src/librustc_borrowck/borrowck/check_loans.rs
+++ b/src/librustc_borrowck/borrowck/check_loans.rs
@@ -656,7 +656,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
&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",
diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs
index bee1ada28e3..c873831cb0f 100644
--- a/src/librustc_borrowck/borrowck/fragments.rs
+++ b/src/librustc_borrowck/borrowck/fragments.rs
@@ -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[..])
}
}
}
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 93d97a054a4..518e4bc472c 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -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);
diff --git a/src/librustc_borrowck/graphviz.rs b/src/librustc_borrowck/graphviz.rs
index 56bf3ae7fd5..39c9d9ba6ad 100644
--- a/src/librustc_borrowck/graphviz.rs
+++ b/src/librustc_borrowck/graphviz.rs
@@ -89,7 +89,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
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
});
diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs
index c2677cc3fd0..b7cfda28092 100644
--- a/src/librustc_borrowck/lib.rs
+++ b/src/librustc_borrowck/lib.rs
@@ -20,7 +20,6 @@
#![allow(non_camel_case_types)]
#![feature(core)]
-#![feature(hash)]
#![feature(int_uint)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 728ff647599..a260997f605 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -85,7 +85,7 @@ pub fn compile_input(sess: Session,
let expanded_crate
= match phase_2_configure_and_expand(&sess,
krate,
- &id[],
+ &id[..],
addl_plugins) {
None => return,
Some(k) => k
@@ -99,20 +99,20 @@ pub fn compile_input(sess: Session,
&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,
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index ac91a0098ea..2550432c810 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -272,7 +272,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
-> 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 @@ Available lint options:
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 @@ Available lint options:
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() {
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 5dfef6c775e..0fbfa5fd89d 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -383,7 +383,7 @@ impl UserIdentifiedItem {
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 @@ impl UserIdentifiedItem {
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[..])
}
}
}
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index 7105a6cc488..fbbd72e2c76 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -254,7 +254,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Env<'a, '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,
diff --git a/src/librustc_llvm/archive_ro.rs b/src/librustc_llvm/archive_ro.rs
index d3555e4c043..14a99026aac 100644
--- a/src/librustc_llvm/archive_ro.rs
+++ b/src/librustc_llvm/archive_ro.rs
@@ -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 @@ impl 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() {
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index aa90d7c851b..09a187befb2 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -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 @@ impl Drop for TargetData {
}
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()) }
}
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 96e146fc894..5662a74a53d 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -585,10 +585,10 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
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 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
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.
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 874c8f2a940..333d32d76b6 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
.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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
-> 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
generics,
implemented_traits,
&**self_type,
- &impl_items[]);
+ &impl_items[..]);
}
ItemTrait(_, ref generics, ref bounds, ref trait_items) => {
@@ -3196,7 +3192,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
};
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
Some((span, msg)) => (span, msg),
None => {
let msg = format!("Use of undeclared module `::{}`",
- self.names_to_string(&module_path[]));
+ self.names_to_string(&module_path[..]));
(path.span, msg)
}
};
@@ -4309,7 +4305,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
} else {
match this.resolve_module_path(root,
- &name_path[],
+ &name_path[..],
UseLexicalScope,
span,
PathSearch) {
@@ -4347,7 +4343,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
// Look for a method in the current self type's impl module.
- match get_module(self, path.span, &name_path[]) {
+ 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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[..]);
}
}
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index 9f26e9182ab..ef849bb3dca 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -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_upstream_rust_crates(cmd: &mut Command, sess: &Session,
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");
diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs
index 0331b6171f3..0a0f2a9c186 100644
--- a/src/librustc_trans/back/lto.rs
+++ b/src/librustc_trans/back/lto.rs
@@ -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();
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 9934d9993d6..86b720d3fc1 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -22,7 +22,7 @@ use syntax::codemap;
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 @@ impl SharedEmitter {
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 @@ unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef,
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 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo
}
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 optimize_and_codegen(cgcx: &CodegenContext,
if config.emit_bc {
let ext = format!("{}.bc", name_extra);
let out = output_names.with_extension(&ext);
- let out = CString::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 optimize_and_codegen(cgcx: &CodegenContext,
if config.emit_ir {
let ext = format!("{}.ll", name_extra);
let out = output_names.with_extension(&ext);
- let out = CString::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);
};
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 4606200d058..3deca436a1f 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -28,7 +28,6 @@
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
-#![feature(hash)]
#![feature(int_uint)]
#![feature(old_io)]
#![feature(env)]
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index cdcd917ee5e..8d2a2d51ee4 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -155,7 +155,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
};
self.fmt.sub_mod_ref_str(path.span,
*span,
- &qualname[],
+ &qualname[..],
self.cur_scope);
}
}
@@ -178,7 +178,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
};
self.fmt.sub_mod_ref_str(path.span,
*span,
- &qualname[],
+ &qualname[..],
self.cur_scope);
}
}
@@ -197,7 +197,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
id,
qualname,
&path_to_string(p)[],
- &typ[]);
+ &typ[..]);
}
self.collected_paths.clear();
}
@@ -356,7 +356,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
};
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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
self.fmt.typedef_str(full_span,
Some(*param_ss),
param.id,
- &name[],
+ &name[..],
"");
}
self.visit_generics(generics);
@@ -487,10 +487,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
// 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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
sub_span,
item.id,
&get_ident(item.ident),
- &qualname[],
- &value[],
+ &qualname[..],
+ &value[..],
&ty_to_string(&*typ)[],
self.cur_scope);
@@ -549,7 +549,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
sub_span,
item.id,
&get_ident(item.ident),
- &qualname[],
+ &qualname[..],
"",
&ty_to_string(&*typ)[],
self.cur_scope);
@@ -575,17 +575,17 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
}
}
- 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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
}
// 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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
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 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
item.id,
cnum,
name,
- &location[],
+ &location[..],
self.cur_scope);
}
ast::ItemFn(ref decl, _, _, ref ty_params, ref body) =>
@@ -1196,8 +1196,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
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 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
};
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 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
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 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
Some(p.span),
id,
&path_to_string(p)[],
- &value[],
+ &value[..],
"")
}
def::DefVariant(..) | def::DefTy(..) | def::DefStruct(..) => {
@@ -1520,8 +1520,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
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);
}
diff --git a/src/librustc_trans/save/recorder.rs b/src/librustc_trans/save/recorder.rs
index 3bd04ed29d4..08e36bb1d85 100644
--- a/src/librustc_trans/save/recorder.rs
+++ b/src/librustc_trans/save/recorder.rs
@@ -43,7 +43,7 @@ impl Recorder {
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 @@ impl<'a> FmtStrs<'a> {
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 @@ impl<'a> FmtStrs<'a> {
};
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 @@ impl<'a> FmtStrs<'a> {
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,
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs
index b0ed6f9e727..2826afb71a2 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -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;
}
diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs
index ddd720f1e84..eaf6eaa2f08 100644
--- a/src/librustc_trans/trans/adt.rs
+++ b/src/librustc_trans/trans/adt.rs
@@ -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)
}
}
diff --git a/src/librustc_trans/trans/asm.rs b/src/librustc_trans/trans/asm.rs
index e419be65fc4..a3bd0cf6b1a 100644
--- a/src/librustc_trans/trans/asm.rs
+++ b/src/librustc_trans/trans/asm.rs
@@ -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(),
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 7f7b5cd8006..3091c852f55 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -86,7 +86,7 @@ use util::nodemap::NodeMap;
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 @@ impl<'a, 'tcx> Drop for StatRecorder<'a, 'tcx> {
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 @@ pub fn create_entry_wrapper(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 {
diff --git a/src/librustc_trans/trans/builder.rs b/src/librustc_trans/trans/builder.rs
index e268c2f0d5c..8199e6189c9 100644
--- a/src/librustc_trans/trans/builder.rs
+++ b/src/librustc_trans/trans/builder.rs
@@ -431,7 +431,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} 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 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}).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);
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index bda8b8938b7..3d3e35cd776 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -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);
}
diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs
index 1c831090e3e..85e53618f6d 100644
--- a/src/librustc_trans/trans/cleanup.rs
+++ b/src/librustc_trans/trans/cleanup.rs
@@ -764,7 +764,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
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 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
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);
}
}
diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs
index f92df999e60..1d4bbd79d71 100644
--- a/src/librustc_trans/trans/closure.rs
+++ b/src/librustc_trans/trans/closure.rs
@@ -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
diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs
index ac9a982f298..a9cda94beba 100644
--- a/src/librustc_trans/trans/common.rs
+++ b/src/librustc_trans/trans/common.rs
@@ -488,7 +488,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
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[..]),
}
}
}
diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs
index 86f5589556a..7705b53ee38 100644
--- a/src/librustc_trans/trans/consts.rs
+++ b/src/librustc_trans/trans/consts.rs
@@ -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")
}
diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs
index 96506291b5a..eb07bdb7ba1 100644
--- a/src/librustc_trans/trans/context.rs
+++ b/src/librustc_trans/trans/context.rs
@@ -225,15 +225,15 @@ impl<'a, 'tcx> Iterator for CrateContextMaybeIterator<'a, 'tcx> {
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 @@ impl<'tcx> SharedCrateContext<'tcx> {
// 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);
}
diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs
index e6cd44676ce..26e12a1af40 100644
--- a/src/librustc_trans/trans/controlflow.rs
+++ b/src/librustc_trans/trans/controlflow.rs
@@ -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);
diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs
index 23498089c58..fc0129239aa 100644
--- a/src/librustc_trans/trans/debuginfo.rs
+++ b/src/librustc_trans/trans/debuginfo.rs
@@ -299,7 +299,7 @@ impl<'tcx> TypeMap<'tcx> {
if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
let unique_type_id_str = self.get_unique_type_id_as_string(unique_type_id);
cx.sess().bug(&format!("Type metadata for unique id '{}' is already in the TypeMap!",
- &unique_type_id_str[])[]);
+ &unique_type_id_str[..])[]);
}
}
@@ -380,14 +380,14 @@ impl<'tcx> TypeMap<'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 @@ impl<'tcx> TypeMap<'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 @@ impl<'tcx> TypeMap<'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 @@ impl<'tcx> TypeMap<'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 @@ impl<'tcx> TypeMap<'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 @@ impl<'tcx> TypeMap<'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 @@ impl<'tcx> 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 @@ impl<'tcx> TypeMap<'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(',');
}
@@ -582,7 +582,7 @@ impl<'tcx> TypeMap<'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("!");
@@ -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 @@ pub fn create_function_debug_context<'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 @@ pub fn create_function_debug_context<'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 @@ pub fn create_function_debug_context<'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 @@ pub fn create_function_debug_context<'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 @@ pub fn create_function_debug_context<'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 @@ pub fn create_function_debug_context<'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 @@ impl<'tcx> RecursiveTypeDescription<'tcx> {
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 @@ impl<'tcx> EnumMemberDescriptionFactory<'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 @@ impl<'tcx> EnumMemberDescriptionFactory<'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 @@ impl<'tcx> EnumMemberDescriptionFactory<'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 {
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index 861a218e0f1..1af9fa87c6b 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -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 trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
trans_adt(bcx,
expr_ty(bcx, expr),
0,
- &numbered_fields[],
+ &numbered_fields[..],
None,
dest,
expr.debug_loc())
@@ -1153,13 +1153,13 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
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 trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
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 trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
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 \
diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs
index 8f0e4e647b5..4508fe21a65 100644
--- a/src/librustc_trans/trans/foreign.rs
+++ b/src/librustc_trans/trans/foreign.rs
@@ -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 @@ pub fn trans_rust_fn_with_foreign_abi<'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)
}
}
diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs
index af90e1ec5c5..268b65c6ceb 100644
--- a/src/librustc_trans/trans/glue.rs
+++ b/src/librustc_trans/trans/glue.rs
@@ -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);
}
diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs
index 5687247561e..a1b66ed94f0 100644
--- a/src/librustc_trans/trans/intrinsic.rs
+++ b/src/librustc_trans/trans/intrinsic.rs
@@ -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)
}
diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs
index 30797344da8..ec48ab0d34a 100644
--- a/src/librustc_trans/trans/monomorphize.rs
+++ b/src/librustc_trans/trans/monomorphize.rs
@@ -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);
diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs
index 456e27967f5..7b59e0258ee 100644
--- a/src/librustc_trans/trans/tvec.rs
+++ b/src/librustc_trans/trans/tvec.rs
@@ -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
}
diff --git a/src/librustc_trans/trans/type_.rs b/src/librustc_trans/trans/type_.rs
index e3e4ca62c26..ad83135a0d4 100644
--- a/src/librustc_trans/trans/type_.rs
+++ b/src/librustc_trans/trans/type_.rs
@@ -163,7 +163,7 @@ impl 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()))
}
diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs
index 9d1c0fadefc..489b56bbe68 100644
--- a/src/librustc_trans/trans/type_of.rs
+++ b/src/librustc_trans/trans/type_of.rs
@@ -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 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
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 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
// 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 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
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[..])
}
}
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 0183b3474a5..e3c1c66f78c 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -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() {
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 0d30741978a..34c52981b79 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -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) => {
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 7354ea7377c..0ad15456df9 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -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,
diff --git a/src/librustc_typeck/check/implicator.rs b/src/librustc_typeck/check/implicator.rs
index da25719baaa..4aaaf4ffe5a 100644
--- a/src/librustc_typeck/check/implicator.rs
+++ b/src/librustc_typeck/check/implicator.rs
@@ -329,6 +329,9 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
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 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
.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; }
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 82bd4ae87ff..978fbbbcffc 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -901,7 +901,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
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 => { }
}
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 063300a1d72..1639772103b 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -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(..) => {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 3c2888e2278..e443b4d0e60 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -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_expr_with_unifier<'a, 'tcx, F>(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_expr_with_unifier<'a, 'tcx, F>(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_expr_with_unifier<'a, 'tcx, F>(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_expr_with_unifier<'a, 'tcx, F>(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_expr_with_unifier<'a, 'tcx, F>(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_expr_with_unifier<'a, 'tcx, F>(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_expr_with_unifier<'a, 'tcx, F>(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_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
}
ast::ExprStruct(ref path, ref fields, ref base_expr) => {
// Resolve the path.
- let def = tcx.def_map.borrow().get(&id).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_expr_with_unifier<'a, 'tcx, F>(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_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
id,
expr.span,
struct_did,
- &fields[],
+ &fields[..],
base_expr.as_ref().map(|e| &**e));
}
_ => {
@@ -3886,7 +3886,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
pprust::path_to_string(path));
check_struct_fields_on_error(fcx,
id,
- &fields[],
+ &fields[..],
base_expr);
}
}
@@ -5231,10 +5231,10 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
}
};
(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 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
"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,
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 4e5550a2106..82abff8c425 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -294,8 +294,8 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
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);
}
diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs
index 2e7eff68bd5..3666b69d1c6 100644
--- a/src/librustc_typeck/check/vtable.rs
+++ b/src/librustc_typeck/check/vtable.rs
@@ -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,
diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs
index d124282d391..2601c4d2752 100644
--- a/src/librustc_typeck/check/wf.rs
+++ b/src/librustc_typeck/check/wf.rs
@@ -10,21 +10,22 @@
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 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
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 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
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 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
}
});
}
+
+ 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 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
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 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
&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);
}
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 44e850a0738..0b78af18e26 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -87,6 +87,7 @@ There are some shortcomings in this design:
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 @@ fn enforce_impl_ty_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
}
}
}
-
- 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
index 00000000000..83d7e985000
--- /dev/null
+++ b/src/librustc_typeck/constrained_type_params.rs
@@ -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;
+ }
+ }
+}
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 7498dc8179d..b5dca0bd4f6 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -123,6 +123,7 @@ mod check;
mod rscope;
mod astconv;
mod collect;
+mod constrained_type_params;
mod coherence;
mod variance;
diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs
index d5883d8bf86..1adcf133bf3 100644
--- a/src/librustc_typeck/variance.rs
+++ b/src/librustc_typeck/variance.rs
@@ -187,6 +187,22 @@
//! 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::*;
@@ -199,7 +215,6 @@ use middle::subst::{ParamSpace, FnSpace, TypeSpace, SelfSpace, VecPerParamSpace}
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 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
&**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 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
ast::ItemTy(..) |
ast::ItemImpl(..) |
ast::ItemMac(..) => {
- visit::walk_item(self, item);
}
}
+
+ visit::walk_item(self, item);
}
}
@@ -648,15 +732,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
-> 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 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
}
}
+ 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 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
}
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 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
}
}
+ 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 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
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 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
// 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,
}
}
+
diff --git a/src/librustdoc/flock.rs b/src/librustdoc/flock.rs
index a7cf5eb8918..ad91c3cb2c3 100644
--- a/src/librustdoc/flock.rs
+++ b/src/librustdoc/flock.rs
@@ -112,7 +112,7 @@ mod imp {
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)
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 6acd1537946..44c0acda66f 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -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`.
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index c513fe2e8eb..7ea5bd569e1 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -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()) }
}
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 95994af7dc8..fc3c8738991 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1404,8 +1404,7 @@ impl<'a> fmt::Display for Item<'a> {
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
diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css
index a4263badb01..2f0755ecb89 100644
--- a/src/librustdoc/html/static/main.css
+++ b/src/librustdoc/html/static/main.css
@@ -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; }
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index bab734db126..f9e0948d7bc 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -23,7 +23,6 @@
#![feature(collections)]
#![feature(core)]
#![feature(env)]
-#![feature(hash)]
#![feature(int_uint)]
#![feature(old_io)]
#![feature(libc)]
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index abd73fcfb70..722f14fa6d4 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -293,7 +293,7 @@ pub fn collapse_docs(krate: clean::Crate) -> plugins::PluginResult {
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));
}
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index ac1a0285412..c52b0bab1fa 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -333,7 +333,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
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,
diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs
index f81edca8371..10cf02f85e8 100644
--- a/src/libserialize/collection_impls.rs
+++ b/src/libserialize/collection_impls.rs
@@ -12,16 +12,17 @@
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 @@ impl<
}
}
-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 @@ impl<T:Decodable> Decodable for DList<T> {
}
}
-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 @@ impl<T: Encodable> Encodable for RingBuf<T> {
}
}
-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 @@ impl<
}
}
+#[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 @@ impl<K, V, S> Encodable for HashMap<K, V, S>
})
}
}
+#[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 @@ impl<K, V, S> Decodable for HashMap<K, V, S>
})
}
}
+#[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 @@ impl<T, S> Encodable for HashSet<T, S>
})
}
}
+#[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 @@ impl<T, S> Decodable for HashSet<T, S>
})
}
}
+#[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> {
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index 68b28784b42..a0f42815b43 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -1120,7 +1120,7 @@ impl Json {
/// 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 @@ impl ::Decoder for Decoder {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
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);
}
diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs
index 853da598ab5..d476fd72abc 100644
--- a/src/libserialize/lib.rs
+++ b/src/libserialize/lib.rs
@@ -31,7 +31,6 @@ Core encoding and decoding interfaces.
#![feature(int_uint)]
#![feature(old_io)]
#![feature(old_path)]
-#![feature(hash)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(std_misc)]
diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs
index 517907bcf58..70f0ba4bb23 100644
--- a/src/libserialize/serialize.rs
+++ b/src/libserialize/serialize.rs
@@ -326,7 +326,7 @@ impl Encodable for str {
impl Encodable for String {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
- s.emit_str(&self[])
+ s.emit_str(&self[..])
}
}
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 1b9f8b99017..ade4f1f0533 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -14,12 +14,12 @@ use self::Entry::*;
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 @@ impl<K, V, M> SearchResult<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 @@ impl<K, V, S, H> HashMap<K, V, S>
/// 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 @@ impl<K, V, S, H> HashMap<K, V, S>
}
}
-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 @@ impl<K: Hash<Hasher> + Eq, V> 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 @@ impl<K, V, S, H> HashMap<K, V, S>
/// ```
#[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 @@ impl<K, V, S, H> HashMap<K, V, S>
/// ```
#[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 @@ impl<K, V, S, H> HashMap<K, V, S>
/// ```
#[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 @@ impl<K, V, S, H> HashMap<K, V, S>
/// ```
#[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 @@ impl<K, V, S, H> PartialEq for HashMap<K, V, S>
}
#[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 @@ impl<K, V, S, H> Debug for HashMap<K, V, S>
}
#[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 @@ impl<K, V, S, H> Default for 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 @@ impl<K, Q: ?Sized, V, S, H> Index<Q> for HashMap<K, V, S>
}
#[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 @@ impl<'a, K, V, S, H> IntoIterator for &'a HashMap<K, V, S>
}
#[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 @@ impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap<K, V, S>
}
#[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 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, 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 @@ impl<K, V, S, H> FromIterator<(K, V)> for 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 @@ impl 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 @@ impl Default for 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
index 00000000000..f9e5044c597
--- /dev/null
+++ b/src/libstd/collections/hash/map_stage0.rs
@@ -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);
+ }
+ }
+}
diff --git a/src/libstd/collections/hash/mod.rs b/src/libstd/collections/hash/mod.rs
index 47e300af269..39c1458b720 100644
--- a/src/libstd/collections/hash/mod.rs
+++ b/src/libstd/collections/hash/mod.rs
@@ -12,6 +12,14 @@
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;
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index 5fbbcb3b347..e0631a64d44 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -10,21 +10,21 @@
//
// 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 @@ impl<T: Hash<Hasher> + Eq> 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 @@ impl<T, S, H> HashSet<T, S>
/// ```
#[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 @@ impl<T, S, H> HashSet<T, S>
/// ```
#[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 @@ impl<T, S, H> PartialEq for HashSet<T, S>
}
#[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 @@ impl<T, S, H> fmt::Debug for HashSet<T, S>
}
#[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 @@ impl<T, S, H> FromIterator<T> for 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 @@ impl<T, S, H> Extend<T> for HashSet<T, S>
}
#[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 @@ impl<T, S, H> Default for 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 @@ impl<'a, 'b, T, S, H> BitOr<&'b HashSet<T, S>> for &'a 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 @@ impl<'a, 'b, T, S, H> BitAnd<&'b HashSet<T, S>> for &'a 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 @@ impl<'a, 'b, T, S, H> BitXor<&'b HashSet<T, S>> for &'a 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 @@ impl<'a, T, S, H> IntoIterator for &'a HashSet<T, S>
}
#[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 @@ impl<'a, K> ExactSizeIterator for Drain<'a, K> {
}
#[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 @@ impl<'a, T, S, H> Iterator for Intersection<'a, T, S>
}
#[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 @@ impl<'a, T, S, H> Iterator for Difference<'a, T, S>
}
#[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 @@ impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, S>
}
#[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
index 00000000000..68c9e02d8ad
--- /dev/null
+++ b/src/libstd/collections/hash/set_stage0.rs
@@ -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);
+ }
+ }
+}
diff --git a/src/libstd/collections/hash/state.rs b/src/libstd/collections/hash/state.rs
index 79e01304fb8..7e6dd45b51e 100644
--- a/src/libstd/collections/hash/state.rs
+++ b/src/libstd/collections/hash/state.rs
@@ -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 @@ impl<H: Default + hash::Hasher> HashState for DefaultState<H> {
}
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) }
}
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 0bb6bd4cf35..f301f6db92f 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -23,8 +23,8 @@ use num::{Int, UnsignedInt};
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;
@@ -69,10 +69,11 @@ 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 @@ impl SafeHash {
/// We need to remove hashes of 0. That's reserved for empty buckets.
/// This function wraps up `hash_keyed` to be the only way outside this
/// module to generate a SafeHash.
+#[cfg(stage0)]
pub fn make_hash<T: ?Sized, S, H>(hash_state: &S, t: &T) -> SafeHash
where T: Hash<H>,
S: HashState<Hasher=H>,
@@ -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 @@ impl<K, V> 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 @@ impl<K, V> RawTable<K, V> {
RawTable {
capacity: capacity,
size: 0,
- hashes: hashes,
- marker: marker::CovariantType,
+ hashes: Unique::new(hashes),
+ marker: marker::PhantomData,
}
}
@@ -615,16 +636,17 @@ impl<K, V> RawTable<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 @@ impl<K, V> RawTable<K, V> {
pub fn new(capacity: usize) -> RawTable<K, V> {
unsafe {
let ret = RawTable::new_uninitialized(capacity);
- zero_memory(ret.hashes, capacity);
+ zero_memory(*ret.hashes, capacity);
ret
}
}
@@ -656,7 +678,7 @@ impl<K, V> RawTable<K, V> {
hashes_end: unsafe {
self.hashes.offset(self.capacity as isize)
},
- marker: marker::ContravariantLifetime,
+ marker: marker::PhantomData,
}
}
@@ -681,7 +703,7 @@ impl<K, V> RawTable<K, V> {
iter: RawBuckets {
raw: raw,
hashes_end: hashes_end,
- marker: marker::ContravariantLifetime,
+ marker: marker::PhantomData,
},
table: self,
}
@@ -694,7 +716,7 @@ impl<K, V> RawTable<K, V> {
iter: RawBuckets {
raw: raw,
hashes_end: hashes_end,
- marker: marker::ContravariantLifetime::<'static>,
+ marker: marker::PhantomData,
},
table: self,
}
@@ -708,7 +730,7 @@ impl<K, V> RawTable<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 @@ impl<K, V> RawTable<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 @@ impl<'a, K, V> Clone for 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 @@ impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
#[unsafe_destructor]
impl<K, V> Drop for RawTable<K, V> {
fn drop(&mut self) {
- if self.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 @@ impl<K, V> Drop for RawTable<K, V> {
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.
}
diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs
index be441bfec88..0e64370df60 100644
--- a/src/libstd/collections/mod.rs
+++ b/src/libstd/collections/mod.rs
@@ -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`
@@ -43,13 +43,13 @@
//! * 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`.
@@ -106,20 +106,20 @@
//!
//! ## 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 |
@@ -166,7 +166,7 @@
//!
//! 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.
@@ -240,10 +240,10 @@
//! ```
//!
//! ```
-//! 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
@@ -362,11 +362,11 @@
#![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;
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index c5dd66630b4..b0fb9c29403 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -112,7 +112,7 @@ impl DynamicLibrary {
// 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 @@ mod test {
mod dl {
use prelude::v1::*;
- use ffi::{self, CString};
+ use ffi::{CString, CStr};
use str;
use libc;
use ptr;
@@ -206,7 +206,7 @@ mod dl {
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 @@ mod dl {
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())
};
diff --git a/src/libstd/env.rs b/src/libstd/env.rs
index 93dc3efe2c4..8676586e7dc 100644
--- a/src/libstd/env.rs
+++ b/src/libstd/env.rs
@@ -926,7 +926,7 @@ mod tests {
#[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 @@ mod tests {
"/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 @@ mod tests {
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());
}
}
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 45089176cba..8976813d3f9 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -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 @@ use vec::Vec;
/// 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());
/// }
@@ -53,19 +60,135 @@ use vec::Vec;
/// ```
#[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 @@ impl 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 @@ impl 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 @@ impl fmt::Debug for CString {
}
}
-/// 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 @@ mod tests {
#[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 @@ mod tests {
#[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");
+ }
+ }
}
diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs
index 07a4f17796c..1bff6afb776 100644
--- a/src/libstd/ffi/mod.rs
+++ b/src/libstd/ffi/mod.rs
@@ -14,8 +14,10 @@
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;
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 1d14b141778..84149a2eb8e 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -34,13 +34,14 @@
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 @@ impl Ord for OsString {
}
}
+#[cfg(stage0)]
impl<'a, S: Hasher + Writer> Hash<S> for OsString {
#[inline]
fn hash(&self, state: &mut S) {
(&**self).hash(state)
}
}
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Hash for OsString {
+ #[inline]
+ 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 @@ impl Debug for OsStr {
}
}
-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 @@ impl AsOsStr for OsStr {
impl AsOsStr for OsString {
fn as_os_str(&self) -> &OsStr {
- &self[]
+ &self[..]
}
}
@@ -300,7 +320,7 @@ impl AsOsStr for str {
impl AsOsStr for String {
fn as_os_str(&self) -> &OsStr {
- OsStr::from_str(&self[])
+ OsStr::from_str(&self[..])
}
}
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 2fd6631ecc4..e9a8dbb4098 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -618,14 +618,14 @@ mod tests {
#[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')));
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs
index 9f3655de20f..f6cb4a8c9f3 100644
--- a/src/libstd/io/cursor.rs
+++ b/src/libstd/io/cursor.rs
@@ -180,7 +180,7 @@ mod tests {
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 @@ mod tests {
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 @@ mod tests {
#[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 @@ mod tests {
#[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 @@ mod tests {
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 @@ mod tests {
#[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());
}
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 7c9a8a7b4b5..fbd403ea593 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -161,7 +161,6 @@ extern crate libc;
// 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;
@@ -184,6 +183,7 @@ pub use core::error;
#[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;
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs
index 66d4d34f8eb..51944adf3b4 100644
--- a/src/libstd/net/addr.rs
+++ b/src/libstd/net/addr.rs
@@ -147,6 +147,7 @@ impl PartialEq for Repr {
}
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 @@ impl<S: hash::Hasher + hash::Writer> hash::Hash<S> for Repr {
}
}
}
+#[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.
diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs
index 08f7a6e2e96..571a1b03ef0 100644
--- a/src/libstd/net/ip.rs
+++ b/src/libstd/net/ip.rs
@@ -189,11 +189,19 @@ impl PartialEq for Ipv4Addr {
}
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 @@ impl PartialEq for Ipv6Addr {
}
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> {
diff --git a/src/libstd/old_io/buffered.rs b/src/libstd/old_io/buffered.rs
index 59a437ad916..2d2d0d8b33a 100644
--- a/src/libstd/old_io/buffered.rs
+++ b/src/libstd/old_io/buffered.rs
@@ -546,7 +546,7 @@ mod test {
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 @@ mod test {
#[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')));
diff --git a/src/libstd/old_io/mod.rs b/src/libstd/old_io/mod.rs
index 21282a0c28a..fc3deb67f41 100644
--- a/src/libstd/old_io/mod.rs
+++ b/src/libstd/old_io/mod.rs
@@ -252,7 +252,7 @@ use error::Error;
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 @@ trait UpdateIoError<T> {
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
diff --git a/src/libstd/old_io/net/pipe.rs b/src/libstd/old_io/net/pipe.rs
index 8a4e8668b10..d05669d32b8 100644
--- a/src/libstd/old_io/net/pipe.rs
+++ b/src/libstd/old_io/net/pipe.rs
@@ -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 @@ impl UnixStream {
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 })
}
diff --git a/src/libstd/old_io/process.rs b/src/libstd/old_io/process.rs
index ea6510c61b7..c803cfbcb7d 100644
--- a/src/libstd/old_io/process.rs
+++ b/src/libstd/old_io/process.rs
@@ -104,7 +104,7 @@ struct EnvKey(CString);
#[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 @@ impl<H: hash::Writer + hash::Hasher> hash::Hash<H> for EnvKey {
}
}
}
+#[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 @@ impl 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 @@ impl Command {
// 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 @@ impl Command {
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 @@ impl Command {
/// 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 @@ impl Command {
-> &'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 @@ mod tests {
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());
}
}
diff --git a/src/libstd/old_path/mod.rs b/src/libstd/old_path/mod.rs
index 37de2993c4d..e9005aa22bc 100644
--- a/src/libstd/old_path/mod.rs
+++ b/src/libstd/old_path/mod.rs
@@ -877,7 +877,7 @@ impl BytesContainer for String {
}
#[inline]
fn container_as_str(&self) -> Option<&str> {
- Some(&self[])
+ Some(&self[..])
}
#[inline]
fn is_str(_: Option<&String>) -> bool { true }
@@ -893,7 +893,7 @@ impl BytesContainer for [u8] {
impl BytesContainer for Vec<u8> {
#[inline]
fn container_as_bytes(&self) -> &[u8] {
- &self[]
+ &self[..]
}
}
diff --git a/src/libstd/old_path/posix.rs b/src/libstd/old_path/posix.rs
index 0a184a01a1d..15eee9e4a0c 100644
--- a/src/libstd/old_path/posix.rs
+++ b/src/libstd/old_path/posix.rs
@@ -100,12 +100,21 @@ impl FromStr for Path {
#[derive(Debug, Clone, PartialEq, Copy)]
pub struct ParsePathError;
+#[cfg(stage0)]
impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Path {
#[inline]
fn hash(&self, state: &mut S) {
self.repr.hash(state)
}
}
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl hash::Hash for Path {
+ #[inline]
+ fn hash<H: hash::Hasher>(&self, state: &mut H) {
+ self.repr.hash(state)
+ }
+}
impl BytesContainer for Path {
#[inline]
@@ -1172,7 +1181,7 @@ mod tests {
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 @@ mod tests {
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);
}
)
diff --git a/src/libstd/old_path/windows.rs b/src/libstd/old_path/windows.rs
index 02a21321c4c..887dc804c7a 100644
--- a/src/libstd/old_path/windows.rs
+++ b/src/libstd/old_path/windows.rs
@@ -127,6 +127,7 @@ impl FromStr for Path {
#[derive(Debug, Clone, PartialEq, Copy)]
pub struct ParsePathError;
+#[cfg(stage0)]
impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Path {
#[cfg(not(test))]
#[inline]
@@ -140,6 +141,21 @@ impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Path {
// 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 @@ impl GenericPathUnsafe for Path {
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 @@ impl GenericPathUnsafe for Path {
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 @@ impl GenericPathUnsafe for Path {
}
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 @@ impl GenericPathUnsafe for Path {
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 @@ impl GenericPathUnsafe for Path {
}
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 @@ impl GenericPath for 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 @@ impl GenericPath for Path {
/// 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 @@ impl GenericPath for Path {
/// 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 @@ impl 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 @@ impl Path {
}
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 @@ impl Path {
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 @@ mod tests {
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 @@ mod tests {
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);
}
)
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index a4213e7373b..f181fc5df57 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -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()
}
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 35221a7e647..2e05f6d974e 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -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>",
}
};
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 1d992668900..49a5efec7c2 100755
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -108,12 +108,11 @@
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 @@ impl PathBuf {
}
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 @@ impl<'a, P: ?Sized + 'a> iter::FromIterator<&'a P> for PathBuf where P: AsPath {
}
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 @@ impl cmp::Ord for PathBuf {
impl AsOsStr for PathBuf {
fn as_os_str(&self) -> &OsStr {
- &self.inner[]
+ &self.inner[..]
}
}
@@ -1066,10 +1070,10 @@ impl Path {
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()
}
diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs
index 25d372b406f..5c891441198 100644
--- a/src/libstd/rand/mod.rs
+++ b/src/libstd/rand/mod.rs
@@ -547,7 +547,7 @@ mod test {
#[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);
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs
index c2f5133eaf3..61f5bd0f013 100644
--- a/src/libstd/rt/args.rs
+++ b/src/libstd/rt/args.rs
@@ -49,7 +49,7 @@ mod imp {
use libc;
use mem;
- use ffi;
+ use ffi::CStr;
use sync::{StaticMutex, MUTEX_INIT};
@@ -96,10 +96,11 @@ mod imp {
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()
}
diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs
index 7325e0a5ac8..e2ac5ac24f8 100644
--- a/src/libstd/sys/common/net.rs
+++ b/src/libstd/sys/common/net.rs
@@ -12,8 +12,7 @@ use prelude::v1::*;
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())
}
}
diff --git a/src/libstd/sys/common/net2.rs b/src/libstd/sys/common/net2.rs
index 5af59ec6d2b..713f79c5d08 100644
--- a/src/libstd/sys/common/net2.rs
+++ b/src/libstd/sys/common/net2.rs
@@ -121,7 +121,7 @@ impl Drop for LookupHost {
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 _,
diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs
index b610f6c370b..ca3ae1a7a34 100644
--- a/src/libstd/sys/common/wtf8.rs
+++ b/src/libstd/sys/common/wtf8.rs
@@ -31,8 +31,9 @@ use ascii::*;
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 @@ impl Wtf8Buf {
/// 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 @@ impl FromIterator<CodePoint> for 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 @@ impl<'a> Iterator for EncodeWide<'a> {
}
}
+#[cfg(stage0)]
impl<S: Writer + Hasher> Hash<S> for CodePoint {
#[inline]
fn hash(&self, state: &mut S) {
self.value.hash(state)
}
}
+#[cfg(not(stage0))]
+impl Hash for CodePoint {
+ #[inline]
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ 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 @@ impl<S: Writer + Hasher> Hash<S> for Wtf8Buf {
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 @@ impl<'a, S: Writer + Hasher> Hash<S> for Wtf8 {
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;
diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs
index 5e512e9261b..8b560339f30 100644
--- a/src/libstd/sys/unix/backtrace.rs
+++ b/src/libstd/sys/unix/backtrace.rs
@@ -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 print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
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 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
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() }))
}
}
diff --git a/src/libstd/sys/unix/ext.rs b/src/libstd/sys/unix/ext.rs
index bbbe022fbaf..b8b9dcfb3c6 100644
--- a/src/libstd/sys/unix/ext.rs
+++ b/src/libstd/sys/unix/ext.rs
@@ -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 @@ impl OsStrExt for OsStr {
&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 @@ impl ExitStatusExt for process::ExitStatus {
/// 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};
}
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 0ee2b5b6809..5c847002d23 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -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 @@ impl Drop for FileDesc {
}
}
-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 @@ pub fn readdir(p: &Path) -> IoResult<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 @@ pub fn readdir(p: &Path) -> IoResult<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 @@ pub fn readdir(p: &Path) -> IoResult<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 mkstat(stat: &libc::stat) -> FileStat {
}
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,
diff --git a/src/libstd/sys/unix/fs2.rs b/src/libstd/sys/unix/fs2.rs
index e5904b074bc..92a47c6c385 100644
--- a/src/libstd/sys/unix/fs2.rs
+++ b/src/libstd/sys/unix/fs2.rs
@@ -12,7 +12,7 @@ use core::prelude::*;
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 @@ impl DirEntry {
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 @@ impl 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 @@ impl File {
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(())
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index 850189140d1..b79ad7031fa 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -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
}
diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs
index 54aec7cf4b1..83b6a14b78d 100644
--- a/src/libstd/sys/unix/net.rs
+++ b/src/libstd/sys/unix/net.rs
@@ -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,
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 5fe84cafb71..3d1ef3a2c37 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -14,7 +14,7 @@ use prelude::v1::*;
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 @@ pub fn error_string(errno: i32) -> String {
}
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 @@ pub fn env() -> Env {
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 @@ pub fn home_dir() -> Option<Path> {
_ => 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))
}
}
diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs
index 45d5b1506c3..3c9cdc65975 100644
--- a/src/libstd/sys/unix/pipe.rs
+++ b/src/libstd/sys/unix/pipe.rs
@@ -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
diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs
index f954024b0e9..b30ac889120 100644
--- a/src/libstd/sys/unix/process.rs
+++ b/src/libstd/sys/unix/process.rs
@@ -12,6 +12,7 @@ use prelude::v1::*;
use self::Req::*;
use collections::HashMap;
+#[cfg(stage0)]
use collections::hash_map::Hasher;
use ffi::CString;
use hash::Hash;
@@ -63,6 +64,7 @@ impl Process {
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 @@ impl Process {
})
})
}
+ #[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)]
diff --git a/src/libstd/sys/unix/process2.rs b/src/libstd/sys/unix/process2.rs
index 5e2c207f375..06fa5c4bba7 100644
--- a/src/libstd/sys/unix/process2.rs
+++ b/src/libstd/sys/unix/process2.rs
@@ -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 @@ impl 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 @@ impl Command {
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())
}
}
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 82c52471d10..c90ba7645fe 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -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());
}
diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs
index 92e309da34b..51cf3032423 100644
--- a/src/libstd/sys/windows/backtrace.rs
+++ b/src/libstd/sys/windows/backtrace.rs
@@ -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 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
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])),
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index f861255a00a..2d1a5e10bd6 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -283,7 +283,7 @@ pub mod compat {
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
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index 4d6d033deee..a756fb29f81 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -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
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index 502d70d4e1a..6520d30487c 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -114,7 +114,7 @@ impl Iterator for Env {
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 @@ impl<'a> Iterator for SplitPaths<'a> {
if !must_yield && in_progress.is_empty() {
None
} else {
- Some(super::os2path(&in_progress[]))
+ Some(super::os2path(&in_progress[..]))
}
}
}
@@ -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 {
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index 96ffc4daddd..60d24e6174f 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -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 @@ impl Process {
}
#[allow(deprecated)]
+ #[cfg(stage0)]
pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
out_fd: Option<P>, err_fd: Option<P>)
-> IoResult<Process>
@@ -267,6 +268,169 @@ impl Process {
})
}
}
+ #[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 make_command_line(prog: &CString, args: &[CString]) -> String {
}
}
+#[cfg(stage0)]
fn with_envp<K, V, T, F>(env: Option<&collections::HashMap<K, V>>, cb: F) -> T
where K: BytesContainer + Eq + Hash<Hasher>,
V: BytesContainer,
@@ -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,
diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs
index 3137d779c40..3653e7e31d5 100644
--- a/src/libstd/thread.rs
+++ b/src/libstd/thread.rs
@@ -153,7 +153,7 @@ use any::Any;
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 @@ impl Builder {
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 @@ impl Drop for JoinHandle {
#[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")]
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index d6778be553e..140e21b5d04 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -198,7 +198,7 @@ impl Encodable for Ident {
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())[..]))
}
}
diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs
index 5535e5911e0..ba08f61b557 100644
--- a/src/libsyntax/ast_map/mod.rs
+++ b/src/libsyntax/ast_map/mod.rs
@@ -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 @@ impl<'ast> Map<'ast> {
}
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 @@ impl<'ast> Map<'ast> {
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 @@ impl<'a, 'ast> NodesMatchingSuffix<'a, 'ast> {
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 @@ impl<'a, 'ast> NodesMatchingSuffix<'a, 'ast> {
// 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 @@ impl<'a> NodePrinter for pprust::State<'a> {
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)) => {
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 117507ad8b7..f660296fcd7 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -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?
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index a3afe5780d0..62e676891a0 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -26,11 +26,11 @@ use parse::token;
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 @@ pub trait AttrMetaMethods {
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 @@ impl AttrMetaMethods for MetaItem {
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 @@ impl AttributeMethods for Attribute {
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),
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 3231342cb50..099f6462942 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -360,7 +360,7 @@ impl CodeMap {
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.
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 7ca0591be50..dfe3477bddc 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -311,7 +311,7 @@ impl<'a> fold::Folder for CfgAttrFolder<'a> {
}
};
- 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,
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index 83a4d938bb5..27219774cf1 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -129,7 +129,7 @@ impl SpanHandler {
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 @@ impl Handler {
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 @@ impl Handler {
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()),
}
}
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index 833a6d52acb..b3afc3fc4dd 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -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())
}
diff --git a/src/libsyntax/diagnostics/registry.rs b/src/libsyntax/diagnostics/registry.rs
index 62d48189c43..a6cfd1a5a9a 100644
--- a/src/libsyntax/diagnostics/registry.rs
+++ b/src/libsyntax/diagnostics/registry.rs
@@ -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()
}
}
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 8800ffd1e9b..d4ccabbd63b 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -640,7 +640,7 @@ impl<'a> ExtCtxt<'a> {
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) {
diff --git a/src/libsyntax/ext/concat.rs b/src/libsyntax/ext/concat.rs
index 80d128959ea..38098e50dee 100644
--- a/src/libsyntax/ext/concat.rs
+++ b/src/libsyntax/ext/concat.rs
@@ -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[..])))
}
diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs
index 63a8bd9ddf1..9410a51e7a5 100644
--- a/src/libsyntax/ext/concat_idents.rs
+++ b/src/libsyntax/ext/concat_idents.rs
@@ -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,
diff --git a/src/libsyntax/ext/deriving/bounds.rs b/src/libsyntax/ext/deriving/bounds.rs
index 879718a6399..93098484ae0 100644
--- a/src/libsyntax/ext/deriving/bounds.rs
+++ b/src/libsyntax/ext/deriving/bounds.rs
@@ -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,
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index f878cb5ca8b..b912ed34ae0 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -367,7 +367,7 @@ impl<'a> TraitDef<'a> {
"allow" | "warn" | "deny" | "forbid" => true,
_ => false,
}
- }).map(|a| a.clone()));
+ }).cloned());
push(P(ast::Item {
attrs: attrs,
..(*newitem).clone()
@@ -410,7 +410,7 @@ impl<'a> TraitDef<'a> {
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 @@ impl<'a> TraitDef<'a> {
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 @@ impl<'a> TraitDef<'a> {
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 @@ impl<'a> TraitDef<'a> {
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 @@ impl<'a> TraitDef<'a> {
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 @@ impl<'a> MethodDef<'a> {
.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 @@ impl<'a> MethodDef<'a> {
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 @@ impl<'a> MethodDef<'a> {
&**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 @@ impl<'a> MethodDef<'a> {
}
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`")
diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs
index 5aa9f9a0c3e..2149c7a7f77 100644
--- a/src/libsyntax/ext/deriving/hash.rs
+++ b/src/libsyntax/ext/deriving/hash.rs
@@ -14,7 +14,6 @@ use ext::base::ExtCtxt;
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)
})
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index 0ed9e85e576..f8bc331bfcf 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -102,7 +102,7 @@ pub fn expand_meta_derive(cx: &mut ExtCtxt,
|i| push(i)))
}
- match &tname[] {
+ match &tname[..] {
"Clone" => expand!(clone::expand_deriving_clone),
"Hash" => expand!(hash::expand_deriving_hash),
diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs
index 3f5947672e0..281f23f9e61 100644
--- a/src/libsyntax/ext/deriving/show.rs
+++ b/src/libsyntax/ext/deriving/show.rs
@@ -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!
diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs
index 5d56707c87a..9c04d1e9282 100644
--- a/src/libsyntax/ext/env.rs
+++ b/src/libsyntax/ext/env.rs
@@ -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)
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 6b7cecee815..d4dda7390a5 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -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 @@ impl Folder for Marker {
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 @@ mod test {
.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 @@ foo_module!();
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")
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs
index 170a455a913..e17329d7d33 100644
--- a/src/libsyntax/ext/format.rs
+++ b/src/libsyntax/ext/format.rs
@@ -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 @@ impl<'a, 'b> Context<'a, 'b> {
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 @@ impl<'a, 'b> Context<'a, 'b> {
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 @@ impl<'a, 'b> Context<'a, 'b> {
-> P<ast::Expr> {
let trait_ = match *ty {
Known(ref tyname) => {
- match &tyname[] {
+ match &tyname[..] {
"" => "Display",
"?" => "Debug",
"e" => "LowerExp",
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 67990895d07..2c7bf713aad 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -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,
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index 7a3a3562bdf..c8d48750c75 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -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 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree
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))))
}
}
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index d649e497ef7..664f7b3e088 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -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 @@ pub fn nameize(p_s: &ParseSess, ms: &[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`")
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index f322cf8bad0..fa6d934a457 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -50,7 +50,7 @@ impl<'a> ParserAnyMacro<'a> {
following",
token_str);
let span = parser.span;
- parser.span_err(span, &msg[]);
+ parser.span_err(span, &msg[..]);
}
}
}
@@ -123,8 +123,8 @@ impl TTMacroExpander for MacroRulesMacroExpander {
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:
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 83234e3b7a5..0d92bd761b4 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -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)));
}
}
}
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 0110823ae98..071158fcebb 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -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 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
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 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
}
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 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
}
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 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
}
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 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
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 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
"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 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
}
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")
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index e8bdcd62b58..3a7fa54edbd 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -28,7 +28,6 @@
#![feature(collections)]
#![feature(core)]
#![feature(env)]
-#![feature(hash)]
#![feature(int_uint)]
#![feature(old_io)]
#![feature(libc)]
diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs
index 0f9a56baa17..f5201d4a8bc 100644
--- a/src/libsyntax/owned_slice.rs
+++ b/src/libsyntax/owned_slice.rs
@@ -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 @@ impl<T: Clone> Clone for 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())
}
}
diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs
index b17fc7fe82e..1f06db60027 100644
--- a/src/libsyntax/parse/lexer/comments.rs
+++ b/src/libsyntax/parse/lexer/comments.rs
@@ -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 @@ pub fn strip_doc_comment_decoration(comment: &str) -> 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'));
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 38ba0b38df5..fd08cbd161b 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -16,14 +16,13 @@ use ext::tt::transcribe::tt_next_token;
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 @@ impl<'a> StringReader<'a> {
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 @@ impl<'a> StringReader<'a> {
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 @@ impl<'a> StringReader<'a> {
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 @@ impl<'a> StringReader<'a> {
/// 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 @@ impl<'a> StringReader<'a> {
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
};
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 6ea23cf3f04..7ed48bdbb92 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -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 @@ mod test {
#[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 @@ mod test {
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 @@ mod test {
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 @@ mod test {
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"),
}
}
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 1df2e762ee7..8480772ce6c 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -28,6 +28,7 @@ pub enum ObsoleteSyntax {
ProcExpr,
ClosureType,
ClosureKind,
+ EmptyIndex,
}
pub trait ParserObsoleteMethods {
@@ -40,7 +41,8 @@ pub trait ParserObsoleteMethods {
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 @@ pub trait ParserObsoleteMethods {
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 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
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
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 407740e580d..370201e5382 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
(format!("expected {}, found `{}`",
expect,
actual))
- }[])
+ })[..]
)
}
}
@@ -467,9 +466,9 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
_ => {
let token_str = self.this_token_to_string();
self.fatal(&format!("expected ident, found `{}`",
- token_str)[])
+ token_str))
}
}
}
@@ -599,7 +597,7 @@ impl<'a> Parser<'a> {
let span = self.span;
self.span_err(span,
&format!("expected identifier, found keyword `{}`",
- token_str)[]);
+ token_str));
}
}
@@ -608,7 +606,7 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
_ => {
let token_str = p.this_token_to_string();
p.fatal(&format!("expected `;` or `{{`, found `{}`",
- token_str)[])
+ token_str)[..])
}
}
}
@@ -1551,7 +1549,7 @@ impl<'a> Parser<'a> {
} 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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
};
}
_ => {
- self.fatal(&format!("expected a lifetime name")[]);
+ self.fatal(&format!("expected a lifetime name"));
}
}
}
@@ -1982,7 +1980,7 @@ impl<'a> Parser<'a> {
let msg = format!("expected `,` or `>` after lifetime \
name, found `{}`",
this_token_str);
- self.fatal(&msg[]);
+ self.fatal(&msg[..]);
}
}
}
@@ -2497,7 +2495,7 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
match self.token {
token::SubstNt(name, _) =>
self.fatal(&format!("unknown macro variable `{}`",
- token::get_ident(name))[]),
+ token::get_ident(name))),
_ => {}
}
}
@@ -2701,7 +2698,7 @@ impl<'a> Parser<'a> {
};
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
&& 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 @@ impl<'a> Parser<'a> {
let tok_str = self.this_token_to_string();
self.fatal(&format!("expected {}`(` or `{{`, found `{}`",
ident_str,
- tok_str)[])
+ tok_str))
},
};
@@ -3758,7 +3755,7 @@ impl<'a> Parser<'a> {
}
} 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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
_ => {
let token_str = self.this_token_to_string();
self.fatal(&format!("expected `self`, found `{}`",
- token_str)[])
+ token_str))
}
}
}
@@ -4404,7 +4401,7 @@ impl<'a> Parser<'a> {
_ => {
let token_str = self.this_token_to_string();
self.fatal(&format!("expected `Self`, found `{}`",
- token_str)[])
+ token_str))
}
}
}
@@ -4539,7 +4536,7 @@ impl<'a> Parser<'a> {
_ => {
let token_str = self.this_token_to_string();
self.fatal(&format!("expected `,` or `)`, found `{}`",
- token_str)[])
+ token_str))
}
}
}
@@ -4712,7 +4709,7 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
} 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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
// 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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
// 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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
&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 @@ impl<'a> Parser<'a> {
(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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
let mut err = String::from_str("circular modules: ");
let len = included_mod_stack.len();
for p in &included_mod_stack[i.. len] {
- err.push_str(&p.display().as_cow()[]);
+ err.push_str(&p.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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
self.span_fatal(span,
&format!("expected extern crate name but \
found `{}`",
- token_str)[]);
+ token_str));
}
};
@@ -5505,7 +5502,7 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
&format!("illegal ABI: expected one of [{}], \
found `{}`",
abi::all_names().connect(", "),
- the_string)[]);
+ the_string));
None
}
}
@@ -5663,7 +5660,7 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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 @@ impl<'a> Parser<'a> {
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
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 0747a97fa37..433c013591c 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -482,7 +482,7 @@ macro_rules! declare_special_idents_and_keywords {(
$(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 @@ impl BytesContainer for InternedString {
// 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())
}
}
diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs
index 6c6cf186e70..1593bfb97fe 100644
--- a/src/libsyntax/print/pp.rs
+++ b/src/libsyntax/print/pp.rs
@@ -539,8 +539,8 @@ impl Printer {
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 @@ impl Printer {
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.
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 4b021f2434f..f26578e7401 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
}
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 @@ impl<'a> State<'a> {
}
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
}
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
}
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 @@ impl<'a> State<'a> {
}
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 @@ impl<'a> State<'a> {
}
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
));
}
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
}
}
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> IoResult<()> {
try!(self.hardbreak_if_not_bol());
try!(self.maybe_print_comment(m.span.lo));
- try!(self.print_outer_attributes(&m.attrs[]));
+ try!(self.print_outer_attributes(&m.attrs));
try!(self.print_ty_fn(m.abi,
m.unsafety,
&*m.decl,
@@ -1263,7 +1262,7 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
}
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 @@ impl<'a> State<'a> {
}
try!(self.commasep(
Inconsistent,
- &data.types[],
+ &data.types,
|s, ty| s.print_type(&**ty)));
comma = true;
}
@@ -2098,7 +2097,7 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
}
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
&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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
// 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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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 @@ impl<'a> State<'a> {
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")
diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs
index 01f3839b039..adb5383a8fd 100644
--- a/src/libsyntax/ptr.rs
+++ b/src/libsyntax/ptr.rs
@@ -111,11 +111,18 @@ impl<T: Display> Display for P<T> {
}
}
+#[cfg(stage0)]
impl<S: Hasher, T: Hash<S>> Hash<S> for P<T> {
fn hash(&self, state: &mut S) {
(**self).hash(state);
}
}
+#[cfg(not(stage0))]
+impl<T: Hash> Hash for P<T> {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ (**self).hash(state);
+ }
+}
impl<T: 'static + Decodable> Decodable for P<T> {
fn decode<D: Decoder>(d: &mut D) -> Result<P<T>, D::Error> {
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index 98c193c7e6b..4e4a571ede7 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -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.
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index 6511dffa6bf..7b1fc91e45b 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -119,7 +119,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
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,
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs
index 51144267519..dffeac6f3f7 100644
--- a/src/libsyntax/util/interner.rs
+++ b/src/libsyntax/util/interner.rs
@@ -14,13 +14,13 @@
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 @@ impl<T: Eq + Hash<Hasher> + Clone + 'static> Interner<T> {
}
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 @@ impl StrInterner {
self.vect.borrow().len()
}
+ #[cfg(stage0)]
+ pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name>
+ where RcStr: Borrow<Q>, Q: Eq + Hash<Hasher> {
+ match (*self.map.borrow()).get(val) {
+ Some(v) => Some(*v),
+ None => None,
+ }
+ }
+ #[cfg(not(stage0))]
pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name>
- where 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,
diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs
index b2009a7e848..0a39d380904 100644
--- a/src/libsyntax/util/small_vector.rs
+++ b/src/libsyntax/util/small_vector.rs
@@ -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 @@ impl<T> FromIterator<T> for 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);
}
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs
index 304f370a199..5418533aff1 100644
--- a/src/libterm/lib.rs
+++ b/src/libterm/lib.rs
@@ -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)]
diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs
index b978d2d8054..be1c623c859 100644
--- a/src/libterm/terminfo/mod.rs
+++ b/src/libterm/terminfo/mod.rs
@@ -180,7 +180,7 @@ impl<T: Writer+Send+'static> TerminfoTerminal<T> {
}
};
- let entry = open(&term[]);
+ let entry = open(&term[..]);
if entry.is_err() {
if env::var("MSYSCON").ok().map_or(false, |s| {
"mintty.exe" == s
diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs
index 82b5ec11d95..0b577f8de74 100644
--- a/src/libterm/terminfo/parm.rs
+++ b/src/libterm/terminfo/parm.rs
@@ -608,7 +608,7 @@ mod test {
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)
}
diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs
index fd6e6a843e1..c40a5534efb 100644
--- a/src/libterm/terminfo/searcher.rs
+++ b/src/libterm/terminfo/searcher.rs
@@ -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);
}
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 2cb30ad9804..82c1a4b1195 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -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()
}
};
diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs
index 31ce3e91a77..4e94be59ade 100644
--- a/src/libtest/stats.rs
+++ b/src/libtest/stats.rs
@@ -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 {
diff --git a/src/llvm b/src/llvm
-Subproject 2089cab13e7f92b487ba0dc1df9f6c05116b004
+Subproject 4891e6382e3e8aa89d530aa18427836428c4715
diff --git a/src/rustbook/build.rs b/src/rustbook/build.rs
index 6f5fc5c1969..224f1ef1a8b 100644
--- a/src/rustbook/build.rs
+++ b/src/rustbook/build.rs
@@ -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
diff --git a/src/rustbook/error.rs b/src/rustbook/error.rs
index 1c10a270acc..43c882c7d5b 100644
--- a/src/rustbook/error.rs
+++ b/src/rustbook/error.rs
@@ -52,7 +52,7 @@ impl<'a> Error for &'a str {
impl Error for String {
fn description<'a>(&'a self) -> &'a str {
- &self[]
+ &self[..]
}
}
@@ -75,7 +75,7 @@ impl Error for IoError {
self.desc
}
fn detail(&self) -> Option<&str> {
- self.detail.as_ref().map(|s| &s[])
+ self.detail.as_ref().map(|s| &s[..])
}
}
diff --git a/src/rustbook/test.rs b/src/rustbook/test.rs
index d3cb8a7316e..c5d4875423a 100644
--- a/src/rustbook/test.rs
+++ b/src/rustbook/test.rs
@@ -65,7 +65,7 @@ impl Subcommand for Test {
}
Err(errors) => {
for err in errors {
- term.err(&err[]);
+ term.err(&err[..]);
}
return Err(box "There was an error." as Box<Error>);
}
diff --git a/src/test/auxiliary/coherence-orphan-lib.rs b/src/test/auxiliary/coherence-orphan-lib.rs
index 2e5d18b58f2..cc42b288e66 100644
--- a/src/test/auxiliary/coherence-orphan-lib.rs
+++ b/src/test/auxiliary/coherence-orphan-lib.rs
@@ -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);
}
diff --git a/src/test/auxiliary/default_type_params_xc.rs b/src/test/auxiliary/default_type_params_xc.rs
index d12f716decf..0a65174911e 100644
--- a/src/test/auxiliary/default_type_params_xc.rs
+++ b/src/test/auxiliary/default_type_params_xc.rs
@@ -12,4 +12,5 @@ pub struct Heap;
pub struct FakeHeap;
-pub struct FakeVec<T, A = FakeHeap>;
+pub struct FakeVec<T, A = FakeHeap> { pub f: Option<(T,A)> }
+
diff --git a/src/test/auxiliary/inner_static.rs b/src/test/auxiliary/inner_static.rs
index 94acea06618..ca5c6072cb3 100644
--- a/src/test/auxiliary/inner_static.rs
+++ b/src/test/auxiliary/inner_static.rs
@@ -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 @@ impl<T> B<T> {
}
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();
diff --git a/src/test/auxiliary/issue-14421.rs b/src/test/auxiliary/issue-14421.rs
index 7c69cba179c..a48088609f9 100644
--- a/src/test/auxiliary/issue-14421.rs
+++ b/src/test/auxiliary/issue-14421.rs
@@ -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 @@ mod src {
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"); }
diff --git a/src/test/auxiliary/issue-16643.rs b/src/test/auxiliary/issue-16643.rs
index c5b3fceaf4a..b590160a0c2 100644
--- a/src/test/auxiliary/issue-16643.rs
+++ b/src/test/auxiliary/issue-16643.rs
@@ -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) {
diff --git a/src/test/auxiliary/issue-17662.rs b/src/test/auxiliary/issue-17662.rs
index be10ca1dd8f..fb55a077005 100644
--- a/src/test/auxiliary/issue-17662.rs
+++ b/src/test/auxiliary/issue-17662.rs
@@ -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 {
diff --git a/src/test/auxiliary/issue-2380.rs b/src/test/auxiliary/issue-2380.rs
index 8eb6cd6e263..96f33f97a69 100644
--- a/src/test/auxiliary/issue-2380.rs
+++ b/src/test/auxiliary/issue-2380.rs
@@ -14,7 +14,10 @@
#![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 () { }
diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs
index e3ce4e8f656..89b3b56121a 100644
--- a/src/test/auxiliary/issue-2526.rs
+++ b/src/test/auxiliary/issue-2526.rs
@@ -13,8 +13,11 @@
#![feature(unsafe_destructor)]
+use std::marker;
+
struct arc_destruct<T> {
- _data: int,
+ _data: int,
+ _marker: marker::PhantomData<T>
}
#[unsafe_destructor]
@@ -24,7 +27,8 @@ impl<T: Sync> Drop for arc_destruct<T> {
fn arc_destruct<T: Sync>(data: int) -> arc_destruct<T> {
arc_destruct {
- _data: data
+ _data: data,
+ _marker: marker::PhantomData
}
}
diff --git a/src/test/auxiliary/issue_20389.rs b/src/test/auxiliary/issue_20389.rs
index 7a378b06df9..4ce7e3079e3 100644
--- a/src/test/auxiliary/issue_20389.rs
+++ b/src/test/auxiliary/issue_20389.rs
@@ -10,4 +10,5 @@
pub trait T {
type C;
+ fn dummy(&self) { }
}
diff --git a/src/test/auxiliary/issue_3907.rs b/src/test/auxiliary/issue_3907.rs
index 2e254e5431d..545e15fe166 100644
--- a/src/test/auxiliary/issue_3907.rs
+++ b/src/test/auxiliary/issue_3907.rs
@@ -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();
}
diff --git a/src/test/auxiliary/issue_8401.rs b/src/test/auxiliary/issue_8401.rs
index 0831993119a..9006a5d1775 100644
--- a/src/test/auxiliary/issue_8401.rs
+++ b/src/test/auxiliary/issue_8401.rs
@@ -12,7 +12,9 @@
use std::mem;
-trait A {}
+trait A {
+ fn dummy(&self) { }
+}
struct B;
impl A for B {}
diff --git a/src/test/auxiliary/issue_9123.rs b/src/test/auxiliary/issue_9123.rs
index 000cc100a12..4f2792aebcd 100644
--- a/src/test/auxiliary/issue_9123.rs
+++ b/src/test/auxiliary/issue_9123.rs
@@ -15,5 +15,6 @@ pub trait X {
fn f() { }
f();
}
+ fn dummy(&self) { }
}
diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs
index 834667968c8..b9cc20b63cc 100644
--- a/src/test/auxiliary/lang-item-public.rs
+++ b/src/test/auxiliary/lang-item-public.rs
@@ -12,8 +12,12 @@
#![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 @@ extern fn stack_exhausted() {}
extern fn eh_personality() {}
#[lang="copy"]
-pub trait Copy {}
+pub trait Copy : PhantomFn<Self> {
+ // Empty.
+}
diff --git a/src/test/auxiliary/lint_group_plugin_test.rs b/src/test/auxiliary/lint_group_plugin_test.rs
index 36b3091852b..e9d98889ff8 100644
--- a/src/test/auxiliary/lint_group_plugin_test.rs
+++ b/src/test/auxiliary/lint_group_plugin_test.rs
@@ -37,9 +37,9 @@ impl LintPass for Pass {
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'");
}
}
diff --git a/src/test/auxiliary/lint_plugin_test.rs b/src/test/auxiliary/lint_plugin_test.rs
index 9020bb7b0fb..ffb234f70c8 100644
--- a/src/test/auxiliary/lint_plugin_test.rs
+++ b/src/test/auxiliary/lint_plugin_test.rs
@@ -35,7 +35,7 @@ impl LintPass for Pass {
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'");
}
}
diff --git a/src/test/auxiliary/lint_stability.rs b/src/test/auxiliary/lint_stability.rs
index 01b2b748ba9..fb535eb8336 100644
--- a/src/test/auxiliary/lint_stability.rs
+++ b/src/test/auxiliary/lint_stability.rs
@@ -96,7 +96,7 @@ pub trait Trait {
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")]
diff --git a/src/test/auxiliary/nested_item.rs b/src/test/auxiliary/nested_item.rs
index 21784bda27a..fc1bea5a9fd 100644
--- a/src/test/auxiliary/nested_item.rs
+++ b/src/test/auxiliary/nested_item.rs
@@ -25,7 +25,7 @@ impl Foo {
}
// 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'];
diff --git a/src/test/auxiliary/orphan_check_diagnostics.rs b/src/test/auxiliary/orphan_check_diagnostics.rs
index 7647f159401..cf3e9903b5a 100644
--- a/src/test/auxiliary/orphan_check_diagnostics.rs
+++ b/src/test/auxiliary/orphan_check_diagnostics.rs
@@ -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) { } }
diff --git a/src/test/auxiliary/overloaded_autoderef_xc.rs b/src/test/auxiliary/overloaded_autoderef_xc.rs
index caa9bbe5736..3c8cba13ae7 100644
--- a/src/test/auxiliary/overloaded_autoderef_xc.rs
+++ b/src/test/auxiliary/overloaded_autoderef_xc.rs
@@ -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 @@ impl<T, H: Helper<T>> Deref for DerefWithHelper<H, 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)
}
diff --git a/src/test/auxiliary/plugin_args.rs b/src/test/auxiliary/plugin_args.rs
index 907d80b50db..d0ab944813a 100644
--- a/src/test/auxiliary/plugin_args.rs
+++ b/src/test/auxiliary/plugin_args.rs
@@ -37,7 +37,7 @@ impl TTMacroExpander for Expander {
_: &[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))
}
}
diff --git a/src/test/auxiliary/private_trait_xc.rs b/src/test/auxiliary/private_trait_xc.rs
index 37ee10c8d37..42691579491 100644
--- a/src/test/auxiliary/private_trait_xc.rs
+++ b/src/test/auxiliary/private_trait_xc.rs
@@ -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 {}
diff --git a/src/test/auxiliary/svh-a-base.rs b/src/test/auxiliary/svh-a-base.rs
index 12833daf604..04f1062c16f 100644
--- a/src/test/auxiliary/svh-a-base.rs
+++ b/src/test/auxiliary/svh-a-base.rs
@@ -15,12 +15,14 @@
#![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 () {}
diff --git a/src/test/auxiliary/svh-a-change-lit.rs b/src/test/auxiliary/svh-a-change-lit.rs
index 9e74bf28135..fabd2289e9a 100644
--- a/src/test/auxiliary/svh-a-change-lit.rs
+++ b/src/test/auxiliary/svh-a-change-lit.rs
@@ -15,12 +15,14 @@
#![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 () {}
diff --git a/src/test/auxiliary/svh-a-change-significant-cfg.rs b/src/test/auxiliary/svh-a-change-significant-cfg.rs
index c900550041b..3fdb861bd40 100644
--- a/src/test/auxiliary/svh-a-change-significant-cfg.rs
+++ b/src/test/auxiliary/svh-a-change-significant-cfg.rs
@@ -15,12 +15,14 @@
#![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 () {}
diff --git a/src/test/auxiliary/svh-a-change-trait-bound.rs b/src/test/auxiliary/svh-a-change-trait-bound.rs
index 04f8eb3cf9b..3116d24673d 100644
--- a/src/test/auxiliary/svh-a-change-trait-bound.rs
+++ b/src/test/auxiliary/svh-a-change-trait-bound.rs
@@ -15,12 +15,14 @@
#![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 () {}
diff --git a/src/test/auxiliary/svh-a-change-type-arg.rs b/src/test/auxiliary/svh-a-change-type-arg.rs
index c7e0a18768a..b49a1533628 100644
--- a/src/test/auxiliary/svh-a-change-type-arg.rs
+++ b/src/test/auxiliary/svh-a-change-type-arg.rs
@@ -15,12 +15,14 @@
#![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 () {}
diff --git a/src/test/auxiliary/svh-a-change-type-ret.rs b/src/test/auxiliary/svh-a-change-type-ret.rs
index 5100af32318..6562a93135f 100644
--- a/src/test/auxiliary/svh-a-change-type-ret.rs
+++ b/src/test/auxiliary/svh-a-change-type-ret.rs
@@ -15,12 +15,14 @@
#![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 () {}
diff --git a/src/test/auxiliary/svh-a-change-type-static.rs b/src/test/auxiliary/svh-a-change-type-static.rs
index 077c33cb90d..c7b392c6ee8 100644
--- a/src/test/auxiliary/svh-a-change-type-static.rs
+++ b/src/test/auxiliary/svh-a-change-type-static.rs
@@ -15,12 +15,14 @@
#![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 () {}
diff --git a/src/test/auxiliary/svh-a-comment.rs b/src/test/auxiliary/svh-a-comment.rs
index d481fa5a1fa..450f6102026 100644
--- a/src/test/auxiliary/svh-a-comment.rs
+++ b/src/test/auxiliary/svh-a-comment.rs
@@ -15,12 +15,14 @@
#![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 () {}
diff --git a/src/test/auxiliary/svh-a-doc.rs b/src/test/auxiliary/svh-a-doc.rs
index 9e99a355ac1..c000737c854 100644
--- a/src/test/auxiliary/svh-a-doc.rs
+++ b/src/test/auxiliary/svh-a-doc.rs
@@ -15,12 +15,14 @@
#![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 () {}
diff --git a/src/test/auxiliary/svh-a-macro.rs b/src/test/auxiliary/svh-a-macro.rs
index b8dd497ac99..1e12659dc4b 100644
--- a/src/test/auxiliary/svh-a-macro.rs
+++ b/src/test/auxiliary/svh-a-macro.rs
@@ -15,12 +15,14 @@
#![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 () {}
diff --git a/src/test/auxiliary/svh-a-no-change.rs b/src/test/auxiliary/svh-a-no-change.rs
index 12833daf604..04f1062c16f 100644
--- a/src/test/auxiliary/svh-a-no-change.rs
+++ b/src/test/auxiliary/svh-a-no-change.rs
@@ -15,12 +15,14 @@
#![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 () {}
diff --git a/src/test/auxiliary/svh-a-redundant-cfg.rs b/src/test/auxiliary/svh-a-redundant-cfg.rs
index 690ddc670f5..1e82b74f1ef 100644
--- a/src/test/auxiliary/svh-a-redundant-cfg.rs
+++ b/src/test/auxiliary/svh-a-redundant-cfg.rs
@@ -15,12 +15,14 @@
#![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 () {}
diff --git a/src/test/auxiliary/svh-a-whitespace.rs b/src/test/auxiliary/svh-a-whitespace.rs
index 216e8e997f2..3c3dac9cdab 100644
--- a/src/test/auxiliary/svh-a-whitespace.rs
+++ b/src/test/auxiliary/svh-a-whitespace.rs
@@ -15,12 +15,14 @@
#![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 () {}
diff --git a/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs b/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs
index 1695e474de9..a7c469fccaa 100644
--- a/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs
+++ b/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs
@@ -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,
diff --git a/src/test/auxiliary/trait_impl_conflict.rs b/src/test/auxiliary/trait_impl_conflict.rs
index 990bc216049..0982efbdbf4 100644
--- a/src/test/auxiliary/trait_impl_conflict.rs
+++ b/src/test/auxiliary/trait_impl_conflict.rs
@@ -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 {
diff --git a/src/test/auxiliary/use_from_trait_xc.rs b/src/test/auxiliary/use_from_trait_xc.rs
index 22e0d3168ca..56fb40bc0a4 100644
--- a/src/test/auxiliary/use_from_trait_xc.rs
+++ b/src/test/auxiliary/use_from_trait_xc.rs
@@ -11,7 +11,7 @@
pub use self::sub::{Bar, Baz};
pub trait Trait {
- fn foo();
+ fn foo(&self);
}
struct Foo;
diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs
index 1d440c4540c..994c9605fc3 100644
--- a/src/test/bench/core-set.rs
+++ b/src/test/bench/core-set.rs
@@ -16,9 +16,8 @@ extern crate collections;
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);
}
}
diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs
index fd559608011..2c640c4b092 100644
--- a/src/test/bench/shootout-fasta.rs
+++ b/src/test/bench/shootout-fasta.rs
@@ -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",
diff --git a/src/test/bench/shootout-meteor.rs b/src/test/bench/shootout-meteor.rs
index 73dce2910c9..a94fe0ccd95 100644
--- a/src/test/bench/shootout-meteor.rs
+++ b/src/test/bench/shootout-meteor.rs
@@ -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/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
index 621f5ec9660..edd1b8255cc 100644
--- a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
+++ b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
@@ -16,8 +16,12 @@
#![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.
}
diff --git a/src/test/compile-fail/associated-types-coherence-failure.rs b/src/test/compile-fail/associated-types-coherence-failure.rs
index 95a68dd6698..b7a16c68a34 100644
--- a/src/test/compile-fail/associated-types-coherence-failure.rs
+++ b/src/test/compile-fail/associated-types-coherence-failure.rs
@@ -11,9 +11,10 @@
// 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> {
diff --git a/src/test/compile-fail/associated-types-eq-expr-path.rs b/src/test/compile-fail/associated-types-eq-expr-path.rs
index 9baa7f1ad5a..c48f9972ebc 100644
--- a/src/test/compile-fail/associated-types-eq-expr-path.rs
+++ b/src/test/compile-fail/associated-types-eq-expr-path.rs
@@ -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/associated-types-issue-17359.rs b/src/test/compile-fail/associated-types-issue-17359.rs
index fa09ae793bf..625f4cdb8ef 100644
--- a/src/test/compile-fail/associated-types-issue-17359.rs
+++ b/src/test/compile-fail/associated-types-issue-17359.rs
@@ -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;
}
diff --git a/src/test/compile-fail/associated-types-multiple-types-one-trait.rs b/src/test/compile-fail/associated-types-multiple-types-one-trait.rs
index 9436f825de8..5632f148da6 100644
--- a/src/test/compile-fail/associated-types-multiple-types-one-trait.rs
+++ b/src/test/compile-fail/associated-types-multiple-types-one-trait.rs
@@ -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;
}
diff --git a/src/test/compile-fail/associated-types-no-suitable-supertrait.rs b/src/test/compile-fail/associated-types-no-suitable-supertrait.rs
index a3f2850b294..2b84c38f80b 100644
--- a/src/test/compile-fail/associated-types-no-suitable-supertrait.rs
+++ b/src/test/compile-fail/associated-types-no-suitable-supertrait.rs
@@ -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;
}
diff --git a/src/test/compile-fail/associated-types-path-2.rs b/src/test/compile-fail/associated-types-path-2.rs
index 51a37b517dd..b9a62ff4e41 100644
--- a/src/test/compile-fail/associated-types-path-2.rs
+++ b/src/test/compile-fail/associated-types-path-2.rs
@@ -12,6 +12,8 @@
pub trait Foo {
type A;
+
+ fn dummy(&self) { }
}
impl Foo for i32 {
diff --git a/src/test/compile-fail/associated-types-unconstrained.rs b/src/test/compile-fail/associated-types-unconstrained.rs
index aecbf217a5b..8832028f9ab 100644
--- a/src/test/compile-fail/associated-types-unconstrained.rs
+++ b/src/test/compile-fail/associated-types-unconstrained.rs
@@ -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/bad-mid-path-type-params.rs b/src/test/compile-fail/bad-mid-path-type-params.rs
index c91849ca53e..3e02a11c378 100644
--- a/src/test/compile-fail/bad-mid-path-type-params.rs
+++ b/src/test/compile-fail/bad-mid-path-type-params.rs
@@ -10,13 +10,6 @@
// ignore-tidy-linelength
-#![feature(no_std)]
-#![no_std]
-#![feature(lang_items)]
-
-#[lang="sized"]
-pub trait Sized {}
-
struct S<T> {
contents: T,
}
diff --git a/src/test/compile-fail/bad-sized.rs b/src/test/compile-fail/bad-sized.rs
index 69be6414e4c..1944acbe1f3 100644
--- a/src/test/compile-fail/bad-sized.rs
+++ b/src/test/compile-fail/bad-sized.rs
@@ -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/coherence-blanket-conflicts-with-blanket-implemented.rs b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs
index 27d97d18c94..d4decb71349 100644
--- a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs
+++ b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs
@@ -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 { }
diff --git a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs
index 0f233b78c72..b1ee1762b6e 100644
--- a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs
+++ b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs
@@ -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 }
diff --git a/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs b/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs
index c9dfb8201a9..a225f6cf473 100644
--- a/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs
+++ b/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs
@@ -10,18 +10,18 @@
#![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
index 00000000000..897cb083f84
--- /dev/null
+++ b/src/test/compile-fail/coherence-subtyping.rs
@@ -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() { }
diff --git a/src/test/compile-fail/cross-borrow-trait.rs b/src/test/compile-fail/cross-borrow-trait.rs
index 86b7a8c8918..6bd21101a60 100644
--- a/src/test/compile-fail/cross-borrow-trait.rs
+++ b/src/test/compile-fail/cross-borrow-trait.rs
@@ -14,7 +14,7 @@
#![feature(box_syntax)]
struct Foo;
-trait Trait {}
+trait Trait { fn foo(&self) {} }
impl Trait for Foo {}
pub fn main() {
diff --git a/src/test/compile-fail/destructure-trait-ref.rs b/src/test/compile-fail/destructure-trait-ref.rs
index f2e068cc4ff..4161cce2843 100644
--- a/src/test/compile-fail/destructure-trait-ref.rs
+++ b/src/test/compile-fail/destructure-trait-ref.rs
@@ -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/dst-bad-coerce1.rs b/src/test/compile-fail/dst-bad-coerce1.rs
index 2b96c5ebe12..ddc92901771 100644
--- a/src/test/compile-fail/dst-bad-coerce1.rs
+++ b/src/test/compile-fail/dst-bad-coerce1.rs
@@ -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.
diff --git a/src/test/compile-fail/dst-bad-coerce2.rs b/src/test/compile-fail/dst-bad-coerce2.rs
index 160197368d6..aa687266acb 100644
--- a/src/test/compile-fail/dst-bad-coerce2.rs
+++ b/src/test/compile-fail/dst-bad-coerce2.rs
@@ -15,7 +15,7 @@ struct Fat<T: ?Sized> {
}
struct Foo;
-trait Bar {}
+trait Bar : ::std::marker::MarkerTrait {}
impl Bar for Foo {}
pub fn main() {
diff --git a/src/test/compile-fail/dst-bad-coerce3.rs b/src/test/compile-fail/dst-bad-coerce3.rs
index 347a2d2ecbe..7bad3bd69d3 100644
--- a/src/test/compile-fail/dst-bad-coerce3.rs
+++ b/src/test/compile-fail/dst-bad-coerce3.rs
@@ -15,7 +15,7 @@ struct Fat<T: ?Sized> {
}
struct Foo;
-trait Bar {}
+trait Bar { fn bar(&self) {} }
impl Bar for Foo {}
fn baz<'a>() {
diff --git a/src/test/compile-fail/dst-bad-coercions.rs b/src/test/compile-fail/dst-bad-coercions.rs
index b30eada162b..8ec1034bc4d 100644
--- a/src/test/compile-fail/dst-bad-coercions.rs
+++ b/src/test/compile-fail/dst-bad-coercions.rs
@@ -10,8 +10,10 @@
// 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> {
diff --git a/src/test/compile-fail/dst-object-from-unsized-type.rs b/src/test/compile-fail/dst-object-from-unsized-type.rs
index 87ff4291f50..b4fd45845f7 100644
--- a/src/test/compile-fail/dst-object-from-unsized-type.rs
+++ b/src/test/compile-fail/dst-object-from-unsized-type.rs
@@ -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) {
diff --git a/src/test/compile-fail/exclusive-drop-and-copy.rs b/src/test/compile-fail/exclusive-drop-and-copy.rs
index 17453bc677f..f47f14d5879 100644
--- a/src/test/compile-fail/exclusive-drop-and-copy.rs
+++ b/src/test/compile-fail/exclusive-drop-and-copy.rs
@@ -20,7 +20,7 @@ impl Drop for Foo {
}
#[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/generic-impl-less-params-with-defaults.rs b/src/test/compile-fail/generic-impl-less-params-with-defaults.rs
index 02f09749d61..9fea5e609d1 100644
--- a/src/test/compile-fail/generic-impl-less-params-with-defaults.rs
+++ b/src/test/compile-fail/generic-impl-less-params-with-defaults.rs
@@ -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() {
diff --git a/src/test/compile-fail/generic-impl-more-params-with-defaults.rs b/src/test/compile-fail/generic-impl-more-params-with-defaults.rs
index d88da2625c1..73c19aa012d 100644
--- a/src/test/compile-fail/generic-impl-more-params-with-defaults.rs
+++ b/src/test/compile-fail/generic-impl-more-params-with-defaults.rs
@@ -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() {
diff --git a/src/test/compile-fail/generic-lifetime-trait-impl.rs b/src/test/compile-fail/generic-lifetime-trait-impl.rs
index fc54002820e..9b9f09f4777 100644
--- a/src/test/compile-fail/generic-lifetime-trait-impl.rs
+++ b/src/test/compile-fail/generic-lifetime-trait-impl.rs
@@ -16,9 +16,12 @@
//
// 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-type-less-params-with-defaults.rs b/src/test/compile-fail/generic-type-less-params-with-defaults.rs
index f25d8f99b8d..37737fda474 100644
--- a/src/test/compile-fail/generic-type-less-params-with-defaults.rs
+++ b/src/test/compile-fail/generic-type-less-params-with-defaults.rs
@@ -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
diff --git a/src/test/compile-fail/generic-type-more-params-with-defaults.rs b/src/test/compile-fail/generic-type-more-params-with-defaults.rs
index 19d303488ac..ad7e4f190c5 100644
--- a/src/test/compile-fail/generic-type-more-params-with-defaults.rs
+++ b/src/test/compile-fail/generic-type-more-params-with-defaults.rs
@@ -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>;
diff --git a/src/test/compile-fail/generic-type-params-name-repr.rs b/src/test/compile-fail/generic-type-params-name-repr.rs
index 3e34344d78b..a452cd35f94 100644
--- a/src/test/compile-fail/generic-type-params-name-repr.rs
+++ b/src/test/compile-fail/generic-type-params-name-repr.rs
@@ -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/issue-11515.rs b/src/test/compile-fail/issue-11515.rs
index f0089b0ae5b..4ff574e939d 100644
--- a/src/test/compile-fail/issue-11515.rs
+++ b/src/test/compile-fail/issue-11515.rs
@@ -10,7 +10,7 @@
#![feature(box_syntax)]
-struct Test<'s> {
+struct Test {
func: Box<FnMut()+'static>
}
diff --git a/src/test/compile-fail/issue-13853-2.rs b/src/test/compile-fail/issue-13853-2.rs
index ea0d880f4a1..dc697e4784f 100644
--- a/src/test/compile-fail/issue-13853-2.rs
+++ b/src/test/compile-fail/issue-13853-2.rs
@@ -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);
}
diff --git a/src/test/compile-fail/issue-13853-3.rs b/src/test/compile-fail/issue-13853-3.rs
index f10c47b594e..7ca158c3e32 100644
--- a/src/test/compile-fail/issue-13853-3.rs
+++ b/src/test/compile-fail/issue-13853-3.rs
@@ -10,6 +10,8 @@
#![crate_type = "lib"]
+use std::marker::PhantomData;
+
enum NodeContents<'a> {
Children(Vec<Node<'a>>),
}
@@ -22,11 +24,12 @@ impl<'a> Drop for NodeContents<'a> {
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 }
}
}
diff --git a/src/test/compile-fail/issue-13853.rs b/src/test/compile-fail/issue-13853.rs
index 251da2c6b3e..cd3f337c4ab 100644
--- a/src/test/compile-fail/issue-13853.rs
+++ b/src/test/compile-fail/issue-13853.rs
@@ -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-14285.rs b/src/test/compile-fail/issue-14285.rs
index cbf4412a81d..3a5df9e805b 100644
--- a/src/test/compile-fail/issue-14285.rs
+++ b/src/test/compile-fail/issue-14285.rs
@@ -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;
diff --git a/src/test/compile-fail/issue-14853.rs b/src/test/compile-fail/issue-14853.rs
index 51deb99a4f2..0b846651acf 100644
--- a/src/test/compile-fail/issue-14853.rs
+++ b/src/test/compile-fail/issue-14853.rs
@@ -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]);
diff --git a/src/test/compile-fail/issue-16747.rs b/src/test/compile-fail/issue-16747.rs
index 814b885e3aa..a213234b89b 100644
--- a/src/test/compile-fail/issue-16747.rs
+++ b/src/test/compile-fail/issue-16747.rs
@@ -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-17431-4.rs b/src/test/compile-fail/issue-17431-4.rs
index 1e27f025564..22aaa796ad0 100644
--- a/src/test/compile-fail/issue-17431-4.rs
+++ b/src/test/compile-fail/issue-17431-4.rs
@@ -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) {} }
diff --git a/src/test/compile-fail/issue-17431-5.rs b/src/test/compile-fail/issue-17431-5.rs
index d22d79ecaa5..cc9cc2e3c03 100644
--- a/src/test/compile-fail/issue-17431-5.rs
+++ b/src/test/compile-fail/issue-17431-5.rs
@@ -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) {} }
diff --git a/src/test/compile-fail/issue-17551.rs b/src/test/compile-fail/issue-17551.rs
index e037ba92b4a..5781cb74117 100644
--- a/src/test/compile-fail/issue-17551.rs
+++ b/src/test/compile-fail/issue-17551.rs
@@ -10,9 +10,11 @@
#![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-17904-2.rs b/src/test/compile-fail/issue-17904-2.rs
new file mode 100644
index 00000000000..a33ec23a16a
--- /dev/null
+++ b/src/test/compile-fail/issue-17904-2.rs
@@ -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-18107.rs b/src/test/compile-fail/issue-18107.rs
index 91689988f58..d5fb22bdebd 100644
--- a/src/test/compile-fail/issue-18107.rs
+++ b/src/test/compile-fail/issue-18107.rs
@@ -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
diff --git a/src/test/compile-fail/issue-18611.rs b/src/test/compile-fail/issue-18611.rs
index a662e9ca98e..e81a576fa63 100644
--- a/src/test/compile-fail/issue-18611.rs
+++ b/src/test/compile-fail/issue-18611.rs
@@ -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;
}
diff --git a/src/test/compile-fail/issue-18783.rs b/src/test/compile-fail/issue-18783.rs
index 5ddf06add9d..13908bda9d8 100644
--- a/src/test/compile-fail/issue-18783.rs
+++ b/src/test/compile-fail/issue-18783.rs
@@ -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> {
diff --git a/src/test/compile-fail/issue-18819.rs b/src/test/compile-fail/issue-18819.rs
index 3a9de741043..951d78410b8 100644
--- a/src/test/compile-fail/issue-18819.rs
+++ b/src/test/compile-fail/issue-18819.rs
@@ -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;
}
diff --git a/src/test/compile-fail/issue-19660.rs b/src/test/compile-fail/issue-19660.rs
index 14601e67a77..77aba7335bd 100644
--- a/src/test/compile-fail/issue-19660.rs
+++ b/src/test/compile-fail/issue-19660.rs
@@ -13,8 +13,12 @@
#![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 {
diff --git a/src/test/compile-fail/issue-2063.rs b/src/test/compile-fail/issue-2063.rs
index 00607f85034..aed395d17ea 100644
--- a/src/test/compile-fail/issue-2063.rs
+++ b/src/test/compile-fail/issue-2063.rs
@@ -12,10 +12,11 @@
// 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;
}
diff --git a/src/test/compile-fail/issue-20831-debruijn.rs b/src/test/compile-fail/issue-20831-debruijn.rs
index aaf45f27398..5b623ac377b 100644
--- a/src/test/compile-fail/issue-20831-debruijn.rs
+++ b/src/test/compile-fail/issue-20831-debruijn.rs
@@ -13,10 +13,11 @@
// 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;
}
diff --git a/src/test/compile-fail/issue-21160.rs b/src/test/compile-fail/issue-21160.rs
index 45b7fbbd0b4..557bf518a3c 100644
--- a/src/test/compile-fail/issue-21160.rs
+++ b/src/test/compile-fail/issue-21160.rs
@@ -16,6 +16,6 @@ impl Bar {
#[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() {}
diff --git a/src/test/compile-fail/issue-2611-4.rs b/src/test/compile-fail/issue-2611-4.rs
index 31796e5e20c..24cc0099b89 100644
--- a/src/test/compile-fail/issue-2611-4.rs
+++ b/src/test/compile-fail/issue-2611-4.rs
@@ -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
}
diff --git a/src/test/compile-fail/issue-3008-3.rs b/src/test/compile-fail/issue-3008-3.rs
index a338a01690d..af6cee1f107 100644
--- a/src/test/compile-fail/issue-3008-3.rs
+++ b/src/test/compile-fail/issue-3008-3.rs
@@ -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) {} }
diff --git a/src/test/compile-fail/issue-4972.rs b/src/test/compile-fail/issue-4972.rs
index 9a398796d2a..f384dba7c9e 100644
--- a/src/test/compile-fail/issue-4972.rs
+++ b/src/test/compile-fail/issue-4972.rs
@@ -11,7 +11,9 @@
#![feature(box_patterns)]
#![feature(box_syntax)]
-trait MyTrait { }
+trait MyTrait {
+ fn dummy(&self) {}
+}
pub enum TraitWrapper {
A(Box<MyTrait+'static>),
diff --git a/src/test/compile-fail/issue-5035-2.rs b/src/test/compile-fail/issue-5035-2.rs
index 9e324cdd61e..d316b44794a 100644
--- a/src/test/compile-fail/issue-5035-2.rs
+++ b/src/test/compile-fail/issue-5035-2.rs
@@ -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
diff --git a/src/test/compile-fail/issue-5543.rs b/src/test/compile-fail/issue-5543.rs
index cf98f1572e5..4d721ad7666 100644
--- a/src/test/compile-fail/issue-5543.rs
+++ b/src/test/compile-fail/issue-5543.rs
@@ -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-5883.rs b/src/test/compile-fail/issue-5883.rs
index 9ff957b6e6d..b0db9906195 100644
--- a/src/test/compile-fail/issue-5883.rs
+++ b/src/test/compile-fail/issue-5883.rs
@@ -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() {}
diff --git a/src/test/compile-fail/issue-6458.rs b/src/test/compile-fail/issue-6458.rs
index efa3100360b..0bf9a3c2d48 100644
--- a/src/test/compile-fail/issue-6458.rs
+++ b/src/test/compile-fail/issue-6458.rs
@@ -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() {
diff --git a/src/test/compile-fail/issue-7575.rs b/src/test/compile-fail/issue-7575.rs
index 9e6000c050a..b6643f43952 100644
--- a/src/test/compile-fail/issue-7575.rs
+++ b/src/test/compile-fail/issue-7575.rs
@@ -10,12 +10,14 @@
// 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 @@ impl Myisize {
}
}
-trait ManyImplTrait {
+trait ManyImplTrait : MarkerTrait {
fn is_str() -> bool { //~ NOTE candidate
false
}
diff --git a/src/test/compile-fail/issue-8727.rs b/src/test/compile-fail/issue-8727.rs
index d1a86d334cb..72da6dcaa6c 100644
--- a/src/test/compile-fail/issue-8727.rs
+++ b/src/test/compile-fail/issue-8727.rs
@@ -13,16 +13,12 @@
// 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/kindck-copy.rs b/src/test/compile-fail/kindck-copy.rs
index 56f83d93008..74e372e41eb 100644
--- a/src/test/compile-fail/kindck-copy.rs
+++ b/src/test/compile-fail/kindck-copy.rs
@@ -10,12 +10,12 @@
// 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 {
diff --git a/src/test/compile-fail/kindck-impl-type-params-2.rs b/src/test/compile-fail/kindck-impl-type-params-2.rs
index 2731be7308a..b575144f637 100644
--- a/src/test/compile-fail/kindck-impl-type-params-2.rs
+++ b/src/test/compile-fail/kindck-impl-type-params-2.rs
@@ -10,7 +10,9 @@
#![feature(box_syntax)]
-trait Foo {
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait {
}
impl<T:Copy> Foo for T {
diff --git a/src/test/compile-fail/kindck-impl-type-params.rs b/src/test/compile-fail/kindck-impl-type-params.rs
index d5276efa8be..dffc8fa2abd 100644
--- a/src/test/compile-fail/kindck-impl-type-params.rs
+++ b/src/test/compile-fail/kindck-impl-type-params.rs
@@ -13,40 +13,44 @@
#![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
}
diff --git a/src/test/compile-fail/kindck-inherited-copy-bound.rs b/src/test/compile-fail/kindck-inherited-copy-bound.rs
index e146cac21a3..0072b1228af 100644
--- a/src/test/compile-fail/kindck-inherited-copy-bound.rs
+++ b/src/test/compile-fail/kindck-inherited-copy-bound.rs
@@ -15,6 +15,7 @@
use std::any::Any;
trait Foo : Copy {
+ fn foo(&self) {}
}
impl<T:Copy> Foo for T {
diff --git a/src/test/compile-fail/kindck-send-object.rs b/src/test/compile-fail/kindck-send-object.rs
index 570f7ad7fe3..0c68401bb2b 100644
--- a/src/test/compile-fail/kindck-send-object.rs
+++ b/src/test/compile-fail/kindck-send-object.rs
@@ -12,8 +12,10 @@
// 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...
diff --git a/src/test/compile-fail/kindck-send-object1.rs b/src/test/compile-fail/kindck-send-object1.rs
index 48d5215b708..f86eac8b16b 100644
--- a/src/test/compile-fail/kindck-send-object1.rs
+++ b/src/test/compile-fail/kindck-send-object1.rs
@@ -12,8 +12,10 @@
// 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>() {
diff --git a/src/test/compile-fail/kindck-send-object2.rs b/src/test/compile-fail/kindck-send-object2.rs
index d3d166e2a69..08516e67318 100644
--- a/src/test/compile-fail/kindck-send-object2.rs
+++ b/src/test/compile-fail/kindck-send-object2.rs
@@ -10,8 +10,10 @@
// 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/lifetime-inference-give-expl-lifetime-param-3.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs
index 04c5b223cb8..66d8927ee51 100644
--- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs
+++ b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs
@@ -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)
diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs
index c60e321219b..a85776a938b 100644
--- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs
+++ b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs
@@ -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/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs
index 3b96fd64fa2..73a58741bbb 100644
--- a/src/test/compile-fail/lint-missing-doc.rs
+++ b/src/test/compile-fail/lint-missing-doc.rs
@@ -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() {}
diff --git a/src/test/compile-fail/lint-non-camel-case-types.rs b/src/test/compile-fail/lint-non-camel-case-types.rs
index 70d6b240985..9f58d5791cb 100644
--- a/src/test/compile-fail/lint-non-camel-case-types.rs
+++ b/src/test/compile-fail/lint-non-camel-case-types.rs
@@ -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`
diff --git a/src/test/compile-fail/lint-stability.rs b/src/test/compile-fail/lint-stability.rs
index f9cdfa4f7d6..88f2cbdea6d 100644
--- a/src/test/compile-fail/lint-stability.rs
+++ b/src/test/compile-fail/lint-stability.rs
@@ -341,7 +341,9 @@ mod this_crate {
#[unstable(feature = "test_feature")]
#[deprecated(since = "1.0.0")]
- pub trait DeprecatedTrait {}
+ pub trait DeprecatedTrait {
+ fn dummy(&self) { }
+ }
struct S;
diff --git a/src/test/compile-fail/lint-visible-private-types.rs b/src/test/compile-fail/lint-visible-private-types.rs
index 8cf375f80fb..918b4ee209c 100644
--- a/src/test/compile-fail/lint-visible-private-types.rs
+++ b/src/test/compile-fail/lint-visible-private-types.rs
@@ -12,8 +12,10 @@
#![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;
}
diff --git a/src/test/compile-fail/liveness-use-after-send.rs b/src/test/compile-fail/liveness-use-after-send.rs
index a49339ecd7f..03d8d62e0b4 100644
--- a/src/test/compile-fail/liveness-use-after-send.rs
+++ b/src/test/compile-fail/liveness-use-after-send.rs
@@ -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/map-types.rs b/src/test/compile-fail/map-types.rs
index ba2205f5868..6e8719eeace 100644
--- a/src/test/compile-fail/map-types.rs
+++ b/src/test/compile-fail/map-types.rs
@@ -14,7 +14,10 @@ extern crate collections;
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
index cb5da4bb547..00000000000
--- a/src/test/compile-fail/method-ambig-one-trait-coerce.rs
+++ /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/parse-fail/mod_file_disambig.rs b/src/test/compile-fail/mod_file_disambig.rs
index 48bd00a3ee0..48bd00a3ee0 100644
--- a/src/test/parse-fail/mod_file_disambig.rs
+++ b/src/test/compile-fail/mod_file_disambig.rs
diff --git a/src/test/parse-fail/mod_file_not_owning.rs b/src/test/compile-fail/mod_file_not_owning.rs
index adbcedd91f2..adbcedd91f2 100644
--- a/src/test/parse-fail/mod_file_not_owning.rs
+++ b/src/test/compile-fail/mod_file_not_owning.rs
diff --git a/src/test/compile-fail/object-does-not-impl-trait.rs b/src/test/compile-fail/object-does-not-impl-trait.rs
index cfaf149a49c..607ab13d122 100644
--- a/src/test/compile-fail/object-does-not-impl-trait.rs
+++ b/src/test/compile-fail/object-does-not-impl-trait.rs
@@ -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
diff --git a/src/test/compile-fail/object-lifetime-default-mybox.rs b/src/test/compile-fail/object-lifetime-default-mybox.rs
index c107c8d131d..23ddea4499a 100644
--- a/src/test/compile-fail/object-lifetime-default-mybox.rs
+++ b/src/test/compile-fail/object-lifetime-default-mybox.rs
@@ -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
index 00000000000..edf32131b68
--- /dev/null
+++ b/src/test/compile-fail/object-safety-issue-22040.rs
@@ -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);
+}
diff --git a/src/test/compile-fail/object-safety-no-static.rs b/src/test/compile-fail/object-safety-no-static.rs
index 6a010d49692..aae829ec7b5 100644
--- a/src/test/compile-fail/object-safety-no-static.rs
+++ b/src/test/compile-fail/object-safety-no-static.rs
@@ -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
index 00000000000..1c95ee43d27
--- /dev/null
+++ b/src/test/compile-fail/object-safety-phantom-fn.rs
@@ -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
index 00000000000..d3f9dc73020
--- /dev/null
+++ b/src/test/compile-fail/object-safety-supertrait-mentions-Self.rs
@@ -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/on-unimplemented-bad-anno.rs b/src/test/compile-fail/on-unimplemented-bad-anno.rs
index dda534cc489..7538b1c85e5 100644
--- a/src/test/compile-fail/on-unimplemented-bad-anno.rs
+++ b/src/test/compile-fail/on-unimplemented-bad-anno.rs
@@ -13,8 +13,12 @@
#![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() {
}
diff --git a/src/test/compile-fail/on-unimplemented.rs b/src/test/compile-fail/on-unimplemented.rs
index 7b406afcf1f..2447d086422 100644
--- a/src/test/compile-fail/on-unimplemented.rs
+++ b/src/test/compile-fail/on-unimplemented.rs
@@ -11,8 +11,12 @@
#![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 {
diff --git a/src/test/compile-fail/orphan-check-diagnostics.rs b/src/test/compile-fail/orphan-check-diagnostics.rs
index ff5c101b917..8201565c331 100644
--- a/src/test/compile-fail/orphan-check-diagnostics.rs
+++ b/src/test/compile-fail/orphan-check-diagnostics.rs
@@ -15,7 +15,7 @@ extern crate orphan_check_diagnostics;
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
diff --git a/src/test/compile-fail/priv-in-bad-locations.rs b/src/test/compile-fail/priv-in-bad-locations.rs
index db649ed0cc6..43d112b8aa0 100644
--- a/src/test/compile-fail/priv-in-bad-locations.rs
+++ b/src/test/compile-fail/priv-in-bad-locations.rs
@@ -14,7 +14,7 @@ pub extern {
}
trait A {
- fn foo() {}
+ fn foo(&self) {}
}
struct B;
@@ -22,7 +22,7 @@ struct B;
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() {}
diff --git a/src/test/compile-fail/privacy-ns2.rs b/src/test/compile-fail/privacy-ns2.rs
index 7fe0574ab7d..67bb566ea68 100644
--- a/src/test/compile-fail/privacy-ns2.rs
+++ b/src/test/compile-fail/privacy-ns2.rs
@@ -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;
diff --git a/src/test/compile-fail/privacy1.rs b/src/test/compile-fail/privacy1.rs
index 7ebbcc2809a..1ae79adbad7 100644
--- a/src/test/compile-fail/privacy1.rs
+++ b/src/test/compile-fail/privacy1.rs
@@ -11,11 +11,15 @@
#![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
diff --git a/src/test/compile-fail/privacy4.rs b/src/test/compile-fail/privacy4.rs
index bcb46663aa8..adce93af079 100644
--- a/src/test/compile-fail/privacy4.rs
+++ b/src/test/compile-fail/privacy4.rs
@@ -11,8 +11,12 @@
#![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/region-object-lifetime-in-coercion.rs b/src/test/compile-fail/region-object-lifetime-in-coercion.rs
index 20cc624ab19..2da414befd8 100644
--- a/src/test/compile-fail/region-object-lifetime-in-coercion.rs
+++ b/src/test/compile-fail/region-object-lifetime-in-coercion.rs
@@ -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> {
diff --git a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs
index fa26c9c54c8..6aa0cc003ce 100644
--- a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs
+++ b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs
@@ -15,15 +15,12 @@
#![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 {
diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs
index 7d955065ff4..9736910d7b5 100644
--- a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs
+++ b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs
@@ -14,12 +14,12 @@
#![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> {
diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs
index 6ee65fbdf91..da7546ce21c 100644
--- a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs
+++ b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs
@@ -15,15 +15,12 @@
#![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> {
diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-outlives-container.rs
index 49a0726fa3b..e1e72e6f56e 100644
--- a/src/test/compile-fail/regions-assoc-type-outlives-container.rs
+++ b/src/test/compile-fail/regions-assoc-type-outlives-container.rs
@@ -13,16 +13,14 @@
// 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> {
diff --git a/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs b/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs
index f833361e3b5..f921eccef1f 100644
--- a/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs
+++ b/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs
@@ -11,7 +11,10 @@
// 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.
diff --git a/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs b/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs
index 0871d8b01f6..1cf83b8ac58 100644
--- a/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs
+++ b/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs
@@ -11,7 +11,10 @@
// 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
diff --git a/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs b/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs
index a3c38dff6b0..278ccd3c119 100644
--- a/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs
+++ b/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs
@@ -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 @@ impl<'a, 't> Foo<'a, 't> for &'a isize {
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() { }
diff --git a/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs b/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs
index 74c2c6e584b..f13d8a60894 100644
--- a/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs
+++ b/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs
@@ -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
}
diff --git a/src/test/compile-fail/regions-close-associated-type-into-object.rs b/src/test/compile-fail/regions-close-associated-type-into-object.rs
index 8a03f36972d..979c1e997d0 100644
--- a/src/test/compile-fail/regions-close-associated-type-into-object.rs
+++ b/src/test/compile-fail/regions-close-associated-type-into-object.rs
@@ -10,7 +10,9 @@
#![feature(box_syntax)]
-trait X {}
+use std::marker::MarkerTrait;
+
+trait X : MarkerTrait {}
trait Iter {
type Item: X;
diff --git a/src/test/compile-fail/regions-close-object-into-object-1.rs b/src/test/compile-fail/regions-close-object-into-object-1.rs
index 7a0e3cf4611..7bbce7dad53 100644
--- a/src/test/compile-fail/regions-close-object-into-object-1.rs
+++ b/src/test/compile-fail/regions-close-object-into-object-1.rs
@@ -11,13 +11,16 @@
#![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
}
diff --git a/src/test/compile-fail/regions-close-object-into-object-2.rs b/src/test/compile-fail/regions-close-object-into-object-2.rs
index 7861fb95fef..6de49020a6f 100644
--- a/src/test/compile-fail/regions-close-object-into-object-2.rs
+++ b/src/test/compile-fail/regions-close-object-into-object-2.rs
@@ -10,10 +10,12 @@
#![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> {
diff --git a/src/test/compile-fail/regions-close-object-into-object-3.rs b/src/test/compile-fail/regions-close-object-into-object-3.rs
index 31354de2a27..e22d0c7d0a4 100644
--- a/src/test/compile-fail/regions-close-object-into-object-3.rs
+++ b/src/test/compile-fail/regions-close-object-into-object-3.rs
@@ -11,10 +11,12 @@
#![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> {
diff --git a/src/test/compile-fail/regions-close-object-into-object-4.rs b/src/test/compile-fail/regions-close-object-into-object-4.rs
index c60975f97e1..147a575d38c 100644
--- a/src/test/compile-fail/regions-close-object-into-object-4.rs
+++ b/src/test/compile-fail/regions-close-object-into-object-4.rs
@@ -10,10 +10,12 @@
#![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
index 00000000000..bdc52eca2cb
--- /dev/null
+++ b/src/test/compile-fail/regions-close-object-into-object-5.rs
@@ -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() {}
+
diff --git a/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs b/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs
index 25b8137d29c..2341d2397c9 100644
--- a/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs
+++ b/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs
@@ -10,7 +10,9 @@
#![feature(box_syntax)]
-trait Foo { }
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait { }
impl<'a> Foo for &'a isize { }
diff --git a/src/test/compile-fail/regions-close-param-into-object.rs b/src/test/compile-fail/regions-close-param-into-object.rs
index 74b36958c92..655ac6f66c9 100644
--- a/src/test/compile-fail/regions-close-param-into-object.rs
+++ b/src/test/compile-fail/regions-close-param-into-object.rs
@@ -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-infer-contravariance-due-to-decl.rs b/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs
index 6c5e90a54de..b7ef19d1e3b 100644
--- a/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs
+++ b/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs
@@ -20,7 +20,7 @@ use std::marker;
// 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>,
diff --git a/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs b/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs
index d8e31fa1374..0d3d9dacbd6 100644
--- a/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs
+++ b/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs
@@ -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>,
diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs b/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs
index e88c96de9e4..8c191fbd5bb 100644
--- a/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs
+++ b/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs
@@ -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/required-lang-item.rs b/src/test/compile-fail/required-lang-item.rs
index 7d252604883..1b749faf1b8 100644
--- a/src/test/compile-fail/required-lang-item.rs
+++ b/src/test/compile-fail/required-lang-item.rs
@@ -11,7 +11,11 @@
#![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
diff --git a/src/test/compile-fail/shadowed-type-parameter.rs b/src/test/compile-fail/shadowed-type-parameter.rs
index 1a3d7821159..1f72db1e894 100644
--- a/src/test/compile-fail/shadowed-type-parameter.rs
+++ b/src/test/compile-fail/shadowed-type-parameter.rs
@@ -12,19 +12,21 @@
#![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
diff --git a/src/test/compile-fail/slice-1.rs b/src/test/compile-fail/slice-1.rs
index 23ad5b09950..3b992e3bcc3 100644
--- a/src/test/compile-fail/slice-1.rs
+++ b/src/test/compile-fail/slice-1.rs
@@ -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
}
diff --git a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs
index 1203d622348..3c1c3796a24 100644
--- a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs
+++ b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs
@@ -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<_, _>`
diff --git a/src/test/compile-fail/staticness-mismatch.rs b/src/test/compile-fail/staticness-mismatch.rs
index bf4e46cace3..2dfc9b79ee2 100644
--- a/src/test/compile-fail/staticness-mismatch.rs
+++ b/src/test/compile-fail/staticness-mismatch.rs
@@ -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/trait-as-struct-constructor.rs b/src/test/compile-fail/trait-as-struct-constructor.rs
index a1fcab002e1..fff14414094 100644
--- a/src/test/compile-fail/trait-as-struct-constructor.rs
+++ b/src/test/compile-fail/trait-as-struct-constructor.rs
@@ -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 };
diff --git a/src/test/compile-fail/trait-bounds-cant-coerce.rs b/src/test/compile-fail/trait-bounds-cant-coerce.rs
index 79174552ae0..3129dceffbb 100644
--- a/src/test/compile-fail/trait-bounds-cant-coerce.rs
+++ b/src/test/compile-fail/trait-bounds-cant-coerce.rs
@@ -10,6 +10,7 @@
trait Foo {
+ fn dummy(&self) { }
}
fn a(_x: Box<Foo+Send>) {
diff --git a/src/test/compile-fail/trait-bounds-impl-comparison-1.rs b/src/test/compile-fail/trait-bounds-impl-comparison-1.rs
index 477bd4f5be9..34e06cc9365 100644
--- a/src/test/compile-fail/trait-bounds-impl-comparison-1.rs
+++ b/src/test/compile-fail/trait-bounds-impl-comparison-1.rs
@@ -11,7 +11,10 @@
// 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 @@ impl Foo for isize {
//~^ 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
}
diff --git a/src/test/compile-fail/trait-bounds-impl-comparison-2.rs b/src/test/compile-fail/trait-bounds-impl-comparison-2.rs
index 8ad19116e7b..284c4fac953 100644
--- a/src/test/compile-fail/trait-bounds-impl-comparison-2.rs
+++ b/src/test/compile-fail/trait-bounds-impl-comparison-2.rs
@@ -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>;
}
diff --git a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
index 434d803d718..448b186f6a5 100644
--- a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
+++ b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
@@ -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-on-structs-and-enums-locals.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs
index 118dfeb37c2..df44e847c50 100644
--- a/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs
+++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs
@@ -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,
diff --git a/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs
index d5369817e9a..18871d0d386 100644
--- a/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs
+++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs
@@ -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,
diff --git a/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs
index 490ee0e8ad6..8dfdb2f205d 100644
--- a/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs
+++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs
@@ -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() {
diff --git a/src/test/compile-fail/trait-bounds-sugar.rs b/src/test/compile-fail/trait-bounds-sugar.rs
index 3d264e681a3..e4058a0943a 100644
--- a/src/test/compile-fail/trait-bounds-sugar.rs
+++ b/src/test/compile-fail/trait-bounds-sugar.rs
@@ -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>) {
}
diff --git a/src/test/compile-fail/trait-impl-1.rs b/src/test/compile-fail/trait-impl-1.rs
index dadcbd5bce7..2f4793b4d88 100644
--- a/src/test/compile-fail/trait-impl-1.rs
+++ b/src/test/compile-fail/trait-impl-1.rs
@@ -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) {}
diff --git a/src/test/compile-fail/trait-object-safety.rs b/src/test/compile-fail/trait-object-safety.rs
index 761bcd4968a..d45d13556e1 100644
--- a/src/test/compile-fail/trait-object-safety.rs
+++ b/src/test/compile-fail/trait-object-safety.rs
@@ -12,6 +12,7 @@
trait Tr {
fn foo();
+ fn bar(&self) { }
}
struct St;
diff --git a/src/test/compile-fail/trait-static-method-generic-inference.rs b/src/test/compile-fail/trait-static-method-generic-inference.rs
index 651f663fc99..0e357d9d4d5 100644
--- a/src/test/compile-fail/trait-static-method-generic-inference.rs
+++ b/src/test/compile-fail/trait-static-method-generic-inference.rs
@@ -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
index 00000000000..8ff514e04e3
--- /dev/null
+++ b/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs
@@ -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
index 00000000000..9982d485024
--- /dev/null
+++ b/src/test/compile-fail/type-parameter-defaults-referencing-Self.rs
@@ -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/typeck-negative-impls-builtin.rs b/src/test/compile-fail/typeck-negative-impls-builtin.rs
index 9da79b11cf0..557fb2f4f88 100644
--- a/src/test/compile-fail/typeck-negative-impls-builtin.rs
+++ b/src/test/compile-fail/typeck-negative-impls-builtin.rs
@@ -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`
diff --git a/src/test/compile-fail/typeck_type_placeholder_mismatch.rs b/src/test/compile-fail/typeck_type_placeholder_mismatch.rs
index a34be63ba6b..1daea8f915b 100644
--- a/src/test/compile-fail/typeck_type_placeholder_mismatch.rs
+++ b/src/test/compile-fail/typeck_type_placeholder_mismatch.rs
@@ -11,14 +11,16 @@
// 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>`
diff --git a/src/test/compile-fail/ufcs-qpath-missing-params.rs b/src/test/compile-fail/ufcs-qpath-missing-params.rs
index 5fa66eb98e1..f4e18265fd9 100644
--- a/src/test/compile-fail/ufcs-qpath-missing-params.rs
+++ b/src/test/compile-fail/ufcs-qpath-missing-params.rs
@@ -12,6 +12,5 @@ use std::borrow::IntoCow;
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
}
-
diff --git a/src/test/compile-fail/unboxed-closure-feature-gate.rs b/src/test/compile-fail/unboxed-closure-feature-gate.rs
index 3536244f011..74a6f869f63 100644
--- a/src/test/compile-fail/unboxed-closure-feature-gate.rs
+++ b/src/test/compile-fail/unboxed-closure-feature-gate.rs
@@ -11,8 +11,12 @@
// 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() {
diff --git a/src/test/compile-fail/unboxed-closure-sugar-default.rs b/src/test/compile-fail/unboxed-closure-sugar-default.rs
index 870377bc1ad..831db98941c 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-default.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-default.rs
@@ -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> { }
diff --git a/src/test/compile-fail/unboxed-closure-sugar-equiv.rs b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs
index dc5576aee65..6d315c1b7a9 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-equiv.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs
@@ -16,12 +16,14 @@
#![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>>() { }
diff --git a/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs b/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs
index d2f781bba11..bd3530e6e30 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs
@@ -16,12 +16,14 @@
#![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>>() { }
diff --git a/src/test/compile-fail/unboxed-closure-sugar-region.rs b/src/test/compile-fail/unboxed-closure-sugar-region.rs
index 75688e44e80..057b496bd43 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-region.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-region.rs
@@ -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>>() { }
diff --git a/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs b/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs
index 215b2c6798e..713b64b1349 100644
--- a/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs
+++ b/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs
@@ -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
@@ -18,12 +18,12 @@ use std::marker::CovariantType;
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 }
}
}
diff --git a/src/test/compile-fail/unnecessary-private.rs b/src/test/compile-fail/unnecessary-private.rs
index e3707292f24..964db6e9a45 100644
--- a/src/test/compile-fail/unnecessary-private.rs
+++ b/src/test/compile-fail/unnecessary-private.rs
@@ -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 {
diff --git a/src/test/compile-fail/unsized-inherent-impl-self-type.rs b/src/test/compile-fail/unsized-inherent-impl-self-type.rs
index 8740346a217..a03c76b12dd 100644
--- a/src/test/compile-fail/unsized-inherent-impl-self-type.rs
+++ b/src/test/compile-fail/unsized-inherent-impl-self-type.rs
@@ -12,7 +12,7 @@
// impl - struct
-struct S5<Y>;
+struct S5<Y>(Y);
impl<X: ?Sized> S5<X> { //~ ERROR not implemented
}
diff --git a/src/test/compile-fail/unsized-trait-impl-self-type.rs b/src/test/compile-fail/unsized-trait-impl-self-type.rs
index 3dd55b0ba7d..08df1d9b7b8 100644
--- a/src/test/compile-fail/unsized-trait-impl-self-type.rs
+++ b/src/test/compile-fail/unsized-trait-impl-self-type.rs
@@ -12,9 +12,10 @@
// 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
}
diff --git a/src/test/compile-fail/unsized-trait-impl-trait-arg.rs b/src/test/compile-fail/unsized-trait-impl-trait-arg.rs
index ac8043d6852..4723dfeaeb9 100644
--- a/src/test/compile-fail/unsized-trait-impl-trait-arg.rs
+++ b/src/test/compile-fail/unsized-trait-impl-trait-arg.rs
@@ -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/unsized3.rs b/src/test/compile-fail/unsized3.rs
index 4fc76c99c60..de1cbab82b2 100644
--- a/src/test/compile-fail/unsized3.rs
+++ b/src/test/compile-fail/unsized3.rs
@@ -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
diff --git a/src/test/compile-fail/unsized6.rs b/src/test/compile-fail/unsized6.rs
index 217d1f44d84..f31a6ffdc0d 100644
--- a/src/test/compile-fail/unsized6.rs
+++ b/src/test/compile-fail/unsized6.rs
@@ -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.
diff --git a/src/test/compile-fail/unsized7.rs b/src/test/compile-fail/unsized7.rs
index 6fc547c0b8e..6ea3d0720ee 100644
--- a/src/test/compile-fail/unsized7.rs
+++ b/src/test/compile-fail/unsized7.rs
@@ -10,13 +10,17 @@
// 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`
}
diff --git a/src/test/compile-fail/unused-attr.rs b/src/test/compile-fail/unused-attr.rs
index 2d4bc0c857a..af242b96a84 100644
--- a/src/test/compile-fail/unused-attr.rs
+++ b/src/test/compile-fail/unused-attr.rs
@@ -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() {}
diff --git a/src/test/compile-fail/useless-priv.rs b/src/test/compile-fail/useless-priv.rs
index d8531f4543d..b1120e54434 100644
--- a/src/test/compile-fail/useless-priv.rs
+++ b/src/test/compile-fail/useless-priv.rs
@@ -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() {}
diff --git a/src/test/compile-fail/useless-priv2.rs b/src/test/compile-fail/useless-priv2.rs
index 7125a66b294..a404d09248f 100644
--- a/src/test/compile-fail/useless-priv2.rs
+++ b/src/test/compile-fail/useless-priv2.rs
@@ -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
index 00000000000..3330e1d0d51
--- /dev/null
+++ b/src/test/compile-fail/variance-contravariant-arg-object.rs
@@ -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
index 00000000000..caaad4014ad
--- /dev/null
+++ b/src/test/compile-fail/variance-contravariant-arg-trait-match.rs
@@ -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
index 00000000000..013511ed517
--- /dev/null
+++ b/src/test/compile-fail/variance-contravariant-self-trait-match.rs
@@ -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
index 00000000000..828c987c082
--- /dev/null
+++ b/src/test/compile-fail/variance-covariant-arg-object.rs
@@ -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
index 00000000000..17761b9c0b1
--- /dev/null
+++ b/src/test/compile-fail/variance-covariant-arg-trait-match.rs
@@ -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
index 00000000000..4e94a3eeb46
--- /dev/null
+++ b/src/test/compile-fail/variance-covariant-self-trait-match.rs
@@ -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
index 00000000000..8f9d24cb132
--- /dev/null
+++ b/src/test/compile-fail/variance-deprecated-markers.rs
@@ -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
index 00000000000..9edb510b826
--- /dev/null
+++ b/src/test/compile-fail/variance-invariant-arg-object.rs
@@ -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
index 00000000000..45fed0b083d
--- /dev/null
+++ b/src/test/compile-fail/variance-invariant-arg-trait-match.rs
@@ -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
index 00000000000..b46cd302ae5
--- /dev/null
+++ b/src/test/compile-fail/variance-invariant-self-trait-match.rs
@@ -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
index 00000000000..0254f56bd1a
--- /dev/null
+++ b/src/test/compile-fail/variance-issue-20533.rs
@@ -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);
+ }
+}
+
diff --git a/src/test/compile-fail/variance-regions-direct.rs b/src/test/compile-fail/variance-regions-direct.rs
index d70305d1106..da4d6c75227 100644
--- a/src/test/compile-fail/variance-regions-direct.rs
+++ b/src/test/compile-fail/variance-regions-direct.rs
@@ -60,6 +60,7 @@ struct Test6<'a, 'b> { //~ ERROR regions=[[-, o];[];[]]
#[rustc_variance]
struct Test7<'a> { //~ ERROR regions=[[*];[];[]]
+ //~^ ERROR parameter `'a` is never used
x: isize
}
diff --git a/src/test/compile-fail/variance-regions-indirect.rs b/src/test/compile-fail/variance-regions-indirect.rs
index 4bb329d6304..9beb90d0b24 100644
--- a/src/test/compile-fail/variance-regions-indirect.rs
+++ b/src/test/compile-fail/variance-regions-indirect.rs
@@ -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),
@@ -23,16 +24,19 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[];[]]
#[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/run-pass/regions-infer-bivariance.rs b/src/test/compile-fail/variance-regions-unused-direct.rs
index a3288e2e1b9..396e7765206 100644
--- a/src/test/run-pass/regions-infer-bivariance.rs
+++ b/src/test/compile-fail/variance-regions-unused-direct.rs
@@ -8,21 +8,18 @@
// 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.
+// Test that disallow lifetime parameters that are unused.
use std::marker;
-struct Bivariant<'a>;
+struct Bivariant<'a>; //~ ERROR parameter `'a` is never used
-fn use1<'short,'long>(c: Bivariant<'short>,
- _where:Option<&'short &'long ()>) {
- let _: Bivariant<'long> = c;
+struct Struct<'a, 'd> { //~ ERROR parameter `'d` is never used
+ field: &'a [i32]
}
-fn use2<'short,'long>(c: Bivariant<'long>,
- _where:Option<&'short &'long ()>) {
- let _: Bivariant<'short> = c;
+trait Trait<'a, 'd> { //~ ERROR parameter `'d` is never used
+ fn method(&'a self);
}
-pub fn main() {}
+fn main() {}
diff --git a/src/test/run-pass/export-non-interference.rs b/src/test/compile-fail/variance-regions-unused-indirect.rs
index 94652e30fe6..2d234ed7b57 100644
--- a/src/test/run-pass/export-non-interference.rs
+++ b/src/test/compile-fail/variance-regions-unused-indirect.rs
@@ -8,7 +8,14 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+// Test that disallow lifetime parameters that are unused.
-enum list_cell<T> { cons(Box<list_cell<T>>), nil }
+enum Foo<'a> { //~ ERROR parameter `'a` is never used
+ Foo1(Bar<'a>)
+}
-pub fn main() { }
+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
index 00000000000..88b50058b65
--- /dev/null
+++ b/src/test/compile-fail/variance-trait-bounds.rs
@@ -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() { }
diff --git a/src/test/compile-fail/variance-trait-object-bound.rs b/src/test/compile-fail/variance-trait-object-bound.rs
index 965b9430a5e..f0ca1edd563 100644
--- a/src/test/compile-fail/variance-trait-object-bound.rs
+++ b/src/test/compile-fail/variance-trait-object-bound.rs
@@ -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
index 00000000000..d53e4cd7610
--- /dev/null
+++ b/src/test/compile-fail/variance-types-bounds.rs
@@ -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
index 00000000000..e407ebe345a
--- /dev/null
+++ b/src/test/compile-fail/variance-types.rs
@@ -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
index 00000000000..5f504226370
--- /dev/null
+++ b/src/test/compile-fail/variance-unused-region-param.rs
@@ -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
index 00000000000..2e867ec3c93
--- /dev/null
+++ b/src/test/compile-fail/variance-unused-type-param.rs
@@ -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
index 00000000000..d2fd2978750
--- /dev/null
+++ b/src/test/compile-fail/variance-use-contravariant-struct-1.rs
@@ -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
index 00000000000..b38fd0e9ffc
--- /dev/null
+++ b/src/test/compile-fail/variance-use-contravariant-struct-2.rs
@@ -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
index 00000000000..2631cfc05e8
--- /dev/null
+++ b/src/test/compile-fail/variance-use-covariant-struct-1.rs
@@ -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
index 00000000000..d8e1a5f5f1c
--- /dev/null
+++ b/src/test/compile-fail/variance-use-covariant-struct-2.rs
@@ -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
index 00000000000..c89436b2094
--- /dev/null
+++ b/src/test/compile-fail/variance-use-invariant-struct-1.rs
@@ -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/visible-private-types-generics.rs b/src/test/compile-fail/visible-private-types-generics.rs
index 7ff18f8e088..1f2205b5c71 100644
--- a/src/test/compile-fail/visible-private-types-generics.rs
+++ b/src/test/compile-fail/visible-private-types-generics.rs
@@ -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
diff --git a/src/test/compile-fail/visible-private-types-supertrait.rs b/src/test/compile-fail/visible-private-types-supertrait.rs
index dc6d446154a..9d9eae4a075 100644
--- a/src/test/compile-fail/visible-private-types-supertrait.rs
+++ b/src/test/compile-fail/visible-private-types-supertrait.rs
@@ -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
diff --git a/src/test/compile-fail/where-clause-method-substituion.rs b/src/test/compile-fail/where-clause-method-substituion.rs
index a5108f005dc..bf614e6eb51 100644
--- a/src/test/compile-fail/where-clause-method-substituion.rs
+++ b/src/test/compile-fail/where-clause-method-substituion.rs
@@ -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-not-parameter.rs b/src/test/compile-fail/where-clauses-not-parameter.rs
index 313ae273c07..7968cc37090 100644
--- a/src/test/compile-fail/where-clauses-not-parameter.rs
+++ b/src/test/compile-fail/where-clauses-not-parameter.rs
@@ -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
}
diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs
index a592484f1a4..bf26fc23d3c 100644
--- a/src/test/debuginfo/type-names.rs
+++ b/src/test/debuginfo/type-names.rs
@@ -177,10 +177,11 @@
#![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 @@ mod Mod1 {
}
}
-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/compile-fail/ascii-only-character-escape.rs b/src/test/parse-fail/ascii-only-character-escape.rs
index 1ba25a827a5..1ba25a827a5 100644
--- a/src/test/compile-fail/ascii-only-character-escape.rs
+++ b/src/test/parse-fail/ascii-only-character-escape.rs
diff --git a/src/test/compile-fail/attr-before-eof.rs b/src/test/parse-fail/attr-before-eof.rs
index e34756229bd..e34756229bd 100644
--- a/src/test/compile-fail/attr-before-eof.rs
+++ b/src/test/parse-fail/attr-before-eof.rs
diff --git a/src/test/compile-fail/attr-before-ext.rs b/src/test/parse-fail/attr-before-ext.rs
index 098c5aaec54..098c5aaec54 100644
--- a/src/test/compile-fail/attr-before-ext.rs
+++ b/src/test/parse-fail/attr-before-ext.rs
diff --git a/src/test/compile-fail/attr-before-let.rs b/src/test/parse-fail/attr-before-let.rs
index b4a90e35c40..b4a90e35c40 100644
--- a/src/test/compile-fail/attr-before-let.rs
+++ b/src/test/parse-fail/attr-before-let.rs
diff --git a/src/test/compile-fail/attr-before-stmt.rs b/src/test/parse-fail/attr-before-stmt.rs
index ec837cd6de3..ec837cd6de3 100644
--- a/src/test/compile-fail/attr-before-stmt.rs
+++ b/src/test/parse-fail/attr-before-stmt.rs
diff --git a/src/test/compile-fail/attr-dangling-in-fn.rs b/src/test/parse-fail/attr-dangling-in-fn.rs
index 384622fb168..384622fb168 100644
--- a/src/test/compile-fail/attr-dangling-in-fn.rs
+++ b/src/test/parse-fail/attr-dangling-in-fn.rs
diff --git a/src/test/compile-fail/attr-dangling-in-mod.rs b/src/test/parse-fail/attr-dangling-in-mod.rs
index 59a922ebee1..59a922ebee1 100644
--- a/src/test/compile-fail/attr-dangling-in-mod.rs
+++ b/src/test/parse-fail/attr-dangling-in-mod.rs
diff --git a/src/test/compile-fail/attr.rs b/src/test/parse-fail/attr.rs
index 4bd61412731..4bd61412731 100644
--- a/src/test/compile-fail/attr.rs
+++ b/src/test/parse-fail/attr.rs
diff --git a/src/test/compile-fail/attrs-after-extern-mod.rs b/src/test/parse-fail/attrs-after-extern-mod.rs
index df747618696..df747618696 100644
--- a/src/test/compile-fail/attrs-after-extern-mod.rs
+++ b/src/test/parse-fail/attrs-after-extern-mod.rs
diff --git a/src/test/compile-fail/bad-char-literals.rs b/src/test/parse-fail/bad-char-literals.rs
index 2a358ae8307..2a358ae8307 100644
--- a/src/test/compile-fail/bad-char-literals.rs
+++ b/src/test/parse-fail/bad-char-literals.rs
diff --git a/src/test/compile-fail/bad-lit-suffixes.rs b/src/test/parse-fail/bad-lit-suffixes.rs
index d10337e768c..d10337e768c 100644
--- a/src/test/compile-fail/bad-lit-suffixes.rs
+++ b/src/test/parse-fail/bad-lit-suffixes.rs
diff --git a/src/test/compile-fail/bad-value-ident-false.rs b/src/test/parse-fail/bad-value-ident-false.rs
index ca10bdd9848..ca10bdd9848 100644
--- a/src/test/compile-fail/bad-value-ident-false.rs
+++ b/src/test/parse-fail/bad-value-ident-false.rs
diff --git a/src/test/compile-fail/bad-value-ident-true.rs b/src/test/parse-fail/bad-value-ident-true.rs
index 4508d5219a2..4508d5219a2 100644
--- a/src/test/compile-fail/bad-value-ident-true.rs
+++ b/src/test/parse-fail/bad-value-ident-true.rs
diff --git a/src/test/compile-fail/doc-before-attr.rs b/src/test/parse-fail/doc-before-attr.rs
index bb44a6a8abb..bb44a6a8abb 100644
--- a/src/test/compile-fail/doc-before-attr.rs
+++ b/src/test/parse-fail/doc-before-attr.rs
diff --git a/src/test/compile-fail/doc-before-eof.rs b/src/test/parse-fail/doc-before-eof.rs
index e6dd4102462..e6dd4102462 100644
--- a/src/test/compile-fail/doc-before-eof.rs
+++ b/src/test/parse-fail/doc-before-eof.rs
diff --git a/src/test/compile-fail/doc-before-extern-rbrace.rs b/src/test/parse-fail/doc-before-extern-rbrace.rs
index 5afd1b2c6b8..5afd1b2c6b8 100644
--- a/src/test/compile-fail/doc-before-extern-rbrace.rs
+++ b/src/test/parse-fail/doc-before-extern-rbrace.rs
diff --git a/src/test/compile-fail/doc-before-macro.rs b/src/test/parse-fail/doc-before-macro.rs
index 8dc6c546500..8dc6c546500 100644
--- a/src/test/compile-fail/doc-before-macro.rs
+++ b/src/test/parse-fail/doc-before-macro.rs
diff --git a/src/test/compile-fail/doc-before-rbrace.rs b/src/test/parse-fail/doc-before-rbrace.rs
index 6d05064277d..6d05064277d 100644
--- a/src/test/compile-fail/doc-before-rbrace.rs
+++ b/src/test/parse-fail/doc-before-rbrace.rs
diff --git a/src/test/compile-fail/doc-before-semi.rs b/src/test/parse-fail/doc-before-semi.rs
index 8b0300edce0..8b0300edce0 100644
--- a/src/test/compile-fail/doc-before-semi.rs
+++ b/src/test/parse-fail/doc-before-semi.rs
diff --git a/src/test/compile-fail/extern-crate-as-no-string-help.rs b/src/test/parse-fail/extern-crate-as-no-string-help.rs
index 5cc52f6f6db..5cc52f6f6db 100644
--- a/src/test/compile-fail/extern-crate-as-no-string-help.rs
+++ b/src/test/parse-fail/extern-crate-as-no-string-help.rs
diff --git a/src/test/compile-fail/generic-non-trailing-defaults.rs b/src/test/parse-fail/generic-non-trailing-defaults.rs
index 0cfb05b9332..0cfb05b9332 100644
--- a/src/test/compile-fail/generic-non-trailing-defaults.rs
+++ b/src/test/parse-fail/generic-non-trailing-defaults.rs
diff --git a/src/test/compile-fail/int-literal-too-large-span.rs b/src/test/parse-fail/int-literal-too-large-span.rs
index 8a496c934b9..8a496c934b9 100644
--- a/src/test/compile-fail/int-literal-too-large-span.rs
+++ b/src/test/parse-fail/int-literal-too-large-span.rs
diff --git a/src/test/compile-fail/issue-10412.rs b/src/test/parse-fail/issue-10412.rs
index 8a99633b4fc..8a99633b4fc 100644
--- a/src/test/compile-fail/issue-10412.rs
+++ b/src/test/parse-fail/issue-10412.rs
diff --git a/src/test/compile-fail/issue-12560-1.rs b/src/test/parse-fail/issue-12560-1.rs
index ea2043e6703..ea2043e6703 100644
--- a/src/test/compile-fail/issue-12560-1.rs
+++ b/src/test/parse-fail/issue-12560-1.rs
diff --git a/src/test/compile-fail/issue-14182.rs b/src/test/parse-fail/issue-14182.rs
index 364951a4fea..364951a4fea 100644
--- a/src/test/compile-fail/issue-14182.rs
+++ b/src/test/parse-fail/issue-14182.rs
diff --git a/src/test/compile-fail/issue-17383.rs b/src/test/parse-fail/issue-17383.rs
index c71e0ecd494..c71e0ecd494 100644
--- a/src/test/compile-fail/issue-17383.rs
+++ b/src/test/parse-fail/issue-17383.rs
diff --git a/src/test/compile-fail/issue-17718-const-mut.rs b/src/test/parse-fail/issue-17718-const-mut.rs
index 5177ebbc188..5177ebbc188 100644
--- a/src/test/compile-fail/issue-17718-const-mut.rs
+++ b/src/test/parse-fail/issue-17718-const-mut.rs
diff --git a/src/test/compile-fail/issue-1802-2.rs b/src/test/parse-fail/issue-1802-2.rs
index f6da2fc82c3..f6da2fc82c3 100644
--- a/src/test/compile-fail/issue-1802-2.rs
+++ b/src/test/parse-fail/issue-1802-2.rs
diff --git a/src/test/compile-fail/issue-5544-a.rs b/src/test/parse-fail/issue-5544-a.rs
index 95a4f36d171..95a4f36d171 100644
--- a/src/test/compile-fail/issue-5544-a.rs
+++ b/src/test/parse-fail/issue-5544-a.rs
diff --git a/src/test/compile-fail/issue-5544-b.rs b/src/test/parse-fail/issue-5544-b.rs
index afff5984b46..afff5984b46 100644
--- a/src/test/compile-fail/issue-5544-b.rs
+++ b/src/test/parse-fail/issue-5544-b.rs
diff --git a/src/test/compile-fail/issue-8537.rs b/src/test/parse-fail/issue-8537.rs
index 52cf420a9ff..52cf420a9ff 100644
--- a/src/test/compile-fail/issue-8537.rs
+++ b/src/test/parse-fail/issue-8537.rs
diff --git a/src/test/compile-fail/keyword-as-as-identifier.rs b/src/test/parse-fail/keyword-as-as-identifier.rs
index f307b12f66e..f307b12f66e 100644
--- a/src/test/compile-fail/keyword-as-as-identifier.rs
+++ b/src/test/parse-fail/keyword-as-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-break-as-identifier.rs b/src/test/parse-fail/keyword-break-as-identifier.rs
index 1e2725eb2fe..1e2725eb2fe 100644
--- a/src/test/compile-fail/keyword-break-as-identifier.rs
+++ b/src/test/parse-fail/keyword-break-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-else-as-identifier.rs b/src/test/parse-fail/keyword-else-as-identifier.rs
index 101fd938dcb..101fd938dcb 100644
--- a/src/test/compile-fail/keyword-else-as-identifier.rs
+++ b/src/test/parse-fail/keyword-else-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-enum-as-identifier.rs b/src/test/parse-fail/keyword-enum-as-identifier.rs
index ed504cc7b7f..ed504cc7b7f 100644
--- a/src/test/compile-fail/keyword-enum-as-identifier.rs
+++ b/src/test/parse-fail/keyword-enum-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-extern-as-identifier.rs b/src/test/parse-fail/keyword-extern-as-identifier.rs
index 3260506b3e1..3260506b3e1 100644
--- a/src/test/compile-fail/keyword-extern-as-identifier.rs
+++ b/src/test/parse-fail/keyword-extern-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-fn-as-identifier.rs b/src/test/parse-fail/keyword-fn-as-identifier.rs
index 8c98da229c8..8c98da229c8 100644
--- a/src/test/compile-fail/keyword-fn-as-identifier.rs
+++ b/src/test/parse-fail/keyword-fn-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-for-as-identifier.rs b/src/test/parse-fail/keyword-for-as-identifier.rs
index 196a3390676..196a3390676 100644
--- a/src/test/compile-fail/keyword-for-as-identifier.rs
+++ b/src/test/parse-fail/keyword-for-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-if-as-identifier.rs b/src/test/parse-fail/keyword-if-as-identifier.rs
index 05f82ec790c..05f82ec790c 100644
--- a/src/test/compile-fail/keyword-if-as-identifier.rs
+++ b/src/test/parse-fail/keyword-if-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-impl-as-identifier.rs b/src/test/parse-fail/keyword-impl-as-identifier.rs
index 1dd21800345..1dd21800345 100644
--- a/src/test/compile-fail/keyword-impl-as-identifier.rs
+++ b/src/test/parse-fail/keyword-impl-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-let-as-identifier.rs b/src/test/parse-fail/keyword-let-as-identifier.rs
index 0069a26a40b..0069a26a40b 100644
--- a/src/test/compile-fail/keyword-let-as-identifier.rs
+++ b/src/test/parse-fail/keyword-let-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-loop-as-identifier.rs b/src/test/parse-fail/keyword-loop-as-identifier.rs
index 6e469e8c0b4..6e469e8c0b4 100644
--- a/src/test/compile-fail/keyword-loop-as-identifier.rs
+++ b/src/test/parse-fail/keyword-loop-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-match-as-identifier.rs b/src/test/parse-fail/keyword-match-as-identifier.rs
index 9155ebc71fa..9155ebc71fa 100644
--- a/src/test/compile-fail/keyword-match-as-identifier.rs
+++ b/src/test/parse-fail/keyword-match-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-mod-as-identifier.rs b/src/test/parse-fail/keyword-mod-as-identifier.rs
index 02f57e937dd..02f57e937dd 100644
--- a/src/test/compile-fail/keyword-mod-as-identifier.rs
+++ b/src/test/parse-fail/keyword-mod-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-pub-as-identifier.rs b/src/test/parse-fail/keyword-pub-as-identifier.rs
index aa679741c1c..aa679741c1c 100644
--- a/src/test/compile-fail/keyword-pub-as-identifier.rs
+++ b/src/test/parse-fail/keyword-pub-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-return-as-identifier.rs b/src/test/parse-fail/keyword-return-as-identifier.rs
index c5676445917..c5676445917 100644
--- a/src/test/compile-fail/keyword-return-as-identifier.rs
+++ b/src/test/parse-fail/keyword-return-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-self-as-identifier.rs b/src/test/parse-fail/keyword-self-as-identifier.rs
index 8bb52142287..8bb52142287 100644
--- a/src/test/compile-fail/keyword-self-as-identifier.rs
+++ b/src/test/parse-fail/keyword-self-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-static-as-identifier.rs b/src/test/parse-fail/keyword-static-as-identifier.rs
index 7268c4f387e..7268c4f387e 100644
--- a/src/test/compile-fail/keyword-static-as-identifier.rs
+++ b/src/test/parse-fail/keyword-static-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-struct-as-identifier.rs b/src/test/parse-fail/keyword-struct-as-identifier.rs
index bd42eac0ecb..bd42eac0ecb 100644
--- a/src/test/compile-fail/keyword-struct-as-identifier.rs
+++ b/src/test/parse-fail/keyword-struct-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-super-as-identifier.rs b/src/test/parse-fail/keyword-super-as-identifier.rs
index 0378c326a89..0378c326a89 100644
--- a/src/test/compile-fail/keyword-super-as-identifier.rs
+++ b/src/test/parse-fail/keyword-super-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-super.rs b/src/test/parse-fail/keyword-super.rs
index 0c94f76f1f6..0c94f76f1f6 100644
--- a/src/test/compile-fail/keyword-super.rs
+++ b/src/test/parse-fail/keyword-super.rs
diff --git a/src/test/compile-fail/keyword-trait-as-identifier.rs b/src/test/parse-fail/keyword-trait-as-identifier.rs
index 95c0d174c33..95c0d174c33 100644
--- a/src/test/compile-fail/keyword-trait-as-identifier.rs
+++ b/src/test/parse-fail/keyword-trait-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-type-as-identifier.rs b/src/test/parse-fail/keyword-type-as-identifier.rs
index 0aaa2a63c7c..0aaa2a63c7c 100644
--- a/src/test/compile-fail/keyword-type-as-identifier.rs
+++ b/src/test/parse-fail/keyword-type-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-unsafe-as-identifier.rs b/src/test/parse-fail/keyword-unsafe-as-identifier.rs
index 1b631eb877d..1b631eb877d 100644
--- a/src/test/compile-fail/keyword-unsafe-as-identifier.rs
+++ b/src/test/parse-fail/keyword-unsafe-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-use-as-identifier.rs b/src/test/parse-fail/keyword-use-as-identifier.rs
index e82afd54442..e82afd54442 100644
--- a/src/test/compile-fail/keyword-use-as-identifier.rs
+++ b/src/test/parse-fail/keyword-use-as-identifier.rs
diff --git a/src/test/compile-fail/keyword-while-as-identifier.rs b/src/test/parse-fail/keyword-while-as-identifier.rs
index 95cea65c610..95cea65c610 100644
--- a/src/test/compile-fail/keyword-while-as-identifier.rs
+++ b/src/test/parse-fail/keyword-while-as-identifier.rs
diff --git a/src/test/compile-fail/keyword.rs b/src/test/parse-fail/keyword.rs
index 64eac47e69b..64eac47e69b 100644
--- a/src/test/compile-fail/keyword.rs
+++ b/src/test/parse-fail/keyword.rs
diff --git a/src/test/compile-fail/keywords-followed-by-double-colon.rs b/src/test/parse-fail/keywords-followed-by-double-colon.rs
index f69b041597e..f69b041597e 100644
--- a/src/test/compile-fail/keywords-followed-by-double-colon.rs
+++ b/src/test/parse-fail/keywords-followed-by-double-colon.rs
diff --git a/src/test/compile-fail/lex-bad-numeric-literals.rs b/src/test/parse-fail/lex-bad-numeric-literals.rs
index 9a490be6a01..9a490be6a01 100644
--- a/src/test/compile-fail/lex-bad-numeric-literals.rs
+++ b/src/test/parse-fail/lex-bad-numeric-literals.rs
diff --git a/src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs b/src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs
index c1e5121d6dd..c1e5121d6dd 100644
--- a/src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs
+++ b/src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs
diff --git a/src/test/compile-fail/lifetime-no-keyword.rs b/src/test/parse-fail/lifetime-no-keyword.rs
index 8ffbcd90df8..8ffbcd90df8 100644
--- a/src/test/compile-fail/lifetime-no-keyword.rs
+++ b/src/test/parse-fail/lifetime-no-keyword.rs
diff --git a/src/test/compile-fail/lifetime-obsoleted-self.rs b/src/test/parse-fail/lifetime-obsoleted-self.rs
index 766922f2f88..766922f2f88 100644
--- a/src/test/compile-fail/lifetime-obsoleted-self.rs
+++ b/src/test/parse-fail/lifetime-obsoleted-self.rs
diff --git a/src/test/compile-fail/macros-no-semicolon-items.rs b/src/test/parse-fail/macros-no-semicolon-items.rs
index 314292085df..314292085df 100644
--- a/src/test/compile-fail/macros-no-semicolon-items.rs
+++ b/src/test/parse-fail/macros-no-semicolon-items.rs
diff --git a/src/test/compile-fail/no-binary-float-literal.rs b/src/test/parse-fail/no-binary-float-literal.rs
index 2e207f90d36..2e207f90d36 100644
--- a/src/test/compile-fail/no-binary-float-literal.rs
+++ b/src/test/parse-fail/no-binary-float-literal.rs
diff --git a/src/test/compile-fail/no-hex-float-literal.rs b/src/test/parse-fail/no-hex-float-literal.rs
index 4abb6093b24..4abb6093b24 100644
--- a/src/test/compile-fail/no-hex-float-literal.rs
+++ b/src/test/parse-fail/no-hex-float-literal.rs
diff --git a/src/test/compile-fail/no-unsafe-self.rs b/src/test/parse-fail/no-unsafe-self.rs
index 0bf73bbdfe3..0bf73bbdfe3 100644
--- a/src/test/compile-fail/no-unsafe-self.rs
+++ b/src/test/parse-fail/no-unsafe-self.rs
diff --git a/src/test/compile-fail/non-str-meta.rs b/src/test/parse-fail/non-str-meta.rs
index 752f72f0b08..752f72f0b08 100644
--- a/src/test/compile-fail/non-str-meta.rs
+++ b/src/test/parse-fail/non-str-meta.rs
diff --git a/src/test/compile-fail/obsolete-for-sized.rs b/src/test/parse-fail/obsolete-for-sized.rs
index 1b86d08a50d..1b86d08a50d 100644
--- a/src/test/compile-fail/obsolete-for-sized.rs
+++ b/src/test/parse-fail/obsolete-for-sized.rs
diff --git a/src/test/compile-fail/obsolete-proc.rs b/src/test/parse-fail/obsolete-proc.rs
index 5208cdb6ad2..5208cdb6ad2 100644
--- a/src/test/compile-fail/obsolete-proc.rs
+++ b/src/test/parse-fail/obsolete-proc.rs
diff --git a/src/test/compile-fail/qquote-1.rs b/src/test/parse-fail/qquote-1.rs
index deae9a83866..deae9a83866 100644
--- a/src/test/compile-fail/qquote-1.rs
+++ b/src/test/parse-fail/qquote-1.rs
diff --git a/src/test/compile-fail/qquote-2.rs b/src/test/parse-fail/qquote-2.rs
index 978287a681e..978287a681e 100644
--- a/src/test/compile-fail/qquote-2.rs
+++ b/src/test/parse-fail/qquote-2.rs
diff --git a/src/test/compile-fail/regions-fn-bound.rs b/src/test/parse-fail/regions-fn-bound.rs
index c2b52b79f6c..c2b52b79f6c 100644
--- a/src/test/compile-fail/regions-fn-bound.rs
+++ b/src/test/parse-fail/regions-fn-bound.rs
diff --git a/src/test/compile-fail/require-parens-for-chained-comparison.rs b/src/test/parse-fail/require-parens-for-chained-comparison.rs
index f2705f58331..f2705f58331 100644
--- a/src/test/compile-fail/require-parens-for-chained-comparison.rs
+++ b/src/test/parse-fail/require-parens-for-chained-comparison.rs
diff --git a/src/test/compile-fail/struct-no-fields-2.rs b/src/test/parse-fail/struct-no-fields-2.rs
index 4f973f81b16..4f973f81b16 100644
--- a/src/test/compile-fail/struct-no-fields-2.rs
+++ b/src/test/parse-fail/struct-no-fields-2.rs
diff --git a/src/test/compile-fail/struct-no-fields-3.rs b/src/test/parse-fail/struct-no-fields-3.rs
index e594683feed..e594683feed 100644
--- a/src/test/compile-fail/struct-no-fields-3.rs
+++ b/src/test/parse-fail/struct-no-fields-3.rs
diff --git a/src/test/compile-fail/struct-no-fields-4.rs b/src/test/parse-fail/struct-no-fields-4.rs
index 60a0a85d0ab..60a0a85d0ab 100644
--- a/src/test/compile-fail/struct-no-fields-4.rs
+++ b/src/test/parse-fail/struct-no-fields-4.rs
diff --git a/src/test/compile-fail/struct-no-fields-5.rs b/src/test/parse-fail/struct-no-fields-5.rs
index 940fa9c7f27..940fa9c7f27 100644
--- a/src/test/compile-fail/struct-no-fields-5.rs
+++ b/src/test/parse-fail/struct-no-fields-5.rs
diff --git a/src/test/compile-fail/struct-variant-no-fields.rs b/src/test/parse-fail/struct-variant-no-fields.rs
index 41dbbeefc0a..41dbbeefc0a 100644
--- a/src/test/compile-fail/struct-variant-no-fields.rs
+++ b/src/test/parse-fail/struct-variant-no-fields.rs
diff --git a/src/test/compile-fail/struct-variant-no-pub.rs b/src/test/parse-fail/struct-variant-no-pub.rs
index e62b39ad5aa..e62b39ad5aa 100644
--- a/src/test/compile-fail/struct-variant-no-pub.rs
+++ b/src/test/parse-fail/struct-variant-no-pub.rs
diff --git a/src/test/compile-fail/syntax-trait-polarity.rs b/src/test/parse-fail/syntax-trait-polarity.rs
index 1ab79f5c80e..1ab79f5c80e 100644
--- a/src/test/compile-fail/syntax-trait-polarity.rs
+++ b/src/test/parse-fail/syntax-trait-polarity.rs
diff --git a/src/test/compile-fail/tag-variant-disr-non-nullary.rs b/src/test/parse-fail/tag-variant-disr-non-nullary.rs
index 207bbe9a446..207bbe9a446 100644
--- a/src/test/compile-fail/tag-variant-disr-non-nullary.rs
+++ b/src/test/parse-fail/tag-variant-disr-non-nullary.rs
diff --git a/src/test/compile-fail/trailing-carriage-return-in-string.rs b/src/test/parse-fail/trailing-carriage-return-in-string.rs
index 81098333261..81098333261 100644
--- a/src/test/compile-fail/trailing-carriage-return-in-string.rs
+++ b/src/test/parse-fail/trailing-carriage-return-in-string.rs
diff --git a/src/test/compile-fail/trailing-plus-in-bounds.rs b/src/test/parse-fail/trailing-plus-in-bounds.rs
index e8f9ed4d2cf..e8f9ed4d2cf 100644
--- a/src/test/compile-fail/trailing-plus-in-bounds.rs
+++ b/src/test/parse-fail/trailing-plus-in-bounds.rs
diff --git a/src/test/compile-fail/trait-bounds-not-on-impl.rs b/src/test/parse-fail/trait-bounds-not-on-impl.rs
index a034352c4a6..a034352c4a6 100644
--- a/src/test/compile-fail/trait-bounds-not-on-impl.rs
+++ b/src/test/parse-fail/trait-bounds-not-on-impl.rs
diff --git a/src/test/compile-fail/type-parameters-in-field-exprs.rs b/src/test/parse-fail/type-parameters-in-field-exprs.rs
index 54ddb3e19fa..54ddb3e19fa 100644
--- a/src/test/compile-fail/type-parameters-in-field-exprs.rs
+++ b/src/test/parse-fail/type-parameters-in-field-exprs.rs
diff --git a/src/test/compile-fail/unsized2.rs b/src/test/parse-fail/unsized2.rs
index b2eb2064aeb..b2eb2064aeb 100644
--- a/src/test/compile-fail/unsized2.rs
+++ b/src/test/parse-fail/unsized2.rs
diff --git a/src/test/compile-fail/virtual-structs.rs b/src/test/parse-fail/virtual-structs.rs
index 3b3c7d5a30f..3b3c7d5a30f 100644
--- a/src/test/compile-fail/virtual-structs.rs
+++ b/src/test/parse-fail/virtual-structs.rs
diff --git a/src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs b/src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs
index b96c7c2de6b..b96c7c2de6b 100644
--- a/src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs
+++ b/src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs
diff --git a/src/test/pretty/empty-impl.rs b/src/test/pretty/empty-impl.rs
index f22f1b40952..f5205de5c1f 100644
--- a/src/test/pretty/empty-impl.rs
+++ b/src/test/pretty/empty-impl.rs
@@ -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 { }
diff --git a/src/test/pretty/path-type-bounds.rs b/src/test/pretty/path-type-bounds.rs
index e27a3365a41..9e1f2aa8bfe 100644
--- a/src/test/pretty/path-type-bounds.rs
+++ b/src/test/pretty/path-type-bounds.rs
@@ -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 }
diff --git a/src/test/run-fail/bug-811.rs b/src/test/run-fail/bug-811.rs
index e46564f8076..4ad81197286 100644
--- a/src/test/run-fail/bug-811.rs
+++ b/src/test/run-fail/bug-811.rs
@@ -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 @@ type port_id = int;
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!(); }
diff --git a/src/test/run-make/rustdoc-json/foo.rs b/src/test/run-make/rustdoc-json/foo.rs
index d57a7164cdb..3bd56c14193 100644
--- a/src/test/run-make/rustdoc-json/foo.rs
+++ b/src/test/run-make/rustdoc-json/foo.rs
@@ -21,5 +21,5 @@ pub mod bar {
}
/// *wow*
- pub trait Doge { }
+ pub trait Doge { fn dummy(&self) { } }
}
diff --git a/src/test/run-make/rustdoc-negative-impl/foo.rs b/src/test/run-make/rustdoc-negative-impl/foo.rs
index b5fcbf46c5c..6c56bcc9be6 100644
--- a/src/test/run-make/rustdoc-negative-impl/foo.rs
+++ b/src/test/run-make/rustdoc-negative-impl/foo.rs
@@ -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 {}
diff --git a/src/test/run-make/rustdoc-search-index/index.rs b/src/test/run-make/rustdoc-search-index/index.rs
index dd68f2d6f1d..42469a21f22 100644
--- a/src/test/run-make/rustdoc-search-index/index.rs
+++ b/src/test/run-make/rustdoc-search-index/index.rs
@@ -21,6 +21,6 @@ mod private {
}
pub trait PrivateTrait {
- fn trait_method() {} // @!has - priv_method
+ fn trait_method(&self) {} // @!has - priv_method
}
}
diff --git a/src/test/run-make/rustdoc-smoke/foo.rs b/src/test/run-make/rustdoc-smoke/foo.rs
index 0438c9aba35..f6b73021beb 100644
--- a/src/test/run-make/rustdoc-smoke/foo.rs
+++ b/src/test/run-make/rustdoc-smoke/foo.rs
@@ -26,7 +26,7 @@ pub mod bar {
/// *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 }
diff --git a/src/test/run-make/rustdoc-viewpath-self/foo.rs b/src/test/run-make/rustdoc-viewpath-self/foo.rs
index da8f7393023..6fd47d84c30 100644
--- a/src/test/run-make/rustdoc-viewpath-self/foo.rs
+++ b/src/test/run-make/rustdoc-viewpath-self/foo.rs
@@ -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> {
diff --git a/src/test/run-make/rustdoc-where/foo.rs b/src/test/run-make/rustdoc-where/foo.rs
index 68fde60564e..91a7e1c9fd4 100644
--- a/src/test/run-make/rustdoc-where/foo.rs
+++ b/src/test/run-make/rustdoc-where/foo.rs
@@ -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' \
diff --git a/src/test/run-make/save-analysis/foo.rs b/src/test/run-make/save-analysis/foo.rs
index db70a245232..38381da3670 100644
--- a/src/test/run-make/save-analysis/foo.rs
+++ b/src/test/run-make/save-analysis/foo.rs
@@ -34,7 +34,7 @@ use std::mem::size_of;
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 {
diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make/simd-ffi/simd.rs
index 834a2adf01f..f418d5d1fb7 100755
--- a/src/test/run-make/simd-ffi/simd.rs
+++ b/src/test/run-make/simd-ffi/simd.rs
@@ -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 {
diff --git a/src/test/run-make/symbols-are-reasonable/lib.rs b/src/test/run-make/symbols-are-reasonable/lib.rs
index 1e0570c95ac..e1f36ecda53 100644
--- a/src/test/run-make/symbols-are-reasonable/lib.rs
+++ b/src/test/run-make/symbols-are-reasonable/lib.rs
@@ -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() {
diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make/target-specs/foo.rs
index 365fc039a4e..acda8705b19 100644
--- a/src/test/run-make/target-specs/foo.rs
+++ b/src/test/run-make/target-specs/foo.rs
@@ -11,11 +11,15 @@
#![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 }
diff --git a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
index 195055f12d1..aecec44f6fd 100644
--- a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
+++ b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
@@ -25,7 +25,7 @@ impl Drop for Foo {
}
-trait Trait {}
+trait Trait { fn dummy(&self) { } }
impl Trait for Foo {}
pub fn main() {
diff --git a/src/test/run-pass-valgrind/dst-dtor-1.rs b/src/test/run-pass-valgrind/dst-dtor-1.rs
index 47e2a18a999..c49a684de94 100644
--- a/src/test/run-pass-valgrind/dst-dtor-1.rs
+++ b/src/test/run-pass-valgrind/dst-dtor-1.rs
@@ -19,7 +19,7 @@ impl Drop for Foo {
}
}
-trait Trait {}
+trait Trait { fn dummy(&self) { } }
impl Trait for Foo {}
struct Fat<T: ?Sized> {
diff --git a/src/test/run-pass/associated-types-basic.rs b/src/test/run-pass/associated-types-basic.rs
index 3314b613201..f5521f7da85 100644
--- a/src/test/run-pass/associated-types-basic.rs
+++ b/src/test/run-pass/associated-types-basic.rs
@@ -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;
}
diff --git a/src/test/run-pass/associated-types-conditional-dispatch.rs b/src/test/run-pass/associated-types-conditional-dispatch.rs
index f21b7183d70..aa65b0ed10b 100644
--- a/src/test/run-pass/associated-types-conditional-dispatch.rs
+++ b/src/test/run-pass/associated-types-conditional-dispatch.rs
@@ -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 @@ impl<'a, A, B, Lhs> MyEq<[B; 0]> for Lhs
}
struct DerefWithHelper<H, T> {
- pub helper: H
+ pub helper: H,
+ pub marker: PhantomData<T>,
}
trait Helper<T> {
@@ -63,7 +65,8 @@ impl<T, H: Helper<T>> Deref for DerefWithHelper<H, 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)
}
diff --git a/src/test/run-pass/associated-types-issue-20371.rs b/src/test/run-pass/associated-types-issue-20371.rs
index d35b7331d4d..40ef7f3531c 100644
--- a/src/test/run-pass/associated-types-issue-20371.rs
+++ b/src/test/run-pass/associated-types-issue-20371.rs
@@ -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() {}
diff --git a/src/test/run-pass/associated-types-issue-21212.rs b/src/test/run-pass/associated-types-issue-21212.rs
index ced44250e4d..3c91577362a 100644
--- a/src/test/run-pass/associated-types-issue-21212.rs
+++ b/src/test/run-pass/associated-types-issue-21212.rs
@@ -20,7 +20,8 @@ pub trait Parser {
panic!()
}
}
-impl <P> Parser for P {
+
+impl <P> Parser for P {
type Input = ();
}
diff --git a/src/test/run-pass/associated-types-nested-projections.rs b/src/test/run-pass/associated-types-nested-projections.rs
index e3227613159..2ee8ef0d3dd 100644
--- a/src/test/run-pass/associated-types-nested-projections.rs
+++ b/src/test/run-pass/associated-types-nested-projections.rs
@@ -10,11 +10,12 @@
// 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;
diff --git a/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs b/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs
index dd5814f875b..de96af83f59 100644
--- a/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs
+++ b/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs
@@ -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>()
diff --git a/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs b/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs
index 1d264655bc4..8617750ca53 100644
--- a/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs
+++ b/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs
@@ -11,15 +11,17 @@
// 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 @@ impl<T> SliceExt2 for [T] {
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 {}
}
diff --git a/src/test/run-pass/associated-types-normalize-in-bounds.rs b/src/test/run-pass/associated-types-normalize-in-bounds.rs
index 742bab0578e..94cfcb83653 100644
--- a/src/test/run-pass/associated-types-normalize-in-bounds.rs
+++ b/src/test/run-pass/associated-types-normalize-in-bounds.rs
@@ -11,15 +11,17 @@
// 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 @@ impl<T> SliceExt2 for [T] {
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 {}
}
diff --git a/src/test/run-pass/associated-types-normalize-unifield-struct.rs b/src/test/run-pass/associated-types-normalize-unifield-struct.rs
index 5aafe93067c..2288e19aae0 100644
--- a/src/test/run-pass/associated-types-normalize-unifield-struct.rs
+++ b/src/test/run-pass/associated-types-normalize-unifield-struct.rs
@@ -13,7 +13,10 @@
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; }
diff --git a/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs b/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs
index 0a1a8589dec..c65d2db9b0c 100644
--- a/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs
+++ b/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs
@@ -13,6 +13,8 @@
trait Int
{
type T;
+
+ fn dummy(&self) { }
}
trait NonZero
diff --git a/src/test/run-pass/associated-types-projection-in-object-type.rs b/src/test/run-pass/associated-types-projection-in-object-type.rs
index 44dd49b7297..a9c34a605ce 100644
--- a/src/test/run-pass/associated-types-projection-in-object-type.rs
+++ b/src/test/run-pass/associated-types-projection-in-object-type.rs
@@ -18,6 +18,8 @@ use std::cell::RefCell;
pub trait Subscriber {
type Input;
+
+ fn dummy(&self) { }
}
pub trait Publisher<'a> {
diff --git a/src/test/run-pass/associated-types-projection-in-supertrait.rs b/src/test/run-pass/associated-types-projection-in-supertrait.rs
index e6fec675b03..4d2358fae27 100644
--- a/src/test/run-pass/associated-types-projection-in-supertrait.rs
+++ b/src/test/run-pass/associated-types-projection-in-supertrait.rs
@@ -14,6 +14,8 @@
trait A
{
type TA;
+
+ fn dummy(&self) { }
}
trait B<TB>
diff --git a/src/test/run-pass/associated-types-projection-in-where-clause.rs b/src/test/run-pass/associated-types-projection-in-where-clause.rs
index 10a459f3c36..3f3f4fbd1d6 100644
--- a/src/test/run-pass/associated-types-projection-in-where-clause.rs
+++ b/src/test/run-pass/associated-types-projection-in-where-clause.rs
@@ -13,6 +13,8 @@
trait Int
{
type T;
+
+ fn dummy(&self) { }
}
trait NonZero
diff --git a/src/test/run-pass/associated-types-ref-in-struct-literal.rs b/src/test/run-pass/associated-types-ref-in-struct-literal.rs
index 022c8f4cd01..67fe11d8fed 100644
--- a/src/test/run-pass/associated-types-ref-in-struct-literal.rs
+++ b/src/test/run-pass/associated-types-ref-in-struct-literal.rs
@@ -12,6 +12,8 @@
pub trait Foo {
type Bar;
+
+ fn dummy(&self) { }
}
impl Foo for int {
diff --git a/src/test/run-pass/associated-types-resolve-lifetime.rs b/src/test/run-pass/associated-types-resolve-lifetime.rs
index e7a8061a346..a4b0b1a6e03 100644
--- a/src/test/run-pass/associated-types-resolve-lifetime.rs
+++ b/src/test/run-pass/associated-types-resolve-lifetime.rs
@@ -15,6 +15,8 @@ trait Get<T> {
trait Trait<'a> {
type T: 'static;
type U: Get<&'a int>;
+
+ fn dummy(&'a self) { }
}
fn main() {}
diff --git a/src/test/run-pass/associated-types-struct-field-named.rs b/src/test/run-pass/associated-types-struct-field-named.rs
index 1ded34ff3ff..8667f6c8430 100644
--- a/src/test/run-pass/associated-types-struct-field-named.rs
+++ b/src/test/run-pass/associated-types-struct-field-named.rs
@@ -13,6 +13,8 @@
pub trait UnifyKey {
type Value;
+
+ fn dummy(&self) { }
}
pub struct Node<K:UnifyKey> {
diff --git a/src/test/run-pass/associated-types-struct-field-numbered.rs b/src/test/run-pass/associated-types-struct-field-numbered.rs
index 3669dec4fbd..9503f78a71b 100644
--- a/src/test/run-pass/associated-types-struct-field-numbered.rs
+++ b/src/test/run-pass/associated-types-struct-field-numbered.rs
@@ -13,6 +13,8 @@
pub trait UnifyKey {
type Value;
+
+ fn dummy(&self) { }
}
pub struct Node<K:UnifyKey>(K, K::Value);
diff --git a/src/test/run-pass/associated-types-sugar-path.rs b/src/test/run-pass/associated-types-sugar-path.rs
index 3b70e941ac5..c068065ac6a 100644
--- a/src/test/run-pass/associated-types-sugar-path.rs
+++ b/src/test/run-pass/associated-types-sugar-path.rs
@@ -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!();
diff --git a/src/test/run-pass/bitv-perf-test.rs b/src/test/run-pass/bitv-perf-test.rs
index b6d428924e3..7bb9f042fe8 100644
--- a/src/test/run-pass/bitv-perf-test.rs
+++ b/src/test/run-pass/bitv-perf-test.rs
@@ -13,11 +13,11 @@
#![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);
}
diff --git a/src/test/run-pass/borrowck-trait-lifetime.rs b/src/test/run-pass/borrowck-trait-lifetime.rs
index b39f03a93c9..a2b0fa56635 100644
--- a/src/test/run-pass/borrowck-trait-lifetime.rs
+++ b/src/test/run-pass/borrowck-trait-lifetime.rs
@@ -12,8 +12,11 @@
// 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
diff --git a/src/test/run-pass/bug-7295.rs b/src/test/run-pass/bug-7295.rs
index ea711d78dd2..143ebfdabfa 100644
--- a/src/test/run-pass/bug-7295.rs
+++ b/src/test/run-pass/bug-7295.rs
@@ -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);
}
}
diff --git a/src/test/run-pass/builtin-superkinds-in-metadata.rs b/src/test/run-pass/builtin-superkinds-in-metadata.rs
index c115415bb9b..7eaed910124 100644
--- a/src/test/run-pass/builtin-superkinds-in-metadata.rs
+++ b/src/test/run-pass/builtin-superkinds-in-metadata.rs
@@ -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);
diff --git a/src/test/run-pass/builtin-superkinds-phantom-typaram.rs b/src/test/run-pass/builtin-superkinds-phantom-typaram.rs
index 7e1b2821937..964c28dc945 100644
--- a/src/test/run-pass/builtin-superkinds-phantom-typaram.rs
+++ b/src/test/run-pass/builtin-superkinds-phantom-typaram.rs
@@ -12,10 +12,12 @@
// 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() { }
diff --git a/src/test/run-pass/c-stack-returning-int64.rs b/src/test/run-pass/c-stack-returning-int64.rs
index 22c322b86c9..6246ee9c6c4 100644
--- a/src/test/run-pass/c-stack-returning-int64.rs
+++ b/src/test/run-pass/c-stack-returning-int64.rs
@@ -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 }
}
diff --git a/src/test/run-pass/class-typarams.rs b/src/test/run-pass/class-typarams.rs
index 68457095944..b56a749d33b 100644
--- a/src/test/run-pass/class-typarams.rs
+++ b/src/test/run-pass/class-typarams.rs
@@ -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 @@ impl<U> cat<U> {
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
}
}
diff --git a/src/test/run-pass/const-polymorphic-paths.rs b/src/test/run-pass/const-polymorphic-paths.rs
index f8f92a56adb..dce12030f79 100644
--- a/src/test/run-pass/const-polymorphic-paths.rs
+++ b/src/test/run-pass/const-polymorphic-paths.rs
@@ -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 @@ 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 @@ 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());
}
diff --git a/src/test/run-pass/deriving-hash.rs b/src/test/run-pass/deriving-hash.rs
index 02ab7e5db5b..5fe7c8bb94b 100644
--- a/src/test/run-pass/deriving-hash.rs
+++ b/src/test/run-pass/deriving-hash.rs
@@ -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)
}
diff --git a/src/test/run-pass/deriving-meta-multiple.rs b/src/test/run-pass/deriving-meta-multiple.rs
index f45dce9da63..62ec2f8e590 100644
--- a/src/test/run-pass/deriving-meta-multiple.rs
+++ b/src/test/run-pass/deriving-meta-multiple.rs
@@ -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};
diff --git a/src/test/run-pass/deriving-meta.rs b/src/test/run-pass/deriving-meta.rs
index d6a2fad08ed..82cf9db3232 100644
--- a/src/test/run-pass/deriving-meta.rs
+++ b/src/test/run-pass/deriving-meta.rs
@@ -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};
diff --git a/src/test/run-pass/dst-coercions.rs b/src/test/run-pass/dst-coercions.rs
index dbad546ce1a..30ed0b8e402 100644
--- a/src/test/run-pass/dst-coercions.rs
+++ b/src/test/run-pass/dst-coercions.rs
@@ -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() {
diff --git a/src/test/run-pass/enum-null-pointer-opt.rs b/src/test/run-pass/enum-null-pointer-opt.rs
index 797c26556aa..023376ce473 100644
--- a/src/test/run-pass/enum-null-pointer-opt.rs
+++ b/src/test/run-pass/enum-null-pointer-opt.rs
@@ -16,7 +16,7 @@ use std::mem::size_of;
use std::rc::Rc;
use std::sync::Arc;
-trait Trait {}
+trait Trait { fn dummy(&self) { } }
fn main() {
// Functions
diff --git a/src/test/run-pass/explicit-self-generic.rs b/src/test/run-pass/explicit-self-generic.rs
index 066a5f9580a..382c5c58e92 100644
--- a/src/test/run-pass/explicit-self-generic.rs
+++ b/src/test/run-pass/explicit-self-generic.rs
@@ -15,21 +15,19 @@
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/foreign-fn-linkname.rs b/src/test/run-pass/foreign-fn-linkname.rs
index 592ab7d0e6e..24b711328a1 100644
--- a/src/test/run-pass/foreign-fn-linkname.rs
+++ b/src/test/run-pass/foreign-fn-linkname.rs
@@ -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
}
diff --git a/src/test/run-pass/generic-default-type-params-cross-crate.rs b/src/test/run-pass/generic-default-type-params-cross-crate.rs
index ed8c6e73255..bf02b82d1a0 100644
--- a/src/test/run-pass/generic-default-type-params-cross-crate.rs
+++ b/src/test/run-pass/generic-default-type-params-cross-crate.rs
@@ -12,13 +12,13 @@
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 };
}
diff --git a/src/test/run-pass/hrtb-opt-in-copy.rs b/src/test/run-pass/hrtb-opt-in-copy.rs
index 9c9f95f61e9..7b16bb867e7 100644
--- a/src/test/run-pass/hrtb-opt-in-copy.rs
+++ b/src/test/run-pass/hrtb-opt-in-copy.rs
@@ -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)]
diff --git a/src/test/run-pass/inner-static.rs b/src/test/run-pass/inner-static.rs
index f9b430c1553..e4026a8fd01 100644
--- a/src/test/run-pass/inner-static.rs
+++ b/src/test/run-pass/inner-static.rs
@@ -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);
diff --git a/src/test/run-pass/issue-10456.rs b/src/test/run-pass/issue-10456.rs
index b714d87f4ef..da73c4b27ac 100644
--- a/src/test/run-pass/issue-10456.rs
+++ b/src/test/run-pass/issue-10456.rs
@@ -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) {}
diff --git a/src/test/run-pass/issue-10802.rs b/src/test/run-pass/issue-10802.rs
index de2b4c51e52..174a69e1135 100644
--- a/src/test/run-pass/issue-10802.rs
+++ b/src/test/run-pass/issue-10802.rs
@@ -29,7 +29,7 @@ impl Drop for DroppableEnum {
}
}
-trait MyTrait { }
+trait MyTrait { fn dummy(&self) { } }
impl MyTrait for Box<DroppableStruct> {}
impl MyTrait for Box<DroppableEnum> {}
diff --git a/src/test/run-pass/issue-10902.rs b/src/test/run-pass/issue-10902.rs
index 324a1701b2f..7fab6662ee0 100644
--- a/src/test/run-pass/issue-10902.rs
+++ b/src/test/run-pass/issue-10902.rs
@@ -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 mod two_tuple {
}
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 }
diff --git a/src/test/run-pass/issue-11205.rs b/src/test/run-pass/issue-11205.rs
index d7c6c1b1bb2..1325b51a54f 100644
--- a/src/test/run-pass/issue-11205.rs
+++ b/src/test/run-pass/issue-11205.rs
@@ -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]) {}
diff --git a/src/test/run-pass/issue-11384.rs b/src/test/run-pass/issue-11384.rs
index a511149b05e..26634fabf5a 100644
--- a/src/test/run-pass/issue-11384.rs
+++ b/src/test/run-pass/issue-11384.rs
@@ -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) {}
diff --git a/src/test/run-pass/issue-11612.rs b/src/test/run-pass/issue-11612.rs
index fa25d25df05..3c69377b375 100644
--- a/src/test/run-pass/issue-11612.rs
+++ b/src/test/run-pass/issue-11612.rs
@@ -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
diff --git a/src/test/run-pass/issue-11677.rs b/src/test/run-pass/issue-11677.rs
index 6fa45058694..7cccac4483d 100644
--- a/src/test/run-pass/issue-11677.rs
+++ b/src/test/run-pass/issue-11677.rs
@@ -14,13 +14,18 @@
// 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};
diff --git a/src/test/run-pass/issue-11736.rs b/src/test/run-pass/issue-11736.rs
index d9bae6886fa..b901e95ff55 100644
--- a/src/test/run-pass/issue-11736.rs
+++ b/src/test/run-pass/issue-11736.rs
@@ -10,13 +10,13 @@
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] {
diff --git a/src/test/run-pass/issue-13105.rs b/src/test/run-pass/issue-13105.rs
index 7fab36bd64e..64807dc44e0 100644
--- a/src/test/run-pass/issue-13105.rs
+++ b/src/test/run-pass/issue-13105.rs
@@ -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) {}
}
diff --git a/src/test/run-pass/issue-14399.rs b/src/test/run-pass/issue-14399.rs
index 7e533c2cf86..db7eacce9d1 100644
--- a/src/test/run-pass/issue-14399.rs
+++ b/src/test/run-pass/issue-14399.rs
@@ -19,7 +19,7 @@
#[derive(Clone)]
struct B1;
-trait A {}
+trait A { fn foo(&self) {} }
impl A for B1 {}
fn main() {
diff --git a/src/test/run-pass/issue-14589.rs b/src/test/run-pass/issue-14589.rs
index d9763baa826..71d88ee6215 100644
--- a/src/test/run-pass/issue-14589.rs
+++ b/src/test/run-pass/issue-14589.rs
@@ -17,17 +17,18 @@
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 {}
diff --git a/src/test/run-pass/issue-14958.rs b/src/test/run-pass/issue-14958.rs
index 814a743648d..6335f79be6c 100644
--- a/src/test/run-pass/issue-14958.rs
+++ b/src/test/run-pass/issue-14958.rs
@@ -10,7 +10,7 @@
#![feature(unboxed_closures)]
-trait Foo {}
+trait Foo { fn dummy(&self) { }}
struct Bar;
diff --git a/src/test/run-pass/issue-14959.rs b/src/test/run-pass/issue-14959.rs
index 33281d7d78f..53d0f7dae05 100644
--- a/src/test/run-pass/issue-14959.rs
+++ b/src/test/run-pass/issue-14959.rs
@@ -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 @@ impl Alloy {
}
}
-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),)) {}
diff --git a/src/test/run-pass/issue-15858.rs b/src/test/run-pass/issue-15858.rs
index c75c6725461..6a4f78442d1 100644
--- a/src/test/run-pass/issue-15858.rs
+++ b/src/test/run-pass/issue-15858.rs
@@ -12,21 +12,21 @@
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 @@ impl<'b, B: Bar<'b>> Drop for Foo<B> {
fn main() {
{
- let _x: Foo<BarImpl> = Foo;
+ let _x: Foo<BarImpl> = Foo(BarImpl);
}
unsafe {
assert_eq!(DROP_RAN, true);
diff --git a/src/test/run-pass/issue-16596.rs b/src/test/run-pass/issue-16596.rs
index e01de3a3262..1ba7b142e5e 100644
--- a/src/test/run-pass/issue-16596.rs
+++ b/src/test/run-pass/issue-16596.rs
@@ -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;
diff --git a/src/test/run-pass/issue-16643.rs b/src/test/run-pass/issue-16643.rs
index b118c9573cd..4e57c55c5f7 100644
--- a/src/test/run-pass/issue-16643.rs
+++ b/src/test/run-pass/issue-16643.rs
@@ -13,5 +13,5 @@
extern crate "issue-16643" as i;
pub fn main() {
- i::TreeBuilder::<uint>.process_token();
+ i::TreeBuilder { h: 3u }.process_token();
}
diff --git a/src/test/run-pass/issue-17662.rs b/src/test/run-pass/issue-17662.rs
index 45e70f59f33..7bd41cc5b52 100644
--- a/src/test/run-pass/issue-17662.rs
+++ b/src/test/run-pass/issue-17662.rs
@@ -12,12 +12,14 @@
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);
}
diff --git a/src/test/run-pass/issue-17732.rs b/src/test/run-pass/issue-17732.rs
index b4bd55da597..de9611f2592 100644
--- a/src/test/run-pass/issue-17732.rs
+++ b/src/test/run-pass/issue-17732.rs
@@ -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() {}
diff --git a/src/test/run-pass/issue-17771.rs b/src/test/run-pass/issue-17771.rs
index 1e9550acef4..2f1b0342b8e 100644
--- a/src/test/run-pass/issue-17771.rs
+++ b/src/test/run-pass/issue-17771.rs
@@ -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) {}
diff --git a/src/test/run-pass/issue-17816.rs b/src/test/run-pass/issue-17816.rs
index f8fbd680dcb..a976eccf89e 100644
--- a/src/test/run-pass/issue-17816.rs
+++ b/src/test/run-pass/issue-17816.rs
@@ -10,9 +10,11 @@
#![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![]);
}
diff --git a/src/test/run-pass/issue-17904.rs b/src/test/run-pass/issue-17904.rs
index 3ce347d67e3..58a0872a571 100644
--- a/src/test/run-pass/issue-17904.rs
+++ b/src/test/run-pass/issue-17904.rs
@@ -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 {
diff --git a/src/test/run-pass/issue-18232.rs b/src/test/run-pass/issue-18232.rs
index 15cf5870d40..67b3239d351 100644
--- a/src/test/run-pass/issue-18232.rs
+++ b/src/test/run-pass/issue-18232.rs
@@ -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 @@ impl CursorNavigator for SimpleNavigator {
}
fn main() {
- let mut c = Cursor;
+ let mut c = Cursor(::std::marker::PhantomData);
let n = SimpleNavigator;
n.init_cursor(&mut c);
}
diff --git a/src/test/run-pass/issue-18906.rs b/src/test/run-pass/issue-18906.rs
index 11ffb4198da..16dd84315ed 100644
--- a/src/test/run-pass/issue-18906.rs
+++ b/src/test/run-pass/issue-18906.rs
@@ -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
diff --git a/src/test/run-pass/issue-19121.rs b/src/test/run-pass/issue-19121.rs
index d95f74ef2a2..222f67af437 100644
--- a/src/test/run-pass/issue-19121.rs
+++ b/src/test/run-pass/issue-19121.rs
@@ -13,6 +13,8 @@
trait Foo {
type A;
+
+ fn dummy(&self) { }
}
fn bar(x: &Foo) {}
diff --git a/src/test/run-pass/issue-19129-2.rs b/src/test/run-pass/issue-19129-2.rs
index d6b3a1908b8..cf0f48e025a 100644
--- a/src/test/run-pass/issue-19129-2.rs
+++ b/src/test/run-pass/issue-19129-2.rs
@@ -11,7 +11,7 @@
trait Trait<Input> {
type Output;
- fn method() -> bool { false }
+ fn method(&self, i: Input) -> bool { false }
}
fn main() {}
diff --git a/src/test/run-pass/issue-19135.rs b/src/test/run-pass/issue-19135.rs
index 031a63ba474..5e6dd567d63 100644
--- a/src/test/run-pass/issue-19135.rs
+++ b/src/test/run-pass/issue-19135.rs
@@ -10,13 +10,15 @@
#![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));
}
diff --git a/src/test/run-pass/issue-19358.rs b/src/test/run-pass/issue-19358.rs
index ff657376ecc..8b5269ab92f 100644
--- a/src/test/run-pass/issue-19358.rs
+++ b/src/test/run-pass/issue-19358.rs
@@ -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> {
diff --git a/src/test/run-pass/issue-19398.rs b/src/test/run-pass/issue-19398.rs
index 1196162568a..e603167b26b 100644
--- a/src/test/run-pass/issue-19398.rs
+++ b/src/test/run-pass/issue-19398.rs
@@ -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() {}
diff --git a/src/test/run-pass/issue-19479.rs b/src/test/run-pass/issue-19479.rs
index 91bc645b2d4..38a7af3a695 100644
--- a/src/test/run-pass/issue-19479.rs
+++ b/src/test/run-pass/issue-19479.rs
@@ -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;
diff --git a/src/test/run-pass/issue-19631.rs b/src/test/run-pass/issue-19631.rs
index 43116f63641..7bb0d055b84 100644
--- a/src/test/run-pass/issue-19631.rs
+++ b/src/test/run-pass/issue-19631.rs
@@ -10,6 +10,7 @@
trait PoolManager {
type C;
+ fn dummy(&self) { }
}
struct InnerPool<M> {
diff --git a/src/test/run-pass/issue-19632.rs b/src/test/run-pass/issue-19632.rs
index 01a073a6889..4339339d74c 100644
--- a/src/test/run-pass/issue-19632.rs
+++ b/src/test/run-pass/issue-19632.rs
@@ -10,6 +10,7 @@
trait PoolManager {
type C;
+ fn dummy(&self) { }
}
struct InnerPool<M: PoolManager> {
diff --git a/src/test/run-pass/issue-20055-box-trait.rs b/src/test/run-pass/issue-20055-box-trait.rs
index 836e78b5b51..572a0d82528 100644
--- a/src/test/run-pass/issue-20055-box-trait.rs
+++ b/src/test/run-pass/issue-20055-box-trait.rs
@@ -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] { }
diff --git a/src/test/run-pass/issue-20343.rs b/src/test/run-pass/issue-20343.rs
index 79034a4a4a6..2f9e8feed24 100644
--- a/src/test/run-pass/issue-20343.rs
+++ b/src/test/run-pass/issue-20343.rs
@@ -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 {
diff --git a/src/test/run-pass/issue-20763-1.rs b/src/test/run-pass/issue-20763-1.rs
index 911ee715da2..97c06ac9826 100644
--- a/src/test/run-pass/issue-20763-1.rs
+++ b/src/test/run-pass/issue-20763-1.rs
@@ -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; }
diff --git a/src/test/run-pass/issue-20763-2.rs b/src/test/run-pass/issue-20763-2.rs
index a17c7b6ade4..d9701763571 100644
--- a/src/test/run-pass/issue-20763-2.rs
+++ b/src/test/run-pass/issue-20763-2.rs
@@ -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; }
diff --git a/src/test/run-pass/issue-21363.rs b/src/test/run-pass/issue-21363.rs
index 2fc1d9fd643..71bb3d39fe1 100644
--- a/src/test/run-pass/issue-21363.rs
+++ b/src/test/run-pass/issue-21363.rs
@@ -12,6 +12,7 @@
trait Iterator {
type Item;
+ fn dummy(&self) { }
}
impl<'a, T> Iterator for &'a mut (Iterator<Item=T> + 'a) {
diff --git a/src/test/run-pass/issue-21909.rs b/src/test/run-pass/issue-21909.rs
index 5bbc90b2606..55b61dd1945 100644
--- a/src/test/run-pass/issue-21909.rs
+++ b/src/test/run-pass/issue-21909.rs
@@ -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 () { }
diff --git a/src/test/run-pass/issue-2311-2.rs b/src/test/run-pass/issue-2311-2.rs
index e0b98ab1965..5529d51b408 100644
--- a/src/test/run-pass/issue-2311-2.rs
+++ b/src/test/run-pass/issue-2311-2.rs
@@ -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,
}
diff --git a/src/test/run-pass/issue-2311.rs b/src/test/run-pass/issue-2311.rs
index dc873ed08d7..b6b3114e2a4 100644
--- a/src/test/run-pass/issue-2311.rs
+++ b/src/test/run-pass/issue-2311.rs
@@ -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;
}
diff --git a/src/test/run-pass/issue-2312.rs b/src/test/run-pass/issue-2312.rs
index 8c597552d75..3f273b56efd 100644
--- a/src/test/run-pass/issue-2312.rs
+++ b/src/test/run-pass/issue-2312.rs
@@ -10,7 +10,7 @@
// Testing that the B's are resolved
-trait clam<A> { }
+trait clam<A> { fn get(self) -> A; }
struct foo(int);
diff --git a/src/test/run-pass/issue-2383.rs b/src/test/run-pass/issue-2383.rs
index b8136323df6..a5a05283f80 100644
--- a/src/test/run-pass/issue-2383.rs
+++ b/src/test/run-pass/issue-2383.rs
@@ -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);
}
diff --git a/src/test/run-pass/issue-2611-3.rs b/src/test/run-pass/issue-2611-3.rs
index 2608c89d155..c005699ce30 100644
--- a/src/test/run-pass/issue-2611-3.rs
+++ b/src/test/run-pass/issue-2611-3.rs
@@ -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
}
diff --git a/src/test/run-pass/issue-2734.rs b/src/test/run-pass/issue-2734.rs
index 7ca439a1a19..a7b53db6b05 100644
--- a/src/test/run-pass/issue-2734.rs
+++ b/src/test/run-pass/issue-2734.rs
@@ -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> {
diff --git a/src/test/run-pass/issue-2735.rs b/src/test/run-pass/issue-2735.rs
index 962359537bf..1594b94879c 100644
--- a/src/test/run-pass/issue-2735.rs
+++ b/src/test/run-pass/issue-2735.rs
@@ -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> {
diff --git a/src/test/run-pass/issue-4107.rs b/src/test/run-pass/issue-4107.rs
index 2ed662e9f2d..d660f300ada 100644
--- a/src/test/run-pass/issue-4107.rs
+++ b/src/test/run-pass/issue-4107.rs
@@ -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 } }
}
diff --git a/src/test/run-pass/issue-5192.rs b/src/test/run-pass/issue-5192.rs
index bb79cd4d046..a6f3771bf62 100644
--- a/src/test/run-pass/issue-5192.rs
+++ b/src/test/run-pass/issue-5192.rs
@@ -12,6 +12,7 @@
#![feature(box_syntax)]
pub trait EventLoop {
+ fn dummy(&self) { }
}
pub struct UvEventLoop {
diff --git a/src/test/run-pass/issue-5708.rs b/src/test/run-pass/issue-5708.rs
index fd39bcc6b61..59bca87bed0 100644
--- a/src/test/run-pass/issue-5708.rs
+++ b/src/test/run-pass/issue-5708.rs
@@ -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)> ,
diff --git a/src/test/run-pass/issue-6128.rs b/src/test/run-pass/issue-6128.rs
index d96862b588f..1746a6281dc 100644
--- a/src/test/run-pass/issue-6128.rs
+++ b/src/test/run-pass/issue-6128.rs
@@ -17,6 +17,7 @@ use std::collections::HashMap;
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() {
diff --git a/src/test/run-pass/issue-6318.rs b/src/test/run-pass/issue-6318.rs
index 1d8fe8bfce8..6e608d34bd5 100644
--- a/src/test/run-pass/issue-6318.rs
+++ b/src/test/run-pass/issue-6318.rs
@@ -15,7 +15,9 @@ pub enum Thing {
A(Box<Foo+'static>)
}
-pub trait Foo {}
+pub trait Foo {
+ fn dummy(&self) { }
+}
pub struct Struct;
diff --git a/src/test/run-pass/issue-7575.rs b/src/test/run-pass/issue-7575.rs
index 225213db6a4..77cfc7f0cf6 100644
--- a/src/test/run-pass/issue-7575.rs
+++ b/src/test/run-pass/issue-7575.rs
@@ -10,6 +10,7 @@
trait Foo {
fn new() -> bool { false }
+ fn dummy(&self) { }
}
trait Bar {
diff --git a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs
index b6dfbb1ca42..736860947f2 100644
--- a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs
+++ b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs
@@ -19,7 +19,10 @@
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>; }
diff --git a/src/test/run-pass/issue-7911.rs b/src/test/run-pass/issue-7911.rs
index 86948ebcb91..3eb593708be 100644
--- a/src/test/run-pass/issue-7911.rs
+++ b/src/test/run-pass/issue-7911.rs
@@ -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 }
diff --git a/src/test/run-pass/issue-8248.rs b/src/test/run-pass/issue-8248.rs
index 377b9ce262c..7bc8dbe616f 100644
--- a/src/test/run-pass/issue-8248.rs
+++ b/src/test/run-pass/issue-8248.rs
@@ -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 {}
diff --git a/src/test/run-pass/issue-8249.rs b/src/test/run-pass/issue-8249.rs
index 44f07def531..83c9e9bf450 100644
--- a/src/test/run-pass/issue-8249.rs
+++ b/src/test/run-pass/issue-8249.rs
@@ -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 {}
diff --git a/src/test/run-pass/issue-9719.rs b/src/test/run-pass/issue-9719.rs
index 8fc86eb49e7..aa1e65efaa4 100644
--- a/src/test/run-pass/issue-9719.rs
+++ b/src/test/run-pass/issue-9719.rs
@@ -13,7 +13,9 @@ mod a {
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 @@ mod a {
}
mod b {
- trait X {}
+ trait X {
+ fn dummy(&self) { }
+ }
impl X for int {}
struct Y<'a>{
x:Option<&'a (X+'a)>,
diff --git a/src/test/run-pass/lint-cstack.rs b/src/test/run-pass/lint-cstack.rs
index 2194453aac2..f180ffcd4e8 100644
--- a/src/test/run-pass/lint-cstack.rs
+++ b/src/test/run-pass/lint-cstack.rs
@@ -15,7 +15,7 @@ extern {
}
trait A {
- fn foo() {
+ fn foo(&self) {
unsafe {
rust_get_test_int();
}
diff --git a/src/test/run-pass/method-early-bound-lifetimes-on-self.rs b/src/test/run-pass/method-early-bound-lifetimes-on-self.rs
index 25ce0d774eb..cec9753a2fe 100644
--- a/src/test/run-pass/method-early-bound-lifetimes-on-self.rs
+++ b/src/test/run-pass/method-early-bound-lifetimes-on-self.rs
@@ -13,7 +13,11 @@
#![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 @@ impl CursorNavigator for SimpleNavigator {
}
fn main() {
- let mut c = Cursor;
+ let mut c = Cursor { m: marker::PhantomData };
let n = SimpleNavigator;
n.init_cursor(&mut c);
}
diff --git a/src/test/run-pass/method-recursive-blanket-impl.rs b/src/test/run-pass/method-recursive-blanket-impl.rs
index 338bd89ab5c..15eb2ae2e4b 100644
--- a/src/test/run-pass/method-recursive-blanket-impl.rs
+++ b/src/test/run-pass/method-recursive-blanket-impl.rs
@@ -17,16 +17,16 @@ use std::marker::Sized;
// 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)
}
}
diff --git a/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs b/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs
index eb17aa78bd9..1164ef1a3c9 100644
--- a/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs
+++ b/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs
@@ -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 {
diff --git a/src/test/run-pass/overloaded-autoderef-vtable.rs b/src/test/run-pass/overloaded-autoderef-vtable.rs
index be2b309b821..d50f2efe0e7 100644
--- a/src/test/run-pass/overloaded-autoderef-vtable.rs
+++ b/src/test/run-pass/overloaded-autoderef-vtable.rs
@@ -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 @@ impl Foo {
}
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);
}
diff --git a/src/test/run-pass/overloaded-calls-param-vtables.rs b/src/test/run-pass/overloaded-calls-param-vtables.rs
index 2838909c1be..2ef9e08134c 100644
--- a/src/test/run-pass/overloaded-calls-param-vtables.rs
+++ b/src/test/run-pass/overloaded-calls-param-vtables.rs
@@ -12,10 +12,11 @@
#![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 @@ impl<'a, A: Add<i32, Output=i32>> Fn<(A,)> for G<A> {
fn main() {
// ICE trigger
- G(1_i32);
+ (G(PhantomData))(1_i32);
}
diff --git a/src/test/run-pass/parameterized-trait-with-bounds.rs b/src/test/run-pass/parameterized-trait-with-bounds.rs
index 840e58848a7..061c9168955 100644
--- a/src/test/run-pass/parameterized-trait-with-bounds.rs
+++ b/src/test/run-pass/parameterized-trait-with-bounds.rs
@@ -11,12 +11,12 @@
#![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)) {}
diff --git a/src/test/run-pass/privacy-ns.rs b/src/test/run-pass/privacy-ns.rs
index f3380352f5f..e9b8e694d60 100644
--- a/src/test/run-pass/privacy-ns.rs
+++ b/src/test/run-pass/privacy-ns.rs
@@ -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;
diff --git a/src/test/run-pass/regions-assoc-type-static-bound.rs b/src/test/run-pass/regions-assoc-type-static-bound.rs
index 6b629a9035d..80ae371e509 100644
--- a/src/test/run-pass/regions-assoc-type-static-bound.rs
+++ b/src/test/run-pass/regions-assoc-type-static-bound.rs
@@ -11,7 +11,10 @@
// 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>() {}
diff --git a/src/test/run-pass/regions-bound-lists-feature-gate-2.rs b/src/test/run-pass/regions-bound-lists-feature-gate-2.rs
index 0a95a89d57c..a06e0f6da78 100644
--- a/src/test/run-pass/regions-bound-lists-feature-gate-2.rs
+++ b/src/test/run-pass/regions-bound-lists-feature-gate-2.rs
@@ -12,7 +12,9 @@
#![feature(issue_5723_bootstrap)]
-trait Foo { }
+trait Foo {
+ fn dummy(&self) { }
+}
fn foo<'a, 'b, 'c:'a+'b, 'd>() {
}
diff --git a/src/test/run-pass/regions-bound-lists-feature-gate.rs b/src/test/run-pass/regions-bound-lists-feature-gate.rs
index c5baecf7272..996583dc6de 100644
--- a/src/test/run-pass/regions-bound-lists-feature-gate.rs
+++ b/src/test/run-pass/regions-bound-lists-feature-gate.rs
@@ -12,8 +12,9 @@
#![feature(issue_5723_bootstrap)]
-
-trait Foo { }
+trait Foo {
+ fn dummy(&self) { }
+}
fn foo<'a>(x: Box<Foo + 'a>) {
}
diff --git a/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs b/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs
index 978383c2447..bdc0d41c94e 100644
--- a/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs
+++ b/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs
@@ -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;
}
diff --git a/src/test/run-pass/regions-early-bound-trait-param.rs b/src/test/run-pass/regions-early-bound-trait-param.rs
index 6fcfaf58a02..3f434a4838d 100644
--- a/src/test/run-pass/regions-early-bound-trait-param.rs
+++ b/src/test/run-pass/regions-early-bound-trait-param.rs
@@ -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 @@ impl<'s> Trait<'s> for (int,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-issue-21422.rs b/src/test/run-pass/regions-issue-21422.rs
new file mode 100644
index 00000000000..c59bf15afc3
--- /dev/null
+++ b/src/test/run-pass/regions-issue-21422.rs
@@ -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() {}
diff --git a/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs b/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs
index d3464f01203..5964ac65d5f 100644
--- a/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs
+++ b/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs
@@ -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;
diff --git a/src/test/run-pass/regions-no-variance-from-fn-generics.rs b/src/test/run-pass/regions-no-variance-from-fn-generics.rs
index a35ab1bfc0c..80c478afa64 100644
--- a/src/test/run-pass/regions-no-variance-from-fn-generics.rs
+++ b/src/test/run-pass/regions-no-variance-from-fn-generics.rs
@@ -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;
diff --git a/src/test/run-pass/regions-refcell.rs b/src/test/run-pass/regions-refcell.rs
index 10c9aef7c3b..a224017780e 100644
--- a/src/test/run-pass/regions-refcell.rs
+++ b/src/test/run-pass/regions-refcell.rs
@@ -19,7 +19,7 @@ use std::cell::RefCell;
#[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);
}
diff --git a/src/test/run-pass/rename-directory.rs b/src/test/run-pass/rename-directory.rs
index a21b5aa1dab..abe6ffe7d4c 100644
--- a/src/test/run-pass/rename-directory.rs
+++ b/src/test/run-pass/rename-directory.rs
@@ -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,
diff --git a/src/test/run-pass/self-impl.rs b/src/test/run-pass/self-impl.rs
index 40a4dc52a70..af2b2de8ab8 100644
--- a/src/test/run-pass/self-impl.rs
+++ b/src/test/run-pass/self-impl.rs
@@ -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>> {
diff --git a/src/test/run-pass/send_str_hashmap.rs b/src/test/run-pass/send_str_hashmap.rs
index c58654670d1..33e4fa85bcb 100644
--- a/src/test/run-pass/send_str_hashmap.rs
+++ b/src/test/run-pass/send_str_hashmap.rs
@@ -13,7 +13,7 @@ extern crate collections;
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();
diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs
index 438724a2b06..3390369242d 100644
--- a/src/test/run-pass/send_str_treemap.rs
+++ b/src/test/run-pass/send_str_treemap.rs
@@ -13,7 +13,7 @@ extern crate collections;
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();
diff --git a/src/test/run-pass/simple-match-generic-tag.rs b/src/test/run-pass/simple-match-generic-tag.rs
index 7ed8cb434ca..2217dddbd21 100644
--- a/src/test/run-pass/simple-match-generic-tag.rs
+++ b/src/test/run-pass/simple-match-generic-tag.rs
@@ -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(_) => { }
+ }
}
diff --git a/src/test/run-pass/syntax-trait-polarity.rs b/src/test/run-pass/syntax-trait-polarity.rs
index 3344844d49f..340ad2a531a 100644
--- a/src/test/run-pass/syntax-trait-polarity.rs
+++ b/src/test/run-pass/syntax-trait-polarity.rs
@@ -10,17 +10,17 @@
#![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> {}
diff --git a/src/test/run-pass/trailing-comma.rs b/src/test/run-pass/trailing-comma.rs
index b5ae259bc63..76c62a83e75 100644
--- a/src/test/run-pass/trailing-comma.rs
+++ b/src/test/run-pass/trailing-comma.rs
@@ -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,);
diff --git a/src/test/run-pass/trait-bounds-basic.rs b/src/test/run-pass/trait-bounds-basic.rs
index d03496403ad..ed25bf8b02e 100644
--- a/src/test/run-pass/trait-bounds-basic.rs
+++ b/src/test/run-pass/trait-bounds-basic.rs
@@ -9,7 +9,7 @@
// except according to those terms.
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
}
fn b(_x: Box<Foo+Send>) {
diff --git a/src/test/run-pass/trait-bounds-on-structs-and-enums.rs b/src/test/run-pass/trait-bounds-on-structs-and-enums.rs
index e3234f03754..976120908b2 100644
--- a/src/test/run-pass/trait-bounds-on-structs-and-enums.rs
+++ b/src/test/run-pass/trait-bounds-on-structs-and-enums.rs
@@ -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>) {}
}
diff --git a/src/test/run-pass/trait-bounds-recursion.rs b/src/test/run-pass/trait-bounds-recursion.rs
index 49f8999cd45..7135dad7d19 100644
--- a/src/test/run-pass/trait-bounds-recursion.rs
+++ b/src/test/run-pass/trait-bounds-recursion.rs
@@ -10,17 +10,17 @@
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() }
}
diff --git a/src/test/run-pass/trait-default-method-bound-subst4.rs b/src/test/run-pass/trait-default-method-bound-subst4.rs
index 3efe2507470..383849ca512 100644
--- a/src/test/run-pass/trait-default-method-bound-subst4.rs
+++ b/src/test/run-pass/trait-default-method-bound-subst4.rs
@@ -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 { }
diff --git a/src/test/run-pass/trait-impl.rs b/src/test/run-pass/trait-impl.rs
index 16ef315c206..325fba8a0ee 100644
--- a/src/test/run-pass/trait-impl.rs
+++ b/src/test/run-pass/trait-impl.rs
@@ -16,7 +16,9 @@ use traitimpl::Bar;
static mut COUNT: uint = 1;
-trait T {}
+trait T {
+ fn t(&self) {}
+}
impl<'a> T+'a {
fn foo(&self) {
diff --git a/src/test/run-pass/trait-inheritance-num2.rs b/src/test/run-pass/trait-inheritance-num2.rs
index 1e6e7227a06..f89eea46090 100644
--- a/src/test/run-pass/trait-inheritance-num2.rs
+++ b/src/test/run-pass/trait-inheritance-num2.rs
@@ -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 {}
diff --git a/src/test/run-pass/trait-inheritance-static2.rs b/src/test/run-pass/trait-inheritance-static2.rs
index 3b454aad03e..8f3b325a513 100644
--- a/src/test/run-pass/trait-inheritance-static2.rs
+++ b/src/test/run-pass/trait-inheritance-static2.rs
@@ -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;
}
diff --git a/src/test/run-pass/trait-object-generics.rs b/src/test/run-pass/trait-object-generics.rs
index 76352c799a0..6f89490716f 100644
--- a/src/test/run-pass/trait-object-generics.rs
+++ b/src/test/run-pass/trait-object-generics.rs
@@ -13,11 +13,14 @@
#![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 @@ impl<V> Trait<u8,V> for () {
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);
}
diff --git a/src/test/run-pass/trait-static-method-overwriting.rs b/src/test/run-pass/trait-static-method-overwriting.rs
index a8cea24db0c..10439d5c86a 100644
--- a/src/test/run-pass/trait-static-method-overwriting.rs
+++ b/src/test/run-pass/trait-static-method-overwriting.rs
@@ -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 @@ mod base {
dummy: (),
}
- impl ::base::HasNew<Foo> for Foo {
+ impl ::base::HasNew for Foo {
fn new() -> Foo {
println!("Foo");
Foo { dummy: () }
@@ -29,7 +29,7 @@ mod base {
dummy: (),
}
- impl ::base::HasNew<Bar> for Bar {
+ impl ::base::HasNew for Bar {
fn new() -> Bar {
println!("Bar");
Bar { dummy: () }
@@ -38,6 +38,6 @@ mod base {
}
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();
}
diff --git a/src/test/run-pass/traits-issue-22019.rs b/src/test/run-pass/traits-issue-22019.rs
index 5d3195e1937..7e0f60d55a8 100644
--- a/src/test/run-pass/traits-issue-22019.rs
+++ b/src/test/run-pass/traits-issue-22019.rs
@@ -23,18 +23,18 @@ pub type Node<'a> = &'a CFGNode;
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 { } }
}
diff --git a/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs b/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs
index 1f9b821178c..2d1ba7f39b2 100644
--- a/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs
+++ b/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs
@@ -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
@@ -20,12 +20,12 @@ use std::marker::CovariantType;
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 }
}
}
diff --git a/src/test/run-pass/unique-object-move.rs b/src/test/run-pass/unique-object-move.rs
index cec523a0671..f01a56142e0 100644
--- a/src/test/run-pass/unique-object-move.rs
+++ b/src/test/run-pass/unique-object-move.rs
@@ -13,7 +13,7 @@
#![allow(unknown_features)]
#![feature(box_syntax)]
-pub trait EventLoop { }
+pub trait EventLoop { fn foo(&self) {} }
pub struct UvEventLoop {
uvio: int
diff --git a/src/test/run-pass/unsized.rs b/src/test/run-pass/unsized.rs
index e6dd8d46952..ae175d27b0a 100644
--- a/src/test/run-pass/unsized.rs
+++ b/src/test/run-pass/unsized.rs
@@ -12,17 +12,19 @@
// 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;
diff --git a/src/test/run-pass/unsized2.rs b/src/test/run-pass/unsized2.rs
index 285100dd719..10b2f2fb709 100644
--- a/src/test/run-pass/unsized2.rs
+++ b/src/test/run-pass/unsized2.rs
@@ -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>);
diff --git a/src/test/run-pass/variadic-ffi.rs b/src/test/run-pass/variadic-ffi.rs
index a729fedb271..5a476ed9ee2 100644
--- a/src/test/run-pass/variadic-ffi.rs
+++ b/src/test/run-pass/variadic-ffi.rs
@@ -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
index 00000000000..948d68e0ccd
--- /dev/null
+++ b/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs
@@ -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
index 00000000000..10441bee3cb
--- /dev/null
+++ b/src/test/run-pass/variance-trait-matching.rs
@@ -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
index 00000000000..caec6df5a4d
--- /dev/null
+++ b/src/test/run-pass/variance-vec-covariant.rs
@@ -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);
+}
diff --git a/src/test/run-pass/visible-private-types-feature-gate.rs b/src/test/run-pass/visible-private-types-feature-gate.rs
index 9518671b479..46e93b25697 100644
--- a/src/test/run-pass/visible-private-types-feature-gate.rs
+++ b/src/test/run-pass/visible-private-types-feature-gate.rs
@@ -10,7 +10,7 @@
#![feature(visible_private_types)]
-trait Foo {}
+trait Foo { fn dummy(&self) { } }
pub trait Bar : Foo {}
diff --git a/src/test/run-pass/where-clause-bounds-inconsistency.rs b/src/test/run-pass/where-clause-bounds-inconsistency.rs
index a1a61127f68..3374f47ed5f 100644
--- a/src/test/run-pass/where-clause-bounds-inconsistency.rs
+++ b/src/test/run-pass/where-clause-bounds-inconsistency.rs
@@ -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;
diff --git a/src/test/run-pass/where-clause-early-bound-lifetimes.rs b/src/test/run-pass/where-clause-early-bound-lifetimes.rs
index cade99b83a2..4a149d4d3df 100644
--- a/src/test/run-pass/where-clause-early-bound-lifetimes.rs
+++ b/src/test/run-pass/where-clause-early-bound-lifetimes.rs
@@ -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 { }
diff --git a/src/test/run-pass/where-clause-method-substituion.rs b/src/test/run-pass/where-clause-method-substituion.rs
index b391df8500b..ecc210ea579 100644
--- a/src/test/run-pass/where-clause-method-substituion.rs
+++ b/src/test/run-pass/where-clause-method-substituion.rs
@@ -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 @@ struct X;
impl Foo<S> for X {}
-impl Bar<X> for int {
+impl Bar<X> for i32 {
fn method<U>(&self) where X: Foo<U> {
}
}
diff --git a/src/test/run-pass/where-for-self.rs b/src/test/run-pass/where-for-self.rs
index 5d426793c2e..1fd223b0dd3 100644
--- a/src/test/run-pass/where-for-self.rs
+++ b/src/test/run-pass/where-for-self.rs
@@ -11,13 +11,19 @@
// 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);
}