]> git.lizzy.rs Git - rust.git/commitdiff
rollup merge of #22437: dotdash/fix_array_type
authorAlex Crichton <alex@alexcrichton.com>
Wed, 18 Feb 2015 22:31:59 +0000 (14:31 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Wed, 18 Feb 2015 22:31:59 +0000 (14:31 -0800)
In trans_slice_vec we currently use arrayalloca, which gives us a
pointer to the element type with enough memory allocated for the
requested number of elements.  This works, but everywhere else we use
the [n x T] type for fixed size arrays and so we have to bitcast the
pointer here. Let's directly use the proper type for the allocation and
remove some code duplication along the way.

730 files changed:
CONTRIBUTING.md
README.md
configure
mk/docs.mk
mk/install.mk
mk/rt.mk
mk/tests.mk
src/compiletest/common.rs
src/compiletest/compiletest.rs
src/compiletest/runtest.rs
src/doc/complement-bugreport.md [deleted file]
src/doc/reference.md
src/doc/style/README.md [new file with mode: 0644]
src/doc/style/SUMMARY.md [new file with mode: 0644]
src/doc/style/changing/README.md [new file with mode: 0644]
src/doc/style/changing/post-1-0.md [new file with mode: 0644]
src/doc/style/changing/pre-1-0.md [new file with mode: 0644]
src/doc/style/changing/unclear.md [new file with mode: 0644]
src/doc/style/errors/README.md [new file with mode: 0644]
src/doc/style/errors/ergonomics.md [new file with mode: 0644]
src/doc/style/errors/handling.md [new file with mode: 0644]
src/doc/style/errors/propagation.md [new file with mode: 0644]
src/doc/style/errors/signaling.md [new file with mode: 0644]
src/doc/style/features/README.md [new file with mode: 0644]
src/doc/style/features/crates.md [new file with mode: 0644]
src/doc/style/features/functions-and-methods/README.md [new file with mode: 0644]
src/doc/style/features/functions-and-methods/convenience.md [new file with mode: 0644]
src/doc/style/features/functions-and-methods/input.md [new file with mode: 0644]
src/doc/style/features/functions-and-methods/output.md [new file with mode: 0644]
src/doc/style/features/let.md [new file with mode: 0644]
src/doc/style/features/loops.md [new file with mode: 0644]
src/doc/style/features/match.md [new file with mode: 0644]
src/doc/style/features/modules.md [new file with mode: 0644]
src/doc/style/features/traits/README.md [new file with mode: 0644]
src/doc/style/features/traits/common.md [new file with mode: 0644]
src/doc/style/features/traits/extensions.md [new file with mode: 0644]
src/doc/style/features/traits/generics.md [new file with mode: 0644]
src/doc/style/features/traits/objects.md [new file with mode: 0644]
src/doc/style/features/traits/overloading.md [new file with mode: 0644]
src/doc/style/features/traits/reuse.md [new file with mode: 0644]
src/doc/style/features/types/README.md [new file with mode: 0644]
src/doc/style/features/types/conversions.md [new file with mode: 0644]
src/doc/style/features/types/newtype.md [new file with mode: 0644]
src/doc/style/ownership/README.md [new file with mode: 0644]
src/doc/style/ownership/builders.md [new file with mode: 0644]
src/doc/style/ownership/cell-smart.md [new file with mode: 0644]
src/doc/style/ownership/constructors.md [new file with mode: 0644]
src/doc/style/ownership/destructors.md [new file with mode: 0644]
src/doc/style/ownership/raii.md [new file with mode: 0644]
src/doc/style/platform.md [new file with mode: 0644]
src/doc/style/safety/README.md [new file with mode: 0644]
src/doc/style/safety/lib-guarantees.md [new file with mode: 0644]
src/doc/style/safety/unsafe.md [new file with mode: 0644]
src/doc/style/style/README.md [new file with mode: 0644]
src/doc/style/style/braces.md [new file with mode: 0644]
src/doc/style/style/comments.md [new file with mode: 0644]
src/doc/style/style/features.md [new file with mode: 0644]
src/doc/style/style/imports.md [new file with mode: 0644]
src/doc/style/style/naming/README.md [new file with mode: 0644]
src/doc/style/style/naming/containers.md [new file with mode: 0644]
src/doc/style/style/naming/conversions.md [new file with mode: 0644]
src/doc/style/style/naming/iterators.md [new file with mode: 0644]
src/doc/style/style/naming/ownership.md [new file with mode: 0644]
src/doc/style/style/optional.md [new file with mode: 0644]
src/doc/style/style/organization.md [new file with mode: 0644]
src/doc/style/style/whitespace.md [new file with mode: 0644]
src/doc/style/testing/README.md [new file with mode: 0644]
src/doc/style/testing/unit.md [new file with mode: 0644]
src/doc/style/todo.md [new file with mode: 0644]
src/doc/trpl/SUMMARY.md
src/doc/trpl/advanced-macros.md [new file with mode: 0644]
src/doc/trpl/compound-data-types.md
src/doc/trpl/concurrency.md
src/doc/trpl/documentation.md
src/doc/trpl/iterators.md
src/doc/trpl/macros.md
src/doc/trpl/method-syntax.md
src/doc/trpl/ownership.md
src/doc/trpl/traits.md
src/doc/trpl/unsafe.md
src/etc/adb_run_wrapper.sh
src/liballoc/arc.rs
src/liballoc/lib.rs
src/liballoc/rc.rs
src/libcollections/binary_heap.rs
src/libcollections/bit.rs
src/libcollections/btree/map.rs
src/libcollections/btree/set.rs
src/libcollections/dlist.rs
src/libcollections/enum_set.rs
src/libcollections/fmt.rs
src/libcollections/lib.rs
src/libcollections/macros.rs
src/libcollections/ring_buf.rs
src/libcollections/string.rs
src/libcollections/vec.rs
src/libcollections/vec_map.rs
src/libcore/array.rs
src/libcore/atomic.rs
src/libcore/cell.rs
src/libcore/cmp.rs
src/libcore/fmt/float.rs
src/libcore/fmt/mod.rs
src/libcore/iter.rs
src/libcore/lib.rs
src/libcore/marker.rs
src/libcore/mem.rs
src/libcore/nonzero.rs
src/libcore/option.rs
src/libcore/ptr.rs
src/libcore/slice.rs
src/libcoretest/finally.rs
src/libcoretest/iter.rs
src/libgetopts/lib.rs
src/libgraphviz/lib.rs
src/liblibc/lib.rs
src/liblog/lib.rs
src/librand/isaac.rs
src/librand/lib.rs
src/librbml/lib.rs
src/librustc/README.txt
src/librustc/lib.rs
src/librustc/lint/builtin.rs
src/librustc/metadata/cstore.rs
src/librustc/middle/check_match.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/dataflow.rs
src/librustc/middle/dependency_format.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/infer/error_reporting.rs
src/librustc/middle/infer/unify.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/stability.rs
src/librustc/middle/subst.rs
src/librustc/middle/traits/fulfill.rs
src/librustc/middle/traits/mod.rs
src/librustc/middle/traits/object_safety.rs
src/librustc/middle/traits/select.rs
src/librustc/middle/ty.rs
src/librustc/session/config.rs
src/librustc/util/common.rs
src/librustc/util/ppaux.rs
src/librustc_back/lib.rs
src/librustc_back/rpath.rs
src/librustc_back/target/aarch64_linux_android.rs
src/librustc_back/target/arm_linux_androideabi.rs
src/librustc_back/target/mod.rs
src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
src/librustc_borrowck/borrowck/gather_loans/move_error.rs
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_driver/test.rs
src/librustc_llvm/lib.rs
src/librustc_resolve/lib.rs
src/librustc_trans/back/write.rs
src/librustc_trans/lib.rs
src/librustc_trans/trans/_match.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/closure.rs
src/librustc_trans/trans/common.rs
src/librustc_trans/trans/debuginfo.rs
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/type_of.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/callee.rs
src/librustc_typeck/check/implicator.rs [new file with mode: 0644]
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/regionmanip.rs [deleted file]
src/librustc_typeck/check/wf.rs
src/librustdoc/lib.rs
src/librustdoc/passes.rs
src/librustdoc/test.rs
src/librustdoc/visit_ast.rs
src/libserialize/json.rs
src/libserialize/lib.rs
src/libstd/ascii.rs
src/libstd/collections/hash/map.rs
src/libstd/collections/hash/set.rs
src/libstd/env.rs
src/libstd/fs.rs
src/libstd/io/mod.rs
src/libstd/lib.rs
src/libstd/macros.rs
src/libstd/net/tcp.rs
src/libstd/net/udp.rs
src/libstd/num/mod.rs
src/libstd/old_io/comm_adapters.rs
src/libstd/old_io/mod.rs
src/libstd/old_io/net/pipe.rs
src/libstd/old_io/net/tcp.rs
src/libstd/old_io/net/udp.rs
src/libstd/old_io/pipe.rs
src/libstd/old_io/process.rs
src/libstd/old_io/stdio.rs
src/libstd/old_io/timer.rs
src/libstd/old_path/mod.rs
src/libstd/old_path/posix.rs
src/libstd/old_path/windows.rs
src/libstd/panicking.rs
src/libstd/path.rs
src/libstd/process.rs
src/libstd/rand/mod.rs
src/libstd/rand/os.rs
src/libstd/rt/at_exit_imp.rs
src/libstd/rt/mod.rs
src/libstd/rt/unwind.rs
src/libstd/rt/util.rs
src/libstd/sync/barrier.rs
src/libstd/sync/condvar.rs
src/libstd/sync/future.rs
src/libstd/sync/mpsc/blocking.rs
src/libstd/sync/mpsc/mod.rs
src/libstd/sync/mpsc/mpsc_queue.rs
src/libstd/sync/mpsc/oneshot.rs
src/libstd/sync/mpsc/select.rs
src/libstd/sync/mpsc/shared.rs
src/libstd/sync/mpsc/spsc_queue.rs
src/libstd/sync/mpsc/stream.rs
src/libstd/sync/mpsc/sync.rs
src/libstd/sync/mutex.rs
src/libstd/sync/once.rs
src/libstd/sync/poison.rs
src/libstd/sync/rwlock.rs
src/libstd/sync/semaphore.rs
src/libstd/sync/task_pool.rs
src/libstd/sys/common/helper_thread.rs
src/libstd/sys/common/thread_info.rs
src/libstd/sys/common/thread_local.rs
src/libstd/sys/common/wtf8.rs
src/libstd/sys/unix/os.rs
src/libstd/sys/unix/process.rs
src/libstd/sys/unix/thread.rs
src/libstd/sys/windows/os.rs
src/libstd/sys/windows/thread.rs
src/libstd/thread.rs
src/libstd/thread_local/mod.rs
src/libstd/thunk.rs
src/libsyntax/ast_map/mod.rs
src/libsyntax/diagnostics/registry.rs
src/libsyntax/ext/asm.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/concat_idents.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/log_syntax.rs
src/libsyntax/ext/source_util.rs
src/libsyntax/ext/trace_macros.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/feature_gate.rs
src/libsyntax/lib.rs
src/libsyntax/parse/lexer/comments.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libterm/lib.rs
src/libterm/terminfo/mod.rs
src/libterm/terminfo/parm.rs
src/libterm/win.rs
src/libtest/lib.rs
src/libunicode/lib.rs
src/rustbook/build.rs
src/rustbook/main.rs
src/rustbook/term.rs
src/rustllvm/llvm-auto-clean-trigger
src/snapshots.txt
src/test/auxiliary/cci_capture_clause.rs
src/test/auxiliary/lint_stability.rs
src/test/bench/core-map.rs
src/test/bench/core-set.rs
src/test/bench/core-std.rs
src/test/bench/core-uint-to-str.rs
src/test/bench/msgsend-pipes-shared.rs
src/test/bench/msgsend-pipes.rs
src/test/bench/msgsend-ring-mutex-arcs.rs
src/test/bench/rt-messaging-ping-pong.rs
src/test/bench/rt-parfib.rs
src/test/bench/shootout-ackermann.rs
src/test/bench/shootout-binarytrees.rs
src/test/bench/shootout-chameneos-redux.rs
src/test/bench/shootout-fannkuch-redux.rs
src/test/bench/shootout-fasta-redux.rs
src/test/bench/shootout-fasta.rs
src/test/bench/shootout-fibo.rs
src/test/bench/shootout-k-nucleotide-pipes.rs
src/test/bench/shootout-k-nucleotide.rs
src/test/bench/shootout-mandelbrot.rs
src/test/bench/shootout-meteor.rs
src/test/bench/shootout-nbody.rs
src/test/bench/shootout-pfib.rs
src/test/bench/shootout-reverse-complement.rs
src/test/bench/shootout-spectralnorm.rs
src/test/bench/shootout-threadring.rs
src/test/bench/std-smallintmap.rs
src/test/bench/sudoku.rs
src/test/bench/task-perf-alloc-unwind.rs
src/test/bench/task-perf-jargon-metal-smoke.rs
src/test/bench/task-perf-spawnalot.rs
src/test/compile-fail-fulldeps/macro-crate-cannot-read-embedded-ident.rs
src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs
src/test/compile-fail-fulldeps/macro-crate-unexported-macro.rs
src/test/compile-fail-fulldeps/plugin-MacroRulesTT.rs
src/test/compile-fail/ascii-only-character-escape.rs [deleted file]
src/test/compile-fail/asm-gated2.rs [new file with mode: 0644]
src/test/compile-fail/attr-before-eof.rs [deleted file]
src/test/compile-fail/attr-before-ext.rs [deleted file]
src/test/compile-fail/attr-before-let.rs [deleted file]
src/test/compile-fail/attr-before-stmt.rs [deleted file]
src/test/compile-fail/attr-dangling-in-fn.rs [deleted file]
src/test/compile-fail/attr-dangling-in-mod.rs [deleted file]
src/test/compile-fail/attr.rs [deleted file]
src/test/compile-fail/attrs-after-extern-mod.rs [deleted file]
src/test/compile-fail/bad-char-literals.rs [deleted file]
src/test/compile-fail/bad-lit-suffixes.rs [deleted file]
src/test/compile-fail/bad-value-ident-false.rs [deleted file]
src/test/compile-fail/bad-value-ident-true.rs [deleted file]
src/test/compile-fail/borrowck-loan-blocks-move-cc.rs
src/test/compile-fail/borrowck-multiple-captures.rs
src/test/compile-fail/builtin-superkinds-simple.rs
src/test/compile-fail/coherence-impls-builtin.rs
src/test/compile-fail/concat_idents-gate.rs [new file with mode: 0644]
src/test/compile-fail/concat_idents-gate2.rs [new file with mode: 0644]
src/test/compile-fail/custom_attribute.rs [new file with mode: 0644]
src/test/compile-fail/doc-before-attr.rs [deleted file]
src/test/compile-fail/doc-before-eof.rs [deleted file]
src/test/compile-fail/doc-before-extern-rbrace.rs [deleted file]
src/test/compile-fail/doc-before-macro.rs [deleted file]
src/test/compile-fail/doc-before-rbrace.rs [deleted file]
src/test/compile-fail/doc-before-semi.rs [deleted file]
src/test/compile-fail/extern-crate-as-no-string-help.rs [deleted file]
src/test/compile-fail/generic-non-trailing-defaults.rs [deleted file]
src/test/compile-fail/int-literal-too-large-span.rs [deleted file]
src/test/compile-fail/issue-10412.rs [deleted file]
src/test/compile-fail/issue-12041.rs
src/test/compile-fail/issue-12560-1.rs [deleted file]
src/test/compile-fail/issue-14182.rs [deleted file]
src/test/compile-fail/issue-17383.rs [deleted file]
src/test/compile-fail/issue-17718-const-mut.rs [deleted file]
src/test/compile-fail/issue-1802-2.rs [deleted file]
src/test/compile-fail/issue-5544-a.rs [deleted file]
src/test/compile-fail/issue-5544-b.rs [deleted file]
src/test/compile-fail/issue-8460-const.rs
src/test/compile-fail/issue-8537.rs [deleted file]
src/test/compile-fail/keyword-as-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-break-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-else-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-enum-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-extern-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-fn-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-for-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-if-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-impl-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-let-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-loop-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-match-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-mod-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-pub-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-return-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-self-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-static-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-struct-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-super-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-super.rs [deleted file]
src/test/compile-fail/keyword-trait-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-type-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-unsafe-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-use-as-identifier.rs [deleted file]
src/test/compile-fail/keyword-while-as-identifier.rs [deleted file]
src/test/compile-fail/keyword.rs [deleted file]
src/test/compile-fail/keywords-followed-by-double-colon.rs [deleted file]
src/test/compile-fail/kindck-impl-type-params.rs
src/test/compile-fail/kindck-send-object.rs
src/test/compile-fail/kindck-send-object1.rs
src/test/compile-fail/kindck-send-object2.rs
src/test/compile-fail/kindck-send-owned.rs
src/test/compile-fail/kindck-send-region-pointers.rs [deleted file]
src/test/compile-fail/lex-bad-numeric-literals.rs [deleted file]
src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs [deleted file]
src/test/compile-fail/lifetime-no-keyword.rs [deleted file]
src/test/compile-fail/lifetime-obsoleted-self.rs [deleted file]
src/test/compile-fail/linkage1.rs
src/test/compile-fail/linkage4.rs
src/test/compile-fail/lint-obsolete-attr.rs
src/test/compile-fail/lint-stability.rs
src/test/compile-fail/lint-unknown-attr.rs
src/test/compile-fail/lint-uppercase-variables.rs
src/test/compile-fail/log-syntax-gate2.rs [new file with mode: 0644]
src/test/compile-fail/macro-inner-attributes.rs
src/test/compile-fail/macro-outer-attributes.rs
src/test/compile-fail/macros-no-semicolon-items.rs [deleted file]
src/test/compile-fail/missing-stability.rs
src/test/compile-fail/mod_file_disambig.rs [new file with mode: 0644]
src/test/compile-fail/mod_file_not_owning.rs [new file with mode: 0644]
src/test/compile-fail/move-fragments-1.rs
src/test/compile-fail/move-fragments-2.rs
src/test/compile-fail/move-fragments-3.rs
src/test/compile-fail/move-fragments-4.rs
src/test/compile-fail/move-fragments-5.rs
src/test/compile-fail/move-fragments-6.rs
src/test/compile-fail/move-fragments-7.rs
src/test/compile-fail/move-fragments-8.rs
src/test/compile-fail/move-fragments-9.rs
src/test/compile-fail/moves-based-on-type-capture-clause-bad.rs
src/test/compile-fail/no-binary-float-literal.rs [deleted file]
src/test/compile-fail/no-capture-arc.rs
src/test/compile-fail/no-hex-float-literal.rs [deleted file]
src/test/compile-fail/no-reuse-move-arc.rs
src/test/compile-fail/no-send-res-ports.rs
src/test/compile-fail/no-unsafe-self.rs [deleted file]
src/test/compile-fail/non-str-meta.rs [deleted file]
src/test/compile-fail/object-lifetime-default.rs
src/test/compile-fail/obsolete-for-sized.rs [deleted file]
src/test/compile-fail/obsolete-proc.rs [deleted file]
src/test/compile-fail/qquote-1.rs [deleted file]
src/test/compile-fail/qquote-2.rs [deleted file]
src/test/compile-fail/region-object-lifetime-1.rs
src/test/compile-fail/region-object-lifetime-3.rs
src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs [new file with mode: 0644]
src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs [new file with mode: 0644]
src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs [new file with mode: 0644]
src/test/compile-fail/regions-assoc-type-outlives-container.rs [new file with mode: 0644]
src/test/compile-fail/regions-bounded-by-send.rs [deleted file]
src/test/compile-fail/regions-fn-bound.rs [deleted file]
src/test/compile-fail/regions-pattern-typing-issue-19552.rs
src/test/compile-fail/require-parens-for-chained-comparison.rs [deleted file]
src/test/compile-fail/rustc-error.rs
src/test/compile-fail/send-is-not-static-ensures-scoping.rs [new file with mode: 0755]
src/test/compile-fail/struct-no-fields-2.rs [deleted file]
src/test/compile-fail/struct-no-fields-3.rs [deleted file]
src/test/compile-fail/struct-no-fields-4.rs [deleted file]
src/test/compile-fail/struct-no-fields-5.rs [deleted file]
src/test/compile-fail/struct-variant-no-fields.rs [deleted file]
src/test/compile-fail/struct-variant-no-pub.rs [deleted file]
src/test/compile-fail/syntax-trait-polarity.rs [deleted file]
src/test/compile-fail/tag-variant-disr-non-nullary.rs [deleted file]
src/test/compile-fail/trace_macros-gate.rs [new file with mode: 0644]
src/test/compile-fail/trace_macros-gate2.rs [new file with mode: 0644]
src/test/compile-fail/trace_macros-gate3.rs [new file with mode: 0644]
src/test/compile-fail/trailing-carriage-return-in-string.rs [deleted file]
src/test/compile-fail/trailing-plus-in-bounds.rs [deleted file]
src/test/compile-fail/trait-bounds-cant-coerce.rs
src/test/compile-fail/trait-bounds-not-on-impl.rs [deleted file]
src/test/compile-fail/type-parameters-in-field-exprs.rs [deleted file]
src/test/compile-fail/unsized2.rs [deleted file]
src/test/compile-fail/unused-attr.rs
src/test/compile-fail/variance-associated-types.rs
src/test/compile-fail/variance-object-types.rs
src/test/compile-fail/variance-regions-direct.rs
src/test/compile-fail/variance-regions-indirect.rs
src/test/compile-fail/variance-trait-object-bound.rs
src/test/compile-fail/virtual-structs.rs [deleted file]
src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs [deleted file]
src/test/debuginfo/associated-types.rs
src/test/debuginfo/basic-types-globals-metadata.rs
src/test/debuginfo/basic-types-globals.rs
src/test/debuginfo/basic-types-metadata.rs
src/test/debuginfo/basic-types-mut-globals.rs
src/test/debuginfo/basic-types.rs
src/test/debuginfo/borrowed-basic.rs
src/test/debuginfo/borrowed-c-style-enum.rs
src/test/debuginfo/borrowed-enum.rs
src/test/debuginfo/borrowed-struct.rs
src/test/debuginfo/borrowed-tuple.rs
src/test/debuginfo/borrowed-unique-basic.rs
src/test/debuginfo/box.rs
src/test/debuginfo/boxed-struct.rs
src/test/debuginfo/by-value-non-immediate-argument.rs
src/test/debuginfo/by-value-self-argument-in-trait-impl.rs
src/test/debuginfo/c-style-enum-in-composite.rs
src/test/debuginfo/c-style-enum.rs
src/test/debuginfo/closure-in-generic-function.rs
src/test/debuginfo/cross-crate-type-uniquing.rs
src/test/debuginfo/destructured-fn-argument.rs
src/test/debuginfo/destructured-for-loop-variable.rs
src/test/debuginfo/destructured-local.rs
src/test/debuginfo/evec-in-struct.rs
src/test/debuginfo/function-arg-initialization.rs
src/test/debuginfo/function-arguments.rs
src/test/debuginfo/generic-function.rs
src/test/debuginfo/generic-functions-nested.rs
src/test/debuginfo/generic-method-on-generic-struct.rs
src/test/debuginfo/generic-static-method-on-struct-and-enum.rs
src/test/debuginfo/generic-struct-style-enum.rs
src/test/debuginfo/generic-struct.rs
src/test/debuginfo/generic-tuple-style-enum.rs
src/test/debuginfo/include_string.rs
src/test/debuginfo/issue11600.rs
src/test/debuginfo/issue12886.rs
src/test/debuginfo/issue13213.rs
src/test/debuginfo/issue14411.rs
src/test/debuginfo/lexical-scope-in-for-loop.rs
src/test/debuginfo/lexical-scope-in-if.rs
src/test/debuginfo/lexical-scope-in-match.rs
src/test/debuginfo/lexical-scope-in-parameterless-closure.rs
src/test/debuginfo/lexical-scope-in-stack-closure.rs
src/test/debuginfo/lexical-scope-in-unconditional-loop.rs
src/test/debuginfo/lexical-scope-in-unique-closure.rs
src/test/debuginfo/lexical-scope-in-while.rs
src/test/debuginfo/lexical-scope-with-macro.rs
src/test/debuginfo/lexical-scopes-in-block-expression.rs
src/test/debuginfo/limited-debuginfo.rs
src/test/debuginfo/method-on-enum.rs
src/test/debuginfo/method-on-generic-struct.rs
src/test/debuginfo/method-on-struct.rs
src/test/debuginfo/method-on-trait.rs
src/test/debuginfo/method-on-tuple-struct.rs
src/test/debuginfo/multi-byte-chars.rs
src/test/debuginfo/multiple-functions-equal-var-names.rs
src/test/debuginfo/multiple-functions.rs
src/test/debuginfo/name-shadowing-and-scope-nesting.rs
src/test/debuginfo/nil-enum.rs
src/test/debuginfo/no-debug-attribute.rs
src/test/debuginfo/option-like-enum.rs
src/test/debuginfo/packed-struct-with-destructor.rs
src/test/debuginfo/packed-struct.rs
src/test/debuginfo/recursive-enum.rs
src/test/debuginfo/recursive-struct.rs
src/test/debuginfo/self-in-default-method.rs
src/test/debuginfo/self-in-generic-default-method.rs
src/test/debuginfo/shadowed-argument.rs
src/test/debuginfo/shadowed-variable.rs
src/test/debuginfo/simd.rs
src/test/debuginfo/simple-lexical-scope.rs
src/test/debuginfo/simple-struct.rs
src/test/debuginfo/simple-tuple.rs
src/test/debuginfo/static-method-on-struct-and-enum.rs
src/test/debuginfo/struct-in-enum.rs
src/test/debuginfo/struct-in-struct.rs
src/test/debuginfo/struct-style-enum.rs
src/test/debuginfo/struct-with-destructor.rs
src/test/debuginfo/trait-pointers.rs
src/test/debuginfo/tuple-in-struct.rs
src/test/debuginfo/tuple-in-tuple.rs
src/test/debuginfo/tuple-struct.rs
src/test/debuginfo/tuple-style-enum.rs
src/test/debuginfo/unique-enum.rs
src/test/debuginfo/unreachable-locals.rs
src/test/debuginfo/var-captured-in-nested-closure.rs
src/test/debuginfo/var-captured-in-sendable-closure.rs
src/test/debuginfo/var-captured-in-stack-closure.rs
src/test/debuginfo/vec.rs
src/test/parse-fail/ascii-only-character-escape.rs [new file with mode: 0644]
src/test/parse-fail/attr-before-eof.rs [new file with mode: 0644]
src/test/parse-fail/attr-before-ext.rs [new file with mode: 0644]
src/test/parse-fail/attr-before-let.rs [new file with mode: 0644]
src/test/parse-fail/attr-before-stmt.rs [new file with mode: 0644]
src/test/parse-fail/attr-dangling-in-fn.rs [new file with mode: 0644]
src/test/parse-fail/attr-dangling-in-mod.rs [new file with mode: 0644]
src/test/parse-fail/attr.rs [new file with mode: 0644]
src/test/parse-fail/attrs-after-extern-mod.rs [new file with mode: 0644]
src/test/parse-fail/bad-char-literals.rs [new file with mode: 0644]
src/test/parse-fail/bad-lit-suffixes.rs [new file with mode: 0644]
src/test/parse-fail/bad-value-ident-false.rs [new file with mode: 0644]
src/test/parse-fail/bad-value-ident-true.rs [new file with mode: 0644]
src/test/parse-fail/doc-before-attr.rs [new file with mode: 0644]
src/test/parse-fail/doc-before-eof.rs [new file with mode: 0644]
src/test/parse-fail/doc-before-extern-rbrace.rs [new file with mode: 0644]
src/test/parse-fail/doc-before-macro.rs [new file with mode: 0644]
src/test/parse-fail/doc-before-rbrace.rs [new file with mode: 0644]
src/test/parse-fail/doc-before-semi.rs [new file with mode: 0644]
src/test/parse-fail/extern-crate-as-no-string-help.rs [new file with mode: 0644]
src/test/parse-fail/generic-non-trailing-defaults.rs [new file with mode: 0644]
src/test/parse-fail/int-literal-too-large-span.rs [new file with mode: 0644]
src/test/parse-fail/issue-10412.rs [new file with mode: 0644]
src/test/parse-fail/issue-12560-1.rs [new file with mode: 0644]
src/test/parse-fail/issue-14182.rs [new file with mode: 0644]
src/test/parse-fail/issue-17383.rs [new file with mode: 0644]
src/test/parse-fail/issue-17718-const-mut.rs [new file with mode: 0644]
src/test/parse-fail/issue-1802-2.rs [new file with mode: 0644]
src/test/parse-fail/issue-5544-a.rs [new file with mode: 0644]
src/test/parse-fail/issue-5544-b.rs [new file with mode: 0644]
src/test/parse-fail/issue-8537.rs [new file with mode: 0644]
src/test/parse-fail/keyword-as-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-break-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-else-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-enum-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-extern-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-fn-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-for-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-if-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-impl-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-let-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-loop-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-match-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-mod-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-pub-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-return-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-self-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-static-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-struct-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-super-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-super.rs [new file with mode: 0644]
src/test/parse-fail/keyword-trait-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-type-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-unsafe-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-use-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword-while-as-identifier.rs [new file with mode: 0644]
src/test/parse-fail/keyword.rs [new file with mode: 0644]
src/test/parse-fail/keywords-followed-by-double-colon.rs [new file with mode: 0644]
src/test/parse-fail/lex-bad-numeric-literals.rs [new file with mode: 0644]
src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs [new file with mode: 0644]
src/test/parse-fail/lifetime-no-keyword.rs [new file with mode: 0644]
src/test/parse-fail/lifetime-obsoleted-self.rs [new file with mode: 0644]
src/test/parse-fail/macros-no-semicolon-items.rs [new file with mode: 0644]
src/test/parse-fail/mod_file_disambig.rs [deleted file]
src/test/parse-fail/mod_file_not_owning.rs [deleted file]
src/test/parse-fail/no-binary-float-literal.rs [new file with mode: 0644]
src/test/parse-fail/no-hex-float-literal.rs [new file with mode: 0644]
src/test/parse-fail/no-unsafe-self.rs [new file with mode: 0644]
src/test/parse-fail/non-str-meta.rs [new file with mode: 0644]
src/test/parse-fail/obsolete-for-sized.rs [new file with mode: 0644]
src/test/parse-fail/obsolete-proc.rs [new file with mode: 0644]
src/test/parse-fail/qquote-1.rs [new file with mode: 0644]
src/test/parse-fail/qquote-2.rs [new file with mode: 0644]
src/test/parse-fail/regions-fn-bound.rs [new file with mode: 0644]
src/test/parse-fail/require-parens-for-chained-comparison.rs [new file with mode: 0644]
src/test/parse-fail/struct-no-fields-2.rs [new file with mode: 0644]
src/test/parse-fail/struct-no-fields-3.rs [new file with mode: 0644]
src/test/parse-fail/struct-no-fields-4.rs [new file with mode: 0644]
src/test/parse-fail/struct-no-fields-5.rs [new file with mode: 0644]
src/test/parse-fail/struct-variant-no-fields.rs [new file with mode: 0644]
src/test/parse-fail/struct-variant-no-pub.rs [new file with mode: 0644]
src/test/parse-fail/syntax-trait-polarity.rs [new file with mode: 0644]
src/test/parse-fail/tag-variant-disr-non-nullary.rs [new file with mode: 0644]
src/test/parse-fail/trailing-carriage-return-in-string.rs [new file with mode: 0644]
src/test/parse-fail/trailing-plus-in-bounds.rs [new file with mode: 0644]
src/test/parse-fail/trait-bounds-not-on-impl.rs [new file with mode: 0644]
src/test/parse-fail/type-parameters-in-field-exprs.rs [new file with mode: 0644]
src/test/parse-fail/unsized2.rs [new file with mode: 0644]
src/test/parse-fail/virtual-structs.rs [new file with mode: 0644]
src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs [new file with mode: 0644]
src/test/pretty/attr-fn-inner.rs
src/test/run-fail/panic-task-name-none.rs
src/test/run-fail/panic-task-name-owned.rs
src/test/run-fail/rt-set-exit-status-panic2.rs
src/test/run-fail/task-spawn-barefn.rs
src/test/run-fail/tls-exit-status.rs
src/test/run-make/cannot-read-embedded-idents/create_and_compile.rs
src/test/run-make/issue-19371/foo.rs
src/test/run-make/static-unwinding/lib.rs
src/test/run-make/static-unwinding/main.rs
src/test/run-make/target-specs/my-awesome-platform.json
src/test/run-make/target-specs/my-incomplete-platform.json
src/test/run-make/target-specs/x86_64-unknown-linux-gnu.json
src/test/run-make/unicode-input/multiple_files.rs
src/test/run-make/unicode-input/span_length.rs
src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs
src/test/run-pass/attr-before-view-item.rs
src/test/run-pass/attr-before-view-item2.rs
src/test/run-pass/attr-mix-new.rs
src/test/run-pass/backtrace.rs
src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
src/test/run-pass/builtin-superkinds-capabilities-xc.rs
src/test/run-pass/builtin-superkinds-capabilities.rs
src/test/run-pass/builtin-superkinds-self-type.rs
src/test/run-pass/capturing-logging.rs
src/test/run-pass/check-static-recursion-foreign.rs
src/test/run-pass/class-attributes-1.rs
src/test/run-pass/class-attributes-2.rs
src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs
src/test/run-pass/cleanup-shortcircuit.rs
src/test/run-pass/colorful-write-macros.rs
src/test/run-pass/drop-trait-enum.rs
src/test/run-pass/foreign-call-no-runtime.rs
src/test/run-pass/ifmt.rs
src/test/run-pass/intrinsic-alignment.rs
src/test/run-pass/issue-10626.rs
src/test/run-pass/issue-12684.rs
src/test/run-pass/issue-13304.rs
src/test/run-pass/issue-14456.rs
src/test/run-pass/issue-14940.rs
src/test/run-pass/issue-15149.rs
src/test/run-pass/issue-16272.rs
src/test/run-pass/issue-16560.rs
src/test/run-pass/issue-16671.rs
src/test/run-pass/issue-18188.rs
src/test/run-pass/issue-20091.rs
src/test/run-pass/issue-21058.rs
src/test/run-pass/issue-2190-1.rs
src/test/run-pass/issue-4446.rs
src/test/run-pass/issue-4448.rs
src/test/run-pass/issue-4541.rs
src/test/run-pass/issue-4542.rs
src/test/run-pass/issue-8460.rs
src/test/run-pass/issue22008.rs [new file with mode: 0644]
src/test/run-pass/item-attributes.rs
src/test/run-pass/linkage1.rs
src/test/run-pass/logging-only-prints-once.rs
src/test/run-pass/logging-separate-lines.rs
src/test/run-pass/method-attributes.rs
src/test/run-pass/no-landing-pads.rs
src/test/run-pass/out-of-stack-new-thread-no-split.rs
src/test/run-pass/out-of-stack-no-split.rs
src/test/run-pass/out-of-stack.rs
src/test/run-pass/panic-in-dtor-drops-fields.rs
src/test/run-pass/process-spawn-with-unicode-params.rs
src/test/run-pass/rec-align-u64.rs
src/test/run-pass/regions-issue-22246.rs [new file with mode: 0644]
src/test/run-pass/segfault-no-out-of-stack.rs
src/test/run-pass/send-is-not-static-par-for.rs [new file with mode: 0755]
src/test/run-pass/send-type-inference.rs
src/test/run-pass/sendfn-spawn-with-fn-arg.rs
src/test/run-pass/sepcomp-lib-lto.rs
src/test/run-pass/sepcomp-unwind.rs
src/test/run-pass/signal-exit-status.rs
src/test/run-pass/sigpipe-should-be-ignored.rs
src/test/run-pass/slice-panic-1.rs
src/test/run-pass/slice-panic-2.rs
src/test/run-pass/smallest-hello-world.rs
src/test/run-pass/spawn-types.rs
src/test/run-pass/spawn.rs
src/test/run-pass/spawn2.rs
src/test/run-pass/task-stderr.rs
src/test/run-pass/tempfile.rs
src/test/run-pass/terminate-in-initializer.rs
src/test/run-pass/traits-issue-22110.rs [new file with mode: 0644]
src/test/run-pass/unique-send-2.rs
src/test/run-pass/unit-like-struct-drop-run.rs
src/test/run-pass/unwind-resource.rs
src/test/run-pass/unwind-unique.rs
src/test/run-pass/variant-attributes.rs
src/test/run-pass/vec-macro-repeat.rs
src/test/run-pass/vector-sort-panic-safe.rs
src/test/run-pass/weak-lang-item.rs
src/test/run-pass/yield.rs
src/test/run-pass/yield1.rs
src/test/run-pass/yield2.rs

index 2724e479384394d6c35c02e7c197134ffc778064..a4656dd415bbd3ec0972c1daad931a0945bba38c 100644 (file)
-## How to submit a bug report
+# Contributing to Rust
 
-If you're just reporting a bug, please see:
+Thank you for your interest in contributing to Rust! There are many ways to
+contribute, and we appreciate all of them. This document is a bit long, so here's
+links to the major sections:
 
-http://doc.rust-lang.org/complement-bugreport.html
+* [Feature Requests](#feature-requests)
+* [Bug Reports](#bug-reports)
+* [Pull Requests](#pull-requests)
+* [Writing Documentation](#writing-documentation)
+* [Issue Triage](#issue-triage)
+* [Out-of-tree Contributions](#out-of-tree-contributions)
 
-## Submitting an issue
+If you have questions, please make a post on [internals.rust-lang.org][internals] or
+hop on [#rust-internals][pound-rust-internals].
 
-Please submit issues here for bug reports or implementation details. For feature
-requests, language changes, or major changes to the libraries, please submit an
-issue against the [RFCs repository](https://github.com/rust-lang/rfcs).
+As a reminder, all contributors are expected to follow our [Code of Conduct](coc).
 
-## Pull request procedure
+[pound-rust-internals]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-internals
+[internals]: http://internals.rust-lang.org
+[coc]: http://www.rust-lang.org/conduct.html
 
-Pull requests should be targeted at Rust's `master` branch.
-Before pushing to your Github repo and issuing the pull request,
-please do two things:
+## Feature Requests
 
-1. [Rebase](http://git-scm.com/book/en/Git-Branching-Rebasing) your
-   local changes against the `master` branch. Resolve any conflicts
-   that arise.
+To request a change to the way that the Rust language works, please open an
+issue in the [RFCs repository](https://github.com/rust-lang/rfcs/issues/new)
+rather than this one. New features and other significant language changes
+must go through the RFC process.
 
-2. Run the full Rust test suite with the `make check` command.  You're
-   not off the hook even if you just stick to documentation; code
-   examples in the docs are tested as well! Although for simple
-   wording or grammar fixes, this is probably unnecessary.
+## Bug Reports
 
-Pull requests will be treated as "review requests", and we will give
-feedback we expect to see corrected on
-[style](http://aturon.github.io/) and
-substance before pulling.  Changes contributed via pull request should
-focus on a single issue at a time, like any other.  We will not accept
-pull-requests that try to "sneak" unrelated changes in.
+While bugs are unfortunate, they're a reality in software. We can't fix what we
+don't know about, so please report liberally. If you're not sure if something
+is a bug or not, feel free to file a bug anyway.
 
-Normally, all pull requests must include regression tests (see
-[Note-testsuite](https://github.com/rust-lang/rust/wiki/Note-testsuite))
-that test your change.  Occasionally, a change will be very difficult
-to test for.  In those cases, please include a note in your commit
-message explaining why.
+If you have the chance, before reporting a bug, please [search existing
+issues](https://github.com/rust-lang/rust/search?q=&type=Issues&utf8=%E2%9C%93),
+as it's possible that someone else has already reported your error. This doesn't
+always work, and sometimes it's hard to know what to search for, so consider this
+extra credit. We won't mind if you accidentally file a duplicate report.
 
-In the licensing header at the beginning of any files you change,
-please make sure the listed date range includes the current year.  For
-example, if it's 2014, and you change a Rust file that was created in
-2010, it should begin:
+Opening an issue is as easy as following [this
+link](https://github.com/rust-lang/rust/issues/new) and filling out the fields.
+Here's a template that you can use to file a bug, though it's not necessary to
+use it exactly:
 
-```
-// Copyright 2010-2014 The Rust Project Developers.
+    <short summary of the bug>
+
+    I tried this code:
+
+    <code sample that causes the bug>
+
+    I expected to see this happen: <explanation>
+
+    Instead, this happened: <explanation>
+
+    ## Meta
+
+    `rustc --version --verbose`:
+
+    Backtrace:
+
+All three components are important: what you did, what you expected, what
+happened instead. Please include the output of `rustc --version --verbose`,
+which includes important information about what platform you're on, what
+version of Rust you're using, etc.
+
+Sometimes, a backtrace is helpful, and so including that is nice. To get
+a backtrace, set the `RUST_BACKTRACE` environment variable. The easiest way
+to do this is to invoke `rustc` like this:
+
+```bash
+$ RUST_BACKTRACE=1 rustc ...
 ```
 
-# Coordination and communication
+## Pull Requests
 
-Get feedback from other developers on
-[internals.rust-lang.org][internals], and
-[#rust-internals][pound-rust-internals].
+Pull requests are the primary mechanism we use to change Rust. GitHub itself
+has some [great documentation][pull-requests] on using the Pull Request
+feature. We use the 'fork and pull' model described there.
 
-[pound-rust-internals]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-internals
-[internals]: http://internals.rust-lang.org
+[pull-requests]: https://help.github.com/articles/using-pull-requests/
+
+Please make pull requests against the `master` branch.
+
+All pull requests are reviewed by another person. We have a bot,
+@rust-highfive, that will automatically assign a random person to review your request.
+
+If you want to request that a specific person reviews your pull request,
+you can add an `r?` to the message. For example, Steve usually reviews
+documentation changes. So if you were to make a documentation change, add
+
+    r? @steveklabnik
+
+to the end of the message, and @rust-highfive will assign @steveklabnik instead
+of a random person. This is entirely optional.
+
+After someone has reviewed your pull request, they will leave an annotation
+on the pull request with an `r+`. It will look something like this:
+
+    @bors: r+ 38fe8d2
+
+This tells @bors, our lovable integration bot, that your pull request has
+been approved. The PR then enters the [merge queue][merge-queue], where @bors
+will run all the tests on every platform we support. If it all works out,
+@bors will merge your code into `master` and close the pull request.
+
+[merge-queue]: http://buildbot.rust-lang.org/homu/queue/rust
+
+## Writing Documentation
+
+Documentation improvements are very welcome. The source of `doc.rust-lang.org`
+is located in `src/doc` in the tree, and standard API documentation is generated
+from the source code itself.
+
+Documentation pull requests function in the same as other pull requests, though
+you may see a slightly different form of `r+`:
+
+    @bors: r+ 38fe8d2 rollup
+
+That additional `rollup` tells @bors that this change is eligible for a 'rollup'.
+To save @bors some work, and to get small changes through more quickly, when
+@bors attempts to merge a commit that's rollup-eligible, it will also merge
+the other rollup-eligible patches too, and they'll get tested and merged at
+the same time.
+
+## Issue Triage
+
+Sometimes, an issue will stay open, even though the bug has been fixed. And
+sometimes, the original bug may go stale because something has changed in the
+meantime.
+
+It can be helpful to go through older bug reports and make sure that they are
+still valid. Load up an older issue, double check that it's still true, and
+leave a comment letting us know if it is or is not. The [least recently updated sort][lru] is good for finding issues like this.
+
+[lru]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-asc
+
+## Out-of-tree Contributions
+
+There are a number of other ways to contribute to Rust that don't deal with
+this repository.
+
+Answer questions in [#rust][pound-rust], or on [users.rust-lang.org][users],
+or on [StackOverflow][so].
+
+Participate in the [RFC process](https://github.com/rust-lang/rfcs).
+
+Find a [requested community library][community-library], build it, and publish
+it to [Crates.io](http://crates.io). Easier said than done, but very, very
+valuable!
 
-For more details, please refer to
-[Note-development-policy](https://github.com/rust-lang/rust/wiki/Note-development-policy).
+[pound-rust]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust
+[users]: http://users.rust-lang.org/
+[so]: http://stackoverflow.com/questions/tagged/rust
+[community-library]: https://github.com/rust-lang/rfcs/labels/A-community-library
index 9d7c939ff9de8a28aa48a28b4516c21da80b5dc5..b6a73730d351cc9f37c39a0fdc8d49bb59e75aca 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,14 +1,16 @@
 # The Rust Programming Language
 
 This is a compiler for Rust, including standard libraries, tools and
-documentation.
+documentation. Rust is a systems programming language that is fast,
+memory safe and multithreaded, but does not employ a garbage collector
+or otherwise impose significant runtime overhead.
 
 ## Quick Start
 
-Read ["Installing Rust"][install] from [The Book][trpl].
+Read ["Installing Rust"] from [The Book].
 
-[install]: http://doc.rust-lang.org/book/installing-rust.html
-[trpl]: http://doc.rust-lang.org/book/index.html
+["Installing Rust"]: http://doc.rust-lang.org/book/installing-rust.html
+[The Book]: http://doc.rust-lang.org/book/index.html
 
 ## Building from Source
 
@@ -18,22 +20,15 @@ Read ["Installing Rust"][install] from [The Book][trpl].
     * GNU `make` 3.81 or later
     * `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
@@ -45,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
 
@@ -71,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
@@ -93,23 +88,33 @@ 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 and getting involved
+## Getting help
 
 The Rust community congregates in a few places:
 
 * [StackOverflow] - Direct questions about using the language here.
 * [users.rust-lang.org] - General discussion, broader questions.
-* [internals.rust-lang.org] - For development of the Rust language itself.
 * [/r/rust] - News and general discussion.
 
 [StackOverflow]: http://stackoverflow.com/questions/tagged/rust
 [/r/rust]: http://reddit.com/r/rust
 [users.rust-lang.org]: http://users.rust-lang.org/
-[internals.rust-lang.org]: http://internals.rust-lang.org/
+
+## Contributing
+
+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
 
index ec1e741fb9c5b10ad9aa854eae345f1039419735..d1b27a96f93b9caf7da8a4fbb9ac0b9e06a24a63 100755 (executable)
--- a/configure
+++ b/configure
@@ -1056,6 +1056,7 @@ do
     make_dir $h/test/run-pass-fulldeps
     make_dir $h/test/run-fail
     make_dir $h/test/compile-fail
+    make_dir $h/test/parse-fail
     make_dir $h/test/compile-fail-fulldeps
     make_dir $h/test/bench
     make_dir $h/test/perf
index 799871e2bd596601a960782deed9b66efdbc63c5..743032f676d217d4201246b9cf8d5984ff8608d0 100644 (file)
@@ -25,7 +25,7 @@
 # L10N_LANGS are the languages for which the docs have been
 # translated.
 ######################################################################
-DOCS := index intro tutorial complement-bugreport \
+DOCS := index intro tutorial \
     complement-lang-faq complement-design-faq complement-project-faq \
     rustdoc reference grammar
 
@@ -73,7 +73,7 @@ RUSTBOOK = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(RUSTBOOK_EXE)
 
 D := $(S)src/doc
 
-DOC_TARGETS := trpl
+DOC_TARGETS := trpl style
 COMPILER_DOC_TARGETS :=
 DOC_L10N_TARGETS :=
 
@@ -275,3 +275,9 @@ trpl: doc/book/index.html
 doc/book/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/trpl/*.md) | doc/
        $(Q)rm -rf doc/book
        $(Q)$(RUSTBOOK) build $(S)src/doc/trpl doc/book
+
+style: doc/style/index.html
+
+doc/style/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/style/*.md) | doc/
+       $(Q)rm -rf doc/style
+       $(Q)$(RUSTBOOK) build $(S)src/doc/style doc/style
index 60c0a6bb4c7649e57c8598b9128fbaff3e83cfd9..8850cd778035f745b12b5d0df27eb9aedce045fc 100644 (file)
@@ -58,14 +58,13 @@ tmp/empty_dir:
 # Android runtime setup
 # FIXME: This probably belongs somewhere else
 
-# target platform specific variables
-# for arm-linux-androidabi
+# target platform specific variables for android
 define DEF_ADB_DEVICE_STATUS
 CFG_ADB_DEVICE_STATUS=$(1)
 endef
 
 $(foreach target,$(CFG_TARGET), \
-  $(if $(findstring $(target),"arm-linux-androideabi"), \
+  $(if $(findstring android, $(target)), \
     $(if $(findstring adb,$(CFG_ADB)), \
       $(if $(findstring device,$(shell $(CFG_ADB) devices 2>/dev/null | grep -E '^[_A-Za-z0-9-]+[[:blank:]]+device')), \
         $(info install: install-runtime-target for $(target) enabled \
@@ -117,8 +116,11 @@ install-runtime-target-$(1)-cleanup:
            $$(call ADB_SHELL,rm,$$(CFG_RUNTIME_PUSH_DIR)/$$(call CFG_LIB_GLOB_$(1),$$(crate)));)
 endef
 
-$(eval $(call INSTALL_RUNTIME_TARGET_N,arm-linux-androideabi,$(CFG_BUILD)))
-$(eval $(call INSTALL_RUNTIME_TARGET_CLEANUP_N,arm-linux-androideabi))
+$(foreach target,$(CFG_TARGET), \
+ $(if $(findstring $(CFG_ADB_DEVICE_STATUS),"true"), \
+  $(eval $(call INSTALL_RUNTIME_TARGET_N,$(taget),$(CFG_BUILD))) \
+  $(eval $(call INSTALL_RUNTIME_TARGET_CLEANUP_N,$(target))) \
+  ))
 
 install-runtime-target: \
        install-runtime-target-arm-linux-androideabi-cleanup \
index a8bbeb4151701055a1c961973565b3dbd24097a5..527485c502936607f41846d4e3e8e7dc118f051c 100644 (file)
--- a/mk/rt.mk
+++ b/mk/rt.mk
@@ -139,9 +139,7 @@ ifeq ($$(CFG_WINDOWSY_$(1)), 1)
   JEMALLOC_ARGS_$(1) := --enable-lazy-lock
 else ifeq ($(OSTYPE_$(1)), apple-ios)
   JEMALLOC_ARGS_$(1) := --disable-tls
-else ifeq ($(OSTYPE_$(1)), linux-androideabi)
-  JEMALLOC_ARGS_$(1) := --disable-tls
-else ifeq ($(OSTYPE_$(1)), linux-android)
+else ifeq ($(findstring android, $(OSTYPE_$(1))), android)
   JEMALLOC_ARGS_$(1) := --disable-tls
 endif
 
index c5bb6ef81f6dae59dbdd73e62c07fd02791b14b5..692d28bfad3d56c5e5cba49ea9489b7268bb45b1 100644 (file)
@@ -107,14 +107,13 @@ endef
 $(foreach target,$(CFG_TARGET), \
   $(eval $(call DEF_TARGET_COMMANDS,$(target))))
 
-# Target platform specific variables
-# for arm-linux-androidabi
+# Target platform specific variables for android
 define DEF_ADB_DEVICE_STATUS
 CFG_ADB_DEVICE_STATUS=$(1)
 endef
 
 $(foreach target,$(CFG_TARGET), \
-  $(if $(findstring $(target),"arm-linux-androideabi"), \
+  $(if $(findstring android, $(target)), \
     $(if $(findstring adb,$(CFG_ADB)), \
       $(if $(findstring device,$(shell $(CFG_ADB) devices 2>/dev/null | grep -E '^[:_A-Za-z0-9-]+[[:blank:]]+device')), \
         $(info check: android device attached) \
@@ -135,12 +134,14 @@ $(info check: android device test dir $(CFG_ADB_TEST_DIR) ready \
  $(shell $(CFG_ADB) remount 1>/dev/null) \
  $(shell $(CFG_ADB) shell rm -r $(CFG_ADB_TEST_DIR) >/dev/null) \
  $(shell $(CFG_ADB) shell mkdir $(CFG_ADB_TEST_DIR)) \
- $(shell $(CFG_ADB) shell mkdir $(CFG_ADB_TEST_DIR)/tmp) \
  $(shell $(CFG_ADB) push $(S)src/etc/adb_run_wrapper.sh $(CFG_ADB_TEST_DIR) 1>/dev/null) \
- $(foreach crate,$(TARGET_CRATES), \
-    $(shell $(CFG_ADB) push $(TLIB2_T_arm-linux-androideabi_H_$(CFG_BUILD))/$(call CFG_LIB_GLOB_arm-linux-androideabi,$(crate)) \
-                    $(CFG_ADB_TEST_DIR))) \
- )
+ $(foreach target,$(CFG_TARGET), \
+  $(if $(findstring android, $(target)), \
+   $(shell $(CFG_ADB) shell mkdir $(CFG_ADB_TEST_DIR)/$(target)) \
+   $(foreach crate,$(TARGET_CRATES), \
+    $(shell $(CFG_ADB) push $(TLIB2_T_$(target)_H_$(CFG_BUILD))/$(call CFG_LIB_GLOB_$(target),$(crate)) \
+                    $(CFG_ADB_TEST_DIR)/$(target))), \
+ )))
 else
 CFG_ADB_TEST_DIR=
 endif
@@ -173,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.
@@ -290,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 \
@@ -393,14 +395,14 @@ $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
            && touch $$@
 endef
 
-define DEF_TEST_CRATE_RULES_arm-linux-androideabi
+define DEF_TEST_CRATE_RULES_android
 check-stage$(1)-T-$(2)-H-$(3)-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4))
 
 $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
                $(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2))
        @$$(call E, run: $$< via adb)
        $$(Q)$(CFG_ADB) push $$< $(CFG_ADB_TEST_DIR)
-       $$(Q)$(CFG_ADB) shell '(cd $(CFG_ADB_TEST_DIR); LD_LIBRARY_PATH=. \
+       $$(Q)$(CFG_ADB) shell '(cd $(CFG_ADB_TEST_DIR); LD_LIBRARY_PATH=./$(2) \
                ./$$(notdir $$<) \
                --logfile $(CFG_ADB_TEST_DIR)/check-stage$(1)-T-$(2)-H-$(3)-$(4).log \
                $$(call CRATE_TEST_EXTRA_ARGS,$(1),$(2),$(3),$(4)) $(TESTARGS))' \
@@ -434,9 +436,9 @@ $(foreach host,$(CFG_HOST), \
    $(foreach crate, $(TEST_CRATES), \
     $(if $(findstring $(target),$(CFG_BUILD)), \
      $(eval $(call DEF_TEST_CRATE_RULES,$(stage),$(target),$(host),$(crate))), \
-     $(if $(findstring $(target),"arm-linux-androideabi"), \
+     $(if $(findstring android, $(target)), \
       $(if $(findstring $(CFG_ADB_DEVICE_STATUS),"true"), \
-       $(eval $(call DEF_TEST_CRATE_RULES_arm-linux-androideabi,$(stage),$(target),$(host),$(crate))), \
+       $(eval $(call DEF_TEST_CRATE_RULES_android,$(stage),$(target),$(host),$(crate))), \
        $(eval $(call DEF_TEST_CRATE_RULES_null,$(stage),$(target),$(host),$(crate))) \
       ), \
       $(eval $(call DEF_TEST_CRATE_RULES,$(stage),$(target),$(host),$(crate))) \
@@ -469,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)
@@ -507,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
@@ -629,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)
@@ -697,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), \
@@ -856,6 +865,7 @@ TEST_GROUPS = \
        cfail-full \
        rfail \
        cfail \
+       pfail \
        bench \
        perf \
        rmake \
index df2981a6c8334a385180a405c4f8155797e020ee..2c046d252799ee02338b399fb4e38a1b1cae75e4 100644 (file)
@@ -15,6 +15,7 @@
 #[derive(Clone, Copy, PartialEq, Debug)]
 pub enum Mode {
     CompileFail,
+    ParseFail,
     RunFail,
     RunPass,
     RunPassValgrind,
@@ -29,6 +30,7 @@ impl FromStr for Mode {
     fn from_str(s: &str) -> Result<Mode, ()> {
         match s {
           "compile-fail" => Ok(CompileFail),
+          "parse-fail" => Ok(ParseFail),
           "run-fail" => Ok(RunFail),
           "run-pass" => Ok(RunPass),
           "run-pass-valgrind" => Ok(RunPassValgrind),
@@ -45,6 +47,7 @@ impl fmt::Display for Mode {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::Display::fmt(match *self {
             CompileFail => "compile-fail",
+            ParseFail => "parse-fail",
             RunFail => "run-fail",
             RunPass => "run-pass",
             RunPassValgrind => "run-pass-valgrind",
index 6b6251a96c944731ad1f3afd3ba8481a074e604e..278ce5565d9fc38d8ce9bec899e5fcf3109d0ab1 100644 (file)
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(int_uint)]
-#![feature(io)]
-#![feature(path)]
+#![feature(old_io)]
+#![feature(old_path)]
 #![feature(rustc_private)]
 #![feature(unboxed_closures)]
 #![feature(std_misc)]
 #![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"),
@@ -153,12 +154,12 @@ fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
         lldb_version: extract_lldb_version(matches.opt_str("lldb-version")),
         android_cross_path: opt_path(matches, "android-cross-path"),
         adb_path: opt_str2(matches.opt_str("adb-path")),
-        adb_test_dir: opt_str2(matches.opt_str("adb-test-dir")),
+        adb_test_dir: format!("{}/{}",
+            opt_str2(matches.opt_str("adb-test-dir")),
+            opt_str2(matches.opt_str("target"))),
         adb_device_status:
-            "arm-linux-androideabi" ==
-                opt_str2(matches.opt_str("target")) &&
-            "(none)" !=
-                opt_str2(matches.opt_str("adb-test-dir")) &&
+            opt_str2(matches.opt_str("target")).contains("android") &&
+            "(none)" != opt_str2(matches.opt_str("adb-test-dir")) &&
             !opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
         lldb_python_dir: matches.opt_str("lldb-python-dir"),
         verbose: matches.opt_present("verbose"),
@@ -213,17 +214,17 @@ pub fn opt_str2(maybestr: Option<String>) -> String {
 }
 
 pub fn run_tests(config: &Config) {
-    if config.target == "arm-linux-androideabi" {
+    if config.target.contains("android") {
         match config.mode {
             DebugInfoGdb => {
-                println!("arm-linux-androideabi debug-info \
-                         test uses tcp 5039 port. please reserve it");
+                println!("{} debug-info test uses tcp 5039 port.\
+                         please reserve it", config.target);
             }
             _ =>{}
         }
 
-        //arm-linux-androideabi debug-info test uses remote debugger
-        //so, we test 1 task at once.
+        // android debug-info test uses remote debugger
+        // so, we test 1 task at once.
         // also trying to isolate problems with adb_run_wrapper.sh ilooping
         env::set_var("RUST_TEST_TASKS","1");
     }
index 5a372fd7cdcb261f83898f29e0ace7a8a63738ab..be26a7caaffe3a306feb7131058ef0bfdd4bae2e 100644 (file)
@@ -11,7 +11,7 @@
 use self::TargetLocation::*;
 
 use common::Config;
-use common::{CompileFail, Pretty, RunFail, RunPass, RunPassValgrind, DebugInfoGdb};
+use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind, DebugInfoGdb};
 use common::{Codegen, DebugInfoLldb};
 use errors;
 use header::TestProps;
 use std::iter::repeat;
 use std::str;
 use std::string::String;
-use std::thread::Thread;
+use std::thread;
 use std::time::Duration;
 use test::MetricMap;
 
 pub fn run(config: Config, testfile: String) {
     match &*config.target {
 
-        "arm-linux-androideabi" => {
+        "arm-linux-androideabi" | "aarch64-linux-android" => {
             if !config.adb_device_status {
                 panic!("android device not available");
             }
@@ -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);
     }
 
@@ -382,17 +383,26 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
 
     let debugger_run_result;
     match &*config.target {
-        "arm-linux-androideabi" => {
+        "arm-linux-androideabi" | "aarch64-linux-android" => {
 
-            cmds = cmds.replace("run", "continue").to_string();
+            cmds = cmds.replace("run", "continue");
 
             // write debugger script
-            let script_str = ["set charset UTF-8".to_string(),
-                              format!("file {}", exe_file.as_str().unwrap()
-                                                         .to_string()),
-                              "target remote :5039".to_string(),
-                              cmds,
-                              "quit".to_string()].connect("\n");
+            let mut script_str = String::with_capacity(2048);
+            script_str.push_str("set charset UTF-8\n");
+            script_str.push_str(&format!("file {}\n", exe_file.as_str().unwrap()));
+            script_str.push_str("target remote :5039\n");
+            script_str.push_str(&format!("set solib-search-path \
+                                         ./{}/stage2/lib/rustlib/{}/lib/\n",
+                                         config.host, config.target));
+            for line in breakpoint_lines.iter() {
+                script_str.push_str(&format!("break {:?}:{}\n",
+                                             testfile.filename_display(),
+                                             *line)[]);
+            }
+            script_str.push_str(&cmds);
+            script_str.push_str("quit\n");
+
             debug!("script_str = {}", script_str);
             dump_output_file(config,
                              testfile,
@@ -425,8 +435,10 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                 .expect(&format!("failed to exec `{:?}`", config.adb_path));
 
             let adb_arg = format!("export LD_LIBRARY_PATH={}; \
-                                   gdbserver :5039 {}/{}",
+                                   gdbserver{} :5039 {}/{}",
                                   config.adb_test_dir.clone(),
+                                  if config.target.contains("aarch64")
+                                  {"64"} else {""},
                                   config.adb_test_dir.clone(),
                                   str::from_utf8(
                                       exe_file.filename()
@@ -447,7 +459,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
             loop {
                 //waiting 1 second for gdbserver start
                 timer::sleep(Duration::milliseconds(1000));
-                let result = Thread::scoped(move || {
+                let result = thread::spawn(move || {
                     tcp::TcpStream::connect("127.0.0.1:5039").unwrap();
                 }).join();
                 if result.is_err() {
@@ -470,7 +482,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                      format!("-command={}", debugger_script.as_str().unwrap()));
 
             let mut gdb_path = tool_path;
-            gdb_path.push_str("/bin/arm-linux-androideabi-gdb");
+            gdb_path.push_str(&format!("/bin/{}-gdb", config.target));
             let procsrv::Result {
                 out,
                 err,
@@ -484,7 +496,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                 .expect(&format!("failed to exec `{:?}`", gdb_path));
             let cmdline = {
                 let cmdline = make_cmdline("",
-                                           "arm-linux-androideabi-gdb",
+                                           &format!("{}-gdb", config.target),
                                            &debugger_opts);
                 logv(config, format!("executing {}", cmdline));
                 cmdline
@@ -496,7 +508,9 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                 stderr: err,
                 cmdline: cmdline
             };
-            process.signal_kill().unwrap();
+            if process.signal_kill().is_err() {
+                println!("Adb process is already finished.");
+            }
         }
 
         _=> {
@@ -1120,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,
@@ -1135,7 +1149,7 @@ fn exec_compiled_test(config: &Config, props: &TestProps,
 
     match &*config.target {
 
-        "arm-linux-androideabi" => {
+        "arm-linux-androideabi" | "aarch64-linux-android" => {
             _arm_exec_compiled_test(config, props, testfile, env)
         }
 
@@ -1200,7 +1214,7 @@ fn compose_and_run_compiler(
         }
 
         match &*config.target {
-            "arm-linux-androideabi" => {
+            "arm-linux-androideabi"  | "aarch64-linux-android" => {
                 _arm_push_aux_shared_library(config, testfile);
             }
             _ => {}
@@ -1499,7 +1513,7 @@ fn _arm_exec_compiled_test(config: &Config,
     for (key, val) in env {
         runargs.push(format!("{}={}", key, val));
     }
-    runargs.push(format!("{}/adb_run_wrapper.sh", config.adb_test_dir));
+    runargs.push(format!("{}/../adb_run_wrapper.sh", config.adb_test_dir));
     runargs.push(format!("{}", config.adb_test_dir));
     runargs.push(format!("{}", prog_short));
 
@@ -1595,7 +1609,7 @@ fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) {
                                             file.as_str()
                                                 .unwrap()
                                                 .to_string(),
-                                            config.adb_test_dir.to_string()
+                                            config.adb_test_dir.to_string(),
                                            ],
                                            vec!(("".to_string(),
                                                  "".to_string())),
diff --git a/src/doc/complement-bugreport.md b/src/doc/complement-bugreport.md
deleted file mode 100644 (file)
index 1a28cd6..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-% How to submit a Rust bug report
-
-# I think I found a bug in the compiler!
-
-If you see this message: `error: internal compiler error: unexpected panic`,
-then you have definitely found a bug in the compiler. It's also possible that
-your code is not well-typed, but if you saw this message, it's still a bug in
-error reporting.
-
-If you see a message about an LLVM assertion failure, then you have also
-definitely found a bug in the compiler. In both of these cases, it's not your
-fault and you should report a bug!
-
-If you see a compiler error message that you think is meant for users to see,
-but it confuses you, *that's a bug too*. If it wasn't clear to you, then it's
-an error message we want to improve, so please report it so that we can try
-to make it better.
-
-# How do I know the bug I found isn't a bug that already exists in the issue tracker?
-
-If you don't have enough time for a search, then don't worry about that. Just submit
-the bug. If it's a duplicate, somebody will notice that and close it during triage.
-
-If you have the time for it, it would be useful to type the text of the error
-message you got [into the issue tracker search box](https://github.com/rust-lang/rust/issues)
-to see if there's an existing bug that resembles your problem. If there is,
-and it's an open bug, you can comment on that issue and say you are also affected.
-This will encourage the devs to fix it. But again, don't let this stop you from
-submitting a bug. We'd rather have to do the work of closing duplicates than
-miss out on valid bug reports.
-
-# What information should I include in a bug report?
-
-It generally helps our diagnosis to include your specific OS (for example: Mac OS X 10.8.3,
-Windows 7, Ubuntu 12.04) and your hardware architecture (for example: i686, x86_64).
-It's also helpful to provide the exact version and host by copying the output of
-re-running the erroneous rustc command with the `--version --verbose` flags, which will
-produce something like this:
-
-```text
-rustc 0.12.0 (ba4081a5a 2014-10-07 13:44:41 -0700)
-binary: rustc
-commit-hash: ba4081a5a8573875fed17545846f6f6902c8ba8d
-commit-date: 2014-10-07 13:44:41 -0700
-host: i686-apple-darwin
-release: 0.12.0
-```
-
-Finally, if you can also provide a backtrace, that'd be great. You can get a
-backtrace by setting the `RUST_BACKTRACE` environment variable to `1`, like
-this: 
-
-```bash
-$ RUST_BACKTRACE=1 rustc ...
-```
-
-# I submitted a bug, but nobody has commented on it!
-
-This is sad, but does happen sometimes, since we're short-staffed. If you submit a
-bug and you haven't received a comment on it within 3 business days, it's entirely
-reasonable to ask about the status of the bug in #rust on irc.mozilla.org.
index 11b2afc1c8822141f5418c43b3bded8df0756b94..00ed5d4562b11e248da5d959486910e08ec4dcad 100644 (file)
@@ -2398,6 +2398,10 @@ The currently implemented features of the reference compiler are:
                     ways insufficient for concatenating identifiers, and may be
                     removed entirely for something more wholesome.
 
+* `custom_attribute` - Allows the usage of attributes unknown to the compiler
+                       so that new attributes can be added in a bacwards compatible
+                       manner (RFC 572).
+
 * `intrinsics` - Allows use of the "rust-intrinsics" ABI. Compiler intrinsics
                  are inherently unstable and no promise about them is made.
 
@@ -2458,6 +2462,9 @@ The currently implemented features of the reference compiler are:
             implemented very poorly and will likely change significantly
             with a proper implementation.
 
+* `rustc_attrs` - Gates internal `#[rustc_*]` attributes which may be
+                  for internal use only or have meaning added to them in the future.
+
 * `rustc_diagnostic_macros`- A mysterious feature, used in the implementation
                              of rustc, not meant for mortals.
 
diff --git a/src/doc/style/README.md b/src/doc/style/README.md
new file mode 100644 (file)
index 0000000..9b328b5
--- /dev/null
@@ -0,0 +1,64 @@
+% Style Guidelines
+
+This document collects the emerging principles, conventions, abstractions, and
+best practices for writing Rust code.
+
+Since Rust is evolving at a rapid pace, these guidelines are
+preliminary. The hope is that writing them down explicitly will help
+drive discussion, consensus and adoption.
+
+Whenever feasible, guidelines provide specific examples from Rust's standard
+libraries.
+
+### Guideline statuses
+
+Every guideline has a status:
+
+* **[FIXME]**: Marks places where there is more work to be done. In
+  some cases, that just means going through the RFC process.
+
+* **[FIXME #NNNNN]**: Like **[FIXME]**, but links to the issue tracker.
+
+* **[RFC #NNNN]**: Marks accepted guidelines, linking to the rust-lang
+  RFC establishing them.
+
+### Guideline stabilization
+
+One purpose of these guidelines is to reach decisions on a number of
+cross-cutting API and stylistic choices. Discussion and development of
+the guidelines will happen primarily on http://discuss.rust-lang.org/,
+using the Guidelines category. Discussion can also occur on the
+[guidelines issue tracker](https://github.com/rust-lang/rust-guidelines).
+
+Guidelines that are under development or discussion will be marked with the
+status **[FIXME]**, with a link to the issue tracker when appropriate.
+
+Once a concrete guideline is ready to be proposed, it should be filed
+as an [FIXME: needs RFC](https://github.com/rust-lang/rfcs). If the RFC is
+accepted, the official guidelines will be updated to match, and will
+include the tag **[RFC #NNNN]** linking to the RFC document.
+
+### What's in this document
+
+This document is broken into four parts:
+
+* **[Style](style/README.md)** provides a set of rules governing naming conventions,
+  whitespace, and other stylistic issues.
+
+* **[Guidelines by Rust feature](features/README.md)** places the focus on each of
+  Rust's features, starting from expressions and working the way out toward
+  crates, dispensing guidelines relevant to each.
+
+* **Topical guidelines and patterns**. The rest of the document proceeds by
+  cross-cutting topic, starting with
+  [Ownership and resources](ownership/README.md).
+
+* **[APIs for a changing Rust](changing/README.md)**
+  discusses the forward-compatibility hazards, especially those that interact
+  with the pre-1.0 library stabilization process.
+
+> **[FIXME]** Add cross-references throughout this document to the tutorial,
+> reference manual, and other guides.
+
+> **[FIXME]** What are some _non_-goals, _non_-principles, or _anti_-patterns that
+> we should document?
diff --git a/src/doc/style/SUMMARY.md b/src/doc/style/SUMMARY.md
new file mode 100644 (file)
index 0000000..41bc08f
--- /dev/null
@@ -0,0 +1,54 @@
+# Summary
+
+* [Style](style/README.md)
+    * [Whitespace](style/whitespace.md)
+    * [Comments](style/comments.md)
+    * [Braces, semicolons, commas](style/braces.md)
+    * [Naming](style/naming/README.md)
+        * [Ownership variants](style/naming/ownership.md)
+        * [Containers/wrappers](style/naming/containers.md)
+        * [Conversions](style/naming/conversions.md)
+        * [Iterators](style/naming/iterators.md)
+    * [Imports](style/imports.md)
+    * [Organization](style/organization.md)
+* [Guidelines by Rust feature](features/README.md)
+    * [Let binding](features/let.md)
+    * [Pattern matching](features/match.md)
+    * [Loops](features/loops.md)
+    * [Functions and methods](features/functions-and-methods/README.md)
+        * [Input](features/functions-and-methods/input.md)
+        * [Output](features/functions-and-methods/output.md)
+        * [For convenience](features/functions-and-methods/convenience.md)
+    * [Types](features/types/README.md)
+        * [Conversions](features/types/conversions.md)
+        * [The newtype pattern](features/types/newtype.md)
+    * [Traits](features/traits/README.md)
+        * [For generics](features/traits/generics.md)
+        * [For objects](features/traits/objects.md)
+        * [For overloading](features/traits/overloading.md)
+        * [For extensions](features/traits/extensions.md)
+        * [For reuse](features/traits/reuse.md)
+        * [Common traits](features/traits/common.md)
+    * [Modules](features/modules.md)
+    * [Crates](features/crates.md)
+* [Ownership and resources](ownership/README.md)
+    * [Constructors](ownership/constructors.md)
+    * [Builders](ownership/builders.md)
+    * [Destructors](ownership/destructors.md)
+    * [RAII](ownership/raii.md)
+    * [Cells and smart pointers](ownership/cell-smart.md)
+* [Errors](errors/README.md)
+    * [Signaling](errors/signaling.md)
+    * [Handling](errors/handling.md)
+    * [Propagation](errors/propagation.md)
+    * [Ergonomics](errors/ergonomics.md)
+* [Safety and guarantees](safety/README.md)
+    * [Using unsafe](safety/unsafe.md)
+    * [Library guarantees](safety/lib-guarantees.md)
+* [Testing](testing/README.md)
+    * [Unit testing](testing/unit.md)
+* [FFI, platform-specific code](platform.md)
+* [APIs for a changing Rust](changing/README.md)
+    * [Pre-1.0 changes](changing/pre-1-0.md)
+    * [Post-1.0 changes](changing/post-1-0.md)
+    * [Timing unclear](changing/unclear.md)
diff --git a/src/doc/style/changing/README.md b/src/doc/style/changing/README.md
new file mode 100644 (file)
index 0000000..38e76f6
--- /dev/null
@@ -0,0 +1,5 @@
+% API design for a changing Rust
+
+A number of planned Rust features will drastically affect the API design
+story. This section collects some of the biggest features with concrete examples
+of how the API will change.
diff --git a/src/doc/style/changing/post-1-0.md b/src/doc/style/changing/post-1-0.md
new file mode 100644 (file)
index 0000000..7ac1c83
--- /dev/null
@@ -0,0 +1,12 @@
+% Post-1.0 changes
+
+### Higher-kinded types
+
+* A trait encompassing both `Iterable<T>` for some fixed `T` and
+  `FromIterator<U>` for _all_ `U` (where HKT comes in).  The train
+  could provide e.g. a default `map` method producing the same kind of
+  the container, but with a new type parameter.
+
+* **Monadic-generic programming**? Can we add this without deprecating
+  huge swaths of the API (including `Option::map`, `option::collect`,
+  `result::collect`, `try!` etc.
diff --git a/src/doc/style/changing/pre-1-0.md b/src/doc/style/changing/pre-1-0.md
new file mode 100644 (file)
index 0000000..adadfe3
--- /dev/null
@@ -0,0 +1,17 @@
+% Pre-1.0 changes
+
+### `std` facade
+
+We should revisit some APIs in `libstd` now that the facade effort is complete.
+
+For example, the treatment of environment variables in the new
+`Command` API is waiting on access to hashtables before being
+approved.
+
+### Trait reform
+
+Potential for standard conversion traits (`to`, `into`, `as`).
+
+Probably many other opportunities here.
+
+### Unboxed closures
diff --git a/src/doc/style/changing/unclear.md b/src/doc/style/changing/unclear.md
new file mode 100644 (file)
index 0000000..e4b8a98
--- /dev/null
@@ -0,0 +1,28 @@
+% Changes with unclear timing
+
+### Associated items
+
+* Many traits that currently take type parameters should instead use associated
+  types; this will _drastically_ simplify signatures in some cases.
+
+* Associated constants would be useful in a few places, e.g. traits for
+  numerics, traits for paths.
+
+### Anonymous, unboxed return types (aka `impl Trait` types)
+
+* See https://github.com/rust-lang/rfcs/pull/105
+
+* Could affect API design in several places, e.g. the `Iterator` trait.
+
+### Default type parameters
+
+We are already using this in a few places (e.g. `HashMap`), but it's
+feature-gated.
+
+### Compile-time function evaluation (CTFE)
+
+https://github.com/mozilla/rust/issues/11621
+
+### Improved constant folding
+
+https://github.com/rust-lang/rust/issues/7834
diff --git a/src/doc/style/errors/README.md b/src/doc/style/errors/README.md
new file mode 100644 (file)
index 0000000..444da26
--- /dev/null
@@ -0,0 +1,3 @@
+% Errors
+
+> **[FIXME]** Add some general text here.
diff --git a/src/doc/style/errors/ergonomics.md b/src/doc/style/errors/ergonomics.md
new file mode 100644 (file)
index 0000000..33f1e82
--- /dev/null
@@ -0,0 +1,66 @@
+% Ergonomic error handling
+
+Error propagation with raw `Result`s can require tedious matching and
+repackaging. This tedium is largely alleviated by the `try!` macro,
+and can be completely removed (in some cases) by the "`Result`-`impl`"
+pattern.
+
+### The `try!` macro
+
+Prefer
+
+```rust
+use std::io::{File, Open, Write, IoError};
+
+struct Info {
+    name: String,
+    age: int,
+    rating: int
+}
+
+fn write_info(info: &Info) -> Result<(), IoError> {
+    let mut file = File::open_mode(&Path::new("my_best_friends.txt"),
+                                   Open, Write);
+    // Early return on error
+    try!(file.write_line(format!("name: {}", info.name).as_slice()));
+    try!(file.write_line(format!("age: {}", info.age).as_slice()));
+    try!(file.write_line(format!("rating: {}", info.rating).as_slice()));
+    return Ok(());
+}
+```
+
+over
+
+```rust
+use std::io::{File, Open, Write, IoError};
+
+struct Info {
+    name: String,
+    age: int,
+    rating: int
+}
+
+fn write_info(info: &Info) -> Result<(), IoError> {
+    let mut file = File::open_mode(&Path::new("my_best_friends.txt"),
+                                   Open, Write);
+    // Early return on error
+    match file.write_line(format!("name: {}", info.name).as_slice()) {
+        Ok(_) => (),
+        Err(e) => return Err(e)
+    }
+    match file.write_line(format!("age: {}", info.age).as_slice()) {
+        Ok(_) => (),
+        Err(e) => return Err(e)
+    }
+    return file.write_line(format!("rating: {}", info.rating).as_slice());
+}
+```
+
+See
+[the `result` module documentation](http://static.rust-lang.org/doc/master/std/result/index.html#the-try!-macro)
+for more details.
+
+### The `Result`-`impl` pattern [FIXME]
+
+> **[FIXME]** Document the way that the `io` module uses trait impls
+> on `IoResult` to painlessly propagate errors.
diff --git a/src/doc/style/errors/handling.md b/src/doc/style/errors/handling.md
new file mode 100644 (file)
index 0000000..cc5b5b4
--- /dev/null
@@ -0,0 +1,7 @@
+% Handling errors
+
+### Use task isolation to cope with failure. [FIXME]
+
+> **[FIXME]** Explain how to isolate tasks and detect task failure for recovery.
+
+### Consuming `Result` [FIXME]
diff --git a/src/doc/style/errors/propagation.md b/src/doc/style/errors/propagation.md
new file mode 100644 (file)
index 0000000..0a347cd
--- /dev/null
@@ -0,0 +1,8 @@
+% Propagation
+
+> **[FIXME]** We need guidelines on how to layer error information up a stack of
+> abstractions.
+
+### Error interoperation [FIXME]
+
+> **[FIXME]** Document the `FromError` infrastructure.
diff --git a/src/doc/style/errors/signaling.md b/src/doc/style/errors/signaling.md
new file mode 100644 (file)
index 0000000..95db4f8
--- /dev/null
@@ -0,0 +1,125 @@
+% Signaling errors [RFC #236]
+
+> The guidelines below were approved by [RFC #236](https://github.com/rust-lang/rfcs/pull/236).
+
+Errors fall into one of three categories:
+
+* Catastrophic errors, e.g. out-of-memory.
+* Contract violations, e.g. wrong input encoding, index out of bounds.
+* Obstructions, e.g. file not found, parse error.
+
+The basic principle of the convention is that:
+
+* Catastrophic errors and programming errors (bugs) can and should only be
+recovered at a *coarse grain*, i.e. a task boundary.
+* Obstructions preventing an operation should be reported at a maximally *fine
+grain* -- to the immediate invoker of the operation.
+
+## Catastrophic errors
+
+An error is _catastrophic_ if there is no meaningful way for the current task to
+continue after the error occurs.
+
+Catastrophic errors are _extremely_ rare, especially outside of `libstd`.
+
+**Canonical examples**: out of memory, stack overflow.
+
+### For catastrophic errors, panic
+
+For errors like stack overflow, Rust currently aborts the process, but
+could in principle panic, which (in the best case) would allow
+reporting and recovery from a supervisory task.
+
+## Contract violations
+
+An API may define a contract that goes beyond the type checking enforced by the
+compiler. For example, slices support an indexing operation, with the contract
+that the supplied index must be in bounds.
+
+Contracts can be complex and involve more than a single function invocation. For
+example, the `RefCell` type requires that `borrow_mut` not be called until all
+existing borrows have been relinquished.
+
+### For contract violations, panic
+
+A contract violation is always a bug, and for bugs we follow the Erlang
+philosophy of "let it crash": we assume that software *will* have bugs, and we
+design coarse-grained task boundaries to report, and perhaps recover, from these
+bugs.
+
+### Contract design
+
+One subtle aspect of these guidelines is that the contract for a function is
+chosen by an API designer -- and so the designer also determines what counts as
+a violation.
+
+This RFC does not attempt to give hard-and-fast rules for designing
+contracts. However, here are some rough guidelines:
+
+* Prefer expressing contracts through static types whenever possible.
+
+* It *must* be possible to write code that uses the API without violating the
+  contract.
+
+* Contracts are most justified when violations are *inarguably* bugs -- but this
+  is surprisingly rare.
+
+* Consider whether the API client could benefit from the contract-checking
+  logic.  The checks may be expensive. Or there may be useful programming
+  patterns where the client does not want to check inputs before hand, but would
+  rather attempt the operation and then find out whether the inputs were invalid.
+
+* When a contract violation is the *only* kind of error a function may encounter
+  -- i.e., there are no obstructions to its success other than "bad" inputs --
+  using `Result` or `Option` instead is especially warranted. Clients can then use
+  `unwrap` to assert that they have passed valid input, or re-use the error
+  checking done by the API for their own purposes.
+
+* When in doubt, use loose contracts and instead return a `Result` or `Option`.
+
+## Obstructions
+
+An operation is *obstructed* if it cannot be completed for some reason, even
+though the operation's contract has been satisfied. Obstructed operations may
+have (documented!) side effects -- they are not required to roll back after
+encountering an obstruction.  However, they should leave the data structures in
+a "coherent" state (satisfying their invariants, continuing to guarantee safety,
+etc.).
+
+Obstructions may involve external conditions (e.g., I/O), or they may involve
+aspects of the input that are not covered by the contract.
+
+**Canonical examples**: file not found, parse error.
+
+### For obstructions, use `Result`
+
+The
+[`Result<T,E>` type](http://static.rust-lang.org/doc/master/std/result/index.html)
+represents either a success (yielding `T`) or failure (yielding `E`). By
+returning a `Result`, a function allows its clients to discover and react to
+obstructions in a fine-grained way.
+
+#### What about `Option`?
+
+The `Option` type should not be used for "obstructed" operations; it
+should only be used when a `None` return value could be considered a
+"successful" execution of the operation.
+
+This is of course a somewhat subjective question, but a good litmus
+test is: would a reasonable client ever ignore the result? The
+`Result` type provides a lint that ensures the result is actually
+inspected, while `Option` does not, and this difference of behavior
+can help when deciding between the two types.
+
+Another litmus test: can the operation be understood as asking a
+question (possibly with sideeffects)? Operations like `pop` on a
+vector can be viewed as asking for the contents of the first element,
+with the side effect of removing it if it exists -- with an `Option`
+return value.
+
+## Do not provide both `Result` and `panic!` variants.
+
+An API should not provide both `Result`-producing and `panic`king versions of an
+operation. It should provide just the `Result` version, allowing clients to use
+`try!` or `unwrap` instead as needed. This is part of the general pattern of
+cutting down on redundant variants by instead using method chaining.
diff --git a/src/doc/style/features/README.md b/src/doc/style/features/README.md
new file mode 100644 (file)
index 0000000..0965750
--- /dev/null
@@ -0,0 +1,9 @@
+% Guidelines by language feature
+
+Rust provides a unique combination of language features, some new and some
+old. This section gives guidance on when and how to use Rust's features, and
+brings attention to some of the tradeoffs between different features.
+
+Notably missing from this section is an in-depth discussion of Rust's pointer
+types (both built-in and in the library). The topic of pointers is discussed at
+length in a [separate section on ownership](../ownership/README.md).
diff --git a/src/doc/style/features/crates.md b/src/doc/style/features/crates.md
new file mode 100644 (file)
index 0000000..4748b05
--- /dev/null
@@ -0,0 +1,6 @@
+% Crates
+
+> **[FIXME]** What general guidelines should we provide for crate design?
+
+> Possible topics: facades; per-crate preludes (to be imported as globs);
+> "lib.rs"
diff --git a/src/doc/style/features/functions-and-methods/README.md b/src/doc/style/features/functions-and-methods/README.md
new file mode 100644 (file)
index 0000000..2dcfc38
--- /dev/null
@@ -0,0 +1,43 @@
+% Functions and methods
+
+### Prefer methods to functions if there is a clear receiver. **[FIXME: needs RFC]**
+
+Prefer
+
+```rust
+impl Foo {
+    pub fn frob(&self, w: widget) { ... }
+}
+```
+
+over
+
+```rust
+pub fn frob(foo: &Foo, w: widget) { ... }
+```
+
+for any operation that is clearly associated with a particular
+type.
+
+Methods have numerous advantages over functions:
+* They do not need to be imported or qualified to be used: all you
+  need is a value of the appropriate type.
+* Their invocation performs autoborrowing (including mutable borrows).
+* They make it easy to answer the question "what can I do with a value
+  of type `T`" (especially when using rustdoc).
+* They provide `self` notation, which is more concise and often more
+  clearly conveys ownership distinctions.
+
+> **[FIXME]** Revisit these guidelines with
+> [UFCS](https://github.com/nick29581/rfcs/blob/ufcs/0000-ufcs.md) and
+> conventions developing around it.
+
+
+
+### Guidelines for inherent methods. **[FIXME]**
+
+> **[FIXME]** We need guidelines for when to provide inherent methods on a type,
+> versus methods through a trait or functions.
+
+> **NOTE**: Rules for method resolution around inherent methods are in flux,
+> which may impact the guidelines.
diff --git a/src/doc/style/features/functions-and-methods/convenience.md b/src/doc/style/features/functions-and-methods/convenience.md
new file mode 100644 (file)
index 0000000..69fd377
--- /dev/null
@@ -0,0 +1,43 @@
+% Convenience methods
+
+### Provide small, coherent sets of convenience methods. **[FIXME: needs RFC]**
+
+_Convenience methods_ wrap up existing functionality in a more convenient
+way. The work done by a convenience method varies widely:
+
+* _Re-providing functions as methods_. For example, the `std::path::Path` type
+  provides methods like `stat` on `Path`s that simply invoke the corresponding
+  function in `std::io::fs`.
+* _Skipping through conversions_. For example, the `str` type provides a
+  `.len()` convenience method which is also expressible as `.as_bytes().len()`.
+  Sometimes the conversion is more complex: the `str` module also provides
+  `from_chars`, which encapsulates a simple use of iterators.
+* _Encapsulating common arguments_. For example, vectors of `&str`s
+  provide a `connect` as well as a special case, `concat`, that is expressible
+  using `connect` with a fixed separator of `""`.
+* _Providing more efficient special cases_. The `connect` and `concat` example
+  also applies here: singling out `concat` as a special case allows for a more
+  efficient implementation.
+
+  Note, however, that the `connect` method actually detects the special case
+  internally and invokes `concat`. Usually, it is not necessary to add a public
+  convenience method just for efficiency gains; there should also be a
+  _conceptual_ reason to add it, e.g. because it is such a common special case.
+
+It is tempting to add convenience methods in a one-off, haphazard way as
+common use patterns emerge. Avoid this temptation, and instead _design_ small,
+coherent sets of convenience methods that are easy to remember:
+
+* _Small_: Avoid combinatorial explosions of convenience methods. For example,
+  instead of adding `_str` variants of methods that provide a `str` output,
+  instead ensure that the normal output type of methods is easily convertible to
+  `str`.
+* _Coherent_: Look for small groups of convenience methods that make sense to
+  include together. For example, the `Path` API mentioned above includes a small
+  selection of the most common filesystem operations that take a `Path`
+  argument.  If one convenience method strongly suggests the existence of others,
+  consider adding the whole group.
+* _Memorable_: It is not worth saving a few characters of typing if you have to
+  look up the name of a convenience method every time you use it. Add
+  convenience methods with names that are obvious and easy to remember, and add
+  them for the most common or painful use cases.
diff --git a/src/doc/style/features/functions-and-methods/input.md b/src/doc/style/features/functions-and-methods/input.md
new file mode 100644 (file)
index 0000000..b0912ea
--- /dev/null
@@ -0,0 +1,201 @@
+% Input to functions and methods
+
+### Let the client decide when to copy and where to place data. [FIXME: needs RFC]
+
+#### Copying:
+
+Prefer
+
+```rust
+fn foo(b: Bar) {
+   // use b as owned, directly
+}
+```
+
+over
+
+```rust
+fn foo(b: &Bar) {
+    let b = b.clone();
+    // use b as owned after cloning
+}
+```
+
+If a function requires ownership of a value of unknown type `T`, but does not
+otherwise need to make copies, the function should take ownership of the
+argument (pass by value `T`) rather than using `.clone()`. That way, the caller
+can decide whether to relinquish ownership or to `clone`.
+
+Similarly, the `Copy` trait bound should only be demanded it when absolutely
+needed, not as a way of signaling that copies should be cheap to make.
+
+#### Placement:
+
+Prefer
+
+```rust
+fn foo(b: Bar) -> Bar { ... }
+```
+
+over
+
+```rust
+fn foo(b: Box<Bar>) -> Box<Bar> { ... }
+```
+
+for concrete types `Bar` (as opposed to trait objects). This way, the caller can
+decide whether to place data on the stack or heap. No overhead is imposed by
+letting the caller determine the placement.
+
+### Minimize assumptions about parameters. [FIXME: needs RFC]
+
+The fewer assumptions a function makes about its inputs, the more widely usable
+it becomes.
+
+#### Minimizing assumptions through generics:
+
+Prefer
+
+```rust
+fn foo<T: Iterator<int>>(c: T) { ... }
+```
+
+over any of
+
+```rust
+fn foo(c: &[int]) { ... }
+fn foo(c: &Vec<int>) { ... }
+fn foo(c: &SomeOtherCollection<int>) { ... }
+```
+
+if the function only needs to iterate over the data.
+
+More generally, consider using generics to pinpoint the assumptions a function
+needs to make about its arguments.
+
+On the other hand, generics can make it more difficult to read and understand a
+function's signature. Aim for "natural" parameter types that a neither overly
+concrete nor overly abstract. See the discussion on
+[traits](../../traits/README.md) for more guidance.
+
+
+#### Minimizing ownership assumptions:
+
+Prefer either of
+
+```rust
+fn foo(b: &Bar) { ... }
+fn foo(b: &mut Bar) { ... }
+```
+
+over
+
+```rust
+fn foo(b: Bar) { ... }
+```
+
+That is, prefer borrowing arguments rather than transferring ownership, unless
+ownership is actually needed.
+
+### Prefer compound return types to out-parameters. [FIXME: needs RFC]
+
+Prefer
+
+```rust
+fn foo() -> (Bar, Bar)
+```
+
+over
+
+```rust
+fn foo(output: &mut Bar) -> Bar
+```
+
+for returning multiple `Bar` values.
+
+Compound return types like tuples and structs are efficiently compiled
+and do not require heap allocation. If a function needs to return
+multiple values, it should do so via one of these types.
+
+The primary exception: sometimes a function is meant to modify data
+that the caller already owns, for example to re-use a buffer:
+
+```rust
+fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>
+```
+
+(From the [Reader trait](http://static.rust-lang.org/doc/master/std/io/trait.Reader.html#tymethod.read).)
+
+### Consider validating arguments, statically or dynamically. [FIXME: needs RFC]
+
+_Note: this material is closely related to
+  [library-level guarantees](../../safety/lib-guarantees.md)._
+
+Rust APIs do _not_ generally follow the
+[robustness principle](http://en.wikipedia.org/wiki/Robustness_principle): "be
+conservative in what you send; be liberal in what you accept".
+
+Instead, Rust code should _enforce_ the validity of input whenever practical.
+
+Enforcement can be achieved through the following mechanisms (listed
+in order of preference).
+
+#### Static enforcement:
+
+Choose an argument type that rules out bad inputs.
+
+For example, prefer
+
+```rust
+fn foo(a: ascii::Ascii) { ... }
+```
+
+over
+
+```rust
+fn foo(a: u8) { ... }
+```
+
+Note that
+[`ascii::Ascii`](http://static.rust-lang.org/doc/master/std/ascii/struct.Ascii.html)
+is a _wrapper_ around `u8` that guarantees the highest bit is zero; see
+[newtype patterns]() for more details on creating typesafe wrappers.
+
+Static enforcement usually comes at little run-time cost: it pushes the
+costs to the boundaries (e.g. when a `u8` is first converted into an
+`Ascii`). It also catches bugs early, during compilation, rather than through
+run-time failures.
+
+On the other hand, some properties are difficult or impossible to
+express using types.
+
+#### Dynamic enforcement:
+
+Validate the input as it is processed (or ahead of time, if necessary).  Dynamic
+checking is often easier to implement than static checking, but has several
+downsides:
+
+1. Runtime overhead (unless checking can be done as part of processing the input).
+2. Delayed detection of bugs.
+3. Introduces failure cases, either via `fail!` or `Result`/`Option` types (see
+   the [error handling guidelines](../../errors/README.md)), which must then be
+   dealt with by client code.
+
+#### Dynamic enforcement with `debug_assert!`:
+
+Same as dynamic enforcement, but with the possibility of easily turning off
+expensive checks for production builds.
+
+#### Dynamic enforcement with opt-out:
+
+Same as dynamic enforcement, but adds sibling functions that opt out of the
+checking.
+
+The convention is to mark these opt-out functions with a suffix like
+`_unchecked` or by placing them in a `raw` submodule.
+
+The unchecked functions can be used judiciously in cases where (1) performance
+dictates avoiding checks and (2) the client is otherwise confident that the
+inputs are valid.
+
+> **[FIXME]** Should opt-out functions be marked `unsafe`?
diff --git a/src/doc/style/features/functions-and-methods/output.md b/src/doc/style/features/functions-and-methods/output.md
new file mode 100644 (file)
index 0000000..a83e2b7
--- /dev/null
@@ -0,0 +1,56 @@
+% Output from functions and methods
+
+### Don't overpromise. [FIXME]
+
+> **[FIXME]** Add discussion of overly-specific return types,
+> e.g. returning a compound iterator type rather than hiding it behind
+> a use of newtype.
+
+### Let clients choose what to throw away. [FIXME: needs RFC]
+
+#### Return useful intermediate results:
+
+Many functions that answer a question also compute interesting related data.  If
+this data is potentially of interest to the client, consider exposing it in the
+API.
+
+Prefer
+
+```rust
+struct SearchResult {
+    found: bool,          // item in container?
+    expected_index: uint  // what would the item's index be?
+}
+
+fn binary_search(&self, k: Key) -> SearchResult
+```
+or
+
+```rust
+fn binary_search(&self, k: Key) -> (bool, uint)
+```
+
+over
+
+```rust
+fn binary_search(&self, k: Key) -> bool
+```
+
+#### Yield back ownership:
+
+Prefer
+
+```rust
+fn from_utf8_owned(vv: Vec<u8>) -> Result<String, Vec<u8>>
+```
+
+over
+
+```rust
+fn from_utf8_owned(vv: Vec<u8>) -> Option<String>
+```
+
+The `from_utf8_owned` function gains ownership of a vector.  In the successful
+case, the function consumes its input, returning an owned string without
+allocating or copying. In the unsuccessful case, however, the function returns
+back ownership of the original slice.
diff --git a/src/doc/style/features/let.md b/src/doc/style/features/let.md
new file mode 100644 (file)
index 0000000..87117a2
--- /dev/null
@@ -0,0 +1,103 @@
+% Let binding
+
+### Always separately bind RAII guards. [FIXME: needs RFC]
+
+Prefer
+
+```rust
+fn use_mutex(m: sync::mutex::Mutex<int>) {
+    let guard = m.lock();
+    do_work(guard);
+    drop(guard); // unlock the lock
+    // do other work
+}
+```
+
+over
+
+```rust
+fn use_mutex(m: sync::mutex::Mutex<int>) {
+    do_work(m.lock());
+    // do other work
+}
+```
+
+As explained in the [RAII guide](../ownership/raii.md), RAII guards are values
+that represent ownership of some resource and whose destructor releases the
+resource. Because the lifetime of guards are significant, they should always be
+explicitly `let`-bound to make the lifetime clear. Consider using an explicit
+`drop` to release the resource early.
+
+### Prefer conditional expressions to deferred initialization. [FIXME: needs RFC]
+
+Prefer
+
+```rust
+let foo = match bar {
+    Baz  => 0,
+    Quux => 1
+};
+```
+
+over
+
+```rust
+let foo;
+match bar {
+    Baz  => {
+        foo = 0;
+    }
+    Quux => {
+        foo = 1;
+    }
+}
+```
+
+unless the conditions for initialization are too complex to fit into a simple
+conditional expression.
+
+### Use type annotations for clarification; prefer explicit generics when inference fails. [FIXME: needs RFC]
+
+Prefer
+
+```rust
+s.iter().map(|x| x * 2)
+        .collect::<Vec<_>>()
+```
+
+over
+
+```rust
+let v: Vec<_> = s.iter().map(|x| x * 2)
+                        .collect();
+```
+
+When the type of a value might be unclear to the _reader_ of the code, consider
+explicitly annotating it in a `let`.
+
+On the other hand, when the type is unclear to the _compiler_, prefer to specify
+the type by explicit generics instantiation, which is usually more clear.
+
+### Shadowing [FIXME]
+
+> **[FIXME]** Repeatedly shadowing a binding is somewhat common in Rust code. We
+> need to articulate a guideline on when it is appropriate/useful and when not.
+
+### Prefer immutable bindings. [FIXME: needs RFC]
+
+Use `mut` bindings to signal the span during which a value is mutated:
+
+```rust
+let mut v = Vec::new();
+// push things onto v
+let v = v;
+// use v immutably henceforth
+```
+
+### Prefer to bind all `struct` or tuple fields. [FIXME: needs RFC]
+
+When consuming a `struct` or tuple via a `let`, bind all of the fields rather
+than using `..` to elide the ones you don't need. The benefit is that when
+fields are added, the compiler will pinpoint all of the places where that type
+of value was consumed, which will often need to be adjusted to take the new
+field properly into account.
diff --git a/src/doc/style/features/loops.md b/src/doc/style/features/loops.md
new file mode 100644 (file)
index 0000000..b144825
--- /dev/null
@@ -0,0 +1,13 @@
+% Loops
+
+### Prefer `for` to `while`. [FIXME: needs RFC]
+
+A `for` loop is preferable to a `while` loop, unless the loop counts in a
+non-uniform way (making it difficult to express using `for`).
+
+### Guidelines for `loop`. [FIXME]
+
+> **[FIXME]** When is `loop` recommended? Some possibilities:
+> * For optimistic retry algorithms
+> * For servers
+> * To avoid mutating local variables sometimes needed to fit `while`
diff --git a/src/doc/style/features/match.md b/src/doc/style/features/match.md
new file mode 100644 (file)
index 0000000..131e0fa
--- /dev/null
@@ -0,0 +1,26 @@
+% Pattern matching
+
+### Dereference `match` targets when possible. [FIXME: needs RFC]
+
+Prefer
+
+~~~~
+match *foo {
+    X(...) => ...
+    Y(...) => ...
+}
+~~~~
+
+over
+
+~~~~
+match foo {
+    box X(...) => ...
+    box Y(...) => ...
+}
+~~~~
+
+<!-- ### Clearly indicate important scopes. **[FIXME: needs RFC]** -->
+
+<!-- If it is important that the destructor for a value be executed at a specific -->
+<!-- time, clearly bind that value using a standalone `let` -->
diff --git a/src/doc/style/features/modules.md b/src/doc/style/features/modules.md
new file mode 100644 (file)
index 0000000..04aae22
--- /dev/null
@@ -0,0 +1,133 @@
+% Modules
+
+> **[FIXME]** What general guidelines should we provide for module design?
+
+> We should discuss visibility, nesting, `mod.rs`, and any interesting patterns
+> around modules.
+
+### Headers [FIXME: needs RFC]
+
+Organize module headers as follows:
+  1. [Imports](../style/imports.md).
+  1. `mod` declarations.
+  1. `pub mod` declarations.
+
+### Avoid `path` directives. [FIXME: needs RFC]
+
+Avoid using `#[path="..."]` directives; make the file system and
+module hierarchy match, instead.
+
+### Use the module hirearchy to organize APIs into coherent sections. [FIXME]
+
+> **[FIXME]** Flesh this out with examples; explain what a "coherent
+> section" is with examples.
+>
+> The module hirearchy defines both the public and internal API of your module.
+> Breaking related functionality into submodules makes it understandable to both
+> users and contributors to the module.
+
+### Place modules in their own file. [FIXME: needs RFC]
+
+> **[FIXME]**
+> - "<100 lines" is arbitrary, but it's a clearer recommendation
+>   than "~1 page" or similar suggestions that vary by screen size, etc.
+
+For all except very short modules (<100 lines) and [tests](../testing/README.md),
+place the module `foo` in a separate file, as in:
+
+```rust
+pub mod foo;
+
+// in foo.rs or foo/mod.rs
+pub fn bar() { println!("..."); }
+/* ... */
+```
+
+rather than declaring it inline:
+
+```rust
+pub mod foo {
+    pub fn bar() { println!("..."); }
+    /* ... */
+}
+```
+
+#### Use subdirectories for modules with children. [FIXME: needs RFC]
+
+For modules that themselves have submodules, place the module in a separate
+directory (e.g., `bar/mod.rs` for a module `bar`) rather than the same directory.
+
+Note the structure of
+[`std::io`](http://doc.rust-lang.org/std/io/). Many of the submodules lack
+children, like
+[`io::fs`](http://doc.rust-lang.org/std/io/fs/)
+and
+[`io::stdio`](http://doc.rust-lang.org/std/io/stdio/).
+On the other hand,
+[`io::net`](http://doc.rust-lang.org/std/io/net/)
+contains submodules, so it lives in a separate directory:
+
+```
+io/mod.rs
+   io/extensions.rs
+   io/fs.rs
+   io/net/mod.rs
+          io/net/addrinfo.rs
+          io/net/ip.rs
+          io/net/tcp.rs
+          io/net/udp.rs
+          io/net/unix.rs
+   io/pipe.rs
+   ...
+```
+
+While it is possible to define all of `io` within a single directory,
+mirroring the module hirearchy in the directory structure makes
+submodules of `io::net` easier to find.
+
+### Consider top-level definitions or reexports. [FIXME: needs RFC]
+
+For modules with submodules,
+define or [reexport](http://doc.rust-lang.org/std/io/#reexports) commonly used
+definitions at the top level:
+
+* Functionality relevant to the module itself or to many of its
+  children should be defined in `mod.rs`.
+* Functionality specific to a submodule should live in that
+  submodule. Reexport at the top level for the most important or
+  common definitions.
+
+For example,
+[`IoError`](http://doc.rust-lang.org/std/io/struct.IoError.html)
+is defined in `io/mod.rs`, since it pertains to the entirety of `io`,
+while
+[`TcpStream`](http://doc.rust-lang.org/std/io/net/tcp/struct.TcpStream.html)
+is defined in `io/net/tcp.rs` and reexported in the `io` module.
+
+### Use internal module hirearchies for organization. [FIXME: needs RFC]
+
+> **[FIXME]**
+> - Referencing internal modules from the standard library is subject to
+>   becoming outdated.
+
+Internal module hirearchies (i.e., private submodules) may be used to
+hide implementation details that are not part of the module's API.
+
+For example, in [`std::io`](http://doc.rust-lang.org/std/io/), `mod mem`
+provides implementations for
+[`BufReader`](http://doc.rust-lang.org/std/io/struct.BufReader.html)
+and
+[`BufWriter`](http://doc.rust-lang.org/std/io/struct.BufWriter.html),
+but these are re-exported in `io/mod.rs` at the top level of the module:
+
+```rust
+// libstd/io/mod.rs
+
+pub use self::mem::{MemReader, BufReader, MemWriter, BufWriter};
+/* ... */
+mod mem;
+```
+
+This hides the detail that there even exists a `mod mem` in `io`, and
+helps keep code organized while offering freedom to change the
+implementation.
diff --git a/src/doc/style/features/traits/README.md b/src/doc/style/features/traits/README.md
new file mode 100644 (file)
index 0000000..1893db2
--- /dev/null
@@ -0,0 +1,22 @@
+% Traits
+
+Traits are probably Rust's most complex feature, supporting a wide range of use
+cases and design tradeoffs. Patterns of trait usage are still emerging.
+
+### Know whether a trait will be used as an object. [FIXME: needs RFC]
+
+Trait objects have some [significant limitations](objects.md): methods
+invoked through a trait object cannot use generics, and cannot use
+`Self` except in receiver position.
+
+When designing a trait, decide early on whether the trait will be used
+as an [object](objects.md) or as a [bound on generics](generics.md);
+the tradeoffs are discussed in each of the linked sections.
+
+If a trait is meant to be used as an object, its methods should take
+and return trait objects rather than use generics.
+
+
+### Default methods [FIXME]
+
+> **[FIXME]** Guidelines for default methods.
diff --git a/src/doc/style/features/traits/common.md b/src/doc/style/features/traits/common.md
new file mode 100644 (file)
index 0000000..48c37ea
--- /dev/null
@@ -0,0 +1,71 @@
+% Common traits
+
+### Eagerly implement common traits. [FIXME: needs RFC]
+
+Rust's trait system does not allow _orphans_: roughly, every `impl` must live
+either in the crate that defines the trait or the implementing
+type. Consequently, crates that define new types should eagerly implement all
+applicable, common traits.
+
+To see why, consider the following situation:
+
+* Crate `std` defines trait `Show`.
+* Crate `url` defines type `Url`, without implementing `Show`.
+* Crate `webapp` imports from both `std` and `url`,
+
+There is no way for `webapp` to add `Show` to `url`, since it defines neither.
+(Note: the newtype pattern can provide an efficient, but inconvenient
+workaround; see [newtype for views](../types/newtype.md))
+
+The most important common traits to implement from `std` are:
+
+```rust
+Clone, Show, Hash, Eq
+```
+
+#### When safe, derive or otherwise implement `Send` and `Share`. [FIXME]
+
+> **[FIXME]**. This guideline is in flux while the "opt-in" nature of
+> built-in traits is being decided. See https://github.com/rust-lang/rfcs/pull/127
+
+### Prefer to derive, rather than implement. [FIXME: needs RFC]
+
+Deriving saves implementation effort, makes correctness trivial, and
+automatically adapts to upstream changes.
+
+### Do not overload operators in surprising ways. [FIXME: needs RFC]
+
+Operators with built in syntax (`*`, `|`, and so on) can be provided for a type
+by implementing the traits in `core::ops`. These operators come with strong
+expectations: implement `Mul` only for an operation that bears some resemblance
+to multiplication (and shares the expected properties, e.g. associativity), and
+so on for the other traits.
+
+### The `Drop` trait
+
+The `Drop` trait is treated specially by the compiler as a way of
+associating destructors with types. See
+[the section on destructors](../../ownership/destructors.md) for
+guidance.
+
+### The `Deref`/`DerefMut` traits
+
+#### Use `Deref`/`DerefMut` only for smart pointers. [FIXME: needs RFC]
+
+The `Deref` traits are used implicitly by the compiler in many circumstances,
+and interact with method resolution. The relevant rules are designed
+specifically to accommodate smart pointers, and so the traits should be used
+only for that purpose.
+
+#### Do not fail within a `Deref`/`DerefMut` implementation. [FIXME: needs RFC]
+
+Because the `Deref` traits are invoked implicitly by the compiler in sometimes
+subtle ways, failure during dereferencing can be extremely confusing. If a
+dereference might not succeed, target the `Deref` trait as a `Result` or
+`Option` type instead.
+
+#### Avoid inherent methods when implementing `Deref`/`DerefMut` [FIXME: needs RFC]
+
+The rules around method resolution and `Deref` are in flux, but inherent methods
+on a type implementing `Deref` are likely to shadow any methods of the referent
+with the same name.
diff --git a/src/doc/style/features/traits/extensions.md b/src/doc/style/features/traits/extensions.md
new file mode 100644 (file)
index 0000000..fc3a03c
--- /dev/null
@@ -0,0 +1,7 @@
+% Using traits to add extension methods
+
+> **[FIXME]** Elaborate.
+
+### Consider using default methods rather than extension traits **[FIXME]**
+
+> **[FIXME]** Elaborate.
diff --git a/src/doc/style/features/traits/generics.md b/src/doc/style/features/traits/generics.md
new file mode 100644 (file)
index 0000000..ab4f9cb
--- /dev/null
@@ -0,0 +1,68 @@
+% Using traits for bounds on generics
+
+The most widespread use of traits is for writing generic functions or types. For
+example, the following signature describes a function for consuming any iterator
+yielding items of type `A` to produce a collection of `A`:
+
+```rust
+fn from_iter<T: Iterator<A>>(iterator: T) -> SomeCollection<A>
+```
+
+Here, the `Iterator` trait is specifies an interface that a type `T` must
+explicitly implement to be used by this generic function.
+
+**Pros**:
+
+* _Reusability_. Generic functions can be applied to an open-ended collection of
+  types, while giving a clear contract for the functionality those types must
+  provide.
+* _Static dispatch and optimization_. Each use of a generic function is
+  specialized ("monomorphized") to the particular types implementing the trait
+  bounds, which means that (1) invocations of trait methods are static, direct
+  calls to the implementation and (2) the compiler can inline and otherwise
+  optimize these calls.
+* _Inline layout_. If a `struct` and `enum` type is generic over some type
+  parameter `T`, values of type `T` will be laid out _inline_ in the
+  `struct`/`enum`, without any indirection.
+* _Inference_. Since the type parameters to generic functions can usually be
+  inferred, generic functions can help cut down on verbosity in code where
+  explicit conversions or other method calls would usually be necessary. See the
+  [overloading/implicits use case](#use-case:-limited-overloading-and/or-implicit-conversions)
+  below.
+* _Precise types_. Because generic give a _name_ to the specific type
+  implementing a trait, it is possible to be precise about places where that
+  exact type is required or produced. For example, a function
+
+  ```rust
+  fn binary<T: Trait>(x: T, y: T) -> T
+  ```
+
+  is guaranteed to consume and produce elements of exactly the same type `T`; it
+  cannot be invoked with parameters of different types that both implement
+  `Trait`.
+
+**Cons**:
+
+* _Code size_. Specializing generic functions means that the function body is
+  duplicated. The increase in code size must be weighed against the performance
+  benefits of static dispatch.
+* _Homogeneous types_. This is the other side of the "precise types" coin: if
+  `T` is a type parameter, it stands for a _single_ actual type. So for example
+  a `Vec<T>` contains elements of a single concrete type (and, indeed, the
+  vector representation is specialized to lay these out in line). Sometimes
+  heterogeneous collections are useful; see
+  [trait objects](#use-case:-trait-objects) below.
+* _Signature verbosity_. Heavy use of generics can bloat function signatures.
+  **[Ed. note]** This problem may be mitigated by some language improvements; stay tuned.
+
+### Favor widespread traits. **[FIXME: needs RFC]**
+
+Generic types are a form of abstraction, which entails a mental indirection: if
+a function takes an argument of type `T` bounded by `Trait`, clients must first
+think about the concrete types that implement `Trait` to understand how and when
+the function is callable.
+
+To keep the cost of abstraction low, favor widely-known traits. Whenever
+possible, implement and use traits provided as part of the standard library.  Do
+not introduce new traits for generics lightly; wait until there are a wide range
+of types that can implement the type.
diff --git a/src/doc/style/features/traits/objects.md b/src/doc/style/features/traits/objects.md
new file mode 100644 (file)
index 0000000..38494a9
--- /dev/null
@@ -0,0 +1,49 @@
+% Using trait objects
+
+> **[FIXME]** What are uses of trait objects other than heterogeneous collections?
+
+Trait objects are useful primarily when _heterogeneous_ collections of objects
+need to be treated uniformly; it is the closest that Rust comes to
+object-oriented programming.
+
+```rust
+struct Frame  { ... }
+struct Button { ... }
+struct Label  { ... }
+
+trait Widget  { ... }
+
+impl Widget for Frame  { ... }
+impl Widget for Button { ... }
+impl Widget for Label  { ... }
+
+impl Frame {
+    fn new(contents: &[Box<Widget>]) -> Frame {
+        ...
+    }
+}
+
+fn make_gui() -> Box<Widget> {
+    let b: Box<Widget> = box Button::new(...);
+    let l: Box<Widget> = box Label::new(...);
+
+    box Frame::new([b, l]) as Box<Widget>
+}
+```
+
+By using trait objects, we can set up a GUI framework with a `Frame` widget that
+contains a heterogeneous collection of children widgets.
+
+**Pros**:
+
+* _Heterogeneity_. When you need it, you really need it.
+* _Code size_. Unlike generics, trait objects do not generate specialized
+  (monomorphized) versions of code, which can greatly reduce code size.
+
+**Cons**:
+
+* _No generic methods_. Trait objects cannot currently provide generic methods.
+* _Dynamic dispatch and fat pointers_. Trait objects inherently involve
+  indirection and vtable dispatch, which can carry a performance penalty.
+* _No Self_. Except for the method receiver argument, methods on trait objects
+  cannot use the `Self` type.
diff --git a/src/doc/style/features/traits/overloading.md b/src/doc/style/features/traits/overloading.md
new file mode 100644 (file)
index 0000000..d7482c9
--- /dev/null
@@ -0,0 +1,7 @@
+% Using traits for overloading
+
+> **[FIXME]** Elaborate.
+
+> **[FIXME]** We need to decide on guidelines for this use case. There are a few
+> patterns emerging in current Rust code, but it's not clear how widespread they
+> should be.
diff --git a/src/doc/style/features/traits/reuse.md b/src/doc/style/features/traits/reuse.md
new file mode 100644 (file)
index 0000000..6735023
--- /dev/null
@@ -0,0 +1,30 @@
+% Using traits to share implementations
+
+> **[FIXME]** Elaborate.
+
+> **[FIXME]** We probably want to discourage this, at least when used in a way
+> that is publicly exposed.
+
+Traits that provide default implmentations for function can provide code reuse
+across types. For example, a `print` method can be defined across multiple
+types as follows:
+
+``` Rust
+trait Printable {
+    // Default method implementation
+    fn print(&self) { println!("{:?}", *self) }
+}
+
+impl Printable for int {}
+
+impl Printable for String {
+    fn print(&self) { println!("{}", *self) }
+}
+
+impl Printable for bool {}
+
+impl Printable for f32 {}
+```
+
+This allows the implementation of `print` to be shared across types, yet
+overridden where needed, as seen in the `impl` for `String`.
diff --git a/src/doc/style/features/types/README.md b/src/doc/style/features/types/README.md
new file mode 100644 (file)
index 0000000..c675eb5
--- /dev/null
@@ -0,0 +1,68 @@
+% Data types
+
+### Use custom types to imbue meaning; do not abuse `bool`, `Option` or other core types. **[FIXME: needs RFC]**
+
+Prefer
+
+```rust
+let w = Widget::new(Small, Round)
+```
+
+over
+
+```rust
+let w = Widget::new(true, false)
+```
+
+Core types like `bool`, `u8` and `Option` have many possible interpretations.
+
+Use custom types (whether `enum`s, `struct`, or tuples) to convey
+interpretation and invariants. In the above example,
+it is not immediately clear what `true` and `false` are conveying without
+looking up the argument names, but `Small` and `Round` are more suggestive.
+
+Using custom types makes it easier to expand the
+options later on, for example by adding an `ExtraLarge` variant.
+
+See [the newtype pattern](newtype.md) for a no-cost way to wrap
+existing types with a distinguished name.
+
+### Prefer private fields, except for passive data. **[FIXME: needs RFC]**
+
+Making a field public is a strong commitment: it pins down a representation
+choice, _and_ prevents the type from providing any validation or maintaining any
+invariants on the contents of the field, since clients can mutate it arbitrarily.
+
+Public fields are most appropriate for `struct` types in the C spirit: compound,
+passive data structures. Otherwise, consider providing getter/setter methods
+and hiding fields instead.
+
+> **[FIXME]** Cross-reference validation for function arguments.
+
+### Use custom `enum`s for alternatives, `bitflags` for C-style flags. **[FIXME: needs RFC]**
+
+Rust supports `enum` types with "custom discriminants":
+
+~~~~
+enum Color {
+  Red = 0xff0000,
+  Green = 0x00ff00,
+  Blue = 0x0000ff
+}
+~~~~
+
+Custom discriminants are useful when an `enum` type needs to be serialized to an
+integer value compatibly with some other system/language. They support
+"typesafe" APIs: by taking a `Color`, rather than an integer, a function is
+guaranteed to get well-formed inputs, even if it later views those inputs as
+integers.
+
+An `enum` allows an API to request exactly one choice from among many. Sometimes
+an API's input is instead the presence or absence of a set of flags. In C code,
+this is often done by having each flag correspond to a particular bit, allowing
+a single integer to represent, say, 32 or 64 flags. Rust's `std::bitflags`
+module provides a typesafe way for doing so.
+
+### Phantom types. [FIXME]
+
+> **[FIXME]** Add some material on phantom types (https://blog.mozilla.org/research/2014/06/23/static-checking-of-units-in-servo/)
diff --git a/src/doc/style/features/types/conversions.md b/src/doc/style/features/types/conversions.md
new file mode 100644 (file)
index 0000000..f0f230f
--- /dev/null
@@ -0,0 +1,22 @@
+% Conversions between types
+
+### Associate conversions with the most specific type involved. **[FIXME: needs RFC]**
+
+When in doubt, prefer `to_`/`as_`/`into_` to `from_`, because they are
+more ergonomic to use (and can be chained with other methods).
+
+For many conversions between two types, one of the types is clearly more
+"specific": it provides some additional invariant or interpretation that is not
+present in the other type. For example, `str` is more specific than `&[u8]`,
+since it is a utf-8 encoded sequence of bytes.
+
+Conversions should live with the more specific of the involved types. Thus,
+`str` provides both the `as_bytes` method and the `from_utf8` constructor for
+converting to and from `&[u8]` values. Besides being intuitive, this convention
+avoids polluting concrete types like `&[u8]` with endless conversion methods.
+
+### Explicitly mark lossy conversions, or do not label them as conversions. **[FIXME: needs RFC]**
+
+If a function's name implies that it is a conversion (prefix `from_`, `as_`,
+`to_` or `into_`), but the function loses information, add a suffix `_lossy` or
+otherwise indicate the lossyness. Consider avoiding the conversion name prefix.
diff --git a/src/doc/style/features/types/newtype.md b/src/doc/style/features/types/newtype.md
new file mode 100644 (file)
index 0000000..60c17fc
--- /dev/null
@@ -0,0 +1,69 @@
+% The newtype pattern
+
+A "newtype" is a tuple or `struct` with a single field. The terminology is borrowed from Haskell.
+
+Newtypes are a zero-cost abstraction: they introduce a new, distinct name for an
+existing type, with no runtime overhead when converting between the two types.
+
+### Use newtypes to provide static distinctions. [FIXME: needs RFC]
+
+Newtypes can statically distinguish between different interpretations of an
+underlying type.
+
+For example, a `f64` value might be used to represent a quantity in miles or in
+kilometers. Using newtypes, we can keep track of the intended interpretation:
+
+```rust
+struct Miles(pub f64);
+struct Kilometers(pub f64);
+
+impl Miles {
+    fn as_kilometers(&self) -> Kilometers { ... }
+}
+impl Kilometers {
+    fn as_miles(&self) -> Miles { ... }
+}
+```
+
+Once we have separated these two types, we can statically ensure that we do not
+confuse them. For example, the function
+
+```rust
+fn are_we_there_yet(distance_travelled: Miles) -> bool { ... }
+```
+
+cannot accidentally be called with a `Kilometers` value. The compiler will
+remind us to perform the conversion, thus averting certain
+[catastrophic bugs](http://en.wikipedia.org/wiki/Mars_Climate_Orbiter).
+
+### Use newtypes with private fields for hiding. [FIXME: needs RFC]
+
+A newtype can be used to hide representation details while making precise
+promises to the client.
+
+For example, consider a function `my_transform` that returns a compound iterator
+type `Enumerate<Skip<vec::MoveItems<T>>>`. We wish to hide this type from the
+client, so that the client's view of the return type is roughly `Iterator<(uint,
+T)>`. We can do so using the newtype pattern:
+
+```rust
+struct MyTransformResult<T>(Enumerate<Skip<vec::MoveItems<T>>>);
+impl<T> Iterator<(uint, T)> for MyTransformResult<T> { ... }
+
+fn my_transform<T, Iter: Iterator<T>>(iter: Iter) -> MyTransformResult<T> {
+    ...
+}
+```
+
+Aside from simplifying the signature, this use of newtypes allows us to make a
+expose and promise less to the client. The client does not know _how_ the result
+iterator is constructed or represented, which means the representation can
+change in the future without breaking client code.
+
+> **[FIXME]** Interaction with auto-deref.
+
+### Use newtypes to provide cost-free _views_ of another type. **[FIXME]**
+
+> **[FIXME]** Describe the pattern of using newtypes to provide a new set of
+> inherent or trait methods, providing a different perspective on the underlying
+> type.
diff --git a/src/doc/style/ownership/README.md b/src/doc/style/ownership/README.md
new file mode 100644 (file)
index 0000000..11bdb03
--- /dev/null
@@ -0,0 +1,3 @@
+% Ownership and resource management
+
+> **[FIXME]** Add general remarks about ownership/resources here.
diff --git a/src/doc/style/ownership/builders.md b/src/doc/style/ownership/builders.md
new file mode 100644 (file)
index 0000000..94eda59
--- /dev/null
@@ -0,0 +1,176 @@
+% The builder pattern
+
+Some data structures are complicated to construct, due to their construction needing:
+
+* a large number of inputs
+* compound data (e.g. slices)
+* optional configuration data
+* choice between several flavors
+
+which can easily lead to a large number of distinct constructors with
+many arguments each.
+
+If `T` is such a data structure, consider introducing a `T` _builder_:
+
+1. Introduce a separate data type `TBuilder` for incrementally configuring a `T`
+   value. When possible, choose a better name: e.g. `Command` is the builder for
+   `Process`.
+2. The builder constructor should take as parameters only the data _required_ to
+   to make a `T`.
+3. The builder should offer a suite of convenient methods for configuration,
+   including setting up compound inputs (like slices) incrementally.
+   These methods should return `self` to allow chaining.
+4. The builder should provide one or more "_terminal_" methods for actually building a `T`.
+
+The builder pattern is especially appropriate when building a `T` involves side
+effects, such as spawning a task or launching a process.
+
+In Rust, there are two variants of the builder pattern, differing in the
+treatment of ownership, as described below.
+
+### Non-consuming builders (preferred):
+
+In some cases, constructing the final `T` does not require the builder itself to
+be consumed. The follow variant on
+[`std::io::process::Command`](http://static.rust-lang.org/doc/master/std/io/process/struct.Command.html)
+is one example:
+
+```rust
+// NOTE: the actual Command API does not use owned Strings;
+// this is a simplified version.
+
+pub struct Command {
+    program: String,
+    args: Vec<String>,
+    cwd: Option<String>,
+    // etc
+}
+
+impl Command {
+    pub fn new(program: String) -> Command {
+        Command {
+            program: program,
+            args: Vec::new(),
+            cwd: None,
+        }
+    }
+
+    /// Add an argument to pass to the program.
+    pub fn arg<'a>(&'a mut self, arg: String) -> &'a mut Command {
+        self.args.push(arg);
+        self
+    }
+
+    /// Add multiple arguments to pass to the program.
+    pub fn args<'a>(&'a mut self, args: &[String])
+                    -> &'a mut Command {
+        self.args.push_all(args);
+        self
+    }
+
+    /// Set the working directory for the child process.
+    pub fn cwd<'a>(&'a mut self, dir: String) -> &'a mut Command {
+        self.cwd = Some(dir);
+        self
+    }
+
+    /// Executes the command as a child process, which is returned.
+    pub fn spawn(&self) -> IoResult<Process> {
+        ...
+    }
+}
+```
+
+Note that the `spawn` method, which actually uses the builder configuration to
+spawn a process, takes the builder by immutable reference. This is possible
+because spawning the process does not require ownership of the configuration
+data.
+
+Because the terminal `spawn` method only needs a reference, the configuration
+methods take and return a mutable borrow of `self`.
+
+#### The benefit
+
+By using borrows throughout, `Command` can be used conveniently for both
+one-liner and more complex constructions:
+
+```rust
+// One-liners
+Command::new("/bin/cat").arg("file.txt").spawn();
+
+// Complex configuration
+let mut cmd = Command::new("/bin/ls");
+cmd.arg(".");
+
+if size_sorted {
+    cmd.arg("-S");
+}
+
+cmd.spawn();
+```
+
+### Consuming builders:
+
+Sometimes builders must transfer ownership when constructing the final type
+`T`, meaning that the terminal methods must take `self` rather than `&self`:
+
+```rust
+// A simplified excerpt from std::task::TaskBuilder
+
+impl TaskBuilder {
+    /// Name the task-to-be. Currently the name is used for identification
+    /// only in failure messages.
+    pub fn named(mut self, name: String) -> TaskBuilder {
+        self.name = Some(name);
+        self
+    }
+
+    /// Redirect task-local stdout.
+    pub fn stdout(mut self, stdout: Box<Writer + Send>) -> TaskBuilder {
+        self.stdout = Some(stdout);
+        //   ^~~~~~ this is owned and cannot be cloned/re-used
+        self
+    }
+
+    /// Creates and executes a new child task.
+    pub fn spawn(self, f: proc():Send) {
+        // consume self
+        ...
+    }
+}
+```
+
+Here, the `stdout` configuration involves passing ownership of a `Writer`,
+which must be transferred to the task upon construction (in `spawn`).
+
+When the terminal methods of the builder require ownership, there is a basic tradeoff:
+
+* If the other builder methods take/return a mutable borrow, the complex
+  configuration case will work well, but one-liner configuration becomes
+  _impossible_.
+
+* If the other builder methods take/return an owned `self`, one-liners
+  continue to work well but complex configuration is less convenient.
+
+Under the rubric of making easy things easy and hard things possible, _all_
+builder methods for a consuming builder should take and returned an owned
+`self`. Then client code works as follows:
+
+```rust
+// One-liners
+TaskBuilder::new().named("my_task").spawn(proc() { ... });
+
+// Complex configuration
+let mut task = TaskBuilder::new();
+task = task.named("my_task_2"); // must re-assign to retain ownership
+
+if reroute {
+    task = task.stdout(mywriter);
+}
+
+task.spawn(proc() { ... });
+```
+
+One-liners work as before, because ownership is threaded through each of the
+builder methods until being consumed by `spawn`. Complex configuration,
+however, is more verbose: it requires re-assigning the builder at each step.
diff --git a/src/doc/style/ownership/cell-smart.md b/src/doc/style/ownership/cell-smart.md
new file mode 100644 (file)
index 0000000..cd027cc
--- /dev/null
@@ -0,0 +1,4 @@
+% Cells and smart pointers
+
+> **[FIXME]** Add guidelines about when to use Cell, RefCell, Rc and
+> Arc (and how to use them together).
diff --git a/src/doc/style/ownership/constructors.md b/src/doc/style/ownership/constructors.md
new file mode 100644 (file)
index 0000000..b4a1147
--- /dev/null
@@ -0,0 +1,62 @@
+% Constructors
+
+### Define constructors as static, inherent methods. [FIXME: needs RFC]
+
+In Rust, "constructors" are just a convention:
+
+```rust
+impl<T> Vec<T> {
+    pub fn new() -> Vec<T> { ... }
+}
+```
+
+Constructors are static (no `self`) inherent methods for the type that they
+construct. Combined with the practice of
+[fully importing type names](../style/imports.md), this convention leads to
+informative but concise construction:
+
+```rust
+use vec::Vec;
+
+// construct a new vector
+let mut v = Vec::new();
+```
+
+This convention also applied to conversion constructors (prefix `from` rather
+than `new`).
+
+### Provide constructors for passive `struct`s with defaults. [FIXME: needs RFC]
+
+Given the `struct`
+
+```rust
+pub struct Config {
+    pub color: Color,
+    pub size:  Size,
+    pub shape: Shape,
+}
+```
+
+provide a constructor if there are sensible defaults:
+
+```rust
+impl Config {
+    pub fn new() -> Config {
+        Config {
+            color: Brown,
+            size: Medium,
+            shape: Square,
+        }
+    }
+}
+```
+
+which then allows clients to concisely override using `struct` update syntax:
+
+```rust
+Config { color: Red, .. Config::new() };
+```
+
+See the [guideline for field privacy](../features/types/README.md) for
+discussion on when to create such "passive" `struct`s with public
+fields.
diff --git a/src/doc/style/ownership/destructors.md b/src/doc/style/ownership/destructors.md
new file mode 100644 (file)
index 0000000..8f58aa6
--- /dev/null
@@ -0,0 +1,22 @@
+% Destructors
+
+Unlike constructors, destructors in Rust have a special status: they are added
+by implementing `Drop` for a type, and they are automatically invoked as values
+go out of scope.
+
+> **[FIXME]** This section needs to be expanded.
+
+### Destructors should not fail. [FIXME: needs RFC]
+
+Destructors are executed on task failure, and in that context a failing
+destructor causes the program to abort.
+
+Instead of failing in a destructor, provide a separate method for checking for
+clean teardown, e.g. a `close` method, that returns a `Result` to signal
+problems.
+
+### Destructors should not block. [FIXME: needs RFC]
+
+Similarly, destructors should not invoke blocking operations, which can make
+debugging much more difficult. Again, consider providing a separate method for
+preparing for an infallible, nonblocking teardown.
diff --git a/src/doc/style/ownership/raii.md b/src/doc/style/ownership/raii.md
new file mode 100644 (file)
index 0000000..244e809
--- /dev/null
@@ -0,0 +1,12 @@
+% RAII
+
+Resource Acquisition is Initialization
+
+> **[FIXME]** Explain the RAII pattern and give best practices.
+
+### Whenever possible, tie resource access to guard scopes [FIXME]
+
+> **[FIXME]** Example: Mutex guards guarantee that access to the
+> protected resource only happens when the guard is in scope.
+
+`must_use`
diff --git a/src/doc/style/platform.md b/src/doc/style/platform.md
new file mode 100644 (file)
index 0000000..d29d060
--- /dev/null
@@ -0,0 +1,7 @@
+% FFI and platform-specific code **[FIXME]**
+
+> **[FIXME]** Not sure where this should live.
+
+When writing cross-platform code, group platform-specific code into a
+module called `platform`. Avoid `#[cfg]` directives outside this
+`platform` module.
diff --git a/src/doc/style/safety/README.md b/src/doc/style/safety/README.md
new file mode 100644 (file)
index 0000000..1ac6e70
--- /dev/null
@@ -0,0 +1,19 @@
+% Safety and guarantees
+
+> **[FIXME]** Is there a better phrase than "strong guarantees" that encompasses
+> both e.g. memory safety and e.g. data structure invariants?
+
+A _guarantee_ is a property that holds no matter what client code does, unless
+the client explicitly opts out:
+
+* Rust guarantees memory safety and data-race freedom, with `unsafe`
+  blocks as an opt-out mechanism.
+
+* APIs in Rust often provide their own guarantees. For example, `std::str`
+guarantees that its underlying buffer is valid utf-8. The `std::path::Path` type
+guarantees no interior nulls. Both strings and paths provide `unsafe` mechanisms
+for opting out of these guarantees (and thereby avoiding runtime checks).
+
+Thinking about guarantees is an essential part of writing good Rust code.  The
+rest of this subsection outlines some cross-cutting principles around
+guarantees.
diff --git a/src/doc/style/safety/lib-guarantees.md b/src/doc/style/safety/lib-guarantees.md
new file mode 100644 (file)
index 0000000..aa87223
--- /dev/null
@@ -0,0 +1,81 @@
+% Library-level guarantees
+
+Most libraries rely on internal invariants, e.g. about their data, resource
+ownership, or protocol states. In Rust, broken invariants cannot produce
+segfaults, but they can still lead to wrong answers.
+
+### Provide library-level guarantees whenever practical. **[FIXME: needs RFC]**
+
+Library-level invariants should be turned into guarantees whenever
+practical. They should hold no matter what the client does, modulo
+explicit opt-outs. Depending on the kind of invariant, this can be
+achieved through a combination of static and dynamic enforcement, as
+described below.
+
+#### Static enforcement:
+
+Guaranteeing invariants almost always requires _hiding_,
+i.e. preventing the client from directly accessing or modifying
+internal data.
+
+For example, the representation of the `str` type is hidden,
+which means that any value of type `str` must have been produced
+through an API under the control of the `str` module, and these
+APIs in turn ensure valid utf-8 encoding.
+
+Rust's type system makes it possible to provide guarantees even while
+revealing more of the representation than usual. For example, the
+`as_bytes()` method on `&str` gives a _read-only_ view into the
+underlying buffer, which cannot be used to violate the utf-8 property.
+
+#### Dynamic enforcement:
+
+Malformed inputs from the client are hazards to library-level
+guarantees, so library APIs should validate their input.
+
+For example, `std::str::from_utf8_owned` attempts to convert a `u8`
+slice into an owned string, but dynamically checks that the slice is
+valid utf-8 and returns `Err` if not.
+
+See
+[the discussion on input validation](../features/functions-and-methods/input.md)
+for more detail.
+
+
+### Prefer static enforcement of guarantees. **[FIXME: needs RFC]**
+
+Static enforcement provides two strong benefits over dynamic enforcement:
+
+* Bugs are caught at compile time.
+* There is no runtime cost.
+
+Sometimes purely static enforcement is impossible or impractical. In these
+cases, a library should check as much as possible statically, but defer to
+dynamic checks where needed.
+
+For example, the `std::string` module exports a `String` type with the guarantee
+that all instances are valid utf-8:
+
+* Any _consumer_ of a `String` is statically guaranteed utf-8 contents. For example,
+  the `append` method can push a `&str` onto the end of a `String` without
+  checking anything dynamically, since the existing `String` and `&str` are
+  statically guaranteed to be in utf-8.
+
+* Some _producers_ of a `String` must perform dynamic checks. For example, the
+  `from_utf8` function attempts to convert a `Vec<u8>` into a `String`, but
+  dynamically checks that the contents are utf-8.
+
+### Provide opt-outs with caution; make them explicit. **[FIXME: needs RFC]**
+
+Providing library-level guarantees sometimes entails inconvenience (for static
+checks) or overhead (for dynamic checks). So it is sometimes desirable to allow
+clients to sidestep this checking, while promising to use the API in a way that
+still provides the guarantee. Such escape hatches should only be be introduced
+when there is a demonstrated need for them.
+
+It should be trivial for clients to audit their use of the library for
+escape hatches.
+
+See
+[the discussion on input validation](../features/functions-and-methods/input.md)
+for conventions on marking opt-out functions.
diff --git a/src/doc/style/safety/unsafe.md b/src/doc/style/safety/unsafe.md
new file mode 100644 (file)
index 0000000..a8a50af
--- /dev/null
@@ -0,0 +1,22 @@
+% Using `unsafe`
+
+### Unconditionally guarantee safety, or mark API as `unsafe`. **[FIXME: needs RFC]**
+
+Memory safety, type safety, and data race freedom are basic assumptions for all
+Rust code.
+
+APIs that use `unsafe` blocks internally thus have two choices:
+
+* They can guarantee safety _unconditionally_ (i.e., regardless of client
+  behavior or inputs) and be exported as safe code. Any safety violation is then
+  the library's fault, not the client's fault.
+
+* They can export potentially unsafe functions with the `unsafe` qualifier. In
+  this case, the documentation should make very clear the conditions under which
+  safety is guaranteed.
+
+The result is that a client program can never violate safety merely by having a
+bug; it must have explicitly opted out by using an `unsafe` block.
+
+Of the two options for using `unsafe`, creating such safe abstractions (the
+first option above) is strongly preferred.
diff --git a/src/doc/style/style/README.md b/src/doc/style/style/README.md
new file mode 100644 (file)
index 0000000..8744971
--- /dev/null
@@ -0,0 +1,5 @@
+% Style
+
+This section gives a set of strict rules for styling Rust code.
+
+> **[FIXME]** General remarks about the style guidelines
diff --git a/src/doc/style/style/braces.md b/src/doc/style/style/braces.md
new file mode 100644 (file)
index 0000000..0f61bac
--- /dev/null
@@ -0,0 +1,77 @@
+% Braces, semicolons, and commas [FIXME: needs RFC]
+
+### Opening braces always go on the same line.
+
+``` rust
+fn foo() {
+    ...
+}
+
+fn frobnicate(a: Bar, b: Bar,
+              c: Bar, d: Bar)
+              -> Bar {
+    ...
+}
+
+trait Bar {
+    fn baz(&self);
+}
+
+impl Bar for Baz {
+    fn baz(&self) {
+        ...
+    }
+}
+
+frob(|x| {
+    x.transpose()
+})
+```
+
+### `match` arms get braces, except for single-line expressions.
+
+``` rust
+match foo {
+    bar => baz,
+    quux => {
+        do_something();
+        do_something_else()
+    }
+}
+```
+
+### `return` statements get semicolons.
+
+``` rust
+fn foo() {
+    do_something();
+
+    if condition() {
+        return;
+    }
+
+    do_something_else();
+}
+```
+
+### Trailing commas
+
+> **[FIXME]** We should have a guideline for when to include trailing
+> commas in `struct`s, `match`es, function calls, etc.
+>
+> One possible rule: a trailing comma should be included whenever the
+> closing delimiter appears on a separate line:
+
+```rust
+Foo { bar: 0, baz: 1 }
+
+Foo {
+    bar: 0,
+    baz: 1,
+}
+
+match a_thing {
+    None => 0,
+    Some(x) => 1,
+}
+```
diff --git a/src/doc/style/style/comments.md b/src/doc/style/style/comments.md
new file mode 100644 (file)
index 0000000..347750c
--- /dev/null
@@ -0,0 +1,87 @@
+% Comments [FIXME: needs RFC]
+
+### Avoid block comments.
+
+Use line comments:
+
+``` rust
+// Wait for the main task to return, and set the process error code
+// appropriately.
+```
+
+Instead of:
+
+``` rust
+/*
+ * Wait for the main task to return, and set the process error code
+ * appropriately.
+ */
+```
+
+## Doc comments
+
+Doc comments are prefixed by three slashes (`///`) and indicate
+documentation that you would like to be included in Rustdoc's output.
+They support
+[Markdown syntax](https://en.wikipedia.org/wiki/Markdown)
+and are the main way of documenting your public APIs.
+
+The supported markdown syntax includes all of the extensions listed in the
+[GitHub Flavored Markdown]
+(https://help.github.com/articles/github-flavored-markdown) documentation,
+plus superscripts.
+
+### Summary line
+
+The first line in any doc comment should be a single-line short sentence
+providing a summary of the code. This line is used as a short summary
+description throughout Rustdoc's output, so it's a good idea to keep it
+short.
+
+### Sentence structure
+
+All doc comments, including the summary line, should begin with a
+capital letter and end with a period, question mark, or exclamation
+point. Prefer full sentences to fragments.
+
+The summary line should be written in
+[third person singular present indicative form]
+(http://en.wikipedia.org/wiki/English_verbs#Third_person_singular_present).
+Basically, this means write "Returns" instead of "Return".
+
+For example:
+
+``` rust
+/// Sets up a default runtime configuration, given compiler-supplied arguments.
+///
+/// This function will block until the entire pool of M:N schedulers has
+/// exited. This function also requires a local task to be available.
+///
+/// # Arguments
+///
+/// * `argc` & `argv` - The argument vector. On Unix this information is used
+///                     by `os::args`.
+/// * `main` - The initial procedure to run inside of the M:N scheduling pool.
+///            Once this procedure exits, the scheduling pool will begin to shut
+///            down. The entire pool (and this function) will only return once
+///            all child tasks have finished executing.
+///
+/// # Return value
+///
+/// The return value is used as the process return code. 0 on success, 101 on
+/// error.
+```
+
+### Code snippets
+
+> **[FIXME]**
+
+### Avoid inner doc comments.
+
+Use inner doc comments _only_ to document crates and file-level modules:
+
+``` rust
+//! The core library.
+//!
+//! The core library is a something something...
+```
diff --git a/src/doc/style/style/features.md b/src/doc/style/style/features.md
new file mode 100644 (file)
index 0000000..f73517c
--- /dev/null
@@ -0,0 +1,13 @@
+## `return` [FIXME: needs RFC]
+
+Terminate `return` statements with semicolons:
+
+``` rust
+fn foo(bar: int) -> Option<int> {
+    if some_condition() {
+        return None;
+    }
+
+    ...
+}
+```
diff --git a/src/doc/style/style/imports.md b/src/doc/style/style/imports.md
new file mode 100644 (file)
index 0000000..207a3fd
--- /dev/null
@@ -0,0 +1,50 @@
+% Imports [FIXME: needs RFC]
+
+The imports of a crate/module should consist of the following
+sections, in order, with a blank space between each:
+
+* `extern crate` directives
+* external `use` imports
+* local `use` imports
+* `pub use` imports
+
+For example:
+
+```rust
+// Crates.
+extern crate getopts;
+extern crate mylib;
+
+// Standard library imports.
+use getopts::{optopt, getopts};
+use std::os;
+
+// Import from a library that we wrote.
+use mylib::webserver;
+
+// Will be reexported when we import this module.
+pub use self::types::Webdata;
+```
+
+### Avoid `use *`, except in tests.
+
+Glob imports have several downsides:
+* They make it harder to tell where names are bound.
+* They are forwards-incompatible, since new upstream exports can clash
+  with existing names.
+
+When writing a [`test` submodule](../testing/README.md), importing `super::*` is appropriate
+as a convenience.
+
+### Prefer fully importing types/traits while module-qualifying functions.
+
+For example:
+
+```rust
+use option::Option;
+use mem;
+
+let i: int = mem::transmute(Option(0));
+```
+
+> **[FIXME]** Add rationale.
diff --git a/src/doc/style/style/naming/README.md b/src/doc/style/style/naming/README.md
new file mode 100644 (file)
index 0000000..9d78721
--- /dev/null
@@ -0,0 +1,115 @@
+% Naming conventions
+
+### General conventions [RFC #430]
+
+> The guidelines below were approved by [RFC #430](https://github.com/rust-lang/rfcs/pull/430).
+
+In general, Rust tends to use `CamelCase` for "type-level" constructs
+(types and traits) and `snake_case` for "value-level" constructs. More
+precisely:
+
+| Item | Convention |
+| ---- | ---------- |
+| Crates | `snake_case` (but prefer single word) |
+| Modules | `snake_case` |
+| Types | `CamelCase` |
+| Traits | `CamelCase` |
+| Enum variants | `CamelCase` |
+| Functions | `snake_case` |
+| Methods | `snake_case` |
+| General constructors | `new` or `with_more_details` |
+| Conversion constructors | `from_some_other_type` |
+| Local variables | `snake_case` |
+| Static variables | `SCREAMING_SNAKE_CASE` |
+| Constant variables | `SCREAMING_SNAKE_CASE` |
+| Type parameters | concise `CamelCase`, usually single uppercase letter: `T` |
+| Lifetimes | short, lowercase: `'a` |
+
+<p>
+In `CamelCase`, acronyms count as one word: use `Uuid` rather than
+`UUID`.  In `snake_case`, acronyms are lower-cased: `is_xid_start`.
+
+In `snake_case` or `SCREAMING_SNAKE_CASE`, a "word" should never
+consist of a single letter unless it is the last "word". So, we have
+`btree_map` rather than `b_tree_map`, but `PI_2` rather than `PI2`.
+
+### Referring to types in function/method names [RFC 344]
+
+> The guidelines below were approved by [RFC #344](https://github.com/rust-lang/rfcs/pull/344).
+
+Function names often involve type names, the most common example being conversions
+like `as_slice`. If the type has a purely textual name (ignoring parameters), it
+is straightforward to convert between type conventions and function conventions:
+
+Type name | Text in methods
+--------- | ---------------
+`String`  | `string`
+`Vec<T>`  | `vec`
+`YourType`| `your_type`
+
+Types that involve notation follow the convention below. There is some
+overlap on these rules; apply the most specific applicable rule:
+
+Type name | Text in methods
+--------- | ---------------
+`&str`    | `str`
+`&[T]`    | `slice`
+`&mut [T]`| `mut_slice`
+`&[u8]`   | `bytes`
+`&T`      | `ref`
+`&mut T`  | `mut`
+`*const T`| `ptr`
+`*mut T`  | `mut_ptr`
+
+### Avoid redundant prefixes [RFC 356]
+
+> The guidelines below were approved by [RFC #356](https://github.com/rust-lang/rfcs/pull/356).
+
+Names of items within a module should not be prefixed with that module's name:
+
+Prefer
+
+``` rust
+mod foo {
+    pub struct Error { ... }
+}
+```
+
+over
+
+``` rust
+mod foo {
+    pub struct FooError { ... }
+}
+```
+
+This convention avoids stuttering (like `io::IoError`). Library clients can
+rename on import to avoid clashes.
+
+### Getter/setter methods [RFC 344]
+
+> The guidelines below were approved by [RFC #344](https://github.com/rust-lang/rfcs/pull/344).
+
+Some data structures do not wish to provide direct access to their fields, but
+instead offer "getter" and "setter" methods for manipulating the field state
+(often providing checking or other functionality).
+
+The convention for a field `foo: T` is:
+
+* A method `foo(&self) -> &T` for getting the current value of the field.
+* A method `set_foo(&self, val: T)` for setting the field. (The `val` argument
+  here may take `&T` or some other type, depending on the context.)
+
+Note that this convention is about getters/setters on ordinary data types, *not*
+on [builder objects](../ownership/builders.html).
+
+### Escape hatches [FIXME]
+
+> **[FIXME]** Should we standardize a convention for functions that may break API
+> guarantees? e.g. `ToCStr::to_c_str_unchecked`
+
+### Predicates
+
+* Simple boolean predicates should be prefixed with `is_` or another
+  short question word, e.g., `is_empty`.
+* Common exceptions: `lt`, `gt`, and other established predicate names.
diff --git a/src/doc/style/style/naming/containers.md b/src/doc/style/style/naming/containers.md
new file mode 100644 (file)
index 0000000..04204f0
--- /dev/null
@@ -0,0 +1,69 @@
+% Common container/wrapper methods [FIXME: needs RFC]
+
+Containers, wrappers, and cells all provide ways to access the data
+they enclose.  Accessor methods often have variants to access the data
+by value, by reference, and by mutable reference.
+
+In general, the `get` family of methods is used to access contained
+data without any risk of task failure; they return `Option` as
+appropriate. This name is chosen rather than names like `find` or
+`lookup` because it is appropriate for a wider range of container types.
+
+#### Containers
+
+For a container with keys/indexes of type `K` and elements of type `V`:
+
+```rust
+// Look up element without failing
+fn get(&self, key: K) -> Option<&V>
+fn get_mut(&mut self, key: K) -> Option<&mut V>
+
+// Convenience for .get(key).map(|elt| elt.clone())
+fn get_clone(&self, key: K) -> Option<V>
+
+// Lookup element, failing if it is not found:
+impl Index<K, V> for Container { ... }
+impl IndexMut<K, V> for Container { ... }
+```
+
+#### Wrappers/Cells
+
+Prefer specific conversion functions like `as_bytes` or `into_vec` whenever
+possible. Otherwise, use:
+
+```rust
+// Extract contents without failing
+fn get(&self) -> &V
+fn get_mut(&mut self) -> &mut V
+fn unwrap(self) -> V
+```
+
+#### Wrappers/Cells around `Copy` data
+
+```rust
+// Extract contents without failing
+fn get(&self) -> V
+```
+
+#### `Option`-like types
+
+Finally, we have the cases of types like `Option` and `Result`, which
+play a special role for failure.
+
+For `Option<V>`:
+
+```rust
+// Extract contents or fail if not available
+fn assert(self) -> V
+fn expect(self, &str) -> V
+```
+
+For `Result<V, E>`:
+
+```rust
+// Extract the contents of Ok variant; fail if Err
+fn assert(self) -> V
+
+// Extract the contents of Err variant; fail if Ok
+fn assert_err(self) -> E
+```
diff --git a/src/doc/style/style/naming/conversions.md b/src/doc/style/style/naming/conversions.md
new file mode 100644 (file)
index 0000000..0287919
--- /dev/null
@@ -0,0 +1,32 @@
+% Conversions [Rust issue #7087]
+
+> The guidelines below were approved by [rust issue #7087](https://github.com/rust-lang/rust/issues/7087).
+
+> **[FIXME]** Should we provide standard traits for conversions? Doing
+> so nicely will require
+> [trait reform](https://github.com/rust-lang/rfcs/pull/48) to land.
+
+Conversions should be provided as methods, with names prefixed as follows:
+
+| Prefix | Cost | Consumes convertee |
+| ------ | ---- | ------------------ |
+| `as_` | Free | No |
+| `to_` | Expensive | No |
+| `into_` | Variable | Yes |
+
+<p>
+For example:
+
+* `as_bytes()` gives a `&[u8]` view into a `&str`, which is a no-op.
+* `to_owned()` copies a `&str` to a new `String`.
+* `into_bytes()` consumes a `String` and yields the underlying
+  `Vec<u8>`, which is a no-op.
+
+Conversions prefixed `as_` and `into_` typically _decrease abstraction_, either
+exposing a view into the underlying representation (`as`) or deconstructing data
+into its underlying representation (`into`). Conversions prefixed `to_`, on the
+other hand, typically stay at the same level of abstraction but do some work to
+change one representation into another.
+
+> **[FIXME]** The distinctions between conversion methods does not work
+> so well for `from_` conversion constructors. Is that a problem?
diff --git a/src/doc/style/style/naming/iterators.md b/src/doc/style/style/naming/iterators.md
new file mode 100644 (file)
index 0000000..38138b5
--- /dev/null
@@ -0,0 +1,32 @@
+% Iterators
+
+#### Method names [RFC #199]
+
+> The guidelines below were approved by [RFC #199](https://github.com/rust-lang/rfcs/pull/199).
+
+For a container with elements of type `U`, iterator methods should be named:
+
+```rust
+fn iter(&self) -> T           // where T implements Iterator<&U>
+fn iter_mut(&mut self) -> T   // where T implements Iterator<&mut U>
+fn into_iter(self) -> T       // where T implements Iterator<U>
+```
+
+The default iterator variant yields shared references `&U`.
+
+#### Type names [RFC #344]
+
+> The guidelines below were approved by [RFC #344](https://github.com/rust-lang/rfcs/pull/344).
+
+The name of an iterator type should be the same as the method that
+produces the iterator.
+
+For example:
+
+* `iter` should yield an `Iter`
+* `iter_mut` should yield an `IterMut`
+* `into_iter` should yield an `IntoIter`
+* `keys` should yield `Keys`
+
+These type names make the most sense when prefixed with their owning module,
+e.g. `vec::IntoIter`.
diff --git a/src/doc/style/style/naming/ownership.md b/src/doc/style/style/naming/ownership.md
new file mode 100644 (file)
index 0000000..32cd8a1
--- /dev/null
@@ -0,0 +1,34 @@
+% Ownership variants [RFC #199]
+
+> The guidelines below were approved by [RFC #199](https://github.com/rust-lang/rfcs/pull/199).
+
+Functions often come in multiple variants: immutably borrowed, mutably
+borrowed, and owned.
+
+The right default depends on the function in question. Variants should
+be marked through suffixes.
+
+#### Immutably borrowed by default
+
+If `foo` uses/produces an immutable borrow by default, use:
+
+* The `_mut` suffix (e.g. `foo_mut`) for the mutably borrowed variant.
+* The `_move` suffix (e.g. `foo_move`) for the owned variant.
+
+#### Owned by default
+
+If `foo` uses/produces owned data by default, use:
+
+* The `_ref` suffix (e.g. `foo_ref`) for the immutably borrowed variant.
+* The `_mut` suffix (e.g. `foo_mut`) for the mutably borrowed variant.
+
+#### Exceptions
+
+In the case of iterators, the moving variant can also be understood as
+an `into` conversion, `into_iter`, and `for x in v.into_iter()` reads
+arguably better than `for x in v.iter_move()`, so the convention is
+`into_iter`.
+
+For mutably borrowed variants, if the `mut` qualifier is part of a
+type name (e.g. `as_mut_slice`), it should appear as it would appear
+in the type.
diff --git a/src/doc/style/style/optional.md b/src/doc/style/style/optional.md
new file mode 100644 (file)
index 0000000..d3c2178
--- /dev/null
@@ -0,0 +1,3 @@
+*
+
+*
diff --git a/src/doc/style/style/organization.md b/src/doc/style/style/organization.md
new file mode 100644 (file)
index 0000000..8506540
--- /dev/null
@@ -0,0 +1,14 @@
+% Organization [FIXME: needs RFC]
+
+> **[FIXME]** What else?
+
+### Reexport the most important types at the crate level.
+
+Crates `pub use` the most common types for convenience, so that clients do not
+have to remember or write the crate's module hierarchy to use these types.
+
+### Define types and operations together.
+
+Type definitions and the functions/methods that operate on them should be
+defined together in a single module, with the type appearing above the
+functions/methods.
diff --git a/src/doc/style/style/whitespace.md b/src/doc/style/style/whitespace.md
new file mode 100644 (file)
index 0000000..b21b280
--- /dev/null
@@ -0,0 +1,133 @@
+% Whitespace [FIXME: needs RFC]
+
+* Lines must not exceed 99 characters.
+* Use 4 spaces for indentation, _not_ tabs.
+* No trailing whitespace at the end of lines or files.
+
+### Spaces
+
+* Use spaces around binary operators, including the equals sign in attributes:
+
+``` rust
+#[deprecated = "Use `bar` instead."]
+fn foo(a: uint, b: uint) -> uint {
+    a + b
+}
+```
+
+* Use a space after colons and commas:
+
+``` rust
+fn foo(a: Bar);
+
+MyStruct { foo: 3, bar: 4 }
+
+foo(bar, baz);
+```
+
+* Use a space after the opening and before the closing brace for
+  single line blocks or `struct` expressions:
+
+``` rust
+spawn(proc() { do_something(); })
+
+Point { x: 0.1, y: 0.3 }
+```
+
+### Line wrapping
+
+* For multiline function signatures, each new line should align with the
+  first parameter. Multiple parameters per line are permitted:
+
+``` rust
+fn frobnicate(a: Bar, b: Bar,
+              c: Bar, d: Bar)
+              -> Bar {
+    ...
+}
+
+fn foo<T: This,
+       U: That>(
+       a: Bar,
+       b: Bar)
+       -> Baz {
+    ...
+}
+```
+
+* Multiline function invocations generally follow the same rule as for
+  signatures. However, if the final argument begins a new block, the
+  contents of the block may begin on a new line, indented one level:
+
+``` rust
+fn foo_bar(a: Bar, b: Bar,
+           c: |Bar|) -> Bar {
+    ...
+}
+
+// Same line is fine:
+foo_bar(x, y, |z| { z.transpose(y) });
+
+// Indented body on new line is also fine:
+foo_bar(x, y, |z| {
+    z.quux();
+    z.rotate(x)
+})
+```
+
+> **[FIXME]** Do we also want to allow the following?
+>
+> ```rust
+> frobnicate(
+>     arg1,
+>     arg2,
+>     arg3)
+> ```
+>
+> This style could ease the conflict between line length and functions
+> with many parameters (or long method chains).
+
+### Matches
+
+> * **[Deprecated]** If you have multiple patterns in a single `match`
+>   arm, write each pattern on a separate line:
+>
+>     ``` rust
+>     match foo {
+>         bar(_)
+>         | baz => quux,
+>         x
+>         | y
+>         | z => {
+>             quuux
+>         }
+>     }
+>     ```
+
+### Alignment
+
+Idiomatic code should not use extra whitespace in the middle of a line
+to provide alignment.
+
+
+``` rust
+// Good
+struct Foo {
+    short: f64,
+    really_long: f64,
+}
+
+// Bad
+struct Bar {
+    short:       f64,
+    really_long: f64,
+}
+
+// Good
+let a = 0;
+let radius = 7;
+
+// Bad
+let b        = 0;
+let diameter = 7;
+```
diff --git a/src/doc/style/testing/README.md b/src/doc/style/testing/README.md
new file mode 100644 (file)
index 0000000..a21f694
--- /dev/null
@@ -0,0 +1,5 @@
+% Testing
+
+> **[FIXME]** Add some general remarks about when and how to unit
+> test, versus other kinds of testing. What are our expectations for
+> Rust's core libraries?
diff --git a/src/doc/style/testing/unit.md b/src/doc/style/testing/unit.md
new file mode 100644 (file)
index 0000000..813660d
--- /dev/null
@@ -0,0 +1,30 @@
+% Unit testing
+
+Unit tests should live in a `test` submodule at the bottom of the module they
+test. Mark the `test` submodule with `#[cfg(test)]` so it is only compiled when
+testing.
+
+The `test` module should contain:
+
+* Imports needed only for testing.
+* Functions marked with `#[test]` striving for full coverage of the parent module's
+  definitions.
+* Auxiliary functions needed for writing the tests.
+
+For example:
+
+``` rust
+// Excerpt from std::str
+
+#[cfg(test)]
+mod test {
+    #[test]
+    fn test_eq() {
+        assert!((eq(&"".to_owned(), &"".to_owned())));
+        assert!((eq(&"foo".to_owned(), &"foo".to_owned())));
+        assert!((!eq(&"foo".to_owned(), &"bar".to_owned())));
+    }
+}
+```
+
+> **[FIXME]** add details about useful macros for testing, e.g. `assert!`
diff --git a/src/doc/style/todo.md b/src/doc/style/todo.md
new file mode 100644 (file)
index 0000000..28ef2a1
--- /dev/null
@@ -0,0 +1,5 @@
+* [Containers and iteration]()
+* [The visitor pattern]()
+* [Concurrency]()
+* [Documentation]()
+* [Macros]()
index 9e16414d225a98e5f9ad636503e726457624c47d..d57aff7f4f411fbc9974666127a02150b324301d 100644 (file)
     * [Generics](generics.md)
     * [Traits](traits.md)
     * [Static and Dynamic Dispatch](static-and-dynamic-dispatch.md)
+    * [Macros](macros.md)
     * [Concurrency](concurrency.md)
     * [Error Handling](error-handling.md)
     * [Documentation](documentation.md)
 * [III: Advanced Topics](advanced.md)
     * [FFI](ffi.md)
     * [Unsafe Code](unsafe.md)
-    * [Macros](macros.md)
+    * [Advanced Macros](advanced-macros.md)
     * [Compiler Plugins](plugins.md)
 * [Conclusion](conclusion.md)
 * [Glossary](glossary.md)
diff --git a/src/doc/trpl/advanced-macros.md b/src/doc/trpl/advanced-macros.md
new file mode 100644 (file)
index 0000000..aff3650
--- /dev/null
@@ -0,0 +1,210 @@
+% Advanced macros
+
+This chapter picks up where the [introductory macro chapter](macros.html) left
+off.
+
+# Syntactic requirements
+
+Even when Rust code contains un-expanded macros, it can be parsed as a full
+syntax tree. This property can be very useful for editors and other tools that
+process code. It also has a few consequences for the design of Rust's macro
+system.
+
+One consequence is that Rust must determine, when it parses a macro invocation,
+whether the macro stands in for
+
+* zero or more items,
+* zero or more methods,
+* an expression,
+* a statement, or
+* a pattern.
+
+A macro invocation within a block could stand for some items, or for an
+expression / statement. Rust uses a simple rule to resolve this ambiguity. A
+macro invocation that stands for items must be either
+
+* delimited by curly braces, e.g. `foo! { ... }`, or
+* terminated by a semicolon, e.g. `foo!(...);`
+
+Another consequence of pre-expansion parsing is that the macro invocation must
+consist of valid Rust tokens. Furthermore, parentheses, brackets, and braces
+must be balanced within a macro invocation. For example, `foo!([)` is
+forbidden. This allows Rust to know where the macro invocation ends.
+
+More formally, the macro invocation body must be a sequence of *token trees*.
+A token tree is defined recursively as either
+
+* a sequence of token trees surrounded by matching `()`, `[]`, or `{}`, or
+* any other single token.
+
+Within a matcher, each metavariable has a *fragment specifier*, identifying
+which syntactic form it matches.
+
+* `ident`: an identifier. Examples: `x`; `foo`.
+* `path`: a qualified name. Example: `T::SpecialA`.
+* `expr`: an expression. Examples: `2 + 2`; `if true then { 1 } else { 2 }`; `f(42)`.
+* `ty`: a type. Examples: `i32`; `Vec<(char, String)>`; `&T`.
+* `pat`: a pattern. Examples: `Some(t)`; `(17, 'a')`; `_`.
+* `stmt`: a single statement. Example: `let x = 3`.
+* `block`: a brace-delimited sequence of statements. Example:
+  `{ log(error, "hi"); return 12; }`.
+* `item`: an [item][]. Examples: `fn foo() { }`; `struct Bar;`.
+* `meta`: a "meta item", as found in attributes. Example: `cfg(target_os = "windows")`.
+* `tt`: a single token tree.
+
+There are additional rules regarding the next token after a metavariable:
+
+* `expr` variables must be followed by one of: `=> , ;`
+* `ty` and `path` variables must be followed by one of: `=> , : = > as`
+* `pat` variables must be followed by one of: `=> , =`
+* Other variables may be followed by any token.
+
+These rules provide some flexibility for Rust's syntax to evolve without
+breaking existing macros.
+
+The macro system does not deal with parse ambiguity at all. For example, the
+grammar `$($t:ty)* $e:expr` will always fail to parse, because the parser would
+be forced to choose between parsing `$t` and parsing `$e`. Changing the
+invocation syntax to put a distinctive token in front can solve the problem. In
+this case, you can write `$(T $t:ty)* E $e:exp`.
+
+[item]: ../reference.html#items
+
+# Scoping and macro import/export
+
+Macros are expanded at an early stage in compilation, before name resolution.
+One downside is that scoping works differently for macros, compared to other
+constructs in the language.
+
+Definition and expansion of macros both happen in a single depth-first,
+lexical-order traversal of a crate's source. So a macro defined at module scope
+is visible to any subsequent code in the same module, which includes the body
+of any subsequent child `mod` items.
+
+A macro defined within the body of a single `fn`, or anywhere else not at
+module scope, is visible only within that item.
+
+If a module has the `macro_use` attribute, its macros are also visible in its
+parent module after the child's `mod` item. If the parent also has `macro_use`
+then the macros will be visible in the grandparent after the parent's `mod`
+item, and so forth.
+
+The `macro_use` attribute can also appear on `extern crate`. In this context
+it controls which macros are loaded from the external crate, e.g.
+
+```rust,ignore
+#[macro_use(foo, bar)]
+extern crate baz;
+```
+
+If the attribute is given simply as `#[macro_use]`, all macros are loaded. If
+there is no `#[macro_use]` attribute then no macros are loaded. Only macros
+defined with the `#[macro_export]` attribute may be loaded.
+
+To load a crate's macros *without* linking it into the output, use `#[no_link]`
+as well.
+
+An example:
+
+```rust
+macro_rules! m1 { () => (()) }
+
+// visible here: m1
+
+mod foo {
+    // visible here: m1
+
+    #[macro_export]
+    macro_rules! m2 { () => (()) }
+
+    // visible here: m1, m2
+}
+
+// visible here: m1
+
+macro_rules! m3 { () => (()) }
+
+// visible here: m1, m3
+
+#[macro_use]
+mod bar {
+    // visible here: m1, m3
+
+    macro_rules! m4 { () => (()) }
+
+    // visible here: m1, m3, m4
+}
+
+// visible here: m1, m3, m4
+# fn main() { }
+```
+
+When this library is loaded with `#[macro_use] extern crate`, only `m2` will
+be imported.
+
+The Rust Reference has a [listing of macro-related
+attributes](../reference.html#macro--and-plugin-related-attributes).
+
+# The variable `$crate`
+
+A further difficulty occurs when a macro is used in multiple crates. Say that
+`mylib` defines
+
+```rust
+pub fn increment(x: u32) -> u32 {
+    x + 1
+}
+
+#[macro_export]
+macro_rules! inc_a {
+    ($x:expr) => ( ::increment($x) )
+}
+
+#[macro_export]
+macro_rules! inc_b {
+    ($x:expr) => ( ::mylib::increment($x) )
+}
+# fn main() { }
+```
+
+`inc_a` only works within `mylib`, while `inc_b` only works outside the
+library. Furthermore, `inc_b` will break if the user imports `mylib` under
+another name.
+
+Rust does not (yet) have a hygiene system for crate references, but it does
+provide a simple workaround for this problem. Within a macro imported from a
+crate named `foo`, the special macro variable `$crate` will expand to `::foo`.
+By contrast, when a macro is defined and then used in the same crate, `$crate`
+will expand to nothing. This means we can write
+
+```rust
+#[macro_export]
+macro_rules! inc {
+    ($x:expr) => ( $crate::increment($x) )
+}
+# fn main() { }
+```
+
+to define a single macro that works both inside and outside our library. The
+function name will expand to either `::increment` or `::mylib::increment`.
+
+To keep this system simple and correct, `#[macro_use] extern crate ...` may
+only appear at the root of your crate, not inside `mod`. This ensures that
+`$crate` is a single identifier.
+
+# A final note
+
+Macros, as currently implemented, are not for the faint of heart. Even
+ordinary syntax errors can be more difficult to debug when they occur inside a
+macro, and errors caused by parse problems in generated code can be very
+tricky. Invoking the `log_syntax!` macro can help elucidate intermediate
+states, invoking `trace_macros!(true)` will automatically print those
+intermediate states out, and passing the flag `--pretty expanded` as a
+command-line argument to the compiler will show the result of expansion.
+
+If Rust's macro system can't do what you need, you may want to write a
+[compiler plugin](plugins.html) instead. Compared to `macro_rules!`
+macros, this is significantly more work, the interfaces are much less stable,
+and the warnings about debugging apply ten-fold. In exchange you get the
+flexibility of running arbitrary Rust code within the compiler. Syntax
+extension plugins are sometimes called *procedural macros* for this reason.
index db3202b30345f5f80b647a19ddea091ff06074df..85d67262c4066d9bf78b9d7185b0020fefa23877 100644 (file)
@@ -322,8 +322,8 @@ The `ordering` variable has the type `Ordering`, and so contains one of the
 three values. We then do a bunch of `if`/`else` comparisons to check which
 one it is.
 
-This `Ordering::Greater` notation is too long. Lets use `use` to import can
-the `enum` variants instead. This will avoid full scoping:
+This `Ordering::Greater` notation is too long. Let's use `use` to import the
+`enum` variants instead. This will avoid full scoping:
 
 ```{rust}
 use std::cmp::Ordering::{self, Equal, Less, Greater};
index 3c933c1c5af5856484dd4fdb992c4b4423d414ff..9f8f76e1fea6e2fe597d9661226921466ec4d9ce 100644 (file)
@@ -57,13 +57,13 @@ place!
 ## Threads
 
 Rust's standard library provides a library for 'threads', which allow you to
-run Rust code in parallel. Here's a basic example of using `Thread`:
+run Rust code in parallel. Here's a basic example of using `std::thread`:
 
 ```
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
-    Thread::scoped(|| {
+    thread::scoped(|| {
         println!("Hello from a thread!");
     });
 }
@@ -73,10 +73,10 @@ The `Thread::scoped()` method accepts a closure, which is executed in a new
 thread. It's called `scoped` because this thread returns a join guard:
 
 ```
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
-    let guard = Thread::scoped(|| {
+    let guard = thread::scoped(|| {
         println!("Hello from a thread!");
     });
 
@@ -85,15 +85,15 @@ fn main() {
 ```
 
 When `guard` goes out of scope, it will block execution until the thread is
-finished. If we didn't want this behaviour, we could use `Thread::spawn()`:
+finished. If we didn't want this behaviour, we could use `thread::spawn()`:
 
 ```
-use std::thread::Thread;
+use std::thread;
 use std::old_io::timer;
 use std::time::Duration;
 
 fn main() {
-    Thread::spawn(|| {
+    thread::spawn(|| {
         println!("Hello from a thread!");
     });
 
@@ -101,24 +101,6 @@ fn main() {
 }
 ```
 
-Or call `.detach()`:
-
-```
-use std::thread::Thread;
-use std::old_io::timer;
-use std::time::Duration;
-
-fn main() {
-    let guard = Thread::scoped(|| {
-        println!("Hello from a thread!");
-    });
-
-    guard.detach();
-
-    timer::sleep(Duration::milliseconds(50));
-}
-```
-
 We need to `sleep` here because when `main()` ends, it kills all of the
 running threads.
 
@@ -164,7 +146,7 @@ As an example, here is a Rust program that would have a data race in many
 languages. It will not compile:
 
 ```ignore
-use std::thread::Thread;
+use std::thread;
 use std::old_io::timer;
 use std::time::Duration;
 
@@ -172,7 +154,7 @@ fn main() {
     let mut data = vec![1u32, 2, 3];
 
     for i in 0..2 {
-        Thread::spawn(move || {
+        thread::spawn(move || {
             data[i] += 1;
         });
     }
@@ -203,7 +185,7 @@ only one person at a time can mutate what's inside. For that, we can use the
 but for a different reason:
 
 ```ignore
-use std::thread::Thread;
+use std::thread;
 use std::old_io::timer;
 use std::time::Duration;
 use std::sync::Mutex;
@@ -213,7 +195,7 @@ fn main() {
 
     for i in 0..2 {
         let data = data.lock().unwrap();
-        Thread::spawn(move || {
+        thread::spawn(move || {
             data[i] += 1;
         });
     }
@@ -255,7 +237,7 @@ We can use `Arc<T>` to fix this. Here's the working version:
 
 ```
 use std::sync::{Arc, Mutex};
-use std::thread::Thread;
+use std::thread;
 use std::old_io::timer;
 use std::time::Duration;
 
@@ -264,7 +246,7 @@ fn main() {
 
     for i in 0us..2 {
         let data = data.clone();
-        Thread::spawn(move || {
+        thread::spawn(move || {
             let mut data = data.lock().unwrap();
             data[i] += 1;
         });
@@ -280,14 +262,14 @@ thread more closely:
 
 ```
 # use std::sync::{Arc, Mutex};
-# use std::thread::Thread;
+# use std::thread;
 # use std::old_io::timer;
 # use std::time::Duration;
 # fn main() {
 #     let data = Arc::new(Mutex::new(vec![1u32, 2, 3]));
 #     for i in 0us..2 {
 #         let data = data.clone();
-Thread::spawn(move || {
+thread::spawn(move || {
     let mut data = data.lock().unwrap();
     data[i] += 1;
 });
@@ -315,7 +297,7 @@ than waiting for a specific time:
 
 ```
 use std::sync::{Arc, Mutex};
-use std::thread::Thread;
+use std::thread;
 use std::sync::mpsc;
 
 fn main() {
@@ -326,7 +308,7 @@ fn main() {
     for _ in 0..10 {
         let (data, tx) = (data.clone(), tx.clone());
 
-        Thread::spawn(move || {
+        thread::spawn(move || {
             let mut data = data.lock().unwrap();
             *data += 1;
 
@@ -348,7 +330,7 @@ is `Send` over the channel!
 
 ```
 use std::sync::{Arc, Mutex};
-use std::thread::Thread;
+use std::thread;
 use std::sync::mpsc;
 
 fn main() {
@@ -357,7 +339,7 @@ fn main() {
     for _ in 0..10 {
         let tx = tx.clone();
 
-        Thread::spawn(move || {
+        thread::spawn(move || {
             let answer = 42u32;
 
             tx.send(answer);
@@ -378,9 +360,9 @@ A `panic!` will crash the currently executing thread. You can use Rust's
 threads as a simple isolation mechanism:
 
 ```
-use std::thread::Thread;
+use std::thread;
 
-let result = Thread::scoped(move || {
+let result = thread::spawn(move || {
     panic!("oops!");
 }).join();
 
index 2651949747952748af855976566024ea941d1e1f..ded30063ebaf08fbf6a539374a1a978d70699172 100644 (file)
@@ -15,7 +15,7 @@ comments":
 // the "link" crate attribute is currently required for rustdoc, but normally
 // isn't needed.
 #![crate_id = "universe"]
-#![crate_type="lib"]
+#![crate_type= "lib"]
 
 //! Tools for dealing with universes (this is a doc comment, and is shown on
 //! the crate index page. The ! makes it apply to the parent of the comment,
index ce0283480c60cb3df49da87f1a3decfa83929f54..45c08af04f8773c6be6469cf0b2b7031ab27c735 100644 (file)
@@ -4,19 +4,19 @@ Let's talk about loops.
 
 Remember Rust's `for` loop? Here's an example:
 
-```{rust}
+```rust
 for x in 0..10 {
     println!("{}", x);
 }
 ```
 
-Now that you know more Rust, we can talk in detail about how this works. The
-`range` function returns an *iterator*. An iterator is something that we can
+Now that you know more Rust, we can talk in detail about how this works.
+Ranges (the `0..10`) are 'iterators'. An iterator is something that we can
 call the `.next()` method on repeatedly, and it gives us a sequence of things.
 
 Like this:
 
-```{rust}
+```rust
 let mut range = 0..10;
 
 loop {
@@ -29,12 +29,12 @@ loop {
 }
 ```
 
-We make a mutable binding to the return value of `range`, which is our iterator.
-We then `loop`, with an inner `match`. This `match` is used on the result of
-`range.next()`, which gives us a reference to the next value of the iterator.
-`next` returns an `Option<i32>`, in this case, which will be `Some(i32)` when
-we have a value and `None` once we run out. If we get `Some(i32)`, we print it
-out, and if we get `None`, we `break` out of the loop.
+We make a mutable binding to the range, which is our iterator. We then `loop`,
+with an inner `match`. This `match` is used on the result of `range.next()`,
+which gives us a reference to the next value of the iterator. `next` returns an
+`Option<i32>`, in this case, which will be `Some(i32)` when we have a value and
+`None` once we run out. If we get `Some(i32)`, we print it out, and if we get
+`None`, we `break` out of the loop.
 
 This code sample is basically the same as our `for` loop version. The `for`
 loop is just a handy way to write this `loop`/`match`/`break` construct.
@@ -43,13 +43,13 @@ loop is just a handy way to write this `loop`/`match`/`break` construct.
 own iterator involves implementing the `Iterator` trait. While doing that is
 outside of the scope of this guide, Rust provides a number of useful iterators
 to accomplish various tasks. Before we talk about those, we should talk about a
-Rust anti-pattern. And that's `range`.
+Rust anti-pattern. And that's using ranges like this.
 
-Yes, we just talked about how `range` is cool. But `range` is also very
-primitive. For example, if you needed to iterate over the contents of
-a vector, you may be tempted to write this:
+Yes, we just talked about how ranges are cool. But ranges are also very
+primitive. For example, if you needed to iterate over the contents of a vector,
+you may be tempted to write this:
 
-```{rust}
+```rust
 let nums = vec![1, 2, 3];
 
 for i in 0..nums.len() {
@@ -61,7 +61,7 @@ This is strictly worse than using an actual iterator. The `.iter()` method on
 vectors returns an iterator which iterates through a reference to each element
 of the vector in turn. So write this:
 
-```{rust}
+```rust
 let nums = vec![1, 2, 3];
 
 for num in nums.iter() {
@@ -83,7 +83,7 @@ works. `num` is actually of type `&i32`. That is, it's a reference to an `i32`,
 not an `i32` itself. `println!` handles the dereferencing for us, so we don't
 see it. This code works fine too:
 
-```{rust}
+```rust
 let nums = vec![1, 2, 3];
 
 for num in nums.iter() {
@@ -97,7 +97,7 @@ involve making a copy of the data and giving us the copy. With references,
 we're just borrowing a reference to the data, and so it's just passing
 a reference, without needing to do the copy.
 
-So, now that we've established that `range` is often not what you want, let's
+So, now that we've established that ranges are often not what you want, let's
 talk about what you do want instead.
 
 There are three broad classes of things that are relevant here: iterators,
@@ -108,8 +108,7 @@ There are three broad classes of things that are relevant here: iterators,
   different output sequence.
 * *consumers* operate on an iterator, producing some final set of values.
 
-Let's talk about consumers first, since you've already seen an iterator,
-`range`.
+Let's talk about consumers first, since you've already seen an iterator, ranges.
 
 ## Consumers
 
@@ -118,7 +117,7 @@ The most common consumer is `collect()`. This code doesn't quite compile,
 but it shows the intention:
 
 ```{rust,ignore}
-let one_to_one_hundred = (1..101i32).collect();
+let one_to_one_hundred = (1..101).collect();
 ```
 
 As you can see, we call `collect()` on our iterator. `collect()` takes
@@ -127,8 +126,8 @@ of the results. So why won't this compile? Rust can't determine what
 type of things you want to collect, and so you need to let it know.
 Here's the version that does compile:
 
-```{rust}
-let one_to_one_hundred = (1..101i32).collect::<Vec<i32>>();
+```rust
+let one_to_one_hundred = (1..101).collect::<Vec<i32>>();
 ```
 
 If you remember, the `::<>` syntax allows us to give a type hint,
@@ -137,7 +136,7 @@ need to use the whole type, though. Using a `_` will let you provide
 a partial hint:
 
 ```rust
-let one_to_one_hundred = range(1, 101).collect::<Vec<_>>();
+let one_to_one_hundred = (1..101).collect::<Vec<_>>();
 ```
 
 This says "Collect into a `Vec<T>`, please, but infer what the `T` is for me."
@@ -146,8 +145,8 @@ This says "Collect into a `Vec<T>`, please, but infer what the `T` is for me."
 `collect()` is the most common consumer, but there are others too. `find()`
 is one:
 
-```{rust}
-let greater_than_forty_two = (0..100i32)
+```rust
+let greater_than_forty_two = (0..100)
                              .find(|x| *x > 42);
 
 match greater_than_forty_two {
@@ -163,9 +162,8 @@ element, `find` returns an `Option` rather than the element itself.
 
 Another important consumer is `fold`. Here's what it looks like:
 
-```{rust}
-let sum = (1..4)
-              .fold(0, |sum, x| sum + x);
+```rust
+let sum = (1..4).fold(0, |sum, x| sum + x);
 ```
 
 `fold()` is a consumer that looks like this:
@@ -187,7 +185,7 @@ in this iterator:
 
 We called `fold()` with these arguments:
 
-```{rust}
+```rust
 # (1..4)
 .fold(0, |sum, x| sum + x);
 ```
@@ -218,25 +216,25 @@ are *lazy* and don't need to generate all of the values upfront.
 This code, for example, does not actually generate the numbers
 `1-100`, and just creates a value that represents the sequence:
 
-```{rust}
+```rust
 let nums = 1..100;
 ```
 
 Since we didn't do anything with the range, it didn't generate the sequence.
 Let's add the consumer:
 
-```{rust}
+```rust
 let nums = (1..100).collect::<Vec<i32>>();
 ```
 
 Now, `collect()` will require that the range gives it some numbers, and so
 it will do the work of generating the sequence.
 
-A range is one of two basic iterators that you'll see. The other is `iter()`,
+Ranges are one of two basic iterators that you'll see. The other is `iter()`,
 which you've used before. `iter()` can turn a vector into a simple iterator
 that gives you each element in turn:
 
-```{rust}
+```rust
 let nums = [1, 2, 3];
 
 for num in nums.iter() {
@@ -247,7 +245,7 @@ for num in nums.iter() {
 These two basic iterators should serve you well. There are some more
 advanced iterators, including ones that are infinite. Like `count`:
 
-```{rust}
+```rust
 std::iter::count(1, 5);
 ```
 
@@ -265,7 +263,7 @@ we need to talk about with regards to iterators. Let's get to it!
 a new iterator. The simplest one is called `map`:
 
 ```{rust,ignore}
-(1..100i32).map(|x| x + 1);
+(1..100).map(|x| x + 1);
 ```
 
 `map` is called upon another iterator, and produces a new iterator where each
@@ -273,7 +271,7 @@ element reference has the closure it's been given as an argument called on it.
 So this would give us the numbers from `2-100`. Well, almost! If you
 compile the example, you'll get a warning:
 
-```{notrust,ignore}
+```text
 warning: unused result which must be used: iterator adaptors are lazy and
          do nothing unless consumed, #[warn(unused_must_use)] on by default
 (1..100).map(|x| x + 1);
@@ -295,7 +293,7 @@ iterator over the next `n` elements of the original iterator, note that this
 has no side effect on the original iterator. Let's try it out with our infinite
 iterator from before, `count()`:
 
-```{rust}
+```rust
 for i in std::iter::count(1, 5).take(5) {
     println!("{}", i);
 }
@@ -303,7 +301,7 @@ for i in std::iter::count(1, 5).take(5) {
 
 This will print
 
-```{notrust,ignore}
+```text
 1
 6
 11
@@ -315,8 +313,8 @@ This will print
 returns `true` or `false`. The new iterator `filter()` produces
 only the elements that that closure returns `true` for:
 
-```{rust}
-for i in (1..100i32).filter(|&x| x % 2 == 0) {
+```rust
+for i in (1..100).filter(|&x| x % 2 == 0) {
     println!("{}", i);
 }
 ```
@@ -330,8 +328,8 @@ itself.)
 You can chain all three things together: start with an iterator, adapt it
 a few times, and then consume the result. Check it out:
 
-```{rust}
-(1..1000i32)
+```rust
+(1..1000)
     .filter(|&x| x % 2 == 0)
     .filter(|&x| x % 3 == 0)
     .take(5)
index f429e9df1965718aa2ec36d706c590f48dfbba70..ce6fa3ce949cd7a1f0878ca79bf20358a5127ba1 100644 (file)
 % Macros
 
-# Introduction
-
-Functions are the primary tool that programmers can use to build abstractions.
-Sometimes, however, programmers want to abstract over compile-time syntax
-rather than run-time values.
-Macros provide syntactic abstraction.
-For an example of how this can be useful, consider the following two code fragments,
-which both pattern-match on their input and both return early in one case,
-doing nothing otherwise:
-
-~~~~
-# enum T { SpecialA(u32), SpecialB(u32) }
-# fn f() -> u32 {
-# let input_1 = T::SpecialA(0);
-# let input_2 = T::SpecialA(0);
-match input_1 {
-    T::SpecialA(x) => { return x; }
-    _ => {}
-}
-// ...
-match input_2 {
-    T::SpecialB(x) => { return x; }
-    _ => {}
-}
-# return 0;
-# }
-~~~~
-
-This code could become tiresome if repeated many times.
-However, no function can capture its functionality to make it possible
-to abstract the repetition away.
-Rust's macro system, however, can eliminate the repetition. Macros are
-lightweight custom syntax extensions, themselves defined using the
-`macro_rules!` syntax extension. The following `early_return` macro captures
-the pattern in the above code:
-
-~~~~
-# enum T { SpecialA(u32), SpecialB(u32) }
-# fn f() -> u32 {
-# let input_1 = T::SpecialA(0);
-# let input_2 = T::SpecialA(0);
-macro_rules! early_return {
-    ($inp:expr, $sp:path) => ( // invoke it like `(input_5, SpecialE)`
-        match $inp {
-            $sp(x) => { return x; }
-            _ => {}
-        }
-    );
-}
-// ...
-early_return!(input_1, T::SpecialA);
-// ...
-early_return!(input_2, T::SpecialB);
-# return 0;
-# }
-# fn main() {}
-~~~~
-
-Macros are defined in pattern-matching style: in the above example, the text
-`($inp:expr, $sp:path)` that appears on the left-hand side of the `=>` is the
-*macro invocation syntax*, a pattern denoting how to write a call to the
-macro. The text on the right-hand side of the `=>`, beginning with `match
-$inp`, is the *macro transcription syntax*: what the macro expands to.
-
-# Invocation syntax
-
-The macro invocation syntax specifies the syntax for the arguments to the
-macro. It appears on the left-hand side of the `=>` in a macro definition. It
-conforms to the following rules:
-
-1. It must be surrounded by parentheses.
-2. `$` has special meaning (described below).
-3. The `()`s, `[]`s, and `{}`s it contains must balance. For example, `([)` is
-forbidden.
-4. Some arguments can be followed only by a limited set of separators, to
-avoid ambiguity (described below).
-
-Otherwise, the invocation syntax is free-form.
-
-To take a fragment of Rust code as an argument, write `$` followed by a name
- (for use on the right-hand side), followed by a `:`, followed by a *fragment
- specifier*. The fragment specifier denotes the sort of fragment to match. The
- most common fragment specifiers are:
-
-* `ident` (an identifier, referring to a variable or item. Examples: `f`, `x`,
-  `foo`.)
-* `expr` (an expression. Examples: `2 + 2`; `if true then { 1 } else { 2 }`;
-  `f(42)`.)
-* `ty` (a type. Examples: `i32`, `Vec<(char, String)>`, `&T`.)
-* `path` (a path to struct or enum variant. Example: `T::SpecialA`)
-* `pat` (a pattern, usually appearing in a `match` or on the left-hand side of
-  a declaration. Examples: `Some(t)`; `(17, 'a')`; `_`.)
-* `block` (a sequence of actions. Example: `{ log(error, "hi"); return 12; }`)
-
-The parser interprets any token that's not preceded by a `$` literally. Rust's usual
-rules of tokenization apply,
-
-So `($x:ident -> (($e:expr)))`, though excessively fancy, would designate a macro
-that could be invoked like: `my_macro!(i->(( 2+2 )))`.
-
-To avoid ambiguity, macro invocation syntax must conform to the following rules:
-
-* `expr` must be followed by `=>`, `,` or `;`.
-* `ty` and `path` must be followed by `=>`, `,`, `:`, `=`, `>` or `as`.
-* `pat` must be followed by `=>`, `,` or `=`.
-* `ident` and `block` can be followed by any token.
-
-## Invocation location
-
-A macro invocation may take the place of (and therefore expand to) an
-expression, item, statement, or pattern.  The Rust parser will parse the macro
-invocation as a "placeholder" for whichever syntactic form is appropriate for
-the location.
-
-At expansion time, the output of the macro will be parsed as whichever of the
-three nonterminals it stands in for. This means that a single macro might,
-for example, expand to an item or an expression, depending on its arguments
-(and cause a syntax error if it is called with the wrong argument for its
-location). Although this behavior sounds excessively dynamic, it is known to
-be useful under some circumstances.
-
-
-# Transcription syntax
-
-The right-hand side of the `=>` follows the same rules as the left-hand side,
-except that a `$` need only be followed by the name of the syntactic fragment
-to transcribe into the macro expansion; its type need not be repeated.
-
-The right-hand side must be enclosed by delimiters, which the transcriber ignores.
-Therefore `() => ((1,2,3))` is a macro that expands to a tuple expression,
-`() => (let $x=$val)` is a macro that expands to a statement,
-and `() => (1,2,3)` is a macro that expands to a syntax error
-(since the transcriber interprets the parentheses on the right-hand-size as delimiters,
-and `1,2,3` is not a valid Rust expression on its own).
-
-Except for permissibility of `$name` (and `$(...)*`, discussed below), the
-right-hand side of a macro definition is ordinary Rust syntax. In particular,
-macro invocations (including invocations of the macro currently being defined)
-are permitted in expression, statement, and item locations. However, nothing
-else about the code is examined or executed by the macro system; execution
-still has to wait until run-time.
-
-## Interpolation location
-
-The interpolation `$argument_name` may appear in any location consistent with
-its fragment specifier (i.e., if it is specified as `ident`, it may be used
-anywhere an identifier is permitted).
-
-# Multiplicity
-
-## Invocation
-
-Going back to the motivating example, recall that `early_return` expanded into
-a `match` that would `return` if the `match`'s scrutinee matched the
-"special case" identifier provided as the second argument to `early_return`,
-and do nothing otherwise. Now suppose that we wanted to write a
-version of `early_return` that could handle a variable number of "special"
-cases.
-
-The syntax `$(...)*` on the left-hand side of the `=>` in a macro definition
-accepts zero or more occurrences of its contents. It works much
-like the `*` operator in regular expressions. It also supports a
-separator token (a comma-separated list could be written `$(...),*`), and `+`
-instead of `*` to mean "at least one".
-
-~~~~
-# enum T { SpecialA(u32), SpecialB(u32), SpecialC(u32), SpecialD(u32) }
-# fn f() -> u32 {
-# let input_1 = T::SpecialA(0);
-# let input_2 = T::SpecialA(0);
-macro_rules! early_return {
-    ($inp:expr, [ $($sp:path),+ ]) => (
-        match $inp {
+By now you've learned about many of the tools Rust provides for abstracting and
+reusing code. These units of code reuse have a rich semantic structure. For
+example, functions have a type signature, type parameters have trait bounds,
+and overloaded functions must belong to a particular trait.
+
+This structure means that Rust's core abstractions have powerful compile-time
+correctness checking. But this comes at the price of reduced flexibility. If
+you visually identify a pattern of repeated code, you may find it's difficult
+or cumbersome to express that pattern as a generic function, a trait, or
+anything else within Rust's semantics.
+
+Macros allow us to abstract at a *syntactic* level. A macro invocation is
+shorthand for an "expanded" syntactic form. This expansion happens early in
+compilation, before any static checking. As a result, macros can capture many
+patterns of code reuse that Rust's core abstractions cannot.
+
+The drawback is that macro-based code can be harder to understand, because
+fewer of the built-in rules apply. Like an ordinary function, a well-behaved
+macro can be used without understanding its implementation. However, it can be
+difficult to design a well-behaved macro!  Additionally, compiler errors in
+macro code are harder to interpret, because they describe problems in the
+expanded code, not the source-level form that developers use.
+
+These drawbacks make macros something of a "feature of last resort". That's not
+to say that macros are bad; they are part of Rust because sometimes they're
+needed for truly concise, well-abstracted code. Just keep this tradeoff in
+mind.
+
+# Defining a macro
+
+You may have seen the `vec!` macro, used to initialize a [vector][] with any
+number of elements.
+
+[vector]: arrays-vectors-and-slices.html
+
+```rust
+let x: Vec<u32> = vec![1, 2, 3];
+# assert_eq!(&[1,2,3], &x);
+```
+
+This can't be an ordinary function, because it takes any number of arguments.
+But we can imagine it as syntactic shorthand for
+
+```rust
+let x: Vec<u32> = {
+    let mut temp_vec = Vec::new();
+    temp_vec.push(1);
+    temp_vec.push(2);
+    temp_vec.push(3);
+    temp_vec
+};
+# assert_eq!(&[1,2,3], &x);
+```
+
+We can implement this shorthand, using a macro: [^actual]
+
+[^actual]: The actual definition of `vec!` in libcollections differs from the
+           one presented here, for reasons of efficiency and reusability. Some
+           of these are mentioned in the [advanced macros chapter][].
+
+```rust
+macro_rules! vec {
+    ( $( $x:expr ),* ) => {
+        {
+            let mut temp_vec = Vec::new();
             $(
-                $sp(x) => { return x; }
-            )+
-            _ => {}
+                temp_vec.push($x);
+            )*
+            temp_vec
         }
-    )
-}
-// ...
-early_return!(input_1, [T::SpecialA,T::SpecialC,T::SpecialD]);
-// ...
-early_return!(input_2, [T::SpecialB]);
-# return 0;
-# }
-# fn main() {}
-~~~~
-
-### Transcription
-
-As the above example demonstrates, `$(...)*` is also valid on the right-hand
-side of a macro definition. The behavior of `*` in transcription,
-especially in cases where multiple `*`s are nested, and multiple different
-names are involved, can seem somewhat magical and unintuitive at first. The
-system that interprets them is called "Macro By Example". The two rules to
-keep in mind are (1) the behavior of `$(...)*` is to walk through one "layer"
-of repetitions for all of the `$name`s it contains in lockstep, and (2) each
-`$name` must be under at least as many `$(...)*`s as it was matched against.
-If it is under more, it'll be repeated, as appropriate.
-
-## Parsing limitations
-
-
-For technical reasons, there are two limitations to the treatment of syntax
-fragments by the macro parser:
-
-1. The parser will always parse as much as possible of a Rust syntactic
-fragment. For example, if the comma were omitted from the syntax of
-`early_return!` above, `input_1 [` would've been interpreted as the beginning
-of an array index. In fact, invoking the macro would have been impossible.
-2. The parser must have eliminated all ambiguity by the time it reaches a
-`$name:fragment_specifier` declaration. This limitation can result in parse
-errors when declarations occur at the beginning of, or immediately after,
-a `$(...)*`. For example, the grammar `$($t:ty)* $e:expr` will always fail to
-parse because the parser would be forced to choose between parsing `t` and
-parsing `e`. Changing the invocation syntax to require a distinctive token in
-front can solve the problem. In the above example, `$(T $t:ty)* E $e:exp`
-solves the problem.
-
-# Macro argument pattern matching
-
-## Motivation
-
-Now consider code like the following:
-
-~~~~
-# enum T1 { Good1(T2, u32), Bad1}
-# struct T2 { body: T3 }
-# enum T3 { Good2(u32), Bad2}
-# fn f(x: T1) -> u32 {
-match x {
-    T1::Good1(g1, val) => {
-        match g1.body {
-            T3::Good2(result) => {
-                // complicated stuff goes here
-                return result + val;
-            },
-            _ => panic!("Didn't get good_2")
-        }
-    }
-    _ => return 0 // default value
+    };
 }
+# fn main() {
+#     assert_eq!(&[1,2,3], &vec![1,2,3]);
 # }
-# fn main() {}
-~~~~
-
-All the complicated stuff is deeply indented, and the error-handling code is
-separated from matches that fail. We'd like to write a macro that performs
-a match, but with a syntax that suits the problem better. The following macro
-can solve the problem:
-
-~~~~
-macro_rules! biased_match {
-    // special case: `let (x) = ...` is illegal, so use `let x = ...` instead
-    ( ($e:expr) -> ($p:pat) else $err:stmt ;
-      binds $bind_res:ident
-    ) => (
-        let $bind_res = match $e {
-            $p => ( $bind_res ),
-            _ => { $err }
-        };
-    );
-    // more than one name; use a tuple
-    ( ($e:expr) -> ($p:pat) else $err:stmt ;
-      binds $( $bind_res:ident ),*
-    ) => (
-        let ( $( $bind_res ),* ) = match $e {
-            $p => ( $( $bind_res ),* ),
-            _ => { $err }
-        };
-    )
-}
+```
 
-# enum T1 { Good1(T2, u32), Bad1}
-# struct T2 { body: T3 }
-# enum T3 { Good2(u32), Bad2}
-# fn f(x: T1) -> u32 {
-biased_match!((x)       -> (T1::Good1(g1, val)) else { return 0 };
-              binds g1, val );
-biased_match!((g1.body) -> (T3::Good2(result) )
-                  else { panic!("Didn't get good_2") };
-              binds result );
-// complicated stuff goes here
-return result + val;
-# }
-# fn main() {}
-~~~~
-
-This solves the indentation problem. But if we have a lot of chained matches
-like this, we might prefer to write a single macro invocation. The input
-pattern we want is clear:
-
-~~~~
-# fn main() {}
-# macro_rules! b {
-    ( $( ($e:expr) -> ($p:pat) else $err:stmt ; )*
-      binds $( $bind_res:ident ),*
-    )
-# => (0) }
-~~~~
-
-However, it's not possible to directly expand to nested match statements. But
-there is a solution.
-
-## The recursive approach to macro writing
-
-A macro may accept multiple different input grammars. The first one to
-successfully match the actual argument to a macro invocation is the one that
-"wins".
-
-In the case of the example above, we want to write a recursive macro to
-process the semicolon-terminated lines, one-by-one. So, we want the following
-input patterns:
-
-~~~~
-# macro_rules! b {
-    ( binds $( $bind_res:ident ),* )
-# => (0) }
-# fn main() {}
-~~~~
-
-...and:
-
-~~~~
-# fn main() {}
-# macro_rules! b {
-    (    ($e     :expr) -> ($p     :pat) else $err     :stmt ;
-      $( ($e_rest:expr) -> ($p_rest:pat) else $err_rest:stmt ; )*
-      binds  $( $bind_res:ident ),*
-    )
-# => (0) }
-~~~~
-
-The resulting macro looks like this. Note that the separation into
-`biased_match!` and `biased_match_rec!` occurs only because we have an outer
-piece of syntax (the `let`) which we only want to transcribe once.
-
-~~~~
-# fn main() {
+Whoa, that's a lot of new syntax! Let's break it down.
 
-macro_rules! biased_match_rec {
-    // Handle the first layer
-    (   ($e     :expr) -> ($p     :pat) else $err     :stmt ;
-     $( ($e_rest:expr) -> ($p_rest:pat) else $err_rest:stmt ; )*
-     binds $( $bind_res:ident ),*
-    ) => (
-        match $e {
-            $p => {
-                // Recursively handle the next layer
-                biased_match_rec!($( ($e_rest) -> ($p_rest) else $err_rest ; )*
-                                  binds $( $bind_res ),*
-                )
-            }
-            _ => { $err }
-        }
-    );
-    // Produce the requested values
-    ( binds $( $bind_res:ident ),* ) => ( ($( $bind_res ),*) )
-}
+```ignore
+macro_rules! vec { ... }
+```
 
-// Wrap the whole thing in a `let`.
-macro_rules! biased_match {
-    // special case: `let (x) = ...` is illegal, so use `let x = ...` instead
-    ( $( ($e:expr) -> ($p:pat) else $err:stmt ; )*
-      binds $bind_res:ident
-    ) => (
-        let $bind_res = biased_match_rec!(
-            $( ($e) -> ($p) else $err ; )*
-            binds $bind_res
-        );
-    );
-    // more than one name: use a tuple
-    ( $( ($e:expr) -> ($p:pat) else $err:stmt ; )*
-      binds  $( $bind_res:ident ),*
-    ) => (
-        let ( $( $bind_res ),* ) = biased_match_rec!(
-            $( ($e) -> ($p) else $err ; )*
-            binds $( $bind_res ),*
-        );
-    )
-}
+This says we're defining a macro named `vec`, much as `fn vec` would define a
+function named `vec`. In prose, we informally write a macro's name with an
+exclamation point, e.g. `vec!`. The exclamation point is part of the invocation
+syntax and serves to distinguish a macro from an ordinary function.
 
+## Matching
 
-# enum T1 { Good1(T2, u32), Bad1}
-# struct T2 { body: T3 }
-# enum T3 { Good2(u32), Bad2}
-# fn f(x: T1) -> u32 {
-biased_match!(
-    (x)       -> (T1::Good1(g1, val)) else { return 0 };
-    (g1.body) -> (T3::Good2(result) ) else { panic!("Didn't get Good2") };
-    binds val, result );
-// complicated stuff goes here
-return result + val;
-# }
-# }
-~~~~
-
-This technique applies to many cases where transcribing a result all at once is not possible.
-The resulting code resembles ordinary functional programming in some respects,
-but has some important differences from functional programming.
-
-The first difference is important, but also easy to forget: the transcription
-(right-hand) side of a `macro_rules!` rule is literal syntax, which can only
-be executed at run-time. If a piece of transcription syntax does not itself
-appear inside another macro invocation, it will become part of the final
-program. If it is inside a macro invocation (for example, the recursive
-invocation of `biased_match_rec!`), it does have the opportunity to affect
-transcription, but only through the process of attempted pattern matching.
-
-The second, related, difference is that the evaluation order of macros feels
-"backwards" compared to ordinary programming. Given an invocation
-`m1!(m2!())`, the expander first expands `m1!`, giving it as input the literal
-syntax `m2!()`. If it transcribes its argument unchanged into an appropriate
-position (in particular, not as an argument to yet another macro invocation),
-the expander will then proceed to evaluate `m2!()` (along with any other macro
-invocations `m1!(m2!())` produced).
+The macro is defined through a series of *rules*, which are pattern-matching
+cases. Above, we had
 
-# Hygiene
+```ignore
+( $( $x:expr ),* ) => { ... };
+```
 
-To prevent clashes, rust implements
-[hygienic macros](http://en.wikipedia.org/wiki/Hygienic_macro).
+This is like a `match` expression arm, but the matching happens on Rust syntax
+trees, at compile time. The semicolon is optional on the last (here, only)
+case. The "pattern" on the left-hand side of `=>` is known as a *matcher*.
+These have [their own little grammar] within the language.
 
-As an example, `loop` and `for-loop` labels (discussed in the lifetimes guide)
-will not clash. The following code will print "Hello!" only once:
+[their own little grammar]: ../reference.html#macros
 
-~~~
-macro_rules! loop_x {
-    ($e: expr) => (
-        // $e will not interact with this 'x
-        'x: loop {
-            println!("Hello!");
-            $e
-        }
-    );
+The matcher `$x:expr` will match any Rust expression, binding that syntax tree
+to the *metavariable* `$x`. The identifier `expr` is a *fragment specifier*;
+the full possibilities are enumerated in the [advanced macros chapter][].
+Surrounding the matcher with `$(...),*` will match zero or more expressions,
+separated by commas.
+
+Aside from the special matcher syntax, any Rust tokens that appear in a matcher
+must match exactly. For example,
+
+```rust
+macro_rules! foo {
+    (x => $e:expr) => (println!("mode X: {}", $e));
+    (y => $e:expr) => (println!("mode Y: {}", $e));
 }
 
 fn main() {
-    'x: loop {
-        loop_x!(break 'x);
-        println!("I am never printed.");
-    }
+    foo!(y => 3);
 }
-~~~
+```
 
-The two `'x` names did not clash, which would have caused the loop
-to print "I am never printed" and to run forever.
+will print
 
-# Scoping and macro import/export
+```text
+mode Y: 3
+```
+
+With
 
-Macros are expanded at an early stage in compilation, before name resolution.
-One downside is that scoping works differently for macros, compared to other
-constructs in the language.
+```rust,ignore
+foo!(z => 3);
+```
 
-Definition and expansion of macros both happen in a single depth-first,
-lexical-order traversal of a crate's source. So a macro defined at module scope
-is visible to any subsequent code in the same module, which includes the body
-of any subsequent child `mod` items.
+we get the compiler error
 
-A macro defined within the body of a single `fn`, or anywhere else not at
-module scope, is visible only within that item.
+```text
+error: no rules expected the token `z`
+```
 
-If a module has the `macro_use` attribute, its macros are also visible in its
-parent module after the child's `mod` item. If the parent also has `macro_use`
-then the macros will be visible in the grandparent after the parent's `mod`
-item, and so forth.
+## Expansion
 
-The `macro_use` attribute can also appear on `extern crate`.  In this context
-it controls which macros are loaded from the external crate, e.g.
+The right-hand side of a macro rule is ordinary Rust syntax, for the most part.
+But we can splice in bits of syntax captured by the matcher. From the original
+example:
 
-```rust,ignore
-#[macro_use(foo, bar)]
-extern crate baz;
+```ignore
+$(
+    temp_vec.push($x);
+)*
 ```
 
-If the attribute is given simply as `#[macro_use]`, all macros are loaded.  If
-there is no `#[macro_use]` attribute then no macros are loaded.  Only macros
-defined with the `#[macro_export]` attribute may be loaded.
+Each matched expression `$x` will produce a single `push` statement in the
+macro expansion. The repetition in the expansion proceeds in "lockstep" with
+repetition in the matcher (more on this in a moment).
 
-To load a crate's macros *without* linking it into the output, use `#[no_link]`
-as well.
+Because `$x` was already declared as matching an expression, we don't repeat
+`:expr` on the right-hand side. Also, we don't include a separating comma as
+part of the repetition operator. Instead, we have a terminating semicolon
+within the repeated block.
 
-An example:
+Another detail: the `vec!` macro has *two* pairs of braces on the right-hand
+side. They are often combined like so:
 
-```rust
-macro_rules! m1 { () => (()) }
+```ignore
+macro_rules! foo {
+    () => {{
+        ...
+    }}
+}
+```
+
+The outer braces are part of the syntax of `macro_rules!`. In fact, you can use
+`()` or `[]` instead. They simply delimit the right-hand side as a whole.
+
+The inner braces are part of the expanded syntax. Remember, the `vec!` macro is
+used in an expression context. To write an expression with multiple statements,
+including `let`-bindings, we use a block. If your macro expands to a single
+expression, you don't need this extra layer of braces.
+
+Note that we never *declared* that the macro produces an expression. In fact,
+this is not determined until we use the macro as an expression. With care, you
+can write a macro whose expansion works in several contexts. For example,
+shorthand for a data type could be valid as either an expression or a pattern.
+
+## Repetition
 
-// visible here: m1
+The repetition behavior can seem somewhat magical, especially when multiple
+names are bound at multiple nested levels of repetition. The two rules to keep
+in mind are:
 
-mod foo {
-    // visible here: m1
+1. the behavior of `$(...)*` is to walk through one "layer" of repetitions, for
+all of the `$name`s it contains, in lockstep, and
+2. each `$name` must be under at least as many `$(...)*`s as it was matched
+against. If it is under more, it'll be duplicated, as appropriate.
 
-    #[macro_export]
-    macro_rules! m2 { () => (()) }
+This baroque macro illustrates the duplication of variables from outer
+repetition levels.
+
+```rust
+macro_rules! o_O {
+    (
+        $(
+            $x:expr; [ $( $y:expr ),* ]
+        );*
+    ) => {
+        &[ $($( $x + $y ),*),* ]
+    }
+}
+
+fn main() {
+    let a: &[i32]
+        = o_O!(10; [1, 2, 3];
+               20; [4, 5, 6]);
 
-    // visible here: m1, m2
+    assert_eq!(a, [11, 12, 13, 24, 25, 26]);
 }
+```
 
-// visible here: m1
+That's most of the matcher syntax. These examples use `$(...)*`, which is a
+"zero or more" match. Alternatively you can write `$(...)+` for a "one or
+more" match. Both forms optionally include a separator, which can be any token
+except `+` or `*`.
 
-macro_rules! m3 { () => (()) }
+# Hygiene
 
-// visible here: m1, m3
+Some languages implement macros using simple text substitution, which leads to
+various problems. For example, this C program prints `13` instead of the
+expected `25`.
 
-#[macro_use]
-mod bar {
-    // visible here: m1, m3
+```text
+#define FIVE_TIMES(x) 5 * x
 
-    macro_rules! m4 { () => (()) }
+int main() {
+    printf("%d\n", FIVE_TIMES(2 + 3));
+    return 0;
+}
+```
 
-    // visible here: m1, m3, m4
+After expansion we have `5 * 2 + 3`, and multiplication has greater precedence
+than addition. If you've used C macros a lot, you probably know the standard
+idioms for avoiding this problem, as well as five or six others. In Rust, we
+don't have to worry about it.
+
+```rust
+macro_rules! five_times {
+    ($x:expr) => (5 * $x);
 }
 
-// visible here: m1, m3, m4
-# fn main() { }
+fn main() {
+    assert_eq!(25, five_times!(2 + 3));
+}
+```
+
+The metavariable `$x` is parsed as a single expression node, and keeps its
+place in the syntax tree even after substitution.
+
+Another common problem in macro systems is *variable capture*. Here's a C
+macro, using [a GNU C extension] to emulate Rust's expression blocks.
+
+[a GNU C extension]: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
+
+```text
+#define LOG(msg) ({ \
+    int state = get_log_state(); \
+    if (state > 0) { \
+        printf("log(%d): %s\n", state, msg); \
+    } \
+})
 ```
 
-When this library is loaded with `#[use_macros] extern crate`, only `m2` will
-be imported.
+This looks reasonable, but watch what happens in this example:
 
-The Rust Reference has a [listing of macro-related
-attributes](../reference.html#macro--and-plugin-related-attributes).
+```text
+const char *state = "reticulating splines";
+LOG(state);
+```
+
+The program will likely segfault, after it tries to execute
 
-# The variable `$crate`
+```text
+printf("log(%d): %s\n", state, state);
+```
 
-A further difficulty occurs when a macro is used in multiple crates.  Say that
-`mylib` defines
+The equivalent Rust macro has the desired behavior.
 
 ```rust
-pub fn increment(x: u32) -> u32 {
-    x + 1
+# fn get_log_state() -> i32 { 3 }
+macro_rules! log {
+    ($msg:expr) => {{
+        let state: i32 = get_log_state();
+        if state > 0 {
+            println!("log({}): {}", state, $msg);
+        }
+    }};
 }
 
-#[macro_export]
-macro_rules! inc_a {
-    ($x:expr) => ( ::increment($x) )
+fn main() {
+    let state: &str = "reticulating splines";
+    log!(state);
 }
+```
+
+This works because Rust has a [hygienic macro system][]. Each macro expansion
+happens in a distinct *syntax context*, and each variable is tagged with the
+syntax context where it was introduced. It's as though the variable `state`
+inside `main` is painted a different "color" from the variable `state` inside
+the macro, and therefore they don't conflict.
 
-#[macro_export]
-macro_rules! inc_b {
-    ($x:expr) => ( ::mylib::increment($x) )
+[hygienic macro system]: http://en.wikipedia.org/wiki/Hygienic_macro
+
+This also restricts the ability of macros to introduce new bindings at the
+invocation site. Code such as the following will not work:
+
+```rust,ignore
+macro_rules! foo {
+    () => (let x = 3);
+}
+
+fn main() {
+    foo!();
+    println!("{}", x);
 }
-# fn main() { }
 ```
 
-`inc_a` only works within `mylib`, while `inc_b` only works outside the
-library.  Furthermore, `inc_b` will break if the user imports `mylib` under
-another name.
+Instead you need to pass the variable name into the invocation, so it's tagged
+with the right syntax context.
 
-Rust does not (yet) have a hygiene system for crate references, but it does
-provide a simple workaround for this problem.  Within a macro imported from a
-crate named `foo`, the special macro variable `$crate` will expand to `::foo`.
-By contrast, when a macro is defined and then used in the same crate, `$crate`
-will expand to nothing.  This means we can write
+```rust
+macro_rules! foo {
+    ($v:ident) => (let $v = 3);
+}
+
+fn main() {
+    foo!(x);
+    println!("{}", x);
+}
+```
+
+This holds for `let` bindings and loop labels, but not for [items][].
+So the following code does compile:
 
 ```rust
-#[macro_export]
-macro_rules! inc {
-    ($x:expr) => ( $crate::increment($x) )
+macro_rules! foo {
+    () => (fn x() { });
+}
+
+fn main() {
+    foo!();
+    x();
 }
-# fn main() { }
 ```
 
-to define a single macro that works both inside and outside our library.  The
-function name will expand to either `::increment` or `::mylib::increment`.
-
-To keep this system simple and correct, `#[macro_use] extern crate ...` may
-only appear at the root of your crate, not inside `mod`.  This ensures that
-`$crate` is a single identifier.
-
-# A final note
-
-Macros, as currently implemented, are not for the faint of heart. Even
-ordinary syntax errors can be more difficult to debug when they occur inside a
-macro, and errors caused by parse problems in generated code can be very
-tricky. Invoking the `log_syntax!` macro can help elucidate intermediate
-states, invoking `trace_macros!(true)` will automatically print those
-intermediate states out, and passing the flag `--pretty expanded` as a
-command-line argument to the compiler will show the result of expansion.
-
-If Rust's macro system can't do what you need, you may want to write a
-[compiler plugin](plugins.html) instead. Compared to `macro_rules!`
-macros, this is significantly more work, the interfaces are much less stable,
-and the warnings about debugging apply ten-fold. In exchange you get the
-flexibility of running arbitrary Rust code within the compiler. Syntax
-extension plugins are sometimes called *procedural macros* for this reason.
+[items]: ../reference.html#items
+
+# Further reading
+
+The [advanced macros chapter][] goes into more detail about macro syntax. It
+also describes how to share macros between different modules or crates.
+
+[advanced macros chapter]: advanced-macros.html
index e6570c2ee74c8d649faaf8afec41cf76358d30ba..64d540582a3998bd7acd97c745379be9d2ba21ba 100644 (file)
@@ -99,8 +99,8 @@ fn grow(&self) -> Circle {
 # Circle } }
 ```
 
-We just say we're returning a `Circle`. With this, we can grow a new circle
-that's twice as big as the old one.
+We just say we're returning a `Circle`. With this method, we can grow a new
+circle with an area that's 100 times larger than the old one.
 
 ## Static methods
 
index a2b70e96e1e8dfff209ad7caf861b3c3d97240c9..6aced23ede08effc8c9f3f01b5c110cb5e6a421a 100644 (file)
@@ -293,7 +293,7 @@ struct Foo<'a> {
 }
 
 fn main() {
-    let y = &5; // this is the same as `let _y = 5; let y = &_y;
+    let y = &5; // this is the same as `let _y = 5; let y = &_y;`
     let f = Foo { x: y };
 
     println!("{}", f.x);
index e091878cf86ec200df19b5b1878adebf7969ef64..abd9af1af33a097e805f0b64cba83d0ccbbc6cdf 100644 (file)
@@ -273,6 +273,96 @@ One last thing about traits: generic functions with a trait bound use
 dispatched. What's that mean? Check out the chapter on [static and dynamic
 dispatch](static-and-dynamic-dispatch.html) for more.
 
+## Where clause
+
+Writing functions with only a few generic types and a small number of trait
+bounds isn't too bad, but as the number increases, the syntax gets increasingly
+awkward:
+
+```
+use std::fmt::Debug;
+
+fn foo<T: Clone, K: Clone + Debug>(x: T, y: K) {
+    x.clone();
+    y.clone();
+    println!("{:?}", y);
+}
+```
+
+The name of the function is on the far left, and the parameter list is on the
+far right. The bounds are getting in the way.
+
+Rust has a solution, and it's called a '`where` clause':
+
+```
+use std::fmt::Debug;
+
+fn foo<T: Clone, K: Clone + Debug>(x: T, y: K) {
+    x.clone();
+    y.clone();
+    println!("{:?}", y);
+}
+
+fn bar<T, K>(x: T, y: K) where T: Clone, K: Clone + Debug {
+    x.clone();
+    y.clone();
+    println!("{:?}", y);
+}
+
+fn main() {
+    foo("Hello", "world");
+    bar("Hello", "workd");
+}
+```
+
+`foo()` uses the syntax we showed earlier, and `bar()` uses a `where` clause.
+All you need to do is leave off the bounds when defining your type parameters,
+and then add `where` after the parameter list. For longer lists, whitespace can
+be added:
+
+```
+use std::fmt::Debug;
+
+fn bar<T, K>(x: T, y: K)
+    where T: Clone,
+          K: Clone + Debug {
+
+    x.clone();
+    y.clone();
+    println!("{:?}", y);
+}
+```
+
+This flexibility can add clarity in complex situations.
+
+`where` is also more powerful than the simpler syntax. For example:
+
+```
+trait ConvertTo<Output> {
+    fn convert(&self) -> Output;
+}
+
+impl ConvertTo<i64> for i32 {
+    fn convert(&self) -> i64 { *self as i64 }
+}
+
+// can be called with T == i32
+fn normal<T: ConvertTo<i64>>(x: &T) -> i64 {
+    x.convert()
+}
+
+// can be called with T == i64
+fn inverse<T>() -> T
+        // this is using ConvertTo as if it were "ConvertFrom<i32>"
+        where i32: ConvertTo<T> {
+    1i32.convert()
+}
+```
+
+This shows off the additional feature of `where` clauses: they allow bounds
+where the left-hand side is an arbitrary type (`i32` in this case), not just a
+plain type parameter (like `T`).
+
 ## Our `inverse` Example
 
 Back in [Generics](generics.html), we were trying to write code like this:
index b364d00f95c20b493640f3bd2e6d8f2cba024c44..4e14085599b603d3b640d672748c8f41eebce10f 100644 (file)
@@ -308,7 +308,7 @@ crate to allow) and of course requires an `unsafe` block.
 ## Assembly template
 
 The `assembly template` is the only required parameter and must be a
-literal string (i.e `""`)
+literal string (i.e. `""`)
 
 ```
 #![feature(asm)]
@@ -412,7 +412,7 @@ memory, `memory` should also be specified.
 ## Options
 
 The last section, `options` is specific to Rust. The format is comma
-separated literal strings (i.e `:"foo", "bar", "baz"`). It's used to
+separated literal strings (i.e. `:"foo", "bar", "baz"`). It's used to
 specify some extra info about the inline assembly:
 
 Current valid options are:
@@ -420,7 +420,7 @@ Current valid options are:
 1. *volatile* - specifying this is analogous to
    `__asm__ __volatile__ (...)` in gcc/clang.
 2. *alignstack* - certain instructions expect the stack to be
-   aligned a certain way (i.e SSE) and specifying this indicates to
+   aligned a certain way (i.e. SSE) and specifying this indicates to
    the compiler to insert its usual stack alignment code
 3. *intel* - use intel syntax instead of the default AT&T.
 
@@ -646,8 +646,8 @@ The `rustc` compiler has certain pluggable operations, that is,
 functionality that isn't hard-coded into the language, but is
 implemented in libraries, with a special marker to tell the compiler
 it exists. The marker is the attribute `#[lang="..."]` and there are
-various different values of `...`, i.e. various different "lang
-items".
+various different values of `...`, i.e. various different 'lang
+items'.
 
 For example, `Box` pointers require two lang items, one for allocation
 and one for deallocation. A freestanding program that uses the `Box`
index 6b5220597e9d7ca4fb55129b77fe10fb894cdde6..bd6c483156f8125df69f0f2753b0dbf5eed15487 100755 (executable)
@@ -24,8 +24,9 @@ then
     then
         shift
 
+        # The length of binary path (i.e. ./$RUN) should be shorter than 128 characters.
         cd $TEST_PATH
-        TEST_EXEC_ENV=22 LD_LIBRARY_PATH=$TEST_PATH PATH=$BIN_PATH:$TEST_PATH $TEST_PATH/$RUN $@ 1>$TEST_PATH/$RUN.stdout 2>$TEST_PATH/$RUN.stderr
+        TEST_EXEC_ENV=22 LD_LIBRARY_PATH=$TEST_PATH PATH=$BIN_PATH:$TEST_PATH ./$RUN $@ 1>$TEST_PATH/$RUN.stdout 2>$TEST_PATH/$RUN.stderr
         L_RET=$?
 
         echo $L_RET > $TEST_PATH/$RUN.exitcode
index 0617c604121f49bcc9cb2569185ca2dbb704b805..3830d7fe29532c228a9521286bfa250ae040b06b 100644 (file)
 //!
 //! ```
 //! use std::sync::Arc;
-//! use std::thread::Thread;
+//! use std::thread;
 //!
 //! let five = Arc::new(5);
 //!
 //! for _ in 0..10 {
 //!     let five = five.clone();
 //!
-//!     Thread::spawn(move || {
+//!     thread::spawn(move || {
 //!         println!("{:?}", five);
 //!     });
 //! }
 //!
 //! ```
 //! use std::sync::{Arc, Mutex};
-//! use std::thread::Thread;
+//! use std::thread;
 //!
 //! let five = Arc::new(Mutex::new(5));
 //!
 //! for _ in 0..10 {
 //!     let five = five.clone();
 //!
-//!     Thread::spawn(move || {
+//!     thread::spawn(move || {
 //!         let mut number = five.lock().unwrap();
 //!
 //!         *number += 1;
@@ -95,7 +95,7 @@
 ///
 /// ```rust
 /// use std::sync::Arc;
-/// use std::thread::Thread;
+/// use std::thread;
 ///
 /// fn main() {
 ///     let numbers: Vec<_> = (0..100u32).map(|i| i as f32).collect();
 ///     for _ in 0..10 {
 ///         let child_numbers = shared_numbers.clone();
 ///
-///         Thread::spawn(move || {
+///         thread::spawn(move || {
 ///             let local_numbers = child_numbers.as_slice();
 ///
 ///             // Work with the local numbers
@@ -621,7 +621,7 @@ mod tests {
     use std::option::Option::{Some, None};
     use std::sync::atomic;
     use std::sync::atomic::Ordering::{Acquire, SeqCst};
-    use std::thread::Thread;
+    use std::thread;
     use std::vec::Vec;
     use super::{Arc, Weak, weak_count, strong_count};
     use std::sync::Mutex;
@@ -648,7 +648,7 @@ fn manually_share_arc() {
 
         let (tx, rx) = channel();
 
-        let _t = Thread::spawn(move || {
+        let _t = thread::spawn(move || {
             let arc_v: Arc<Vec<i32>> = rx.recv().unwrap();
             assert_eq!((*arc_v)[3], 4);
         });
index 87106041c69d7f213e903aab58a791ca3a780bf1..b3c2638f3ae282a190c5318fe147c1873f7ea844 100644 (file)
@@ -126,11 +126,3 @@ pub fn oom() -> ! {
 //                optimize it out).
 #[doc(hidden)]
 pub fn fixme_14344_be_sure_to_link_to_collections() {}
-
-// NOTE: remove after next snapshot
-#[cfg(all(stage0, not(test)))]
-#[doc(hidden)]
-mod std {
-    pub use core::fmt;
-    pub use core::option;
-}
index ab3c0901bc9563276b8a13660286db43fbf1900b..f361c36ec8fa73bafb333c6a1a5284d851164ea9 100644 (file)
@@ -170,7 +170,7 @@ struct RcBox<T> {
     weak: Cell<usize>
 }
 
-/// An immutable reference-counted pointer type.
+/// A reference-counted pointer type over an immutable value.
 ///
 /// See the [module level documentation](./index.html) for more details.
 #[unsafe_no_drop_flag]
@@ -776,9 +776,7 @@ fn inner(&self) -> &RcBox<T> {
             // the contract anyway.
             // This allows the null check to be elided in the destructor if we
             // manipulated the reference count in the same function.
-            if cfg!(not(stage0)) { // NOTE remove cfg after next snapshot
-                assume(!self._ptr.is_null());
-            }
+            assume(!self._ptr.is_null());
             &(**self._ptr)
         }
     }
@@ -792,9 +790,7 @@ fn inner(&self) -> &RcBox<T> {
             // the contract anyway.
             // This allows the null check to be elided in the destructor if we
             // manipulated the reference count in the same function.
-            if cfg!(not(stage0)) { // NOTE remove cfg after next snapshot
-                assume(!self._ptr.is_null());
-            }
+            assume(!self._ptr.is_null());
             &(**self._ptr)
         }
     }
index 1d994839d99410677ea349342c3d6b1b7a5d9675..6196d94b5a6bd9be2d9892530686dc557b779069 100644 (file)
@@ -655,17 +655,7 @@ fn from_iter<Iter: Iterator<Item=T>>(iter: Iter) -> BinaryHeap<T> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<T: Ord> IntoIterator for BinaryHeap<T> {
-    type IntoIter = IntoIter<T>;
-
-    fn into_iter(self) -> IntoIter<T> {
-        self.into_iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Ord> IntoIterator for BinaryHeap<T> {
     type Item = T;
     type IntoIter = IntoIter<T>;
@@ -675,17 +665,7 @@ fn into_iter(self) -> IntoIter<T> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a, T> IntoIterator for &'a BinaryHeap<T> where T: Ord {
-    type IntoIter = Iter<'a, T>;
-
-    fn into_iter(self) -> Iter<'a, T> {
-        self.iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> IntoIterator for &'a BinaryHeap<T> where T: Ord {
     type Item = &'a T;
     type IntoIter = Iter<'a, T>;
index ca598a8d4d29255145f51abefe7056be6fb50109..1e49679d116e641222cb91984cddc69797de3b8b 100644 (file)
@@ -1070,17 +1070,7 @@ fn idx(&mut self, index: usize) -> Option<bool> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a> IntoIterator for &'a Bitv {
-    type IntoIter = Iter<'a>;
-
-    fn into_iter(self) -> Iter<'a> {
-        self.iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> IntoIterator for &'a Bitv {
     type Item = bool;
     type IntoIter = Iter<'a>;
@@ -1894,17 +1884,7 @@ impl<'a> Iterator for SymmetricDifference<'a> {
     #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a> IntoIterator for &'a BitvSet {
-    type IntoIter = SetIter<'a>;
-
-    fn into_iter(self) -> SetIter<'a> {
-        self.iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> IntoIterator for &'a BitvSet {
     type Item = usize;
     type IntoIter = SetIter<'a>;
@@ -2306,7 +2286,7 @@ fn test_to_bytes() {
     #[test]
     fn test_from_bools() {
         let bools = vec![true, false, true, true];
-        let bitv: Bitv = bools.iter().map(|n| *n).collect();
+        let bitv: Bitv = bools.iter().cloned().collect();
         assert_eq!(format!("{:?}", bitv), "1011");
     }
 
@@ -2319,12 +2299,12 @@ fn test_to_bools() {
     #[test]
     fn test_bitv_iterator() {
         let bools = vec![true, false, true, true];
-        let bitv: Bitv = bools.iter().map(|n| *n).collect();
+        let bitv: Bitv = bools.iter().cloned().collect();
 
         assert_eq!(bitv.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();
+        let bitv: Bitv = long.iter().cloned().collect();
         assert_eq!(bitv.iter().collect::<Vec<bool>>(), long)
     }
 
index 84f9825e989b365af71a4cae1a2d1a6dad90ee10..747211e923859df6d1fbab7b13bfb3716f56afa9 100644 (file)
@@ -462,17 +462,7 @@ pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V> where Q: BorrowFrom<K>
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<K, V> IntoIterator for BTreeMap<K, V> {
-    type IntoIter = IntoIter<K, V>;
-
-    fn into_iter(self) -> IntoIter<K, V> {
-        self.into_iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<K, V> IntoIterator for BTreeMap<K, V> {
     type Item = (K, V);
     type IntoIter = IntoIter<K, V>;
@@ -482,17 +472,7 @@ fn into_iter(self) -> IntoIter<K, V> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a, K, V> IntoIterator for &'a BTreeMap<K, V> {
-    type IntoIter = Iter<'a, K, V>;
-
-    fn into_iter(self) -> Iter<'a, K, V> {
-        self.iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, K, V> IntoIterator for &'a BTreeMap<K, V> {
     type Item = (&'a K, &'a V);
     type IntoIter = Iter<'a, K, V>;
@@ -502,17 +482,7 @@ fn into_iter(self) -> Iter<'a, K, V> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a, K, V> IntoIterator for &'a mut BTreeMap<K, V> {
-    type IntoIter = IterMut<'a, K, V>;
-
-    fn into_iter(mut self) -> IterMut<'a, K, V> {
-        self.iter_mut()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, K, V> IntoIterator for &'a mut BTreeMap<K, V> {
     type Item = (&'a K, &'a mut V);
     type IntoIter = IterMut<'a, K, V>;
index aecf59403119244a66e29c44ae1e3120eb523ca8..7ef887b70cc6ca4ec0736f56de47ba4330de0922 100644 (file)
@@ -480,17 +480,7 @@ fn from_iter<Iter: Iterator<Item=T>>(iter: Iter) -> BTreeSet<T> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<T> IntoIterator for BTreeSet<T> {
-    type IntoIter = IntoIter<T>;
-
-    fn into_iter(self) -> IntoIter<T> {
-        self.into_iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T> IntoIterator for BTreeSet<T> {
     type Item = T;
     type IntoIter = IntoIter<T>;
@@ -500,17 +490,7 @@ fn into_iter(self) -> IntoIter<T> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a, T> IntoIterator for &'a BTreeSet<T> {
-    type IntoIter = Iter<'a, T>;
-
-    fn into_iter(self) -> Iter<'a, T> {
-        self.iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> IntoIterator for &'a BTreeSet<T> {
     type Item = &'a T;
     type IntoIter = Iter<'a, T>;
index 27b282ee9a9c1a04ee344d21ef2450180623d7b2..9b05975470e86185dc621e72f5eebc917599b78e 100644 (file)
@@ -837,17 +837,7 @@ fn from_iter<T: Iterator<Item=A>>(iterator: T) -> DList<A> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<T> IntoIterator for DList<T> {
-    type IntoIter = IntoIter<T>;
-
-    fn into_iter(self) -> IntoIter<T> {
-        self.into_iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T> IntoIterator for DList<T> {
     type Item = T;
     type IntoIter = IntoIter<T>;
@@ -857,17 +847,7 @@ fn into_iter(self) -> IntoIter<T> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a, T> IntoIterator for &'a DList<T> {
-    type IntoIter = Iter<'a, T>;
-
-    fn into_iter(self) -> Iter<'a, T> {
-        self.iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> IntoIterator for &'a DList<T> {
     type Item = &'a T;
     type IntoIter = Iter<'a, T>;
@@ -877,17 +857,6 @@ fn into_iter(self) -> Iter<'a, T> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a, T> IntoIterator for &'a mut DList<T> {
-    type IntoIter = IterMut<'a, T>;
-
-    fn into_iter(mut self) -> IterMut<'a, T> {
-        self.iter_mut()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
 impl<'a, T> IntoIterator for &'a mut DList<T> {
     type Item = &'a mut T;
     type IntoIter = IterMut<'a, T>;
@@ -938,7 +907,7 @@ fn cmp(&self, other: &DList<A>) -> Ordering {
 #[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()
+        self.iter().cloned().collect()
     }
 }
 
@@ -971,7 +940,7 @@ mod tests {
     use prelude::*;
     use std::rand;
     use std::hash::{self, SipHasher};
-    use std::thread::Thread;
+    use std::thread;
     use test::Bencher;
     use test;
 
@@ -1056,7 +1025,7 @@ fn generate_test() -> DList<i32> {
 
     #[cfg(test)]
     fn list_from<T: Clone>(v: &[T]) -> DList<T> {
-        v.iter().map(|x| (*x).clone()).collect()
+        v.iter().cloned().collect()
     }
 
     #[test]
@@ -1320,7 +1289,7 @@ fn test_mut_rev_iter() {
     #[test]
     fn test_send() {
         let n = list_from(&[1,2,3]);
-        Thread::scoped(move || {
+        thread::spawn(move || {
             check_links(&n);
             let a: &[_] = &[&1,&2,&3];
             assert_eq!(a, n.iter().collect::<Vec<_>>());
index 5c37be188fea4c972859790ba405362e53663a98..d5403ca5d9b195b0e867ad76c2dd945c850b3415 100644 (file)
@@ -257,17 +257,7 @@ fn from_iter<I:Iterator<Item=E>>(iterator: I) -> EnumSet<E> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a, E> IntoIterator for &'a EnumSet<E> where E: CLike {
-    type IntoIter = Iter<E>;
-
-    fn into_iter(self) -> Iter<E> {
-        self.iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, E> IntoIterator for &'a EnumSet<E> where E: CLike {
     type Item = E;
     type IntoIter = Iter<E>;
index 0892a1c2008858d0d6faa7ffd9ddc10096772ceb..95cf307ba419b47a47df9bd085c664426f789a1e 100644 (file)
 //!
 //! impl fmt::Display for Vector2D {
 //!     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-//!         // The `f` value implements the `Writer` trait, which is what the
+//!         // The `f` value implements the `Write` trait, which is what the
 //!         // write! macro is expecting. Note that this formatting ignores the
 //!         // various flags provided to format strings.
 //!         write!(f, "({}, {})", self.x, self.y)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-pub use core::fmt::{Formatter, Result, Writer, rt};
+pub use core::fmt::{Formatter, Result, Write, rt};
 pub use core::fmt::{Show, String, Octal, Binary};
 pub use core::fmt::{Display, Debug};
 pub use core::fmt::{LowerHex, UpperHex, Pointer};
index 8325e7247d5fcd4e90047b3e7c022649fcfad762..cacbf3bce80f018e80016abe6d3396a407ecd402 100644 (file)
@@ -111,15 +111,6 @@ pub fn fixme_14344_be_sure_to_link_to_collections() {}
 
 #[cfg(not(test))]
 mod std {
-    // NOTE: remove after next snapshot
-    #[cfg(stage0)] pub use core::clone;    // derive(Clone)
-    #[cfg(stage0)] pub use core::cmp;      // derive(Eq, Ord, etc.)
-    #[cfg(stage0)] pub use core::marker;   // derive(Copy)
-    #[cfg(stage0)] pub use core::hash;     // derive(Hash)
-    #[cfg(stage0)] pub use core::iter;
-    #[cfg(stage0)] pub use core::fmt;      // necessary for panic!()
-    #[cfg(stage0)] pub use core::option;   // necessary for panic!()
-
     pub use core::ops;      // RangeFull
 }
 
index 79c86a846f1b90e96b0b969af1eb0bd9a884df21..ebcfb8d1cf84e2a4d421e2fc000c2cf767e8e559 100644 (file)
@@ -9,12 +9,34 @@
 // except according to those terms.
 
 /// Creates a `Vec` containing the arguments.
+///
+/// `vec!` allows `Vec`s to be defined with the same syntax as array expressions.
+/// There are two forms of this macro:
+///
+/// - Create a `Vec` containing a given list of elements:
+///
+/// ```
+/// let v = vec![1, 2, 3];
+/// assert_eq!(v[0], 1);
+/// assert_eq!(v[1], 2);
+/// assert_eq!(v[2], 3);
+/// ```
+///
+/// - Create a `Vec` from a given element and size:
+///
+/// ```
+/// let v = vec![1; 3];
+/// assert_eq!(v, vec![1, 1, 1]);
+/// ```
+///
+/// Note that unlike array expressions this syntax supports all elements
+/// which implement `Clone` and the number of elements doesn't have to be
+/// a constant.
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! vec {
-    ($x:expr; $y:expr) => (
-        <[_] as $crate::slice::SliceExt>::into_vec(
-            $crate::boxed::Box::new([$x; $y]))
+    ($elem:expr; $n:expr) => (
+        $crate::vec::from_elem($elem, $n)
     );
     ($($x:expr),*) => (
         <[_] as $crate::slice::SliceExt>::into_vec(
index 0a4ccde923667ef01764443f05c58293ca495895..6dcdb21f8000b0f855b58445166cc24343787727 100644 (file)
@@ -8,9 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! This crate implements a double-ended queue with `O(1)` amortized inserts and removals from both
-//! ends of the container. It also has `O(1)` indexing like a vector. The contained elements are
-//! not required to be copyable, and the queue will be sendable if the contained type is sendable.
+//! RingBuf is a double-ended queue, which is implemented with the help of a
+//! growing circular buffer.
+//!
+//! This queue has `O(1)` amortized inserts and removals from both ends of the
+//! container. It also has `O(1)` indexing like a vector. The contained elements
+//! are not required to be copyable, and the queue will be sendable if the
+//! contained type is sendable.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -113,7 +117,8 @@ unsafe fn buffer_write(&mut self, off: usize, t: T) {
     #[inline]
     fn is_full(&self) -> bool { self.cap - self.len() == 1 }
 
-    /// Returns the index in the underlying buffer for a given logical element index.
+    /// Returns the index in the underlying buffer for a given logical element
+    /// index.
     #[inline]
     fn wrap_index(&self, idx: usize) -> usize { wrap_index(idx, self.cap) }
 
@@ -1699,17 +1704,7 @@ fn from_iter<T: Iterator<Item=A>>(iterator: T) -> RingBuf<A> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<T> IntoIterator for RingBuf<T> {
-    type IntoIter = IntoIter<T>;
-
-    fn into_iter(self) -> IntoIter<T> {
-        self.into_iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T> IntoIterator for RingBuf<T> {
     type Item = T;
     type IntoIter = IntoIter<T>;
@@ -1719,17 +1714,7 @@ fn into_iter(self) -> IntoIter<T> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a, T> IntoIterator for &'a RingBuf<T> {
-    type IntoIter = Iter<'a, T>;
-
-    fn into_iter(self) -> Iter<'a, T> {
-        self.iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> IntoIterator for &'a RingBuf<T> {
     type Item = &'a T;
     type IntoIter = Iter<'a, T>;
@@ -1739,17 +1724,7 @@ fn into_iter(self) -> Iter<'a, T> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a, T> IntoIterator for &'a mut RingBuf<T> {
-    type IntoIter = IterMut<'a, T>;
-
-    fn into_iter(mut self) -> IterMut<'a, T> {
-        self.iter_mut()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> IntoIterator for &'a mut RingBuf<T> {
     type Item = &'a mut T;
     type IntoIter = IterMut<'a, T>;
index 63483d30dd202a46e3fbbedd95646bcb55a3c14c..69fd28d1723685067d77df6a650b693f6f7b09c2 100644 (file)
@@ -950,7 +950,7 @@ pub trait ToString {
 impl<T: fmt::Display + ?Sized> ToString for T {
     #[inline]
     fn to_string(&self) -> String {
-        use core::fmt::Writer;
+        use core::fmt::Write;
         let mut buf = String::new();
         let _ = buf.write_fmt(format_args!("{}", self));
         buf.shrink_to_fit();
@@ -984,7 +984,7 @@ fn as_slice<'b>(&'b self) -> &'b str {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Writer for String {
+impl fmt::Write for String {
     #[inline]
     fn write_str(&mut self, s: &str) -> fmt::Result {
         self.push_str(s);
index f294dd3c3e0f62c88321284cd564373430a2c435..25226afd8c9b72b771c049b1e757a25fcd51170e 100644 (file)
@@ -56,6 +56,7 @@
 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::mem;
@@ -1252,6 +1253,30 @@ unsafe fn dealloc<T>(ptr: *mut T, len: usize) {
     }
 }
 
+#[doc(hidden)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T> {
+    unsafe {
+        let mut v = Vec::with_capacity(n);
+        let mut ptr = v.as_mut_ptr();
+
+        // Write all elements except the last one
+        for i in 1..n {
+            ptr::write(ptr, Clone::clone(&elem));
+            ptr = ptr.offset(1);
+            v.set_len(i); // Increment the length in every step in case Clone::clone() panics
+        }
+
+        if n > 0 {
+            // We can write the last element directly without cloning needlessly
+            ptr::write(ptr, elem);
+            v.set_len(n);
+        }
+
+        v
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Common trait implementations for Vec
 ////////////////////////////////////////////////////////////////////////////////
@@ -1383,7 +1408,7 @@ fn deref_mut(&mut self) -> &mut [T] { self.as_mut_slice() }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> FromIterator<T> for Vec<T> {
     #[inline]
-    fn from_iter<I:Iterator<Item=T>>(iterator: I) -> Vec<T> {
+    fn from_iter<I:Iterator<Item=T>>(mut iterator: I) -> Vec<T> {
         let (lower, _) = iterator.size_hint();
         let mut vector = Vec::with_capacity(lower);
 
@@ -1393,13 +1418,20 @@ fn from_iter<I:Iterator<Item=T>>(iterator: I) -> Vec<T> {
         //          vector.push(item);
         //      }
         //
-        // This equivalent crucially runs the iterator precisely once. The
-        // optimization below (eliding bound/growth checks) means that we
-        // actually run the iterator twice. To ensure the "moral equivalent" we
-        // do a `fuse()` operation to ensure that the iterator continues to
-        // return `None` after seeing the first `None`.
-        let mut i = iterator.fuse();
-        for element in i.by_ref().take(vector.capacity()) {
+        // This equivalent crucially runs the iterator precisely once. Below we
+        // actually in theory run the iterator twice (one without bounds checks
+        // and one with). To achieve the "moral equivalent", we use the `if`
+        // statement below to break out early.
+        //
+        // If the first loop has terminated, then we have one of two conditions.
+        //
+        // 1. The underlying iterator returned `None`. In this case we are
+        //    guaranteed that less than `vector.capacity()` elements have been
+        //    returned, so we break out early.
+        // 2. The underlying iterator yielded `vector.capacity()` elements and
+        //    has not yielded `None` yet. In this case we run the iterator to
+        //    its end below.
+        for element in iterator.by_ref().take(vector.capacity()) {
             let len = vector.len();
             unsafe {
                 ptr::write(vector.get_unchecked_mut(len), element);
@@ -1407,24 +1439,16 @@ fn from_iter<I:Iterator<Item=T>>(iterator: I) -> Vec<T> {
             }
         }
 
-        for element in i {
-            vector.push(element)
+        if vector.len() == vector.capacity() {
+            for element in iterator {
+                vector.push(element);
+            }
         }
         vector
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<T> IntoIterator for Vec<T> {
-    type IntoIter = IntoIter<T>;
-
-    fn into_iter(self) -> IntoIter<T> {
-        self.into_iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T> IntoIterator for Vec<T> {
     type Item = T;
     type IntoIter = IntoIter<T>;
@@ -1434,17 +1458,7 @@ fn into_iter(self) -> IntoIter<T> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a, T> IntoIterator for &'a Vec<T> {
-    type IntoIter = slice::Iter<'a, T>;
-
-    fn into_iter(self) -> slice::Iter<'a, T> {
-        self.iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> IntoIterator for &'a Vec<T> {
     type Item = &'a T;
     type IntoIter = slice::Iter<'a, T>;
@@ -1454,17 +1468,7 @@ fn into_iter(self) -> slice::Iter<'a, T> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a, T> IntoIterator for &'a mut Vec<T> {
-    type IntoIter = slice::IterMut<'a, T>;
-
-    fn into_iter(mut self) -> slice::IterMut<'a, T> {
-        self.iter_mut()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> IntoIterator for &'a mut Vec<T> {
     type Item = &'a mut T;
     type IntoIter = slice::IterMut<'a, T>;
@@ -1584,8 +1588,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
             })
         }
index 7f9484c58a18575994e941a7ce4e1ce2f8400bb1..82ccfd0614fd5e14c94f1e47a9d11efcc70410a7 100644 (file)
@@ -668,17 +668,7 @@ fn from_iter<Iter: Iterator<Item=(usize, V)>>(iter: Iter) -> VecMap<V> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<T> IntoIterator for VecMap<T> {
-    type IntoIter = IntoIter<T>;
-
-    fn into_iter(self) -> IntoIter<T> {
-        self.into_iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T> IntoIterator for VecMap<T> {
     type Item = (usize, T);
     type IntoIter = IntoIter<T>;
@@ -688,17 +678,7 @@ fn into_iter(self) -> IntoIter<T> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a, T> IntoIterator for &'a VecMap<T> {
-    type IntoIter = Iter<'a, T>;
-
-    fn into_iter(self) -> Iter<'a, T> {
-        self.iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> IntoIterator for &'a VecMap<T> {
     type Item = (usize, &'a T);
     type IntoIter = Iter<'a, T>;
@@ -708,17 +688,7 @@ fn into_iter(self) -> Iter<'a, T> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a, T> IntoIterator for &'a mut VecMap<T> {
-    type IntoIter = IterMut<'a, T>;
-
-    fn into_iter(mut self) -> IterMut<'a, T> {
-        self.iter_mut()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> IntoIterator for &'a mut VecMap<T> {
     type Item = (usize, &'a mut T);
     type IntoIter = IterMut<'a, T>;
index abaa7594d04780678661e93ecb0087070baa9170..838ca4e478b72223c20583ac4089e99a66469a04 100644 (file)
@@ -48,17 +48,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 }
             }
 
-            // NOTE(stage0): remove impl after a snapshot
-            #[cfg(stage0)]
-            impl<'a, T> IntoIterator for &'a [T; $N] {
-                type IntoIter = Iter<'a, T>;
-
-                fn into_iter(self) -> Iter<'a, T> {
-                    self.iter()
-                }
-            }
-
-            #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+            #[stable(feature = "rust1", since = "1.0.0")]
             impl<'a, T> IntoIterator for &'a [T; $N] {
                 type Item = &'a T;
                 type IntoIter = Iter<'a, T>;
@@ -68,17 +58,7 @@ fn into_iter(self) -> Iter<'a, T> {
                 }
             }
 
-            // NOTE(stage0): remove impl after a snapshot
-            #[cfg(stage0)]
-            impl<'a, T> IntoIterator for &'a mut [T; $N] {
-                type IntoIter = IterMut<'a, T>;
-
-                fn into_iter(self) -> IterMut<'a, T> {
-                    self.iter_mut()
-                }
-            }
-
-            #[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+            #[stable(feature = "rust1", since = "1.0.0")]
             impl<'a, T> IntoIterator for &'a mut [T; $N] {
                 type Item = &'a mut T;
                 type IntoIter = IterMut<'a, T>;
index 32e8cffcae4f91e9156d35a804d82edd5c53f108..05d864accc130050edb18322e7866b4fed50bc7f 100644 (file)
 //! ```
 //! use std::sync::Arc;
 //! use std::sync::atomic::{AtomicUsize, Ordering};
-//! use std::thread::Thread;
+//! use std::thread;
 //!
 //! fn main() {
 //!     let spinlock = Arc::new(AtomicUsize::new(1));
 //!
 //!     let spinlock_clone = spinlock.clone();
-//!     Thread::spawn(move|| {
+//!     thread::spawn(move|| {
 //!         spinlock_clone.store(0, Ordering::SeqCst);
 //!     });
 //!
index cf293ded13f00b9dc5f99e55797d257915ba2ffc..eb138e6142b80e36e5c4217225ed301dcfcea2d1 100644 (file)
 //! use std::cell::RefCell;
 //!
 //! struct Graph {
-//!     edges: Vec<(uint, uint)>,
-//!     span_tree_cache: RefCell<Option<Vec<(uint, uint)>>>
+//!     edges: Vec<(i32, i32)>,
+//!     span_tree_cache: RefCell<Option<Vec<(i32, i32)>>>
 //! }
 //!
 //! impl Graph {
-//!     fn minimum_spanning_tree(&self) -> Vec<(uint, uint)> {
+//!     fn minimum_spanning_tree(&self) -> Vec<(i32, i32)> {
 //!         // Create a new scope to contain the lifetime of the
 //!         // dynamic borrow
 //!         {
 //!         // This is the major hazard of using `RefCell`.
 //!         self.minimum_spanning_tree()
 //!     }
-//! #   fn calc_span_tree(&self) -> Vec<(uint, uint)> { vec![] }
+//! #   fn calc_span_tree(&self) -> Vec<(i32, i32)> { vec![] }
 //! }
 //! ```
 //!
 //!
 //! struct RcBox<T> {
 //!     value: T,
-//!     refcount: Cell<uint>
+//!     refcount: Cell<usize>
 //! }
 //!
 //! impl<T> Clone for Rc<T> {
@@ -279,8 +279,8 @@ pub enum BorrowState {
 }
 
 // Values [1, MAX-1] represent the number of `Ref` active
-// (will not outgrow its range since `uint` is the size of the address space)
-type BorrowFlag = uint;
+// (will not outgrow its range since `usize` is the size of the address space)
+type BorrowFlag = usize;
 const UNUSED: BorrowFlag = 0;
 const WRITING: BorrowFlag = -1;
 
@@ -375,9 +375,9 @@ pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
     ///
     /// ```
     /// use std::cell::RefCell;
-    /// use std::thread::Thread;
+    /// use std::thread;
     ///
-    /// let result = Thread::scoped(move || {
+    /// let result = thread::spawn(move || {
     ///    let c = RefCell::new(5);
     ///    let m = c.borrow_mut();
     ///
@@ -436,9 +436,9 @@ pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
     ///
     /// ```
     /// use std::cell::RefCell;
-    /// use std::thread::Thread;
+    /// use std::thread;
     ///
-    /// let result = Thread::scoped(move || {
+    /// let result = thread::spawn(move || {
     ///    let c = RefCell::new(5);
     ///    let m = c.borrow_mut();
     ///
@@ -649,8 +649,7 @@ fn deref_mut<'a>(&'a mut self) -> &'a mut T {
 ///
 /// **NOTE:** `UnsafeCell<T>`'s fields are public to allow static initializers. It is not
 /// recommended to access its fields directly, `get` should be used instead.
-#[cfg_attr(stage0, lang="unsafe")]  // NOTE: remove after next snapshot
-#[cfg_attr(not(stage0), lang="unsafe_cell")]
+#[lang="unsafe_cell"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct UnsafeCell<T> {
     /// Wrapped value
index 1ebd2df5814d16ca0f660d4365125df6a28fab84..19ec245300d02ab325fec9e3cc6d834a5877201e 100644 (file)
@@ -8,35 +8,33 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Defines the `PartialOrd` and `PartialEq` comparison traits.
+//! Functionality for ordering and comparison.
 //!
-//! This module defines both `PartialOrd` and `PartialEq` traits which are used by the
-//! compiler to implement comparison operators. Rust programs may implement
-//!`PartialOrd` to overload the `<`, `<=`, `>`, and `>=` operators, and may implement
-//! `PartialEq` to overload the `==` and `!=` operators.
+//! This module defines both `PartialOrd` and `PartialEq` traits which are used by the compiler to
+//! implement comparison operators. Rust programs may implement `PartialOrd` to overload the `<`,
+//! `<=`, `>`, and `>=` operators, and may implement `PartialEq` to overload the `==` and `!=`
+//! operators.
 //!
-//! For example, to define a type with a customized definition for the PartialEq
-//! operators, you could do the following:
+//! For example, to define a type with a customized definition for the PartialEq operators, you
+//! could do the following:
 //!
-//! ```rust
+//! ```
 //! use core::num::SignedInt;
 //!
-//! // Our type.
-//! struct SketchyNum {
-//!     num : int
+//! struct FuzzyNum {
+//!     num: i32,
 //! }
 //!
-//! // Our implementation of `PartialEq` to support `==` and `!=`.
-//! impl PartialEq for SketchyNum {
+//! impl PartialEq for FuzzyNum {
 //!     // Our custom eq allows numbers which are near each other to be equal! :D
-//!     fn eq(&self, other: &SketchyNum) -> bool {
+//!     fn eq(&self, other: &FuzzyNum) -> bool {
 //!         (self.num - other.num).abs() < 5
 //!     }
 //! }
 //!
 //! // Now these binary operators will work when applied!
-//! assert!(SketchyNum {num: 37} == SketchyNum {num: 34});
-//! assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
+//! assert!(FuzzyNum { num: 37 } == FuzzyNum { num: 34 });
+//! assert!(FuzzyNum { num: 25 } != FuzzyNum { num: 57 });
 //! ```
 
 #![stable(feature = "rust1", since = "1.0.0")]
 /// Trait for equality comparisons which are [partial equivalence relations](
 /// http://en.wikipedia.org/wiki/Partial_equivalence_relation).
 ///
-/// This trait allows for partial equality, for types that do not have a full
-/// equivalence relation. For example, in floating point numbers `NaN != NaN`,
-/// so floating point types implement `PartialEq` but not `Eq`.
+/// This trait allows for partial equality, for types that do not have a full equivalence relation.
+/// For example, in floating point numbers `NaN != NaN`, so floating point types implement
+/// `PartialEq` but not `Eq`.
 ///
 /// Formally, the equality must be (for all `a`, `b` and `c`):
 ///
 /// - symmetric: `a == b` implies `b == a`; and
 /// - transitive: `a == b` and `b == c` implies `a == c`.
 ///
-/// Note that these requirements mean that the trait itself must be
-/// implemented symmetrically and transitively: if `T: PartialEq<U>`
-/// and `U: PartialEq<V>` then `U: PartialEq<T>` and `T:
+/// Note that these requirements mean that the trait itself must be implemented symmetrically and
+/// transitively: if `T: PartialEq<U>` and `U: PartialEq<V>` then `U: PartialEq<T>` and `T:
 /// PartialEq<V>`.
 ///
-/// PartialEq only requires the `eq` method to be implemented; `ne` is defined
-/// in terms of it by default. Any manual implementation of `ne` *must* respect
-/// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and
-/// only if `a != b`.
+/// PartialEq only requires the `eq` method to be implemented; `ne` is defined in terms of it by
+/// default. Any manual implementation of `ne` *must* respect the rule that `eq` is a strict
+/// inverse of `ne`; that is, `!(a == b)` if and only if `a != b`.
 #[lang="eq"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[old_orphan_check]
@@ -84,12 +80,15 @@ fn ne(&self, other: &Rhs) -> bool { !self.eq(other) }
 /// Trait for equality comparisons which are [equivalence relations](
 /// https://en.wikipedia.org/wiki/Equivalence_relation).
 ///
-/// This means, that in addition to `a == b` and `a != b` being strict
-/// inverses, the equality must be (for all `a`, `b` and `c`):
+/// This means, that in addition to `a == b` and `a != b` being strict inverses, the equality must
+/// be (for all `a`, `b` and `c`):
 ///
 /// - reflexive: `a == a`;
 /// - symmetric: `a == b` implies `b == a`; and
 /// - transitive: `a == b` and `b == c` implies `a == c`.
+///
+/// This property cannot be checked by the compiler, and therefore `Eq` implies
+/// `PartialEq`, and has no extra methods.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Eq: PartialEq<Self> {
     // FIXME #13101: this method is used solely by #[deriving] to
@@ -101,10 +100,26 @@ pub trait Eq: PartialEq<Self> {
     // This should never be implemented by hand.
     #[doc(hidden)]
     #[inline(always)]
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn assert_receiver_is_total_eq(&self) {}
 }
 
-/// An ordering is, e.g, a result of a comparison between two values.
+/// An `Ordering` is the result of a comparison between two values.
+///
+/// # Examples
+///
+/// ```
+/// use std::cmp::Ordering;
+///
+/// let result = 1.cmp(&2);
+/// assert_eq!(Ordering::Less, result);
+///
+/// let result = 1.cmp(&1);
+/// assert_eq!(Ordering::Equal, result);
+///
+/// let result = 2.cmp(&1);
+/// assert_eq!(Ordering::Greater, result);
+/// ```
 #[derive(Clone, Copy, PartialEq, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Ordering {
@@ -120,17 +135,28 @@ pub enum Ordering {
 }
 
 impl Ordering {
-    /// Reverse the `Ordering`, so that `Less` becomes `Greater` and
-    /// vice versa.
+    /// Reverse the `Ordering`.
     ///
-    /// # Example
+    /// * `Less` becomes `Greater`.
+    /// * `Greater` becomes `Less`.
+    /// * `Equal` becomes `Equal`.
     ///
-    /// ```rust
-    /// use std::cmp::Ordering::{Less, Equal, Greater};
+    /// # Examples
     ///
-    /// assert_eq!(Less.reverse(), Greater);
-    /// assert_eq!(Equal.reverse(), Equal);
-    /// assert_eq!(Greater.reverse(), Less);
+    /// Basic behavior:
+    ///
+    /// ```
+    /// use std::cmp::Ordering;
+    ///
+    /// assert_eq!(Ordering::Less.reverse(), Ordering::Greater);
+    /// assert_eq!(Ordering::Equal.reverse(), Ordering::Equal);
+    /// assert_eq!(Ordering::Greater.reverse(), Ordering::Less);
+    /// ```
+    ///
+    /// This method can be used to reverse a comparison:
+    ///
+    /// ```
+    /// use std::cmp::Ordering;
     ///
     /// let mut data: &mut [_] = &mut [2, 10, 5, 8];
     ///
@@ -155,28 +181,27 @@ pub fn reverse(self) -> Ordering {
     }
 }
 
-/// Trait for types that form a [total order](
-/// https://en.wikipedia.org/wiki/Total_order).
+/// Trait for types that form a [total order](https://en.wikipedia.org/wiki/Total_order).
 ///
 /// An order is a total order if it is (for all `a`, `b` and `c`):
 ///
-/// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is
-///   true; and
-/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for
-///   both `==` and `>`.
+/// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true; and
+/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Ord: Eq + PartialOrd<Self> {
-    /// This method returns an ordering between `self` and `other` values.
+    /// This method returns an `Ordering` between `self` and `other`.
     ///
-    /// By convention, `self.cmp(&other)` returns the ordering matching
-    /// the expression `self <operator> other` if true.  For example:
+    /// By convention, `self.cmp(&other)` returns the ordering matching the expression
+    /// `self <operator> other` if true.
+    ///
+    /// # Examples
     ///
     /// ```
-    /// use std::cmp::Ordering::{Less, Equal, Greater};
+    /// use std::cmp::Ordering;
     ///
-    /// assert_eq!( 5.cmp(&10), Less);     // because 5 < 10
-    /// assert_eq!(10.cmp(&5),  Greater);  // because 10 > 5
-    /// assert_eq!( 5.cmp(&5),  Equal);    // because 5 == 5
+    /// assert_eq!(5.cmp(&10), Ordering::Less);
+    /// assert_eq!(10.cmp(&5), Ordering::Greater);
+    /// assert_eq!(5.cmp(&5), Ordering::Equal);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn cmp(&self, other: &Self) -> Ordering;
@@ -208,30 +233,60 @@ fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
 /// The comparison must satisfy, for all `a`, `b` and `c`:
 ///
 /// - antisymmetry: if `a < b` then `!(a > b)` and vice versa; and
-/// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for
-///   both `==` and `>`.
+/// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
 ///
-/// Note that these requirements mean that the trait itself must be
-/// implemented symmetrically and transitively: if `T: PartialOrd<U>`
-/// and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
+/// Note that these requirements mean that the trait itself must be implemented symmetrically and
+/// transitively: if `T: PartialOrd<U>` and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
 /// PartialOrd<V>`.
 ///
-/// PartialOrd only requires implementation of the `partial_cmp` method,
-/// with the others generated from default implementations.
+/// PartialOrd only requires implementation of the `partial_cmp` method, with the others generated
+/// from default implementations.
 ///
-/// However it remains possible to implement the others separately for types
-/// which do not have a total order. For example, for floating point numbers,
-/// `NaN < 0 == false` and `NaN >= 0 == false` (cf. IEEE 754-2008 section
-/// 5.11).
+/// However it remains possible to implement the others separately for types which do not have a
+/// total order. For example, for floating point numbers, `NaN < 0 == false` and `NaN >= 0 ==
+/// false` (cf. IEEE 754-2008 section 5.11).
 #[lang="ord"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
-    /// This method returns an ordering between `self` and `other` values
-    /// if one exists.
+    /// This method returns an ordering between `self` and `other` values if one exists.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::cmp::Ordering;
+    ///
+    /// let result = 1.0.partial_cmp(&2.0);
+    /// assert_eq!(result, Some(Ordering::Less));
+    ///
+    /// let result = 1.0.partial_cmp(&1.0);
+    /// assert_eq!(result, Some(Ordering::Equal));
+    ///
+    /// let result = 2.0.partial_cmp(&1.0);
+    /// assert_eq!(result, Some(Ordering::Greater));
+    /// ```
+    ///
+    /// When comparison is impossible:
+    ///
+    /// ```
+    /// let result = std::f64::NAN.partial_cmp(&1.0);
+    /// assert_eq!(result, None);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
 
     /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::cmp::Ordering;
+    ///
+    /// let result = 1.0 < 2.0;
+    /// assert_eq!(result, true);
+    ///
+    /// let result = 2.0 < 1.0;
+    /// assert_eq!(result, false);
+    /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn lt(&self, other: &Rhs) -> bool {
@@ -241,7 +296,18 @@ fn lt(&self, other: &Rhs) -> bool {
         }
     }
 
-    /// This method tests less than or equal to (`<=`).
+    /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=`
+    /// operator.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let result = 1.0 <= 2.0;
+    /// assert_eq!(result, true);
+    ///
+    /// let result = 2.0 <= 2.0;
+    /// assert_eq!(result, true);
+    /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn le(&self, other: &Rhs) -> bool {
@@ -251,7 +317,17 @@ fn le(&self, other: &Rhs) -> bool {
         }
     }
 
-    /// This method tests greater than (`>`).
+    /// This method tests greater than (for `self` and `other`) and is used by the `>` operator.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let result = 1.0 > 2.0;
+    /// assert_eq!(result, false);
+    ///
+    /// let result = 2.0 > 2.0;
+    /// assert_eq!(result, false);
+    /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn gt(&self, other: &Rhs) -> bool {
@@ -261,7 +337,18 @@ fn gt(&self, other: &Rhs) -> bool {
         }
     }
 
-    /// This method tests greater than or equal to (`>=`).
+    /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=`
+    /// operator.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let result = 2.0 >= 1.0;
+    /// assert_eq!(result, true);
+    ///
+    /// let result = 2.0 >= 2.0;
+    /// assert_eq!(result, true);
+    /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn ge(&self, other: &Rhs) -> bool {
@@ -273,6 +360,15 @@ fn ge(&self, other: &Rhs) -> bool {
 }
 
 /// Compare and return the minimum of two values.
+///
+/// # Examples
+///
+/// ```
+/// use std::cmp;
+///
+/// assert_eq!(1, cmp::min(1, 2));
+/// assert_eq!(2, cmp::min(2, 2));
+/// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn min<T: Ord>(v1: T, v2: T) -> T {
@@ -280,6 +376,15 @@ pub fn min<T: Ord>(v1: T, v2: T) -> T {
 }
 
 /// Compare and return the maximum of two values.
+///
+/// # Examples
+///
+/// ```
+/// use std::cmp;
+///
+/// assert_eq!(2, cmp::max(1, 2));
+/// assert_eq!(2, cmp::max(2, 2));
+/// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn max<T: Ord>(v1: T, v2: T) -> T {
@@ -289,6 +394,24 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
 /// Compare and return the minimum of two values if there is one.
 ///
 /// Returns the first argument if the comparison determines them to be equal.
+///
+/// # Examples
+///
+/// ```
+/// use std::cmp;
+///
+/// assert_eq!(Some(1), cmp::partial_min(1, 2));
+/// assert_eq!(Some(2), cmp::partial_min(2, 2));
+/// ```
+///
+/// When comparison is impossible:
+///
+/// ```
+/// use std::cmp;
+///
+/// let result = cmp::partial_min(std::f64::NAN, 1.0);
+/// assert_eq!(result, None);
+/// ```
 #[inline]
 #[unstable(feature = "core")]
 pub fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
@@ -302,6 +425,24 @@ pub fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
 /// Compare and return the maximum of two values if there is one.
 ///
 /// Returns the first argument if the comparison determines them to be equal.
+///
+/// # Examples
+///
+/// ```
+/// use std::cmp;
+///
+/// assert_eq!(Some(2), cmp::partial_max(1, 2));
+/// assert_eq!(Some(2), cmp::partial_max(2, 2));
+/// ```
+///
+/// When comparison is impossible:
+///
+/// ```
+/// use std::cmp;
+///
+/// let result = cmp::partial_max(std::f64::NAN, 1.0);
+/// assert_eq!(result, None);
+/// ```
 #[inline]
 #[unstable(feature = "core")]
 pub fn partial_max<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
index 8e09e52daee198cff18f31a26433f173e4ad5d14..7f7264a04684b61426996c16ea82fd1683e3b913 100644 (file)
@@ -314,7 +314,7 @@ struct Filler<'a> {
                 end: &'a mut uint,
             }
 
-            impl<'a> fmt::Writer for Filler<'a> {
+            impl<'a> fmt::Write for Filler<'a> {
                 fn write_str(&mut self, s: &str) -> fmt::Result {
                     slice::bytes::copy_memory(&mut self.buf[(*self.end)..],
                                               s.as_bytes());
index f940300a26945cf84ed29536f217ec28a4f5fb9e..67c8c9fec09ab9df4fd04c16439b783dcc423e89 100644 (file)
@@ -57,14 +57,14 @@ pub mod rt {
 /// A collection of methods that are required to format a message into a stream.
 ///
 /// This trait is the type which this modules requires when formatting
-/// information. This is similar to the standard library's `io::Writer` trait,
+/// information. This is similar to the standard library's `io::Write` trait,
 /// but it is only intended for use in libcore.
 ///
 /// This trait should generally not be implemented by consumers of the standard
-/// library. The `write!` macro accepts an instance of `io::Writer`, and the
-/// `io::Writer` trait is favored over implementing this trait.
+/// library. The `write!` macro accepts an instance of `io::Write`, and the
+/// `io::Write` trait is favored over implementing this trait.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub trait Writer {
+pub trait Write {
     /// Writes a slice of bytes into this writer, returning whether the write
     /// succeeded.
     ///
@@ -85,12 +85,12 @@ pub trait Writer {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn write_fmt(&mut self, args: Arguments) -> Result {
         // This Adapter is needed to allow `self` (of type `&mut
-        // Self`) to be cast to a FormatWriter (below) without
+        // Self`) to be cast to a Write (below) without
         // requiring a `Sized` bound.
         struct Adapter<'a,T: ?Sized +'a>(&'a mut T);
 
-        impl<'a, T: ?Sized> Writer for Adapter<'a, T>
-            where T: Writer
+        impl<'a, T: ?Sized> Write for Adapter<'a, T>
+            where T: Write
         {
             fn write_str(&mut self, s: &str) -> Result {
                 self.0.write_str(s)
@@ -116,7 +116,7 @@ pub struct Formatter<'a> {
     width: Option<uint>,
     precision: Option<uint>,
 
-    buf: &'a mut (Writer+'a),
+    buf: &'a mut (Write+'a),
     curarg: slice::Iter<'a, ArgumentV1<'a>>,
     args: &'a [ArgumentV1<'a>],
 }
@@ -197,6 +197,7 @@ pub fn new_v1(pieces: &'a [&'a str],
     /// created with `argumentuint`. However, failing to do so doesn't cause
     /// unsafety, but will ignore invalid .
     #[doc(hidden)] #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new_v1_formatted(pieces: &'a [&'a str],
                             args: &'a [ArgumentV1<'a>],
                             fmt: &'a [rt::v1::Argument]) -> Arguments<'a> {
@@ -367,7 +368,7 @@ pub trait UpperExp {
 ///   * output - the buffer to write output to
 ///   * args - the precompiled arguments generated by `format_args!`
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn write(output: &mut Writer, args: Arguments) -> Result {
+pub fn write(output: &mut Write, args: Arguments) -> Result {
     let mut formatter = Formatter {
         flags: 0,
         width: None,
index 03c473ed9674117b0a29bd58280a11f7edbbb0e3..8e5396f2229e201b2353d987adc21f09b242ce46 100644 (file)
@@ -118,21 +118,13 @@ pub trait FromIterator<A> {
     fn from_iter<T: Iterator<Item=A>>(iterator: T) -> Self;
 }
 
-// NOTE(stage0): remove trait after a snapshot
-#[cfg(stage0)]
 /// Conversion into an `Iterator`
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait IntoIterator {
-    type IntoIter: Iterator;
-
-    /// Consumes `Self` and returns an iterator over it
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn into_iter(self) -> Self::IntoIter;
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
-/// Conversion into an `Iterator`
-pub trait IntoIterator {
     type Item;
+
+    #[stable(feature = "rust1", since = "1.0.0")]
     type IntoIter: Iterator<Item=Self::Item>;
 
     /// Consumes `Self` and returns an iterator over it
@@ -140,17 +132,7 @@ pub trait IntoIterator {
     fn into_iter(self) -> Self::IntoIter;
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<I> IntoIterator for I where I: Iterator {
-    type IntoIter = I;
-
-    fn into_iter(self) -> I {
-        self
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<I: Iterator> IntoIterator for I {
     type Item = I::Item;
     type IntoIter = I;
@@ -350,7 +332,7 @@ fn enumerate(self) -> Enumerate<Self> {
     ///
     /// ```
     /// let xs = [100, 200, 300];
-    /// let mut it = xs.iter().map(|x| *x).peekable();
+    /// let mut it = xs.iter().cloned().peekable();
     /// assert_eq!(*it.peek().unwrap(), 100);
     /// assert_eq!(it.next().unwrap(), 100);
     /// assert_eq!(it.next().unwrap(), 200);
@@ -540,7 +522,7 @@ fn fuse(self) -> Fuse<Self> {
     ///
     /// let a = [1, 4, 2, 3, 8, 9, 6];
     /// let sum = a.iter()
-    ///             .map(|&x| x)
+    ///             .cloned()
     ///             .inspect(|&x| println!("filtering {}", x))
     ///             .filter(|&x| x % 2 == 0)
     ///             .inspect(|&x| println!("{} made it through", x))
@@ -579,7 +561,7 @@ fn by_ref(&mut self) -> &mut Self { self }
     ///
     /// ```
     /// let a = [1, 2, 3, 4, 5];
-    /// let b: Vec<_> = a.iter().map(|&x| x).collect();
+    /// let b: Vec<_> = a.iter().cloned().collect();
     /// assert_eq!(a, b);
     /// ```
     #[inline]
@@ -955,7 +937,7 @@ fn rev(self) -> Rev<Self> {
     ///
     /// ```
     /// let a = [(1, 2), (3, 4)];
-    /// let (left, right): (Vec<_>, Vec<_>) = a.iter().map(|&x| x).unzip();
+    /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip();
     /// assert_eq!([1, 3], left);
     /// assert_eq!([2, 4], right);
     /// ```
@@ -1160,7 +1142,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;
@@ -1323,6 +1305,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"]
@@ -2374,7 +2373,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
 /// iteration
 #[derive(Clone)]
 #[unstable(feature = "core",
-           reason = "may be renamed or replaced by range notation adapaters")]
+           reason = "may be renamed or replaced by range notation adapters")]
 pub struct Counter<A> {
     /// The current state the counter is at (next value to be yielded)
     state: A,
@@ -2385,7 +2384,7 @@ pub struct Counter<A> {
 /// Creates a new counter with the specified start/step
 #[inline]
 #[unstable(feature = "core",
-           reason = "may be renamed or replaced by range notation adapaters")]
+           reason = "may be renamed or replaced by range notation adapters")]
 pub fn count<A>(start: A, step: A) -> Counter<A> {
     Counter{state: start, step: step}
 }
index 7243bd4f0cb258d59af2316da88217999e105bc9..f0c60ffe4bf66f8bb0794d105ac56b83230c14d5 100644 (file)
@@ -67,6 +67,7 @@
 #![feature(simd, unsafe_destructor)]
 #![feature(staged_api)]
 #![feature(unboxed_closures)]
+#![feature(rustc_attrs)]
 
 #[macro_use]
 mod macros;
@@ -153,25 +154,16 @@ mod bool {
 mod core {
     pub use panicking;
     pub use fmt;
-    #[cfg(not(stage0))] pub use clone;
-    #[cfg(not(stage0))] pub use cmp;
-    #[cfg(not(stage0))] pub use hash;
-    #[cfg(not(stage0))] pub use marker;
-    #[cfg(not(stage0))] pub use option;
-    #[cfg(not(stage0))] pub use iter;
+    pub use clone;
+    pub use cmp;
+    pub use hash;
+    pub use marker;
+    pub use option;
+    pub use iter;
 }
 
 #[doc(hidden)]
 mod std {
-    // NOTE: remove after next snapshot
-    #[cfg(stage0)] pub use clone;
-    #[cfg(stage0)] pub use cmp;
-    #[cfg(stage0)] pub use hash;
-    #[cfg(stage0)] pub use marker;
-    #[cfg(stage0)] pub use option;
-    #[cfg(stage0)] pub use fmt;
-    #[cfg(stage0)] pub use iter;
-
     // range syntax
     pub use ops;
 }
index da93d4f6ca44e172a8c53d2a5e34260d7ecce63d..56e1c5dedc1cebbc06c21b043629542de6dc4bea 100644 (file)
            reason = "will be overhauled with new lifetime rules; see RFC 458")]
 #[lang="send"]
 #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
+#[cfg(stage0)]
 pub unsafe trait Send: 'static {
     // empty.
 }
+/// Types able to be transferred across thread boundaries.
+#[unstable(feature = "core",
+           reason = "will be overhauled with new lifetime rules; see RFC 458")]
+#[lang="send"]
+#[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
+#[cfg(not(stage0))]
+pub unsafe trait Send {
+    // empty.
+}
 
 /// Types with a constant size known at compile-time.
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -424,3 +434,11 @@ fn clone(&self) -> InvariantType<T> { *self }
 #[lang="managed_bound"]
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
 pub struct Managed;
+
+#[cfg(not(stage0))]
+mod impls {
+    use super::{Send, Sync, Sized};
+
+    unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {}
+    unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {}
+}
index 51bf3c1648f568482abce0ad2ea1e54c6269435a..740997b7a249d5a6fcdf472c2e5c277f472a0327 100644 (file)
@@ -43,7 +43,7 @@
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn size_of<T>() -> uint {
+pub fn size_of<T>() -> usize {
     unsafe { intrinsics::size_of::<T>() }
 }
 
@@ -58,7 +58,7 @@ pub fn size_of<T>() -> uint {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn size_of_val<T>(_val: &T) -> uint {
+pub fn size_of_val<T>(_val: &T) -> usize {
     size_of::<T>()
 }
 
@@ -75,7 +75,7 @@ pub fn size_of_val<T>(_val: &T) -> uint {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn min_align_of<T>() -> uint {
+pub fn min_align_of<T>() -> usize {
     unsafe { intrinsics::min_align_of::<T>() }
 }
 
@@ -90,7 +90,7 @@ pub fn min_align_of<T>() -> uint {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn min_align_of_val<T>(_val: &T) -> uint {
+pub fn min_align_of_val<T>(_val: &T) -> usize {
     min_align_of::<T>()
 }
 
@@ -108,7 +108,7 @@ pub fn min_align_of_val<T>(_val: &T) -> uint {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn align_of<T>() -> uint {
+pub fn align_of<T>() -> usize {
     // We use the preferred alignment as the default alignment for a type. This
     // appears to be what clang migrated towards as well:
     //
@@ -130,7 +130,7 @@ pub fn align_of<T>() -> uint {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn align_of_val<T>(_val: &T) -> uint {
+pub fn align_of_val<T>(_val: &T) -> usize {
     align_of::<T>()
 }
 
@@ -150,7 +150,7 @@ pub fn align_of_val<T>(_val: &T) -> uint {
 /// ```
 /// use std::mem;
 ///
-/// let x: int = unsafe { mem::zeroed() };
+/// let x: i32 = unsafe { mem::zeroed() };
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -171,7 +171,7 @@ pub unsafe fn zeroed<T>() -> T {
 /// ```
 /// use std::mem;
 ///
-/// let x: int = unsafe { mem::uninitialized() };
+/// let x: i32 = unsafe { mem::uninitialized() };
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
index 3f83302742c8caffef831c7d1c1c22d8764a5acb..5644f76306929e0fbfe7a531058e679bb12a9fb3 100644 (file)
@@ -19,8 +19,8 @@ pub unsafe trait Zeroable {}
 unsafe impl<T> Zeroable for *const T {}
 unsafe impl<T> Zeroable for *mut T {}
 unsafe impl<T> Zeroable for Unique<T> { }
-unsafe impl Zeroable for int {}
-unsafe impl Zeroable for uint {}
+unsafe impl Zeroable for isize {}
+unsafe impl Zeroable for usize {}
 unsafe impl Zeroable for i8 {}
 unsafe impl Zeroable for u8 {}
 unsafe impl Zeroable for i16 {}
index 3dc94ba555f3589bff0aec08c7cfde3f2232bead..9a89682127fb1633df1538942e52ac7a277af71e 100644 (file)
@@ -605,6 +605,8 @@ pub fn and<U>(self, optb: Option<U>) -> Option<U> {
     /// Returns `None` if the option is `None`, otherwise calls `f` with the
     /// wrapped value and returns the result.
     ///
+    /// Some languages call this operation flatmap.
+    ///
     /// # Example
     ///
     /// ```
index 072c60c7036cffceb2c5c88beb2e14841ebb7a17..2779e67c74300dff2efa4eecdc220bc73681910e 100644 (file)
@@ -303,7 +303,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 +330,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")]
index cd91843f359ea9abae945c6599f8e9c67386ddb4..bbfe7e58ef4ac4f703b0294c5e6cbab7d1da8b29 100644 (file)
@@ -626,17 +626,7 @@ fn default() -> &'a [T] { &[] }
 // Iterators
 //
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a, T> IntoIterator for &'a [T] {
-    type IntoIter = Iter<'a, T>;
-
-    fn into_iter(self) -> Iter<'a, T> {
-        self.iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> IntoIterator for &'a [T] {
     type Item = &'a T;
     type IntoIter = Iter<'a, T>;
@@ -646,17 +636,7 @@ fn into_iter(self) -> Iter<'a, T> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a, T> IntoIterator for &'a mut [T] {
-    type IntoIter = IterMut<'a, T>;
-
-    fn into_iter(self) -> IterMut<'a, T> {
-        self.iter_mut()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> IntoIterator for &'a mut [T] {
     type Item = &'a mut T;
     type IntoIter = IterMut<'a, T>;
index 42c2dfbda082af112e9b208bc1839428f792eee8..55fcb8498513c5a804cff7d0cbf3976e0b639171 100644 (file)
@@ -11,7 +11,7 @@
 #![allow(deprecated)]
 
 use core::finally::{try_finally, Finally};
-use std::thread::Thread;
+use std::thread;
 
 #[test]
 fn test_success() {
@@ -22,7 +22,7 @@ fn test_success() {
             *i = 10;
         },
         |i| {
-            assert!(!Thread::panicking());
+            assert!(!thread::panicking());
             assert_eq!(*i, 10);
             *i = 20;
         });
@@ -40,7 +40,7 @@ fn test_fail() {
             panic!();
         },
         |i| {
-            assert!(Thread::panicking());
+            assert!(thread::panicking());
             assert_eq!(*i, 10);
         })
 }
index 7eb0fb97bed2a54f48efce97d6b65f759c55da5c..4eee0454f5d255cf9f2f8b0ed11d3ce58bb82e8f 100644 (file)
@@ -91,7 +91,7 @@ fn test_iterator_chain() {
     assert_eq!(i, expected.len());
 
     let ys = count(30, 10).take(4);
-    let mut it = xs.iter().map(|&x| x).chain(ys);
+    let mut it = xs.iter().cloned().chain(ys);
     let mut i = 0;
     for x in it {
         assert_eq!(x, expected[i]);
@@ -119,7 +119,7 @@ fn test_iterator_enumerate() {
 #[test]
 fn test_iterator_peekable() {
     let xs = vec![0, 1, 2, 3, 4, 5];
-    let mut it = xs.iter().map(|&x|x).peekable();
+    let mut it = xs.iter().cloned().peekable();
 
     assert_eq!(it.len(), 6);
     assert_eq!(it.peek().unwrap(), &0);
@@ -259,7 +259,7 @@ fn test_inspect() {
     let mut n = 0;
 
     let ys = xs.iter()
-               .map(|&x| x)
+               .cloned()
                .inspect(|_| n += 1)
                .collect::<Vec<uint>>();
 
@@ -329,33 +329,33 @@ fn test_iterator_len() {
 #[test]
 fn test_iterator_sum() {
     let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().map(|&x| x).sum(), 6);
-    assert_eq!(v.iter().map(|&x| x).sum(), 55);
-    assert_eq!(v[..0].iter().map(|&x| x).sum(), 0);
+    assert_eq!(v[..4].iter().cloned().sum(), 6);
+    assert_eq!(v.iter().cloned().sum(), 55);
+    assert_eq!(v[..0].iter().cloned().sum(), 0);
 }
 
 #[test]
 fn test_iterator_product() {
     let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().map(|&x| x).product(), 0);
-    assert_eq!(v[1..5].iter().map(|&x| x).product(), 24);
-    assert_eq!(v[..0].iter().map(|&x| x).product(), 1);
+    assert_eq!(v[..4].iter().cloned().product(), 0);
+    assert_eq!(v[1..5].iter().cloned().product(), 24);
+    assert_eq!(v[..0].iter().cloned().product(), 1);
 }
 
 #[test]
 fn test_iterator_max() {
     let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().map(|&x| x).max(), Some(3));
-    assert_eq!(v.iter().map(|&x| x).max(), Some(10));
-    assert_eq!(v[..0].iter().map(|&x| x).max(), None);
+    assert_eq!(v[..4].iter().cloned().max(), Some(3));
+    assert_eq!(v.iter().cloned().max(), Some(10));
+    assert_eq!(v[..0].iter().cloned().max(), None);
 }
 
 #[test]
 fn test_iterator_min() {
     let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().map(|&x| x).min(), Some(0));
-    assert_eq!(v.iter().map(|&x| x).min(), Some(0));
-    assert_eq!(v[..0].iter().map(|&x| x).min(), None);
+    assert_eq!(v[..4].iter().cloned().min(), Some(0));
+    assert_eq!(v.iter().cloned().min(), Some(0));
+    assert_eq!(v[..0].iter().cloned().min(), None);
 }
 
 #[test]
@@ -373,7 +373,7 @@ fn test_iterator_size_hint() {
     assert_eq!(c.clone().take_while(|_| false).size_hint(), (0, None));
     assert_eq!(c.clone().skip_while(|_| false).size_hint(), (0, None));
     assert_eq!(c.clone().enumerate().size_hint(), (uint::MAX, None));
-    assert_eq!(c.clone().chain(vi.clone().map(|&i| i)).size_hint(), (uint::MAX, None));
+    assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (uint::MAX, None));
     assert_eq!(c.clone().zip(vi.clone()).size_hint(), (10, Some(10)));
     assert_eq!(c.clone().scan(0, |_,_| Some(0)).size_hint(), (0, None));
     assert_eq!(c.clone().filter(|_| false).size_hint(), (0, None));
@@ -398,7 +398,7 @@ fn test_iterator_size_hint() {
 #[test]
 fn test_collect() {
     let a = vec![1, 2, 3, 4, 5];
-    let b: Vec<int> = a.iter().map(|&x| x).collect();
+    let b: Vec<int> = a.iter().cloned().collect();
     assert!(a == b);
 }
 
@@ -471,7 +471,7 @@ fn test_rev() {
     let mut it = xs.iter();
     it.next();
     it.next();
-    assert!(it.rev().map(|&x| x).collect::<Vec<int>>() ==
+    assert!(it.rev().cloned().collect::<Vec<int>>() ==
             vec![16, 14, 12, 10, 8, 6]);
 }
 
@@ -508,7 +508,7 @@ fn test_double_ended_map() {
 #[test]
 fn test_double_ended_enumerate() {
     let xs = [1, 2, 3, 4, 5, 6];
-    let mut it = xs.iter().map(|&x| x).enumerate();
+    let mut it = xs.iter().cloned().enumerate();
     assert_eq!(it.next(), Some((0, 1)));
     assert_eq!(it.next(), Some((1, 2)));
     assert_eq!(it.next_back(), Some((5, 6)));
@@ -522,8 +522,8 @@ fn test_double_ended_enumerate() {
 fn test_double_ended_zip() {
     let xs = [1, 2, 3, 4, 5, 6];
     let ys = [1, 2, 3, 7];
-    let a = xs.iter().map(|&x| x);
-    let b = ys.iter().map(|&x| x);
+    let a = xs.iter().cloned();
+    let b = ys.iter().cloned();
     let mut it = a.zip(b);
     assert_eq!(it.next(), Some((1, 1)));
     assert_eq!(it.next(), Some((2, 2)));
@@ -713,7 +713,7 @@ fn test_random_access_inspect() {
 fn test_random_access_map() {
     let xs = [1, 2, 3, 4, 5];
 
-    let mut it = xs.iter().map(|x| *x);
+    let mut it = xs.iter().cloned();
     assert_eq!(xs.len(), it.indexable());
     for (i, elt) in xs.iter().enumerate() {
         assert_eq!(Some(*elt), it.idx(i));
index ca184fb8736cdd78d0f335fc08857a2faad39b24..c743119f4090911bb5d69e0d7383f82e1efc6fef 100644 (file)
@@ -92,6 +92,7 @@
 #![feature(collections)]
 #![feature(int_uint)]
 #![feature(staged_api)]
+#![feature(str_words)]
 #![cfg_attr(test, feature(rustc_private))]
 
 #[cfg(test)] #[macro_use] extern crate log;
index a1a271bc5abb557799763a8eb92d1ebb9faf8bbc..230deabee0034eaff12df6802944b6e415464fee 100644 (file)
 #![feature(int_uint)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(io)]
+#![feature(old_io)]
 
 use self::LabelText::*;
 
index 4535e0b1691952821ee50cc9f3d19e60a5ef6a72..0aa41e03f9f71734a764e4fd06aba0da157c3be2 100644 (file)
@@ -5473,6 +5473,7 @@ pub mod bsd44 {
         use types::os::arch::c95::{c_uchar, c_int, size_t};
 
         extern {
+            #[cfg(not(all(target_os = "android", target_arch = "aarch64")))]
             pub fn getdtablesize() -> c_int;
             pub fn ioctl(d: c_int, request: c_int, ...) -> c_int;
             pub fn madvise(addr: *mut c_void, len: size_t, advice: c_int)
@@ -5733,10 +5734,3 @@ pub mod winsock {
 pub fn issue_14344_workaround() {} // FIXME #14344 force linkage to happen correctly
 
 #[test] fn work_on_windows() { } // FIXME #10872 needed for a happy windows
-
-// NOTE: remove after next snapshot
-#[doc(hidden)]
-#[cfg(all(stage0, not(test)))]
-mod std {
-    pub use core::marker;
-}
index 5edb4a96a7df66ad9e952da74ead57001794c11a..4dab07acfd2a0285626f962f7325440adf07709f 100644 (file)
 #![feature(box_syntax)]
 #![feature(int_uint)]
 #![feature(core)]
-#![feature(io)]
+#![feature(old_io)]
 #![feature(std_misc)]
 #![feature(env)]
 
index f15523fc010b61118d77eaac322844de6cdb5d6b..701749ff3443f6e0280ad1308001854ea645cfe2 100644 (file)
@@ -215,7 +215,7 @@ impl<'a> SeedableRng<&'a [u32]> for IsaacRng {
     fn reseed(&mut self, seed: &'a [u32]) {
         // make the seed into [seed[0], seed[1], ..., seed[seed.len()
         // - 1], 0, 0, ...], to fill rng.rsl.
-        let seed_iter = seed.iter().map(|&x| x).chain(repeat(0u32));
+        let seed_iter = seed.iter().cloned().chain(repeat(0u32));
 
         for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
             *rsl_elem = seed_elem;
@@ -458,7 +458,7 @@ impl<'a> SeedableRng<&'a [u64]> for Isaac64Rng {
     fn reseed(&mut self, seed: &'a [u64]) {
         // make the seed into [seed[0], seed[1], ..., seed[seed.len()
         // - 1], 0, 0, ...], to fill rng.rsl.
-        let seed_iter = seed.iter().map(|&x| x).chain(repeat(0u64));
+        let seed_iter = seed.iter().cloned().chain(repeat(0u64));
 
         for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
             *rsl_elem = seed_elem;
index 4113718cfd15b92989dd8e86d894883470a3e3e1..915c70bbf8ce1d90a6818dc8367ed95c00da4588 100644 (file)
@@ -497,17 +497,6 @@ fn rand<R: Rng>(rng: &mut R) -> XorShiftRng {
 /// ```
 pub struct Closed01<F>(pub F);
 
-// NOTE: remove after next snapshot
-#[cfg(all(stage0, not(test)))]
-mod std {
-    pub use core::{option, fmt}; // panic!()
-    pub use core::clone; // derive Clone
-    pub use core::marker;
-    // for-loops
-    pub use core::iter;
-    pub use core::ops; // slicing syntax
-}
-
 #[cfg(test)]
 mod test {
     use std::rand;
index 154dbbdb750344d556dc32480fca970666e64132..488d5999323866e5ba5bbc98606cb5c2288519a9 100644 (file)
@@ -28,7 +28,7 @@
 #![feature(collections)]
 #![feature(core)]
 #![feature(int_uint)]
-#![feature(io)]
+#![feature(old_io)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 
index 697dddca74fb1291182e8c326b1633a02f43be40..37097764f717c10bc1e5c0ca2b0e21df19e83607 100644 (file)
@@ -4,8 +4,8 @@ An informal guide to reading and working on the rustc compiler.
 If you wish to expand on this document, or have a more experienced
 Rust contributor add anything else to it, please get in touch:
 
-https://github.com/rust-lang/rust/wiki/Note-development-policy
-("Communication" subheading)
+* http://internals.rust-lang.org/
+* https://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust
 
 or file a bug:
 
index abf70813d36e783d3d25193c2b9f2e27874f65f1..fe9a81bb7c984f60d7b2b40e12b9f9106ddfd4ce 100644 (file)
 #![feature(core)]
 #![feature(hash)]
 #![feature(int_uint)]
-#![feature(io)]
+#![feature(old_io)]
 #![feature(libc)]
 #![feature(env)]
-#![feature(path)]
+#![feature(old_path)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
index d09e4bd975924f3392c3b417b1fcc542f641f9a4..ba108b5488edee23cb7d84a09192b74f2e20b987 100644 (file)
@@ -47,6 +47,7 @@
 use syntax::ast_util::is_shift_binop;
 use syntax::attr::{self, AttrMetaMethods};
 use syntax::codemap::{self, Span};
+use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType};
 use syntax::parse::token;
 use syntax::ast::{TyIs, TyUs, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64};
 use syntax::ast_util;
@@ -640,67 +641,19 @@ fn get_lints(&self) -> LintArray {
     }
 
     fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
-        static ATTRIBUTE_WHITELIST: &'static [&'static str] = &[
-            // FIXME: #14408 whitelist docs since rustdoc looks at them
-            "doc",
-
-            // FIXME: #14406 these are processed in trans, which happens after the
-            // lint pass
-            "cold",
-            "export_name",
-            "inline",
-            "link",
-            "link_name",
-            "link_section",
-            "linkage",
-            "no_builtins",
-            "no_mangle",
-            "no_split_stack",
-            "no_stack_check",
-            "packed",
-            "static_assert",
-            "thread_local",
-            "no_debug",
-            "omit_gdb_pretty_printer_section",
-            "unsafe_no_drop_flag",
-
-            // used in resolve
-            "prelude_import",
-
-            // FIXME: #14407 these are only looked at on-demand so we can't
-            // guarantee they'll have already been checked
-            "deprecated",
-            "must_use",
-            "stable",
-            "unstable",
-            "rustc_on_unimplemented",
-            "rustc_error",
-
-            // FIXME: #19470 this shouldn't be needed forever
-            "old_orphan_check",
-            "old_impl_check",
-            "rustc_paren_sugar", // FIXME: #18101 temporary unboxed closure hack
-        ];
-
-        static CRATE_ATTRS: &'static [&'static str] = &[
-            "crate_name",
-            "crate_type",
-            "feature",
-            "no_start",
-            "no_main",
-            "no_std",
-            "no_builtins",
-        ];
-
-        for &name in ATTRIBUTE_WHITELIST {
-            if attr.check_name(name) {
-                break;
+        for &(ref name, ty) in KNOWN_ATTRIBUTES {
+            match ty {
+                AttributeType::Whitelisted
+                | AttributeType::Gated(_, _) if attr.check_name(name) => {
+                    break;
+                },
+                _ => ()
             }
         }
 
         if !attr::is_used(attr) {
             cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
-            if CRATE_ATTRS.contains(&&attr.name()[]) {
+            if KNOWN_ATTRIBUTES.contains(&(&attr.name()[], AttributeType::CrateLevel)) {
                 let msg = match attr.node.style {
                     ast::AttrOuter => "crate-level attribute should be an inner \
                                        attribute: add an exclamation mark: #![foo]",
@@ -1761,7 +1714,7 @@ fn get_lints(&self) -> LintArray {
     }
 
     fn check_item(&mut self, cx: &Context, item: &ast::Item) {
-        stability::check_item(cx.tcx, item,
+        stability::check_item(cx.tcx, item, false,
                               &mut |id, sp, stab| self.lint(cx, id, sp, stab));
     }
 
index 0a3e173b35ee517cde4025249d01381356729d71..a3f7d57da67486b39a976a8289743612960ef5b4 100644 (file)
@@ -139,8 +139,7 @@ pub fn add_used_crate_source(&self, src: CrateSource) {
     pub fn get_used_crate_source(&self, cnum: ast::CrateNum)
                                      -> Option<CrateSource> {
         self.used_crate_sources.borrow_mut()
-            .iter().find(|source| source.cnum == cnum)
-            .map(|source| source.clone())
+            .iter().find(|source| source.cnum == cnum).cloned()
     }
 
     pub fn reset(&self) {
@@ -218,7 +217,7 @@ pub fn add_extern_mod_stmt_cnum(&self,
 
     pub fn find_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId)
                                      -> Option<ast::CrateNum> {
-        self.extern_mod_crate_map.borrow().get(&emod_id).map(|x| *x)
+        self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
     }
 }
 
index 03456f8529028a36a8527a3f00cc3a5e8e99548a..4544f283e1cc2ccfceaedc2f27c114890fe9f0f1 100644 (file)
@@ -76,7 +76,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             pretty_printed_matrix.iter().map(|row| row[col].len()).max().unwrap_or(0)
         }).collect();
 
-        let total_width = column_widths.iter().map(|n| *n).sum() + column_count * 3 + 1;
+        let total_width = column_widths.iter().cloned().sum() + column_count * 3 + 1;
         let br = repeat('+').take(total_width).collect::<String>();
         try!(write!(f, "{}\n", br));
         for row in pretty_printed_matrix {
index 3d03cd946c48fadf517ca238ab75d540e63dd313..456d4a3a86e39336f57bad24ba88dcbdd6fba1bd 100644 (file)
@@ -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),
index b792a44d4d89aad86e57da055cdd5ea1c81fe3d8..307423734b3bf7a932d97cb3f378636d58974ba4 100644 (file)
@@ -89,7 +89,7 @@ struct PropagationContext<'a, 'b: 'a, 'tcx: 'b, O: 'a> {
 }
 
 fn to_cfgidx_or_die(id: ast::NodeId, index: &NodeMap<CFGIndex>) -> CFGIndex {
-    let opt_cfgindex = index.get(&id).map(|&i|i);
+    let opt_cfgindex = index.get(&id).cloned();
     opt_cfgindex.unwrap_or_else(|| {
         panic!("nodeid_to_index does not have entry for NodeId {}", id);
     })
@@ -400,7 +400,7 @@ pub fn add_kills_from_flow_exits(&mut self, cfg: &cfg::CFG) {
 
             let mut changed = false;
             for &node_id in &edge.data.exiting_scopes {
-                let opt_cfg_idx = self.nodeid_to_index.get(&node_id).map(|&i|i);
+                let opt_cfg_idx = self.nodeid_to_index.get(&node_id).cloned();
                 match opt_cfg_idx {
                     Some(cfg_idx) => {
                         let (start, end) = self.compute_id_range(cfg_idx);
index 6d35a82d153cd6c5151e9fedd428c0ae963364e6..ad9f4eade5c90d25538240080640f300aace049a 100644 (file)
@@ -158,7 +158,7 @@ fn calculate_type(sess: &session::Session,
 
     // Collect what we've got so far in the return vector.
     let mut ret = (1..sess.cstore.next_crate_num()).map(|i| {
-        match formats.get(&i).map(|v| *v) {
+        match formats.get(&i).cloned() {
             v @ Some(cstore::RequireDynamic) => v,
             _ => None,
         }
index 5cc7502b5128d3e2674769732670dec36c0ea0c1..8dbac7f515ea8fc23412fda8f8c49192efceaecf 100644 (file)
@@ -838,7 +838,7 @@ fn walk_autoderefs(&mut self,
                     // the method call infrastructure should have
                     // replaced all late-bound regions with variables:
                     let self_ty = ty::ty_fn_sig(method_ty).input(0);
-                    let self_ty = ty::assert_no_late_bound_regions(self.tcx(), &self_ty);
+                    let self_ty = ty::no_late_bound_regions(self.tcx(), &self_ty).unwrap();
 
                     let (m, r) = match self_ty.sty {
                         ty::ty_rptr(r, ref m) => (m.mutbl, r),
index 72b33613c66aab63e81c562e53237821decd3058..49bd2e67a19181dfd45115e341488c7c58f45573 100644 (file)
@@ -924,7 +924,7 @@ fn new(tcx: &'a ty::ctxt<'tcx>,
 
     fn rebuild(&self)
                -> (ast::FnDecl, Option<ast::ExplicitSelf_>, ast::Generics) {
-        let mut expl_self_opt = self.expl_self_opt.map(|x| x.clone());
+        let mut expl_self_opt = self.expl_self_opt.cloned();
         let mut inputs = self.fn_decl.inputs.clone();
         let mut output = self.fn_decl.output.clone();
         let mut ty_params = self.generics.ty_params.clone();
index 923f7d2d4ef358074568545e9eead858b478b6f9..235f3f994c65e40aa79c901e4f5a8cd4e7067126 100644 (file)
@@ -212,7 +212,7 @@ pub fn unify<'tcx>(&mut self,
     }
 }
 
-impl<K> sv::SnapshotVecDelegate for Delegate<K> {
+impl<K:UnifyKey> sv::SnapshotVecDelegate for Delegate<K> {
     type Value = VarValue<K>;
     type Undo = ();
 
index e13a5672778e24da1a4a88980b21fc01eacff0ce..ce8f0d87e564c24511c7a3a7cddbf0a8e7231a96 100644 (file)
@@ -147,18 +147,12 @@ struct LanguageItemCollector<'a> {
 
 impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> {
     fn visit_item(&mut self, item: &ast::Item) {
-        match extract(&item.attrs) {
-            Some(value) => {
-                let item_index = self.item_refs.get(&value[]).map(|x| *x);
-
-                match item_index {
-                    Some(item_index) => {
-                        self.collect_item(item_index, local_def(item.id), item.span)
-                    }
-                    None => {}
-                }
+        if let Some(value) = extract(&item.attrs) {
+            let item_index = self.item_refs.get(&value[]).cloned();
+
+            if let Some(item_index) = item_index {
+                self.collect_item(item_index, local_def(item.id), item.span)
             }
-            None => {}
         }
 
         visit::walk_item(self, item);
index 6c295142c9f326d485a817ad646d4baacbc69d87..4be7bb9c365a16d57d846ac70a178dfda6f944ff 100644 (file)
@@ -281,7 +281,6 @@ impl<'t,TYPER:'t> Copy for MemCategorizationContext<'t,TYPER> {}
 /// know that no errors have occurred, so we simply consult the tcx and we
 /// can be sure that only `Ok` results will occur.
 pub trait Typer<'tcx> : ty::ClosureTyper<'tcx> {
-    fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
     fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>>;
     fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>>;
     fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool;
@@ -905,8 +904,8 @@ fn cat_deref<N:ast_node>(&self,
         let base_cmt = match method_ty {
             Some(method_ty) => {
                 let ref_ty =
-                    ty::assert_no_late_bound_regions(
-                        self.tcx(), &ty::ty_fn_ret(method_ty)).unwrap();
+                    ty::no_late_bound_regions(
+                        self.tcx(), &ty::ty_fn_ret(method_ty)).unwrap().unwrap();
                 self.cat_rvalue_node(node.id(), node.span(), ref_ty)
             }
             None => base_cmt
@@ -996,7 +995,7 @@ pub fn cat_index<N:ast_node>(&self,
 
                 // FIXME(#20649) -- why are we using the `self_ty` as the element type...?
                 let self_ty = ty::ty_fn_sig(method_ty).input(0);
-                ty::assert_no_late_bound_regions(self.tcx(), &self_ty)
+                ty::no_late_bound_regions(self.tcx(), &self_ty).unwrap()
             }
             None => {
                 match ty::array_element_ty(self.tcx(), base_cmt.ty) {
@@ -1336,8 +1335,9 @@ fn overloaded_method_return_ty(&self,
         // types are generated by method resolution and always have
         // all late-bound regions fully instantiated, so we just want
         // to skip past the binder.
-        ty::assert_no_late_bound_regions(self.tcx(), &ty::ty_fn_ret(method_ty))
-            .unwrap() // overloaded ops do not diverge, either
+        ty::no_late_bound_regions(self.tcx(), &ty::ty_fn_ret(method_ty))
+           .unwrap()
+           .unwrap() // overloaded ops do not diverge, either
     }
 }
 
index 2f0462ab8c338177692ca3314e247c5c3e467e71..e539f6ae6cb9382898b2167093e91fe5b288e3db 100644 (file)
@@ -407,7 +407,7 @@ pub fn mark_as_terminating_scope(&self, scope_id: CodeExtent) {
 
     pub fn opt_encl_scope(&self, id: CodeExtent) -> Option<CodeExtent> {
         //! Returns the narrowest scope that encloses `id`, if any.
-        self.scope_map.borrow().get(&id).map(|x| *x)
+        self.scope_map.borrow().get(&id).cloned()
     }
 
     #[allow(dead_code)] // used in middle::cfg
index e91d7d8c52cde8fcbe52af0d0ce6b4797dde80c3..3ba08c1032031075224aaa0dddcd1ac67902f5d4 100644 (file)
@@ -562,7 +562,7 @@ pub fn early_bound_lifetimes<'a>(generics: &'a ast::Generics) -> Vec<ast::Lifeti
 
     generics.lifetimes.iter()
         .filter(|l| referenced_idents.iter().any(|&i| i == l.lifetime.name))
-        .map(|l| (*l).clone())
+        .cloned()
         .collect()
 }
 
index a086e91f4d9f26e40cf8dfe9f29a3aceeb52c1a5..0a0f555f977698e7581c1435489bc5bd9dfa6781 100644 (file)
@@ -261,12 +261,12 @@ fn check(&mut self, id: ast::DefId, span: Span, stab: &Option<Stability>) {
                 if self.tcx.sess.features.borrow().unmarked_api {
                     self.tcx.sess.span_warn(span, "use of unmarked library feature");
                     self.tcx.sess.span_note(span, "this is either a bug in the library you are \
-                                                   using and a bug in the compiler - please \
+                                                   using or a bug in the compiler - please \
                                                    report it in both places");
                 } else {
                     self.tcx.sess.span_err(span, "use of unmarked library feature");
                     self.tcx.sess.span_note(span, "this is either a bug in the library you are \
-                                                   using and a bug in the compiler - please \
+                                                   using or a bug in the compiler - please \
                                                    report it in both places");
                     self.tcx.sess.span_note(span, "use #![feature(unmarked_api)] in the \
                                                    crate attributes to override this");
@@ -283,7 +283,7 @@ fn visit_item(&mut self, item: &ast::Item) {
         // name `__test`
         if item.span == DUMMY_SP && item.ident.as_str() == "__test" { return }
 
-        check_item(self.tcx, item,
+        check_item(self.tcx, item, true,
                    &mut |id, sp, stab| self.check(id, sp, stab));
         visit::walk_item(self, item);
     }
@@ -302,7 +302,7 @@ fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
 }
 
 /// Helper for discovering nodes to check for stability
-pub fn check_item(tcx: &ty::ctxt, item: &ast::Item,
+pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool,
                   cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) {
     match item.node {
         ast::ItemExternCrate(_) => {
@@ -316,6 +316,35 @@ pub fn check_item(tcx: &ty::ctxt, item: &ast::Item,
             let id = ast::DefId { krate: cnum, node: ast::CRATE_NODE_ID };
             maybe_do_stability_check(tcx, id, item.span, cb);
         }
+
+        // For implementations of traits, check the stability of each item
+        // individually as it's possible to have a stable trait with unstable
+        // items.
+        ast::ItemImpl(_, _, _, Some(ref t), _, ref impl_items) => {
+            let trait_did = tcx.def_map.borrow()[t.ref_id].def_id();
+            let trait_items = ty::trait_items(tcx, trait_did);
+
+            for impl_item in impl_items {
+                let (ident, span) = match *impl_item {
+                    ast::MethodImplItem(ref method) => {
+                        (match method.node {
+                            ast::MethDecl(ident, _, _, _, _, _, _, _) => ident,
+                            ast::MethMac(..) => unreachable!(),
+                        }, method.span)
+                    }
+                    ast::TypeImplItem(ref typedef) => {
+                        (typedef.ident, typedef.span)
+                    }
+                };
+                let item = trait_items.iter().find(|item| {
+                    item.name() == ident.name
+                }).unwrap();
+                if warn_about_defns {
+                    maybe_do_stability_check(tcx, item.def_id(), span, cb);
+                }
+            }
+        }
+
         _ => (/* pass */)
     }
 }
index e27e7a80246858058081618883503e7c0b5daa74..04fd03ab34224a3af51bfeed5ab69aad2c355bf4 100644 (file)
@@ -113,7 +113,7 @@ pub fn has_regions_escaping_depth(&self, depth: u32) -> bool {
     }
 
     pub fn self_ty(&self) -> Option<Ty<'tcx>> {
-        self.types.get_self().map(|&t| t)
+        self.types.get_self().cloned()
     }
 
     pub fn with_self_ty(&self, self_ty: Ty<'tcx>) -> Substs<'tcx> {
@@ -530,17 +530,6 @@ fn next(&mut self) -> Option<(ParamSpace, uint, &'a T)> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<T> IntoIterator for VecPerParamSpace<T> {
-    type IntoIter = IntoIter<T>;
-
-    fn into_iter(self) -> IntoIter<T> {
-        self.into_vec().into_iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
 impl<T> IntoIterator for VecPerParamSpace<T> {
     type Item = T;
     type IntoIter = IntoIter<T>;
@@ -550,17 +539,6 @@ fn into_iter(self) -> IntoIter<T> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<'a,T> IntoIterator for &'a VecPerParamSpace<T> {
-    type IntoIter = Iter<'a, T>;
-
-    fn into_iter(self) -> Iter<'a, T> {
-        self.as_slice().into_iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
 impl<'a,T> IntoIterator for &'a VecPerParamSpace<T> {
     type Item = &'a T;
     type IntoIter = Iter<'a, T>;
index 07c7453783d9561ccef45ca8d3f12612968b9629..a9cac4be3e368026e319a32b890df4a6f36263fb 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use middle::infer::{InferCtxt};
-use middle::mem_categorization::Typer;
 use middle::ty::{self, RegionEscape, Ty};
 use std::collections::HashSet;
 use std::collections::hash_map::Entry::{Occupied, Vacant};
index 83090dd72aa94e33447a77e0e2b66472b1514b4c..57c9fa7a4d964a0b834e473247e2278f24631761 100644 (file)
@@ -15,9 +15,9 @@
 pub use self::Vtable::*;
 pub use self::ObligationCauseCode::*;
 
-use middle::mem_categorization::Typer;
 use middle::subst;
-use middle::ty::{self, Ty};
+use middle::ty::{self, HasProjectionTypes, Ty};
+use middle::ty_fold::TypeFoldable;
 use middle::infer::{self, InferCtxt};
 use std::slice::Iter;
 use std::rc::Rc;
@@ -432,18 +432,8 @@ pub fn normalize_param_env<'a,'tcx>(param_env: &ty::ParameterEnvironment<'a,'tcx
     debug!("normalize_param_env(param_env={})",
            param_env.repr(tcx));
 
-    let predicates: Vec<ty::Predicate<'tcx>> = {
-        let infcx = infer::new_infer_ctxt(tcx);
-        let mut selcx = &mut SelectionContext::new(&infcx, param_env);
-        let mut fulfill_cx = FulfillmentContext::new();
-        let Normalized { value: predicates, obligations } =
-            project::normalize(selcx, cause, &param_env.caller_bounds);
-        for obligation in obligations {
-            fulfill_cx.register_predicate_obligation(selcx.infcx(), obligation);
-        }
-        try!(fulfill_cx.select_all_or_error(selcx.infcx(), param_env));
-        predicates.iter().map(|p| infcx.resolve_type_vars_if_possible(p)).collect()
-    };
+    let infcx = infer::new_infer_ctxt(tcx);
+    let predicates = try!(fully_normalize(&infcx, param_env, cause, &param_env.caller_bounds));
 
     debug!("normalize_param_env: predicates={}",
            predicates.repr(tcx));
@@ -451,6 +441,35 @@ pub fn normalize_param_env<'a,'tcx>(param_env: &ty::ParameterEnvironment<'a,'tcx
     Ok(param_env.with_caller_bounds(predicates))
 }
 
+pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
+                                  closure_typer: &ty::ClosureTyper<'tcx>,
+                                  cause: ObligationCause<'tcx>,
+                                  value: &T)
+                                  -> Result<T, Vec<FulfillmentError<'tcx>>>
+    where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + Repr<'tcx>
+{
+    let tcx = closure_typer.tcx();
+
+    debug!("normalize_param_env(value={})",
+           value.repr(tcx));
+
+    let mut selcx = &mut SelectionContext::new(infcx, closure_typer);
+    let mut fulfill_cx = FulfillmentContext::new();
+    let Normalized { value: normalized_value, obligations } =
+        project::normalize(selcx, cause, value);
+    debug!("normalize_param_env: normalized_value={} obligations={}",
+           normalized_value.repr(tcx),
+           obligations.repr(tcx));
+    for obligation in obligations {
+        fulfill_cx.register_predicate_obligation(selcx.infcx(), obligation);
+    }
+    try!(fulfill_cx.select_all_or_error(infcx, closure_typer));
+    let resolved_value = infcx.resolve_type_vars_if_possible(&normalized_value);
+    debug!("normalize_param_env: resolved_value={}",
+           resolved_value.repr(tcx));
+    Ok(resolved_value)
+}
+
 impl<'tcx,O> Obligation<'tcx,O> {
     pub fn new(cause: ObligationCause<'tcx>,
                trait_ref: O)
index b2701ae875c0cb51cc1b914236bda73260b64e1a..7442dd47f7bb7fab3e0794fc23b449806d3c44c8 100644 (file)
@@ -57,7 +57,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(|| {
index 6f58f4655fed1ed944805e58485c9525a98b1e8d..0bfe0d9b96e1123d4409224890bbdc4a19dac8f1 100644 (file)
@@ -20,7 +20,7 @@
 use super::{DerivedObligationCause};
 use super::{project};
 use super::project::Normalized;
-use super::{PredicateObligation, Obligation, TraitObligation, ObligationCause};
+use super::{PredicateObligation, TraitObligation, ObligationCause};
 use super::{ObligationCauseCode, BuiltinDerivedObligation};
 use super::{SelectionError, Unimplemented, Overflow, OutputTypeParameterMismatch};
 use super::{Selection};
@@ -32,9 +32,8 @@
 use super::{util};
 
 use middle::fast_reject;
-use middle::mem_categorization::Typer;
 use middle::subst::{Subst, Substs, TypeSpace, VecPerParamSpace};
-use middle::ty::{self, AsPredicate, RegionEscape, ToPolyTraitRef, Ty};
+use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty};
 use middle::infer;
 use middle::infer::{InferCtxt, TypeFreshener};
 use middle::ty_fold::TypeFoldable;
@@ -653,8 +652,7 @@ fn candidate_from_obligation_no_cache<'o>(&mut self,
                 let is_dup =
                     (0..candidates.len())
                     .filter(|&j| i != j)
-                    .any(|j| self.candidate_should_be_dropped_in_favor_of(stack,
-                                                                          &candidates[i],
+                    .any(|j| self.candidate_should_be_dropped_in_favor_of(&candidates[i],
                                                                           &candidates[j]));
                 if is_dup {
                     debug!("Dropping candidate #{}/{}: {}",
@@ -738,7 +736,7 @@ fn check_candidate_cache(&mut self,
     {
         let cache = self.pick_candidate_cache();
         let hashmap = cache.hashmap.borrow();
-        hashmap.get(&cache_fresh_trait_pred.0.trait_ref).map(|c| (*c).clone())
+        hashmap.get(&cache_fresh_trait_pred.0.trait_ref).cloned()
     }
 
     fn insert_candidate_cache(&mut self,
@@ -1236,31 +1234,10 @@ fn winnow_selection<'o>(&mut self,
         self.evaluate_predicates_recursively(stack, selection.iter_nested())
     }
 
-    /// Returns true if `candidate_i` should be dropped in favor of `candidate_j`.
-    ///
-    /// This is generally true if either:
-    /// - candidate i and candidate j are equivalent; or,
-    /// - candidate i is a concrete impl and candidate j is a where clause bound,
-    ///   and the concrete impl is applicable to the types in the where clause bound.
-    ///
-    /// The last case refers to cases where there are blanket impls (often conditional
-    /// blanket impls) as well as a where clause. This can come down to one of two cases:
-    ///
-    /// - The impl is truly unconditional (it has no where clauses
-    ///   of its own), in which case the where clause is
-    ///   unnecessary, because coherence requires that we would
-    ///   pick that particular impl anyhow (at least so long as we
-    ///   don't have specialization).
-    ///
-    /// - The impl is conditional, in which case we may not have winnowed it out
-    ///   because we don't know if the conditions apply, but the where clause is basically
-    ///   telling us that there is some impl, though not necessarily the one we see.
-    ///
-    /// In both cases we prefer to take the where clause, which is
-    /// essentially harmless.  See issue #18453 for more details of
-    /// a case where doing the opposite caused us harm.
+    /// Returns true if `candidate_i` should be dropped in favor of
+    /// `candidate_j`.  Generally speaking we will drop duplicate
+    /// candidates and prefer where-clause candidates.
     fn candidate_should_be_dropped_in_favor_of<'o>(&mut self,
-                                                   stack: &TraitObligationStack<'o, 'tcx>,
                                                    candidate_i: &SelectionCandidate<'tcx>,
                                                    candidate_j: &SelectionCandidate<'tcx>)
                                                    -> bool
@@ -1270,37 +1247,16 @@ fn candidate_should_be_dropped_in_favor_of<'o>(&mut self,
         }
 
         match (candidate_i, candidate_j) {
-            (&ImplCandidate(impl_def_id), &ParamCandidate(ref bound)) => {
-                debug!("Considering whether to drop param {} in favor of impl {}",
-                       candidate_i.repr(self.tcx()),
-                       candidate_j.repr(self.tcx()));
-
-                self.infcx.probe(|snapshot| {
-                    let (skol_obligation_trait_ref, skol_map) =
-                        self.infcx().skolemize_late_bound_regions(
-                            &stack.obligation.predicate, snapshot);
-                    let impl_substs =
-                        self.rematch_impl(impl_def_id, stack.obligation, snapshot,
-                                          &skol_map, skol_obligation_trait_ref.trait_ref.clone());
-                    let impl_trait_ref =
-                        ty::impl_trait_ref(self.tcx(), impl_def_id).unwrap();
-                    let impl_trait_ref =
-                        impl_trait_ref.subst(self.tcx(), &impl_substs.value);
-                    let poly_impl_trait_ref =
-                        ty::Binder(impl_trait_ref);
-                    let origin =
-                        infer::RelateOutputImplTypes(stack.obligation.cause.span);
-                    self.infcx
-                        .sub_poly_trait_refs(false, origin, poly_impl_trait_ref, bound.clone())
-                        .is_ok()
-                })
-            }
-            (&BuiltinCandidate(_), &ParamCandidate(_)) => {
-                // If we have a where-clause like `Option<K> : Send`,
-                // then we wind up in a situation where there is a
-                // default rule (`Option<K>:Send if K:Send) and the
-                // where-clause that both seem applicable. Just take
-                // the where-clause in that case.
+            (&ImplCandidate(..), &ParamCandidate(..)) |
+            (&ClosureCandidate(..), &ParamCandidate(..)) |
+            (&FnPointerCandidate(..), &ParamCandidate(..)) |
+            (&BuiltinCandidate(..), &ParamCandidate(..)) => {
+                // We basically prefer always prefer to use a
+                // where-clause over another option. Where clauses
+                // impose the burden of finding the exact match onto
+                // the caller. Using an impl in preference of a where
+                // clause can also lead us to "overspecialize", as in
+                // #18453.
                 true
             }
             (&ProjectionCandidate, &ParamCandidate(_)) => {
@@ -1459,22 +1415,6 @@ fn builtin_bound(&mut self,
 
                     ty::BoundSync |
                     ty::BoundSend => {
-                        // Note: technically, a region pointer is only
-                        // sendable if it has lifetime
-                        // `'static`. However, we don't take regions
-                        // into account when doing trait matching:
-                        // instead, when we decide that `T : Send`, we
-                        // will register a separate constraint with
-                        // the region inferencer that `T : 'static`
-                        // holds as well (because the trait `Send`
-                        // requires it). This will ensure that there
-                        // is no borrowed data in `T` (or else report
-                        // an inference error). The reason we do it
-                        // this way is that we do not yet *know* what
-                        // lifetime the borrowed reference has, since
-                        // we haven't finished running inference -- in
-                        // other words, there's a kind of
-                        // chicken-and-egg problem.
                         Ok(If(vec![referent_ty]))
                     }
                 }
@@ -1581,7 +1521,7 @@ fn builtin_bound(&mut self,
                     ty::substd_enum_variants(self.tcx(), def_id, substs)
                     .iter()
                     .flat_map(|variant| variant.args.iter())
-                    .map(|&ty| ty)
+                    .cloned()
                     .collect();
                 nominal(self, bound, def_id, types)
             }
@@ -1817,21 +1757,11 @@ fn vtable_builtin_data(&mut self,
                 }
             })
         }).collect::<Result<_, _>>();
-        let mut obligations = match obligations {
+        let obligations = match obligations {
             Ok(o) => o,
             Err(ErrorReported) => Vec::new()
         };
 
-        // as a special case, `Send` requires `'static`
-        if bound == ty::BoundSend {
-            obligations.push(Obligation {
-                cause: obligation.cause.clone(),
-                recursion_depth: obligation.recursion_depth+1,
-                predicate: ty::Binder(ty::OutlivesPredicate(obligation.self_ty(),
-                                                            ty::ReStatic)).as_predicate(),
-            });
-        }
-
         let obligations = VecPerParamSpace::new(obligations, Vec::new(), Vec::new());
 
         debug!("vtable_builtin_data: obligations={}",
index 107715a8261574858a6233678264466652accab0..4e2b5903ca7bfbe3c366171351c830f0f61e4fb1 100644 (file)
@@ -73,8 +73,6 @@
 use std::cmp;
 use std::fmt;
 use std::hash::{Hash, Writer, SipHasher, Hasher};
-#[cfg(stage0)]
-use std::marker;
 use std::mem;
 use std::ops;
 use std::rc::Rc;
@@ -944,26 +942,6 @@ pub struct TyS<'tcx> {
 
     // the maximal depth of any bound regions appearing in this type.
     region_depth: u32,
-
-    // force the lifetime to be invariant to work-around
-    // region-inference issues with a covariant lifetime.
-    #[cfg(stage0)]
-    marker: ShowInvariantLifetime<'tcx>,
-}
-
-#[cfg(stage0)]
-struct ShowInvariantLifetime<'a>(marker::InvariantLifetime<'a>);
-#[cfg(stage0)]
-impl<'a> ShowInvariantLifetime<'a> {
-    fn new() -> ShowInvariantLifetime<'a> {
-        ShowInvariantLifetime(marker::InvariantLifetime)
-    }
-}
-#[cfg(stage0)]
-impl<'a> fmt::Debug for ShowInvariantLifetime<'a> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "InvariantLifetime")
-    }
 }
 
 impl fmt::Debug for TypeFlags {
@@ -972,14 +950,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[cfg(stage0)]
-impl<'tcx> PartialEq for TyS<'tcx> {
-    fn eq<'a,'b>(&'a self, other: &'b TyS<'tcx>) -> bool {
-        let other: &'a TyS<'tcx> = unsafe { mem::transmute(other) };
-        (self as *const _) == (other as *const _)
-    }
-}
-#[cfg(not(stage0))]
 impl<'tcx> PartialEq for TyS<'tcx> {
     fn eq(&self, other: &TyS<'tcx>) -> bool {
         // (self as *const _) == (other as *const _)
@@ -2367,6 +2337,10 @@ pub fn trait_did(&self, cx: &ctxt) -> ast::DefId {
 }
 
 pub trait ClosureTyper<'tcx> {
+    fn tcx(&self) -> &ty::ctxt<'tcx> {
+        self.param_env().tcx
+    }
+
     fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx>;
 
     /// Is this a `Fn`, `FnMut` or `FnOnce` closure? During typeck,
@@ -2562,12 +2536,6 @@ fn intern_ty<'tcx>(type_arena: &'tcx TypedArena<TyS<'tcx>>,
     let flags = FlagComputation::for_sty(&st);
 
     let ty = match () {
-        #[cfg(stage0)]
-        () => type_arena.alloc(TyS { sty: st,
-                                     flags: flags.flags,
-                                     region_depth: flags.depth,
-                                     marker: ShowInvariantLifetime::new(), }),
-        #[cfg(not(stage0))]
         () => type_arena.alloc(TyS { sty: st,
                                      flags: flags.flags,
                                      region_depth: flags.depth, }),
@@ -2868,7 +2836,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 {
@@ -3837,7 +3805,7 @@ fn are_inner_types_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
                                        -> Representability {
         match ty.sty {
             ty_tup(ref ts) => {
-                find_nonrepresentable(cx, sp, seen, ts.iter().map(|ty| *ty))
+                find_nonrepresentable(cx, sp, seen, ts.iter().cloned())
             }
             // Fixed-length vectors.
             // FIXME(#11924) Behavior undecided for zero-length vectors.
@@ -4144,7 +4112,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)
@@ -4420,8 +4388,8 @@ pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
                                     // overloaded deref operators have all late-bound
                                     // regions fully instantiated and coverge
                                     let fn_ret =
-                                        ty::assert_no_late_bound_regions(cx,
-                                                                         &ty_fn_ret(method_ty));
+                                        ty::no_late_bound_regions(cx,
+                                                                  &ty_fn_ret(method_ty)).unwrap();
                                     adjusted_ty = fn_ret.unwrap();
                                 }
                                 None => {}
@@ -4965,7 +4933,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)
@@ -5222,7 +5190,7 @@ pub fn from_ast_variant(cx: &ctxt<'tcx>,
                 let arg_tys = if args.len() > 0 {
                     // the regions in the argument types come from the
                     // enum def'n, and hence will all be early bound
-                    ty::assert_no_late_bound_regions(cx, &ty_fn_args(ctor_ty))
+                    ty::no_late_bound_regions(cx, &ty_fn_args(ctor_ty)).unwrap()
                 } else {
                     Vec::new()
                 };
@@ -6499,10 +6467,6 @@ pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
 }
 
 impl<'a,'tcx> mc::Typer<'tcx> for ParameterEnvironment<'a,'tcx> {
-    fn tcx(&self) -> &ty::ctxt<'tcx> {
-        self.tcx
-    }
-
     fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> {
         Ok(ty::node_id_to_type(self.tcx, id))
     }
@@ -6636,7 +6600,7 @@ fn accum_substs(accumulator: &mut Vec<Region>, substs: &Substs) {
 }
 
 /// A free variable referred to in a function.
-#[derive(Copy, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
 pub struct Freevar {
     /// The variable being accessed free.
     pub def: def::Def,
@@ -6713,14 +6677,17 @@ pub fn binds_late_bound_regions<'tcx, T>(
     count_late_bound_regions(tcx, value) > 0
 }
 
-pub fn assert_no_late_bound_regions<'tcx, T>(
+pub fn no_late_bound_regions<'tcx, T>(
     tcx: &ty::ctxt<'tcx>,
     value: &Binder<T>)
-    -> T
+    -> Option<T>
     where T : TypeFoldable<'tcx> + Repr<'tcx> + Clone
 {
-    assert!(!binds_late_bound_regions(tcx, value));
-    value.0.clone()
+    if binds_late_bound_regions(tcx, value) {
+        None
+    } else {
+        Some(value.0.clone())
+    }
 }
 
 /// Replace any late-bound regions bound in `value` with `'static`. Useful in trans but also
index 8340a49b92ae35ef419f4619c27cc5001d9e9b27..5768539b2cd76fe5502a20598bc5e1bee9ace8c4 100644 (file)
@@ -645,7 +645,7 @@ pub fn build_target_config(opts: &Options, sp: &SpanHandler) -> Config {
         "32" => (ast::TyI32, ast::TyU32),
         "64" => (ast::TyI64, ast::TyU64),
         w    => sp.handler().fatal(&format!("target specification was invalid: unrecognized \
-                                            target-word-size {}", w)[])
+                                             target-pointer-width {}", w)[])
     };
 
     Config {
index d3d0f56c3ce904b7836f4f51ea80c4d4e39d2267..a6d8bc24da76f501eac9e2cd2a63ecaa35cd12a4 100644 (file)
@@ -214,7 +214,7 @@ 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).map(|result| result.clone());
+    let result = cache.borrow().get(&key).cloned();
     match result {
         Some(result) => result,
         None => {
index 0363978bada2530db3160b99b0f9ffa8443771aa..426101e858a8985e00b83c3618052c7d85d1888f 100644 (file)
@@ -697,9 +697,8 @@ fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
         }
 
         // Region, if not obviously implied by builtin bounds.
-        if bounds.region_bound != ty::ReStatic ||
-            !bounds.builtin_bounds.contains(&ty::BoundSend)
-        { // Region bound is implied by builtin bounds:
+        if bounds.region_bound != ty::ReStatic {
+            // Region bound is implied by builtin bounds:
             components.push(bounds.region_bound.user_string(tcx));
         }
 
index 54b3e8f208125e8253ddc528957bd0d774a84684..d589b063204c7d2d0fa903d6ff2848cd2de84454 100644 (file)
@@ -35,9 +35,9 @@
 #![feature(core)]
 #![feature(hash)]
 #![feature(int_uint)]
-#![feature(io)]
+#![feature(old_io)]
 #![feature(os)]
-#![feature(path)]
+#![feature(old_path)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(env)]
index 36bbd4b987297d020e5fe867d36b604bfbf9211f..3de69bd72e1e43d87bfc55e6a0558ab2f8cb99f1 100644 (file)
@@ -40,10 +40,7 @@ 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 libs = libs.into_iter().filter_map(|(_, l)| l).collect::<Vec<_>>();
     let rpaths = get_rpaths(config, &libs[]);
     flags.push_all(&rpaths_to_flags(&rpaths[])[]);
     flags
index 313c0dc2a6ea74c1ee10d8ce3109379165a90ecd..64b0e0cfd6baca44462cd6b733329580aaf1c277 100644 (file)
@@ -13,6 +13,7 @@
 pub fn target() -> Target {
     let mut base = super::linux_base::opts();
     base.pre_link_args.push("-Wl,--allow-multiple-definition".to_string());
+    base.is_like_android = true;
     base.position_independent_executables = true;
     Target {
         data_layout: "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
index 6fc77a715a55667b672a7edafa1f23229360bf28..fad9344143155628ee92b56fdda2ff0819dfd8af 100644 (file)
@@ -16,6 +16,7 @@ pub fn target() -> Target {
     // Many of the symbols defined in compiler-rt are also defined in libgcc.  Android
     // linker doesn't like that by default.
     base.pre_link_args.push("-Wl,--allow-multiple-definition".to_string());
+    base.is_like_android = true;
     // FIXME #17437 (and #17448): Android doesn't support position dependent executables anymore.
     base.position_independent_executables = false;
 
index b80a486b191d20ede43a37b50bb558ca8a330d36..692e6b474fd27b985ba55ca7eb6f7f41372ef7e3 100644 (file)
@@ -40,7 +40,7 @@
 //! this module defines the format the JSON file should take, though each
 //! underscore in the field names should be replaced with a hyphen (`-`) in the
 //! JSON file. Some fields are required in every target specification, such as
-//! `data-layout`, `llvm-target`, `target-endian`, `target-word-size`, and
+//! `data-layout`, `llvm-target`, `target-endian`, `target-pointer-width`, and
 //! `arch`. In general, options passed to rustc with `-C` override the target's
 //! settings, though `target-feature` and `link-args` will *add* to the list
 //! specified by the target, rather than replace.
@@ -158,6 +158,9 @@ pub struct TargetOptions {
     /// only realy used for figuring out how to find libraries, since Windows uses its own
     /// library naming convention. Defaults to false.
     pub is_like_windows: bool,
+    /// Whether the target toolchain is like Android's. Only useful for compiling against Android.
+    /// Defaults to false.
+    pub is_like_android: bool,
     /// Whether the linker support GNU-like arguments such as -O. Defaults to false.
     pub linker_is_gnu: bool,
     /// Whether the linker support rpaths or not. Defaults to false.
@@ -197,6 +200,7 @@ fn default() -> TargetOptions {
             staticlib_suffix: ".a".to_string(),
             is_like_osx: false,
             is_like_windows: false,
+            is_like_android: false,
             linker_is_gnu: false,
             has_rpath: false,
             no_compiler_rt: false,
@@ -241,7 +245,7 @@ pub fn from_json(obj: Json) -> Target {
             data_layout: get_req_field("data-layout"),
             llvm_target: get_req_field("llvm-target"),
             target_endian: get_req_field("target-endian"),
-            target_pointer_width: get_req_field("target-word-size"),
+            target_pointer_width: get_req_field("target-pointer-width"),
             arch: get_req_field("arch"),
             target_os: get_req_field("os"),
             options: Default::default(),
@@ -345,11 +349,13 @@ macro_rules! load_specific {
             mips_unknown_linux_gnu,
             mipsel_unknown_linux_gnu,
             powerpc_unknown_linux_gnu,
-            arm_linux_androideabi,
             arm_unknown_linux_gnueabi,
             arm_unknown_linux_gnueabihf,
             aarch64_unknown_linux_gnu,
 
+            arm_linux_androideabi,
+            aarch64_linux_android,
+
             x86_64_unknown_freebsd,
 
             i686_unknown_dragonfly,
@@ -363,7 +369,6 @@ macro_rules! load_specific {
             i386_apple_ios,
             x86_64_apple_ios,
             aarch64_apple_ios,
-            aarch64_linux_android,
             armv7_apple_ios,
             armv7s_apple_ios,
 
index da53e9fac11875e6974092c8e9c4b73605f31f99..d0f5aa8cf003b5e36f8996913723cbb6cfeaffeb 100644 (file)
@@ -16,7 +16,6 @@
 use borrowck::move_data::*;
 use rustc::middle::expr_use_visitor as euv;
 use rustc::middle::mem_categorization as mc;
-use rustc::middle::mem_categorization::Typer;
 use rustc::middle::mem_categorization::InteriorOffsetKind as Kind;
 use rustc::middle::ty;
 use rustc::util::ppaux::Repr;
index 10ffb89e728ff4fe08fe4fc3f901b2327d9af0d1..da5c847a04607e7cc79fc8e3de8e01726906d578 100644 (file)
@@ -10,7 +10,6 @@
 
 use borrowck::BorrowckCtxt;
 use rustc::middle::mem_categorization as mc;
-use rustc::middle::mem_categorization::Typer;
 use rustc::middle::mem_categorization::InteriorOffsetKind as Kind;
 use rustc::middle::ty;
 use rustc::util::ppaux::UserString;
index eb1dba7159cf8a537b1633b463703c5c4e9b72b3..728ff6475999800e8300c11fece1457afb946a90 100644 (file)
@@ -471,9 +471,10 @@ pub fn phase_2_configure_and_expand(sess: &Session,
                 new_path.extend(env::split_paths(&_old_path));
                 env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap());
             }
+            let features = sess.features.borrow();
             let cfg = syntax::ext::expand::ExpansionConfig {
                 crate_name: crate_name.to_string(),
-                enable_quotes: sess.features.borrow().quote,
+                features: Some(&features),
                 recursion_limit: sess.recursion_limit.get(),
             };
             let ret = syntax::ext::expand::expand_crate(&sess.parse_sess,
index 9b8ca398b12b887445e0ff0ff2726248523e419d..ac91a0098ea75bf20b7ed1f0ef633b200a2e9c14 100644 (file)
 #![feature(core)]
 #![feature(env)]
 #![feature(int_uint)]
-#![feature(io)]
+#![feature(old_io)]
 #![feature(libc)]
 #![feature(os)]
-#![feature(path)]
+#![feature(old_path)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
 #![feature(unsafe_destructor)]
 #![feature(staged_api)]
-#![feature(std_misc)]
 #![feature(unicode)]
 
 extern crate arena;
@@ -73,7 +72,7 @@
 use rustc::util::common::time;
 
 use std::cmp::Ordering::Equal;
-use std::old_io;
+use std::old_io::{self, stdio};
 use std::iter::repeat;
 use std::env;
 use std::sync::mpsc::channel;
@@ -94,7 +93,7 @@
 
 
 static BUG_REPORT_URL: &'static str =
-    "http://doc.rust-lang.org/complement-bugreport.html";
+    "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports";
 
 
 pub fn run(args: Vec<String>) -> int {
@@ -765,7 +764,7 @@ fn parse_crate_attrs(sess: &Session, input: &Input) ->
 ///
 /// The diagnostic emitter yielded to the procedure should be used for reporting
 /// errors of the compiler.
-pub fn monitor<F:FnOnce()+Send>(f: F) {
+pub fn monitor<F:FnOnce()+Send+'static>(f: F) {
     static STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB
 
     let (tx, rx) = channel();
@@ -780,7 +779,7 @@ pub fn monitor<F:FnOnce()+Send>(f: F) {
         cfg = cfg.stack_size(STACK_SIZE);
     }
 
-    match cfg.scoped(move || { std::old_io::stdio::set_stderr(box w); f() }).join() {
+    match cfg.spawn(move || { stdio::set_stderr(box w); f() }).unwrap().join() {
         Ok(()) => { /* fallthrough */ }
         Err(value) => {
             // Thread panicked without emitting a fatal diagnostic
index 7105a6cc488821e0e30460cdcc7c83329a69a0e6..e614f87c9809997afcb6d3f667f975f0e6ee8a4f 100644 (file)
@@ -254,7 +254,7 @@ pub fn t_fn(&self,
                 output_ty: Ty<'tcx>)
                 -> Ty<'tcx>
     {
-        let input_args = input_tys.iter().map(|ty| *ty).collect();
+        let input_args = input_tys.iter().cloned().collect();
         ty::mk_bare_fn(self.infcx.tcx,
                        None,
                        self.infcx.tcx.mk_bare_fn(ty::BareFnTy {
index 213e356536246bb60631baafed5a218c5dbc61b1..aa90d7c851ba62f8b6c75e9f38be8bb081dcd463 100644 (file)
@@ -29,7 +29,7 @@
 #![feature(int_uint)]
 #![feature(libc)]
 #![feature(link_args)]
-#![feature(path)]
+#![feature(old_path)]
 #![feature(staged_api)]
 #![feature(std_misc)]
 
@@ -58,7 +58,7 @@
 
 use std::ffi::CString;
 use std::cell::RefCell;
-use std::{raw, mem, ptr};
+use std::{raw, mem};
 use libc::{c_uint, c_ushort, uint64_t, c_int, size_t, c_char};
 use libc::{c_longlong, c_ulonglong, c_void};
 use debuginfo::{DIBuilderRef, DIDescriptor,
@@ -2251,65 +2251,6 @@ pub unsafe fn debug_loc_to_string(c: ContextRef, tr: DebugLocRef) -> String {
         .expect("got a non-UTF8 DebugLoc from LLVM")
 }
 
-// FIXME #15460 - create a public function that actually calls our
-// static LLVM symbols. Otherwise the linker will just throw llvm
-// away.  We're just calling lots of stuff until we transitively get
-// all of LLVM. This is worse than anything.
-pub unsafe fn static_link_hack_this_sucks() {
-    LLVMInitializePasses();
-
-    LLVMInitializeX86TargetInfo();
-    LLVMInitializeX86Target();
-    LLVMInitializeX86TargetMC();
-    LLVMInitializeX86AsmPrinter();
-    LLVMInitializeX86AsmParser();
-
-    LLVMInitializeARMTargetInfo();
-    LLVMInitializeARMTarget();
-    LLVMInitializeARMTargetMC();
-    LLVMInitializeARMAsmPrinter();
-    LLVMInitializeARMAsmParser();
-
-    LLVMInitializeAArch64TargetInfo();
-    LLVMInitializeAArch64Target();
-    LLVMInitializeAArch64TargetMC();
-    LLVMInitializeAArch64AsmPrinter();
-    LLVMInitializeAArch64AsmParser();
-
-    LLVMInitializeMipsTargetInfo();
-    LLVMInitializeMipsTarget();
-    LLVMInitializeMipsTargetMC();
-    LLVMInitializeMipsAsmPrinter();
-    LLVMInitializeMipsAsmParser();
-
-    LLVMInitializePowerPCTargetInfo();
-    LLVMInitializePowerPCTarget();
-    LLVMInitializePowerPCTargetMC();
-    LLVMInitializePowerPCAsmPrinter();
-    LLVMInitializePowerPCAsmParser();
-
-    LLVMRustSetLLVMOptions(0 as c_int, ptr::null());
-
-    LLVMPassManagerBuilderPopulateModulePassManager(ptr::null_mut(), ptr::null_mut());
-    LLVMPassManagerBuilderPopulateLTOPassManager(ptr::null_mut(), ptr::null_mut(), False, False);
-    LLVMPassManagerBuilderPopulateFunctionPassManager(ptr::null_mut(), ptr::null_mut());
-    LLVMPassManagerBuilderSetOptLevel(ptr::null_mut(), 0 as c_uint);
-    LLVMPassManagerBuilderUseInlinerWithThreshold(ptr::null_mut(), 0 as c_uint);
-    LLVMWriteBitcodeToFile(ptr::null_mut(), ptr::null());
-    LLVMPassManagerBuilderCreate();
-    LLVMPassManagerBuilderDispose(ptr::null_mut());
-
-    LLVMRustLinkInExternalBitcode(ptr::null_mut(), ptr::null(), 0 as size_t);
-
-    LLVMLinkInMCJIT();
-    LLVMLinkInInterpreter();
-
-    extern {
-        fn LLVMLinkInMCJIT();
-        fn LLVMLinkInInterpreter();
-    }
-}
-
 // The module containing the native LLVM dependencies, generated by the build system
 // Note that this must come after the rustllvm extern declaration so that
 // parts of LLVM that rustllvm depends on aren't thrown away by the linker.
index 874c8f2a9402df38653c04fcf0d7389fdb48ca46..337ba77fe7fbb9a31c18755e5036f7c483a1ee1e 100644 (file)
@@ -1920,18 +1920,15 @@ fn resolve_module_path_from_root(&mut self,
                                 -> ResolveResult<(Rc<Module>, LastPrivate)> {
         fn search_parent_externals(needle: Name, module: &Rc<Module>)
                                 -> Option<Rc<Module>> {
-            module.external_module_children.borrow()
-                                            .get(&needle).cloned()
-                                            .map(|_| module.clone())
-                                            .or_else(|| {
-                match module.parent_link.clone() {
-                    ModuleParentLink(parent, _) => {
-                        search_parent_externals(needle,
-                                                &parent.upgrade().unwrap())
+            match module.external_module_children.borrow().get(&needle) {
+                Some(_) => Some(module.clone()),
+                None => match module.parent_link {
+                    ModuleParentLink(ref parent, _) => {
+                        search_parent_externals(needle, &parent.upgrade().unwrap())
                     }
                    _ => None
                 }
-            })
+            }
         }
 
         let mut search_module = module_;
index 68f413eff85c691efbee33f8337d1f3d338a2bb7..9934d9993d61df0b2b95e6bacc048fd181aa616d 100644 (file)
@@ -939,7 +939,7 @@ fn run_work_multithreaded(sess: &Session,
             }
 
             tx.take().unwrap().send(()).unwrap();
-        });
+        }).unwrap();
     }
 
     let mut panicked = false;
index 21557379e3ae2a2ad01a48c717d4f51e94f5ba91..4606200d058c6e06d43d8fe19a6f1217c4658352 100644 (file)
 #![feature(core)]
 #![feature(hash)]
 #![feature(int_uint)]
-#![feature(io)]
+#![feature(old_io)]
 #![feature(env)]
 #![feature(libc)]
-#![feature(path)]
+#![feature(old_path)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
index 5ece5e59299a07bf8fb0b963b3d691f2264295bb..b0ed6f9e727a2fdf5f64b3050df0b12bf1a66f98 100644 (file)
@@ -827,7 +827,19 @@ fn compare_str<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                            &format!("comparison of `{}`",
                                    cx.ty_to_string(rhs_t))[],
                            StrEqFnLangItem);
-        callee::trans_lang_call(cx, did, &[lhs, rhs], None, debug_loc)
+        let t = ty::mk_str_slice(cx.tcx(), cx.tcx().mk_region(ty::ReStatic), ast::MutImmutable);
+        // The comparison function gets the slices by value, so we have to make copies here. Even
+        // if the function doesn't write through the pointer, things like lifetime intrinsics
+        // require that we do this properly
+        let lhs_arg = alloc_ty(cx, t, "lhs");
+        let rhs_arg = alloc_ty(cx, t, "rhs");
+        memcpy_ty(cx, lhs_arg, lhs, t);
+        memcpy_ty(cx, rhs_arg, rhs, t);
+        let res = callee::trans_lang_call(cx, did, &[lhs_arg, rhs_arg], None, debug_loc);
+        call_lifetime_end(res.bcx, lhs_arg);
+        call_lifetime_end(res.bcx, rhs_arg);
+
+        res
     }
 
     let _icx = push_ctxt("compare_values");
index 971d73aa899b61cbd2e72eee6412542d07d4cbca..b299f6f897176cb66d0b8b0bd59f5d66a7f786d1 100644 (file)
@@ -3198,7 +3198,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
     reachable.push("rust_eh_personality_catch".to_string());
 
     if codegen_units > 1 {
-        internalize_symbols(&shared_ccx, &reachable.iter().map(|x| x.clone()).collect());
+        internalize_symbols(&shared_ccx, &reachable.iter().cloned().collect());
     }
 
     let metadata_module = ModuleTranslation {
index f92df999e6049a3da4c189da516a2cbe925c98d4..ed75330ffcc70b46402258308e90f2288ec7e50a 100644 (file)
@@ -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);
 
index d658003702dcaabbb90924dd1e326774dbad7a8e..3709490d8dad796121c83ad626222ebb2a023708 100644 (file)
@@ -637,10 +637,6 @@ pub fn monomorphize<T>(&self, value: &T) -> T
 }
 
 impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
-    fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> {
-        self.tcx()
-    }
-
     fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> {
         Ok(node_id_type(self, id))
     }
index c10ff753936b317dbaad2ccf5b63e89aea0f00f5..23498089c5839cc2aad225b5acbb7f99ff5aa853 100644 (file)
@@ -736,7 +736,9 @@ pub fn finalize(cx: &CrateContext) {
         // instruct LLVM to emit an older version of dwarf, however,
         // for OS X to understand. For more info see #11352
         // This can be overridden using --llvm-opts -dwarf-version,N.
-        if cx.sess().target.target.options.is_like_osx {
+        // Android has the same issue (#22398)
+        if cx.sess().target.target.options.is_like_osx ||
+           cx.sess().target.target.options.is_like_android {
             llvm::LLVMRustAddModuleFlag(cx.llmod(),
                                         "Dwarf Version\0".as_ptr() as *const _,
                                         2)
index 480679f43cb767567481f4593343aeddae89cc28..aaf6b4c71745ffabf87ba966cb8f9c71bbc3889e 100644 (file)
@@ -781,8 +781,8 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let ix_datum = unpack_datum!(bcx, trans(bcx, idx));
 
             let ref_ty = // invoked methods have LB regions instantiated:
-                ty::assert_no_late_bound_regions(
-                    bcx.tcx(), &ty::ty_fn_ret(method_ty)).unwrap();
+                ty::no_late_bound_regions(
+                    bcx.tcx(), &ty::ty_fn_ret(method_ty)).unwrap().unwrap();
             let elt_ty = match ty::deref(ref_ty, true) {
                 None => {
                     bcx.tcx().sess.span_bug(index_expr.span,
@@ -1197,7 +1197,7 @@ fn make_field(field_name: &str, expr: P<ast::Expr>) -> ast::Field {
                 let trait_ref =
                     bcx.tcx().object_cast_map.borrow()
                                              .get(&expr.id)
-                                             .map(|t| (*t).clone())
+                                             .cloned()
                                              .unwrap();
                 let trait_ref = bcx.monomorphize(&trait_ref);
                 let datum = unpack_datum!(bcx, trans(bcx, &**val));
@@ -2214,8 +2214,8 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             };
 
             let ref_ty = // invoked methods have their LB regions instantiated
-                ty::assert_no_late_bound_regions(
-                    ccx.tcx(), &ty::ty_fn_ret(method_ty)).unwrap();
+                ty::no_late_bound_regions(
+                    ccx.tcx(), &ty::ty_fn_ret(method_ty)).unwrap().unwrap();
             let scratch = rvalue_scratch_datum(bcx, ref_ty, "overloaded_deref");
 
             unpack_result!(bcx, trans_overloaded_op(bcx, expr, method_call,
index 9d1c0fadefcd22718ca1dac09debc1fb7cb9e3fc..546c62e5dd24743b3f6b108a6dec3eba67512096 100644 (file)
@@ -67,7 +67,7 @@ pub fn untuple_arguments_if_necessary<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                                 abi: abi::Abi)
                                                 -> Vec<Ty<'tcx>> {
     if abi != abi::RustCall {
-        return inputs.iter().map(|x| (*x).clone()).collect()
+        return inputs.iter().cloned().collect()
     }
 
     if inputs.len() == 0 {
index 81868f3695c28dafea22137a4a7edda229cb7603..0d30741978a5a5c109a285b04bbf142045ac3509 100644 (file)
@@ -509,7 +509,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
     let ctor_scheme = ty::lookup_item_type(tcx, enum_def);
     let ctor_predicates = ty::lookup_predicates(tcx, enum_def);
     let path_scheme = if ty::is_fn_ty(ctor_scheme.ty) {
-        let fn_ret = ty::assert_no_late_bound_regions(tcx, &ty::ty_fn_ret(ctor_scheme.ty));
+        let fn_ret = ty::no_late_bound_regions(tcx, &ty::ty_fn_ret(ctor_scheme.ty)).unwrap();
         ty::TypeScheme {
             ty: fn_ret.unwrap(),
             generics: ctor_scheme.generics,
index 6a9d34d7637b23d57a9be8b71387f5e991dd47b6..7354ea7377c36126f40d9e22d25e83177ae2d09c 100644 (file)
@@ -367,8 +367,8 @@ fn resolve<'a>(&mut self, fcx: &FnCtxt<'a,'tcx>) {
                 // (This always bites me, should find a way to
                 // refactor it.)
                 let method_sig =
-                    ty::assert_no_late_bound_regions(fcx.tcx(),
-                                                     ty::ty_fn_sig(method_callee.ty));
+                    ty::no_late_bound_regions(fcx.tcx(),
+                                              ty::ty_fn_sig(method_callee.ty)).unwrap();
 
                 debug!("attempt_resolution: method_callee={}",
                        method_callee.repr(fcx.tcx()));
diff --git a/src/librustc_typeck/check/implicator.rs b/src/librustc_typeck/check/implicator.rs
new file mode 100644 (file)
index 0000000..da25719
--- /dev/null
@@ -0,0 +1,456 @@
+// 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.
+
+// #![warn(deprecated_mode)]
+
+use astconv::object_region_bounds;
+use middle::infer::{InferCtxt, GenericKind};
+use middle::subst::{Substs};
+use middle::traits;
+use middle::ty::{self, ToPolyTraitRef, Ty};
+use middle::ty_fold::{TypeFoldable, TypeFolder};
+
+use std::rc::Rc;
+use syntax::ast;
+use syntax::codemap::Span;
+
+use util::common::ErrorReported;
+use util::ppaux::Repr;
+
+// Helper functions related to manipulating region types.
+
+pub enum Implication<'tcx> {
+    RegionSubRegion(Option<Ty<'tcx>>, ty::Region, ty::Region),
+    RegionSubGeneric(Option<Ty<'tcx>>, ty::Region, GenericKind<'tcx>),
+    Predicate(ast::DefId, ty::Predicate<'tcx>),
+}
+
+struct Implicator<'a, 'tcx: 'a> {
+    infcx: &'a InferCtxt<'a,'tcx>,
+    closure_typer: &'a (ty::ClosureTyper<'tcx>+'a),
+    body_id: ast::NodeId,
+    stack: Vec<(ty::Region, Option<Ty<'tcx>>)>,
+    span: Span,
+    out: Vec<Implication<'tcx>>,
+}
+
+/// This routine computes the well-formedness constraints that must hold for the type `ty` to
+/// appear in a context with lifetime `outer_region`
+pub fn implications<'a,'tcx>(
+    infcx: &'a InferCtxt<'a,'tcx>,
+    closure_typer: &ty::ClosureTyper<'tcx>,
+    body_id: ast::NodeId,
+    ty: Ty<'tcx>,
+    outer_region: ty::Region,
+    span: Span)
+    -> Vec<Implication<'tcx>>
+{
+    debug!("implications(body_id={}, ty={}, outer_region={})",
+           body_id,
+           ty.repr(closure_typer.tcx()),
+           outer_region.repr(closure_typer.tcx()));
+
+    let mut stack = Vec::new();
+    stack.push((outer_region, None));
+    let mut wf = Implicator { closure_typer: closure_typer,
+                              infcx: infcx,
+                              body_id: body_id,
+                              span: span,
+                              stack: stack,
+                              out: Vec::new() };
+    wf.accumulate_from_ty(ty);
+    debug!("implications: out={}", wf.out.repr(closure_typer.tcx()));
+    wf.out
+}
+
+impl<'a, 'tcx> Implicator<'a, 'tcx> {
+    fn tcx(&self) -> &'a ty::ctxt<'tcx> {
+        self.infcx.tcx
+    }
+
+    fn accumulate_from_ty(&mut self, ty: Ty<'tcx>) {
+        debug!("accumulate_from_ty(ty={})",
+               ty.repr(self.tcx()));
+
+        match ty.sty {
+            ty::ty_bool |
+            ty::ty_char |
+            ty::ty_int(..) |
+            ty::ty_uint(..) |
+            ty::ty_float(..) |
+            ty::ty_bare_fn(..) |
+            ty::ty_err |
+            ty::ty_str => {
+                // No borrowed content reachable here.
+            }
+
+            ty::ty_closure(_, region, _) => {
+                // An "closure type" is basically
+                // modeled here as equivalent to a struct like
+                //
+                //     struct TheClosure<'b> {
+                //         ...
+                //     }
+                //
+                // where the `'b` is the lifetime bound of the
+                // contents (i.e., all contents must outlive 'b).
+                //
+                // Even though closures are glorified structs
+                // of upvars, we do not need to consider them as they
+                // can't generate any new constraints.  The
+                // substitutions on the closure are equal to the free
+                // substitutions of the enclosing parameter
+                // environment.  An upvar captured by value has the
+                // same type as the original local variable which is
+                // already checked for consistency.  If the upvar is
+                // captured by reference it must also outlive the
+                // region bound on the closure, but this is explicitly
+                // handled by logic in regionck.
+                self.push_region_constraint_from_top(*region);
+            }
+
+            ty::ty_trait(ref t) => {
+                let required_region_bounds =
+                    object_region_bounds(self.tcx(), &t.principal, t.bounds.builtin_bounds);
+                self.accumulate_from_object_ty(ty, t.bounds.region_bound, required_region_bounds)
+            }
+
+            ty::ty_enum(def_id, substs) |
+            ty::ty_struct(def_id, substs) => {
+                let item_scheme = ty::lookup_item_type(self.tcx(), def_id);
+                self.accumulate_from_adt(ty, def_id, &item_scheme.generics, substs)
+            }
+
+            ty::ty_vec(t, _) |
+            ty::ty_ptr(ty::mt { ty: t, .. }) |
+            ty::ty_uniq(t) => {
+                self.accumulate_from_ty(t)
+            }
+
+            ty::ty_rptr(r_b, mt) => {
+                self.accumulate_from_rptr(ty, *r_b, mt.ty);
+            }
+
+            ty::ty_param(p) => {
+                self.push_param_constraint_from_top(p);
+            }
+
+            ty::ty_projection(ref data) => {
+                // `<T as TraitRef<..>>::Name`
+
+                self.push_projection_constraint_from_top(data);
+            }
+
+            ty::ty_tup(ref tuptys) => {
+                for &tupty in tuptys {
+                    self.accumulate_from_ty(tupty);
+                }
+            }
+
+            ty::ty_infer(_) => {
+                // This should not happen, BUT:
+                //
+                //   Currently we uncover region relationships on
+                //   entering the fn check. We should do this after
+                //   the fn check, then we can call this case a bug().
+            }
+
+            ty::ty_open(_) => {
+                self.tcx().sess.bug(
+                    &format!("Unexpected type encountered while doing wf check: {}",
+                            ty.repr(self.tcx()))[]);
+            }
+        }
+    }
+
+    fn accumulate_from_rptr(&mut self,
+                            ty: Ty<'tcx>,
+                            r_b: ty::Region,
+                            ty_b: Ty<'tcx>) {
+        // We are walking down a type like this, and current
+        // position is indicated by caret:
+        //
+        //     &'a &'b ty_b
+        //         ^
+        //
+        // At this point, top of stack will be `'a`. We must
+        // require that `'a <= 'b`.
+
+        self.push_region_constraint_from_top(r_b);
+
+        // Now we push `'b` onto the stack, because it must
+        // constrain any borrowed content we find within `T`.
+
+        self.stack.push((r_b, Some(ty)));
+        self.accumulate_from_ty(ty_b);
+        self.stack.pop().unwrap();
+    }
+
+    /// Pushes a constraint that `r_b` must outlive the top region on the stack.
+    fn push_region_constraint_from_top(&mut self,
+                                       r_b: ty::Region) {
+
+        // Indicates that we have found borrowed content with a lifetime
+        // of at least `r_b`. This adds a constraint that `r_b` must
+        // outlive the region `r_a` on top of the stack.
+        //
+        // As an example, imagine walking a type like:
+        //
+        //     &'a &'b T
+        //         ^
+        //
+        // when we hit the inner pointer (indicated by caret), `'a` will
+        // be on top of stack and `'b` will be the lifetime of the content
+        // we just found. So we add constraint that `'a <= 'b`.
+
+        let &(r_a, opt_ty) = self.stack.last().unwrap();
+        self.push_sub_region_constraint(opt_ty, r_a, r_b);
+    }
+
+    /// Pushes a constraint that `r_a <= r_b`, due to `opt_ty`
+    fn push_sub_region_constraint(&mut self,
+                                  opt_ty: Option<Ty<'tcx>>,
+                                  r_a: ty::Region,
+                                  r_b: ty::Region) {
+        self.out.push(Implication::RegionSubRegion(opt_ty, r_a, r_b));
+    }
+
+    /// Pushes a constraint that `param_ty` must outlive the top region on the stack.
+    fn push_param_constraint_from_top(&mut self,
+                                      param_ty: ty::ParamTy) {
+        let &(region, opt_ty) = self.stack.last().unwrap();
+        self.push_param_constraint(region, opt_ty, param_ty);
+    }
+
+    /// Pushes a constraint that `projection_ty` must outlive the top region on the stack.
+    fn push_projection_constraint_from_top(&mut self,
+                                           projection_ty: &ty::ProjectionTy<'tcx>) {
+        let &(region, opt_ty) = self.stack.last().unwrap();
+        self.out.push(Implication::RegionSubGeneric(
+            opt_ty, region, GenericKind::Projection(projection_ty.clone())));
+    }
+
+    /// Pushes a constraint that `region <= param_ty`, due to `opt_ty`
+    fn push_param_constraint(&mut self,
+                             region: ty::Region,
+                             opt_ty: Option<Ty<'tcx>>,
+                             param_ty: ty::ParamTy) {
+        self.out.push(Implication::RegionSubGeneric(
+            opt_ty, region, GenericKind::Param(param_ty)));
+    }
+
+    fn accumulate_from_adt(&mut self,
+                           ty: Ty<'tcx>,
+                           def_id: ast::DefId,
+                           _generics: &ty::Generics<'tcx>,
+                           substs: &Substs<'tcx>)
+    {
+        let predicates =
+            ty::lookup_predicates(self.tcx(), def_id).instantiate(self.tcx(), substs);
+        let predicates = match self.fully_normalize(&predicates) {
+            Ok(predicates) => predicates,
+            Err(ErrorReported) => { return; }
+        };
+
+        for predicate in predicates.predicates.as_slice() {
+            match *predicate {
+                ty::Predicate::Trait(ref data) => {
+                    self.accumulate_from_assoc_types_transitive(data);
+                }
+                ty::Predicate::Equate(..) => { }
+                ty::Predicate::Projection(..) => { }
+                ty::Predicate::RegionOutlives(ref data) => {
+                    match ty::no_late_bound_regions(self.tcx(), data) {
+                        None => { }
+                        Some(ty::OutlivesPredicate(r_a, r_b)) => {
+                            self.push_sub_region_constraint(Some(ty), r_b, r_a);
+                        }
+                    }
+                }
+                ty::Predicate::TypeOutlives(ref data) => {
+                    match ty::no_late_bound_regions(self.tcx(), data) {
+                        None => { }
+                        Some(ty::OutlivesPredicate(ty_a, r_b)) => {
+                            self.stack.push((r_b, Some(ty)));
+                            self.accumulate_from_ty(ty_a);
+                            self.stack.pop().unwrap();
+                        }
+                    }
+                }
+            }
+        }
+
+        let obligations = predicates.predicates
+                                    .into_iter()
+                                    .map(|pred| Implication::Predicate(def_id, pred));
+        self.out.extend(obligations);
+
+        let variances = ty::item_variances(self.tcx(), def_id);
+
+        for (&region, &variance) in substs.regions().iter().zip(variances.regions.iter()) {
+            match variance {
+                ty::Contravariant | ty::Invariant => {
+                    // If any data with this lifetime is reachable
+                    // within, it must be at least contravariant.
+                    self.push_region_constraint_from_top(region)
+                }
+                ty::Covariant | ty::Bivariant => { }
+            }
+        }
+
+        for (&ty, &variance) in substs.types.iter().zip(variances.types.iter()) {
+            match variance {
+                ty::Covariant | ty::Invariant => {
+                    // If any data of this type is reachable within,
+                    // it must be at least covariant.
+                    self.accumulate_from_ty(ty);
+                }
+                ty::Contravariant | ty::Bivariant => { }
+            }
+        }
+    }
+
+    /// Given that there is a requirement that `Foo<X> : 'a`, where
+    /// `Foo` is declared like `struct Foo<T> where T : SomeTrait`,
+    /// this code finds all the associated types defined in
+    /// `SomeTrait` (and supertraits) and adds a requirement that `<X
+    /// as SomeTrait>::N : 'a` (where `N` is some associated type
+    /// defined in `SomeTrait`). This rule only applies to
+    /// trait-bounds that are not higher-ranked, because we cannot
+    /// project out of a HRTB. This rule helps code using associated
+    /// types to compile, see Issue #22246 for an example.
+    fn accumulate_from_assoc_types_transitive(&mut self,
+                                              data: &ty::PolyTraitPredicate<'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); }
+                None => { }
+            }
+        }
+    }
+
+    fn accumulate_from_assoc_types(&mut self,
+                                   trait_ref: Rc<ty::TraitRef<'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<_> =
+            trait_def.associated_type_names
+                     .iter()
+                     .map(|&name| ty::mk_projection(self.tcx(), trait_ref.clone(), name))
+                     .collect();
+        let tys = match self.fully_normalize(&assoc_type_projections) {
+            Ok(tys) => { tys }
+            Err(ErrorReported) => { return; }
+        };
+        for ty in tys {
+            self.accumulate_from_ty(ty);
+        }
+    }
+
+    fn accumulate_from_object_ty(&mut self,
+                                 ty: Ty<'tcx>,
+                                 region_bound: ty::Region,
+                                 required_region_bounds: Vec<ty::Region>)
+    {
+        // Imagine a type like this:
+        //
+        //     trait Foo { }
+        //     trait Bar<'c> : 'c { }
+        //
+        //     &'b (Foo+'c+Bar<'d>)
+        //         ^
+        //
+        // In this case, the following relationships must hold:
+        //
+        //     'b <= 'c
+        //     'd <= 'c
+        //
+        // The first conditions is due to the normal region pointer
+        // rules, which say that a reference cannot outlive its
+        // referent.
+        //
+        // The final condition may be a bit surprising. In particular,
+        // you may expect that it would have been `'c <= 'd`, since
+        // usually lifetimes of outer things are conservative
+        // approximations for inner things. However, it works somewhat
+        // differently with trait objects: here the idea is that if the
+        // user specifies a region bound (`'c`, in this case) it is the
+        // "master bound" that *implies* that bounds from other traits are
+        // all met. (Remember that *all bounds* in a type like
+        // `Foo+Bar+Zed` must be met, not just one, hence if we write
+        // `Foo<'x>+Bar<'y>`, we know that the type outlives *both* 'x and
+        // 'y.)
+        //
+        // Note: in fact we only permit builtin traits, not `Bar<'d>`, I
+        // am looking forward to the future here.
+
+        // The content of this object type must outlive
+        // `bounds.region_bound`:
+        let r_c = region_bound;
+        self.push_region_constraint_from_top(r_c);
+
+        // And then, in turn, to be well-formed, the
+        // `region_bound` that user specified must imply the
+        // region bounds required from all of the trait types:
+        for &r_d in &required_region_bounds {
+            // Each of these is an instance of the `'c <= 'b`
+            // constraint above
+            self.out.push(Implication::RegionSubRegion(Some(ty), r_d, r_c));
+        }
+    }
+
+    fn fully_normalize<T>(&self, value: &T) -> Result<T,ErrorReported>
+        where T : TypeFoldable<'tcx> + ty::HasProjectionTypes + Clone + Repr<'tcx>
+    {
+        let value =
+            traits::fully_normalize(self.infcx,
+                                    self.closure_typer,
+                                    traits::ObligationCause::misc(self.span, self.body_id),
+                                    value);
+        match value {
+            Ok(value) => Ok(value),
+            Err(errors) => {
+                // I don't like reporting these errors here, but I
+                // don't know where else to report them just now. And
+                // I don't really expect errors to arise here
+                // frequently. I guess the best option would be to
+                // propagate them out.
+                traits::report_fulfillment_errors(self.infcx, &errors);
+                Err(ErrorReported)
+            }
+        }
+    }
+}
+
+impl<'tcx> Repr<'tcx> for Implication<'tcx> {
+    fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
+        match *self {
+            Implication::RegionSubRegion(_, ref r_a, ref r_b) => {
+                format!("RegionSubRegion({}, {})",
+                        r_a.repr(tcx),
+                        r_b.repr(tcx))
+            }
+
+            Implication::RegionSubGeneric(_, ref r, ref p) => {
+                format!("RegionSubGeneric({}, {})",
+                        r.repr(tcx),
+                        p.repr(tcx))
+            }
+
+            Implication::Predicate(ref def_id, ref p) => {
+                format!("Predicate({}, {})",
+                        def_id.repr(tcx),
+                        p.repr(tcx))
+            }
+        }
+    }
+}
index 30896c1607a88140be22fdfafda6d698051fe42e..f62465ea572bf988814e16862a83c05c2f2f20ca 100644 (file)
 pub mod _match;
 pub mod vtable;
 pub mod writeback;
-pub mod regionmanip;
+pub mod implicator;
 pub mod regionck;
 pub mod coercion;
 pub mod demand;
@@ -309,9 +309,6 @@ pub struct FnCtxt<'a, 'tcx: 'a> {
 }
 
 impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> {
-    fn tcx(&self) -> &ty::ctxt<'tcx> {
-        self.ccx.tcx
-    }
     fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
         let ty = self.node_ty(id);
         self.resolve_type_vars_or_error(&ty)
@@ -484,7 +481,8 @@ pub fn check_item_types(ccx: &CrateCtxt) {
 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                            decl: &'tcx ast::FnDecl,
                            body: &'tcx ast::Block,
-                           id: ast::NodeId,
+                           fn_id: ast::NodeId,
+                           fn_span: Span,
                            raw_fty: Ty<'tcx>,
                            param_env: ty::ParameterEnvironment<'a, 'tcx>)
 {
@@ -502,13 +500,13 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
             let fn_sig =
                 inh.normalize_associated_types_in(&inh.param_env, body.span, body.id, &fn_sig);
 
-            let fcx = check_fn(ccx, fn_ty.unsafety, id, &fn_sig,
-                               decl, id, body, &inh);
+            let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
+                               decl, fn_id, body, &inh);
 
             vtable::select_all_fcx_obligations_and_apply_defaults(&fcx);
-            upvar::closure_analyze_fn(&fcx, id, decl, body);
+            upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
             vtable::select_all_fcx_obligations_or_error(&fcx);
-            regionck::regionck_fn(&fcx, id, decl, body);
+            regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
             writeback::resolve_type_vars_in_fn(&fcx, decl, body);
         }
         _ => ccx.tcx.sess.impossible_case(body.span,
@@ -640,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 {
@@ -721,7 +719,7 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
       ast::ItemFn(ref decl, _, _, _, ref body) => {
         let fn_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
         let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
-        check_bare_fn(ccx, &**decl, &**body, it.id, fn_pty.ty, param_env);
+        check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
       }
       ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
         debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
@@ -868,6 +866,7 @@ fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                   &*method.pe_fn_decl(),
                   &*method.pe_body(),
                   method.id,
+                  method.span,
                   fty,
                   param_env);
 }
@@ -2050,8 +2049,8 @@ fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     match method {
         Some(method) => {
             let ref_ty = // invoked methods have all LB regions instantiated
-                ty::assert_no_late_bound_regions(
-                    fcx.tcx(), &ty::ty_fn_ret(method.ty));
+                ty::no_late_bound_regions(
+                    fcx.tcx(), &ty::ty_fn_ret(method.ty)).unwrap();
             match method_call {
                 Some(method_call) => {
                     fcx.inh.method_map.borrow_mut().insert(method_call,
@@ -3220,7 +3219,7 @@ fn check_struct_or_variant_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         for field in ast_fields {
             let mut expected_field_type = tcx.types.err;
 
-            let pair = class_field_map.get(&field.ident.node.name).map(|x| *x);
+            let pair = class_field_map.get(&field.ident.node.name).cloned();
             match pair {
                 None => {
                     fcx.type_error_message(
@@ -3852,7 +3851,7 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
       }
       ast::ExprStruct(ref path, ref fields, ref base_expr) => {
         // Resolve the path.
-        let def = tcx.def_map.borrow().get(&id).map(|i| *i);
+        let def = tcx.def_map.borrow().get(&id).cloned();
         let struct_id = match def {
             Some(def::DefVariant(enum_id, variant_id, true)) => {
                 check_struct_enum_variant(fcx, id, expr.span, enum_id,
index 17c259e674e9f08f2ea38ea710ed65dba1e69f62..4e5550a2106a98aa64cc38dfc118e1e97af829b8 100644 (file)
@@ -85,7 +85,7 @@
 use astconv::AstConv;
 use check::dropck;
 use check::FnCtxt;
-use check::regionmanip;
+use check::implicator;
 use check::vtable;
 use middle::def;
 use middle::mem_categorization as mc;
 use middle::pat_util;
 use util::ppaux::{ty_to_string, Repr};
 
+use std::mem;
 use syntax::{ast, ast_util};
 use syntax::codemap::Span;
 use syntax::visit;
 use syntax::visit::Visitor;
 
-use self::RepeatingScope::Repeating;
 use self::SubjectNode::Subject;
 
 // a variation on try that just returns unit
@@ -114,7 +114,7 @@ macro_rules! ignore_err {
 // PUBLIC ENTRY POINTS
 
 pub fn regionck_expr(fcx: &FnCtxt, e: &ast::Expr) {
-    let mut rcx = Rcx::new(fcx, Repeating(e.id), Subject(e.id));
+    let mut rcx = Rcx::new(fcx, RepeatingScope(e.id), e.id, Subject(e.id));
     if fcx.err_count_since_creation() == 0 {
         // regionck assumes typeck succeeded
         rcx.visit_expr(e);
@@ -124,22 +124,23 @@ pub fn regionck_expr(fcx: &FnCtxt, e: &ast::Expr) {
 }
 
 pub fn regionck_item(fcx: &FnCtxt, item: &ast::Item) {
-    let mut rcx = Rcx::new(fcx, Repeating(item.id), Subject(item.id));
+    let mut rcx = Rcx::new(fcx, RepeatingScope(item.id), item.id, Subject(item.id));
     rcx.visit_region_obligations(item.id);
     rcx.resolve_regions_and_report_errors();
 }
 
-pub fn regionck_fn(fcx: &FnCtxt, id: ast::NodeId, decl: &ast::FnDecl, blk: &ast::Block) {
-    let mut rcx = Rcx::new(fcx, Repeating(blk.id), Subject(id));
+pub fn regionck_fn(fcx: &FnCtxt,
+                   fn_id: ast::NodeId,
+                   fn_span: Span,
+                   decl: &ast::FnDecl,
+                   blk: &ast::Block) {
+    debug!("regionck_fn(id={})", fn_id);
+    let mut rcx = Rcx::new(fcx, RepeatingScope(blk.id), blk.id, Subject(fn_id));
     if fcx.err_count_since_creation() == 0 {
         // regionck assumes typeck succeeded
-        rcx.visit_fn_body(id, decl, blk);
+        rcx.visit_fn_body(fn_id, decl, blk, fn_span);
     }
 
-    // Region checking a fn can introduce new trait obligations,
-    // particularly around closure bounds.
-    vtable::select_all_fcx_obligations_or_error(fcx);
-
     rcx.resolve_regions_and_report_errors();
 }
 
@@ -148,7 +149,7 @@ pub fn regionck_fn(fcx: &FnCtxt, id: ast::NodeId, decl: &ast::FnDecl, blk: &ast:
 pub fn regionck_ensure_component_tys_wf<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                                   span: Span,
                                                   component_tys: &[Ty<'tcx>]) {
-    let mut rcx = Rcx::new(fcx, Repeating(0), SubjectNode::None);
+    let mut rcx = Rcx::new(fcx, RepeatingScope(0), 0, SubjectNode::None);
     for &component_ty in component_tys {
         // Check that each type outlives the empty region. Since the
         // empty region is a subregion of all others, this can't fail
@@ -167,6 +168,9 @@ pub struct Rcx<'a, 'tcx: 'a> {
 
     region_bound_pairs: Vec<(ty::Region, GenericKind<'tcx>)>,
 
+    // id of innermost fn body id
+    body_id: ast::NodeId,
+
     // id of innermost fn or loop
     repeating_scope: ast::NodeId,
 
@@ -189,16 +193,18 @@ fn region_of_def(fcx: &FnCtxt, def: def::Def) -> ty::Region {
     }
 }
 
-pub enum RepeatingScope { Repeating(ast::NodeId) }
+struct RepeatingScope(ast::NodeId);
 pub enum SubjectNode { Subject(ast::NodeId), None }
 
 impl<'a, 'tcx> Rcx<'a, 'tcx> {
     pub fn new(fcx: &'a FnCtxt<'a, 'tcx>,
                initial_repeating_scope: RepeatingScope,
+               initial_body_id: ast::NodeId,
                subject: SubjectNode) -> Rcx<'a, 'tcx> {
-        let Repeating(initial_repeating_scope) = initial_repeating_scope;
+        let RepeatingScope(initial_repeating_scope) = initial_repeating_scope;
         Rcx { fcx: fcx,
               repeating_scope: initial_repeating_scope,
+              body_id: initial_body_id,
               subject: subject,
               region_bound_pairs: Vec::new()
         }
@@ -208,10 +214,12 @@ pub fn tcx(&self) -> &'a ty::ctxt<'tcx> {
         self.fcx.ccx.tcx
     }
 
-    pub fn set_repeating_scope(&mut self, scope: ast::NodeId) -> ast::NodeId {
-        let old_scope = self.repeating_scope;
-        self.repeating_scope = scope;
-        old_scope
+    fn set_body_id(&mut self, body_id: ast::NodeId) -> ast::NodeId {
+        mem::replace(&mut self.body_id, body_id)
+    }
+
+    fn set_repeating_scope(&mut self, scope: ast::NodeId) -> ast::NodeId {
+        mem::replace(&mut self.repeating_scope, scope)
     }
 
     /// Try to resolve the type for the given node, returning t_err if an error results.  Note that
@@ -269,9 +277,11 @@ pub fn resolve_expr_type_adjusted(&mut self, expr: &ast::Expr) -> Ty<'tcx> {
     fn visit_fn_body(&mut self,
                      id: ast::NodeId,
                      fn_decl: &ast::FnDecl,
-                     body: &ast::Block)
+                     body: &ast::Block,
+                     span: Span)
     {
         // When we enter a function, we can derive
+        debug!("visit_fn_body(id={})", id);
 
         let fn_sig_map = self.fcx.inh.fn_sig_map.borrow();
         let fn_sig = match fn_sig_map.get(&id) {
@@ -283,17 +293,24 @@ fn visit_fn_body(&mut self,
         };
 
         let len = self.region_bound_pairs.len();
-        self.relate_free_regions(&fn_sig[], body.id);
+        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.visit_block(body);
         self.visit_region_obligations(body.id);
         self.region_bound_pairs.truncate(len);
+        self.set_body_id(old_body_id);
     }
 
     fn visit_region_obligations(&mut self, node_id: ast::NodeId)
     {
         debug!("visit_region_obligations: node_id={}", node_id);
 
+        // region checking can introduce new pending obligations
+        // which, when processed, might generate new region
+        // obligations. So make sure we process those.
+        vtable::select_all_fcx_obligations_or_error(self.fcx);
+
         // Make a copy of the region obligations vec because we'll need
         // to be able to borrow the fulfillment-cx below when projecting.
         let region_obligations =
@@ -326,7 +343,8 @@ fn visit_region_obligations(&mut self, node_id: ast::NodeId)
     /// Tests: `src/test/compile-fail/regions-free-region-ordering-*.rs`
     fn relate_free_regions(&mut self,
                            fn_sig_tys: &[Ty<'tcx>],
-                           body_id: ast::NodeId) {
+                           body_id: ast::NodeId,
+                           span: Span) {
         debug!("relate_free_regions >>");
         let tcx = self.tcx();
 
@@ -335,25 +353,22 @@ fn relate_free_regions(&mut self,
             debug!("relate_free_regions(t={})", ty.repr(tcx));
             let body_scope = CodeExtent::from_node_id(body_id);
             let body_scope = ty::ReScope(body_scope);
-            let constraints =
-                regionmanip::region_wf_constraints(
-                    tcx,
-                    ty,
-                    body_scope);
-            for constraint in &constraints {
-                debug!("constraint: {}", constraint.repr(tcx));
-                match *constraint {
-                    regionmanip::RegionSubRegionConstraint(_,
-                                              ty::ReFree(free_a),
-                                              ty::ReFree(free_b)) => {
+            let implications = implicator::implications(self.fcx.infcx(), self.fcx, body_id,
+                                                        ty, body_scope, span);
+            for implication in implications {
+                debug!("implication: {}", implication.repr(tcx));
+                match implication {
+                    implicator::Implication::RegionSubRegion(_,
+                                                             ty::ReFree(free_a),
+                                                             ty::ReFree(free_b)) => {
                         tcx.region_maps.relate_free_regions(free_a, free_b);
                     }
-                    regionmanip::RegionSubRegionConstraint(_,
-                                              ty::ReFree(free_a),
-                                              ty::ReInfer(ty::ReVar(vid_b))) => {
+                    implicator::Implication::RegionSubRegion(_,
+                                                             ty::ReFree(free_a),
+                                                             ty::ReInfer(ty::ReVar(vid_b))) => {
                         self.fcx.inh.infcx.add_given(free_a, vid_b);
                     }
-                    regionmanip::RegionSubRegionConstraint(..) => {
+                    implicator::Implication::RegionSubRegion(..) => {
                         // In principle, we could record (and take
                         // advantage of) every relationship here, but
                         // we are also free not to -- it simply means
@@ -364,12 +379,13 @@ fn relate_free_regions(&mut self,
                         // relationship that arises here, but
                         // presently we do not.)
                     }
-                    regionmanip::RegionSubGenericConstraint(_, r_a, ref generic_b) => {
-                        debug!("RegionSubGenericConstraint: {} <= {}",
+                    implicator::Implication::RegionSubGeneric(_, r_a, ref generic_b) => {
+                        debug!("RegionSubGeneric: {} <= {}",
                                r_a.repr(tcx), generic_b.repr(tcx));
 
                         self.region_bound_pairs.push((r_a, generic_b.clone()));
                     }
+                    implicator::Implication::Predicate(..) => { }
                 }
             }
         }
@@ -400,8 +416,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Rcx<'a, 'tcx> {
     // regions, until regionck, as described in #3238.
 
     fn visit_fn(&mut self, _fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
-                b: &'v ast::Block, _s: Span, id: ast::NodeId) {
-        self.visit_fn_body(id, fd, b)
+                b: &'v ast::Block, span: Span, id: ast::NodeId) {
+        self.visit_fn_body(id, fd, b, span)
     }
 
     fn visit_item(&mut self, i: &ast::Item) { visit_item(self, i); }
@@ -628,7 +644,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
                     constrain_call(rcx, expr, Some(&**base),
                                    None::<ast::Expr>.iter(), true);
                     let fn_ret = // late-bound regions in overloaded method calls are instantiated
-                        ty::assert_no_late_bound_regions(rcx.tcx(), &ty::ty_fn_ret(method.ty));
+                        ty::no_late_bound_regions(rcx.tcx(), &ty::ty_fn_ret(method.ty)).unwrap();
                     fn_ret.unwrap()
                 }
                 None => rcx.resolve_node_type(base.id)
@@ -975,7 +991,7 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
                 // was applied on the base type, as that is always the case.
                 let fn_sig = ty::ty_fn_sig(method.ty);
                 let fn_sig = // late-bound regions should have been instantiated
-                    ty::assert_no_late_bound_regions(rcx.tcx(), fn_sig);
+                    ty::no_late_bound_regions(rcx.tcx(), fn_sig).unwrap();
                 let self_ty = fn_sig.inputs[0];
                 let (m, r) = match self_ty.sty {
                     ty::ty_rptr(r, ref m) => (m.mutbl, r),
@@ -1481,28 +1497,32 @@ pub fn type_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
            ty.repr(rcx.tcx()),
            region.repr(rcx.tcx()));
 
-    let constraints =
-        regionmanip::region_wf_constraints(
-            rcx.tcx(),
-            ty,
-            region);
-    for constraint in &constraints {
-        debug!("constraint: {}", constraint.repr(rcx.tcx()));
-        match *constraint {
-            regionmanip::RegionSubRegionConstraint(None, r_a, r_b) => {
+    let implications = implicator::implications(rcx.fcx.infcx(), rcx.fcx, rcx.body_id,
+                                                ty, region, origin.span());
+    for implication in implications {
+        debug!("implication: {}", implication.repr(rcx.tcx()));
+        match implication {
+            implicator::Implication::RegionSubRegion(None, r_a, r_b) => {
                 rcx.fcx.mk_subr(origin.clone(), r_a, r_b);
             }
-            regionmanip::RegionSubRegionConstraint(Some(ty), r_a, r_b) => {
+            implicator::Implication::RegionSubRegion(Some(ty), r_a, r_b) => {
                 let o1 = infer::ReferenceOutlivesReferent(ty, origin.span());
                 rcx.fcx.mk_subr(o1, r_a, r_b);
             }
-            regionmanip::RegionSubGenericConstraint(None, r_a, ref generic_b) => {
+            implicator::Implication::RegionSubGeneric(None, r_a, ref generic_b) => {
                 generic_must_outlive(rcx, origin.clone(), r_a, generic_b);
             }
-            regionmanip::RegionSubGenericConstraint(Some(ty), r_a, ref generic_b) => {
+            implicator::Implication::RegionSubGeneric(Some(ty), r_a, ref generic_b) => {
                 let o1 = infer::ReferenceOutlivesReferent(ty, origin.span());
                 generic_must_outlive(rcx, o1, r_a, generic_b);
             }
+            implicator::Implication::Predicate(def_id, predicate) => {
+                let cause = traits::ObligationCause::new(origin.span(),
+                                                         rcx.body_id,
+                                                         traits::ItemObligation(def_id));
+                let obligation = traits::Obligation::new(cause, predicate);
+                rcx.fcx.register_predicate(obligation);
+            }
         }
     }
 }
diff --git a/src/librustc_typeck/check/regionmanip.rs b/src/librustc_typeck/check/regionmanip.rs
deleted file mode 100644 (file)
index 2095705..0000000
+++ /dev/null
@@ -1,396 +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.
-
-// #![warn(deprecated_mode)]
-
-pub use self::WfConstraint::*;
-
-use astconv::object_region_bounds;
-use middle::infer::GenericKind;
-use middle::subst::{ParamSpace, Subst, Substs};
-use middle::ty::{self, Ty};
-use middle::ty_fold::{TypeFolder};
-
-use syntax::ast;
-
-use util::ppaux::Repr;
-
-// Helper functions related to manipulating region types.
-
-pub enum WfConstraint<'tcx> {
-    RegionSubRegionConstraint(Option<Ty<'tcx>>, ty::Region, ty::Region),
-    RegionSubGenericConstraint(Option<Ty<'tcx>>, ty::Region, GenericKind<'tcx>),
-}
-
-struct Wf<'a, 'tcx: 'a> {
-    tcx: &'a ty::ctxt<'tcx>,
-    stack: Vec<(ty::Region, Option<Ty<'tcx>>)>,
-    out: Vec<WfConstraint<'tcx>>,
-}
-
-/// This routine computes the well-formedness constraints that must hold for the type `ty` to
-/// appear in a context with lifetime `outer_region`
-pub fn region_wf_constraints<'tcx>(
-    tcx: &ty::ctxt<'tcx>,
-    ty: Ty<'tcx>,
-    outer_region: ty::Region)
-    -> Vec<WfConstraint<'tcx>>
-{
-    let mut stack = Vec::new();
-    stack.push((outer_region, None));
-    let mut wf = Wf { tcx: tcx,
-                      stack: stack,
-                      out: Vec::new() };
-    wf.accumulate_from_ty(ty);
-    wf.out
-}
-
-impl<'a, 'tcx> Wf<'a, 'tcx> {
-    fn accumulate_from_ty(&mut self, ty: Ty<'tcx>) {
-        debug!("Wf::accumulate_from_ty(ty={})",
-               ty.repr(self.tcx));
-
-        match ty.sty {
-            ty::ty_bool |
-            ty::ty_char |
-            ty::ty_int(..) |
-            ty::ty_uint(..) |
-            ty::ty_float(..) |
-            ty::ty_bare_fn(..) |
-            ty::ty_err |
-            ty::ty_str => {
-                // No borrowed content reachable here.
-            }
-
-            ty::ty_closure(_, region, _) => {
-                // An "closure type" is basically
-                // modeled here as equivalent to a struct like
-                //
-                //     struct TheClosure<'b> {
-                //         ...
-                //     }
-                //
-                // where the `'b` is the lifetime bound of the
-                // contents (i.e., all contents must outlive 'b).
-                //
-                // Even though closures are glorified structs
-                // of upvars, we do not need to consider them as they
-                // can't generate any new constraints.  The
-                // substitutions on the closure are equal to the free
-                // substitutions of the enclosing parameter
-                // environment.  An upvar captured by value has the
-                // same type as the original local variable which is
-                // already checked for consistency.  If the upvar is
-                // captured by reference it must also outlive the
-                // region bound on the closure, but this is explicitly
-                // handled by logic in regionck.
-                self.push_region_constraint_from_top(*region);
-            }
-
-            ty::ty_trait(ref t) => {
-                let required_region_bounds =
-                    object_region_bounds(self.tcx, &t.principal, t.bounds.builtin_bounds);
-                self.accumulate_from_object_ty(ty, t.bounds.region_bound, required_region_bounds)
-            }
-
-            ty::ty_enum(def_id, substs) |
-            ty::ty_struct(def_id, substs) => {
-                let item_scheme = ty::lookup_item_type(self.tcx, def_id);
-                self.accumulate_from_adt(ty, def_id, &item_scheme.generics, substs)
-            }
-
-            ty::ty_vec(t, _) |
-            ty::ty_ptr(ty::mt { ty: t, .. }) |
-            ty::ty_uniq(t) => {
-                self.accumulate_from_ty(t)
-            }
-
-            ty::ty_rptr(r_b, mt) => {
-                self.accumulate_from_rptr(ty, *r_b, mt.ty);
-            }
-
-            ty::ty_param(p) => {
-                self.push_param_constraint_from_top(p);
-            }
-
-            ty::ty_projection(ref data) => {
-                // `<T as TraitRef<..>>::Name`
-
-                self.push_projection_constraint_from_top(data);
-            }
-
-            ty::ty_tup(ref tuptys) => {
-                for &tupty in tuptys {
-                    self.accumulate_from_ty(tupty);
-                }
-            }
-
-            ty::ty_infer(_) => {
-                // This should not happen, BUT:
-                //
-                //   Currently we uncover region relationships on
-                //   entering the fn check. We should do this after
-                //   the fn check, then we can call this case a bug().
-            }
-
-            ty::ty_open(_) => {
-                self.tcx.sess.bug(
-                    &format!("Unexpected type encountered while doing wf check: {}",
-                            ty.repr(self.tcx))[]);
-            }
-        }
-    }
-
-    fn accumulate_from_rptr(&mut self,
-                            ty: Ty<'tcx>,
-                            r_b: ty::Region,
-                            ty_b: Ty<'tcx>) {
-        // We are walking down a type like this, and current
-        // position is indicated by caret:
-        //
-        //     &'a &'b ty_b
-        //         ^
-        //
-        // At this point, top of stack will be `'a`. We must
-        // require that `'a <= 'b`.
-
-        self.push_region_constraint_from_top(r_b);
-
-        // Now we push `'b` onto the stack, because it must
-        // constrain any borrowed content we find within `T`.
-
-        self.stack.push((r_b, Some(ty)));
-        self.accumulate_from_ty(ty_b);
-        self.stack.pop().unwrap();
-    }
-
-    /// Pushes a constraint that `r_b` must outlive the top region on the stack.
-    fn push_region_constraint_from_top(&mut self,
-                                       r_b: ty::Region) {
-
-        // Indicates that we have found borrowed content with a lifetime
-        // of at least `r_b`. This adds a constraint that `r_b` must
-        // outlive the region `r_a` on top of the stack.
-        //
-        // As an example, imagine walking a type like:
-        //
-        //     &'a &'b T
-        //         ^
-        //
-        // when we hit the inner pointer (indicated by caret), `'a` will
-        // be on top of stack and `'b` will be the lifetime of the content
-        // we just found. So we add constraint that `'a <= 'b`.
-
-        let &(r_a, opt_ty) = self.stack.last().unwrap();
-        self.push_sub_region_constraint(opt_ty, r_a, r_b);
-    }
-
-    /// Pushes a constraint that `r_a <= r_b`, due to `opt_ty`
-    fn push_sub_region_constraint(&mut self,
-                                  opt_ty: Option<Ty<'tcx>>,
-                                  r_a: ty::Region,
-                                  r_b: ty::Region) {
-        self.out.push(RegionSubRegionConstraint(opt_ty, r_a, r_b));
-    }
-
-    /// Pushes a constraint that `param_ty` must outlive the top region on the stack.
-    fn push_param_constraint_from_top(&mut self,
-                                      param_ty: ty::ParamTy) {
-        let &(region, opt_ty) = self.stack.last().unwrap();
-        self.push_param_constraint(region, opt_ty, param_ty);
-    }
-
-    /// Pushes a constraint that `projection_ty` must outlive the top region on the stack.
-    fn push_projection_constraint_from_top(&mut self,
-                                           projection_ty: &ty::ProjectionTy<'tcx>) {
-        let &(region, opt_ty) = self.stack.last().unwrap();
-        self.out.push(RegionSubGenericConstraint(
-            opt_ty, region, GenericKind::Projection(projection_ty.clone())));
-    }
-
-    /// Pushes a constraint that `region <= param_ty`, due to `opt_ty`
-    fn push_param_constraint(&mut self,
-                             region: ty::Region,
-                             opt_ty: Option<Ty<'tcx>>,
-                             param_ty: ty::ParamTy) {
-        self.out.push(RegionSubGenericConstraint(
-            opt_ty, region, GenericKind::Param(param_ty)));
-    }
-
-    fn accumulate_from_adt(&mut self,
-                           ty: Ty<'tcx>,
-                           def_id: ast::DefId,
-                           generics: &ty::Generics<'tcx>,
-                           substs: &Substs<'tcx>)
-    {
-        // The generic declarations from the type, appropriately
-        // substituted for the actual substitutions.
-        let generics = generics.subst(self.tcx, substs);
-
-        // Variance of each type/region parameter.
-        let variances = ty::item_variances(self.tcx, def_id);
-
-        for &space in &ParamSpace::all() {
-            let region_params = substs.regions().get_slice(space);
-            let region_variances = variances.regions.get_slice(space);
-            let region_param_defs = generics.regions.get_slice(space);
-            assert_eq!(region_params.len(), region_variances.len());
-            for (&region_param, (&region_variance, region_param_def)) in
-                region_params.iter().zip(
-                    region_variances.iter().zip(
-                        region_param_defs.iter()))
-            {
-                match region_variance {
-                    ty::Covariant | ty::Bivariant => {
-                        // Ignore covariant or bivariant region
-                        // parameters.  To understand why, consider a
-                        // struct `Foo<'a>`. If `Foo` contains any
-                        // references with lifetime `'a`, then `'a` must
-                        // be at least contravariant (and possibly
-                        // invariant). The only way to have a covariant
-                        // result is if `Foo` contains only a field with a
-                        // type like `fn() -> &'a T`; i.e., a bare
-                        // function that can produce a reference of
-                        // lifetime `'a`. In this case, there is no
-                        // *actual data* with lifetime `'a` that is
-                        // reachable. (Presumably this bare function is
-                        // really returning static data.)
-                    }
-
-                    ty::Contravariant | ty::Invariant => {
-                        // If the parameter is contravariant or
-                        // invariant, there may indeed be reachable
-                        // data with this lifetime. See other case for
-                        // more details.
-                        self.push_region_constraint_from_top(region_param);
-                    }
-                }
-
-                for &region_bound in &region_param_def.bounds {
-                    // The type declared a constraint like
-                    //
-                    //     'b : 'a
-                    //
-                    // which means that `'a <= 'b` (after
-                    // substitution).  So take the region we
-                    // substituted for `'a` (`region_bound`) and make
-                    // it a subregion of the region we substituted
-                    // `'b` (`region_param`).
-                    self.push_sub_region_constraint(
-                        Some(ty), region_bound, region_param);
-                }
-            }
-
-            let types = substs.types.get_slice(space);
-            let type_variances = variances.types.get_slice(space);
-            let type_param_defs = generics.types.get_slice(space);
-            assert_eq!(types.len(), type_variances.len());
-            for (&type_param_ty, (&variance, type_param_def)) in
-                types.iter().zip(
-                    type_variances.iter().zip(
-                        type_param_defs.iter()))
-            {
-                debug!("type_param_ty={} variance={}",
-                       type_param_ty.repr(self.tcx),
-                       variance.repr(self.tcx));
-
-                match variance {
-                    ty::Contravariant | ty::Bivariant => {
-                        // As above, except that in this it is a
-                        // *contravariant* reference that indices that no
-                        // actual data of type T is reachable.
-                    }
-
-                    ty::Covariant | ty::Invariant => {
-                        self.accumulate_from_ty(type_param_ty);
-                    }
-                }
-
-                // Inspect bounds on this type parameter for any
-                // region bounds.
-                for &r in &type_param_def.bounds.region_bounds {
-                    self.stack.push((r, Some(ty)));
-                    self.accumulate_from_ty(type_param_ty);
-                    self.stack.pop().unwrap();
-                }
-            }
-        }
-    }
-
-    fn accumulate_from_object_ty(&mut self,
-                                 ty: Ty<'tcx>,
-                                 region_bound: ty::Region,
-                                 required_region_bounds: Vec<ty::Region>)
-    {
-        // Imagine a type like this:
-        //
-        //     trait Foo { }
-        //     trait Bar<'c> : 'c { }
-        //
-        //     &'b (Foo+'c+Bar<'d>)
-        //         ^
-        //
-        // In this case, the following relationships must hold:
-        //
-        //     'b <= 'c
-        //     'd <= 'c
-        //
-        // The first conditions is due to the normal region pointer
-        // rules, which say that a reference cannot outlive its
-        // referent.
-        //
-        // The final condition may be a bit surprising. In particular,
-        // you may expect that it would have been `'c <= 'd`, since
-        // usually lifetimes of outer things are conservative
-        // approximations for inner things. However, it works somewhat
-        // differently with trait objects: here the idea is that if the
-        // user specifies a region bound (`'c`, in this case) it is the
-        // "master bound" that *implies* that bounds from other traits are
-        // all met. (Remember that *all bounds* in a type like
-        // `Foo+Bar+Zed` must be met, not just one, hence if we write
-        // `Foo<'x>+Bar<'y>`, we know that the type outlives *both* 'x and
-        // 'y.)
-        //
-        // Note: in fact we only permit builtin traits, not `Bar<'d>`, I
-        // am looking forward to the future here.
-
-        // The content of this object type must outlive
-        // `bounds.region_bound`:
-        let r_c = region_bound;
-        self.push_region_constraint_from_top(r_c);
-
-        // And then, in turn, to be well-formed, the
-        // `region_bound` that user specified must imply the
-        // region bounds required from all of the trait types:
-        for &r_d in &required_region_bounds {
-            // Each of these is an instance of the `'c <= 'b`
-            // constraint above
-            self.out.push(RegionSubRegionConstraint(Some(ty), r_d, r_c));
-        }
-    }
-}
-
-impl<'tcx> Repr<'tcx> for WfConstraint<'tcx> {
-    fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
-        match *self {
-            RegionSubRegionConstraint(_, ref r_a, ref r_b) => {
-                format!("RegionSubRegionConstraint({}, {})",
-                        r_a.repr(tcx),
-                        r_b.repr(tcx))
-            }
-
-            RegionSubGenericConstraint(_, ref r, ref p) => {
-                format!("RegionSubGenericConstraint({}, {})",
-                        r.repr(tcx),
-                        p.repr(tcx))
-            }
-        }
-    }
-}
index 94670305be7557edcb27a449161c37014b9edd00..d124282d391281c65137ec6c2a1cccad466a3ecc 100644 (file)
@@ -97,14 +97,10 @@ fn check_item_well_formed(&mut self, item: &ast::Item) {
                 self.check_item_type(item);
             }
             ast::ItemStruct(ref struct_def, _) => {
-                self.check_type_defn(item, |fcx| {
-                    vec![struct_variant(fcx, &**struct_def)]
-                });
+                self.check_type_defn(item, |fcx| vec![struct_variant(fcx, &**struct_def)]);
             }
             ast::ItemEnum(ref enum_def, _) => {
-                self.check_type_defn(item, |fcx| {
-                    enum_variants(fcx, enum_def)
-                });
+                self.check_type_defn(item, |fcx| enum_variants(fcx, enum_def));
             }
             ast::ItemTrait(..) => {
                 let trait_predicates =
@@ -578,8 +574,8 @@ fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                     // the regions in the argument types come from the
                     // enum def'n, and hence will all be early bound
                     let arg_tys =
-                        ty::assert_no_late_bound_regions(
-                            fcx.tcx(), &ty::ty_fn_args(ctor_ty));
+                        ty::no_late_bound_regions(
+                            fcx.tcx(), &ty::ty_fn_args(ctor_ty)).unwrap();
                     AdtVariant {
                         fields: args.iter().enumerate().map(|(index, arg)| {
                             let arg_ty = arg_tys[index];
index b09c3f730fc6476782f4d06a351813bfa3c6973c..bab734db126505efa94ec072d6bd92d91fb2f6de 100644 (file)
 #![feature(env)]
 #![feature(hash)]
 #![feature(int_uint)]
-#![feature(io)]
+#![feature(old_io)]
 #![feature(libc)]
 #![feature(os)]
-#![feature(path)]
+#![feature(old_path)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(std_misc)]
 #![feature(test)]
 #![feature(unicode)]
+#![feature(str_words)]
 
 extern crate arena;
 extern crate getopts;
@@ -55,6 +56,7 @@
 use std::old_io::File;
 use std::old_io;
 use std::rc::Rc;
+use std::sync::mpsc::channel;
 use externalfiles::ExternalHtml;
 use serialize::Decodable;
 use serialize::json::{self, Json};
@@ -125,8 +127,8 @@ pub fn main() {
     let res = std::thread::Builder::new().stack_size(STACK_SIZE).scoped(move || {
         let s = env::args().collect::<Vec<_>>();
         main_args(&s)
-    }).join();
-    env::set_exit_status(res.ok().unwrap() as i32);
+    }).unwrap().join();
+    env::set_exit_status(res as i32);
 }
 
 pub fn opts() -> Vec<getopts::OptGroup> {
@@ -365,12 +367,14 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
     let cr = Path::new(cratefile);
     info!("starting to run rustc");
 
-    let (mut krate, analysis) = std::thread::Thread::scoped(move || {
+    let (tx, rx) = channel();
+    std::thread::spawn(move || {
         use rustc::session::config::Input;
 
         let cr = cr;
-        core::run_core(paths, cfgs, externs, Input::File(cr), triple)
+        tx.send(core::run_core(paths, cfgs, externs, Input::File(cr), triple)).unwrap();
     }).join().map_err(|_| "rustc failed").unwrap();
+    let (mut krate, analysis) = rx.recv().unwrap();
     info!("finished with rustc");
     let mut analysis = Some(analysis);
     ANALYSISKEY.with(|s| {
index abd73fcfb70289981213f7ef579fc4f657ab7268..722f14fa6d4c7b0dcff44ad75f8d7f7bfa8686c2 100644 (file)
@@ -293,7 +293,7 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
             let mut a: Vec<clean::Attribute> = i.attrs.iter().filter(|&a| match a {
                 &clean::NameValue(ref x, _) if "doc" == *x => false,
                 _ => true
-            }).map(|x| x.clone()).collect();
+            }).cloned().collect();
             if docstr.len() > 0 {
                 a.push(clean::NameValue("doc".to_string(), docstr));
             }
index 09df9fc8cbb66bc3b12d9abea82537e03c3457ba..bf14b86ebd1e39e21189cd0097dff9072a15fcd7 100644 (file)
@@ -15,7 +15,7 @@
 use std::old_io;
 use std::env;
 use std::str;
-use std::thread::Thread;
+use std::thread;
 use std::thunk::Thunk;
 
 use std::collections::{HashSet, HashMap};
@@ -142,7 +142,7 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
     let w1 = old_io::ChanWriter::new(tx);
     let w2 = w1.clone();
     let old = old_io::stdio::set_stderr(box w1);
-    Thread::spawn(move || {
+    thread::spawn(move || {
         let mut p = old_io::ChanReader::new(rx);
         let mut err = match old {
             Some(old) => {
index ac1a02854124afda82d3183550ebd9e7c63a6933..c52b0bab1fa8b800129e3688e7423bca40dba82d 100644 (file)
@@ -333,7 +333,7 @@ pub fn visit_item(&mut self, item: &ast::Item,
                     name: name,
                     items: items.clone(),
                     generics: gen.clone(),
-                    bounds: b.iter().map(|x| (*x).clone()).collect(),
+                    bounds: b.iter().cloned().collect(),
                     id: item.id,
                     attrs: item.attrs.clone(),
                     whence: item.span,
index daa358647d8e6bec3bcea870fb089d3f74217046..d79a31718555357fc8a06df0a8872388e0ed202e 100644 (file)
@@ -371,7 +371,7 @@ fn from_error(err: fmt::Error) -> EncoderError { EncoderError::FmtError(err) }
 pub type EncodeResult = Result<(), EncoderError>;
 pub type DecodeResult<T> = Result<T, DecoderError>;
 
-fn escape_str(wr: &mut fmt::Writer, v: &str) -> EncodeResult {
+fn escape_str(wr: &mut fmt::Write, v: &str) -> EncodeResult {
     try!(wr.write_str("\""));
 
     let mut start = 0;
@@ -433,14 +433,14 @@ fn escape_str(wr: &mut fmt::Writer, v: &str) -> EncodeResult {
     Ok(())
 }
 
-fn escape_char(writer: &mut fmt::Writer, v: char) -> EncodeResult {
+fn escape_char(writer: &mut fmt::Write, v: char) -> EncodeResult {
     let mut buf = [0; 4];
     let n = v.encode_utf8(&mut buf).unwrap();
     let buf = unsafe { str::from_utf8_unchecked(&buf[..n]) };
     escape_str(writer, buf)
 }
 
-fn spaces(wr: &mut fmt::Writer, mut n: uint) -> EncodeResult {
+fn spaces(wr: &mut fmt::Write, mut n: uint) -> EncodeResult {
     const BUF: &'static str = "                ";
 
     while n >= BUF.len() {
@@ -464,14 +464,14 @@ fn fmt_number_or_null(v: f64) -> string::String {
 
 /// A structure for implementing serialization to JSON.
 pub struct Encoder<'a> {
-    writer: &'a mut (fmt::Writer+'a),
+    writer: &'a mut (fmt::Write+'a),
     is_emitting_map_key: bool,
 }
 
 impl<'a> Encoder<'a> {
     /// Creates a new JSON encoder whose output will be written to the writer
     /// specified.
-    pub fn new(writer: &'a mut fmt::Writer) -> Encoder<'a> {
+    pub fn new(writer: &'a mut fmt::Write) -> Encoder<'a> {
         Encoder { writer: writer, is_emitting_map_key: false, }
     }
 }
@@ -709,7 +709,7 @@ fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
 /// Another encoder for JSON, but prints out human-readable JSON instead of
 /// compact data
 pub struct PrettyEncoder<'a> {
-    writer: &'a mut (fmt::Writer+'a),
+    writer: &'a mut (fmt::Write+'a),
     curr_indent: uint,
     indent: uint,
     is_emitting_map_key: bool,
@@ -717,7 +717,7 @@ pub struct PrettyEncoder<'a> {
 
 impl<'a> PrettyEncoder<'a> {
     /// Creates a new encoder whose output will be written to the specified writer
-    pub fn new(writer: &'a mut fmt::Writer) -> PrettyEncoder<'a> {
+    pub fn new(writer: &'a mut fmt::Write) -> PrettyEncoder<'a> {
         PrettyEncoder {
             writer: writer,
             curr_indent: 0,
@@ -2527,7 +2527,7 @@ struct FormatShim<'a, 'b: 'a> {
     inner: &'a mut fmt::Formatter<'b>,
 }
 
-impl<'a, 'b> fmt::Writer for FormatShim<'a, 'b> {
+impl<'a, 'b> fmt::Write for FormatShim<'a, 'b> {
     fn write_str(&mut self, s: &str) -> fmt::Result {
         match self.inner.write_str(s) {
             Ok(_) => Ok(()),
index 6cada2e5614ba0abe9b32472484661bd5e8df336..853da598ab5be8aebeaa86bf8718e4c9882b0eab 100644 (file)
@@ -29,8 +29,8 @@
 #![feature(collections)]
 #![feature(core)]
 #![feature(int_uint)]
-#![feature(io)]
-#![feature(path)]
+#![feature(old_io)]
+#![feature(old_path)]
 #![feature(hash)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
index 0a3abd5d1acc3cbe3787d7478d06d77e0dadc598..4d38d17576ddb2a15ee7fe13624ff1a993a979e6 100644 (file)
 
 //! Operations on ASCII strings and characters
 
-#![unstable(feature = "std_misc",
-            reason = "unsure about placement and naming")]
+#![stable(feature = "rust1", since = "1.0.0")]
 
-use iter::IteratorExt;
-use ops::FnMut;
-use slice::SliceExt;
-use str::StrExt;
-use string::String;
-use vec::Vec;
+use prelude::v1::*;
+
+use mem;
+use iter::Range;
 
 /// Extension methods for ASCII-subset only operations on owned strings
 #[unstable(feature = "std_misc",
@@ -38,31 +35,50 @@ pub trait OwnedAsciiExt {
 }
 
 /// Extension methods for ASCII-subset only operations on string slices
-#[unstable(feature = "std_misc",
-           reason = "would prefer to do this in a more general way")]
-pub trait AsciiExt<T = Self> {
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait AsciiExt {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Owned;
+
     /// Check if within the ASCII range.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn is_ascii(&self) -> bool;
 
     /// Makes a copy of the string in ASCII upper case:
     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
     /// but non-ASCII letters are unchanged.
-    fn to_ascii_uppercase(&self) -> T;
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn to_ascii_uppercase(&self) -> Self::Owned;
 
     /// Makes a copy of the string in ASCII lower case:
     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
     /// but non-ASCII letters are unchanged.
-    fn to_ascii_lowercase(&self) -> T;
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn to_ascii_lowercase(&self) -> Self::Owned;
 
     /// Check that two strings are an ASCII case-insensitive match.
     /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
     /// but without allocating and copying temporary strings.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn eq_ignore_ascii_case(&self, other: &Self) -> bool;
+
+    /// Convert this type to its ASCII upper case equivalent in-place.
+    ///
+    /// See `to_ascii_uppercase` for more information.
+    #[unstable(feature = "ascii")]
+    fn make_ascii_uppercase(&mut self);
+
+    /// Convert this type to its ASCII lower case equivalent in-place.
+    ///
+    /// See `to_ascii_lowercase` for more information.
+    #[unstable(feature = "ascii")]
+    fn make_ascii_lowercase(&mut self);
 }
 
-#[unstable(feature = "std_misc",
-           reason = "would prefer to do this in a more general way")]
-impl AsciiExt<String> for str {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsciiExt for str {
+    type Owned = String;
+
     #[inline]
     fn is_ascii(&self) -> bool {
         self.bytes().all(|b| b.is_ascii())
@@ -70,20 +86,28 @@ fn is_ascii(&self) -> bool {
 
     #[inline]
     fn to_ascii_uppercase(&self) -> String {
-        // Vec<u8>::to_ascii_uppercase() preserves the UTF-8 invariant.
-        unsafe { String::from_utf8_unchecked(self.as_bytes().to_ascii_uppercase()) }
+        self.to_string().into_ascii_uppercase()
     }
 
     #[inline]
     fn to_ascii_lowercase(&self) -> String {
-        // Vec<u8>::to_ascii_lowercase() preserves the UTF-8 invariant.
-        unsafe { String::from_utf8_unchecked(self.as_bytes().to_ascii_lowercase()) }
+        self.to_string().into_ascii_lowercase()
     }
 
     #[inline]
     fn eq_ignore_ascii_case(&self, other: &str) -> bool {
         self.as_bytes().eq_ignore_ascii_case(other.as_bytes())
     }
+
+    fn make_ascii_uppercase(&mut self) {
+        let me: &mut [u8] = unsafe { mem::transmute(self) };
+        me.make_ascii_uppercase()
+    }
+
+    fn make_ascii_lowercase(&mut self) {
+        let me: &mut [u8] = unsafe { mem::transmute(self) };
+        me.make_ascii_lowercase()
+    }
 }
 
 #[unstable(feature = "std_misc",
@@ -102,9 +126,9 @@ fn into_ascii_lowercase(self) -> String {
     }
 }
 
-#[unstable(feature = "std_misc",
-           reason = "would prefer to do this in a more general way")]
-impl AsciiExt<Vec<u8>> for [u8] {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsciiExt for [u8] {
+    type Owned = Vec<u8>;
     #[inline]
     fn is_ascii(&self) -> bool {
         self.iter().all(|b| b.is_ascii())
@@ -112,12 +136,12 @@ fn is_ascii(&self) -> bool {
 
     #[inline]
     fn to_ascii_uppercase(&self) -> Vec<u8> {
-        self.iter().map(|b| b.to_ascii_uppercase()).collect()
+        self.to_vec().into_ascii_uppercase()
     }
 
     #[inline]
     fn to_ascii_lowercase(&self) -> Vec<u8> {
-        self.iter().map(|b| b.to_ascii_lowercase()).collect()
+        self.to_vec().into_ascii_lowercase()
     }
 
     #[inline]
@@ -127,6 +151,18 @@ fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool {
             a.eq_ignore_ascii_case(b)
         })
     }
+
+    fn make_ascii_uppercase(&mut self) {
+        for byte in self {
+            byte.make_ascii_uppercase();
+        }
+    }
+
+    fn make_ascii_lowercase(&mut self) {
+        for byte in self {
+            byte.make_ascii_lowercase();
+        }
+    }
 }
 
 #[unstable(feature = "std_misc",
@@ -134,48 +170,39 @@ fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool {
 impl OwnedAsciiExt for Vec<u8> {
     #[inline]
     fn into_ascii_uppercase(mut self) -> Vec<u8> {
-        for byte in &mut self {
-            *byte = byte.to_ascii_uppercase();
-        }
+        self.make_ascii_uppercase();
         self
     }
 
     #[inline]
     fn into_ascii_lowercase(mut self) -> Vec<u8> {
-        for byte in &mut self {
-            *byte = byte.to_ascii_lowercase();
-        }
+        self.make_ascii_lowercase();
         self
     }
 }
 
-#[unstable(feature = "std_misc",
-           reason = "would prefer to do this in a more general way")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl AsciiExt for u8 {
+    type Owned = u8;
     #[inline]
-    fn is_ascii(&self) -> bool {
-        *self & 128 == 0u8
-    }
-
+    fn is_ascii(&self) -> bool { *self & 128 == 0u8 }
     #[inline]
-    fn to_ascii_uppercase(&self) -> u8 {
-        ASCII_UPPERCASE_MAP[*self as usize]
-    }
-
+    fn to_ascii_uppercase(&self) -> u8 { ASCII_UPPERCASE_MAP[*self as usize] }
     #[inline]
-    fn to_ascii_lowercase(&self) -> u8 {
-        ASCII_LOWERCASE_MAP[*self as usize]
-    }
-
+    fn to_ascii_lowercase(&self) -> u8 { ASCII_LOWERCASE_MAP[*self as usize] }
     #[inline]
     fn eq_ignore_ascii_case(&self, other: &u8) -> bool {
         self.to_ascii_lowercase() == other.to_ascii_lowercase()
     }
+    #[inline]
+    fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); }
+    #[inline]
+    fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); }
 }
 
-#[unstable(feature = "std_misc",
-           reason = "would prefer to do this in a more general way")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl AsciiExt for char {
+    type Owned = char;
     #[inline]
     fn is_ascii(&self) -> bool {
         *self as u32 <= 0x7F
@@ -203,6 +230,19 @@ fn to_ascii_lowercase(&self) -> char {
     fn eq_ignore_ascii_case(&self, other: &char) -> bool {
         self.to_ascii_lowercase() == other.to_ascii_lowercase()
     }
+
+    #[inline]
+    fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); }
+    #[inline]
+    fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); }
+}
+
+/// An iterator over the escaped version of a byte, constructed via
+/// `std::ascii::escape_default`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct EscapeDefault {
+    range: Range<usize>,
+    data: [u8; 4],
 }
 
 /// Returns a 'default' ASCII and C++11-like literal escape of a `u8`
@@ -214,34 +254,46 @@ fn eq_ignore_ascii_case(&self, other: &char) -> bool {
 /// - Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
 /// - Single-quote, double-quote and backslash chars are backslash-escaped.
 /// - Any other chars in the range [0x20,0x7e] are not escaped.
-/// - Any other chars are given hex escapes.
+/// - Any other chars are given hex escapes of the form '\xNN'.
 /// - Unicode escapes are never generated by this function.
-#[unstable(feature = "std_misc",
-           reason = "needs to be updated to use an iterator")]
-pub fn escape_default<F>(c: u8, mut f: F) where
-    F: FnMut(u8),
-{
-    match c {
-        b'\t' => { f(b'\\'); f(b't'); }
-        b'\r' => { f(b'\\'); f(b'r'); }
-        b'\n' => { f(b'\\'); f(b'n'); }
-        b'\\' => { f(b'\\'); f(b'\\'); }
-        b'\'' => { f(b'\\'); f(b'\''); }
-        b'"'  => { f(b'\\'); f(b'"'); }
-        b'\x20' ... b'\x7e' => { f(c); }
-        _ => {
-            f(b'\\');
-            f(b'x');
-            for &offset in &[4u, 0u] {
-                match ((c as i32) >> offset) & 0xf {
-                    i @ 0 ... 9 => f(b'0' + (i as u8)),
-                    i => f(b'a' + (i as u8 - 10)),
-                }
-            }
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn escape_default(c: u8) -> EscapeDefault {
+    let (data, len) = match c {
+        b'\t' => ([b'\\', b't', 0, 0], 2),
+        b'\r' => ([b'\\', b'r', 0, 0], 2),
+        b'\n' => ([b'\\', b'n', 0, 0], 2),
+        b'\\' => ([b'\\', b'\\', 0, 0], 2),
+        b'\'' => ([b'\\', b'\'', 0, 0], 2),
+        b'"' => ([b'\\', b'"', 0, 0], 2),
+        b'\x20' ... b'\x7e' => ([c, 0, 0, 0], 1),
+        _ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4),
+    };
+
+    return EscapeDefault { range: range(0, len), data: data };
+
+    fn hexify(b: u8) -> u8 {
+        match b {
+            0 ... 9 => b'0' + b,
+            _ => b'a' + b - 10,
         }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Iterator for EscapeDefault {
+    type Item = u8;
+    fn next(&mut self) -> Option<u8> { self.range.next().map(|i| self.data[i]) }
+    fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl DoubleEndedIterator for EscapeDefault {
+    fn next_back(&mut self) -> Option<u8> {
+        self.range.next_back().map(|i| self.data[i])
+    }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl ExactSizeIterator for EscapeDefault {}
+
 static ASCII_LOWERCASE_MAP: [u8; 256] = [
     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
index 241e409910f366b859af95528b99f87ac85afb43..1b9f8b9901723af27cffd7df2a72aed7c93794d9 100644 (file)
@@ -1372,21 +1372,7 @@ enum VacantEntryState<K, V, M> {
     NoElem(EmptyBucket<K, V, M>),
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-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 IntoIter = Iter<'a, K, V>;
-
-    fn into_iter(self) -> Iter<'a, K, V> {
-        self.iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[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>,
@@ -1400,21 +1386,7 @@ fn into_iter(self) -> Iter<'a, K, V> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-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 IntoIter = IterMut<'a, K, V>;
-
-    fn into_iter(mut self) -> IterMut<'a, K, V> {
-        self.iter_mut()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[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>,
@@ -1428,21 +1400,7 @@ fn into_iter(mut self) -> IterMut<'a, K, V> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-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 IntoIter = IntoIter<K, V>;
-
-    fn into_iter(self) -> IntoIter<K, V> {
-        self.into_iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[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>,
index 300e208931765087bea28a51755e4399914cf66a..5fbbcb3b347afefdeba9ac386a0d62e16c5b6a0b 100644 (file)
@@ -835,21 +835,7 @@ pub struct Union<'a, T: 'a, S: 'a> {
     iter: Chain<Iter<'a, T>, Difference<'a, T, S>>
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-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 IntoIter = Iter<'a, T>;
-
-    fn into_iter(self) -> Iter<'a, T> {
-        self.iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[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>,
@@ -863,21 +849,7 @@ fn into_iter(self) -> Iter<'a, T> {
     }
 }
 
-// NOTE(stage0): remove impl after a snapshot
-#[cfg(stage0)]
-impl<T, S, H> IntoIterator for HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    type IntoIter = IntoIter<T>;
-
-    fn into_iter(self) -> IntoIter<T> {
-        self.into_iter()
-    }
-}
-
-#[cfg(not(stage0))]  // NOTE(stage0): remove cfg after a snapshot
+#[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>,
index ea18838211f26b37b84f87ab94bc1695e57feda8..8676586e7dc2a7e32971773e026af9537bdbea25 100644 (file)
@@ -488,12 +488,20 @@ fn next(&mut self) -> Option<String> {
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
 
+impl ExactSizeIterator for Args {
+    fn len(&self) -> usize { self.inner.len() }
+}
+
 impl Iterator for ArgsOs {
     type Item = OsString;
     fn next(&mut self) -> Option<OsString> { self.inner.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
 
+impl ExactSizeIterator for ArgsOs {
+    fn len(&self) -> usize { self.inner.len() }
+}
+
 /// Returns the page size of the current architecture in bytes.
 pub fn page_size() -> usize {
     os_imp::page_size()
@@ -918,7 +926,7 @@ fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
     #[cfg(unix)]
     fn join_paths_unix() {
         fn test_eq(input: &[&str], output: &str) -> bool {
-            &*join_paths(input.iter().map(|s| *s)).unwrap() ==
+            &*join_paths(input.iter().cloned()).unwrap() ==
                 OsStr::from_str(output)
         }
 
@@ -927,14 +935,14 @@ fn test_eq(input: &[&str], output: &str) -> bool {
                          "/bin:/usr/bin:/usr/local/bin"));
         assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""],
                          ":/bin:::/usr/bin:"));
-        assert!(join_paths(["/te:st"].iter().map(|s| *s)).is_err());
+        assert!(join_paths(["/te:st"].iter().cloned()).is_err());
     }
 
     #[test]
     #[cfg(windows)]
     fn join_paths_windows() {
         fn test_eq(input: &[&str], output: &str) -> bool {
-            &*join_paths(input.iter().map(|s| *s)).unwrap() ==
+            &*join_paths(input.iter().cloned()).unwrap() ==
                 OsStr::from_str(output)
         }
 
@@ -945,6 +953,6 @@ fn test_eq(input: &[&str], output: &str) -> bool {
                         r";c:\windows;;;c:\;"));
         assert!(test_eq(&[r"c:\te;st", r"c:\"],
                         r#""c:\te;st";c:\"#));
-        assert!(join_paths([r#"c:\te"st"#].iter().map(|s| *s)).is_err());
+        assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err());
     }
     }
index 5f91d173ed2acfaead56b000d3e675805fa34fef..69791084e2f9fa77fa24301c9947e27bcdaa622b 100644 (file)
@@ -114,7 +114,7 @@ pub fn open<P: AsPath + ?Sized>(path: &P) -> io::Result<File> {
 
     /// Open a file in write-only mode.
     ///
-    /// This function will create a file it it does not exist,
+    /// This function will create a file if it does not exist,
     /// and will truncate it if it does.
     ///
     /// See the `OpenOptions::open` function for more details.
index 2668baba095b875f7436d5ff675827f577be8518..c38d52161c96e8484ab8e656b224d29f7f9595e8 100644 (file)
@@ -381,14 +381,14 @@ fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
     ///
     /// This function will return any I/O error reported while formatting.
     fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<()> {
-        // Create a shim which translates a Writer to a fmt::Writer and saves
+        // Create a shim which translates a Write to a fmt::Write and saves
         // off I/O errors. instead of discarding them
         struct Adaptor<'a, T: ?Sized + 'a> {
             inner: &'a mut T,
             error: Result<()>,
         }
 
-        impl<'a, T: Write + ?Sized> fmt::Writer for Adaptor<'a, T> {
+        impl<'a, T: Write + ?Sized> fmt::Write for Adaptor<'a, T> {
             fn write_str(&mut self, s: &str) -> fmt::Result {
                 match self.inner.write_all(s.as_bytes()) {
                     Ok(()) => Ok(()),
@@ -443,9 +443,8 @@ pub trait Seek {
     /// A seek beyond the end of a stream is allowed, but seeking before offset
     /// 0 is an error.
     ///
-    /// Seeking past the end of the stream does not modify the underlying
-    /// stream, but the next write may cause the previous data to be filled in
-    /// with a bit pattern.
+    /// The behavior when seeking past the end of the stream is implementation
+    /// defined.
     ///
     /// This method returns the new position within the stream if the seek
     /// operation completed successfully.
index 139693ccdbcb9c3c0d022c48b694d4234f100b29..7c9a8a7b4b5ad2a8bef03bb3337ae19d7c3346c4 100644 (file)
 // can be resolved within libstd.
 #[doc(hidden)]
 mod std {
-    // NOTE: remove after next snapshot
-    // mods used for deriving
-    #[cfg(stage0)] pub use clone;
-    #[cfg(stage0)] pub use cmp;
-    #[cfg(stage0)] pub use hash;
-    #[cfg(stage0)] pub use default;
-
     pub use sync; // used for select!()
     pub use error; // used for try!()
     pub use fmt; // used for any formatting strings
@@ -319,7 +312,4 @@ mod std {
     pub use slice;
 
     pub use boxed; // used for vec![]
-    // for-loops
-    // NOTE: remove after next snapshot
-    #[cfg(stage0)] pub use iter;
 }
index 6a2aafcf8f396d985b52883a2c1a938be3c0fbd8..00bb7f86b170cf47b536ed5bdfac11b0405dd590 100644 (file)
@@ -60,23 +60,6 @@ macro_rules! panic {
     });
 }
 
-/// Use the syntax described in `std::fmt` to create a value of type `String`.
-/// See `std::fmt` for more information.
-///
-/// # Example
-///
-/// ```
-/// format!("test");
-/// format!("hello {}", "world!");
-/// format!("x = {}, y = {y}", 10, y = 30);
-/// ```
-#[cfg(stage0)] // NOTE: remove after snapshot
-#[macro_export]
-#[stable(feature = "rust1", since = "1.0.0")]
-macro_rules! format {
-    ($($arg:tt)*) => ($crate::fmt::format(format_args!($($arg)*)))
-}
-
 /// Equivalent to the `println!` macro except that a newline is not printed at
 /// the end of the message.
 #[macro_export]
@@ -126,7 +109,7 @@ macro_rules! try {
 /// # Examples
 ///
 /// ```
-/// use std::thread::Thread;
+/// use std::thread;
 /// use std::sync::mpsc;
 ///
 /// // two placeholder functions for now
@@ -136,8 +119,8 @@ macro_rules! try {
 /// let (tx1, rx1) = mpsc::channel();
 /// let (tx2, rx2) = mpsc::channel();
 ///
-/// Thread::spawn(move|| { long_running_task(); tx1.send(()).unwrap(); });
-/// Thread::spawn(move|| { tx2.send(calculate_the_answer()).unwrap(); });
+/// thread::spawn(move|| { long_running_task(); tx1.send(()).unwrap(); });
+/// thread::spawn(move|| { tx2.send(calculate_the_answer()).unwrap(); });
 ///
 /// select! (
 ///     _ = rx1.recv() => println!("the long running task finished first"),
index 50eafdfc5c2389677aa0cd6cb6c5dcf39fc4b98d..b861b74947eeb20961995bc8a48450ccc3efe25c 100644 (file)
@@ -43,7 +43,7 @@
 ///
 /// ```no_run
 /// use std::net::{TcpListener, TcpStream};
-/// use std::thread::Thread;
+/// use std::thread;
 ///
 /// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
 ///
@@ -55,7 +55,7 @@
 /// for stream in listener.incoming() {
 ///     match stream {
 ///         Ok(stream) => {
-///             Thread::spawn(move|| {
+///             thread::spawn(move|| {
 ///                 // connection succeeded
 ///                 handle_client(stream)
 ///             });
@@ -217,7 +217,7 @@ mod tests {
     use net::*;
     use net::test::{next_test_ip4, next_test_ip6};
     use sync::mpsc::channel;
-    use thread::Thread;
+    use thread;
 
     fn each_ip(f: &mut FnMut(SocketAddr)) {
         f(next_test_ip4());
@@ -247,7 +247,8 @@ fn bind_error() {
     fn connect_error() {
         match TcpStream::connect("0.0.0.0:1") {
             Ok(..) => panic!(),
-            Err(e) => assert_eq!(e.kind(), ErrorKind::ConnectionRefused),
+            Err(e) => assert!((e.kind() == ErrorKind::ConnectionRefused)
+                              || (e.kind() == ErrorKind::InvalidInput)),
         }
     }
 
@@ -256,7 +257,7 @@ fn listen_localhost() {
         let socket_addr = next_test_ip4();
         let listener = t!(TcpListener::bind(&socket_addr));
 
-        let _t = Thread::scoped(move || {
+        let _t = thread::spawn(move || {
             let mut stream = t!(TcpStream::connect(&("localhost",
                                                      socket_addr.port())));
             t!(stream.write(&[144]));
@@ -273,7 +274,7 @@ fn connect_ip4_loopback() {
         let addr = next_test_ip4();
         let acceptor = t!(TcpListener::bind(&addr));
 
-        let _t = Thread::scoped(move|| {
+        let _t = thread::spawn(move|| {
             let mut stream = t!(TcpStream::connect(&("127.0.0.1", addr.port())));
             t!(stream.write(&[44]));
         });
@@ -289,7 +290,7 @@ fn connect_ip6_loopback() {
         let addr = next_test_ip6();
         let acceptor = t!(TcpListener::bind(&addr));
 
-        let _t = Thread::scoped(move|| {
+        let _t = thread::spawn(move|| {
             let mut stream = t!(TcpStream::connect(&("::1", addr.port())));
             t!(stream.write(&[66]));
         });
@@ -306,7 +307,7 @@ fn smoke_test_ip6() {
             let acceptor = t!(TcpListener::bind(&addr));
 
             let (tx, rx) = channel();
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let mut stream = t!(TcpStream::connect(&addr));
                 t!(stream.write(&[99]));
                 tx.send(t!(stream.socket_addr())).unwrap();
@@ -325,7 +326,7 @@ fn read_eof_ip4() {
         each_ip(&mut |addr| {
             let acceptor = t!(TcpListener::bind(&addr));
 
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let _stream = t!(TcpStream::connect(&addr));
                 // Close
             });
@@ -345,7 +346,7 @@ fn write_close() {
             let acceptor = t!(TcpListener::bind(&addr));
 
             let (tx, rx) = channel();
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 drop(t!(TcpStream::connect(&addr)));
                 tx.send(()).unwrap();
             });
@@ -371,7 +372,7 @@ fn multiple_connect_serial_ip4() {
             let max = 10;
             let acceptor = t!(TcpListener::bind(&addr));
 
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 for _ in 0..max {
                     let mut stream = t!(TcpStream::connect(&addr));
                     t!(stream.write(&[99]));
@@ -393,11 +394,11 @@ fn multiple_connect_interleaved_greedy_schedule() {
         each_ip(&mut |addr| {
             let acceptor = t!(TcpListener::bind(&addr));
 
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let acceptor = acceptor;
                 for (i, stream) in acceptor.incoming().enumerate().take(MAX) {
                     // Start another task to handle the connection
-                    let _t = Thread::scoped(move|| {
+                    let _t = thread::spawn(move|| {
                         let mut stream = t!(stream);
                         let mut buf = [0];
                         t!(stream.read(&mut buf));
@@ -412,7 +413,7 @@ fn multiple_connect_interleaved_greedy_schedule() {
         fn connect(i: usize, addr: SocketAddr) {
             if i == MAX { return }
 
-            let t = Thread::scoped(move|| {
+            let t = thread::spawn(move|| {
                 let mut stream = t!(TcpStream::connect(&addr));
                 // Connect again before writing
                 connect(i + 1, addr);
@@ -428,10 +429,10 @@ fn multiple_connect_interleaved_lazy_schedule_ip4() {
         each_ip(&mut |addr| {
             let acceptor = t!(TcpListener::bind(&addr));
 
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 for stream in acceptor.incoming().take(MAX) {
                     // Start another task to handle the connection
-                    let _t = Thread::scoped(move|| {
+                    let _t = thread::spawn(move|| {
                         let mut stream = t!(stream);
                         let mut buf = [0];
                         t!(stream.read(&mut buf));
@@ -446,7 +447,7 @@ fn multiple_connect_interleaved_lazy_schedule_ip4() {
         fn connect(i: usize, addr: SocketAddr) {
             if i == MAX { return }
 
-            let t = Thread::scoped(move|| {
+            let t = thread::spawn(move|| {
                 let mut stream = t!(TcpStream::connect(&addr));
                 connect(i + 1, addr);
                 t!(stream.write(&[99]));
@@ -467,7 +468,7 @@ fn socket_and_peer_name_ip4() {
             let listener = t!(TcpListener::bind(&addr));
             let so_name = t!(listener.socket_addr());
             assert_eq!(addr, so_name);
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 t!(listener.accept());
             });
 
@@ -481,7 +482,7 @@ fn partial_read() {
         each_ip(&mut |addr| {
             let (tx, rx) = channel();
             let srv = t!(TcpListener::bind(&addr));
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let mut cl = t!(srv.accept()).0;
                 cl.write(&[10]).unwrap();
                 let mut b = [0];
@@ -517,7 +518,7 @@ fn fast_rebind() {
         each_ip(&mut |addr| {
             let acceptor = t!(TcpListener::bind(&addr));
 
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 t!(TcpStream::connect(&addr));
             });
 
@@ -532,7 +533,7 @@ fn tcp_clone_smoke() {
         each_ip(&mut |addr| {
             let acceptor = t!(TcpListener::bind(&addr));
 
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let mut s = t!(TcpStream::connect(&addr));
                 let mut buf = [0, 0];
                 assert_eq!(s.read(&mut buf), Ok(1));
@@ -545,7 +546,7 @@ fn tcp_clone_smoke() {
 
             let (tx1, rx1) = channel();
             let (tx2, rx2) = channel();
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let mut s2 = s2;
                 rx1.recv().unwrap();
                 t!(s2.write(&[1]));
@@ -565,7 +566,7 @@ fn tcp_clone_two_read() {
             let (tx1, rx) = channel();
             let tx2 = tx1.clone();
 
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let mut s = t!(TcpStream::connect(&addr));
                 t!(s.write(&[1]));
                 rx.recv().unwrap();
@@ -577,7 +578,7 @@ fn tcp_clone_two_read() {
             let s2 = t!(s1.try_clone());
 
             let (done, rx) = channel();
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let mut s2 = s2;
                 let mut buf = [0, 0];
                 t!(s2.read(&mut buf));
@@ -597,7 +598,7 @@ fn tcp_clone_two_write() {
         each_ip(&mut |addr| {
             let acceptor = t!(TcpListener::bind(&addr));
 
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let mut s = t!(TcpStream::connect(&addr));
                 let mut buf = [0, 1];
                 t!(s.read(&mut buf));
@@ -608,7 +609,7 @@ fn tcp_clone_two_write() {
             let s2 = t!(s1.try_clone());
 
             let (done, rx) = channel();
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let mut s2 = s2;
                 t!(s2.write(&[1]));
                 done.send(()).unwrap();
@@ -623,7 +624,7 @@ fn tcp_clone_two_write() {
     fn shutdown_smoke() {
         each_ip(&mut |addr| {
             let a = t!(TcpListener::bind(&addr));
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let mut c = t!(a.accept()).0;
                 let mut b = [0];
                 assert_eq!(c.read(&mut b), Ok(0));
@@ -644,7 +645,7 @@ fn close_readwrite_smoke() {
         each_ip(&mut |addr| {
             let a = t!(TcpListener::bind(&addr));
             let (tx, rx) = channel::<()>();
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let _s = t!(a.accept());
                 let _ = rx.recv();
             });
@@ -682,7 +683,7 @@ fn close_read_wakes_up() {
         each_ip(&mut |addr| {
             let a = t!(TcpListener::bind(&addr));
             let (tx1, rx) = channel::<()>();
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let _s = t!(a.accept());
                 let _ = rx.recv();
             });
@@ -690,7 +691,7 @@ fn close_read_wakes_up() {
             let s = t!(TcpStream::connect(&addr));
             let s2 = t!(s.try_clone());
             let (tx, rx) = channel();
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let mut s2 = s2;
                 assert_eq!(t!(s2.read(&mut [0])), 0);
                 tx.send(()).unwrap();
@@ -713,7 +714,7 @@ fn clone_while_reading() {
             let (tx, rx) = channel();
             let (txdone, rxdone) = channel();
             let txdone2 = txdone.clone();
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let mut tcp = t!(TcpStream::connect(&addr));
                 rx.recv().unwrap();
                 t!(tcp.write(&[0]));
@@ -724,7 +725,7 @@ fn clone_while_reading() {
             let tcp = t!(accept.accept()).0;
             let tcp2 = t!(tcp.try_clone());
             let txdone3 = txdone.clone();
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let mut tcp2 = tcp2;
                 t!(tcp2.read(&mut [0]));
                 txdone3.send(()).unwrap();
@@ -732,7 +733,7 @@ fn clone_while_reading() {
 
             // Try to ensure that the reading clone is indeed reading
             for _ in 0..50 {
-                Thread::yield_now();
+                thread::yield_now();
             }
 
             // clone the handle again while it's reading, then let it finish the
@@ -750,10 +751,10 @@ fn clone_accept_smoke() {
             let a = t!(TcpListener::bind(&addr));
             let a2 = t!(a.try_clone());
 
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let _ = TcpStream::connect(&addr);
             });
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let _ = TcpStream::connect(&addr);
             });
 
@@ -771,17 +772,17 @@ fn clone_accept_concurrent() {
             let (tx, rx) = channel();
             let tx2 = tx.clone();
 
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 tx.send(t!(a.accept())).unwrap();
             });
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 tx2.send(t!(a2.accept())).unwrap();
             });
 
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let _ = TcpStream::connect(&addr);
             });
-            let _t = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
                 let _ = TcpStream::connect(&addr);
             });
 
index d162a29790ea16c77ea4e6463209b00f8f829554..92f00599826dd14d1e603cae5a68988a6ee55d9d 100644 (file)
@@ -131,7 +131,7 @@ mod tests {
     use net::*;
     use net::test::{next_test_ip4, next_test_ip6};
     use sync::mpsc::channel;
-    use thread::Thread;
+    use thread;
 
     fn each_ip(f: &mut FnMut(SocketAddr, SocketAddr)) {
         f(next_test_ip4(), next_test_ip4());
@@ -164,7 +164,7 @@ fn socket_smoke_test_ip4() {
             let (tx1, rx1) = channel();
             let (tx2, rx2) = channel();
 
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 let client = t!(UdpSocket::bind(&client_ip));
                 rx1.recv().unwrap();
                 t!(client.send_to(&[99], &server_ip));
@@ -196,7 +196,7 @@ fn udp_clone_smoke() {
             let sock1 = t!(UdpSocket::bind(&addr1));
             let sock2 = t!(UdpSocket::bind(&addr2));
 
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 let mut buf = [0, 0];
                 assert_eq!(sock2.recv_from(&mut buf), Ok((1, addr1)));
                 assert_eq!(buf[0], 1);
@@ -207,7 +207,7 @@ fn udp_clone_smoke() {
 
             let (tx1, rx1) = channel();
             let (tx2, rx2) = channel();
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 rx1.recv().unwrap();
                 t!(sock3.send_to(&[1], &addr2));
                 tx2.send(()).unwrap();
@@ -227,7 +227,7 @@ fn udp_clone_two_read() {
             let (tx1, rx) = channel();
             let tx2 = tx1.clone();
 
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 t!(sock2.send_to(&[1], &addr1));
                 rx.recv().unwrap();
                 t!(sock2.send_to(&[2], &addr1));
@@ -237,7 +237,7 @@ fn udp_clone_two_read() {
             let sock3 = t!(sock1.try_clone());
 
             let (done, rx) = channel();
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 let mut buf = [0, 0];
                 t!(sock3.recv_from(&mut buf));
                 tx2.send(()).unwrap();
@@ -260,7 +260,7 @@ fn udp_clone_two_write() {
             let (tx, rx) = channel();
             let (serv_tx, serv_rx) = channel();
 
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 let mut buf = [0, 1];
                 rx.recv().unwrap();
                 t!(sock2.recv_from(&mut buf));
@@ -271,7 +271,7 @@ fn udp_clone_two_write() {
 
             let (done, rx) = channel();
             let tx2 = tx.clone();
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 match sock3.send_to(&[1], &addr2) {
                     Ok(..) => { let _ = tx2.send(()); }
                     Err(..) => {}
index 29532cb9b02d09fcc9031f44db9d004c082573c5..4582dcd2b0392f117556dc807e9e42719b5fb6ea 100644 (file)
@@ -51,71 +51,143 @@ pub trait Float
     + Rem<Output=Self>
 {
     // inlined methods from `num::Float`
-    /// Returns the NaN value.
+    /// Returns the `NaN` value.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let nan: f32 = Float::nan();
+    ///
+    /// assert!(nan.is_nan());
+    /// ```
     #[unstable(feature = "std_misc",
                reason = "unsure about its place in the world")]
     fn nan() -> Self;
     /// Returns the infinite value.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f32;
+    ///
+    /// let infinity: f32 = Float::infinity();
+    ///
+    /// assert!(infinity.is_infinite());
+    /// assert!(!infinity.is_finite());
+    /// assert!(infinity > f32::MAX);
+    /// ```
     #[unstable(feature = "std_misc",
                reason = "unsure about its place in the world")]
     fn infinity() -> Self;
     /// Returns the negative infinite value.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f32;
+    ///
+    /// let neg_infinity: f32 = Float::neg_infinity();
+    ///
+    /// assert!(neg_infinity.is_infinite());
+    /// assert!(!neg_infinity.is_finite());
+    /// assert!(neg_infinity < f32::MIN);
+    /// ```
     #[unstable(feature = "std_misc",
                reason = "unsure about its place in the world")]
     fn neg_infinity() -> Self;
-    /// Returns the `0` value.
+    /// Returns `0.0`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let inf: f32 = Float::infinity();
+    /// let zero: f32 = Float::zero();
+    /// let neg_zero: f32 = Float::neg_zero();
+    ///
+    /// assert_eq!(zero, neg_zero);
+    /// assert_eq!(7.0f32/inf, zero);
+    /// assert_eq!(zero * 10.0, zero);
+    /// ```
     #[unstable(feature = "std_misc",
                reason = "unsure about its place in the world")]
     fn zero() -> Self;
-    /// Returns -0.0.
+    /// Returns `-0.0`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let inf: f32 = Float::infinity();
+    /// let zero: f32 = Float::zero();
+    /// let neg_zero: f32 = Float::neg_zero();
+    ///
+    /// assert_eq!(zero, neg_zero);
+    /// assert_eq!(7.0f32/inf, zero);
+    /// assert_eq!(zero * 10.0, zero);
+    /// ```
     #[unstable(feature = "std_misc",
                reason = "unsure about its place in the world")]
     fn neg_zero() -> Self;
-    /// Returns the `1` value.
+    /// Returns `1.0`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let one: f32 = Float::one();
+    ///
+    /// assert_eq!(one, 1.0f32);
+    /// ```
     #[unstable(feature = "std_misc",
                reason = "unsure about its place in the world")]
     fn one() -> Self;
 
     // FIXME (#5527): These should be associated constants
 
-    /// Returns the number of binary digits of mantissa that this type supports.
+    /// Deprecated: use `std::f32::MANTISSA_DIGITS` or `std::f64::MANTISSA_DIGITS`
+    /// instead.
     #[unstable(feature = "std_misc")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MANTISSA_DIGITS` or \
                            `std::f64::MANTISSA_DIGITS` as appropriate")]
     fn mantissa_digits(unused_self: Option<Self>) -> uint;
-    /// Returns the number of base-10 digits of precision that this type supports.
+    /// Deprecated: use `std::f32::DIGITS` or `std::f64::DIGITS` instead.
     #[unstable(feature = "std_misc")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::DIGITS` or `std::f64::DIGITS` as appropriate")]
     fn digits(unused_self: Option<Self>) -> uint;
-    /// Returns the difference between 1.0 and the smallest representable number larger than 1.0.
+    /// Deprecated: use `std::f32::EPSILON` or `std::f64::EPSILON` instead.
     #[unstable(feature = "std_misc")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::EPSILON` or `std::f64::EPSILON` as appropriate")]
     fn epsilon() -> Self;
-    /// Returns the minimum binary exponent that this type can represent.
+    /// Deprecated: use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` instead.
     #[unstable(feature = "std_misc")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` as appropriate")]
     fn min_exp(unused_self: Option<Self>) -> int;
-    /// Returns the maximum binary exponent that this type can represent.
+    /// Deprecated: use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` instead.
     #[unstable(feature = "std_misc")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` as appropriate")]
     fn max_exp(unused_self: Option<Self>) -> int;
-    /// Returns the minimum base-10 exponent that this type can represent.
+    /// Deprecated: use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` instead.
     #[unstable(feature = "std_misc")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` as appropriate")]
     fn min_10_exp(unused_self: Option<Self>) -> int;
-    /// Returns the maximum base-10 exponent that this type can represent.
+    /// Deprecated: use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` instead.
     #[unstable(feature = "std_misc")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` as appropriate")]
     fn max_10_exp(unused_self: Option<Self>) -> int;
 
     /// Returns the smallest finite value that this type can represent.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x: f64 = Float::min_value();
+    ///
+    /// assert_eq!(x, f64::MIN);
+    /// ```
     #[unstable(feature = "std_misc",
                reason = "unsure about its place in the world")]
     fn min_value() -> Self;
@@ -124,50 +196,222 @@ pub trait Float
                reason = "unsure about its place in the world")]
     fn min_pos_value(unused_self: Option<Self>) -> Self;
     /// Returns the largest finite value that this type can represent.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x: f64 = Float::max_value();
+    /// assert_eq!(x, f64::MAX);
+    /// ```
     #[unstable(feature = "std_misc",
                reason = "unsure about its place in the world")]
     fn max_value() -> Self;
-
-    /// Returns true if this value is NaN and false otherwise.
+    /// Returns `true` if this value is `NaN` and false otherwise.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let nan = f64::NAN;
+    /// let f = 7.0;
+    ///
+    /// assert!(nan.is_nan());
+    /// assert!(!f.is_nan());
+    /// ```
     #[unstable(feature = "std_misc", reason = "position is undecided")]
     fn is_nan(self) -> bool;
-    /// Returns true if this value is positive infinity or negative infinity and
+    /// Returns `true` if this value is positive infinity or negative infinity and
     /// false otherwise.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f32;
+    ///
+    /// let f = 7.0f32;
+    /// let inf: f32 = Float::infinity();
+    /// let neg_inf: f32 = Float::neg_infinity();
+    /// let nan: f32 = f32::NAN;
+    ///
+    /// assert!(!f.is_infinite());
+    /// assert!(!nan.is_infinite());
+    ///
+    /// assert!(inf.is_infinite());
+    /// assert!(neg_inf.is_infinite());
+    /// ```
     #[unstable(feature = "std_misc", reason = "position is undecided")]
     fn is_infinite(self) -> bool;
-    /// Returns true if this number is neither infinite nor NaN.
+    /// Returns `true` if this number is neither infinite nor `NaN`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f32;
+    ///
+    /// let f = 7.0f32;
+    /// let inf: f32 = Float::infinity();
+    /// let neg_inf: f32 = Float::neg_infinity();
+    /// let nan: f32 = f32::NAN;
+    ///
+    /// assert!(f.is_finite());
+    ///
+    /// assert!(!nan.is_finite());
+    /// assert!(!inf.is_finite());
+    /// assert!(!neg_inf.is_finite());
+    /// ```
     #[unstable(feature = "std_misc", reason = "position is undecided")]
     fn is_finite(self) -> bool;
-    /// Returns true if this number is neither zero, infinite, denormal, or NaN.
+    /// Returns `true` if the number is neither zero, infinite,
+    /// [subnormal][subnormal], or `NaN`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f32;
+    ///
+    /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
+    /// let max = f32::MAX;
+    /// let lower_than_min = 1.0e-40_f32;
+    /// let zero = 0.0f32;
+    ///
+    /// assert!(min.is_normal());
+    /// assert!(max.is_normal());
+    ///
+    /// assert!(!zero.is_normal());
+    /// assert!(!f32::NAN.is_normal());
+    /// assert!(!f32::INFINITY.is_normal());
+    /// // Values between `0` and `min` are Subnormal.
+    /// assert!(!lower_than_min.is_normal());
+    /// ```
+    /// [subnormal]: http://en.wikipedia.org/wiki/Denormal_number
     #[unstable(feature = "std_misc", reason = "position is undecided")]
     fn is_normal(self) -> bool;
-    /// Returns the category that this number falls into.
+
+    /// Returns the floating point category of the number. If only one property
+    /// is going to be tested, it is generally faster to use the specific
+    /// predicate instead.
+    ///
+    /// ```
+    /// use std::num::{Float, FpCategory};
+    /// use std::f32;
+    ///
+    /// let num = 12.4f32;
+    /// let inf = f32::INFINITY;
+    ///
+    /// assert_eq!(num.classify(), FpCategory::Normal);
+    /// assert_eq!(inf.classify(), FpCategory::Infinite);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn classify(self) -> FpCategory;
 
-    /// Returns the mantissa, exponent and sign as integers, respectively.
+    /// Returns the mantissa, base 2 exponent, and sign as integers, respectively.
+    /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`.
+    /// The floating point encoding is documented in the [Reference][floating-point].
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let num = 2.0f32;
+    ///
+    /// // (8388608u64, -22i16, 1i8)
+    /// let (mantissa, exponent, sign) = num.integer_decode();
+    /// let sign_f = sign as f32;
+    /// let mantissa_f = mantissa as f32;
+    /// let exponent_f = num.powf(exponent as f32);
+    ///
+    /// // 1 * 8388608 * 2^(-22) == 2
+    /// let abs_difference = (sign_f * mantissa_f * exponent_f - num).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    /// [floating-point]: ../../../../../reference.html#machine-types
     #[unstable(feature = "std_misc", reason = "signature is undecided")]
     fn integer_decode(self) -> (u64, i16, i8);
 
-    /// Return the largest integer less than or equal to a number.
+    /// Returns the largest integer less than or equal to a number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 3.99;
+    /// let g = 3.0;
+    ///
+    /// assert_eq!(f.floor(), 3.0);
+    /// assert_eq!(g.floor(), 3.0);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn floor(self) -> Self;
-    /// Return the smallest integer greater than or equal to a number.
+    /// Returns the smallest integer greater than or equal to a number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 3.01;
+    /// let g = 4.0;
+    ///
+    /// assert_eq!(f.ceil(), 4.0);
+    /// assert_eq!(g.ceil(), 4.0);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn ceil(self) -> Self;
-    /// Return the nearest integer to a number. Round half-way cases away from
+    /// Returns the nearest integer to a number. Round half-way cases away from
     /// `0.0`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 3.3;
+    /// let g = -3.3;
+    ///
+    /// assert_eq!(f.round(), 3.0);
+    /// assert_eq!(g.round(), -3.0);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn round(self) -> Self;
     /// Return the integer part of a number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 3.3;
+    /// let g = -3.7;
+    ///
+    /// assert_eq!(f.trunc(), 3.0);
+    /// assert_eq!(g.trunc(), -3.0);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn trunc(self) -> Self;
-    /// Return the fractional part of a number.
+    /// Returns the fractional part of a number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 3.5;
+    /// let y = -3.5;
+    /// let abs_difference_x = (x.fract() - 0.5).abs();
+    /// let abs_difference_y = (y.fract() - (-0.5)).abs();
+    ///
+    /// assert!(abs_difference_x < 1e-10);
+    /// assert!(abs_difference_y < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn fract(self) -> Self;
-
     /// Computes the absolute value of `self`. Returns `Float::nan()` if the
     /// number is `Float::nan()`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = 3.5;
+    /// let y = -3.5;
+    ///
+    /// let abs_difference_x = (x.abs() - x).abs();
+    /// let abs_difference_y = (y.abs() - (-y)).abs();
+    ///
+    /// assert!(abs_difference_x < 1e-10);
+    /// assert!(abs_difference_y < 1e-10);
+    ///
+    /// assert!(f64::NAN.abs().is_nan());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn abs(self) -> Self;
     /// Returns a number that represents the sign of `self`.
@@ -175,24 +419,88 @@ pub trait Float
     /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()`
     /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()`
     /// - `Float::nan()` if the number is `Float::nan()`
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let f = 3.5;
+    ///
+    /// assert_eq!(f.signum(), 1.0);
+    /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0);
+    ///
+    /// assert!(f64::NAN.signum().is_nan());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn signum(self) -> Self;
     /// Returns `true` if `self` is positive, including `+0.0` and
     /// `Float::infinity()`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let nan: f64 = f64::NAN;
+    ///
+    /// let f = 7.0;
+    /// let g = -7.0;
+    ///
+    /// assert!(f.is_positive());
+    /// assert!(!g.is_positive());
+    /// // Requires both tests to determine if is `NaN`
+    /// assert!(!nan.is_positive() && !nan.is_negative());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn is_positive(self) -> bool;
     /// Returns `true` if `self` is negative, including `-0.0` and
     /// `Float::neg_infinity()`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let nan = f64::NAN;
+    ///
+    /// let f = 7.0;
+    /// let g = -7.0;
+    ///
+    /// assert!(!f.is_negative());
+    /// assert!(g.is_negative());
+    /// // Requires both tests to determine if is `NaN`.
+    /// assert!(!nan.is_positive() && !nan.is_negative());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn is_negative(self) -> bool;
 
     /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
     /// error. This produces a more accurate result with better performance than
     /// a separate multiplication operation followed by an add.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let m = 10.0;
+    /// let x = 4.0;
+    /// let b = 60.0;
+    ///
+    /// // 100.0
+    /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[unstable(feature = "std_misc",
                reason = "unsure about its place in the world")]
     fn mul_add(self, a: Self, b: Self) -> Self;
     /// Take the reciprocal (inverse) of a number, `1/x`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 2.0;
+    /// let abs_difference = (x.recip() - (1.0/x)).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[unstable(feature = "std_misc",
                reason = "unsure about its place in the world")]
     fn recip(self) -> Self;
@@ -200,149 +508,576 @@ pub trait Float
     /// Raise a number to an integer power.
     ///
     /// Using this function is generally faster than using `powf`
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 2.0;
+    /// let abs_difference = (x.powi(2) - x*x).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn powi(self, n: i32) -> Self;
     /// Raise a number to a floating point power.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 2.0;
+    /// let abs_difference = (x.powf(2.0) - x*x).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn powf(self, n: Self) -> Self;
-
     /// Take the square root of a number.
     ///
     /// Returns NaN if `self` is a negative number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let positive = 4.0;
+    /// let negative = -4.0;
+    ///
+    /// let abs_difference = (positive.sqrt() - 2.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// assert!(negative.sqrt().is_nan());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn sqrt(self) -> Self;
+
     /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 4.0;
+    ///
+    /// let abs_difference = (f.rsqrt() - 0.5).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[unstable(feature = "std_misc",
                reason = "unsure about its place in the world")]
     fn rsqrt(self) -> Self;
 
     /// Returns `e^(self)`, (the exponential function).
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let one = 1.0;
+    /// // e^1
+    /// let e = one.exp();
+    ///
+    /// // ln(e) - 1 == 0
+    /// let abs_difference = (e.ln() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn exp(self) -> Self;
-    /// Returns 2 raised to the power of the number, `2^(self)`.
+    /// Returns `2^(self)`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 2.0;
+    ///
+    /// // 2^2 - 4 == 0
+    /// let abs_difference = (f.exp2() - 4.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn exp2(self) -> Self;
     /// Returns the natural logarithm of the number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let one = 1.0;
+    /// // e^1
+    /// let e = one.exp();
+    ///
+    /// // ln(e) - 1 == 0
+    /// let abs_difference = (e.ln() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn ln(self) -> Self;
     /// Returns the logarithm of the number with respect to an arbitrary base.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let ten = 10.0;
+    /// let two = 2.0;
+    ///
+    /// // log10(10) - 1 == 0
+    /// let abs_difference_10 = (ten.log(10.0) - 1.0).abs();
+    ///
+    /// // log2(2) - 1 == 0
+    /// let abs_difference_2 = (two.log(2.0) - 1.0).abs();
+    ///
+    /// assert!(abs_difference_10 < 1e-10);
+    /// assert!(abs_difference_2 < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn log(self, base: Self) -> Self;
     /// Returns the base 2 logarithm of the number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let two = 2.0;
+    ///
+    /// // log2(2) - 1 == 0
+    /// let abs_difference = (two.log2() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn log2(self) -> Self;
     /// Returns the base 10 logarithm of the number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let ten = 10.0;
+    ///
+    /// // log10(10) - 1 == 0
+    /// let abs_difference = (ten.log10() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn log10(self) -> Self;
 
     /// Convert radians to degrees.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64::consts;
+    ///
+    /// let angle = consts::PI;
+    ///
+    /// let abs_difference = (angle.to_degrees() - 180.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[unstable(feature = "std_misc", reason = "desirability is unclear")]
     fn to_degrees(self) -> Self;
     /// Convert degrees to radians.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64::consts;
+    ///
+    /// let angle = 180.0;
+    ///
+    /// let abs_difference = (angle.to_radians() - consts::PI).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[unstable(feature = "std_misc", reason = "desirability is unclear")]
     fn to_radians(self) -> Self;
-
-    /// Constructs a floating point number created by multiplying `x` by 2
-    /// raised to the power of `exp`.
+    /// Constructs a floating point number of `x*2^exp`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// // 3*2^2 - 12 == 0
+    /// let abs_difference = (Float::ldexp(3.0, 2) - 12.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[unstable(feature = "std_misc",
                reason = "pending integer conventions")]
     fn ldexp(x: Self, exp: int) -> Self;
     /// Breaks the number into a normalized fraction and a base-2 exponent,
     /// satisfying:
     ///
-    ///  * `self = x * pow(2, exp)`
-    ///
+    ///  * `self = x * 2^exp`
     ///  * `0.5 <= abs(x) < 1.0`
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 4.0;
+    ///
+    /// // (1/2)*2^3 -> 1 * 8/2 -> 4.0
+    /// let f = x.frexp();
+    /// let abs_difference_0 = (f.0 - 0.5).abs();
+    /// let abs_difference_1 = (f.1 as f64 - 3.0).abs();
+    ///
+    /// assert!(abs_difference_0 < 1e-10);
+    /// assert!(abs_difference_1 < 1e-10);
+    /// ```
     #[unstable(feature = "std_misc",
                reason = "pending integer conventions")]
     fn frexp(self) -> (Self, int);
-
     /// Returns the next representable floating-point value in the direction of
     /// `other`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 1.0f32;
+    ///
+    /// let abs_diff = (x.next_after(2.0) - 1.00000011920928955078125_f32).abs();
+    ///
+    /// assert!(abs_diff < 1e-10);
+    /// ```
     #[unstable(feature = "std_misc",
                reason = "unsure about its place in the world")]
     fn next_after(self, other: Self) -> Self;
 
     /// Returns the maximum of the two numbers.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 1.0;
+    /// let y = 2.0;
+    ///
+    /// assert_eq!(x.max(y), y);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn max(self, other: Self) -> Self;
     /// Returns the minimum of the two numbers.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 1.0;
+    /// let y = 2.0;
+    ///
+    /// assert_eq!(x.min(y), x);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn min(self, other: Self) -> Self;
 
-    /// The positive difference of two numbers. Returns `0.0` if the number is
-    /// less than or equal to `other`, otherwise the difference between`self`
-    /// and `other` is returned.
+    /// The positive difference of two numbers.
+    ///
+    /// * If `self <= other`: `0:0`
+    /// * Else: `self - other`
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 3.0;
+    /// let y = -3.0;
+    ///
+    /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs();
+    /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs();
+    ///
+    /// assert!(abs_difference_x < 1e-10);
+    /// assert!(abs_difference_y < 1e-10);
+    /// ```
     #[unstable(feature = "std_misc", reason = "may be renamed")]
     fn abs_sub(self, other: Self) -> Self;
-
     /// Take the cubic root of a number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 8.0;
+    ///
+    /// // x^(1/3) - 2 == 0
+    /// let abs_difference = (x.cbrt() - 2.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[unstable(feature = "std_misc", reason = "may be renamed")]
     fn cbrt(self) -> Self;
     /// Calculate the length of the hypotenuse of a right-angle triangle given
     /// legs of length `x` and `y`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 2.0;
+    /// let y = 3.0;
+    ///
+    /// // sqrt(x^2 + y^2)
+    /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[unstable(feature = "std_misc",
                reason = "unsure about its place in the world")]
     fn hypot(self, other: Self) -> Self;
 
     /// Computes the sine of a number (in radians).
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/2.0;
+    ///
+    /// let abs_difference = (x.sin() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn sin(self) -> Self;
     /// Computes the cosine of a number (in radians).
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = 2.0*f64::consts::PI;
+    ///
+    /// let abs_difference = (x.cos() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn cos(self) -> Self;
     /// Computes the tangent of a number (in radians).
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/4.0;
+    /// let abs_difference = (x.tan() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-14);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn tan(self) -> Self;
-
     /// Computes the arcsine of a number. Return value is in radians in
     /// the range [-pi/2, pi/2] or NaN if the number is outside the range
     /// [-1, 1].
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let f = f64::consts::PI / 2.0;
+    ///
+    /// // asin(sin(pi/2))
+    /// let abs_difference = (f.sin().asin() - f64::consts::PI / 2.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn asin(self) -> Self;
     /// Computes the arccosine of a number. Return value is in radians in
     /// the range [0, pi] or NaN if the number is outside the range
     /// [-1, 1].
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let f = f64::consts::PI / 4.0;
+    ///
+    /// // acos(cos(pi/4))
+    /// let abs_difference = (f.cos().acos() - f64::consts::PI / 4.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn acos(self) -> Self;
     /// Computes the arctangent of a number. Return value is in radians in the
     /// range [-pi/2, pi/2];
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 1.0;
+    ///
+    /// // atan(tan(1))
+    /// let abs_difference = (f.tan().atan() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn atan(self) -> Self;
-    /// Computes the four quadrant arctangent of a number, `y`, and another
-    /// number `x`. Return value is in radians in the range [-pi, pi].
+    /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`).
+    ///
+    /// * `x = 0`, `y = 0`: `0`
+    /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
+    /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
+    /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let pi = f64::consts::PI;
+    /// // All angles from horizontal right (+x)
+    /// // 45 deg counter-clockwise
+    /// let x1 = 3.0;
+    /// let y1 = -3.0;
+    ///
+    /// // 135 deg clockwise
+    /// let x2 = -3.0;
+    /// let y2 = 3.0;
+    ///
+    /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs();
+    /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs();
+    ///
+    /// assert!(abs_difference_1 < 1e-10);
+    /// assert!(abs_difference_2 < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn atan2(self, other: Self) -> Self;
     /// Simultaneously computes the sine and cosine of the number, `x`. Returns
     /// `(sin(x), cos(x))`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/4.0;
+    /// let f = x.sin_cos();
+    ///
+    /// let abs_difference_0 = (f.0 - x.sin()).abs();
+    /// let abs_difference_1 = (f.1 - x.cos()).abs();
+    ///
+    /// assert!(abs_difference_0 < 1e-10);
+    /// assert!(abs_difference_0 < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn sin_cos(self) -> (Self, Self);
 
-    /// Returns the exponential of the number, minus 1, in a way that is
-    /// accurate even if the number is close to zero.
+    /// Returns `e^(self) - 1` in a way that is accurate even if the
+    /// number is close to zero.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 7.0;
+    ///
+    /// // e^(ln(7)) - 1
+    /// let abs_difference = (x.ln().exp_m1() - 6.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[unstable(feature = "std_misc", reason = "may be renamed")]
     fn exp_m1(self) -> Self;
-    /// Returns the natural logarithm of the number plus 1 (`ln(1+n)`) more
-    /// accurately than if the operations were performed separately.
+    /// Returns `ln(1+n)` (natural logarithm) more accurately than if
+    /// the operations were performed separately.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::E - 1.0;
+    ///
+    /// // ln(1 + (e - 1)) == ln(e) == 1
+    /// let abs_difference = (x.ln_1p() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[unstable(feature = "std_misc", reason = "may be renamed")]
     fn ln_1p(self) -> Self;
 
     /// Hyperbolic sine function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let x = 1.0;
+    ///
+    /// let f = x.sinh();
+    /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
+    /// let g = (e*e - 1.0)/(2.0*e);
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn sinh(self) -> Self;
     /// Hyperbolic cosine function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let x = 1.0;
+    /// let f = x.cosh();
+    /// // Solving cosh() at 1 gives this result
+    /// let g = (e*e + 1.0)/(2.0*e);
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// // Same result
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn cosh(self) -> Self;
     /// Hyperbolic tangent function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let x = 1.0;
+    ///
+    /// let f = x.tanh();
+    /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
+    /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2));
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn tanh(self) -> Self;
     /// Inverse hyperbolic sine function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 1.0;
+    /// let f = x.sinh().asinh();
+    ///
+    /// let abs_difference = (f - x).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn asinh(self) -> Self;
     /// Inverse hyperbolic cosine function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 1.0;
+    /// let f = x.cosh().acosh();
+    ///
+    /// let abs_difference = (f - x).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn acosh(self) -> Self;
     /// Inverse hyperbolic tangent function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let f = e.tanh().atanh();
+    ///
+    /// let abs_difference = (f - e).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn atanh(self) -> Self;
 }
index d8f9b1bb3feae4cd2c52d15f67f40bfaaddde6f1..207d3d39167660b929225e667725357d166a1b63 100644 (file)
@@ -161,12 +161,12 @@ mod test {
     use sync::mpsc::channel;
     use super::*;
     use old_io;
-    use thread::Thread;
+    use thread;
 
     #[test]
     fn test_rx_reader() {
         let (tx, rx) = channel();
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
           tx.send(vec![1u8, 2u8]).unwrap();
           tx.send(vec![]).unwrap();
           tx.send(vec![3u8, 4u8]).unwrap();
@@ -208,7 +208,7 @@ fn test_rx_reader() {
     #[test]
     fn test_rx_buffer() {
         let (tx, rx) = channel();
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
           tx.send(b"he".to_vec()).unwrap();
           tx.send(b"llo wo".to_vec()).unwrap();
           tx.send(b"".to_vec()).unwrap();
@@ -234,10 +234,7 @@ fn test_chan_writer() {
         writer.write_be_u32(42).unwrap();
 
         let wanted = vec![0u8, 0u8, 0u8, 42u8];
-        let got = match Thread::scoped(move|| { rx.recv().unwrap() }).join() {
-            Ok(got) => got,
-            Err(_) => panic!(),
-        };
+        let got = thread::scoped(move|| { rx.recv().unwrap() }).join();
         assert_eq!(wanted, got);
 
         match writer.write_u8(1) {
index 3673f590c0a9dcd2c192a83b7071d51c1d977862..4bd0662232fecccacb64e69bcdb78395225daff8 100644 (file)
 //!     # #![allow(dead_code)]
 //!     use std::old_io::{TcpListener, TcpStream};
 //!     use std::old_io::{Acceptor, Listener};
-//!     use std::thread::Thread;
+//!     use std::thread;
 //!
 //!     let listener = TcpListener::bind("127.0.0.1:80");
 //!
 //!         match stream {
 //!             Err(e) => { /* connection failed */ }
 //!             Ok(stream) => {
-//!                 Thread::spawn(move|| {
+//!                 thread::spawn(move|| {
 //!                     // connection succeeded
 //!                     handle_client(stream)
 //!                 });
 //! concerned with error handling; instead its caller is responsible for
 //! responding to errors that may occur while attempting to read the numbers.
 
-#![unstable(feature = "io")]
+#![unstable(feature = "old_io")]
 #![deny(unused_must_use)]
 
 pub use self::SeekStyle::*;
@@ -1023,14 +1023,14 @@ fn flush(&mut self) -> IoResult<()> { Ok(()) }
     ///
     /// This function will return any I/O error reported while formatting.
     fn write_fmt(&mut self, fmt: fmt::Arguments) -> IoResult<()> {
-        // Create a shim which translates a Writer to a fmt::Writer and saves
+        // Create a shim which translates a Writer to a fmt::Write and saves
         // off I/O errors. instead of discarding them
         struct Adaptor<'a, T: ?Sized +'a> {
             inner: &'a mut T,
             error: IoResult<()>,
         }
 
-        impl<'a, T: ?Sized + Writer> fmt::Writer for Adaptor<'a, T> {
+        impl<'a, T: ?Sized + Writer> fmt::Write for Adaptor<'a, T> {
             fn write_str(&mut self, s: &str) -> fmt::Result {
                 match self.inner.write_all(s.as_bytes()) {
                     Ok(()) => Ok(()),
index 8c4a10a55d489d86865f8ca661754fefc97d56b5..6b32d936c05bec0e8352b373dbdf88ec81c20dfa 100644 (file)
@@ -282,19 +282,19 @@ mod tests {
     use old_io::test::*;
     use super::*;
     use sync::mpsc::channel;
-    use thread::Thread;
+    use thread;
     use time::Duration;
 
     pub fn smalltest<F,G>(server: F, client: G)
         where F : FnOnce(UnixStream), F : Send,
-              G : FnOnce(UnixStream), G : Send
+              G : FnOnce(UnixStream), G : Send + 'static
     {
         let path1 = next_test_unix();
         let path2 = path1.clone();
 
         let mut acceptor = UnixListener::bind(&path1).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             match UnixStream::connect(&path2) {
                 Ok(c) => client(c),
                 Err(e) => panic!("failed connect: {}", e),
@@ -389,7 +389,7 @@ fn accept_lots() {
             Err(e) => panic!("failed listen: {}", e),
         };
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             for _ in 0u..times {
                 let mut stream = UnixStream::connect(&path2);
                 match stream.write(&[100]) {
@@ -423,7 +423,7 @@ fn unix_clone_smoke() {
         let addr = next_test_unix();
         let mut acceptor = UnixListener::bind(&addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s = UnixStream::connect(&addr);
             let mut buf = [0, 0];
             debug!("client reading");
@@ -439,7 +439,7 @@ fn unix_clone_smoke() {
 
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s2 = s2;
             rx1.recv().unwrap();
             debug!("writer writing");
@@ -462,7 +462,7 @@ fn unix_clone_two_read() {
         let (tx1, rx) = channel();
         let tx2 = tx1.clone();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s = UnixStream::connect(&addr);
             s.write(&[1]).unwrap();
             rx.recv().unwrap();
@@ -474,7 +474,7 @@ fn unix_clone_two_read() {
         let s2 = s1.clone();
 
         let (done, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s2 = s2;
             let mut buf = [0, 0];
             s2.read(&mut buf).unwrap();
@@ -493,7 +493,7 @@ fn unix_clone_two_write() {
         let addr = next_test_unix();
         let mut acceptor = UnixListener::bind(&addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s = UnixStream::connect(&addr);
             let buf = &mut [0, 1];
             s.read(buf).unwrap();
@@ -504,7 +504,7 @@ fn unix_clone_two_write() {
         let s2 = s1.clone();
 
         let (tx, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s2 = s2;
             s2.write(&[1]).unwrap();
             tx.send(()).unwrap();
@@ -551,7 +551,7 @@ fn accept_timeout() {
         // continue to receive any pending connections.
         let (tx, rx) = channel();
         let addr2 = addr.clone();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             tx.send(UnixStream::connect(&addr2).unwrap()).unwrap();
         });
         let l = rx.recv().unwrap();
@@ -561,7 +561,7 @@ fn accept_timeout() {
                 Err(ref e) if e.kind == TimedOut => {}
                 Err(e) => panic!("error: {}", e),
             }
-            ::thread::Thread::yield_now();
+            ::thread::yield_now();
             if i == 1000 { panic!("should have a pending connection") }
         }
         drop(l);
@@ -569,7 +569,7 @@ fn accept_timeout() {
         // Unset the timeout and make sure that this always blocks.
         a.set_timeout(None);
         let addr2 = addr.clone();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             drop(UnixStream::connect(&addr2).unwrap());
         });
         a.accept().unwrap();
@@ -607,7 +607,7 @@ fn close_readwrite_smoke() {
         let addr = next_test_unix();
         let a = UnixListener::bind(&addr).listen().unwrap();
         let (_tx, rx) = channel::<()>();
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let mut a = a;
             let _s = a.accept().unwrap();
             let _ = rx.recv();
@@ -644,7 +644,7 @@ fn close_read_wakes_up() {
         let addr = next_test_unix();
         let a = UnixListener::bind(&addr).listen().unwrap();
         let (_tx, rx) = channel::<()>();
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let mut a = a;
             let _s = a.accept().unwrap();
             let _ = rx.recv();
@@ -653,7 +653,7 @@ fn close_read_wakes_up() {
         let mut s = UnixStream::connect(&addr).unwrap();
         let s2 = s.clone();
         let (tx, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s2 = s2;
             assert!(s2.read(&mut [0]).is_err());
             tx.send(()).unwrap();
@@ -670,7 +670,7 @@ fn readwrite_timeouts() {
         let addr = next_test_unix();
         let mut a = UnixListener::bind(&addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let mut s = UnixStream::connect(&addr).unwrap();
             rx.recv().unwrap();
             assert!(s.write(&[0]).is_ok());
@@ -708,7 +708,7 @@ fn read_timeouts() {
         let addr = next_test_unix();
         let mut a = UnixListener::bind(&addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let mut s = UnixStream::connect(&addr).unwrap();
             rx.recv().unwrap();
             let mut amt = 0;
@@ -737,7 +737,7 @@ fn write_timeouts() {
         let addr = next_test_unix();
         let mut a = UnixListener::bind(&addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let mut s = UnixStream::connect(&addr).unwrap();
             rx.recv().unwrap();
             assert!(s.write(&[0]).is_ok());
@@ -764,7 +764,7 @@ fn timeout_concurrent_read() {
         let addr = next_test_unix();
         let mut a = UnixListener::bind(&addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let mut s = UnixStream::connect(&addr).unwrap();
             rx.recv().unwrap();
             assert!(s.write(&[0]).is_ok());
@@ -774,7 +774,7 @@ fn timeout_concurrent_read() {
         let mut s = a.accept().unwrap();
         let s2 = s.clone();
         let (tx2, rx2) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s2 = s2;
             assert!(s2.read(&mut [0]).is_ok());
             tx2.send(()).unwrap();
@@ -796,10 +796,10 @@ fn clone_accept_smoke() {
         let mut a2 = a.clone();
 
         let addr2 = addr.clone();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _ = UnixStream::connect(&addr2);
         });
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _ = UnixStream::connect(&addr);
         });
 
@@ -819,20 +819,20 @@ fn clone_accept_concurrent() {
         let (tx, rx) = channel();
         let tx2 = tx.clone();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut a = a;
             tx.send(a.accept()).unwrap()
         });
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut a = a2;
             tx2.send(a.accept()).unwrap()
         });
 
         let addr2 = addr.clone();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _ = UnixStream::connect(&addr2);
         });
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _ = UnixStream::connect(&addr);
         });
 
@@ -858,7 +858,7 @@ fn close_accept_concurrent() {
         let mut a2 = a.clone();
 
         let (tx, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut a = a;
             tx.send(a.accept()).unwrap();
         });
index ebf7f6cc0f2a9e6b4d256033ef1669e755827cfc..2afff9fc1c9b9c2a831bbc28a027d800a255e125 100644 (file)
@@ -137,12 +137,12 @@ pub fn set_keepalive(&mut self, delay_in_seconds: Option<uint>) -> IoResult<()>
     /// use std::old_io::timer;
     /// use std::old_io::TcpStream;
     /// use std::time::Duration;
-    /// use std::thread::Thread;
+    /// use std::thread;
     ///
     /// let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap();
     /// let stream2 = stream.clone();
     ///
-    /// let _t = Thread::spawn(move|| {
+    /// let _t = thread::spawn(move|| {
     ///     // close this stream after one second
     ///     timer::sleep(Duration::seconds(1));
     ///     let mut stream = stream2;
@@ -282,7 +282,7 @@ fn as_inner(&self) -> &TcpStreamImp {
 /// # fn foo() {
 /// use std::old_io::{TcpListener, TcpStream};
 /// use std::old_io::{Acceptor, Listener};
-/// use std::thread::Thread;
+/// use std::thread;
 ///
 /// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
 ///
@@ -298,7 +298,7 @@ fn as_inner(&self) -> &TcpStreamImp {
 ///     match stream {
 ///         Err(e) => { /* connection failed */ }
 ///         Ok(stream) => {
-///             Thread::spawn(move|| {
+///             thread::spawn(move|| {
 ///                 // connection succeeded
 ///                 handle_client(stream)
 ///             });
@@ -421,12 +421,12 @@ impl TcpAcceptor {
     ///
     /// ```
     /// use std::old_io::{TcpListener, Listener, Acceptor, EndOfFile};
-    /// use std::thread::Thread;
+    /// use std::thread;
     ///
     /// let mut a = TcpListener::bind("127.0.0.1:8482").listen().unwrap();
     /// let a2 = a.clone();
     ///
-    /// let _t = Thread::spawn(move|| {
+    /// let _t = thread::spawn(move|| {
     ///     let mut a2 = a2;
     ///     for socket in a2.incoming() {
     ///         match socket {
@@ -487,13 +487,14 @@ mod test {
     use prelude::v1::*;
 
     use sync::mpsc::channel;
-    use thread::Thread;
+    use thread;
     use old_io::net::tcp::*;
     use old_io::net::ip::*;
     use old_io::test::*;
     use old_io::{EndOfFile, TimedOut, ShortWrite, IoError};
     use old_io::{ConnectionRefused, BrokenPipe, ConnectionAborted};
     use old_io::{ConnectionReset, NotConnected, PermissionDenied, OtherIoError};
+    use old_io::{InvalidInput};
     use old_io::{Acceptor, Listener};
 
     // FIXME #11530 this fails on android because tests are run as root
@@ -510,7 +511,8 @@ fn bind_error() {
     fn connect_error() {
         match TcpStream::connect("0.0.0.0:1") {
             Ok(..) => panic!(),
-            Err(e) => assert_eq!(e.kind, ConnectionRefused),
+            Err(e) => assert!((e.kind == ConnectionRefused)
+                              || (e.kind == InvalidInput)),
         }
     }
 
@@ -520,7 +522,7 @@ fn listen_ip4_localhost() {
         let listener = TcpListener::bind(socket_addr);
         let mut acceptor = listener.listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut stream = TcpStream::connect(("localhost", socket_addr.port));
             stream.write(&[144]).unwrap();
         });
@@ -536,7 +538,7 @@ fn connect_localhost() {
         let addr = next_test_ip4();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut stream = TcpStream::connect(("localhost", addr.port));
             stream.write(&[64]).unwrap();
         });
@@ -552,7 +554,7 @@ fn connect_ip4_loopback() {
         let addr = next_test_ip4();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut stream = TcpStream::connect(("127.0.0.1", addr.port));
             stream.write(&[44]).unwrap();
         });
@@ -568,7 +570,7 @@ fn connect_ip6_loopback() {
         let addr = next_test_ip6();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut stream = TcpStream::connect(("::1", addr.port));
             stream.write(&[66]).unwrap();
         });
@@ -584,7 +586,7 @@ fn smoke_test_ip4() {
         let addr = next_test_ip4();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut stream = TcpStream::connect(addr);
             stream.write(&[99]).unwrap();
         });
@@ -600,7 +602,7 @@ fn smoke_test_ip6() {
         let addr = next_test_ip6();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut stream = TcpStream::connect(addr);
             stream.write(&[99]).unwrap();
         });
@@ -616,7 +618,7 @@ fn read_eof_ip4() {
         let addr = next_test_ip4();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _stream = TcpStream::connect(addr);
             // Close
         });
@@ -632,7 +634,7 @@ fn read_eof_ip6() {
         let addr = next_test_ip6();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _stream = TcpStream::connect(addr);
             // Close
         });
@@ -648,7 +650,7 @@ fn read_eof_twice_ip4() {
         let addr = next_test_ip4();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _stream = TcpStream::connect(addr);
             // Close
         });
@@ -672,7 +674,7 @@ fn read_eof_twice_ip6() {
         let addr = next_test_ip6();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _stream = TcpStream::connect(addr);
             // Close
         });
@@ -697,7 +699,7 @@ fn write_close_ip4() {
         let mut acceptor = TcpListener::bind(addr).listen();
 
         let (tx, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             drop(TcpStream::connect(addr));
             tx.send(()).unwrap();
         });
@@ -722,7 +724,7 @@ fn write_close_ip6() {
         let mut acceptor = TcpListener::bind(addr).listen();
 
         let (tx, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             drop(TcpStream::connect(addr));
             tx.send(()).unwrap();
         });
@@ -747,7 +749,7 @@ fn multiple_connect_serial_ip4() {
         let max = 10u;
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             for _ in 0..max {
                 let mut stream = TcpStream::connect(addr);
                 stream.write(&[99]).unwrap();
@@ -767,7 +769,7 @@ fn multiple_connect_serial_ip6() {
         let max = 10u;
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             for _ in 0..max {
                 let mut stream = TcpStream::connect(addr);
                 stream.write(&[99]).unwrap();
@@ -787,11 +789,11 @@ fn multiple_connect_interleaved_greedy_schedule_ip4() {
         static MAX: int = 10;
         let acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut acceptor = acceptor;
             for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
                 // Start another task to handle the connection
-                let _t = Thread::spawn(move|| {
+                let _t = thread::spawn(move|| {
                     let mut stream = stream;
                     let mut buf = [0];
                     stream.read(&mut buf).unwrap();
@@ -806,7 +808,7 @@ fn multiple_connect_interleaved_greedy_schedule_ip4() {
         fn connect(i: int, addr: SocketAddr) {
             if i == MAX { return }
 
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 debug!("connecting");
                 let mut stream = TcpStream::connect(addr);
                 // Connect again before writing
@@ -823,11 +825,11 @@ fn multiple_connect_interleaved_greedy_schedule_ip6() {
         static MAX: int = 10;
         let acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut acceptor = acceptor;
             for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
                 // Start another task to handle the connection
-                let _t = Thread::spawn(move|| {
+                let _t = thread::spawn(move|| {
                     let mut stream = stream;
                     let mut buf = [0];
                     stream.read(&mut buf).unwrap();
@@ -842,7 +844,7 @@ fn multiple_connect_interleaved_greedy_schedule_ip6() {
         fn connect(i: int, addr: SocketAddr) {
             if i == MAX { return }
 
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 debug!("connecting");
                 let mut stream = TcpStream::connect(addr);
                 // Connect again before writing
@@ -859,11 +861,11 @@ fn multiple_connect_interleaved_lazy_schedule_ip4() {
         let addr = next_test_ip4();
         let acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut acceptor = acceptor;
             for stream in acceptor.incoming().take(MAX as uint) {
                 // Start another task to handle the connection
-                let _t = Thread::spawn(move|| {
+                let _t = thread::spawn(move|| {
                     let mut stream = stream;
                     let mut buf = [0];
                     stream.read(&mut buf).unwrap();
@@ -878,7 +880,7 @@ fn multiple_connect_interleaved_lazy_schedule_ip4() {
         fn connect(i: int, addr: SocketAddr) {
             if i == MAX { return }
 
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 debug!("connecting");
                 let mut stream = TcpStream::connect(addr);
                 // Connect again before writing
@@ -895,11 +897,11 @@ fn multiple_connect_interleaved_lazy_schedule_ip6() {
         let addr = next_test_ip6();
         let acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut acceptor = acceptor;
             for stream in acceptor.incoming().take(MAX as uint) {
                 // Start another task to handle the connection
-                let _t = Thread::spawn(move|| {
+                let _t = thread::spawn(move|| {
                     let mut stream = stream;
                     let mut buf = [0];
                     stream.read(&mut buf).unwrap();
@@ -914,7 +916,7 @@ fn multiple_connect_interleaved_lazy_schedule_ip6() {
         fn connect(i: int, addr: SocketAddr) {
             if i == MAX { return }
 
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 debug!("connecting");
                 let mut stream = TcpStream::connect(addr);
                 // Connect again before writing
@@ -937,7 +939,7 @@ pub fn socket_name(addr: SocketAddr) {
 
     pub fn peer_name(addr: SocketAddr) {
         let acceptor = TcpListener::bind(addr).listen();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut acceptor = acceptor;
             acceptor.accept().unwrap();
         });
@@ -972,7 +974,7 @@ fn socket_and_peer_name_ip6() {
     fn partial_read() {
         let addr = next_test_ip4();
         let (tx, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut srv = TcpListener::bind(addr).listen().unwrap();
             tx.send(()).unwrap();
             let mut cl = srv.accept().unwrap();
@@ -1009,7 +1011,7 @@ fn fast_rebind() {
         let addr = next_test_ip4();
         let (tx, rx) = channel();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             rx.recv().unwrap();
             let _stream = TcpStream::connect(addr).unwrap();
             // Close
@@ -1034,7 +1036,7 @@ fn tcp_clone_smoke() {
         let addr = next_test_ip4();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s = TcpStream::connect(addr);
             let mut buf = [0, 0];
             assert_eq!(s.read(&mut buf), Ok(1));
@@ -1047,7 +1049,7 @@ fn tcp_clone_smoke() {
 
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s2 = s2;
             rx1.recv().unwrap();
             s2.write(&[1]).unwrap();
@@ -1066,7 +1068,7 @@ fn tcp_clone_two_read() {
         let (tx1, rx) = channel();
         let tx2 = tx1.clone();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s = TcpStream::connect(addr);
             s.write(&[1]).unwrap();
             rx.recv().unwrap();
@@ -1078,7 +1080,7 @@ fn tcp_clone_two_read() {
         let s2 = s1.clone();
 
         let (done, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s2 = s2;
             let mut buf = [0, 0];
             s2.read(&mut buf).unwrap();
@@ -1097,7 +1099,7 @@ fn tcp_clone_two_write() {
         let addr = next_test_ip4();
         let mut acceptor = TcpListener::bind(addr).listen();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s = TcpStream::connect(addr);
             let mut buf = [0, 1];
             s.read(&mut buf).unwrap();
@@ -1108,7 +1110,7 @@ fn tcp_clone_two_write() {
         let s2 = s1.clone();
 
         let (done, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s2 = s2;
             s2.write(&[1]).unwrap();
             done.send(()).unwrap();
@@ -1122,7 +1124,7 @@ fn tcp_clone_two_write() {
     fn shutdown_smoke() {
         let addr = next_test_ip4();
         let a = TcpListener::bind(addr).unwrap().listen();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut a = a;
             let mut c = a.accept().unwrap();
             assert_eq!(c.read_to_end(), Ok(vec!()));
@@ -1156,7 +1158,7 @@ fn accept_timeout() {
         //        flakiness.
         if !cfg!(target_os = "freebsd") {
             let (tx, rx) = channel();
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 tx.send(TcpStream::connect(addr).unwrap()).unwrap();
             });
             let _l = rx.recv().unwrap();
@@ -1166,14 +1168,14 @@ fn accept_timeout() {
                     Err(ref e) if e.kind == TimedOut => {}
                     Err(e) => panic!("error: {}", e),
                 }
-                ::thread::Thread::yield_now();
+                ::thread::yield_now();
                 if i == 1000 { panic!("should have a pending connection") }
             }
         }
 
         // Unset the timeout and make sure that this always blocks.
         a.set_timeout(None);
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             drop(TcpStream::connect(addr).unwrap());
         });
         a.accept().unwrap();
@@ -1184,7 +1186,7 @@ fn close_readwrite_smoke() {
         let addr = next_test_ip4();
         let a = TcpListener::bind(addr).listen().unwrap();
         let (_tx, rx) = channel::<()>();
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let mut a = a;
             let _s = a.accept().unwrap();
             let _ = rx.recv().unwrap();
@@ -1221,7 +1223,7 @@ fn close_read_wakes_up() {
         let addr = next_test_ip4();
         let a = TcpListener::bind(addr).listen().unwrap();
         let (_tx, rx) = channel::<()>();
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let mut a = a;
             let _s = a.accept().unwrap();
             let _ = rx.recv().unwrap();
@@ -1230,7 +1232,7 @@ fn close_read_wakes_up() {
         let mut s = TcpStream::connect(addr).unwrap();
         let s2 = s.clone();
         let (tx, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s2 = s2;
             assert!(s2.read(&mut [0]).is_err());
             tx.send(()).unwrap();
@@ -1247,7 +1249,7 @@ fn readwrite_timeouts() {
         let addr = next_test_ip6();
         let mut a = TcpListener::bind(addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let mut s = TcpStream::connect(addr).unwrap();
             rx.recv().unwrap();
             assert!(s.write(&[0]).is_ok());
@@ -1280,7 +1282,7 @@ fn read_timeouts() {
         let addr = next_test_ip6();
         let mut a = TcpListener::bind(addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let mut s = TcpStream::connect(addr).unwrap();
             rx.recv().unwrap();
             let mut amt = 0;
@@ -1309,7 +1311,7 @@ fn write_timeouts() {
         let addr = next_test_ip6();
         let mut a = TcpListener::bind(addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let mut s = TcpStream::connect(addr).unwrap();
             rx.recv().unwrap();
             assert!(s.write(&[0]).is_ok());
@@ -1337,7 +1339,7 @@ fn timeout_concurrent_read() {
         let addr = next_test_ip6();
         let mut a = TcpListener::bind(addr).listen().unwrap();
         let (tx, rx) = channel::<()>();
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let mut s = TcpStream::connect(addr).unwrap();
             rx.recv().unwrap();
             assert_eq!(s.write(&[0]), Ok(()));
@@ -1347,7 +1349,7 @@ fn timeout_concurrent_read() {
         let mut s = a.accept().unwrap();
         let s2 = s.clone();
         let (tx2, rx2) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut s2 = s2;
             assert_eq!(s2.read(&mut [0]), Ok(1));
             tx2.send(()).unwrap();
@@ -1370,7 +1372,7 @@ fn clone_while_reading() {
         let (tx, rx) = channel();
         let (txdone, rxdone) = channel();
         let txdone2 = txdone.clone();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut tcp = TcpStream::connect(addr).unwrap();
             rx.recv().unwrap();
             tcp.write_u8(0).unwrap();
@@ -1381,7 +1383,7 @@ fn clone_while_reading() {
         let tcp = accept.accept().unwrap();
         let tcp2 = tcp.clone();
         let txdone3 = txdone.clone();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut tcp2 = tcp2;
             tcp2.read_u8().unwrap();
             txdone3.send(()).unwrap();
@@ -1389,7 +1391,7 @@ fn clone_while_reading() {
 
         // Try to ensure that the reading clone is indeed reading
         for _ in 0..50 {
-            ::thread::Thread::yield_now();
+            ::thread::yield_now();
         }
 
         // clone the handle again while it's reading, then let it finish the
@@ -1407,10 +1409,10 @@ fn clone_accept_smoke() {
         let mut a = l.listen().unwrap();
         let mut a2 = a.clone();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _ = TcpStream::connect(addr);
         });
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _ = TcpStream::connect(addr);
         });
 
@@ -1428,19 +1430,19 @@ fn clone_accept_concurrent() {
         let (tx, rx) = channel();
         let tx2 = tx.clone();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut a = a;
             tx.send(a.accept()).unwrap();
         });
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut a = a2;
             tx2.send(a.accept()).unwrap();
         });
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _ = TcpStream::connect(addr);
         });
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _ = TcpStream::connect(addr);
         });
 
@@ -1466,7 +1468,7 @@ fn close_accept_concurrent() {
         let mut a2 = a.clone();
 
         let (tx, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut a = a;
             tx.send(a.accept()).unwrap();
         });
index 8dc19047de08e0f7b1f585d837b1c919d8a42352..7171198e7a4aaed7d847c240ffdbbeb1ac9fe5ec 100644 (file)
@@ -186,7 +186,7 @@ mod test {
     use old_io::test::*;
     use old_io::{IoError, TimedOut, PermissionDenied, ShortWrite};
     use super::*;
-    use thread::Thread;
+    use thread;
 
     // FIXME #11530 this fails on android because tests are run as root
     #[cfg_attr(any(windows, target_os = "android"), ignore)]
@@ -206,7 +206,7 @@ fn socket_smoke_test_ip4() {
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             match UdpSocket::bind(client_ip) {
                 Ok(ref mut client) => {
                     rx1.recv().unwrap();
@@ -241,7 +241,7 @@ fn socket_smoke_test_ip6() {
         let client_ip = next_test_ip6();
         let (tx, rx) = channel::<()>();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             match UdpSocket::bind(client_ip) {
                 Ok(ref mut client) => {
                     rx.recv().unwrap();
@@ -298,7 +298,7 @@ fn udp_clone_smoke() {
         let mut sock1 = UdpSocket::bind(addr1).unwrap();
         let sock2 = UdpSocket::bind(addr2).unwrap();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut sock2 = sock2;
             let mut buf = [0, 0];
             assert_eq!(sock2.recv_from(&mut buf), Ok((1, addr1)));
@@ -310,7 +310,7 @@ fn udp_clone_smoke() {
 
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut sock3 = sock3;
             rx1.recv().unwrap();
             sock3.send_to(&[1], addr2).unwrap();
@@ -331,7 +331,7 @@ fn udp_clone_two_read() {
         let (tx1, rx) = channel();
         let tx2 = tx1.clone();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut sock2 = sock2;
             sock2.send_to(&[1], addr1).unwrap();
             rx.recv().unwrap();
@@ -342,7 +342,7 @@ fn udp_clone_two_read() {
         let sock3 = sock1.clone();
 
         let (done, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut sock3 = sock3;
             let mut buf = [0, 0];
             sock3.recv_from(&mut buf).unwrap();
@@ -366,7 +366,7 @@ fn udp_clone_two_write() {
         let (tx, rx) = channel();
         let (serv_tx, serv_rx) = channel();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut sock2 = sock2;
             let mut buf = [0, 1];
 
@@ -382,7 +382,7 @@ fn udp_clone_two_write() {
 
         let (done, rx) = channel();
         let tx2 = tx.clone();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut sock3 = sock3;
             match sock3.send_to(&[1], addr2) {
                 Ok(..) => { let _ = tx2.send(()); }
@@ -410,7 +410,7 @@ fn recv_from_timeout() {
 
         let (tx, rx) = channel();
         let (tx2, rx2) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut a = a2;
             assert_eq!(a.recv_from(&mut [0]), Ok((1, addr1)));
             assert_eq!(a.send_to(&[0], addr1), Ok(()));
index 5843b1ba1b13f377c70264035099ea7db8e2d9e5..b7b626db034e1648076fc250b22ff4284ce30afe 100644 (file)
@@ -115,7 +115,7 @@ mod test {
     use prelude::v1::*;
 
     use sync::mpsc::channel;
-    use thread::Thread;
+    use thread;
 
     #[test]
     fn partial_read() {
@@ -126,7 +126,7 @@ fn partial_read() {
         let out = PipeStream::open(writer);
         let mut input = PipeStream::open(reader);
         let (tx, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut out = out;
             out.write(&[10]).unwrap();
             rx.recv().unwrap(); // don't close the pipe until the other read has finished
index 195d33c41a68e98e02210ccb4ad6eba323315a2d..ea6510c61b76be626372d567d9c4818d43228f0c 100644 (file)
@@ -30,7 +30,7 @@
 use sys::fs::FileDesc;
 use sys::process::Process as ProcessImp;
 use sys;
-use thread::Thread;
+use thread;
 
 #[cfg(windows)] use hash;
 #[cfg(windows)] use str;
@@ -703,7 +703,7 @@ fn read(stream: Option<old_io::PipeStream>) -> Receiver<IoResult<Vec<u8>>> {
             let (tx, rx) = channel();
             match stream {
                 Some(stream) => {
-                    Thread::spawn(move || {
+                    thread::spawn(move || {
                         let mut stream = stream;
                         tx.send(stream.read_to_end()).unwrap();
                     });
@@ -764,7 +764,7 @@ mod tests {
     use super::{CreatePipe};
     use super::{InheritFd, Process, PleaseExitSignal, Command, ProcessOutput};
     use sync::mpsc::channel;
-    use thread::Thread;
+    use thread;
     use time::Duration;
 
     // FIXME(#10380) these tests should not all be ignored on android.
@@ -800,12 +800,12 @@ fn exit_reported_right() {
     #[cfg(all(unix, not(target_os="android")))]
     #[test]
     fn signal_reported_right() {
-        let p = Command::new("/bin/sh").arg("-c").arg("kill -1 $$").spawn();
+        let p = Command::new("/bin/sh").arg("-c").arg("kill -9 $$").spawn();
         assert!(p.is_ok());
         let mut p = p.unwrap();
         match p.wait().unwrap() {
-            process::ExitSignal(1) => {},
-            result => panic!("not terminated by signal 1 (instead, {})", result),
+            process::ExitSignal(9) => {},
+            result => panic!("not terminated by signal 9 (instead, {})", result),
         }
     }
 
@@ -1169,14 +1169,14 @@ fn wait_timeout() {
     fn wait_timeout2() {
         let (tx, rx) = channel();
         let tx2 = tx.clone();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut p = sleeper();
             p.set_timeout(Some(10));
             assert_eq!(p.wait().err().unwrap().kind, TimedOut);
             p.signal_kill().unwrap();
             tx.send(()).unwrap();
         });
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut p = sleeper();
             p.set_timeout(Some(10));
             assert_eq!(p.wait().err().unwrap().kind, TimedOut);
index 70cce1f7e769eab05f3619db65acf1fad2077ff4..e3d0232684fcc3a9b57c25735973550c8a00b607 100644 (file)
@@ -530,7 +530,7 @@ mod tests {
 
     use super::*;
     use sync::mpsc::channel;
-    use thread::Thread;
+    use thread;
 
     #[test]
     fn smoke() {
@@ -546,7 +546,7 @@ fn capture_stdout() {
 
         let (tx, rx) = channel();
         let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             set_stdout(box w);
             println!("hello!");
         });
@@ -559,7 +559,7 @@ fn capture_stderr() {
 
         let (tx, rx) = channel();
         let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
-        let _t = Thread::spawn(move || -> () {
+        let _t = thread::spawn(move || -> () {
             set_stderr(box w);
             panic!("my special message");
         });
index 35f0bcb21d94b4a5b5e8c0ec35baaf81903ba7a4..8b84e27eae1ba83f1ed90712bf0f7403d64980cb 100644 (file)
@@ -224,13 +224,13 @@ fn in_ms_u64(d: Duration) -> u64 {
 #[cfg(test)]
 mod test {
     use super::Timer;
-    use thread::Thread;
+    use thread;
     use time::Duration;
 
     #[test]
     fn test_timer_send() {
         let mut timer = Timer::new().unwrap();
-        Thread::spawn(move || timer.sleep(Duration::milliseconds(1)));
+        thread::spawn(move || timer.sleep(Duration::milliseconds(1)));
     }
 
     #[test]
@@ -360,7 +360,7 @@ fn closing_channel_during_drop_doesnt_kill_everything() {
         let mut timer = Timer::new().unwrap();
         let timer_rx = timer.periodic(Duration::milliseconds(1000));
 
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let _ = timer_rx.recv();
         });
 
@@ -374,7 +374,7 @@ fn reset_doesnt_switch_tasks() {
         let mut timer = Timer::new().unwrap();
         let timer_rx = timer.periodic(Duration::milliseconds(1000));
 
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let _ = timer_rx.recv();
         });
 
@@ -387,7 +387,7 @@ fn reset_doesnt_switch_tasks2() {
         let mut timer = Timer::new().unwrap();
         let timer_rx = timer.periodic(Duration::milliseconds(1000));
 
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let _ = timer_rx.recv();
         });
 
index 17cfe1c82972f33c6a7a1d30d166bcafee15c82d..37de2993c4d0f77ed22f01d7544f750aaedd123b 100644 (file)
@@ -59,7 +59,7 @@
 //! println!("path exists: {}", path.exists());
 //! ```
 
-#![unstable(feature = "path")]
+#![unstable(feature = "old_path")]
 
 use core::marker::Sized;
 use ffi::CString;
index 6bf2a30b7b184e91aa85fe2b13b1b46173a19b57..35bffa689f31e66a8ff3d4d894310613b984d932 100644 (file)
@@ -518,18 +518,18 @@ fn test_opt_paths() {
 
     #[test]
     fn test_null_byte() {
-        use thread::Thread;
-        let result = Thread::scoped(move|| {
-            Path::new(b"foo/bar\0")
+        use thread;
+        let result = thread::spawn(move|| {
+            Path::new(b"foo/bar\0");
         }).join();
         assert!(result.is_err());
 
-        let result = Thread::scoped(move|| {
+        let result = thread::spawn(move|| {
             Path::new("test").set_filename(b"f\0o")
         }).join();
         assert!(result.is_err());
 
-        let result = Thread::scoped(move|| {
+        let result = thread::spawn(move|| {
             Path::new("test").push(b"f\0o");
         }).join();
         assert!(result.is_err());
@@ -1172,7 +1172,7 @@ macro_rules! t {
                     let exp: &[&[u8]] = &[$($exp),*];
                     assert_eq!(comps, exp);
                     let comps = path.components().rev().collect::<Vec<&[u8]>>();
-                    let exp = exp.iter().rev().map(|&x|x).collect::<Vec<&[u8]>>();
+                    let exp = exp.iter().rev().cloned().collect::<Vec<&[u8]>>();
                     assert_eq!(comps, exp)
                 }
             )
@@ -1204,7 +1204,7 @@ macro_rules! t {
                     let exp: &[Option<&str>] = &$exp;
                     assert_eq!(comps, exp);
                     let comps = path.str_components().rev().collect::<Vec<Option<&str>>>();
-                    let exp = exp.iter().rev().map(|&x|x).collect::<Vec<Option<&str>>>();
+                    let exp = exp.iter().rev().cloned().collect::<Vec<Option<&str>>>();
                     assert_eq!(comps, exp);
                 }
             )
index 54c070e1b7db83eb507f1da9c290f526ec5f4de9..c9d6eeda7620ab4542375615357def56a8b2e503 100644 (file)
@@ -1305,18 +1305,18 @@ fn test_opt_paths() {
 
     #[test]
     fn test_null_byte() {
-        use thread::Thread;
-        let result = Thread::scoped(move|| {
-            Path::new(b"foo/bar\0")
+        use thread;
+        let result = thread::spawn(move|| {
+            Path::new(b"foo/bar\0");
         }).join();
         assert!(result.is_err());
 
-        let result = Thread::scoped(move|| {
+        let result = thread::spawn(move|| {
             Path::new("test").set_filename(b"f\0o")
         }).join();
         assert!(result.is_err());
 
-        let result = Thread::scoped(move || {
+        let result = thread::spawn(move || {
             Path::new("test").push(b"f\0o");
         }).join();
         assert!(result.is_err());
@@ -2226,7 +2226,7 @@ macro_rules! t {
                     assert_eq!(comps, exp);
                     let comps = path.str_components().rev().map(|x|x.unwrap())
                                 .collect::<Vec<&str>>();
-                    let exp = exp.iter().rev().map(|&x|x).collect::<Vec<&str>>();
+                    let exp = exp.iter().rev().cloned().collect::<Vec<&str>>();
                     assert_eq!(comps, exp);
                 }
             );
@@ -2282,7 +2282,7 @@ macro_rules! t {
                     let exp: &[&[u8]] = &$exp;
                     assert_eq!(comps, exp);
                     let comps = path.components().rev().collect::<Vec<&[u8]>>();
-                    let exp = exp.iter().rev().map(|&x|x).collect::<Vec<&[u8]>>();
+                    let exp = exp.iter().rev().cloned().collect::<Vec<&[u8]>>();
                     assert_eq!(comps, exp);
                 }
             )
index e485c6a63c6f12afff71491b993eaad02bb3107a..35221a7e647cc728fd5896b284669567533ceb2e 100644 (file)
@@ -17,7 +17,7 @@
 use old_io::IoResult;
 use rt::{backtrace, unwind};
 use rt::util::{Stderr, Stdio};
-use thread::Thread;
+use thread;
 
 // Defined in this module instead of old_io::stdio so that the unwinding
 thread_local! {
@@ -42,7 +42,7 @@ pub fn on_panic(obj: &(Any+Send), file: &'static str, line: uint) {
         }
     };
     let mut err = Stderr;
-    let thread = Thread::current();
+    let thread = thread::current();
     let name = thread.name().unwrap_or("<unnamed>");
     let prev = LOCAL_STDERR.with(|s| s.borrow_mut().take());
     match prev {
index 1f6d39fb1b3f4d3394f56b2db848209c2d017fa5..1d992668900f05b4fb8c49b189ec23951131552a 100755 (executable)
 
 use core::prelude::*;
 
+use ascii::*;
 use borrow::BorrowFrom;
 use cmp;
 use iter;
 
 use ffi::{OsStr, OsString, AsOsStr};
 
-use self::platform::{is_sep, is_verbatim_sep, MAIN_SEP_STR, parse_prefix, Prefix};
+use self::platform::{is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix};
 
 ////////////////////////////////////////////////////////////////////////////////
 // GENERAL NOTES
 
 #[cfg(unix)]
 mod platform {
+    use super::Prefix;
     use core::prelude::*;
     use ffi::OsStr;
 
     #[inline]
-    pub fn is_sep(b: u8) -> bool {
+    pub fn is_sep_byte(b: u8) -> bool {
         b == b'/'
     }
 
@@ -156,34 +158,21 @@ pub fn parse_prefix(_: &OsStr) -> Option<Prefix> {
         None
     }
 
-    #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-    pub struct Prefix<'a>;
-
-    impl<'a> Prefix<'a> {
-        #[inline]
-        pub fn len(&self) -> usize { 0 }
-        #[inline]
-        pub fn is_verbatim(&self) -> bool { false }
-        #[inline]
-        pub fn is_drive(&self) -> bool { false }
-        #[inline]
-        pub fn has_implicit_root(&self) -> bool { false }
-    }
-
     pub const MAIN_SEP_STR: &'static str = "/";
+    pub const MAIN_SEP: char = '/';
 }
 
 #[cfg(windows)]
 mod platform {
     use core::prelude::*;
+    use ascii::*;
 
     use char::CharExt as UnicodeCharExt;
-    use super::{os_str_as_u8_slice, u8_slice_as_os_str};
-    use ascii::*;
+    use super::{os_str_as_u8_slice, u8_slice_as_os_str, Prefix};
     use ffi::OsStr;
 
     #[inline]
-    pub fn is_sep(b: u8) -> bool {
+    pub fn is_sep_byte(b: u8) -> bool {
         b == b'/' || b == b'\\'
     }
 
@@ -193,7 +182,7 @@ pub fn is_verbatim_sep(b: u8) -> bool {
     }
 
     pub fn parse_prefix<'a>(path: &'a OsStr) -> Option<Prefix> {
-        use self::Prefix::*;
+        use super::Prefix::*;
         unsafe {
             // The unsafety here stems from converting between &OsStr and &[u8]
             // and back. This is safe to do because (1) we only look at ASCII
@@ -224,8 +213,7 @@ pub fn parse_prefix<'a>(path: &'a OsStr) -> Option<Prefix> {
                             let c = path[0];
                             if c.is_ascii() && (c as char).is_alphabetic() {
                                 // \\?\C:\ path
-                                let slice = u8_slice_as_os_str(&path[0..1]);
-                                return Some(VerbatimDisk(slice));
+                                return Some(VerbatimDisk(c.to_ascii_uppercase()));
                             }
                         }
                         let slice = &path[.. idx.unwrap_or(path.len())];
@@ -237,7 +225,7 @@ pub fn parse_prefix<'a>(path: &'a OsStr) -> Option<Prefix> {
                     let slice = &path[.. path.position_elem(&b'\\').unwrap_or(path.len())];
                     return Some(DeviceNS(u8_slice_as_os_str(slice)));
                 }
-                match parse_two_comps(path, is_sep) {
+                match parse_two_comps(path, is_sep_byte) {
                     Some((server, share)) if server.len() > 0 && share.len() > 0 => {
                         // \\server\share
                         return Some(UNC(u8_slice_as_os_str(server),
@@ -249,7 +237,7 @@ pub fn parse_prefix<'a>(path: &'a OsStr) -> Option<Prefix> {
                 // C:
                 let c = path[0];
                 if c.is_ascii() && (c as char).is_alphabetic() {
-                    return Some(Disk(u8_slice_as_os_str(&path[0..1])));
+                    return Some(Disk(c.to_ascii_uppercase()));
                 }
             }
             return None;
@@ -267,99 +255,102 @@ fn parse_two_comps(mut path: &[u8], f: fn(u8) -> bool) -> Option<(&[u8], &[u8])>
         }
     }
 
-    /// Windows path prefixes.
-    ///
-    /// Windows uses a variety of path styles, including references to drive
-    /// volumes (like `C:`), network shared (like `\\server\share`) and
-    /// others. In addition, some path prefixes are "verbatim", in which case
-    /// `/` is *not* treated as a separator and essentially no normalization is
-    /// performed.
-    #[derive(Copy, Clone, Debug, Hash, Eq)]
-    pub enum Prefix<'a> {
-        /// Prefix `\\?\`, together with the given component immediately following it.
-        Verbatim(&'a OsStr),
-
-        /// Prefix `\\?\UNC\`, with the "server" and "share" components following it.
-        VerbatimUNC(&'a OsStr, &'a OsStr),
-
-        /// Prefix like `\\?\C:\`, for the given drive letter
-        VerbatimDisk(&'a OsStr),
-
-        /// Prefix `\\.\`, together with the given component immediately following it.
-        DeviceNS(&'a OsStr),
-
-        /// Prefix `\\server\share`, with the given "server" and "share" components.
-        UNC(&'a OsStr, &'a OsStr),
-
-        /// Prefix `C:` for the given disk drive.
-        Disk(&'a OsStr),
-    }
-
-    impl<'a> Prefix<'a> {
-        #[inline]
-        pub fn len(&self) -> usize {
-            use self::Prefix::*;
-            fn os_str_len(s: &OsStr) -> usize {
-                os_str_as_u8_slice(s).len()
-            }
-            match *self {
-                Verbatim(x) => 4 + os_str_len(x),
-                VerbatimUNC(x,y) => 8 + os_str_len(x) +
-                    if os_str_len(y) > 0 { 1 + os_str_len(y) }
-                    else { 0 },
-                VerbatimDisk(_) => 6,
-                UNC(x,y) => 2 + os_str_len(x) +
-                    if os_str_len(y) > 0 { 1 + os_str_len(y) }
-                    else { 0 },
-                DeviceNS(x) => 4 + os_str_len(x),
-                Disk(_) => 2
-            }
+    pub const MAIN_SEP_STR: &'static str = "\\";
+    pub const MAIN_SEP: char = '\\';
+}
 
-        }
+////////////////////////////////////////////////////////////////////////////////
+// Windows Prefixes
+////////////////////////////////////////////////////////////////////////////////
 
-        #[inline]
-        pub fn is_verbatim(&self) -> bool {
-            use self::Prefix::*;
-            match *self {
-                Verbatim(_) | VerbatimDisk(_) | VerbatimUNC(_, _) => true,
-                _ => false
-            }
-        }
+/// Path prefixes (Windows only).
+///
+/// Windows uses a variety of path styles, including references to drive
+/// volumes (like `C:`), network shared (like `\\server\share`) and
+/// others. In addition, some path prefixes are "verbatim", in which case
+/// `/` is *not* treated as a separator and essentially no normalization is
+/// performed.
+#[derive(Copy, Clone, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)]
+pub enum Prefix<'a> {
+    /// Prefix `\\?\`, together with the given component immediately following it.
+    Verbatim(&'a OsStr),
+
+    /// Prefix `\\?\UNC\`, with the "server" and "share" components following it.
+    VerbatimUNC(&'a OsStr, &'a OsStr),
+
+    /// Prefix like `\\?\C:\`, for the given drive letter
+    VerbatimDisk(u8),
+
+    /// Prefix `\\.\`, together with the given component immediately following it.
+    DeviceNS(&'a OsStr),
+
+    /// Prefix `\\server\share`, with the given "server" and "share" components.
+    UNC(&'a OsStr, &'a OsStr),
+
+    /// Prefix `C:` for the given disk drive.
+    Disk(u8),
+}
 
-        #[inline]
-        pub fn is_drive(&self) -> bool {
-            match *self {
-                Prefix::Disk(_) => true,
-                _ => false,
-            }
+impl<'a> Prefix<'a> {
+    #[inline]
+    fn len(&self) -> usize {
+        use self::Prefix::*;
+        fn os_str_len(s: &OsStr) -> usize {
+            os_str_as_u8_slice(s).len()
+        }
+        match *self {
+            Verbatim(x) => 4 + os_str_len(x),
+            VerbatimUNC(x,y) => 8 + os_str_len(x) +
+                if os_str_len(y) > 0 { 1 + os_str_len(y) }
+                else { 0 },
+            VerbatimDisk(_) => 6,
+            UNC(x,y) => 2 + os_str_len(x) +
+                if os_str_len(y) > 0 { 1 + os_str_len(y) }
+                else { 0 },
+            DeviceNS(x) => 4 + os_str_len(x),
+            Disk(_) => 2
         }
 
-        #[inline]
-        pub fn has_implicit_root(&self) -> bool {
-            !self.is_drive()
+    }
+
+    /// Determine if the prefix is verbatim, i.e. begins `\\?\`.
+    #[inline]
+    pub fn is_verbatim(&self) -> bool {
+        use self::Prefix::*;
+        match *self {
+            Verbatim(_) | VerbatimDisk(_) | VerbatimUNC(_, _) => true,
+            _ => false
         }
     }
 
-    impl<'a> PartialEq for Prefix<'a> {
-        fn eq(&self, other: &Prefix<'a>) -> bool {
-            use self::Prefix::*;
-            match (*self, *other) {
-                (Verbatim(x), Verbatim(y)) => x == y,
-                (VerbatimUNC(x1, x2), VerbatimUNC(y1, y2)) => x1 == y1 && x2 == y2,
-                (VerbatimDisk(x), VerbatimDisk(y)) =>
-                    os_str_as_u8_slice(x).eq_ignore_ascii_case(os_str_as_u8_slice(y)),
-                (DeviceNS(x), DeviceNS(y)) => x == y,
-                (UNC(x1, x2), UNC(y1, y2)) => x1 == y1 && x2 == y2,
-                (Disk(x), Disk(y)) =>
-                    os_str_as_u8_slice(x).eq_ignore_ascii_case(os_str_as_u8_slice(y)),
-                _ => false,
-            }
+    #[inline]
+    fn is_drive(&self) -> bool {
+        match *self {
+            Prefix::Disk(_) => true,
+            _ => false,
         }
     }
 
-    pub const MAIN_SEP_STR: &'static str = "\\";
+    #[inline]
+    fn has_implicit_root(&self) -> bool {
+        !self.is_drive()
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Exposed parsing helpers
+////////////////////////////////////////////////////////////////////////////////
+
+/// Determine whether the character is one of the permitted path
+/// separators for the current platform.
+pub fn is_separator(c: char) -> bool {
+    use ascii::*;
+    c.is_ascii() && is_sep_byte(c as u8)
 }
 
+/// The primary sperator for the current platform
+pub const MAIN_SEPARATOR: char = platform::MAIN_SEP;
+
 ////////////////////////////////////////////////////////////////////////////////
 // Misc helpers
 ////////////////////////////////////////////////////////////////////////////////
@@ -403,7 +394,7 @@ fn has_suffix(s: &[u8], prefix: Option<Prefix>) -> bool {
         (p.len(), p.is_verbatim())
     } else { (0, false) };
     if prefix_len > 0 && prefix_len == s.len() && !verbatim { return true; }
-    let mut splits = s[prefix_len..].split(|b| is_sep(*b));
+    let mut splits = s[prefix_len..].split(|b| is_sep_byte(*b));
     let last = splits.next_back().unwrap();
     let more = splits.next_back().is_some();
     more && last == b""
@@ -412,7 +403,7 @@ fn has_suffix(s: &[u8], prefix: Option<Prefix>) -> bool {
 /// Says whether the first byte after the prefix is a separator.
 fn has_physical_root(s: &[u8], prefix: Option<Prefix>) -> bool {
     let path = if let Some(p) = prefix { &s[p.len()..] } else { s };
-    path.len() > 0 && is_sep(path[0])
+    path.len() > 0 && is_sep_byte(path[0])
 }
 
 fn parse_single_component(comp: &[u8]) -> Option<Component> {
@@ -473,8 +464,16 @@ enum State {
 /// their role in the API.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 pub enum Component<'a> {
-    /// A Windows path prefix, e.g. `C:` or `\server\share`
-    Prefix(&'a OsStr),
+    /// A Windows path prefix, e.g. `C:` or `\server\share`.
+    ///
+    /// Does not occur on Unix.
+    Prefix {
+        /// The prefix as an unparsed `OsStr` slice.
+        raw: &'a OsStr,
+
+        /// The parsed prefix data.
+        parsed: Prefix<'a>
+    },
 
     /// An empty component. Only used on Windows for the last component of
     /// verbatim paths ending with a separator (e.g. the last component of
@@ -498,7 +497,7 @@ impl<'a> Component<'a> {
     /// Extract the underlying `OsStr` slice
     pub fn as_os_str(self) -> &'a OsStr {
         match self {
-            Component::Prefix(path) => path,
+            Component::Prefix { raw, .. } => &raw,
             Component::Empty => OsStr::from_str(""),
             Component::RootDir => OsStr::from_str(MAIN_SEP_STR),
             Component::CurDir => OsStr::from_str("."),
@@ -568,11 +567,11 @@ fn finished(&self) -> bool {
     }
 
     #[inline]
-    fn is_sep(&self, b: u8) -> bool {
+    fn is_sep_byte(&self, b: u8) -> bool {
         if self.prefix_verbatim() {
             is_verbatim_sep(b)
         } else {
-            is_sep(b)
+            is_sep_byte(b)
         }
     }
 
@@ -601,7 +600,7 @@ fn has_root(&self) -> bool {
     // remove the component
     fn parse_next_component(&self) -> (usize, Option<Component<'a>>) {
         debug_assert!(self.front == State::Body);
-        let (extra, comp) = match self.path.iter().position(|b| self.is_sep(*b)) {
+        let (extra, comp) = match self.path.iter().position(|b| self.is_sep_byte(*b)) {
             None => (0, self.path),
             Some(i) => (1, &self.path[.. i]),
         };
@@ -613,7 +612,7 @@ fn parse_next_component(&self) -> (usize, Option<Component<'a>>) {
     fn parse_next_component_back(&self) -> (usize, Option<Component<'a>>) {
         debug_assert!(self.back == State::Body);
         let start = self.prefix_and_root();
-        let (extra, comp) = match self.path[start..].iter().rposition(|b| self.is_sep(*b)) {
+        let (extra, comp) = match self.path[start..].iter().rposition(|b| self.is_sep_byte(*b)) {
             None => (0, &self.path[start ..]),
             Some(i) => (1, &self.path[start + i + 1 ..]),
         };
@@ -680,9 +679,12 @@ fn next(&mut self) -> Option<Component<'a>> {
                 State::Prefix if self.prefix_len() > 0 => {
                     self.front = State::Root;
                     debug_assert!(self.prefix_len() <= self.path.len());
-                    let prefix = &self.path[.. self.prefix_len()];
+                    let raw = &self.path[.. self.prefix_len()];
                     self.path = &self.path[self.prefix_len() .. ];
-                    return Some(Component::Prefix(unsafe { u8_slice_as_os_str(prefix) }))
+                    return Some(Component::Prefix {
+                        raw: unsafe { u8_slice_as_os_str(raw) },
+                        parsed: self.prefix.unwrap()
+                    })
                 }
                 State::Prefix => {
                     self.front = State::Root;
@@ -755,9 +757,10 @@ fn next_back(&mut self) -> Option<Component<'a>> {
                 }
                 State::Prefix if self.prefix_len() > 0 => {
                     self.back = State::Done;
-                    return Some(Component::Prefix(unsafe {
-                        u8_slice_as_os_str(self.path)
-                    }))
+                    return Some(Component::Prefix {
+                        raw: unsafe { u8_slice_as_os_str(self.path) },
+                        parsed: self.prefix.unwrap()
+                    })
                 }
                 State::Prefix => {
                     self.back = State::Done;
@@ -844,7 +847,7 @@ pub fn new<S: ?Sized + AsOsStr>(s: &S) -> PathBuf {
     /// * if `path` has a prefix but no root, it replaces `self.
     pub fn push<P: ?Sized>(&mut self, path: &P) where P: AsPath {
         // in general, a separator is needed if the rightmost byte is not a separator
-        let mut need_sep = self.as_mut_vec().last().map(|c| !is_sep(*c)).unwrap_or(false);
+        let mut need_sep = self.as_mut_vec().last().map(|c| !is_sep_byte(*c)).unwrap_or(false);
 
         // in the special case of `C:` on Windows, do *not* add a separator
         {
@@ -1142,11 +1145,11 @@ pub fn parent(&self) -> Option<&Path> {
 
         match (comp, comps.next_back()) {
             (Some(Component::CurDir), Some(Component::RootDir)) => None,
-            (Some(Component::CurDir), Some(Component::Prefix(_))) => None,
+            (Some(Component::CurDir), Some(Component::Prefix { .. })) => None,
             (Some(Component::Empty), Some(Component::RootDir)) => None,
-            (Some(Component::Empty), Some(Component::Prefix(_))) => None,
-            (Some(Component::Prefix(_)), None) => None,
-            (Some(Component::RootDir), Some(Component::Prefix(_))) => None,
+            (Some(Component::Empty), Some(Component::Prefix { .. })) => None,
+            (Some(Component::Prefix { .. }), None) => None,
+            (Some(Component::RootDir), Some(Component::Prefix { .. })) => None,
             _ => rest
         }
     }
index d2b98ec89390b1b7798734e3ef7870f3251f8b54..5baa095d35985c7b44aed14c10f4d49359f113ce 100644 (file)
@@ -27,7 +27,7 @@
 use sys::process2::Command as CommandImp;
 use sys::process2::ExitStatus as ExitStatusImp;
 use sys_common::{AsInner, AsInnerMut};
-use thread::Thread;
+use thread;
 
 /// Representation of a running or exited child process.
 ///
@@ -458,11 +458,11 @@ pub fn wait(&mut self) -> io::Result<ExitStatus> {
     /// the parent waits for the child to exit.
     pub fn wait_with_output(mut self) -> io::Result<Output> {
         drop(self.stdin.take());
-        fn read<T: Read + Send>(stream: Option<T>) -> Receiver<io::Result<Vec<u8>>> {
+        fn read<T: Read + Send + 'static>(stream: Option<T>) -> Receiver<io::Result<Vec<u8>>> {
             let (tx, rx) = channel();
             match stream {
                 Some(stream) => {
-                    Thread::spawn(move || {
+                    thread::spawn(move || {
                         let mut stream = stream;
                         let mut ret = Vec::new();
                         let res = stream.read_to_end(&mut ret);
@@ -499,7 +499,7 @@ mod tests {
     use str;
     use super::{Child, Command, Output, ExitStatus, Stdio};
     use sync::mpsc::channel;
-    use thread::Thread;
+    use thread;
     use time::Duration;
 
     // FIXME(#10380) these tests should not all be ignored on android.
@@ -537,12 +537,12 @@ fn exit_reported_right() {
     fn signal_reported_right() {
         use os::unix::ExitStatusExt;
 
-        let p = Command::new("/bin/sh").arg("-c").arg("kill -1 $$").spawn();
+        let p = Command::new("/bin/sh").arg("-c").arg("kill -9 $$").spawn();
         assert!(p.is_ok());
         let mut p = p.unwrap();
         match p.wait().unwrap().signal() {
-            Some(1) => {},
-            result => panic!("not terminated by signal 1 (instead, {:?})", result),
+            Some(9) => {},
+            result => panic!("not terminated by signal 9 (instead, {:?})", result),
         }
     }
 
index 8f9e966cbb2b7a9fbe29a33d8d7ff6fad8cd4b28..5b888c7612d195e214d59f60d9b0467b3593f124 100644 (file)
@@ -547,7 +547,7 @@ fn test_gen_vec() {
     #[test]
     fn test_choose() {
         let mut r = thread_rng();
-        assert_eq!(r.choose(&[1, 1, 1]).map(|&x|x), Some(1));
+        assert_eq!(r.choose(&[1, 1, 1]).cloned(), Some(1));
 
         let v: &[int] = &[];
         assert_eq!(r.choose(v), None);
index 535af08c96c70d70f25245008dddf8f5570a3b1c..0feacf5581c97414d6726b7d3ecebf598e69930b 100644 (file)
@@ -360,7 +360,7 @@ mod test {
     use sync::mpsc::channel;
     use rand::Rng;
     use super::OsRng;
-    use thread::Thread;
+    use thread;
 
     #[test]
     fn test_os_rng() {
@@ -381,23 +381,23 @@ fn test_os_rng_tasks() {
             let (tx, rx) = channel();
             txs.push(tx);
 
-            Thread::spawn(move|| {
+            thread::spawn(move|| {
                 // wait until all the tasks are ready to go.
                 rx.recv().unwrap();
 
                 // deschedule to attempt to interleave things as much
                 // as possible (XXX: is this a good test?)
                 let mut r = OsRng::new().unwrap();
-                Thread::yield_now();
+                thread::yield_now();
                 let mut v = [0u8; 1000];
 
                 for _ in 0u..100 {
                     r.next_u32();
-                    Thread::yield_now();
+                    thread::yield_now();
                     r.next_u64();
-                    Thread::yield_now();
+                    thread::yield_now();
                     r.fill_bytes(&mut v);
-                    Thread::yield_now();
+                    thread::yield_now();
                 }
             });
         }
index 3f15cf71ec3f74974e2f1fc8397ae1f9144c294b..72486fc55d48ee91ef09c3e4a73b3908c9d395d0 100644 (file)
@@ -20,7 +20,7 @@
 use thunk::Thunk;
 use sys_common::mutex::{Mutex, MUTEX_INIT};
 
-type Queue = Vec<Thunk>;
+type Queue = Vec<Thunk<'static>>;
 
 // NB these are specifically not types from `std::sync` as they currently rely
 // on poisoning and this module needs to operate at a lower level than requiring
@@ -65,7 +65,7 @@ pub fn cleanup() {
     }
 }
 
-pub fn push(f: Thunk) {
+pub fn push(f: Thunk<'static>) {
     unsafe {
         LOCK.lock();
         init();
index 00088d6d99a0a6af49b02b8910da11c29832cd00..42cca73e5e24128e2b40b92b64615277aa01da82 100644 (file)
@@ -148,7 +148,7 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
 ///
 /// It is forbidden for procedures to register more `at_exit` handlers when they
 /// are running, and doing so will lead to a process abort.
-pub fn at_exit<F:FnOnce()+Send>(f: F) {
+pub fn at_exit<F:FnOnce()+Send+'static>(f: F) {
     at_exit_imp::push(Thunk::new(f));
 }
 
index b45878584e02d0a957de8a86ea7d5957d57ae051..1f5eb3af695be8e09040c92463db3ce950031e97 100644 (file)
@@ -74,7 +74,7 @@
 
 struct Exception {
     uwe: uw::_Unwind_Exception,
-    cause: Option<Box<Any + Send>>,
+    cause: Option<Box<Any + Send + 'static>>,
 }
 
 pub type Callback = fn(msg: &(Any + Send), file: &'static str, line: uint);
@@ -161,7 +161,7 @@ pub fn panicking() -> bool {
 #[inline(never)]
 #[no_mangle]
 #[allow(private_no_mangle_fns)]
-fn rust_panic(cause: Box<Any + Send>) -> ! {
+fn rust_panic(cause: Box<Any + Send + 'static>) -> ! {
     rtdebug!("begin_unwind()");
 
     unsafe {
@@ -495,7 +495,7 @@ extern "C" fn inner(
 #[inline(never)] #[cold]
 #[stable(since = "1.0.0", feature = "rust1")]
 pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
-    use fmt::Writer;
+    use fmt::Write;
 
     // We do two allocations here, unfortunately. But (a) they're
     // required with the current scheme, and (b) we don't handle
index bb57d19ed2666ae45d172b64edfd0fea9488e96b..a304f1f844d748f8f263fc73db78d984ec38bbe9 100644 (file)
@@ -110,7 +110,7 @@ pub fn write_bytes(&mut self, data: &[u8]) {
     }
 }
 
-impl fmt::Writer for Stdio {
+impl fmt::Write for Stdio {
     fn write_str(&mut self, data: &str) -> fmt::Result {
         self.write_bytes(data.as_bytes());
         Ok(()) // yes, we're lying
@@ -122,13 +122,13 @@ pub fn dumb_print(args: fmt::Arguments) {
 }
 
 pub fn abort(args: fmt::Arguments) -> ! {
-    use fmt::Writer;
+    use fmt::Write;
 
     struct BufWriter<'a> {
         buf: &'a mut [u8],
         pos: uint,
     }
-    impl<'a> fmt::Writer for BufWriter<'a> {
+    impl<'a> fmt::Write for BufWriter<'a> {
         fn write_str(&mut self, bytes: &str) -> fmt::Result {
             let left = &mut self.buf[self.pos..];
             let to_write = &bytes.as_bytes()[..cmp::min(bytes.len(), left.len())];
@@ -149,7 +149,7 @@ fn write_str(&mut self, bytes: &str) -> fmt::Result {
 }
 
 pub unsafe fn report_overflow() {
-    use thread::Thread;
+    use thread;
 
     // See the message below for why this is not emitted to the
     // ^ Where did the message below go?
@@ -159,5 +159,5 @@ pub unsafe fn report_overflow() {
     // and the FFI call needs 2MB of stack when we just ran out.
 
     rterrln!("\nthread '{}' has overflowed its stack",
-             Thread::current().name().unwrap_or("<unknown>"));
+             thread::current().name().unwrap_or("<unknown>"));
 }
index cca376f7b6d05397776202005627afd0c6153b7c..fc781eb4bece4efa0f16b943b05875db5b7acecc 100644 (file)
 ///
 /// ```rust
 /// use std::sync::{Arc, Barrier};
-/// use std::thread::Thread;
+/// use std::thread;
 ///
 /// let barrier = Arc::new(Barrier::new(10));
 /// for _ in 0u..10 {
 ///     let c = barrier.clone();
 ///     // The same messages will be printed together.
 ///     // You will NOT see any interleaving.
-///     Thread::spawn(move|| {
+///     thread::spawn(move|| {
 ///         println!("before wait");
 ///         c.wait();
 ///         println!("after wait");
@@ -111,7 +111,7 @@ mod tests {
 
     use sync::{Arc, Barrier};
     use sync::mpsc::{channel, TryRecvError};
-    use thread::Thread;
+    use thread;
 
     #[test]
     fn test_barrier() {
@@ -123,7 +123,7 @@ fn test_barrier() {
         for _ in 0u..N - 1 {
             let c = barrier.clone();
             let tx = tx.clone();
-            Thread::spawn(move|| {
+            thread::spawn(move|| {
                 tx.send(c.wait().is_leader()).unwrap();
             });
         }
index d4d722cab3d929288aaea0d17989036cf21592f2..52561d482c39dcc4b5acf9a05de030865870b91d 100644 (file)
 ///
 /// ```
 /// use std::sync::{Arc, Mutex, Condvar};
-/// use std::thread::Thread;
+/// use std::thread;
 ///
 /// let pair = Arc::new((Mutex::new(false), Condvar::new()));
 /// let pair2 = pair.clone();
 ///
 /// // Inside of our lock, spawn a new thread, and then wait for it to start
-/// Thread::spawn(move|| {
+/// thread::spawn(move|| {
 ///     let &(ref lock, ref cvar) = &*pair2;
 ///     let mut started = lock.lock().unwrap();
 ///     *started = true;
@@ -353,7 +353,7 @@ mod tests {
     use sync::mpsc::channel;
     use sync::{StaticMutex, MUTEX_INIT, Condvar, Mutex, Arc};
     use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
-    use thread::Thread;
+    use thread;
     use time::Duration;
 
     #[test]
@@ -377,7 +377,7 @@ fn notify_one() {
         static M: StaticMutex = MUTEX_INIT;
 
         let g = M.lock().unwrap();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _g = M.lock().unwrap();
             C.notify_one();
         });
@@ -395,7 +395,7 @@ fn notify_all() {
         for _ in 0..N {
             let data = data.clone();
             let tx = tx.clone();
-            Thread::spawn(move|| {
+            thread::spawn(move|| {
                 let &(ref lock, ref cond) = &*data;
                 let mut cnt = lock.lock().unwrap();
                 *cnt += 1;
@@ -431,7 +431,7 @@ fn wait_timeout() {
         let (g, _no_timeout) = C.wait_timeout(g, Duration::nanoseconds(1000)).unwrap();
         // spurious wakeups mean this isn't necessarily true
         // assert!(!no_timeout);
-        let _t = Thread::spawn(move || {
+        let _t = thread::spawn(move || {
             let _g = M.lock().unwrap();
             C.notify_one();
         });
@@ -452,7 +452,7 @@ fn wait_timeout_with() {
         assert!(!success);
 
         let (tx, rx) = channel();
-        let _t = Thread::scoped(move || {
+        let _t = thread::spawn(move || {
             rx.recv().unwrap();
             let g = M.lock().unwrap();
             S.store(1, Ordering::SeqCst);
@@ -492,7 +492,7 @@ fn two_mutexes() {
         static C: StaticCondvar = CONDVAR_INIT;
 
         let mut g = M1.lock().unwrap();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _g = M1.lock().unwrap();
             C.notify_one();
         });
index a230e35dac8c3db163a46ba7b4e56713c3f804b0..d60e27388086444a4323c8f53525a8046b28ecec 100644 (file)
@@ -38,7 +38,7 @@
 use self::FutureState::*;
 use sync::mpsc::{Receiver, channel};
 use thunk::{Thunk};
-use thread::Thread;
+use thread;
 
 /// A type encapsulating the result of a computation which may not be complete
 pub struct Future<A> {
@@ -46,7 +46,7 @@ pub struct Future<A> {
 }
 
 enum FutureState<A> {
-    Pending(Thunk<(),A>),
+    Pending(Thunk<'static,(),A>),
     Evaluating,
     Forced(A)
 }
@@ -103,7 +103,7 @@ pub fn from_value(val: A) -> Future<A> {
     }
 
     pub fn from_fn<F>(f: F) -> Future<A>
-        where F : FnOnce() -> A, F : Send
+        where F : FnOnce() -> A, F : Send + 'static
     {
         /*!
          * Create a future from a function.
@@ -117,7 +117,7 @@ pub fn from_fn<F>(f: F) -> Future<A>
     }
 }
 
-impl<A:Send> Future<A> {
+impl<A:Send+'static> Future<A> {
     pub fn from_receiver(rx: Receiver<A>) -> Future<A> {
         /*!
          * Create a future from a port
@@ -132,7 +132,7 @@ pub fn from_receiver(rx: Receiver<A>) -> Future<A> {
     }
 
     pub fn spawn<F>(blk: F) -> Future<A>
-        where F : FnOnce() -> A, F : Send
+        where F : FnOnce() -> A, F : Send + 'static
     {
         /*!
          * Create a future from a unique closure.
@@ -143,7 +143,7 @@ pub fn spawn<F>(blk: F) -> Future<A>
 
         let (tx, rx) = channel();
 
-        Thread::spawn(move || {
+        thread::spawn(move || {
             // Don't panic if the other end has hung up
             let _ = tx.send(blk());
         });
@@ -157,7 +157,7 @@ mod test {
     use prelude::v1::*;
     use sync::mpsc::channel;
     use sync::Future;
-    use thread::Thread;
+    use thread;
 
     #[test]
     fn test_from_value() {
@@ -215,7 +215,7 @@ fn test_sendable_future() {
         let expected = "schlorf";
         let (tx, rx) = channel();
         let f = Future::spawn(move|| { expected });
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut f = f;
             tx.send(f.get()).unwrap();
         });
index 61ffb532d36ad49cb20a97822371d53ac7af5b73..69b1e242b154d472857c032aab0ff00cdec3366c 100644 (file)
@@ -10,7 +10,7 @@
 
 //! Generic support for building blocking abstractions.
 
-use thread::Thread;
+use thread::{self, Thread};
 use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
 use sync::Arc;
 use marker::{Sync, Send};
@@ -40,7 +40,7 @@ impl !Sync for WaitToken {}
 
 pub fn tokens() -> (WaitToken, SignalToken) {
     let inner = Arc::new(Inner {
-        thread: Thread::current(),
+        thread: thread::current(),
         woken: ATOMIC_BOOL_INIT,
     });
     let wait_token = WaitToken {
@@ -80,7 +80,7 @@ pub unsafe fn cast_from_uint(signal_ptr: uint) -> SignalToken {
 impl WaitToken {
     pub fn wait(self) {
         while !self.inner.woken.load(Ordering::SeqCst) {
-            Thread::park()
+            thread::park()
         }
     }
 }
index d783acd57ac04356fe6e6f06fa1e722f1cfbd1fd..410d3c0ecd5e459cb9c84c6e68386dfd0beaaa46 100644 (file)
 //! Simple usage:
 //!
 //! ```
-//! use std::thread::Thread;
+//! use std::thread;
 //! use std::sync::mpsc::channel;
 //!
 //! // Create a simple streaming channel
 //! let (tx, rx) = channel();
-//! Thread::spawn(move|| {
+//! thread::spawn(move|| {
 //!     tx.send(10).unwrap();
 //! });
 //! assert_eq!(rx.recv().unwrap(), 10);
@@ -67,7 +67,7 @@
 //! Shared usage:
 //!
 //! ```
-//! use std::thread::Thread;
+//! use std::thread;
 //! use std::sync::mpsc::channel;
 //!
 //! // Create a shared channel that can be sent along from many threads
@@ -76,7 +76,7 @@
 //! let (tx, rx) = channel();
 //! for i in 0..10 {
 //!     let tx = tx.clone();
-//!     Thread::spawn(move|| {
+//!     thread::spawn(move|| {
 //!         tx.send(i).unwrap();
 //!     });
 //! }
 //! Synchronous channels:
 //!
 //! ```
-//! use std::thread::Thread;
+//! use std::thread;
 //! use std::sync::mpsc::sync_channel;
 //!
 //! let (tx, rx) = sync_channel::<int>(0);
-//! Thread::spawn(move|| {
+//! thread::spawn(move|| {
 //!     // This will wait for the parent task to start receiving
 //!     tx.send(53).unwrap();
 //! });
@@ -345,7 +345,7 @@ pub struct Receiver<T> {
 
 // The receiver port can be sent from place to place, so long as it
 // is not used to receive non-sendable things.
-unsafe impl<T:Send> Send for Receiver<T> { }
+unsafe impl<T: Send + 'static> Send for Receiver<T> { }
 
 /// An iterator over messages on a receiver, this iterator will block
 /// whenever `next` is called, waiting for a new message, and `None` will be
@@ -364,7 +364,7 @@ pub struct Sender<T> {
 
 // The send port can be sent from place to place, so long as it
 // is not used to send non-sendable things.
-unsafe impl<T:Send> Send for Sender<T> { }
+unsafe impl<T: Send + 'static> Send for Sender<T> { }
 
 /// The sending-half of Rust's synchronous channel type. This half can only be
 /// owned by one task, but it can be cloned to send to other tasks.
@@ -373,7 +373,7 @@ pub struct SyncSender<T> {
     inner: Arc<UnsafeCell<sync::Packet<T>>>,
 }
 
-unsafe impl<T:Send> Send for SyncSender<T> {}
+unsafe impl<T: Send + 'static> Send for SyncSender<T> {}
 
 impl<T> !Sync for SyncSender<T> {}
 
@@ -467,14 +467,14 @@ fn inner_unsafe<'a>(&'a self) -> &'a UnsafeCell<Flavor<T>> {
 ///
 /// ```
 /// use std::sync::mpsc::channel;
-/// use std::thread::Thread;
+/// use std::thread;
 ///
 /// // tx is is the sending half (tx for transmission), and rx is the receiving
 /// // half (rx for receiving).
 /// let (tx, rx) = channel();
 ///
 /// // Spawn off an expensive computation
-/// Thread::spawn(move|| {
+/// thread::spawn(move|| {
 /// #   fn expensive_computation() {}
 ///     tx.send(expensive_computation()).unwrap();
 /// });
@@ -485,7 +485,7 @@ fn inner_unsafe<'a>(&'a self) -> &'a UnsafeCell<Flavor<T>> {
 /// println!("{:?}", rx.recv().unwrap());
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) {
+pub fn channel<T: Send + 'static>() -> (Sender<T>, Receiver<T>) {
     let a = Arc::new(UnsafeCell::new(oneshot::Packet::new()));
     (Sender::new(Flavor::Oneshot(a.clone())), Receiver::new(Flavor::Oneshot(a)))
 }
@@ -509,14 +509,14 @@ pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) {
 ///
 /// ```
 /// use std::sync::mpsc::sync_channel;
-/// use std::thread::Thread;
+/// use std::thread;
 ///
 /// let (tx, rx) = sync_channel(1);
 ///
 /// // this returns immediately
 /// tx.send(1).unwrap();
 ///
-/// Thread::spawn(move|| {
+/// thread::spawn(move|| {
 ///     // this will block until the previous message has been received
 ///     tx.send(2).unwrap();
 /// });
@@ -525,7 +525,7 @@ pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) {
 /// assert_eq!(rx.recv().unwrap(), 2);
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn sync_channel<T: Send>(bound: uint) -> (SyncSender<T>, Receiver<T>) {
+pub fn sync_channel<T: Send + 'static>(bound: uint) -> (SyncSender<T>, Receiver<T>) {
     let a = Arc::new(UnsafeCell::new(sync::Packet::new(bound)));
     (SyncSender::new(a.clone()), Receiver::new(Flavor::Sync(a)))
 }
@@ -534,7 +534,7 @@ pub fn sync_channel<T: Send>(bound: uint) -> (SyncSender<T>, Receiver<T>) {
 // Sender
 ////////////////////////////////////////////////////////////////////////////////
 
-impl<T: Send> Sender<T> {
+impl<T: Send + 'static> Sender<T> {
     fn new(inner: Flavor<T>) -> Sender<T> {
         Sender {
             inner: UnsafeCell::new(inner),
@@ -616,7 +616,7 @@ pub fn send(&self, t: T) -> Result<(), SendError<T>> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> Clone for Sender<T> {
+impl<T: Send + 'static> Clone for Sender<T> {
     fn clone(&self) -> Sender<T> {
         let (packet, sleeper, guard) = match *unsafe { self.inner() } {
             Flavor::Oneshot(ref p) => {
@@ -662,7 +662,7 @@ fn clone(&self) -> Sender<T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> Drop for Sender<T> {
+impl<T: Send + 'static> Drop for Sender<T> {
     fn drop(&mut self) {
         match *unsafe { self.inner_mut() } {
             Flavor::Oneshot(ref mut p) => unsafe { (*p.get()).drop_chan(); },
@@ -677,7 +677,7 @@ fn drop(&mut self) {
 // SyncSender
 ////////////////////////////////////////////////////////////////////////////////
 
-impl<T: Send> SyncSender<T> {
+impl<T: Send + 'static> SyncSender<T> {
     fn new(inner: Arc<UnsafeCell<sync::Packet<T>>>) -> SyncSender<T> {
         SyncSender { inner: inner }
     }
@@ -717,7 +717,7 @@ pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> Clone for SyncSender<T> {
+impl<T: Send + 'static> Clone for SyncSender<T> {
     fn clone(&self) -> SyncSender<T> {
         unsafe { (*self.inner.get()).clone_chan(); }
         return SyncSender::new(self.inner.clone());
@@ -726,7 +726,7 @@ fn clone(&self) -> SyncSender<T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> Drop for SyncSender<T> {
+impl<T: Send + 'static> Drop for SyncSender<T> {
     fn drop(&mut self) {
         unsafe { (*self.inner.get()).drop_chan(); }
     }
@@ -736,7 +736,7 @@ fn drop(&mut self) {
 // Receiver
 ////////////////////////////////////////////////////////////////////////////////
 
-impl<T: Send> Receiver<T> {
+impl<T: Send + 'static> Receiver<T> {
     fn new(inner: Flavor<T>) -> Receiver<T> {
         Receiver { inner: UnsafeCell::new(inner) }
     }
@@ -855,7 +855,7 @@ pub fn iter(&self) -> Iter<T> {
     }
 }
 
-impl<T: Send> select::Packet for Receiver<T> {
+impl<T: Send + 'static> select::Packet for Receiver<T> {
     fn can_recv(&self) -> bool {
         loop {
             let new_port = match *unsafe { self.inner() } {
@@ -942,7 +942,7 @@ fn abort_selection(&self) -> bool {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T: Send> Iterator for Iter<'a, T> {
+impl<'a, T: Send + 'static> Iterator for Iter<'a, T> {
     type Item = T;
 
     fn next(&mut self) -> Option<T> { self.rx.recv().ok() }
@@ -950,7 +950,7 @@ fn next(&mut self) -> Option<T> { self.rx.recv().ok() }
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> Drop for Receiver<T> {
+impl<T: Send + 'static> Drop for Receiver<T> {
     fn drop(&mut self) {
         match *unsafe { self.inner_mut() } {
             Flavor::Oneshot(ref mut p) => unsafe { (*p.get()).drop_port(); },
@@ -1026,7 +1026,7 @@ mod test {
 
     use std::env;
     use super::*;
-    use thread::Thread;
+    use thread;
 
     pub fn stress_factor() -> uint {
         match env::var("RUST_TEST_STRESS") {
@@ -1069,7 +1069,7 @@ fn smoke_shared() {
     #[test]
     fn smoke_threads() {
         let (tx, rx) = channel::<int>();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             tx.send(1).unwrap();
         });
         assert_eq!(rx.recv().unwrap(), 1);
@@ -1101,7 +1101,7 @@ fn smoke_shared_port_gone2() {
     #[test]
     fn port_gone_concurrent() {
         let (tx, rx) = channel::<int>();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             rx.recv().unwrap();
         });
         while tx.send(1).is_ok() {}
@@ -1111,7 +1111,7 @@ fn port_gone_concurrent() {
     fn port_gone_concurrent_shared() {
         let (tx, rx) = channel::<int>();
         let tx2 = tx.clone();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             rx.recv().unwrap();
         });
         while tx.send(1).is_ok() && tx2.send(1).is_ok() {}
@@ -1136,7 +1136,7 @@ fn smoke_chan_gone_shared() {
     #[test]
     fn chan_gone_concurrent() {
         let (tx, rx) = channel::<int>();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             tx.send(1).unwrap();
             tx.send(1).unwrap();
         });
@@ -1146,7 +1146,7 @@ fn chan_gone_concurrent() {
     #[test]
     fn stress() {
         let (tx, rx) = channel::<int>();
-        let t = Thread::scoped(move|| {
+        let t = thread::spawn(move|| {
             for _ in 0u..10000 { tx.send(1).unwrap(); }
         });
         for _ in 0u..10000 {
@@ -1161,7 +1161,7 @@ fn stress_shared() {
         static NTHREADS: uint = 8;
         let (tx, rx) = channel::<int>();
 
-        let t = Thread::scoped(move|| {
+        let t = thread::spawn(move|| {
             for _ in 0..AMT * NTHREADS {
                 assert_eq!(rx.recv().unwrap(), 1);
             }
@@ -1173,7 +1173,7 @@ fn stress_shared() {
 
         for _ in 0..NTHREADS {
             let tx = tx.clone();
-            Thread::spawn(move|| {
+            thread::spawn(move|| {
                 for _ in 0..AMT { tx.send(1).unwrap(); }
             });
         }
@@ -1185,14 +1185,14 @@ fn stress_shared() {
     fn send_from_outside_runtime() {
         let (tx1, rx1) = channel::<()>();
         let (tx2, rx2) = channel::<int>();
-        let t1 = Thread::scoped(move|| {
+        let t1 = thread::spawn(move|| {
             tx1.send(()).unwrap();
             for _ in 0..40 {
                 assert_eq!(rx2.recv().unwrap(), 1);
             }
         });
         rx1.recv().unwrap();
-        let t2 = Thread::scoped(move|| {
+        let t2 = thread::spawn(move|| {
             for _ in 0..40 {
                 tx2.send(1).unwrap();
             }
@@ -1204,7 +1204,7 @@ fn send_from_outside_runtime() {
     #[test]
     fn recv_from_outside_runtime() {
         let (tx, rx) = channel::<int>();
-        let t = Thread::scoped(move|| {
+        let t = thread::spawn(move|| {
             for _ in 0..40 {
                 assert_eq!(rx.recv().unwrap(), 1);
             }
@@ -1219,11 +1219,11 @@ fn recv_from_outside_runtime() {
     fn no_runtime() {
         let (tx1, rx1) = channel::<int>();
         let (tx2, rx2) = channel::<int>();
-        let t1 = Thread::scoped(move|| {
+        let t1 = thread::spawn(move|| {
             assert_eq!(rx1.recv().unwrap(), 1);
             tx2.send(2).unwrap();
         });
-        let t2 = Thread::scoped(move|| {
+        let t2 = thread::spawn(move|| {
             tx1.send(1).unwrap();
             assert_eq!(rx2.recv().unwrap(), 2);
         });
@@ -1256,7 +1256,7 @@ fn oneshot_single_thread_send_port_close() {
     #[test]
     fn oneshot_single_thread_recv_chan_close() {
         // Receiving on a closed chan will panic
-        let res = Thread::scoped(move|| {
+        let res = thread::spawn(move|| {
             let (tx, rx) = channel::<int>();
             drop(tx);
             rx.recv().unwrap();
@@ -1325,7 +1325,7 @@ fn oneshot_single_thread_peek_open() {
     #[test]
     fn oneshot_multi_task_recv_then_send() {
         let (tx, rx) = channel::<Box<int>>();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             assert!(rx.recv().unwrap() == box 10);
         });
 
@@ -1335,10 +1335,10 @@ fn oneshot_multi_task_recv_then_send() {
     #[test]
     fn oneshot_multi_task_recv_then_close() {
         let (tx, rx) = channel::<Box<int>>();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             drop(tx);
         });
-        let res = Thread::scoped(move|| {
+        let res = thread::spawn(move|| {
             assert!(rx.recv().unwrap() == box 10);
         }).join();
         assert!(res.is_err());
@@ -1348,7 +1348,7 @@ fn oneshot_multi_task_recv_then_close() {
     fn oneshot_multi_thread_close_stress() {
         for _ in 0..stress_factor() {
             let (tx, rx) = channel::<int>();
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 drop(rx);
             });
             drop(tx);
@@ -1359,10 +1359,10 @@ fn oneshot_multi_thread_close_stress() {
     fn oneshot_multi_thread_send_close_stress() {
         for _ in 0..stress_factor() {
             let (tx, rx) = channel::<int>();
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 drop(rx);
             });
-            let _ = Thread::scoped(move|| {
+            let _ = thread::spawn(move|| {
                 tx.send(1).unwrap();
             }).join();
         }
@@ -1372,14 +1372,14 @@ fn oneshot_multi_thread_send_close_stress() {
     fn oneshot_multi_thread_recv_close_stress() {
         for _ in 0..stress_factor() {
             let (tx, rx) = channel::<int>();
-            Thread::spawn(move|| {
-                let res = Thread::scoped(move|| {
+            thread::spawn(move|| {
+                let res = thread::spawn(move|| {
                     rx.recv().unwrap();
                 }).join();
                 assert!(res.is_err());
             });
-            let _t = Thread::spawn(move|| {
-                Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
+                thread::spawn(move|| {
                     drop(tx);
                 });
             });
@@ -1390,7 +1390,7 @@ fn oneshot_multi_thread_recv_close_stress() {
     fn oneshot_multi_thread_send_recv_stress() {
         for _ in 0..stress_factor() {
             let (tx, rx) = channel();
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 tx.send(box 10).unwrap();
             });
             assert!(rx.recv().unwrap() == box 10);
@@ -1408,7 +1408,7 @@ fn stream_send_recv_stress() {
             fn send(tx: Sender<Box<int>>, i: int) {
                 if i == 10 { return }
 
-                Thread::spawn(move|| {
+                thread::spawn(move|| {
                     tx.send(box i).unwrap();
                     send(tx, i + 1);
                 });
@@ -1417,7 +1417,7 @@ fn send(tx: Sender<Box<int>>, i: int) {
             fn recv(rx: Receiver<Box<int>>, i: int) {
                 if i == 10 { return }
 
-                Thread::spawn(move|| {
+                thread::spawn(move|| {
                     assert!(rx.recv().unwrap() == box i);
                     recv(rx, i + 1);
                 });
@@ -1439,7 +1439,7 @@ fn shared_chan_stress() {
         let total = stress_factor() + 100;
         for _ in 0..total {
             let tx = tx.clone();
-            Thread::spawn(move|| {
+            thread::spawn(move|| {
                 tx.send(()).unwrap();
             });
         }
@@ -1454,7 +1454,7 @@ fn test_nested_recv_iter() {
         let (tx, rx) = channel::<int>();
         let (total_tx, total_rx) = channel::<int>();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut acc = 0;
             for x in rx.iter() {
                 acc += x;
@@ -1474,7 +1474,7 @@ fn test_recv_iter_break() {
         let (tx, rx) = channel::<int>();
         let (count_tx, count_rx) = channel();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut count = 0;
             for x in rx.iter() {
                 if count >= 3 {
@@ -1499,7 +1499,7 @@ fn try_recv_states() {
         let (tx1, rx1) = channel::<int>();
         let (tx2, rx2) = channel::<()>();
         let (tx3, rx3) = channel::<()>();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             rx2.recv().unwrap();
             tx1.send(1).unwrap();
             tx3.send(()).unwrap();
@@ -1524,13 +1524,13 @@ fn try_recv_states() {
     fn destroy_upgraded_shared_port_when_sender_still_active() {
         let (tx, rx) = channel();
         let (tx2, rx2) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             rx.recv().unwrap(); // wait on a oneshot
             drop(rx);  // destroy a shared
             tx2.send(()).unwrap();
         });
         // make sure the other task has gone to sleep
-        for _ in 0u..5000 { Thread::yield_now(); }
+        for _ in 0u..5000 { thread::yield_now(); }
 
         // upgrade to a shared chan and send a message
         let t = tx.clone();
@@ -1547,7 +1547,7 @@ mod sync_tests {
     use prelude::v1::*;
 
     use std::env;
-    use thread::Thread;
+    use thread;
     use super::*;
 
     pub fn stress_factor() -> uint {
@@ -1583,7 +1583,7 @@ fn smoke_shared() {
     #[test]
     fn smoke_threads() {
         let (tx, rx) = sync_channel::<int>(0);
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             tx.send(1).unwrap();
         });
         assert_eq!(rx.recv().unwrap(), 1);
@@ -1608,7 +1608,7 @@ fn smoke_shared_port_gone2() {
     #[test]
     fn port_gone_concurrent() {
         let (tx, rx) = sync_channel::<int>(0);
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             rx.recv().unwrap();
         });
         while tx.send(1).is_ok() {}
@@ -1618,7 +1618,7 @@ fn port_gone_concurrent() {
     fn port_gone_concurrent_shared() {
         let (tx, rx) = sync_channel::<int>(0);
         let tx2 = tx.clone();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             rx.recv().unwrap();
         });
         while tx.send(1).is_ok() && tx2.send(1).is_ok() {}
@@ -1643,7 +1643,7 @@ fn smoke_chan_gone_shared() {
     #[test]
     fn chan_gone_concurrent() {
         let (tx, rx) = sync_channel::<int>(0);
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             tx.send(1).unwrap();
             tx.send(1).unwrap();
         });
@@ -1653,7 +1653,7 @@ fn chan_gone_concurrent() {
     #[test]
     fn stress() {
         let (tx, rx) = sync_channel::<int>(0);
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             for _ in 0u..10000 { tx.send(1).unwrap(); }
         });
         for _ in 0u..10000 {
@@ -1668,7 +1668,7 @@ fn stress_shared() {
         let (tx, rx) = sync_channel::<int>(0);
         let (dtx, drx) = sync_channel::<()>(0);
 
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             for _ in 0..AMT * NTHREADS {
                 assert_eq!(rx.recv().unwrap(), 1);
             }
@@ -1681,7 +1681,7 @@ fn stress_shared() {
 
         for _ in 0..NTHREADS {
             let tx = tx.clone();
-            Thread::spawn(move|| {
+            thread::spawn(move|| {
                 for _ in 0..AMT { tx.send(1).unwrap(); }
             });
         }
@@ -1714,7 +1714,7 @@ fn oneshot_single_thread_send_port_close() {
     #[test]
     fn oneshot_single_thread_recv_chan_close() {
         // Receiving on a closed chan will panic
-        let res = Thread::scoped(move|| {
+        let res = thread::spawn(move|| {
             let (tx, rx) = sync_channel::<int>(0);
             drop(tx);
             rx.recv().unwrap();
@@ -1789,7 +1789,7 @@ fn oneshot_single_thread_peek_open() {
     #[test]
     fn oneshot_multi_task_recv_then_send() {
         let (tx, rx) = sync_channel::<Box<int>>(0);
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             assert!(rx.recv().unwrap() == box 10);
         });
 
@@ -1799,10 +1799,10 @@ fn oneshot_multi_task_recv_then_send() {
     #[test]
     fn oneshot_multi_task_recv_then_close() {
         let (tx, rx) = sync_channel::<Box<int>>(0);
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             drop(tx);
         });
-        let res = Thread::scoped(move|| {
+        let res = thread::spawn(move|| {
             assert!(rx.recv().unwrap() == box 10);
         }).join();
         assert!(res.is_err());
@@ -1812,7 +1812,7 @@ fn oneshot_multi_task_recv_then_close() {
     fn oneshot_multi_thread_close_stress() {
         for _ in 0..stress_factor() {
             let (tx, rx) = sync_channel::<int>(0);
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 drop(rx);
             });
             drop(tx);
@@ -1823,10 +1823,10 @@ fn oneshot_multi_thread_close_stress() {
     fn oneshot_multi_thread_send_close_stress() {
         for _ in 0..stress_factor() {
             let (tx, rx) = sync_channel::<int>(0);
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 drop(rx);
             });
-            let _ = Thread::scoped(move || {
+            let _ = thread::spawn(move || {
                 tx.send(1).unwrap();
             }).join();
         }
@@ -1836,14 +1836,14 @@ fn oneshot_multi_thread_send_close_stress() {
     fn oneshot_multi_thread_recv_close_stress() {
         for _ in 0..stress_factor() {
             let (tx, rx) = sync_channel::<int>(0);
-            let _t = Thread::spawn(move|| {
-                let res = Thread::scoped(move|| {
+            let _t = thread::spawn(move|| {
+                let res = thread::spawn(move|| {
                     rx.recv().unwrap();
                 }).join();
                 assert!(res.is_err());
             });
-            let _t = Thread::spawn(move|| {
-                Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
+                thread::spawn(move|| {
                     drop(tx);
                 });
             });
@@ -1854,7 +1854,7 @@ fn oneshot_multi_thread_recv_close_stress() {
     fn oneshot_multi_thread_send_recv_stress() {
         for _ in 0..stress_factor() {
             let (tx, rx) = sync_channel::<Box<int>>(0);
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 tx.send(box 10).unwrap();
             });
             assert!(rx.recv().unwrap() == box 10);
@@ -1872,7 +1872,7 @@ fn stream_send_recv_stress() {
             fn send(tx: SyncSender<Box<int>>, i: int) {
                 if i == 10 { return }
 
-                Thread::spawn(move|| {
+                thread::spawn(move|| {
                     tx.send(box i).unwrap();
                     send(tx, i + 1);
                 });
@@ -1881,7 +1881,7 @@ fn send(tx: SyncSender<Box<int>>, i: int) {
             fn recv(rx: Receiver<Box<int>>, i: int) {
                 if i == 10 { return }
 
-                Thread::spawn(move|| {
+                thread::spawn(move|| {
                     assert!(rx.recv().unwrap() == box i);
                     recv(rx, i + 1);
                 });
@@ -1903,7 +1903,7 @@ fn shared_chan_stress() {
         let total = stress_factor() + 100;
         for _ in 0..total {
             let tx = tx.clone();
-            Thread::spawn(move|| {
+            thread::spawn(move|| {
                 tx.send(()).unwrap();
             });
         }
@@ -1918,7 +1918,7 @@ fn test_nested_recv_iter() {
         let (tx, rx) = sync_channel::<int>(0);
         let (total_tx, total_rx) = sync_channel::<int>(0);
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut acc = 0;
             for x in rx.iter() {
                 acc += x;
@@ -1938,7 +1938,7 @@ fn test_recv_iter_break() {
         let (tx, rx) = sync_channel::<int>(0);
         let (count_tx, count_rx) = sync_channel(0);
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let mut count = 0;
             for x in rx.iter() {
                 if count >= 3 {
@@ -1963,7 +1963,7 @@ fn try_recv_states() {
         let (tx1, rx1) = sync_channel::<int>(1);
         let (tx2, rx2) = sync_channel::<()>(1);
         let (tx3, rx3) = sync_channel::<()>(1);
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             rx2.recv().unwrap();
             tx1.send(1).unwrap();
             tx3.send(()).unwrap();
@@ -1988,13 +1988,13 @@ fn try_recv_states() {
     fn destroy_upgraded_shared_port_when_sender_still_active() {
         let (tx, rx) = sync_channel::<()>(0);
         let (tx2, rx2) = sync_channel::<()>(0);
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             rx.recv().unwrap(); // wait on a oneshot
             drop(rx);  // destroy a shared
             tx2.send(()).unwrap();
         });
         // make sure the other task has gone to sleep
-        for _ in 0u..5000 { Thread::yield_now(); }
+        for _ in 0u..5000 { thread::yield_now(); }
 
         // upgrade to a shared chan and send a message
         let t = tx.clone();
@@ -2008,14 +2008,14 @@ fn destroy_upgraded_shared_port_when_sender_still_active() {
     #[test]
     fn send1() {
         let (tx, rx) = sync_channel::<int>(0);
-        let _t = Thread::spawn(move|| { rx.recv().unwrap(); });
+        let _t = thread::spawn(move|| { rx.recv().unwrap(); });
         assert_eq!(tx.send(1), Ok(()));
     }
 
     #[test]
     fn send2() {
         let (tx, rx) = sync_channel::<int>(0);
-        let _t = Thread::spawn(move|| { drop(rx); });
+        let _t = thread::spawn(move|| { drop(rx); });
         assert!(tx.send(1).is_err());
     }
 
@@ -2023,7 +2023,7 @@ fn send2() {
     fn send3() {
         let (tx, rx) = sync_channel::<int>(1);
         assert_eq!(tx.send(1), Ok(()));
-        let _t =Thread::spawn(move|| { drop(rx); });
+        let _t =thread::spawn(move|| { drop(rx); });
         assert!(tx.send(1).is_err());
     }
 
@@ -2033,11 +2033,11 @@ fn send4() {
         let tx2 = tx.clone();
         let (done, donerx) = channel();
         let done2 = done.clone();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             assert!(tx.send(1).is_err());
             done.send(()).unwrap();
         });
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             assert!(tx2.send(2).is_err());
             done2.send(()).unwrap();
         });
@@ -2073,7 +2073,7 @@ fn repro() {
             let (tx1, rx1) = sync_channel::<()>(3);
             let (tx2, rx2) = sync_channel::<()>(3);
 
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 rx1.recv().unwrap();
                 tx2.try_send(()).unwrap();
             });
index 3980d2a1fefb521820fbe1b45863f6d45d584633..0a4ff8769abf49ba675a4e80ebf24459913c4e59 100644 (file)
@@ -78,7 +78,7 @@ pub struct Queue<T> {
 }
 
 unsafe impl<T:Send> Send for Queue<T> { }
-unsafe impl<T:Send> Sync for Queue<T> { }
+unsafe impl<T: Send + 'static> Sync for Queue<T> { }
 
 impl<T> Node<T> {
     unsafe fn new(v: Option<T>) -> *mut Node<T> {
@@ -89,7 +89,7 @@ unsafe fn new(v: Option<T>) -> *mut Node<T> {
     }
 }
 
-impl<T: Send> Queue<T> {
+impl<T: Send + 'static> Queue<T> {
     /// Creates a new queue that is safe to share among multiple producers and
     /// one consumer.
     pub fn new() -> Queue<T> {
@@ -140,7 +140,7 @@ pub fn pop(&self) -> PopResult<T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> Drop for Queue<T> {
+impl<T: Send + 'static> Drop for Queue<T> {
     fn drop(&mut self) {
         unsafe {
             let mut cur = *self.tail.get();
@@ -160,7 +160,7 @@ mod tests {
     use sync::mpsc::channel;
     use super::{Queue, Data, Empty, Inconsistent};
     use sync::Arc;
-    use thread::Thread;
+    use thread;
 
     #[test]
     fn test_full() {
@@ -184,7 +184,7 @@ fn test() {
         for _ in 0..nthreads {
             let tx = tx.clone();
             let q = q.clone();
-            Thread::spawn(move|| {
+            thread::spawn(move|| {
                 for i in 0..nmsgs {
                     q.push(i);
                 }
index eb45681fa626d6e3018447c676efe23b688ce478..55b2caf7c6d4cccea53aa2331ea3defaf0113524 100644 (file)
@@ -88,7 +88,7 @@ enum MyUpgrade<T> {
     GoUp(Receiver<T>),
 }
 
-impl<T: Send> Packet<T> {
+impl<T: Send + 'static> Packet<T> {
     pub fn new() -> Packet<T> {
         Packet {
             data: None,
@@ -368,7 +368,7 @@ pub fn abort_selection(&mut self) -> Result<bool, Receiver<T>> {
 }
 
 #[unsafe_destructor]
-impl<T: Send> Drop for Packet<T> {
+impl<T: Send + 'static> Drop for Packet<T> {
     fn drop(&mut self) {
         assert_eq!(self.state.load(Ordering::SeqCst), DISCONNECTED);
     }
index 87b2fe8f100c36a8a22c5b9e209e4c039285a811..4756ef612f947eeb8f7118388c91e13ec80c51b4 100644 (file)
@@ -134,7 +134,7 @@ pub fn new() -> Select {
     /// Creates a new handle into this receiver set for a new receiver. Note
     /// that this does *not* add the receiver to the receiver set, for that you
     /// must call the `add` method on the handle itself.
-    pub fn handle<'a, T: Send>(&'a self, rx: &'a Receiver<T>) -> Handle<'a, T> {
+    pub fn handle<'a, T: Send + 'static>(&'a self, rx: &'a Receiver<T>) -> Handle<'a, T> {
         let id = self.next_id.get();
         self.next_id.set(id + 1);
         Handle {
@@ -251,7 +251,7 @@ fn wait2(&self, do_preflight_checks: bool) -> uint {
     fn iter(&self) -> Packets { Packets { cur: self.head } }
 }
 
-impl<'rx, T: Send> Handle<'rx, T> {
+impl<'rx, T: Send + 'static> Handle<'rx, T> {
     /// Retrieve the id of this handle.
     #[inline]
     pub fn id(&self) -> uint { self.id }
@@ -322,7 +322,7 @@ fn drop(&mut self) {
 }
 
 #[unsafe_destructor]
-impl<'rx, T: Send> Drop for Handle<'rx, T> {
+impl<'rx, T: Send + 'static> Drop for Handle<'rx, T> {
     fn drop(&mut self) {
         unsafe { self.remove() }
     }
@@ -347,7 +347,7 @@ fn next(&mut self) -> Option<*mut Handle<'static, ()>> {
 mod test {
     use prelude::v1::*;
 
-    use thread::Thread;
+    use thread;
     use sync::mpsc::*;
 
     // Don't use the libstd version so we can pull in the right Select structure
@@ -427,11 +427,11 @@ fn unblocks() {
         let (_tx2, rx2) = channel::<int>();
         let (tx3, rx3) = channel::<int>();
 
-        let _t = Thread::spawn(move|| {
-            for _ in 0u..20 { Thread::yield_now(); }
+        let _t = thread::spawn(move|| {
+            for _ in 0u..20 { thread::yield_now(); }
             tx1.send(1).unwrap();
             rx3.recv().unwrap();
-            for _ in 0u..20 { Thread::yield_now(); }
+            for _ in 0u..20 { thread::yield_now(); }
         });
 
         select! {
@@ -451,8 +451,8 @@ fn both_ready() {
         let (tx2, rx2) = channel::<int>();
         let (tx3, rx3) = channel::<()>();
 
-        let _t = Thread::spawn(move|| {
-            for _ in 0u..20 { Thread::yield_now(); }
+        let _t = thread::spawn(move|| {
+            for _ in 0u..20 { thread::yield_now(); }
             tx1.send(1).unwrap();
             tx2.send(2).unwrap();
             rx3.recv().unwrap();
@@ -478,7 +478,7 @@ fn stress() {
         let (tx2, rx2) = channel::<int>();
         let (tx3, rx3) = channel::<()>();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             for i in 0..AMT {
                 if i % 2 == 0 {
                     tx1.send(i).unwrap();
@@ -504,7 +504,7 @@ fn cloning() {
         let (_tx2, rx2) = channel::<int>();
         let (tx3, rx3) = channel::<()>();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             rx3.recv().unwrap();
             tx1.clone();
             assert_eq!(rx3.try_recv(), Err(TryRecvError::Empty));
@@ -526,7 +526,7 @@ fn cloning2() {
         let (_tx2, rx2) = channel::<int>();
         let (tx3, rx3) = channel::<()>();
 
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             rx3.recv().unwrap();
             tx1.clone();
             assert_eq!(rx3.try_recv(), Err(TryRecvError::Empty));
@@ -547,7 +547,7 @@ fn cloning3() {
         let (tx1, rx1) = channel::<()>();
         let (tx2, rx2) = channel::<()>();
         let (tx3, rx3) = channel::<()>();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let s = Select::new();
             let mut h1 = s.handle(&rx1);
             let mut h2 = s.handle(&rx2);
@@ -557,7 +557,7 @@ fn cloning3() {
             tx3.send(()).unwrap();
         });
 
-        for _ in 0u..1000 { Thread::yield_now(); }
+        for _ in 0u..1000 { thread::yield_now(); }
         drop(tx1.clone());
         tx2.send(()).unwrap();
         rx3.recv().unwrap();
@@ -663,14 +663,14 @@ fn preflight9() {
     fn oneshot_data_waiting() {
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             select! {
                 _n = rx1.recv() => {}
             }
             tx2.send(()).unwrap();
         });
 
-        for _ in 0u..100 { Thread::yield_now() }
+        for _ in 0u..100 { thread::yield_now() }
         tx1.send(()).unwrap();
         rx2.recv().unwrap();
     }
@@ -683,14 +683,14 @@ fn stream_data_waiting() {
         tx1.send(()).unwrap();
         rx1.recv().unwrap();
         rx1.recv().unwrap();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             select! {
                 _n = rx1.recv() => {}
             }
             tx2.send(()).unwrap();
         });
 
-        for _ in 0u..100 { Thread::yield_now() }
+        for _ in 0u..100 { thread::yield_now() }
         tx1.send(()).unwrap();
         rx2.recv().unwrap();
     }
@@ -702,14 +702,14 @@ fn shared_data_waiting() {
         drop(tx1.clone());
         tx1.send(()).unwrap();
         rx1.recv().unwrap();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             select! {
                 _n = rx1.recv() => {}
             }
             tx2.send(()).unwrap();
         });
 
-        for _ in 0u..100 { Thread::yield_now() }
+        for _ in 0u..100 { thread::yield_now() }
         tx1.send(()).unwrap();
         rx2.recv().unwrap();
     }
@@ -726,8 +726,8 @@ fn sync1() {
     #[test]
     fn sync2() {
         let (tx, rx) = sync_channel::<int>(0);
-        let _t = Thread::spawn(move|| {
-            for _ in 0u..100 { Thread::yield_now() }
+        let _t = thread::spawn(move|| {
+            for _ in 0u..100 { thread::yield_now() }
             tx.send(1).unwrap();
         });
         select! {
@@ -739,8 +739,8 @@ fn sync2() {
     fn sync3() {
         let (tx1, rx1) = sync_channel::<int>(0);
         let (tx2, rx2): (Sender<int>, Receiver<int>) = channel();
-        let _t = Thread::spawn(move|| { tx1.send(1).unwrap(); });
-        let _t = Thread::spawn(move|| { tx2.send(2).unwrap(); });
+        let _t = thread::spawn(move|| { tx1.send(1).unwrap(); });
+        let _t = thread::spawn(move|| { tx2.send(2).unwrap(); });
         select! {
             n = rx1.recv() => {
                 let n = n.unwrap();
index 6c31fb925911edbbea453cdbcb57af7ab9b3ab26..bc9c73585c21fe86ff9ec4e5630191f6330289e9 100644 (file)
@@ -31,7 +31,7 @@
 use sync::mpsc::select::StartResult::*;
 use sync::mpsc::select::StartResult;
 use sync::{Mutex, MutexGuard};
-use thread::Thread;
+use thread;
 
 const DISCONNECTED: isize = isize::MIN;
 const FUDGE: isize = 1024;
@@ -64,7 +64,7 @@ pub enum Failure {
     Disconnected,
 }
 
-impl<T: Send> Packet<T> {
+impl<T: Send + 'static> Packet<T> {
     // Creation of a packet *must* be followed by a call to postinit_lock
     // and later by inherit_blocker
     pub fn new() -> Packet<T> {
@@ -194,7 +194,7 @@ pub fn send(&mut self, t: T) -> Result<(), T> {
                             match self.queue.pop() {
                                 mpsc::Data(..) => {}
                                 mpsc::Empty => break,
-                                mpsc::Inconsistent => Thread::yield_now(),
+                                mpsc::Inconsistent => thread::yield_now(),
                             }
                         }
                         // maybe we're done, if we're not the last ones
@@ -283,7 +283,7 @@ pub fn try_recv(&mut self) -> Result<T, Failure> {
             mpsc::Inconsistent => {
                 let data;
                 loop {
-                    Thread::yield_now();
+                    thread::yield_now();
                     match self.queue.pop() {
                         mpsc::Data(t) => { data = t; break }
                         mpsc::Empty => panic!("inconsistent => empty"),
@@ -460,7 +460,7 @@ pub fn abort_selection(&mut self, _was_upgrade: bool) -> bool {
                 drop(self.take_to_wake());
             } else {
                 while self.to_wake.load(Ordering::SeqCst) != 0 {
-                    Thread::yield_now();
+                    thread::yield_now();
                 }
             }
             // if the number of steals is -1, it was the pre-emptive -1 steal
@@ -474,7 +474,7 @@ pub fn abort_selection(&mut self, _was_upgrade: bool) -> bool {
 }
 
 #[unsafe_destructor]
-impl<T: Send> Drop for Packet<T> {
+impl<T: Send + 'static> Drop for Packet<T> {
     fn drop(&mut self) {
         // Note that this load is not only an assert for correctness about
         // disconnection, but also a proper fence before the read of
index f0558c33d1ec8d973ba11430443570a0cd176369..b8f835bde5191d79b6d0332d39d70c70c7c762c9 100644 (file)
@@ -74,11 +74,11 @@ pub struct Queue<T> {
     cache_subtractions: AtomicUsize,
 }
 
-unsafe impl<T: Send> Send for Queue<T> { }
+unsafe impl<T: Send + 'static> Send for Queue<T> { }
 
-unsafe impl<T: Send> Sync for Queue<T> { }
+unsafe impl<T: Send + 'static> Sync for Queue<T> { }
 
-impl<T: Send> Node<T> {
+impl<T: Send + 'static> Node<T> {
     fn new() -> *mut Node<T> {
         unsafe {
             mem::transmute(box Node {
@@ -89,7 +89,7 @@ fn new() -> *mut Node<T> {
     }
 }
 
-impl<T: Send> Queue<T> {
+impl<T: Send + 'static> Queue<T> {
     /// Creates a new queue.
     ///
     /// This is unsafe as the type system doesn't enforce a single
@@ -227,7 +227,7 @@ pub fn peek<'a>(&'a self) -> Option<&'a mut T> {
 }
 
 #[unsafe_destructor]
-impl<T: Send> Drop for Queue<T> {
+impl<T: Send + 'static> Drop for Queue<T> {
     fn drop(&mut self) {
         unsafe {
             let mut cur = *self.first.get();
@@ -246,7 +246,7 @@ mod test {
 
     use sync::Arc;
     use super::Queue;
-    use thread::Thread;
+    use thread;
     use sync::mpsc::channel;
 
     #[test]
@@ -324,7 +324,7 @@ unsafe fn stress_bound(bound: uint) {
 
             let (tx, rx) = channel();
             let q2 = q.clone();
-            let _t = Thread::spawn(move|| {
+            let _t = thread::spawn(move|| {
                 for _ in 0u..100000 {
                     loop {
                         match q2.pop() {
index ab9bd6b2ed7f6982a5c48273ea4548adb54a3d97..a194c99669263e356e1ad1bf46f160a6c212f8cf 100644 (file)
@@ -26,7 +26,7 @@
 
 use core::cmp;
 use core::isize;
-use thread::Thread;
+use thread;
 
 use sync::atomic::{AtomicIsize, AtomicUsize, Ordering, AtomicBool};
 use sync::mpsc::Receiver;
@@ -74,7 +74,7 @@ enum Message<T> {
     GoUp(Receiver<T>),
 }
 
-impl<T: Send> Packet<T> {
+impl<T: Send + 'static> Packet<T> {
     pub fn new() -> Packet<T> {
         Packet {
             queue: unsafe { spsc::Queue::new(128) },
@@ -440,7 +440,7 @@ pub fn abort_selection(&mut self,
                 drop(self.take_to_wake());
             } else {
                 while self.to_wake.load(Ordering::SeqCst) != 0 {
-                    Thread::yield_now();
+                    thread::yield_now();
                 }
             }
             assert_eq!(self.steals, 0);
@@ -472,7 +472,7 @@ pub fn abort_selection(&mut self,
 }
 
 #[unsafe_destructor]
-impl<T: Send> Drop for Packet<T> {
+impl<T: Send + 'static> Drop for Packet<T> {
     fn drop(&mut self) {
         // Note that this load is not only an assert for correctness about
         // disconnection, but also a proper fence before the read of
index da3ce51a652f792823cac87646197331d9ebfb60..ae96a2491dc267ee06066c369ee6cfb838e3c204 100644 (file)
@@ -55,9 +55,9 @@ pub struct Packet<T> {
     lock: Mutex<State<T>>,
 }
 
-unsafe impl<T:Send> Send for Packet<T> { }
+unsafe impl<T: Send + 'static> Send for Packet<T> { }
 
-unsafe impl<T:Send> Sync for Packet<T> { }
+unsafe impl<T: Send + 'static> Sync for Packet<T> { }
 
 struct State<T> {
     disconnected: bool, // Is the channel disconnected yet?
@@ -75,7 +75,7 @@ struct State<T> {
     canceled: Option<&'static mut bool>,
 }
 
-unsafe impl<T: Send> Send for State<T> {}
+unsafe impl<T: Send + 'static> Send for State<T> {}
 
 /// Possible flavors of threads who can be blocked on this channel.
 enum Blocker {
@@ -113,7 +113,7 @@ pub enum Failure {
 
 /// Atomically blocks the current thread, placing it into `slot`, unlocking `lock`
 /// in the meantime. This re-locks the mutex upon returning.
-fn wait<'a, 'b, T: Send>(lock: &'a Mutex<State<T>>,
+fn wait<'a, 'b, T: Send + 'static>(lock: &'a Mutex<State<T>>,
                          mut guard: MutexGuard<'b, State<T>>,
                          f: fn(SignalToken) -> Blocker)
                          -> MutexGuard<'a, State<T>>
@@ -136,7 +136,7 @@ fn wakeup<T>(token: SignalToken, guard: MutexGuard<State<T>>) {
     token.signal();
 }
 
-impl<T: Send> Packet<T> {
+impl<T: Send + 'static> Packet<T> {
     pub fn new(cap: uint) -> Packet<T> {
         Packet {
             channels: AtomicUsize::new(1),
@@ -412,7 +412,7 @@ pub fn abort_selection(&self) -> bool {
 }
 
 #[unsafe_destructor]
-impl<T: Send> Drop for Packet<T> {
+impl<T: Send + 'static> Drop for Packet<T> {
     fn drop(&mut self) {
         assert_eq!(self.channels.load(Ordering::SeqCst), 0);
         let mut guard = self.lock.lock().unwrap();
index 74692c1273c2790130597171adfc86a679cd6e8f..65cae90857e44f3b1a4c50480e122ba084c00bb9 100644 (file)
@@ -47,7 +47,7 @@
 ///
 /// ```rust
 /// use std::sync::{Arc, Mutex};
-/// use std::thread::Thread;
+/// use std::thread;
 /// use std::sync::mpsc::channel;
 ///
 /// const N: uint = 10;
@@ -62,7 +62,7 @@
 /// let (tx, rx) = channel();
 /// for _ in 0u..10 {
 ///     let (data, tx) = (data.clone(), tx.clone());
-///     Thread::spawn(move || {
+///     thread::spawn(move || {
 ///         // The shared static can only be accessed once the lock is held.
 ///         // Our non-atomic increment is safe because we're the only thread
 ///         // which can access the shared state when the lock is held.
 ///
 /// ```rust
 /// use std::sync::{Arc, Mutex};
-/// use std::thread::Thread;
+/// use std::thread;
 ///
 /// let lock = Arc::new(Mutex::new(0u));
 /// let lock2 = lock.clone();
 ///
-/// let _ = Thread::scoped(move || -> () {
+/// let _ = thread::spawn(move || -> () {
 ///     // This thread will acquire the mutex first, unwrapping the result of
 ///     // `lock` because the lock has not been poisoned.
 ///     let _lock = lock2.lock().unwrap();
@@ -120,9 +120,9 @@ pub struct Mutex<T> {
     data: UnsafeCell<T>,
 }
 
-unsafe impl<T:Send> Send for Mutex<T> { }
+unsafe impl<T: Send + 'static> Send for Mutex<T> { }
 
-unsafe impl<T:Send> Sync for Mutex<T> { }
+unsafe impl<T: Send + 'static> Sync for Mutex<T> { }
 
 /// The static mutex type is provided to allow for static allocation of mutexes.
 ///
@@ -180,7 +180,7 @@ impl<'a, T> !marker::Send for MutexGuard<'a, T> {}
     poison: poison::FLAG_INIT,
 };
 
-impl<T: Send> Mutex<T> {
+impl<T: Send + 'static> Mutex<T> {
     /// Creates a new mutex in an unlocked state ready for use.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(t: T) -> Mutex<T> {
@@ -243,7 +243,7 @@ pub fn is_poisoned(&self) -> bool {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> Drop for Mutex<T> {
+impl<T: Send + 'static> Drop for Mutex<T> {
     fn drop(&mut self) {
         // This is actually safe b/c we know that there is no further usage of
         // this mutex (it's up to the user to arrange for a mutex to get
@@ -350,7 +350,7 @@ mod test {
 
     use sync::mpsc::channel;
     use sync::{Arc, Mutex, StaticMutex, MUTEX_INIT, Condvar};
-    use thread::Thread;
+    use thread;
 
     struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
 
@@ -393,9 +393,9 @@ fn inc() {
         let (tx, rx) = channel();
         for _ in 0..K {
             let tx2 = tx.clone();
-            Thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
+            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
             let tx2 = tx.clone();
-            Thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
+            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
         }
 
         drop(tx);
@@ -419,7 +419,7 @@ fn test_mutex_arc_condvar() {
         let packet = Packet(Arc::new((Mutex::new(false), Condvar::new())));
         let packet2 = Packet(packet.0.clone());
         let (tx, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             // wait until parent gets in
             rx.recv().unwrap();
             let &(ref lock, ref cvar) = &*packet2.0;
@@ -443,7 +443,7 @@ fn test_arc_condvar_poison() {
         let packet2 = Packet(packet.0.clone());
         let (tx, rx) = channel();
 
-        let _t = Thread::spawn(move || -> () {
+        let _t = thread::spawn(move || -> () {
             rx.recv().unwrap();
             let &(ref lock, ref cvar) = &*packet2.0;
             let _g = lock.lock().unwrap();
@@ -471,7 +471,7 @@ fn test_mutex_arc_poison() {
         let arc = Arc::new(Mutex::new(1));
         assert!(!arc.is_poisoned());
         let arc2 = arc.clone();
-        let _ = Thread::scoped(move|| {
+        let _ = thread::spawn(move|| {
             let lock = arc2.lock().unwrap();
             assert_eq!(*lock, 2);
         }).join();
@@ -486,7 +486,7 @@ fn test_mutex_arc_nested() {
         let arc = Arc::new(Mutex::new(1));
         let arc2 = Arc::new(Mutex::new(arc));
         let (tx, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let lock = arc2.lock().unwrap();
             let lock2 = lock.lock().unwrap();
             assert_eq!(*lock2, 1);
@@ -499,7 +499,7 @@ fn test_mutex_arc_nested() {
     fn test_mutex_arc_access_in_unwind() {
         let arc = Arc::new(Mutex::new(1));
         let arc2 = arc.clone();
-        let _ = Thread::scoped(move|| -> () {
+        let _ = thread::spawn(move|| -> () {
             struct Unwinder {
                 i: Arc<Mutex<int>>,
             }
index 29c2051e5adc46f8b42cac7570f1c469dc03ca4d..1e87c0d612bdcc5561eb8cf79cdf8709662be3c7 100644 (file)
@@ -127,7 +127,7 @@ pub fn call_once<F>(&'static self, f: F) where F: FnOnce() {
 mod test {
     use prelude::v1::*;
 
-    use thread::Thread;
+    use thread;
     use super::{ONCE_INIT, Once};
     use sync::mpsc::channel;
 
@@ -149,8 +149,8 @@ fn stampede_once() {
         let (tx, rx) = channel();
         for _ in 0u..10 {
             let tx = tx.clone();
-            Thread::spawn(move|| {
-                for _ in 0u..4 { Thread::yield_now() }
+            thread::spawn(move|| {
+                for _ in 0u..4 { thread::yield_now() }
                 unsafe {
                     O.call_once(|| {
                         assert!(!run);
index a93bd31f5ae38ab58d59ad9569807ca33d747729..32c8150ba4070172473cfe7d7602dca56a8c09de 100644 (file)
@@ -13,7 +13,7 @@
 use cell::UnsafeCell;
 use error::{Error, FromError};
 use fmt;
-use thread::Thread;
+use thread;
 
 pub struct Flag { failed: UnsafeCell<bool> }
 pub const FLAG_INIT: Flag = Flag { failed: UnsafeCell { value: false } };
@@ -21,7 +21,7 @@ pub struct Flag { failed: UnsafeCell<bool> }
 impl Flag {
     #[inline]
     pub fn borrow(&self) -> LockResult<Guard> {
-        let ret = Guard { panicking: Thread::panicking() };
+        let ret = Guard { panicking: thread::panicking() };
         if unsafe { *self.failed.get() } {
             Err(PoisonError::new(ret))
         } else {
@@ -31,7 +31,7 @@ pub fn borrow(&self) -> LockResult<Guard> {
 
     #[inline]
     pub fn done(&self, guard: &Guard) {
-        if !guard.panicking && Thread::panicking() {
+        if !guard.panicking && thread::panicking() {
             unsafe { *self.failed.get() = true; }
         }
     }
index c4f1f2ccadddd034038a3e62c77d3e991c642e14..b8d157d341e031e7b353d6a34207543baa018315 100644 (file)
@@ -400,7 +400,7 @@ mod tests {
 
     use rand::{self, Rng};
     use sync::mpsc::channel;
-    use thread::Thread;
+    use thread;
     use sync::{Arc, RwLock, StaticRwLock, RW_LOCK_INIT};
 
     #[test]
@@ -425,13 +425,13 @@ fn static_smoke() {
     #[test]
     fn frob() {
         static R: StaticRwLock = RW_LOCK_INIT;
-        static N: uint = 10;
-        static M: uint = 1000;
+        static N: usize = 10;
+        static M: usize = 1000;
 
         let (tx, rx) = channel::<()>();
         for _ in 0..N {
             let tx = tx.clone();
-            Thread::spawn(move|| {
+            thread::spawn(move|| {
                 let mut rng = rand::thread_rng();
                 for _ in 0..M {
                     if rng.gen_weighted_bool(N) {
@@ -452,7 +452,7 @@ fn frob() {
     fn test_rw_arc_poison_wr() {
         let arc = Arc::new(RwLock::new(1));
         let arc2 = arc.clone();
-        let _: Result<uint, _> = Thread::scoped(move|| {
+        let _: Result<(), _> = thread::spawn(move|| {
             let _lock = arc2.write().unwrap();
             panic!();
         }).join();
@@ -464,7 +464,7 @@ fn test_rw_arc_poison_ww() {
         let arc = Arc::new(RwLock::new(1));
         assert!(!arc.is_poisoned());
         let arc2 = arc.clone();
-        let _: Result<uint, _> = Thread::scoped(move|| {
+        let _: Result<(), _> = thread::spawn(move|| {
             let _lock = arc2.write().unwrap();
             panic!();
         }).join();
@@ -476,7 +476,7 @@ fn test_rw_arc_poison_ww() {
     fn test_rw_arc_no_poison_rr() {
         let arc = Arc::new(RwLock::new(1));
         let arc2 = arc.clone();
-        let _: Result<uint, _> = Thread::scoped(move|| {
+        let _: Result<(), _> = thread::spawn(move|| {
             let _lock = arc2.read().unwrap();
             panic!();
         }).join();
@@ -487,7 +487,7 @@ fn test_rw_arc_no_poison_rr() {
     fn test_rw_arc_no_poison_rw() {
         let arc = Arc::new(RwLock::new(1));
         let arc2 = arc.clone();
-        let _: Result<uint, _> = Thread::scoped(move|| {
+        let _: Result<(), _> = thread::spawn(move|| {
             let _lock = arc2.read().unwrap();
             panic!()
         }).join();
@@ -501,12 +501,12 @@ fn test_rw_arc() {
         let arc2 = arc.clone();
         let (tx, rx) = channel();
 
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let mut lock = arc2.write().unwrap();
             for _ in 0u..10 {
                 let tmp = *lock;
                 *lock = -1;
-                Thread::yield_now();
+                thread::yield_now();
                 *lock = tmp + 1;
             }
             tx.send(()).unwrap();
@@ -516,7 +516,7 @@ fn test_rw_arc() {
         let mut children = Vec::new();
         for _ in 0u..5 {
             let arc3 = arc.clone();
-            children.push(Thread::scoped(move|| {
+            children.push(thread::spawn(move|| {
                 let lock = arc3.read().unwrap();
                 assert!(*lock >= 0);
             }));
@@ -537,7 +537,7 @@ fn test_rw_arc() {
     fn test_rw_arc_access_in_unwind() {
         let arc = Arc::new(RwLock::new(1));
         let arc2 = arc.clone();
-        let _ = Thread::scoped(move|| -> () {
+        let _ = thread::spawn(move|| -> () {
             struct Unwinder {
                 i: Arc<RwLock<int>>,
             }
index 0304b898884ccb2e47cfa0d11faf0484dac82c25..410e1c11bb9a992387af0b8fa0562b7eb6e65e56 100644 (file)
@@ -114,7 +114,7 @@ mod tests {
     use sync::Arc;
     use super::Semaphore;
     use sync::mpsc::channel;
-    use thread::Thread;
+    use thread;
 
     #[test]
     fn test_sem_acquire_release() {
@@ -134,7 +134,7 @@ fn test_sem_basic() {
     fn test_sem_as_mutex() {
         let s = Arc::new(Semaphore::new(1));
         let s2 = s.clone();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _g = s2.access();
         });
         let _g = s.access();
@@ -146,7 +146,7 @@ fn test_sem_as_cvar() {
         let (tx, rx) = channel();
         let s = Arc::new(Semaphore::new(0));
         let s2 = s.clone();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             s2.acquire();
             tx.send(()).unwrap();
         });
@@ -157,7 +157,7 @@ fn test_sem_as_cvar() {
         let (tx, rx) = channel();
         let s = Arc::new(Semaphore::new(0));
         let s2 = s.clone();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             s2.release();
             let _ = rx.recv();
         });
@@ -173,7 +173,7 @@ fn test_sem_multi_resource() {
         let s2 = s.clone();
         let (tx1, rx1) = channel();
         let (tx2, rx2) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             let _g = s2.access();
             let _ = rx2.recv();
             tx1.send(()).unwrap();
@@ -190,7 +190,7 @@ fn test_sem_runtime_friendly_blocking() {
         let (tx, rx) = channel();
         {
             let _g = s.access();
-            Thread::spawn(move|| {
+            thread::spawn(move|| {
                 tx.send(()).unwrap();
                 drop(s2.access());
                 tx.send(()).unwrap();
index 684a46fd6ff5fa51fde077b0540c2c7a604491b5..f4274dd91cc7a27eef8fa80b89e6b2392f942a45 100644 (file)
 
 use sync::{Arc, Mutex};
 use sync::mpsc::{channel, Sender, Receiver};
-use thread::Thread;
+use thread;
 use thunk::Thunk;
 
 struct Sentinel<'a> {
-    jobs: &'a Arc<Mutex<Receiver<Thunk>>>,
+    jobs: &'a Arc<Mutex<Receiver<Thunk<'static>>>>,
     active: bool
 }
 
 impl<'a> Sentinel<'a> {
-    fn new(jobs: &Arc<Mutex<Receiver<Thunk>>>) -> Sentinel {
+    fn new(jobs: &'a Arc<Mutex<Receiver<Thunk<'static>>>>) -> Sentinel<'a> {
         Sentinel {
             jobs: jobs,
             active: true
@@ -80,7 +80,7 @@ pub struct TaskPool {
     //
     // This is the only such Sender, so when it is dropped all subthreads will
     // quit.
-    jobs: Sender<Thunk>
+    jobs: Sender<Thunk<'static>>
 }
 
 impl TaskPool {
@@ -105,14 +105,14 @@ pub fn new(threads: uint) -> TaskPool {
 
     /// Executes the function `job` on a thread in the pool.
     pub fn execute<F>(&self, job: F)
-        where F : FnOnce(), F : Send
+        where F : FnOnce(), F : Send + 'static
     {
         self.jobs.send(Thunk::new(job)).unwrap();
     }
 }
 
-fn spawn_in_pool(jobs: Arc<Mutex<Receiver<Thunk>>>) {
-    Thread::spawn(move || {
+fn spawn_in_pool(jobs: Arc<Mutex<Receiver<Thunk<'static>>>>) {
+    thread::spawn(move || {
         // Will spawn a new thread on panic unless it is cancelled.
         let sentinel = Sentinel::new(&jobs);
 
index 255f474d4f4afb42bca461c9a0fad3f5013dee20..dc1ae85efe03395660f9e63fd82b0a398e5a969e 100644 (file)
@@ -30,7 +30,7 @@
 use sync::mpsc::{channel, Sender, Receiver};
 use sys::helper_signal;
 
-use thread::Thread;
+use thread;
 
 /// A structure for management of a helper thread.
 ///
@@ -81,7 +81,7 @@ impl<M: Send> Helper<M> {
     ///
     /// This function is safe to be called many times.
     pub fn boot<T, F>(&'static self, f: F, helper: fn(helper_signal::signal, Receiver<M>, T)) where
-        T: Send,
+        T: Send + 'static,
         F: FnOnce() -> T,
     {
         unsafe {
@@ -95,7 +95,7 @@ pub fn boot<T, F>(&'static self, f: F, helper: fn(helper_signal::signal, Receive
                 let receive = RaceBox(receive);
 
                 let t = f();
-                Thread::spawn(move || {
+                thread::spawn(move || {
                     helper(receive.0, rx, t);
                     let _g = self.lock.lock().unwrap();
                     *self.shutdown.get() = true;
index 92b936e74f6542a611a05a0a2bff6de29c780976..65c706033f213034c2923f4a78b1c8ce859fe16e 100644 (file)
@@ -29,7 +29,7 @@ struct ThreadInfo {
 impl ThreadInfo {
     fn with<R, F>(f: F) -> R where F: FnOnce(&mut ThreadInfo) -> R {
         if THREAD_INFO.state() == State::Destroyed {
-            panic!("Use of std::thread::Thread::current() is not possible after \
+            panic!("Use of std::thread::current() is not possible after \
                     the thread's local data has been destroyed");
         }
 
@@ -63,7 +63,7 @@ pub fn set(stack_bounds: (uint, uint), stack_guard: uint, thread: Thread) {
     }));
 }
 
-// a hack to get around privacy restrictions; implemented by `std::thread::Thread`
+// a hack to get around privacy restrictions; implemented by `std::thread`
 pub trait NewThread {
     fn new(name: Option<String>) -> Self;
 }
index 905fac07c5d5d76cc0d00cb729a43f59af0397a5..27b8784e3943a6a46320fbddc45c6ee8066d88da 100644 (file)
@@ -24,7 +24,7 @@
 //! # Usage
 //!
 //! This module should likely not be used directly unless other primitives are
-//! being built on. types such as `thread_local::scoped::Key` are likely much
+//! being built on. types such as `thread_local::spawn::Key` are likely much
 //! more useful in practice than this OS-based version which likely requires
 //! unsafe code to interoperate with.
 //!
index 6047f94b3b4599428d6fbff2c1a743c358aa3200..b610f6c370bb3bcfcc99db2c47e99180f538cc8c 100644 (file)
@@ -817,7 +817,9 @@ fn hash(&self, state: &mut S) {
     }
 }
 
-impl AsciiExt<Wtf8Buf> for Wtf8 {
+impl AsciiExt for Wtf8 {
+    type Owned = Wtf8Buf;
+
     fn is_ascii(&self) -> bool {
         self.bytes.is_ascii()
     }
@@ -830,6 +832,9 @@ fn to_ascii_lowercase(&self) -> Wtf8Buf {
     fn eq_ignore_ascii_case(&self, other: &Wtf8) -> bool {
         self.bytes.eq_ignore_ascii_case(&other.bytes)
     }
+
+    fn make_ascii_uppercase(&mut self) { self.bytes.make_ascii_uppercase() }
+    fn make_ascii_lowercase(&mut self) { self.bytes.make_ascii_lowercase() }
 }
 
 #[cfg(test)]
index 8a6ef17818a0956b57834360490c9445ea86d185..df03841276e9e483cf22444cd9e6cc4f1559f1f2 100644 (file)
@@ -247,6 +247,10 @@ fn next(&mut self) -> Option<OsString> { self.iter.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
 }
 
+impl ExactSizeIterator for Args {
+    fn len(&self) -> usize { self.iter.len() }
+}
+
 /// Returns the command line arguments
 ///
 /// Returns a list of the command line arguments.
index 32e45009887a8e67195fad8e19dd71a77ab80a52..f954024b0e9e3450f8461da4a1f7a9e2da918098 100644 (file)
@@ -70,7 +70,6 @@ pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
               K: BytesContainer + Eq + Hash<Hasher>, V: BytesContainer
     {
         use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp};
-        use libc::funcs::bsd44::getdtablesize;
 
         mod rustrt {
             extern {
@@ -78,6 +77,15 @@ mod rustrt {
             }
         }
 
+        #[cfg(all(target_os = "android", target_arch = "aarch64"))]
+        unsafe fn getdtablesize() -> c_int {
+            libc::sysconf(libc::consts::os::sysconf::_SC_OPEN_MAX) as c_int
+        }
+        #[cfg(not(all(target_os = "android", target_arch = "aarch64")))]
+        unsafe fn getdtablesize() -> c_int {
+            libc::funcs::bsd44::getdtablesize()
+        }
+
         unsafe fn set_cloexec(fd: c_int) {
             let ret = c::ioctl(fd, c::FIOCLEX);
             assert_eq!(ret, 0);
index 6f030ee91fe2d6db045ca5daec23dc3dc8240c8c..82c52471d109719ef99d0e5aab5a6fa4103a434f 100644 (file)
@@ -10,6 +10,7 @@
 
 use core::prelude::*;
 
+use io;
 use boxed::Box;
 use cmp;
 use mem;
@@ -191,7 +192,7 @@ pub unsafe fn current() -> uint {
     }
 }
 
-pub unsafe fn create(stack: uint, p: Thunk) -> rust_thread {
+pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> {
     let mut native: libc::pthread_t = mem::zeroed();
     let mut attr: libc::pthread_attr_t = mem::zeroed();
     assert_eq!(pthread_attr_init(&mut attr), 0);
@@ -226,9 +227,10 @@ pub unsafe fn create(stack: uint, p: Thunk) -> rust_thread {
     if ret != 0 {
         // be sure to not leak the closure
         let _p: Box<Box<FnOnce()+Send>> = mem::transmute(arg);
-        panic!("failed to spawn native thread: {}", ret);
+        Err(io::Error::from_os_error(ret))
+    } else {
+        Ok(native)
     }
-    native
 }
 
 #[cfg(any(target_os = "linux", target_os = "android"))]
index 7e684c5234141aad1e15762f0fa6503ba2996ae6..502d70d4e1a16f297464b5f08b09eb202fc5dd19 100644 (file)
@@ -18,7 +18,7 @@
 use error::Error as StdError;
 use ffi::{OsString, OsStr, AsOsStr};
 use fmt;
-use iter::Range;
+use ops::Range;
 use libc::types::os::arch::extra::LPWCH;
 use libc::{self, c_int, c_void};
 use mem;
@@ -303,6 +303,10 @@ fn next(&mut self) -> Option<OsString> {
     fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
 }
 
+impl ExactSizeIterator for Args {
+    fn len(&self) -> usize { self.range.len() }
+}
+
 impl Drop for Args {
     fn drop(&mut self) {
         unsafe { c::LocalFree(self.cur as *mut c_void); }
@@ -315,7 +319,7 @@ pub fn args() -> Args {
         let lpCmdLine = c::GetCommandLineW();
         let szArgList = c::CommandLineToArgvW(lpCmdLine, &mut nArgs);
 
-        Args { cur: szArgList, range: range(0, nArgs as isize) }
+        Args { cur: szArgList, range: 0..(nArgs as isize) }
     }
 }
 
index a38dc9b2d340770d643d9539e349abe706044292..f3a27877e5c58512fc8c6dce9dc08749141f12d5 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use boxed::Box;
+use prelude::v1::*;
+
 use cmp;
+use io;
 use mem;
 use ptr;
 use libc;
@@ -42,7 +44,7 @@ pub unsafe fn init() {
     }
 }
 
-pub unsafe fn create(stack: uint, p: Thunk) -> rust_thread {
+pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> {
     let arg: *mut libc::c_void = mem::transmute(box p);
     // FIXME On UNIX, we guard against stack sizes that are too small but
     // that's because pthreads enforces that stacks are at least
@@ -60,9 +62,10 @@ pub unsafe fn create(stack: uint, p: Thunk) -> rust_thread {
     if ret as uint == 0 {
         // be sure to not leak the closure
         let _p: Box<Thunk> = mem::transmute(arg);
-        panic!("failed to spawn native thread: {:?}", ret);
+        Err(io::Error::last_os_error())
+    } else {
+        Ok(ret)
     }
-    return ret;
 }
 
 pub unsafe fn set_name(_name: &str) {
index cc9d7492441cd86175a138ad7b325c6332d33573..3137d779c4071c24cee2bfe723f79de99713b3f4 100644 (file)
 //! Already-running threads are represented via the `Thread` type, which you can
 //! get in one of two ways:
 //!
-//! * By spawning a new thread, e.g. using the `Thread::spawn` constructor;
-//! * By requesting the current thread, using the `Thread::current` function.
+//! * By spawning a new thread, e.g. using the `thread::spawn` constructor;
+//! * By requesting the current thread, using the `thread::current` function.
 //!
 //! Threads can be named, and provide some built-in support for low-level
 //! synchronization described below.
 //!
-//! The `Thread::current()` function is available even for threads not spawned
+//! The `thread::current()` function is available even for threads not spawned
 //! by the APIs of this module.
 //!
 //! ## Spawning a thread
 //!
-//! A new thread can be spawned using the `Thread::spawn` function:
+//! A new thread can be spawned using the `thread::spawn` function:
 //!
 //! ```rust
-//! use std::thread::Thread;
+//! use std::thread;
 //!
-//! let thread = Thread::spawn(move || {
+//! thread::spawn(move || {
 //!     println!("Hello, World!");
 //!     // some computation here
 //! });
 //! ```
 //!
-//! The spawned thread is "detached" from the current thread, meaning that it
-//! can outlive the thread that spawned it. (Note, however, that when the main
-//! thread terminates all detached threads are terminated as well.) The returned
-//! `Thread` handle can be used for low-level synchronization as described below.
+//! In this example, the spawned thread is "detached" from the current
+//! thread, meaning that it can outlive the thread that spawned
+//! it. (Note, however, that when the main thread terminates all
+//! detached threads are terminated as well.)
 //!
 //! ## Scoped threads
 //!
 //! For this scenario, use the `scoped` constructor:
 //!
 //! ```rust
-//! use std::thread::Thread;
+//! use std::thread;
 //!
-//! let guard = Thread::scoped(move || {
+//! let guard = thread::scoped(move || {
 //!     println!("Hello, World!");
 //!     // some computation here
 //! });
 //! // do some other work in the meantime
-//! let result = guard.join();
+//! let output = guard.join();
 //! ```
 //!
-//! The `scoped` function doesn't return a `Thread` directly; instead, it
-//! returns a *join guard* from which a `Thread` can be extracted. The join
-//! guard is an RAII-style guard that will automatically join the child thread
-//! (block until it terminates) when it is dropped. You can join the child
-//! thread in advance by calling the `join` method on the guard, which will also
-//! return the result produced by the thread.  A handle to the thread itself is
-//! available via the `thread` method on the join guard.
+//! The `scoped` function doesn't return a `Thread` directly; instead,
+//! it returns a *join guard*. The join guard is an RAII-style guard
+//! that will automatically join the child thread (block until it
+//! terminates) when it is dropped. You can join the child thread in
+//! advance by calling the `join` method on the guard, which will also
+//! return the result produced by the thread.  A handle to the thread
+//! itself is available via the `thread` method on the join guard.
 //!
 //! (Note: eventually, the `scoped` constructor will allow the parent and child
 //! threads to data that lives on the parent thread's stack, but some language
 //! Conceptually, each `Thread` handle has an associated token, which is
 //! initially not present:
 //!
-//! * The `Thread::park()` function blocks the current thread unless or until
+//! * The `thread::park()` function blocks the current thread unless or until
 //!   the token is available for its thread handle, at which point It atomically
 //!   consumes the token. It may also return *spuriously*, without consuming the
-//!   token. `Thread::park_timeout()` does the same, but allows specifying a
+//!   token. `thread::park_timeout()` does the same, but allows specifying a
 //!   maximum time to block the thread for.
 //!
 //! * The `unpark()` method on a `Thread` atomically makes the token available
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use prelude::v1::*;
+
 use any::Any;
-use boxed::Box;
 use cell::UnsafeCell;
-use clone::Clone;
-use marker::{Send, Sync};
-use ops::{Drop, FnOnce};
-use option::Option::{self, Some, None};
-use result::Result::{Err, Ok};
-use sync::{Mutex, Condvar, Arc};
-use str::Str;
-use string::String;
+use fmt;
+use io;
+use marker;
+use old_io::stdio;
 use rt::{self, unwind};
-use old_io::{Writer, stdio};
+use sync::{Mutex, Condvar, Arc};
 use thunk::Thunk;
 use time::Duration;
 
@@ -175,9 +172,9 @@ pub struct Builder {
     // The size of the stack for the spawned thread
     stack_size: Option<uint>,
     // Thread-local stdout
-    stdout: Option<Box<Writer + Send>>,
+    stdout: Option<Box<Writer + Send + 'static>>,
     // Thread-local stderr
-    stderr: Option<Box<Writer + Send>>,
+    stderr: Option<Box<Writer + Send + 'static>>,
 }
 
 impl Builder {
@@ -211,7 +208,7 @@ pub fn stack_size(mut self, size: uint) -> Builder {
     /// Redirect thread-local stdout.
     #[unstable(feature = "std_misc",
                reason = "Will likely go away after proc removal")]
-    pub fn stdout(mut self, stdout: Box<Writer + Send>) -> Builder {
+    pub fn stdout(mut self, stdout: Box<Writer + Send + 'static>) -> Builder {
         self.stdout = Some(stdout);
         self
     }
@@ -219,54 +216,65 @@ pub fn stdout(mut self, stdout: Box<Writer + Send>) -> Builder {
     /// Redirect thread-local stderr.
     #[unstable(feature = "std_misc",
                reason = "Will likely go away after proc removal")]
-    pub fn stderr(mut self, stderr: Box<Writer + Send>) -> Builder {
+    pub fn stderr(mut self, stderr: Box<Writer + Send + 'static>) -> Builder {
         self.stderr = Some(stderr);
         self
     }
 
-    /// Spawn a new detached thread, and return a handle to it.
+    /// Spawn a new thread, and return a join handle for it.
     ///
-    /// See `Thead::spawn` and the module doc for more details.
-    #[unstable(feature = "std_misc",
-               reason = "may change with specifics of new Send semantics")]
-    pub fn spawn<F>(self, f: F) -> Thread where F: FnOnce(), F: Send + 'static {
-        let (native, thread) = self.spawn_inner(Thunk::new(f), Thunk::with_arg(|_| {}));
-        unsafe { imp::detach(native) };
-        thread
+    /// The child thread may outlive the parent (unless the parent thread
+    /// is the main thread; the whole process is terminated when the main
+    /// thread finishes.) The join handle can be used to block on
+    /// termination of the child thread, including recovering its panics.
+    ///
+    /// # Errors
+    ///
+    /// Unlike the `spawn` free function, this method yields an
+    /// `io::Result` to capture any failure to create the thread at
+    /// the OS level.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn spawn<F>(self, f: F) -> io::Result<JoinHandle> where
+        F: FnOnce(), F: Send + 'static
+    {
+        self.spawn_inner(Thunk::new(f)).map(|i| JoinHandle(i))
     }
 
     /// Spawn a new child thread that must be joined within a given
     /// scope, and return a `JoinGuard`.
     ///
-    /// See `Thead::scoped` and the module doc for more details.
-    #[unstable(feature = "std_misc",
-               reason = "may change with specifics of new Send semantics")]
-    pub fn scoped<'a, T, F>(self, f: F) -> JoinGuard<'a, T> where
+    /// The join guard can be used to explicitly join the child thread (via
+    /// `join`), returning `Result<T>`, or it will implicitly join the child
+    /// upon being dropped. Because the child thread may refer to data on the
+    /// current thread's stack (hence the "scoped" name), it cannot be detached;
+    /// it *must* be joined before the relevant stack frame is popped. See the
+    /// module documentation for additional details.
+    ///
+    /// # Errors
+    ///
+    /// Unlike the `scoped` free function, this method yields an
+    /// `io::Result` to capture any failure to create the thread at
+    /// the OS level.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn scoped<'a, T, F>(self, f: F) -> io::Result<JoinGuard<'a, T>> where
         T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
     {
-        let my_packet = Packet(Arc::new(UnsafeCell::new(None)));
-        let their_packet = Packet(my_packet.0.clone());
-        let (native, thread) = self.spawn_inner(Thunk::new(f), Thunk::with_arg(move |ret| unsafe {
-            *their_packet.0.get() = Some(ret);
-        }));
-
-        JoinGuard {
-            native: native,
-            joined: false,
-            packet: my_packet,
-            thread: thread,
-        }
+        self.spawn_inner(Thunk::new(f)).map(|inner| {
+            JoinGuard { inner: inner, _marker: marker::CovariantType }
+        })
     }
 
-    fn spawn_inner<T: Send>(self, f: Thunk<(), T>, finish: Thunk<Result<T>, ()>)
-                      -> (imp::rust_thread, Thread)
-    {
+    fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> io::Result<JoinInner<T>> {
         let Builder { name, stack_size, stdout, stderr } = self;
 
         let stack_size = stack_size.unwrap_or(rt::min_stack());
+
         let my_thread = Thread::new(name);
         let their_thread = my_thread.clone();
 
+        let my_packet = Packet(Arc::new(UnsafeCell::new(None)));
+        let their_packet = Packet(my_packet.0.clone());
+
         // Spawning a new OS thread guarantees that __morestack will never get
         // triggered, but we must manually set up the actual stack bounds once
         // this function starts executing. This raises the lower limit by a bit
@@ -316,17 +324,120 @@ fn spawn_inner<T: Send>(self, f: Thunk<(), T>, finish: Thunk<Result<T>, ()>)
                     unwind::try(move || *ptr = Some(f.invoke(())))
                 }
             };
-            finish.invoke(match (output, try_result) {
-                (Some(data), Ok(_)) => Ok(data),
-                (None, Err(cause)) => Err(cause),
-                _ => unreachable!()
-            });
+            unsafe {
+                *their_packet.0.get() = Some(match (output, try_result) {
+                    (Some(data), Ok(_)) => Ok(data),
+                    (None, Err(cause)) => Err(cause),
+                    _ => unreachable!()
+                });
+            }
         };
 
-        (unsafe { imp::create(stack_size, Thunk::new(main)) }, my_thread)
+        Ok(JoinInner {
+            native: try!(unsafe { imp::create(stack_size, Thunk::new(main)) }),
+            thread: my_thread,
+            packet: my_packet,
+            joined: false,
+        })
+    }
+}
+
+/// Spawn a new, returning a join handle for it.
+///
+/// The child thread may outlive the parent (unless the parent thread
+/// is the main thread; the whole process is terminated when the main
+/// thread finishes.) The join handle can be used to block on
+/// termination of the child thread, including recovering its panics.
+///
+/// # Panics
+///
+/// Panicks if the OS fails to create a thread; use `Builder::spawn`
+/// to recover from such errors.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn spawn<F>(f: F) -> JoinHandle where F: FnOnce(), F: Send + 'static {
+    Builder::new().spawn(f).unwrap()
+}
+
+/// Spawn a new *scoped* thread, returning a `JoinGuard` for it.
+///
+/// The join guard can be used to explicitly join the child thread (via
+/// `join`), returning `Result<T>`, or it will implicitly join the child
+/// upon being dropped. Because the child thread may refer to data on the
+/// current thread's stack (hence the "scoped" name), it cannot be detached;
+/// it *must* be joined before the relevant stack frame is popped. See the
+/// module documentation for additional details.
+///
+/// # Panics
+///
+/// Panicks if the OS fails to create a thread; use `Builder::scoped`
+/// to recover from such errors.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn scoped<'a, T, F>(f: F) -> JoinGuard<'a, T> where
+    T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
+{
+    Builder::new().scoped(f).unwrap()
+}
+
+/// Gets a handle to the thread that invokes it.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn current() -> Thread {
+    thread_info::current_thread()
+}
+
+/// Cooperatively give up a timeslice to the OS scheduler.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn yield_now() {
+    unsafe { imp::yield_now() }
+}
+
+/// Determines whether the current thread is unwinding because of panic.
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn panicking() -> bool {
+    unwind::panicking()
+}
+
+/// Block unless or until the current thread's token is made available (may wake spuriously).
+///
+/// See the module doc for more detail.
+//
+// The implementation currently uses the trivial strategy of a Mutex+Condvar
+// with wakeup flag, which does not actually allow spurious wakeups. In the
+// future, this will be implemented in a more efficient way, perhaps along the lines of
+//   http://cr.openjdk.java.net/~stefank/6989984.1/raw_files/new/src/os/linux/vm/os_linux.cpp
+// or futuxes, and in either case may allow spurious wakeups.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn park() {
+    let thread = current();
+    let mut guard = thread.inner.lock.lock().unwrap();
+    while !*guard {
+        guard = thread.inner.cvar.wait(guard).unwrap();
     }
+    *guard = false;
+}
+
+/// Block unless or until the current thread's token is made available or
+/// the specified duration has been reached (may wake spuriously).
+///
+/// The semantics of this function are equivalent to `park()` except that the
+/// thread will be blocked for roughly no longer than dur. This method
+/// should not be used for precise timing due to anomalies such as
+/// preemption or platform differences that may not cause the maximum
+/// amount of time waited to be precisely dur
+///
+/// See the module doc for more detail.
+#[unstable(feature = "std_misc", reason = "recently introduced, depends on Duration")]
+pub fn park_timeout(dur: Duration) {
+    let thread = current();
+    let mut guard = thread.inner.lock.lock().unwrap();
+    if !*guard {
+        let (g, _) = thread.inner.cvar.wait_timeout(guard, dur).unwrap();
+        guard = g;
+    }
+    *guard = false;
 }
 
+/// The internal representation of a `Thread` handle
 struct Inner {
     name: Option<String>,
     lock: Mutex<bool>,          // true when there is a buffered unpark
@@ -354,65 +465,51 @@ fn new(name: Option<String>) -> Thread {
         }
     }
 
-    /// Spawn a new detached thread, returning a handle to it.
-    ///
-    /// The child thread may outlive the parent (unless the parent thread is the
-    /// main thread; the whole process is terminated when the main thread
-    /// finishes.) The thread handle can be used for low-level
-    /// synchronization. See the module documentation for additional details.
+    /// Deprecated: use module-level free fucntion.
+    #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")]
     #[unstable(feature = "std_misc",
                reason = "may change with specifics of new Send semantics")]
     pub fn spawn<F>(f: F) -> Thread where F: FnOnce(), F: Send + 'static {
-        Builder::new().spawn(f)
+        Builder::new().spawn(f).unwrap().thread().clone()
     }
 
-    /// Spawn a new *scoped* thread, returning a `JoinGuard` for it.
-    ///
-    /// The join guard can be used to explicitly join the child thread (via
-    /// `join`), returning `Result<T>`, or it will implicitly join the child
-    /// upon being dropped. Because the child thread may refer to data on the
-    /// current thread's stack (hence the "scoped" name), it cannot be detached;
-    /// it *must* be joined before the relevant stack frame is popped. See the
-    /// module documentation for additional details.
+    /// Deprecated: use module-level free fucntion.
+    #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")]
     #[unstable(feature = "std_misc",
                reason = "may change with specifics of new Send semantics")]
     pub fn scoped<'a, T, F>(f: F) -> JoinGuard<'a, T> where
         T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
     {
-        Builder::new().scoped(f)
+        Builder::new().scoped(f).unwrap()
     }
 
-    /// Gets a handle to the thread that invokes it.
+    /// Deprecated: use module-level free fucntion.
+    #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn current() -> Thread {
         thread_info::current_thread()
     }
 
-    /// Cooperatively give up a timeslice to the OS scheduler.
+    /// Deprecated: use module-level free fucntion.
+    #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")]
     #[unstable(feature = "std_misc", reason = "name may change")]
     pub fn yield_now() {
         unsafe { imp::yield_now() }
     }
 
-    /// Determines whether the current thread is unwinding because of panic.
+    /// Deprecated: use module-level free fucntion.
+    #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn panicking() -> bool {
         unwind::panicking()
     }
 
-    /// Block unless or until the current thread's token is made available (may wake spuriously).
-    ///
-    /// See the module doc for more detail.
-    //
-    // The implementation currently uses the trivial strategy of a Mutex+Condvar
-    // with wakeup flag, which does not actually allow spurious wakeups. In the
-    // future, this will be implemented in a more efficient way, perhaps along the lines of
-    //   http://cr.openjdk.java.net/~stefank/6989984.1/raw_files/new/src/os/linux/vm/os_linux.cpp
-    // or futuxes, and in either case may allow spurious wakeups.
+    /// Deprecated: use module-level free fucntion.
+    #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")]
     #[unstable(feature = "std_misc", reason = "recently introduced")]
     pub fn park() {
-        let thread = Thread::current();
+        let thread = current();
         let mut guard = thread.inner.lock.lock().unwrap();
         while !*guard {
             guard = thread.inner.cvar.wait(guard).unwrap();
@@ -420,19 +517,11 @@ pub fn park() {
         *guard = false;
     }
 
-    /// Block unless or until the current thread's token is made available or
-    /// the specified duration has been reached (may wake spuriously).
-    ///
-    /// The semantics of this function are equivalent to `park()` except that the
-    /// thread will be blocked for roughly no longer than dur. This method
-    /// should not be used for precise timing due to anomalies such as
-    /// preemption or platform differences that may not cause the maximum
-    /// amount of time waited to be precisely dur
-    ///
-    /// See the module doc for more detail.
+    /// Deprecated: use module-level free fucntion.
+    #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")]
     #[unstable(feature = "std_misc", reason = "recently introduced")]
     pub fn park_timeout(dur: Duration) {
-        let thread = Thread::current();
+        let thread = current();
         let mut guard = thread.inner.lock.lock().unwrap();
         if !*guard {
             let (g, _) = thread.inner.cvar.wait_timeout(guard, dur).unwrap();
@@ -444,7 +533,7 @@ pub fn park_timeout(dur: Duration) {
     /// Atomically makes the handle's token available if it is not already.
     ///
     /// See the module doc for more detail.
-    #[unstable(feature = "std_misc", reason = "recently introduced")]
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn unpark(&self) {
         let mut guard = self.inner.lock.lock().unwrap();
         if !*guard {
@@ -460,6 +549,13 @@ pub fn name(&self) -> Option<&str> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Debug for Thread {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(&self.name(), f)
+    }
+}
+
 // a hack to get around privacy restrictions
 impl thread_info::NewThread for Thread {
     fn new(name: Option<String>) -> Thread { Thread::new(name) }
@@ -469,24 +565,84 @@ fn new(name: Option<String>) -> Thread { Thread::new(name) }
 ///
 /// A thread that completes without panicking is considered to exit successfully.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub type Result<T> = ::result::Result<T, Box<Any + Send>>;
+pub type Result<T> = ::result::Result<T, Box<Any + Send + 'static>>;
 
 struct Packet<T>(Arc<UnsafeCell<Option<Result<T>>>>);
 
-unsafe impl<T:'static+Send> Send for Packet<T> {}
+unsafe impl<T:Send> Send for Packet<T> {}
 unsafe impl<T> Sync for Packet<T> {}
 
+/// Inner representation for JoinHandle and JoinGuard
+struct JoinInner<T> {
+    native: imp::rust_thread,
+    thread: Thread,
+    packet: Packet<T>,
+    joined: bool,
+}
+
+impl<T> JoinInner<T> {
+    fn join(&mut self) -> Result<T> {
+        assert!(!self.joined);
+        unsafe { imp::join(self.native) };
+        self.joined = true;
+        unsafe {
+            (*self.packet.0.get()).take().unwrap()
+        }
+    }
+}
+
+/// An owned permission to join on a thread (block on its termination).
+///
+/// Unlike a `JoinGuard`, a `JoinHandle` *detaches* the child thread
+/// when it is dropped, rather than automatically joining on drop.
+///
+/// Due to platform restrictions, it is not possible to `Clone` this
+/// handle: the ability to join a child thread is a uniquely-owned
+/// permission.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct JoinHandle(JoinInner<()>);
+
+impl JoinHandle {
+    /// Extract a handle to the underlying thread
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn thread(&self) -> &Thread {
+        &self.0.thread
+    }
+
+    /// Wait for the associated thread to finish.
+    ///
+    /// If the child thread panics, `Err` is returned with the parameter given
+    /// to `panic`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn join(mut self) -> Result<()> {
+        self.0.join()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Drop for JoinHandle {
+    fn drop(&mut self) {
+        if !self.0.joined {
+            unsafe { imp::detach(self.0.native) }
+        }
+    }
+}
+
 /// An RAII-style guard that will block until thread termination when dropped.
 ///
 /// The type `T` is the return type for the thread's main function.
+///
+/// Joining on drop is necessary to ensure memory safety when stack
+/// data is shared between a parent and child thread.
+///
+/// Due to platform restrictions, it is not possible to `Clone` this
+/// handle: the ability to join a child thread is a uniquely-owned
+/// permission.
 #[must_use]
-#[unstable(feature = "std_misc",
-           reason = "may change with specifics of new Send semantics")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct JoinGuard<'a, T: 'a> {
-    native: imp::rust_thread,
-    thread: Thread,
-    joined: bool,
-    packet: Packet<T>,
+    inner: JoinInner<T>,
+    _marker: marker::CovariantType<&'a T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -496,32 +652,32 @@ impl<'a, T: Send + 'a> JoinGuard<'a, T> {
     /// Extract a handle to the thread this guard will join on.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn thread(&self) -> &Thread {
-        &self.thread
+        &self.inner.thread
     }
 
     /// Wait for the associated thread to finish, returning the result of the thread's
     /// calculation.
     ///
-    /// If the child thread panics, `Err` is returned with the parameter given
-    /// to `panic`.
+    /// # Panics
+    ///
+    /// Panics on the child thread are propagated by panicking the parent.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn join(mut self) -> Result<T> {
-        assert!(!self.joined);
-        unsafe { imp::join(self.native) };
-        self.joined = true;
-        unsafe {
-            (*self.packet.0.get()).take().unwrap()
+    pub fn join(mut self) -> T {
+        match self.inner.join() {
+            Ok(res) => res,
+            Err(_) => panic!("child thread {:?} panicked", self.thread()),
         }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Send> JoinGuard<'static, T> {
     /// Detaches the child thread, allowing it to outlive its parent.
-    #[unstable(feature = "std_misc",
-               reason = "unsure whether this API imposes limitations elsewhere")]
+    #[deprecated(since = "1.0.0", reason = "use spawn instead")]
+    #[unstable(feature = "std_misc")]
     pub fn detach(mut self) {
-        unsafe { imp::detach(self.native) };
-        self.joined = true; // avoid joining in the destructor
+        unsafe { imp::detach(self.inner.native) };
+        self.inner.joined = true; // avoid joining in the destructor
     }
 }
 
@@ -529,8 +685,10 @@ pub fn detach(mut self) {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: Send + 'a> Drop for JoinGuard<'a, T> {
     fn drop(&mut self) {
-        if !self.joined {
-            unsafe { imp::join(self.native) };
+        if !self.inner.joined {
+            if self.inner.join().is_err() {
+                panic!("child thread {:?} panicked", self.thread());
+            }
         }
     }
 }
@@ -545,6 +703,7 @@ mod test {
     use result;
     use std::old_io::{ChanReader, ChanWriter};
     use super::{Thread, Builder};
+    use thread;
     use thunk::Thunk;
     use time::Duration;
 
@@ -553,22 +712,22 @@ mod test {
 
     #[test]
     fn test_unnamed_thread() {
-        Thread::scoped(move|| {
-            assert!(Thread::current().name().is_none());
+        thread::spawn(move|| {
+            assert!(thread::current().name().is_none());
         }).join().ok().unwrap();
     }
 
     #[test]
     fn test_named_thread() {
         Builder::new().name("ada lovelace".to_string()).scoped(move|| {
-            assert!(Thread::current().name().unwrap() == "ada lovelace".to_string());
-        }).join().ok().unwrap();
+            assert!(thread::current().name().unwrap() == "ada lovelace".to_string());
+        }).unwrap().join();
     }
 
     #[test]
     fn test_run_basic() {
         let (tx, rx) = channel();
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             tx.send(()).unwrap();
         });
         rx.recv().unwrap();
@@ -576,17 +735,14 @@ fn test_run_basic() {
 
     #[test]
     fn test_join_success() {
-        match Thread::scoped(move|| -> String {
+        assert!(thread::scoped(move|| -> String {
             "Success!".to_string()
-        }).join().as_ref().map(|s| &**s) {
-            result::Result::Ok("Success!") => (),
-            _ => panic!()
-        }
+        }).join() == "Success!");
     }
 
     #[test]
     fn test_join_panic() {
-        match Thread::scoped(move|| {
+        match thread::spawn(move|| {
             panic!()
         }).join() {
             result::Result::Err(_) => (),
@@ -594,6 +750,26 @@ fn test_join_panic() {
         }
     }
 
+    #[test]
+    fn test_scoped_success() {
+        let res = thread::scoped(move|| -> String {
+            "Success!".to_string()
+        }).join();
+        assert!(res == "Success!");
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_scoped_panic() {
+        thread::scoped(|| panic!()).join();
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_scoped_implicit_panic() {
+        thread::scoped(|| panic!());
+    }
+
     #[test]
     fn test_spawn_sched() {
         use clone::Clone;
@@ -602,7 +778,7 @@ fn test_spawn_sched() {
 
         fn f(i: int, tx: Sender<()>) {
             let tx = tx.clone();
-            Thread::spawn(move|| {
+            thread::spawn(move|| {
                 if i == 0 {
                     tx.send(()).unwrap();
                 } else {
@@ -619,8 +795,8 @@ fn f(i: int, tx: Sender<()>) {
     fn test_spawn_sched_childs_on_default_sched() {
         let (tx, rx) = channel();
 
-        Thread::spawn(move|| {
-            Thread::spawn(move|| {
+        thread::spawn(move|| {
+            thread::spawn(move|| {
                 tx.send(()).unwrap();
             });
         });
@@ -628,7 +804,7 @@ fn test_spawn_sched_childs_on_default_sched() {
         rx.recv().unwrap();
     }
 
-    fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk) {
+    fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk<'static>) {
         let (tx, rx) = channel::<uint>();
 
         let x = box 1;
@@ -646,14 +822,14 @@ fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk) {
     #[test]
     fn test_avoid_copying_the_body_spawn() {
         avoid_copying_the_body(|v| {
-            Thread::spawn(move || v.invoke(()));
+            thread::spawn(move || v.invoke(()));
         });
     }
 
     #[test]
     fn test_avoid_copying_the_body_thread_spawn() {
         avoid_copying_the_body(|f| {
-            Thread::spawn(move|| {
+            thread::spawn(move|| {
                 f.invoke(());
             });
         })
@@ -662,7 +838,7 @@ fn test_avoid_copying_the_body_thread_spawn() {
     #[test]
     fn test_avoid_copying_the_body_join() {
         avoid_copying_the_body(|f| {
-            let _ = Thread::scoped(move|| {
+            let _ = thread::spawn(move|| {
                 f.invoke(())
             }).join();
         })
@@ -675,24 +851,24 @@ fn test_child_doesnt_ref_parent() {
         // (well, it would if the constant were 8000+ - I lowered it to be more
         // valgrind-friendly. try this at home, instead..!)
         static GENERATIONS: uint = 16;
-        fn child_no(x: uint) -> Thunk {
+        fn child_no(x: uint) -> Thunk<'static> {
             return Thunk::new(move|| {
                 if x < GENERATIONS {
-                    Thread::spawn(move|| child_no(x+1).invoke(()));
+                    thread::spawn(move|| child_no(x+1).invoke(()));
                 }
             });
         }
-        Thread::spawn(|| child_no(0).invoke(()));
+        thread::spawn(|| child_no(0).invoke(()));
     }
 
     #[test]
     fn test_simple_newsched_spawn() {
-        Thread::spawn(move || {});
+        thread::spawn(move || {});
     }
 
     #[test]
     fn test_try_panic_message_static_str() {
-        match Thread::scoped(move|| {
+        match thread::spawn(move|| {
             panic!("static string");
         }).join() {
             Err(e) => {
@@ -706,7 +882,7 @@ fn test_try_panic_message_static_str() {
 
     #[test]
     fn test_try_panic_message_owned_str() {
-        match Thread::scoped(move|| {
+        match thread::spawn(move|| {
             panic!("owned string".to_string());
         }).join() {
             Err(e) => {
@@ -720,7 +896,7 @@ fn test_try_panic_message_owned_str() {
 
     #[test]
     fn test_try_panic_message_any() {
-        match Thread::scoped(move|| {
+        match thread::spawn(move|| {
             panic!(box 413u16 as Box<Any + Send>);
         }).join() {
             Err(e) => {
@@ -738,7 +914,7 @@ fn test_try_panic_message_any() {
     fn test_try_panic_message_unit_struct() {
         struct Juju;
 
-        match Thread::scoped(move|| {
+        match thread::spawn(move|| {
             panic!(Juju)
         }).join() {
             Err(ref e) if e.is::<Juju>() => {}
@@ -752,10 +928,9 @@ fn test_stdout() {
         let mut reader = ChanReader::new(rx);
         let stdout = ChanWriter::new(tx);
 
-        let r = Builder::new().stdout(box stdout as Box<Writer + Send>).scoped(move|| {
+        Builder::new().stdout(box stdout as Box<Writer + Send>).scoped(move|| {
             print!("Hello, world!");
-        }).join();
-        assert!(r.is_ok());
+        }).unwrap().join();
 
         let output = reader.read_to_string().unwrap();
         assert_eq!(output, "Hello, world!".to_string());
@@ -764,15 +939,15 @@ fn test_stdout() {
     #[test]
     fn test_park_timeout_unpark_before() {
         for _ in 0..10 {
-            Thread::current().unpark();
-            Thread::park_timeout(Duration::seconds(10_000_000));
+            thread::current().unpark();
+            thread::park_timeout(Duration::seconds(10_000_000));
         }
     }
 
     #[test]
     fn test_park_timeout_unpark_not_called() {
         for _ in 0..10 {
-            Thread::park_timeout(Duration::milliseconds(10));
+            thread::park_timeout(Duration::milliseconds(10));
         }
     }
 
@@ -781,14 +956,14 @@ fn test_park_timeout_unpark_called_other_thread() {
         use std::old_io;
 
         for _ in 0..10 {
-            let th = Thread::current();
+            let th = thread::current();
 
-            let _guard = Thread::scoped(move || {
+            let _guard = thread::spawn(move || {
                 old_io::timer::sleep(Duration::milliseconds(50));
                 th.unpark();
             });
 
-            Thread::park_timeout(Duration::seconds(10_000_000));
+            thread::park_timeout(Duration::seconds(10_000_000));
         }
     }
 
index eab9cd84539edabde17d286b322ae743f4f2c5fe..2ed296e081c90f3b4a5988fbaf4332633d43bba6 100644 (file)
@@ -72,7 +72,7 @@ pub mod __impl {
 ///
 /// ```
 /// use std::cell::RefCell;
-/// use std::thread::Thread;
+/// use std::thread;
 ///
 /// thread_local!(static FOO: RefCell<uint> = RefCell::new(1));
 ///
@@ -82,7 +82,7 @@ pub mod __impl {
 /// });
 ///
 /// // each thread starts out with the initial value of 1
-/// Thread::spawn(move|| {
+/// thread::spawn(move|| {
 ///     FOO.with(|f| {
 ///         assert_eq!(*f.borrow(), 1);
 ///         *f.borrow_mut() = 3;
@@ -548,7 +548,7 @@ mod tests {
     use sync::mpsc::{channel, Sender};
     use cell::UnsafeCell;
     use super::State;
-    use thread::Thread;
+    use thread;
 
     struct Foo(Sender<()>);
 
@@ -568,7 +568,7 @@ fn smoke_no_dtor() {
             *f.get() = 2;
         });
         let (tx, rx) = channel();
-        let _t = Thread::spawn(move|| {
+        let _t = thread::spawn(move|| {
             FOO.with(|f| unsafe {
                 assert_eq!(*f.get(), 1);
             });
@@ -595,7 +595,7 @@ fn foo() -> Foo {
         }
         thread_local!(static FOO: Foo = foo());
 
-        Thread::scoped(|| {
+        thread::spawn(|| {
             assert!(FOO.state() == State::Uninitialized);
             FOO.with(|_| {
                 assert!(FOO.state() == State::Valid);
@@ -611,7 +611,7 @@ fn smoke_dtor() {
         });
 
         let (tx, rx) = channel();
-        let _t = Thread::spawn(move|| unsafe {
+        let _t = thread::spawn(move|| unsafe {
             let mut tx = Some(tx);
             FOO.with(|f| {
                 *f.get() = Some(Foo(tx.take().unwrap()));
@@ -659,7 +659,7 @@ fn drop(&mut self) {
             }
         }
 
-        Thread::scoped(move|| {
+        thread::spawn(move|| {
             drop(S1);
         }).join().ok().unwrap();
     }
@@ -677,7 +677,7 @@ fn drop(&mut self) {
             }
         }
 
-        Thread::scoped(move|| unsafe {
+        thread::spawn(move|| unsafe {
             K1.with(|s| *s.get() = Some(S1));
         }).join().ok().unwrap();
     }
@@ -704,7 +704,7 @@ fn drop(&mut self) {
         }
 
         let (tx, rx) = channel();
-        let _t = Thread::spawn(move|| unsafe {
+        let _t = thread::spawn(move|| unsafe {
             let mut tx = Some(tx);
             K1.with(|s| *s.get() = Some(S1(tx.take().unwrap())));
         });
index 0831242f954cf0e95b12ecae70766a3dc991554c..fe39954f0d446fd5ae3b45d8971b097a8ecae6a6 100644 (file)
 use core::marker::Send;
 use core::ops::FnOnce;
 
-pub struct Thunk<A=(),R=()> {
-    invoke: Box<Invoke<A,R>+Send>
+pub struct Thunk<'a, A=(),R=()> {
+    #[cfg(stage0)]
+    invoke: Box<Invoke<A,R>+Send>,
+    #[cfg(not(stage0))]
+    invoke: Box<Invoke<A,R>+Send + 'a>,
 }
 
-impl<R> Thunk<(),R> {
-    pub fn new<F>(func: F) -> Thunk<(),R>
-        where F : FnOnce() -> R, F : Send
+impl<'a, R> Thunk<'a,(),R> {
+    pub fn new<F>(func: F) -> Thunk<'a,(),R>
+        where F : FnOnce() -> R, F : Send + 'a
     {
         Thunk::with_arg(move|()| func())
     }
 }
 
-impl<A,R> Thunk<A,R> {
-    pub fn with_arg<F>(func: F) -> Thunk<A,R>
-        where F : FnOnce(A) -> R, F : Send
+impl<'a,A,R> Thunk<'a,A,R> {
+    pub fn with_arg<F>(func: F) -> Thunk<'a,A,R>
+        where F : FnOnce(A) -> R, F : Send + 'a
     {
         Thunk {
             invoke: box func
index 5535e5911e0c2fd5e85ae763a14dcaef7e18915a..6535705388d0104437377181a351bd19ac87660a 100644 (file)
@@ -251,7 +251,7 @@ fn entry_count(&self) -> usize {
     }
 
     fn find_entry(&self, id: NodeId) -> Option<MapEntry<'ast>> {
-        self.map.borrow().get(id as usize).map(|e| *e)
+        self.map.borrow().get(id as usize).cloned()
     }
 
     pub fn krate(&self) -> &'ast Crate {
index 62d48189c43475149b013f223bb2079af97e0199..a6cfd1a5a9ac3c1e612b02995457433ee344987d 100644 (file)
@@ -17,10 +17,10 @@ pub struct Registry {
 
 impl Registry {
     pub fn new(descriptions: &[(&'static str, &'static str)]) -> Registry {
-        Registry { descriptions: descriptions.iter().map(|&tuple| tuple).collect() }
+        Registry { descriptions: descriptions.iter().cloned().collect() }
     }
 
     pub fn find_description(&self, code: &str) -> Option<&'static str> {
-        self.descriptions.get(code).map(|desc| *desc)
+        self.descriptions.get(code).cloned()
     }
 }
index 1ceda2e08dd8219663623d3457689c5ea71114b5..d8cba139fb5979b9258c5d8e6498a24e00be8f42 100644 (file)
@@ -18,6 +18,7 @@
 use codemap::Span;
 use ext::base;
 use ext::base::*;
+use feature_gate;
 use parse::token::InternedString;
 use parse::token;
 use ptr::P;
@@ -48,6 +49,12 @@ fn next(&self) -> State {
 
 pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                        -> Box<base::MacResult+'cx> {
+    if !cx.ecfg.enable_asm() {
+        feature_gate::emit_feature_err(
+            &cx.parse_sess.span_diagnostic, "asm", sp, feature_gate::EXPLAIN_ASM);
+        return DummyResult::expr(sp);
+    }
+
     let mut p = cx.new_parser_from_tts(tts);
     let mut asm = InternedString::new("");
     let mut asm_str_style = None;
index 083039995ee955ce5366292ceff367578e6b0a6e..d4ccabbd63b4a2edfb5f411a13b06b317e27440c 100644 (file)
@@ -439,7 +439,8 @@ pub fn new() -> BlockInfo {
 
 /// The base map of methods for expanding syntax extension
 /// AST nodes into full ASTs
-fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv {
+fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>)
+                                        -> SyntaxEnv {
     // utility function to simplify creating NormalTT syntax extensions
     fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
         NormalTT(box f, None)
@@ -470,7 +471,7 @@ fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
     syntax_expanders.insert(intern("deriving"),
                             Decorator(box ext::deriving::expand_deprecated_deriving));
 
-    if ecfg.enable_quotes {
+    if ecfg.enable_quotes() {
         // Quasi-quoting expanders
         syntax_expanders.insert(intern("quote_tokens"),
                            builtin_normal_expander(
@@ -541,7 +542,7 @@ pub struct ExtCtxt<'a> {
     pub parse_sess: &'a parse::ParseSess,
     pub cfg: ast::CrateConfig,
     pub backtrace: ExpnId,
-    pub ecfg: expand::ExpansionConfig,
+    pub ecfg: expand::ExpansionConfig<'a>,
     pub use_std: bool,
 
     pub mod_path: Vec<ast::Ident> ,
@@ -554,7 +555,7 @@ pub struct ExtCtxt<'a> {
 
 impl<'a> ExtCtxt<'a> {
     pub fn new(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig,
-               ecfg: expand::ExpansionConfig) -> ExtCtxt<'a> {
+               ecfg: expand::ExpansionConfig<'a>) -> ExtCtxt<'a> {
         let env = initial_syntax_expander_table(&ecfg);
         ExtCtxt {
             parse_sess: parse_sess,
@@ -639,7 +640,7 @@ pub fn original_span_in_file(&self) -> Span {
     pub fn mod_path(&self) -> Vec<ast::Ident> {
         let mut v = Vec::new();
         v.push(token::str_to_ident(&self.ecfg.crate_name[]));
-        v.extend(self.mod_path.iter().map(|a| *a));
+        v.extend(self.mod_path.iter().cloned());
         return v;
     }
     pub fn bt_push(&mut self, ei: ExpnInfo) {
index 364cacd735cc73386c45e4ea0e540f277914f795..63a8bd9ddf1b39972868aeba18fe19fbe52117fa 100644 (file)
 use codemap::Span;
 use ext::base::*;
 use ext::base;
+use feature_gate;
 use parse::token;
 use parse::token::{str_to_ident};
 use ptr::P;
 
 pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                               -> Box<base::MacResult+'cx> {
+    if !cx.ecfg.enable_concat_idents() {
+        feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
+                                       "concat_idents",
+                                       sp,
+                                       feature_gate::EXPLAIN_CONCAT_IDENTS);
+        return base::DummyResult::expr(sp);
+    }
+
     let mut res_str = String::new();
     for (i, e) in tts.iter().enumerate() {
         if i & 1 == 1 {
index f878cb5ca8b78ff74377b6817bf6311a392b7885..8b4eaab386d007c867f57ee4e6014d765df44f6e 100644 (file)
@@ -367,7 +367,7 @@ pub fn expand<F>(&self,
                 "allow" | "warn" | "deny" | "forbid" => true,
                 _ => false,
             }
-        }).map(|a| a.clone()));
+        }).cloned());
         push(P(ast::Item {
             attrs: attrs,
             ..(*newitem).clone()
@@ -410,7 +410,7 @@ fn create_derived_impl(&self,
         let mut ty_params = ty_params.into_vec();
 
         // Copy the lifetimes
-        lifetimes.extend(generics.lifetimes.iter().map(|l| (*l).clone()));
+        lifetimes.extend(generics.lifetimes.iter().cloned());
 
         // Create the type parameters.
         ty_params.extend(generics.ty_params.iter().map(|ty_param| {
@@ -445,14 +445,14 @@ fn create_derived_impl(&self,
                         span: self.span,
                         bound_lifetimes: wb.bound_lifetimes.clone(),
                         bounded_ty: wb.bounded_ty.clone(),
-                        bounds: OwnedSlice::from_vec(wb.bounds.iter().map(|b| b.clone()).collect())
+                        bounds: OwnedSlice::from_vec(wb.bounds.iter().cloned().collect())
                     })
                 }
                 ast::WherePredicate::RegionPredicate(ref rb) => {
                     ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
                         span: self.span,
                         lifetime: rb.lifetime,
-                        bounds: rb.bounds.iter().map(|b| b.clone()).collect()
+                        bounds: rb.bounds.iter().cloned().collect()
                     })
                 }
                 ast::WherePredicate::EqPredicate(ref we) => {
@@ -500,7 +500,7 @@ fn create_derived_impl(&self,
         let opt_trait_ref = Some(trait_ref);
         let ident = ast_util::impl_pretty_name(&opt_trait_ref, &*self_type);
         let mut a = vec![attr];
-        a.extend(self.attributes.iter().map(|a| a.clone()));
+        a.extend(self.attributes.iter().cloned());
         cx.item(
             self.span,
             ident,
index fd98f42c2ab03c0693c21e2f75b74980fdf4f7ec..6b7cecee815765f3bebd2e83f0090a5d0a1c0660 100644 (file)
@@ -22,6 +22,7 @@
 use codemap;
 use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
 use ext::base::*;
+use feature_gate::{Features};
 use fold;
 use fold::*;
 use parse;
@@ -1408,28 +1409,63 @@ fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
     }
 }
 
-pub struct ExpansionConfig {
+pub struct ExpansionConfig<'feat> {
     pub crate_name: String,
-    pub enable_quotes: bool,
+    pub features: Option<&'feat Features>,
     pub recursion_limit: usize,
 }
 
-impl ExpansionConfig {
-    pub fn default(crate_name: String) -> ExpansionConfig {
+impl<'feat> ExpansionConfig<'feat> {
+    pub fn default(crate_name: String) -> ExpansionConfig<'static> {
         ExpansionConfig {
             crate_name: crate_name,
-            enable_quotes: false,
+            features: None,
             recursion_limit: 64,
         }
     }
+
+    pub fn enable_quotes(&self) -> bool {
+        match self.features {
+            Some(&Features { allow_quote: true, .. }) => true,
+            _ => false,
+        }
+    }
+
+    pub fn enable_asm(&self) -> bool {
+        match self.features {
+            Some(&Features { allow_asm: true, .. }) => true,
+            _ => false,
+        }
+    }
+
+    pub fn enable_log_syntax(&self) -> bool {
+        match self.features {
+            Some(&Features { allow_log_syntax: true, .. }) => true,
+            _ => false,
+        }
+    }
+
+    pub fn enable_concat_idents(&self) -> bool {
+        match self.features {
+            Some(&Features { allow_concat_idents: true, .. }) => true,
+            _ => false,
+        }
+    }
+
+    pub fn enable_trace_macros(&self) -> bool {
+        match self.features {
+            Some(&Features { allow_trace_macros: true, .. }) => true,
+            _ => false,
+        }
+    }
 }
 
-pub fn expand_crate(parse_sess: &parse::ParseSess,
-                    cfg: ExpansionConfig,
-                    // these are the macros being imported to this crate:
-                    imported_macros: Vec<ast::MacroDef>,
-                    user_exts: Vec<NamedSyntaxExtension>,
-                    c: Crate) -> Crate {
+pub fn expand_crate<'feat>(parse_sess: &parse::ParseSess,
+                           cfg: ExpansionConfig<'feat>,
+                           // these are the macros being imported to this crate:
+                           imported_macros: Vec<ast::MacroDef>,
+                           user_exts: Vec<NamedSyntaxExtension>,
+                           c: Crate) -> Crate {
     let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
     cx.use_std = std_inject::use_std(&c);
 
@@ -1598,7 +1634,7 @@ fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> {
     // these following tests are quite fragile, in that they don't test what
     // *kind* of failure occurs.
 
-    fn test_ecfg() -> ExpansionConfig {
+    fn test_ecfg() -> ExpansionConfig<'static> {
         ExpansionConfig::default("test".to_string())
     }
 
index 30301e3b8cc92414a940ebc6fb374d958a267479..8173dd93f7468db4c5c2853d9e9f958cf63c264c 100644 (file)
 use ast;
 use codemap;
 use ext::base;
+use feature_gate;
 use print;
 
 pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt,
                               sp: codemap::Span,
                               tts: &[ast::TokenTree])
                               -> Box<base::MacResult+'cx> {
+    if !cx.ecfg.enable_log_syntax() {
+        feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
+                                       "log_syntax",
+                                       sp,
+                                       feature_gate::EXPLAIN_LOG_SYNTAX);
+        return base::DummyResult::any(sp);
+    }
 
     cx.print_backtrace();
 
index 7a3a3562bdfdcbd9ede0d2597241449c74371470..d1dee115b6bcdf247054cb829dc21459c72b3246 100644 (file)
@@ -179,7 +179,7 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             return DummyResult::expr(sp);
         }
         Ok(bytes) => {
-            let bytes = bytes.iter().map(|x| *x).collect();
+            let bytes = bytes.iter().cloned().collect();
             base::MacExpr::new(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes))))
         }
     }
index 76f7b7b0d7b3b18c95f0dbb37fbc479436060da9..3fcc6a8d69241b7cb2bfa80258589457f176dcf5 100644 (file)
@@ -12,6 +12,7 @@
 use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::base;
+use feature_gate;
 use parse::token::keywords;
 
 
@@ -19,6 +20,15 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt,
                            sp: Span,
                            tt: &[ast::TokenTree])
                            -> Box<base::MacResult+'static> {
+    if !cx.ecfg.enable_trace_macros() {
+        feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
+                                       "trace_macros",
+                                       sp,
+                                       feature_gate::EXPLAIN_TRACE_MACROS);
+        return base::DummyResult::any(sp);
+    }
+
+
     match tt {
         [ast::TtToken(_, ref tok)] if tok.is_keyword(keywords::True) => {
             cx.set_trace_macros(true);
index d752e34c11253c149318013f13e1c02269a205f9..a3224c25d09579752e78d2642acb941d64fc1f60 100644 (file)
@@ -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));
index f322cf8bad09cc103cdf627353b297be0dddd0d6..1a6cf7d07f19da2820520a4b40334d33071c7e51 100644 (file)
@@ -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) {
index fd1ca11818c9832575aefb9a57cc3463e4c20cb6..3bebba15a572b2e307231dd6c1a48cfade2e8ddb 100644 (file)
@@ -23,6 +23,7 @@
 //! becomes stable.
 
 use self::Status::*;
+use self::AttributeType::*;
 
 use abi::RustIntrinsic;
 use ast::NodeId;
@@ -35,7 +36,6 @@
 use visit::Visitor;
 use parse::token::{self, InternedString};
 
-use std::slice;
 use std::ascii::AsciiExt;
 
 // If you change this list without updating src/doc/reference.md, @cmr will be sad
     // Allows using the unsafe_no_drop_flag attribute (unlikely to
     // switch to Accepted; see RFC 320)
     ("unsafe_no_drop_flag", "1.0.0", Active),
+
+    // Allows the use of custom attributes; RFC 572
+    ("custom_attribute", "1.0.0", Active),
+
+    // Allows the use of rustc_* attributes; RFC 572
+    ("rustc_attrs", "1.0.0", Active),
 ];
 // (changing above list without updating src/doc/reference.md makes @cmr sad)
 
@@ -152,12 +158,148 @@ enum Status {
     Accepted,
 }
 
+// Attributes that have a special meaning to rustc or rustdoc
+pub static KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
+    // Normal attributes
+
+    ("warn", Normal),
+    ("allow", Normal),
+    ("forbid", Normal),
+    ("deny", Normal),
+
+    ("macro_reexport", Normal),
+    ("macro_use", Normal),
+    ("macro_export", Normal),
+    ("plugin_registrar", Normal),
+
+    ("cfg", Normal),
+    ("main", Normal),
+    ("start", Normal),
+    ("test", Normal),
+    ("bench", Normal),
+    ("simd", Normal),
+    ("repr", Normal),
+    ("path", Normal),
+    ("abi", Normal),
+    ("unsafe_destructor", Normal),
+    ("automatically_derived", Normal),
+    ("no_mangle", Normal),
+    ("no_link", Normal),
+    ("derive", Normal),
+    ("should_fail", Normal),
+    ("ignore", Normal),
+    ("no_implicit_prelude", Normal),
+    ("reexport_test_harness_main", Normal),
+    ("link_args", Normal),
+    ("macro_escape", Normal),
+
+
+    ("staged_api", Gated("staged_api",
+                         "staged_api is for use by rustc only")),
+    ("plugin", Gated("plugin",
+                     "compiler plugins are experimental \
+                      and possibly buggy")),
+    ("no_std", Gated("no_std",
+                     "no_std is experimental")),
+    ("lang", Gated("lang_items",
+                     "language items are subject to change")),
+    ("linkage", Gated("linkage",
+                      "the `linkage` attribute is experimental \
+                       and not portable across platforms")),
+    ("thread_local", Gated("thread_local",
+                            "`#[thread_local]` is an experimental feature, and does not \
+                             currently handle destructors. There is no corresponding \
+                             `#[task_local]` mapping to the task model")),
+
+    ("rustc_on_unimplemented", Gated("on_unimplemented",
+                                     "the `#[rustc_on_unimplemented]` attribute \
+                                      is an experimental feature")),
+    ("rustc_variance", Gated("rustc_attrs",
+                             "the `#[rustc_variance]` attribute \
+                              is an experimental feature")),
+    ("rustc_error", Gated("rustc_attrs",
+                          "the `#[rustc_error]` attribute \
+                           is an experimental feature")),
+    ("rustc_move_fragments", Gated("rustc_attrs",
+                                   "the `#[rustc_move_fragments]` attribute \
+                                    is an experimental feature")),
+
+    // FIXME: #14408 whitelist docs since rustdoc looks at them
+    ("doc", Whitelisted),
+
+    // FIXME: #14406 these are processed in trans, which happens after the
+    // lint pass
+    ("cold", Whitelisted),
+    ("export_name", Whitelisted),
+    ("inline", Whitelisted),
+    ("link", Whitelisted),
+    ("link_name", Whitelisted),
+    ("link_section", Whitelisted),
+    ("no_builtins", Whitelisted),
+    ("no_mangle", Whitelisted),
+    ("no_split_stack", Whitelisted),
+    ("no_stack_check", Whitelisted),
+    ("packed", Whitelisted),
+    ("static_assert", Whitelisted),
+    ("no_debug", Whitelisted),
+    ("omit_gdb_pretty_printer_section", Whitelisted),
+    ("unsafe_no_drop_flag", Whitelisted),
+
+    // used in resolve
+    ("prelude_import", Whitelisted),
+
+    // FIXME: #14407 these are only looked at on-demand so we can't
+    // guarantee they'll have already been checked
+    ("deprecated", Whitelisted),
+    ("must_use", Whitelisted),
+    ("stable", Whitelisted),
+    ("unstable", Whitelisted),
+
+    // FIXME: #19470 this shouldn't be needed forever
+    ("old_orphan_check", Whitelisted),
+    ("old_impl_check", Whitelisted),
+    ("rustc_paren_sugar", Whitelisted), // FIXME: #18101 temporary unboxed closure hack
+
+    // Crate level attributes
+    ("crate_name", CrateLevel),
+    ("crate_type", CrateLevel),
+    ("crate_id", CrateLevel),
+    ("feature", CrateLevel),
+    ("no_start", CrateLevel),
+    ("no_main", CrateLevel),
+    ("no_builtins", CrateLevel),
+    ("recursion_limit", CrateLevel),
+];
+
+#[derive(PartialEq, Copy)]
+pub enum AttributeType {
+    /// Normal, builtin attribute that is consumed
+    /// by the compiler before the unused_attribute check
+    Normal,
+
+    /// Builtin attribute that may not be consumed by the compiler
+    /// before the unused_attribute check. These attributes
+    /// will be ignored by the unused_attribute lint
+    Whitelisted,
+
+    /// Is gated by a given feature gate and reason
+    /// These get whitelisted too
+    Gated(&'static str, &'static str),
+
+    /// Builtin attribute that is only allowed at the crate level
+    CrateLevel,
+}
+
 /// A set of features to be used by later passes.
 pub struct Features {
     pub unboxed_closures: bool,
     pub rustc_diagnostic_macros: bool,
     pub visible_private_types: bool,
-    pub quote: bool,
+    pub allow_quote: bool,
+    pub allow_asm: bool,
+    pub allow_log_syntax: bool,
+    pub allow_concat_idents: bool,
+    pub allow_trace_macros: bool,
     pub old_orphan_check: bool,
     pub simd_ffi: bool,
     pub unmarked_api: bool,
@@ -173,7 +315,11 @@ pub fn new() -> Features {
             unboxed_closures: false,
             rustc_diagnostic_macros: false,
             visible_private_types: false,
-            quote: false,
+            allow_quote: false,
+            allow_asm: false,
+            allow_log_syntax: false,
+            allow_concat_idents: false,
+            allow_trace_macros: false,
             old_orphan_check: false,
             simd_ffi: false,
             unmarked_api: false,
@@ -222,6 +368,18 @@ pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain:
     }
 }
 
+pub const EXPLAIN_ASM: &'static str =
+    "inline assembly is not stable enough for use and is subject to change";
+
+pub const EXPLAIN_LOG_SYNTAX: &'static str =
+    "`log_syntax!` is not stable enough for use and is subject to change";
+
+pub const EXPLAIN_CONCAT_IDENTS: &'static str =
+    "`concat_idents` is not stable enough for use and is subject to change";
+
+pub const EXPLAIN_TRACE_MACROS: &'static str =
+    "`trace_macros` is not stable enough for use and is subject to change";
+
 struct MacroVisitor<'a> {
     context: &'a Context<'a>
 }
@@ -231,24 +389,28 @@ fn visit_mac(&mut self, mac: &ast::Mac) {
         let ast::MacInvocTT(ref path, _, _) = mac.node;
         let id = path.segments.last().unwrap().identifier;
 
+        // Issue 22234: If you add a new case here, make sure to also
+        // add code to catch the macro during or after expansion.
+        //
+        // We still keep this MacroVisitor (rather than *solely*
+        // relying on catching cases during or after expansion) to
+        // catch uses of these macros within conditionally-compiled
+        // code, e.g. `#[cfg]`-guarded functions.
+
         if id == token::str_to_ident("asm") {
-            self.context.gate_feature("asm", path.span, "inline assembly is not \
-                stable enough for use and is subject to change");
+            self.context.gate_feature("asm", path.span, EXPLAIN_ASM);
         }
 
         else if id == token::str_to_ident("log_syntax") {
-            self.context.gate_feature("log_syntax", path.span, "`log_syntax!` is not \
-                stable enough for use and is subject to change");
+            self.context.gate_feature("log_syntax", path.span, EXPLAIN_LOG_SYNTAX);
         }
 
         else if id == token::str_to_ident("trace_macros") {
-            self.context.gate_feature("trace_macros", path.span, "`trace_macros` is not \
-                stable enough for use and is subject to change");
+            self.context.gate_feature("trace_macros", path.span, EXPLAIN_TRACE_MACROS);
         }
 
         else if id == token::str_to_ident("concat_idents") {
-            self.context.gate_feature("concat_idents", path.span, "`concat_idents` is not \
-                stable enough for use and is subject to change");
+            self.context.gate_feature("concat_idents", path.span, EXPLAIN_CONCAT_IDENTS);
         }
     }
 }
@@ -274,22 +436,6 @@ fn visit_name(&mut self, sp: Span, name: ast::Name) {
     }
 
     fn visit_item(&mut self, i: &ast::Item) {
-        for attr in &i.attrs {
-            if attr.name() == "thread_local" {
-                self.gate_feature("thread_local", i.span,
-                                  "`#[thread_local]` is an experimental feature, and does not \
-                                  currently handle destructors. There is no corresponding \
-                                  `#[task_local]` mapping to the task model");
-            } else if attr.name() == "linkage" {
-                self.gate_feature("linkage", i.span,
-                                  "the `linkage` attribute is experimental \
-                                   and not portable across platforms")
-            } else if attr.name() == "rustc_on_unimplemented" {
-                self.gate_feature("on_unimplemented", i.span,
-                                  "the `#[rustc_on_unimplemented]` attribute \
-                                  is an experimental feature")
-            }
-        }
         match i.node {
             ast::ItemExternCrate(_) => {
                 if attr::contains_name(&i.attrs[], "macro_reexport") {
@@ -463,30 +609,27 @@ fn visit_expr(&mut self, e: &ast::Expr) {
     }
 
     fn visit_attribute(&mut self, attr: &ast::Attribute) {
-        if attr.check_name("staged_api") {
-            self.gate_feature("staged_api", attr.span,
-                              "staged_api is for use by rustc only");
-        } else if attr.check_name("plugin") {
-            self.gate_feature("plugin", attr.span,
-                              "compiler plugins are experimental \
-                               and possibly buggy");
-        }
-
-        if attr::contains_name(slice::ref_slice(attr), "lang") {
-            self.gate_feature("lang_items",
-                              attr.span,
-                              "language items are subject to change");
-        }
-
-        if attr.check_name("no_std") {
-            self.gate_feature("no_std", attr.span,
-                              "no_std is experimental");
+        let name = &*attr.name();
+        for &(n, ty) in KNOWN_ATTRIBUTES {
+            if n == name {
+                if let Gated(gate, desc) = ty {
+                    self.gate_feature(gate, attr.span, desc);
+                }
+                return;
+            }
         }
-
-        if attr.check_name("unsafe_no_drop_flag") {
-            self.gate_feature("unsafe_no_drop_flag", attr.span,
-                              "unsafe_no_drop_flag has unstable semantics \
-                               and may be removed in the future");
+        if name.starts_with("rustc_") {
+            self.gate_feature("rustc_attrs", attr.span,
+                              "unless otherwise specified, attributes \
+                               with the prefix `rustc_` \
+                               are reserved for internal compiler diagnostics");
+        } else {
+            self.gate_feature("custom_attribute", attr.span,
+                       format!("The attribute `{}` is currently \
+                                unknown to the the compiler and \
+                                may have meaning \
+                                added to it in the future",
+                                name).as_slice());
         }
     }
 
@@ -591,11 +734,18 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
 
     check(&mut cx, krate);
 
+    // FIXME (pnkfelix): Before adding the 99th entry below, change it
+    // to a single-pass (instead of N calls to `.has_feature`).
+
     Features {
         unboxed_closures: cx.has_feature("unboxed_closures"),
         rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"),
         visible_private_types: cx.has_feature("visible_private_types"),
-        quote: cx.has_feature("quote"),
+        allow_quote: cx.has_feature("quote"),
+        allow_asm: cx.has_feature("asm"),
+        allow_log_syntax: cx.has_feature("log_syntax"),
+        allow_concat_idents: cx.has_feature("concat_idents"),
+        allow_trace_macros: cx.has_feature("trace_macros"),
         old_orphan_check: cx.has_feature("old_orphan_check"),
         simd_ffi: cx.has_feature("simd_ffi"),
         unmarked_api: cx.has_feature("unmarked_api"),
index f4b0c867f42c61ede7e931b0297b4709303d62a0..e8bdcd62b588bbc3672a8435bf49353842829053 100644 (file)
@@ -30,9 +30,9 @@
 #![feature(env)]
 #![feature(hash)]
 #![feature(int_uint)]
-#![feature(io)]
+#![feature(old_io)]
 #![feature(libc)]
-#![feature(path)]
+#![feature(old_path)]
 #![feature(quote, unsafe_destructor)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
index b17fc7fe82e6c66b09da7c36c0b9cd80b239fb34..c0823e04288e31bb078dd6e66607bdd1fc00831b 100644 (file)
@@ -61,7 +61,7 @@ pub fn doc_comment_style(comment: &str) -> ast::AttrStyle {
 
 pub fn strip_doc_comment_decoration(comment: &str) -> String {
     /// remove whitespace-only lines from the start/end of lines
-    fn vertical_trim(lines: Vec<String> ) -> Vec<String> {
+    fn vertical_trim(lines: Vec<String>) -> Vec<String> {
         let mut i = 0;
         let mut j = lines.len();
         // first line of all-stars should be omitted
@@ -82,7 +82,7 @@ fn vertical_trim(lines: Vec<String> ) -> Vec<String> {
         while j > i && lines[j - 1].trim().is_empty() {
             j -= 1;
         }
-        return lines[i..j].iter().map(|x| (*x).clone()).collect();
+        lines[i..j].iter().cloned().collect()
     }
 
     /// remove a "[ \t]*\*" block from each line, if possible
index 407740e580d2e30eff0e5d720d78dfc7490ee62a..f6ec4816b63fc5ac442c8c5b3ba51fa41f57b825 100644 (file)
@@ -240,9 +240,8 @@ macro_rules! maybe_whole {
 
 fn maybe_append(mut lhs: Vec<Attribute>, rhs: Option<Vec<Attribute>>)
                 -> Vec<Attribute> {
-    match rhs {
-        Some(ref attrs) => lhs.extend(attrs.iter().map(|a| a.clone())),
-        None => {}
+    if let Some(ref attrs) = rhs {
+        lhs.extend(attrs.iter().cloned())
     }
     lhs
 }
@@ -467,7 +466,7 @@ pub fn commit_expr(&mut self, e: &Expr, edible: &[token::Token], inedible: &[tok
         debug!("commit_expr {:?}", e);
         if let ExprPath(..) = e.node {
             // might be unit-struct construction; check for recoverableinput error.
-            let mut expected = edible.iter().map(|x| x.clone()).collect::<Vec<_>>();
+            let mut expected = edible.iter().cloned().collect::<Vec<_>>();
             expected.push_all(inedible);
             self.check_for_erroneous_unit_struct_expecting(&expected[]);
         }
@@ -485,7 +484,7 @@ pub fn commit_stmt(&mut self, edible: &[token::Token], inedible: &[token::Token]
         if self.last_token
                .as_ref()
                .map_or(false, |t| t.is_ident() || t.is_path()) {
-            let mut expected = edible.iter().map(|x| x.clone()).collect::<Vec<_>>();
+            let mut expected = edible.iter().cloned().collect::<Vec<_>>();
             expected.push_all(&inedible[]);
             self.check_for_erroneous_unit_struct_expecting(
                 &expected[]);
@@ -1706,7 +1705,7 @@ pub fn lit_from_token(&self, tok: &token::Token) -> Lit_ {
                         (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 {
index 583095e15742738d5fdf2eeb1a42bae3462336a4..7742185897612adbfbdb02a5c7208afac96e9042 100644 (file)
@@ -983,15 +983,14 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
                 try!(self.word_nbsp("trait"));
                 try!(self.print_ident(item.ident));
                 try!(self.print_generics(generics));
-                let bounds: Vec<_> = bounds.iter().map(|b| b.clone()).collect();
                 let mut real_bounds = Vec::with_capacity(bounds.len());
-                for b in bounds {
-                    if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = b {
+                for b in bounds.iter() {
+                    if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = *b {
                         try!(space(&mut self.s));
                         try!(self.word_space("for ?"));
                         try!(self.print_trait_ref(&ptr.trait_ref));
                     } else {
-                        real_bounds.push(b);
+                        real_bounds.push(b.clone());
                     }
                 }
                 try!(self.print_bounds(":", &real_bounds[]));
@@ -2761,15 +2760,13 @@ pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
             ast::LitStr(ref st, style) => self.print_string(&st, style),
             ast::LitByte(byte) => {
                 let mut res = String::from_str("b'");
-                ascii::escape_default(byte, |c| res.push(c as char));
+                res.extend(ascii::escape_default(byte).map(|c| c as char));
                 res.push('\'');
                 word(&mut self.s, &res[])
             }
             ast::LitChar(ch) => {
                 let mut res = String::from_str("'");
-                for c in ch.escape_default() {
-                    res.push(c);
-                }
+                res.extend(ch.escape_default());
                 res.push('\'');
                 word(&mut self.s, &res[])
             }
@@ -2809,8 +2806,8 @@ pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
             ast::LitBinary(ref v) => {
                 let mut escaped: String = String::new();
                 for &ch in &**v {
-                    ascii::escape_default(ch as u8,
-                                          |ch| escaped.push(ch as char));
+                    escaped.extend(ascii::escape_default(ch as u8)
+                                         .map(|c| c as char));
                 }
                 word(&mut self.s, &format!("b\"{}\"", escaped)[])
             }
index c4b3d2813afe4e254838f13f9abf04e44df85872..304f370a1993e0b44284401793c4389f98774d01 100644 (file)
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(int_uint)]
-#![feature(io)]
-#![feature(path)]
+#![feature(old_io)]
+#![feature(old_path)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
-#![feature(std_misc)]
 #![feature(unicode)]
+#![feature(std_misc)]
 #![feature(env)]
 #![cfg_attr(windows, feature(libc))]
 
index 758191a6e1107e8566dfe16d205bfe7f32491504..b978d2d8054e566212eb33868777ad3d9d1924ea 100644 (file)
@@ -72,7 +72,7 @@ pub struct TerminfoTerminal<T> {
     ti: Box<TermInfo>
 }
 
-impl<T: Writer+Send> Terminal<T> for TerminfoTerminal<T> {
+impl<T: Writer+Send+'static> Terminal<T> for TerminfoTerminal<T> {
     fn fg(&mut self, color: color::Color) -> IoResult<bool> {
         let color = self.dim_if_necessary(color);
         if self.num_colors > color {
@@ -164,11 +164,11 @@ fn get_ref<'a>(&'a self) -> &'a T { &self.out }
     fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.out }
 }
 
-impl<T: Writer+Send> UnwrappableTerminal<T> for TerminfoTerminal<T> {
+impl<T: Writer+Send+'static> UnwrappableTerminal<T> for TerminfoTerminal<T> {
     fn unwrap(self) -> T { self.out }
 }
 
-impl<T: Writer+Send> TerminfoTerminal<T> {
+impl<T: Writer+Send+'static> TerminfoTerminal<T> {
     /// Returns `None` whenever the terminal cannot be created for some
     /// reason.
     pub fn new(out: T) -> Option<Box<Terminal<T>+Send+'static>> {
@@ -229,4 +229,3 @@ fn flush(&mut self) -> IoResult<()> {
         self.out.flush()
     }
 }
-
index 82b5ec11d95d1dd8aef5c9f990ade25c9a950d27..0b577f8de74c2a9b2e8178584173c29e8d134b7a 100644 (file)
@@ -608,7 +608,7 @@ fn get_res(fmt: &str, cap: &str, params: &[Param], vars: &mut Variables) ->
             Result<Vec<u8>, String>
         {
             let mut u8v: Vec<_> = fmt.bytes().collect();
-            u8v.extend(cap.as_bytes().iter().map(|&b| b));
+            u8v.extend(cap.bytes());
             expand(&u8v, params, vars)
         }
 
index a56613681c8ca0e7b213601003bfac9a7158b344..e93b956dc7c835eaee3f11af0606a8bcf7437ba2 100644 (file)
@@ -86,7 +86,7 @@ fn bits_to_color(bits: u16) -> color::Color {
     color | (bits & 0x8) // copy the hi-intensity bit
 }
 
-impl<T: Writer+Send> WinConsole<T> {
+impl<T: Writer+Send+'static> WinConsole<T> {
     fn apply(&mut self) {
         let _unused = self.buf.flush();
         let mut accum: libc::WORD = 0;
@@ -139,7 +139,7 @@ fn flush(&mut self) -> IoResult<()> {
     }
 }
 
-impl<T: Writer+Send> Terminal<T> for WinConsole<T> {
+impl<T: Writer+Send+'static> Terminal<T> for WinConsole<T> {
     fn fg(&mut self, color: color::Color) -> IoResult<bool> {
         self.foreground = color;
         self.apply();
@@ -192,6 +192,6 @@ fn get_ref<'a>(&'a self) -> &'a T { &self.buf }
     fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.buf }
 }
 
-impl<T: Writer+Send> UnwrappableTerminal<T> for WinConsole<T> {
+impl<T: Writer+Send+'static> UnwrappableTerminal<T> for WinConsole<T> {
     fn unwrap(self) -> T { self.buf }
 }
index 860ce209d451f11199632fef2ea9288c908a8a29..2cb30ad9804c6de074bbec45e5b29a19c909eb2e 100644 (file)
@@ -39,8 +39,8 @@
 #![feature(env)]
 #![feature(hash)]
 #![feature(int_uint)]
-#![feature(io)]
-#![feature(path)]
+#![feature(old_io)]
+#![feature(old_path)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(std_misc)]
@@ -75,7 +75,7 @@
 use std::num::{Float, Int};
 use std::env;
 use std::sync::mpsc::{channel, Sender};
-use std::thread::{self, Thread};
+use std::thread;
 use std::thunk::{Thunk, Invoke};
 use std::time::Duration;
 
@@ -154,7 +154,7 @@ pub enum TestFn {
     StaticTestFn(fn()),
     StaticBenchFn(fn(&mut Bencher)),
     StaticMetricFn(fn(&mut MetricMap)),
-    DynTestFn(Thunk),
+    DynTestFn(Thunk<'static>),
     DynMetricFn(Box<for<'a> Invoke<&'a mut MetricMap>+'static>),
     DynBenchFn(Box<TDynBenchFn+'static>)
 }
@@ -878,8 +878,8 @@ pub fn run_test(opts: &TestOpts,
     fn run_test_inner(desc: TestDesc,
                       monitor_ch: Sender<MonitorMsg>,
                       nocapture: bool,
-                      testfn: Thunk) {
-        Thread::spawn(move || {
+                      testfn: Thunk<'static>) {
+        thread::spawn(move || {
             let (tx, rx) = channel();
             let mut reader = ChanReader::new(rx);
             let stdout = ChanWriter::new(tx.clone());
@@ -895,7 +895,7 @@ fn run_test_inner(desc: TestDesc,
                 cfg = cfg.stderr(box stderr as Box<Writer + Send>);
             }
 
-            let result_guard = cfg.scoped(move || { testfn.invoke(()) });
+            let result_guard = cfg.spawn(move || { testfn.invoke(()) }).unwrap();
             let stdout = reader.read_to_end().unwrap().into_iter().collect();
             let test_result = calc_result(&desc, result_guard.join());
             monitor_ch.send((desc.clone(), test_result, stdout)).unwrap();
index 89b310d494971a60260e6b2587adc85cdaeac34c..791886be1ce5b6a6de76889ca83bc7d7f53a3f7e 100644 (file)
@@ -77,16 +77,3 @@ pub mod str {
     pub use u_str::{utf8_char_width, is_utf16, Utf16Items, Utf16Item};
     pub use u_str::{utf16_items, Utf16Encoder};
 }
-
-// NOTE: remove after next snapshot
-// this lets us use #[derive(..)]
-#[cfg(stage0)]
-mod std {
-    pub use core::clone;
-    pub use core::cmp;
-    pub use core::fmt;
-    pub use core::marker;
-    // for-loops
-    pub use core::iter;
-    pub use core::option;
-}
index 3c9c4bdedcc876febdf62a64dfaa8698ece966c4..6f5fc5c1969f0a8704e0f5b8fabb27b6610877c4 100644 (file)
@@ -11,6 +11,7 @@
 //! Implementation of the `build` subcommand, used to compile a book.
 
 use std::os;
+use std::env;
 use std::old_io;
 use std::old_io::{fs, File, BufferedWriter, TempDir, IoResult};
 
@@ -80,10 +81,10 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> {
         let out_path = tgt.join(item.path.dirname());
 
         let src;
-        if os::args().len() < 3 {
+        if env::args().len() < 3 {
             src = os::getcwd().unwrap().clone();
         } else {
-            src = Path::new(os::args()[2].clone());
+            src = Path::new(env::args().nth(2).unwrap().clone());
         }
         // preprocess the markdown, rerouting markdown references to html references
         let markdown_data = try!(File::open(&src.join(&item.path)).read_to_string());
@@ -153,16 +154,16 @@ fn execute(&mut self, term: &mut Term) -> CommandResult<()> {
         let src;
         let tgt;
 
-        if os::args().len() < 3 {
+        if env::args().len() < 3 {
             src = cwd.clone();
         } else {
-            src = Path::new(os::args()[2].clone());
+            src = Path::new(env::args().nth(2).unwrap().clone());
         }
 
-        if os::args().len() < 4 {
+        if env::args().len() < 4 {
             tgt = cwd.join("_book");
         } else {
-            tgt = Path::new(os::args()[3].clone());
+            tgt = Path::new(env::args().nth(3).unwrap().clone());
         }
 
         try!(fs::mkdir(&tgt, old_io::USER_DIR));
index a8466465f871bdce7c2c0cc15e208a0aa4460ac2..ace57f0ac2c0b9351e6df4860955697cedd209b4 100644 (file)
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(io)]
+#![feature(old_io)]
 #![feature(os)]
-#![feature(path)]
+#![feature(env)]
+#![feature(old_path)]
 #![feature(rustdoc)]
 
 extern crate rustdoc;
 
-use std::os;
+use std::env;
 use subcommand::Subcommand;
 use term::Term;
 
@@ -48,7 +49,7 @@ macro_rules! try (
 #[cfg(not(test))] // thanks #12327
 fn main() {
     let mut term = Term::new();
-    let cmd = os::args();
+    let cmd: Vec<_> = env::args().collect();
 
     if cmd.len() <= 1 {
         help::usage()
index b922bf1cdd3675fce2f370e6689094b7db1d33dd..98aa3fca184dca3f4c05e04fc9d09ba91641892d 100644 (file)
@@ -11,7 +11,7 @@
 //! An abstraction of the terminal. Eventually, provide color and
 //! verbosity support. For now, just a wrapper around stdout/stderr.
 
-use std::os;
+use std::env;
 use std::old_io::stdio;
 
 pub struct Term {
@@ -28,6 +28,6 @@ pub fn new() -> Term {
     pub fn err(&mut self, msg: &str) {
         // swallow any errors
         let _ = self.err.write_line(msg);
-        os::set_exit_status(101);
+        env::set_exit_status(101);
     }
 }
index 6bb6f1ad2c7e8ef84e0512badbcd8ed62e11824e..1317343712430d241e9115d1c70fd69d63a57e4c 100644 (file)
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2015-02-12
+2015-02-13
index 56948ea1219ea437dff3933d31db71dcc80ccfec..4759c44259d5289d7a71a29b47a6ff1387882c2f 100644 (file)
@@ -1,3 +1,12 @@
+S 2015-02-17 f1bb6c2
+  freebsd-x86_64 59f3a2c6350c170804fb65838e1b504eeab89105
+  linux-i386 191ed5ec4f17e32d36abeade55a1c6085e51245c
+  linux-x86_64 acec86045632f4f3f085c072ba696f889906dffe
+  macos-i386 9d9e622584bfa318f32bcb5b9ce6a365febff595
+  macos-x86_64 e96c1e9860b186507cc75c186d1b96d44df12292
+  winnt-i386 3f43e0e71311636f9143ad6f2ee7a514e9fa3f8e
+  winnt-x86_64 26ef3d9098ea346e5ff8945d5b224bb10c24341d
+
 S 2015-02-04 ac134f7
   freebsd-x86_64 483e37a02a7ebc12a872e3146145e342ba4a5c04
   linux-i386 8af64e5df839cc945399484380a8b2ebe05a6751
index 673c38697b79cbf10644f7b8ecc8f97b1b318348..b38e955231e4a7e5e7985736d4cda9ad1edb609c 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+use std::thread;
 use std::sync::mpsc::{Receiver, channel};
 
-pub fn foo<T:Send + Clone>(x: T) -> Receiver<T> {
+pub fn foo<T:'static + Send + Clone>(x: T) -> Receiver<T> {
     let (tx, rx) = channel();
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         tx.send(x.clone());
     });
     rx
index 7ac3925fb24766385d7958742fa5dc49d84b44f0..01b2b748ba9d83910105567c020b3fb8fd52d311 100644 (file)
@@ -64,16 +64,6 @@ pub fn method_unstable_text(&self) {}
     pub fn method_stable(&self) {}
     #[stable(feature = "rust1", since = "1.0.0", reason = "text")]
     pub fn method_stable_text(&self) {}
-
-    #[locked]
-    pub fn method_locked(&self) {}
-    #[locked="text"]
-    pub fn method_locked_text(&self) {}
-
-    #[frozen]
-    pub fn method_frozen(&self) {}
-    #[frozen="text"]
-    pub fn method_frozen_text(&self) {}
 }
 
 #[stable(feature = "test_feature", since = "1.0.0")]
@@ -101,16 +91,6 @@ fn trait_unstable_text(&self) {}
     fn trait_stable(&self) {}
     #[stable(feature = "rust1", since = "1.0.0", reason = "text")]
     fn trait_stable_text(&self) {}
-
-    #[locked]
-    fn trait_locked(&self) {}
-    #[locked="text"]
-    fn trait_locked_text(&self) {}
-
-    #[frozen]
-    fn trait_frozen(&self) {}
-    #[frozen="text"]
-    fn trait_frozen_text(&self) {}
 }
 
 impl Trait for MethodTester {}
index 12c95e4c60c64beff6a75fcae565e2a0a769ef55..4909d84a34f126960aadfb6e28343ceb275a34fd 100644 (file)
@@ -11,7 +11,7 @@
 #![feature(unboxed_closures)]
 
 use std::collections::{BTreeMap, HashMap, HashSet};
-use std::os;
+use std::env;
 use std::rand::{Rng, IsaacRng, SeedableRng};
 use std::time::Duration;
 
@@ -20,33 +20,33 @@ fn timed<F>(label: &str, f: F) where F: FnMut() {
 }
 
 trait MutableMap {
-    fn insert(&mut self, k: uint, v: uint);
-    fn remove(&mut self, k: &uint) -> bool;
-    fn find(&self, k: &uint) -> Option<&uint>;
+    fn insert(&mut self, k: usize, v: usize);
+    fn remove(&mut self, k: &usize) -> bool;
+    fn find(&self, k: &usize) -> Option<&usize>;
 }
 
-impl MutableMap for BTreeMap<uint, uint> {
-    fn insert(&mut self, k: uint, v: uint) { self.insert(k, v); }
-    fn remove(&mut self, k: &uint) -> bool { self.remove(k).is_some() }
-    fn find(&self, k: &uint) -> Option<&uint> { self.get(k) }
+impl MutableMap for BTreeMap<usize, usize> {
+    fn insert(&mut self, k: usize, v: usize) { self.insert(k, v); }
+    fn remove(&mut self, k: &usize) -> bool { self.remove(k).is_some() }
+    fn find(&self, k: &usize) -> Option<&usize> { self.get(k) }
 }
-impl MutableMap for HashMap<uint, uint> {
-    fn insert(&mut self, k: uint, v: uint) { self.insert(k, v); }
-    fn remove(&mut self, k: &uint) -> bool { self.remove(k).is_some() }
-    fn find(&self, k: &uint) -> Option<&uint> { self.get(k) }
+impl MutableMap for HashMap<usize, usize> {
+    fn insert(&mut self, k: usize, v: usize) { self.insert(k, v); }
+    fn remove(&mut self, k: &usize) -> bool { self.remove(k).is_some() }
+    fn find(&self, k: &usize) -> Option<&usize> { self.get(k) }
 }
 
-fn ascending<M: MutableMap>(map: &mut M, n_keys: uint) {
+fn ascending<M: MutableMap>(map: &mut M, n_keys: usize) {
     println!(" Ascending integers:");
 
     timed("insert", || {
-        for i in 0u..n_keys {
+        for i in 0..n_keys {
             map.insert(i, i + 1);
         }
     });
 
     timed("search", || {
-        for i in 0u..n_keys {
+        for i in 0..n_keys {
             assert_eq!(map.find(&i).unwrap(), &(i + 1));
         }
     });
@@ -58,7 +58,7 @@ fn ascending<M: MutableMap>(map: &mut M, n_keys: uint) {
     });
 }
 
-fn descending<M: MutableMap>(map: &mut M, n_keys: uint) {
+fn descending<M: MutableMap>(map: &mut M, n_keys: usize) {
     println!(" Descending integers:");
 
     timed("insert", || {
@@ -80,32 +80,31 @@ fn descending<M: MutableMap>(map: &mut M, n_keys: uint) {
     });
 }
 
-fn vector<M: MutableMap>(map: &mut M, n_keys: uint, dist: &[uint]) {
+fn vector<M: MutableMap>(map: &mut M, n_keys: usize, dist: &[usize]) {
     timed("insert", || {
-        for i in 0u..n_keys {
+        for i in 0..n_keys {
             map.insert(dist[i], i + 1);
         }
     });
 
     timed("search", || {
-        for i in 0u..n_keys {
+        for i in 0..n_keys {
             assert_eq!(map.find(&dist[i]).unwrap(), &(i + 1));
         }
     });
 
     timed("remove", || {
-        for i in 0u..n_keys {
+        for i in 0..n_keys {
             assert!(map.remove(&dist[i]));
         }
     });
 }
 
 fn main() {
-    let args = os::args();
-    let args = args;
+    let mut args = env::args();
     let n_keys = {
         if args.len() == 2 {
-            args[1].parse::<uint>().unwrap()
+            args.nth(1).unwrap().parse::<usize>().unwrap()
         } else {
             1000000
         }
@@ -131,18 +130,18 @@ fn main() {
     println!("{}", "\nBTreeMap:");
 
     {
-        let mut map: BTreeMap<uint,uint> = BTreeMap::new();
+        let mut map: BTreeMap<usize,usize> = BTreeMap::new();
         ascending(&mut map, n_keys);
     }
 
     {
-        let mut map: BTreeMap<uint,uint> = BTreeMap::new();
+        let mut map: BTreeMap<usize,usize> = BTreeMap::new();
         descending(&mut map, n_keys);
     }
 
     {
         println!(" Random integers:");
-        let mut map: BTreeMap<uint,uint> = BTreeMap::new();
+        let mut map: BTreeMap<usize,usize> = BTreeMap::new();
         vector(&mut map, n_keys, &rand);
     }
 
@@ -150,18 +149,18 @@ fn main() {
     println!("{}", "\nHashMap:");
 
     {
-        let mut map: HashMap<uint,uint> = HashMap::new();
+        let mut map: HashMap<usize,usize> = HashMap::new();
         ascending(&mut map, n_keys);
     }
 
     {
-        let mut map: HashMap<uint,uint> = HashMap::new();
+        let mut map: HashMap<usize,usize> = HashMap::new();
         descending(&mut map, n_keys);
     }
 
     {
         println!(" Random integers:");
-        let mut map: HashMap<uint,uint> = HashMap::new();
+        let mut map: HashMap<usize,usize> = HashMap::new();
         vector(&mut map, n_keys, &rand);
     }
 }
index 33ac8a43b437bf24dcdc17bb0641bf93b4b0f75a..1d440c4540ca3e9a1110ac2fe01646659dd372c1 100644 (file)
@@ -20,7 +20,7 @@
 use std::collections::HashSet;
 use std::collections::hash_map::Hasher;
 use std::hash::Hash;
-use std::os;
+use std::env;
 use std::time::Duration;
 
 struct Results {
@@ -53,29 +53,29 @@ 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<uint> for BitvSet {
-    fn insert(&mut self, k: uint) { self.insert(k); }
-    fn remove(&mut self, k: &uint) -> bool { self.remove(k) }
-    fn contains(&self, k: &uint) -> bool { self.contains(k) }
+impl MutableSet<usize> for BitvSet {
+    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) }
 }
 
 impl Results {
-    pub fn bench_int<T:MutableSet<uint>,
+    pub fn bench_int<T:MutableSet<usize>,
                      R:rand::Rng,
                      F:FnMut() -> T>(
                      &mut self,
                      rng: &mut R,
-                     num_keys: uint,
-                     rand_cap: uint,
+                     num_keys: usize,
+                     rand_cap: usize,
                      mut f: F) {
         {
             let mut set = f();
             timed(&mut self.sequential_ints, || {
-                for i in 0u..num_keys {
+                for i in 0..num_keys {
                     set.insert(i);
                 }
 
-                for i in 0u..num_keys {
+                for i in 0..num_keys {
                     assert!(set.contains(&i));
                 }
             })
@@ -85,19 +85,19 @@ pub fn bench_int<T:MutableSet<uint>,
             let mut set = f();
             timed(&mut self.random_ints, || {
                 for _ in 0..num_keys {
-                    set.insert(rng.gen::<uint>() % rand_cap);
+                    set.insert(rng.gen::<usize>() % rand_cap);
                 }
             })
         }
 
         {
             let mut set = f();
-            for i in 0u..num_keys {
+            for i in 0..num_keys {
                 set.insert(i);
             }
 
             timed(&mut self.delete_ints, || {
-                for i in 0u..num_keys {
+                for i in 0..num_keys {
                     assert!(set.remove(&i));
                 }
             })
@@ -109,16 +109,16 @@ pub fn bench_str<T:MutableSet<String>,
                      F:FnMut() -> T>(
                      &mut self,
                      rng: &mut R,
-                     num_keys: uint,
+                     num_keys: usize,
                      mut f: F) {
         {
             let mut set = f();
             timed(&mut self.sequential_strings, || {
-                for i in 0u..num_keys {
+                for i in 0..num_keys {
                     set.insert(i.to_string());
                 }
 
-                for i in 0u..num_keys {
+                for i in 0..num_keys {
                     assert!(set.contains(&i.to_string()));
                 }
             })
@@ -128,7 +128,7 @@ pub fn bench_str<T:MutableSet<String>,
             let mut set = f();
             timed(&mut self.random_strings, || {
                 for _ in 0..num_keys {
-                    let s = rng.gen::<uint>().to_string();
+                    let s = rng.gen::<usize>().to_string();
                     set.insert(s);
                 }
             })
@@ -136,11 +136,11 @@ pub fn bench_str<T:MutableSet<String>,
 
         {
             let mut set = f();
-            for i in 0u..num_keys {
+            for i in 0..num_keys {
                 set.insert(i.to_string());
             }
             timed(&mut self.delete_strings, || {
-                for i in 0u..num_keys {
+                for i in 0..num_keys {
                     assert!(set.remove(&i.to_string()));
                 }
             })
@@ -179,11 +179,10 @@ fn empty_results() -> Results {
 }
 
 fn main() {
-    let args = os::args();
-    let args = args;
+    let mut args = env::args();
     let num_keys = {
         if args.len() == 2 {
-            args[1].parse::<uint>().unwrap()
+            args.nth(1).unwrap().parse::<usize>().unwrap()
         } else {
             100 // woefully inadequate for any real measurement
         }
@@ -196,7 +195,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, || {
-            let s: HashSet<uint> = HashSet::new();
+            let s: HashSet<usize> = HashSet::new();
             s
         });
         results.bench_str(&mut rng, num_keys, || {
@@ -210,7 +209,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, || {
-            let s: BTreeSet<uint> = BTreeSet::new();
+            let s: BTreeSet<usize> = BTreeSet::new();
             s
         });
         results.bench_str(&mut rng, num_keys, || {
index 00f8feacff8cab0710b16b85f3864a92a2e1da8c..2409487c04fc10072e225e0fe20676a67918ed52 100644 (file)
@@ -16,7 +16,6 @@
 use std::old_io::File;
 use std::iter::repeat;
 use std::mem::swap;
-use std::os;
 use std::env;
 use std::rand::Rng;
 use std::rand;
@@ -25,8 +24,7 @@
 use std::vec;
 
 fn main() {
-    let argv = os::args();
-    let _tests = &argv[1..argv.len()];
+    let argv: Vec<String> = env::args().collect();
 
     macro_rules! bench {
         ($id:ident) =>
index 90cc222c3deba06188dc9788ad9b35817f64367f..57889053e3c1b7a4a751451dc48a00677f87cb66 100644 (file)
@@ -8,17 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::os;
 use std::env;
 
 fn main() {
-    let args = os::args();
+    let args = env::args();
     let args = if env::var_os("RUST_BENCH").is_some() {
         vec!("".to_string(), "10000000".to_string())
     } else if args.len() <= 1u {
         vec!("".to_string(), "100000".to_string())
     } else {
-        args.into_iter().collect()
+        args.collect()
     };
 
     let n = args[1].parse().unwrap();
index 4e9c2fe99bd4a342fdecef0033ca366a2d7019fb..208f088442b9b401c4f13c13c0188f71f3d13663 100644 (file)
@@ -19,9 +19,8 @@
 // version.
 
 use std::sync::mpsc::{channel, Sender, Receiver};
-use std::os;
 use std::env;
-use std::thread::Thread;
+use std::thread;
 use std::time::Duration;
 
 fn move_out<T>(_x: T) {}
@@ -64,7 +63,7 @@ fn run(args: &[String]) {
         let mut worker_results = Vec::new();
         for _ in 0u..workers {
             let to_child = to_child.clone();
-            worker_results.push(Thread::scoped(move|| {
+            worker_results.push(thread::spawn(move|| {
                 for _ in 0u..size / workers {
                     //println!("worker {}: sending {} bytes", i, num_bytes);
                     to_child.send(request::bytes(num_bytes)).unwrap();
@@ -72,7 +71,7 @@ fn run(args: &[String]) {
                 //println!("worker {} exiting", i);
             }));
         }
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             server(&from_parent, &to_parent);
         });
 
@@ -94,13 +93,13 @@ fn run(args: &[String]) {
 }
 
 fn main() {
-    let args = os::args();
+    let args = env::args();
     let args = if env::var_os("RUST_BENCH").is_some() {
         vec!("".to_string(), "1000000".to_string(), "10000".to_string())
-    } else if args.len() <= 1u {
+    } else if args.len() <= 1 {
         vec!("".to_string(), "10000".to_string(), "4".to_string())
     } else {
-        args.into_iter().map(|x| x.to_string()).collect()
+        args.map(|x| x.to_string()).collect()
     };
 
     println!("{:?}", args);
index 2530e8bd90707f31b2e9aa01d6693411516f64cb..76b91f0295bb56abbad11b5c2fa6d86d863519ba 100644 (file)
@@ -15,9 +15,8 @@
 // I *think* it's the same, more or less.
 
 use std::sync::mpsc::{channel, Sender, Receiver};
-use std::os;
 use std::env;
-use std::thread::Thread;
+use std::thread;
 use std::time::Duration;
 
 enum request {
@@ -57,7 +56,7 @@ fn run(args: &[String]) {
         let mut worker_results = Vec::new();
         let from_parent = if workers == 1 {
             let (to_child, from_parent) = channel();
-            worker_results.push(Thread::scoped(move|| {
+            worker_results.push(thread::spawn(move|| {
                 for _ in 0u..size / workers {
                     //println!("worker {}: sending {} bytes", i, num_bytes);
                     to_child.send(request::bytes(num_bytes));
@@ -69,7 +68,7 @@ fn run(args: &[String]) {
             let (to_child, from_parent) = channel();
             for _ in 0u..workers {
                 let to_child = to_child.clone();
-                worker_results.push(Thread::scoped(move|| {
+                worker_results.push(thread::spawn(move|| {
                     for _ in 0u..size / workers {
                         //println!("worker {}: sending {} bytes", i, num_bytes);
                         to_child.send(request::bytes(num_bytes));
@@ -79,7 +78,7 @@ fn run(args: &[String]) {
             }
             from_parent
         };
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             server(&from_parent, &to_parent);
         });
 
@@ -101,13 +100,13 @@ fn run(args: &[String]) {
 }
 
 fn main() {
-    let args = os::args();
+    let args = env::args();
     let args = if env::var_os("RUST_BENCH").is_some() {
         vec!("".to_string(), "1000000".to_string(), "8".to_string())
-    } else if args.len() <= 1u {
+    } else if args.len() <= 1 {
         vec!("".to_string(), "10000".to_string(), "4".to_string())
     } else {
-        args.clone().into_iter().map(|x| x.to_string()).collect()
+        args.map(|x| x.to_string()).collect()
     };
 
     println!("{:?}", args);
index a935a6b30864612eef5b356bf700f74c11de2274..168fe929e12542f79e4a27d5704097a96642f1e2 100644 (file)
@@ -18,7 +18,6 @@
 // no-pretty-expanded FIXME #15189
 // ignore-lexer-test FIXME #15679
 
-use std::os;
 use std::env;
 use std::sync::{Arc, Future, Mutex, Condvar};
 use std::time::Duration;
@@ -64,13 +63,13 @@ fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) {
 }
 
 fn main() {
-    let args = os::args();
+    let args = env::args();
     let args = if env::var_os("RUST_BENCH").is_some() {
         vec!("".to_string(), "100".to_string(), "10000".to_string())
-    } else if args.len() <= 1u {
+    } else if args.len() <= 1 {
         vec!("".to_string(), "10".to_string(), "100".to_string())
     } else {
-        args.clone().into_iter().collect()
+        args.collect()
     };
 
     let num_tasks = args[1].parse::<uint>().unwrap();
index e4e8b4a6e6e1e2a954aadf48ba360d5a27e33c5c..b9512324e42d6426a5c92908c4a4825eb91fb7a4 100644 (file)
 // except according to those terms.
 
 use std::sync::mpsc::channel;
-use std::os;
-use std::thread::Thread;
+use std::env;
+use std::thread;
 
 // This is a simple bench that creates M pairs of tasks. These
 // tasks ping-pong back and forth over a pair of streams. This is a
 // canonical message-passing benchmark as it heavily strains message
 // passing and almost nothing else.
 
-fn ping_pong_bench(n: uint, m: uint) {
+fn ping_pong_bench(n: usize, m: usize) {
 
     // Create pairs of tasks that pingpong back and forth.
-    fn run_pair(n: uint) {
+    fn run_pair(n: usize) {
         // Create a channel: A->B
         let (atx, arx) = channel();
         // Create a channel: B->A
         let (btx, brx) = channel();
 
-        let guard_a = Thread::scoped(move|| {
+        let guard_a = thread::spawn(move|| {
             let (tx, rx) = (atx, brx);
             for _ in 0..n {
                 tx.send(()).unwrap();
@@ -43,7 +43,7 @@ fn run_pair(n: uint) {
             }
         });
 
-        let guard_b = Thread::scoped(move|| {
+        let guard_b = thread::spawn(move|| {
             let (tx, rx) = (btx, arx);
             for _ in 0..n {
                 rx.recv().unwrap();
@@ -63,19 +63,13 @@ fn run_pair(n: uint) {
 
 
 fn main() {
-
-    let args = os::args();
-    let args = args;
-    let n = if args.len() == 3 {
-        args[1].parse::<uint>().unwrap()
-    } else {
-        10000
-    };
-
-    let m = if args.len() == 3 {
-        args[2].parse::<uint>().unwrap()
+    let mut args = env::args();
+    let (n, m) = if args.len() == 3 {
+        let n = args.nth(1).unwrap().parse::<usize>().unwrap();
+        let m = args.next().unwrap().parse::<usize>().unwrap();
+        (n, m)
     } else {
-        4
+        (10000, 4)
     };
 
     ping_pong_bench(n, m);
index 13b8a5ca763ad1e5a8814c08ebdcba27d4470fa8..d420023cf0059eacb92a27f458d0b8dfde1ef4b5 100644 (file)
@@ -9,20 +9,20 @@
 // except according to those terms.
 
 use std::sync::mpsc::channel;
-use std::os;
-use std::thread::Thread;
+use std::env;
+use std::thread;
 
 // A simple implementation of parfib. One subtree is found in a new
 // task and communicated over a oneshot pipe, the other is found
 // locally. There is no sequential-mode threshold.
 
-fn parfib(n: uint) -> uint {
+fn parfib(n: u64) -> u64 {
     if n == 0 || n == 1 {
         return 1;
     }
 
     let (tx, rx) = channel();
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         tx.send(parfib(n-1)).unwrap();
     });
     let m2 = parfib(n-2);
@@ -30,11 +30,9 @@ fn parfib(n: uint) -> uint {
 }
 
 fn main() {
-
-    let args = os::args();
-    let args = args;
+    let mut args = env::args();
     let n = if args.len() == 2 {
-        args[1].parse::<uint>().unwrap()
+        args.nth(1).unwrap().parse::<u64>().unwrap()
     } else {
         10
     };
index 933c1c218c376441004a08eb34a9405025299e4b..d07aa8850aa8306c4ca22d200db5d3a385a3d7e2 100644 (file)
@@ -8,10 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::os;
 use std::env;
 
-fn ack(m: int, n: int) -> int {
+fn ack(m: i64, n: i64) -> i64 {
     if m == 0 {
         return n + 1
     } else {
@@ -24,13 +23,13 @@ fn ack(m: int, n: int) -> int {
 }
 
 fn main() {
-    let args = os::args();
+    let mut args = env::args();
     let args = if env::var_os("RUST_BENCH").is_some() {
         vec!("".to_string(), "12".to_string())
-    } else if args.len() <= 1u {
+    } else if args.len() <= 1 {
         vec!("".to_string(), "8".to_string())
     } else {
-        args.into_iter().collect()
+        args.collect()
     };
     let n = args[1].parse().unwrap();
     println!("Ack(3,{}): {}\n", n, ack(3, n));
index 0311a1ac7c4e1e6ca4e79f69c1d660d8436730c0..1e23da3020f277b7262145bab28a0c3216e010a5 100644 (file)
@@ -41,7 +41,7 @@
 extern crate arena;
 
 use std::iter::range_step;
-use std::thread::{Thread, JoinGuard};
+use std::thread;
 use arena::TypedArena;
 
 struct Tree<'a> {
@@ -84,14 +84,13 @@ fn inner(depth: i32, iterations: i32) -> String {
 }
 
 fn main() {
-    let args = std::os::args();
-    let args = args;
+    let mut args = std::env::args();
     let n = if std::env::var_os("RUST_BENCH").is_some() {
         17
-    } else if args.len() <= 1u {
+    } else if args.len() <= 1 {
         8
     } else {
-        args[1].parse().unwrap()
+        args.nth(1).unwrap().parse().unwrap()
     };
     let min_depth = 4;
     let max_depth = if min_depth + 2 > n {min_depth + 2} else {n};
@@ -111,11 +110,11 @@ fn main() {
     let messages = range_step(min_depth, max_depth + 1, 2).map(|depth| {
         use std::num::Int;
         let iterations = 2.pow((max_depth - depth + min_depth) as usize);
-        Thread::scoped(move || inner(depth, iterations))
+        thread::scoped(move || inner(depth, iterations))
     }).collect::<Vec<_>>();
 
     for message in messages {
-        println!("{}", message.join().ok().unwrap());
+        println!("{}", message.join());
     }
 
     println!("long lived tree of depth {}\t check: {}",
index 628206986c51829a7a6d31c29dd2acd619f887f6..5bd1e91ae14e432776ec859418e4e7dd3fb2e825 100644 (file)
@@ -43,7 +43,7 @@
 use self::Color::{Red, Yellow, Blue};
 use std::sync::mpsc::{channel, Sender, Receiver};
 use std::fmt;
-use std::thread::Thread;
+use std::thread;
 
 fn print_complements() {
     let all = [Blue, Red, Yellow];
@@ -187,7 +187,7 @@ fn rendezvous(nn: uint, set: Vec<Color>) {
             let to_rendezvous = to_rendezvous.clone();
             let to_rendezvous_log = to_rendezvous_log.clone();
             let (to_creature, from_rendezvous) = channel();
-            Thread::spawn(move|| {
+            thread::spawn(move|| {
                 creature(ii,
                          col,
                          from_rendezvous,
@@ -230,10 +230,10 @@ fn main() {
     let nn = if std::env::var_os("RUST_BENCH").is_some() {
         200000
     } else {
-        std::os::args()
-                       .get(1)
+        std::env::args()
+                       .nth(1)
                        .and_then(|arg| arg.parse().ok())
-                       .unwrap_or(600u)
+                       .unwrap_or(600us)
     };
 
     print_complements();
index 92e1bc1a922c281043e468edaa880e0791572a67..f7de935d08fdd3b67fcfc13d264a66154d48a8bf 100644 (file)
@@ -39,7 +39,7 @@
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
 use std::{cmp, iter, mem};
-use std::thread::Thread;
+use std::thread;
 
 fn rotate(x: &mut [i32]) {
     let mut prev = x[0];
@@ -164,7 +164,7 @@ fn fannkuch(n: i32) -> (i32, i32) {
     for (_, j) in (0..N).zip(iter::count(0, k)) {
         let max = cmp::min(j+k, perm.max());
 
-        futures.push(Thread::scoped(move|| {
+        futures.push(thread::scoped(move|| {
             work(perm, j as uint, max as uint)
         }))
     }
@@ -172,7 +172,7 @@ fn fannkuch(n: i32) -> (i32, i32) {
     let mut checksum = 0;
     let mut maxflips = 0;
     for fut in futures {
-        let (cs, mf) = fut.join().ok().unwrap();
+        let (cs, mf) = fut.join();
         checksum += cs;
         maxflips = cmp::max(maxflips, mf);
     }
@@ -180,8 +180,8 @@ fn fannkuch(n: i32) -> (i32, i32) {
 }
 
 fn main() {
-    let n = std::os::args()
-        .get(1)
+    let n = std::env::args()
+        .nth(1)
         .and_then(|arg| arg.parse().ok())
         .unwrap_or(2i32);
 
index d91031b8401f3fddd06235922018c9278a42a63e..277c3ee73dff1aa8693eb4154292a13d85c8822a 100644 (file)
 use std::cmp::min;
 use std::old_io::{stdout, IoResult};
 use std::iter::repeat;
-use std::os;
+use std::env;
 use std::slice::bytes::copy_memory;
 
-const LINE_LEN: uint = 60;
-const LOOKUP_SIZE: uint = 4 * 1024;
+const LINE_LEN: usize = 60;
+const LOOKUP_SIZE: usize = 4 * 1024;
 const LOOKUP_SCALE: f32 = (LOOKUP_SIZE - 1) as f32;
 
 // Random number generator constants
@@ -119,7 +119,7 @@ fn new(alu: &'static str, w: &'a mut W) -> RepeatFasta<'a, W> {
         RepeatFasta { alu: alu, out: w }
     }
 
-    fn make(&mut self, n: uint) -> IoResult<()> {
+    fn make(&mut self, n: usize) -> IoResult<()> {
         let alu_len = self.alu.len();
         let mut buf = repeat(0u8).take(alu_len + LINE_LEN).collect::<Vec<_>>();
         let alu: &[u8] = self.alu.as_bytes();
@@ -188,19 +188,19 @@ fn nextc(&mut self) -> u8 {
         0
     }
 
-    fn make(&mut self, n: uint) -> IoResult<()> {
+    fn make(&mut self, n: usize) -> IoResult<()> {
         let lines = n / LINE_LEN;
         let chars_left = n % LINE_LEN;
         let mut buf = [0;LINE_LEN + 1];
 
         for _ in 0..lines {
-            for i in 0u..LINE_LEN {
+            for i in 0..LINE_LEN {
                 buf[i] = self.nextc();
             }
             buf[LINE_LEN] = '\n' as u8;
             try!(self.out.write(&buf));
         }
-        for i in 0u..chars_left {
+        for i in 0..chars_left {
             buf[i] = self.nextc();
         }
         self.out.write(&buf[..chars_left])
@@ -208,10 +208,9 @@ fn make(&mut self, n: uint) -> IoResult<()> {
 }
 
 fn main() {
-    let args = os::args();
-    let args = args;
+    let mut args = env::args();
     let n = if args.len() > 1 {
-        args[1].parse::<uint>().unwrap()
+        args.nth(1).unwrap().parse::<usize>().unwrap()
     } else {
         5
     };
index 5bf0862e0a1d6b8d809ca254bee45dd3c56d8a9d..2c640c4b092556cab96df76819b992575a0fbf66 100644 (file)
 use std::old_io::{BufferedWriter, File};
 use std::old_io;
 use std::num::Float;
-use std::os;
 use std::env;
 
-const LINE_LENGTH: uint = 60;
+const LINE_LENGTH: usize = 60;
 const IM: u32 = 139968;
 
 struct MyRandom {
@@ -86,7 +85,7 @@ fn next(&mut self) -> Option<u8> {
 }
 
 fn make_fasta<W: Writer, I: Iterator<Item=u8>>(
-    wr: &mut W, header: &str, mut it: I, mut n: uint)
+    wr: &mut W, header: &str, mut it: I, mut n: usize)
     -> std::old_io::IoResult<()>
 {
     try!(wr.write(header.as_bytes()));
@@ -104,14 +103,13 @@ fn make_fasta<W: Writer, I: Iterator<Item=u8>>(
 }
 
 fn run<W: Writer>(writer: &mut W) -> std::old_io::IoResult<()> {
-    let args = os::args();
-    let args = args;
+    let mut args = env::args();
     let n = if env::var_os("RUST_BENCH").is_some() {
         25000000
-    } else if args.len() <= 1u {
+    } else if args.len() <= 1 {
         1000
     } else {
-        args[1].parse().unwrap()
+        args.nth(1).unwrap().parse().unwrap()
     };
 
     let rng = &mut MyRandom::new();
@@ -134,7 +132,7 @@ fn run<W: Writer>(writer: &mut W) -> std::old_io::IoResult<()> {
                         ('t', 0.3015094502008)];
 
     try!(make_fasta(writer, ">ONE Homo sapiens alu\n",
-                    alu.as_bytes().iter().cycle().map(|c| *c), n * 2));
+                    alu.as_bytes().iter().cycle().cloned(), n * 2));
     try!(make_fasta(writer, ">TWO IUB ambiguity codes\n",
                     AAGen::new(rng, iub), n * 3));
     try!(make_fasta(writer, ">THREE Homo sapiens frequency\n",
index 6a062ba3980d65606eb670b96ad1da7dd46416dc..6f9c775609af5ee6a3fd03d484140fb9753420fc 100644 (file)
@@ -8,10 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::os;
 use std::env;
 
-fn fib(n: int) -> int {
+fn fib(n: i64) -> i64 {
     if n < 2 {
         return 1;
     } else {
@@ -20,13 +19,13 @@ fn fib(n: int) -> int {
 }
 
 fn main() {
-    let args = os::args();
+    let args = env::args();
     let args = if env::var_os("RUST_BENCH").is_some() {
         vec!("".to_string(), "40".to_string())
-    } else if args.len() <= 1u {
+    } else if args.len() <= 1 {
         vec!("".to_string(), "30".to_string())
     } else {
-        args.into_iter().collect()
+        args.collect()
     };
     let n = args[1].parse().unwrap();
     println!("{}\n", fib(n));
index 3c96878179f3ab473e05ec3e1a2396f899c84a8b..4d6ef3d533e3f96e3cd9c784d27bfe21e37cf10d 100644 (file)
@@ -24,7 +24,7 @@
 use std::os;
 use std::env;
 use std::sync::mpsc::{channel, Sender, Receiver};
-use std::thread::Thread;
+use std::thread;
 
 fn f64_cmp(x: f64, y: f64) -> Ordering {
     // arbitrarily decide that NaNs are larger than everything.
@@ -172,7 +172,7 @@ fn main() {
 
         let (to_child, from_parent) = channel();
 
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             make_sequence_processor(sz, &from_parent, &to_parent_);
         });
 
index ca920b2fa821c9470b1072db83da7b22ff4b07cc..b5c460737b86cbdf71149c152d310d35636c34e3 100644 (file)
@@ -45,7 +45,7 @@
 use std::ascii::OwnedAsciiExt;
 use std::slice;
 use std::sync::Arc;
-use std::thread::Thread;
+use std::thread;
 
 static TABLE: [u8;4] = [ 'A' as u8, 'C' as u8, 'G' as u8, 'T' as u8 ];
 static TABLE_SIZE: uint = 2 << 16;
@@ -303,17 +303,17 @@ fn main() {
 
     let nb_freqs: Vec<_> = (1u..3).map(|i| {
         let input = input.clone();
-        (i, Thread::scoped(move|| generate_frequencies(&input, i)))
+        (i, thread::scoped(move|| generate_frequencies(&input, i)))
     }).collect();
     let occ_freqs: Vec<_> = OCCURRENCES.iter().map(|&occ| {
         let input = input.clone();
-        Thread::scoped(move|| generate_frequencies(&input, occ.len()))
+        thread::scoped(move|| generate_frequencies(&input, occ.len()))
     }).collect();
 
     for (i, freq) in nb_freqs {
-        print_frequencies(&freq.join().ok().unwrap(), i);
+        print_frequencies(&freq.join(), i);
     }
     for (&occ, freq) in OCCURRENCES.iter().zip(occ_freqs.into_iter()) {
-        print_occurrences(&mut freq.join().ok().unwrap(), occ);
+        print_occurrences(&mut freq.join(), occ);
     }
 }
index e2d51fbf4111d43f63371143e6ea59eafb5b903f..bddf615322816d40e1212465d46b01e9d2503be0 100644 (file)
 // ignore-pretty very bad with line comments
 
 use std::old_io;
-use std::os;
+use std::env;
 use std::simd::f64x2;
 use std::sync::Arc;
-use std::thread::Thread;
+use std::thread;
 
 const ITER: usize = 50;
 const LIMIT: f64 = 2.0;
@@ -81,7 +81,7 @@ fn mandelbrot<W: old_io::Writer>(w: usize, mut out: W) -> old_io::IoResult<()> {
     let mut precalc_i = Vec::with_capacity(h);
 
     let precalc_futures = (0..WORKERS).map(|i| {
-        Thread::scoped(move|| {
+        thread::scoped(move|| {
             let mut rs = Vec::with_capacity(w / WORKERS);
             let mut is = Vec::with_capacity(w / WORKERS);
 
@@ -107,7 +107,7 @@ fn mandelbrot<W: old_io::Writer>(w: usize, mut out: W) -> old_io::IoResult<()> {
     }).collect::<Vec<_>>();
 
     for res in precalc_futures {
-        let (rs, is) = res.join().ok().unwrap();
+        let (rs, is) = res.join();
         precalc_r.extend(rs.into_iter());
         precalc_i.extend(is.into_iter());
     }
@@ -122,7 +122,7 @@ fn mandelbrot<W: old_io::Writer>(w: usize, mut out: W) -> old_io::IoResult<()> {
         let vec_init_r = arc_init_r.clone();
         let vec_init_i = arc_init_i.clone();
 
-        Thread::scoped(move|| {
+        thread::scoped(move|| {
             let mut res: Vec<u8> = Vec::with_capacity((chunk_size * w) / 8);
             let init_r_slice = vec_init_r;
 
@@ -143,7 +143,7 @@ fn mandelbrot<W: old_io::Writer>(w: usize, mut out: W) -> old_io::IoResult<()> {
 
     try!(writeln!(&mut out as &mut Writer, "P4\n{} {}", w, h));
     for res in data {
-        try!(out.write(&res.join().ok().unwrap()));
+        try!(out.write(&res.join()));
     }
     out.flush()
 }
@@ -197,13 +197,13 @@ fn write_line(init_i: f64, vec_init_r: &[f64], res: &mut Vec<u8>) {
 }
 
 fn main() {
-    let args = os::args();
+    let mut args = env::args();
     let res = if args.len() < 2 {
         println!("Test mode: do not dump the image because it's not utf8, \
                   which interferes with the test runner.");
         mandelbrot(1000, old_io::util::NullWriter)
     } else {
-        mandelbrot(args[1].parse().unwrap(), old_io::stdout())
+        mandelbrot(args.nth(1).unwrap().parse().unwrap(), old_io::stdout())
     };
     res.unwrap();
 }
index d061403d5901d175828fb86ad8b82c180020b14a..20249b47d089a0ca87676efecb139e6ac0a0cfe0 100644 (file)
@@ -43,7 +43,7 @@
 use std::iter::repeat;
 use std::sync::Arc;
 use std::sync::mpsc::channel;
-use std::thread::Thread;
+use std::thread;
 
 //
 // Utilities.
@@ -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();
@@ -317,7 +317,7 @@ fn par_search(masks: Vec<Vec<Vec<u64>>>) -> Data {
         let masks = masks.clone();
         let tx = tx.clone();
         let m = *m;
-        Thread::spawn(move|| {
+        thread::spawn(move|| {
             let mut data = Data::new();
             search(&*masks, m, 1, List::Cons(m, &List::Nil), &mut data);
             tx.send(data).unwrap();
index 7904657bece2855dee67265f8f001d3a9c87cdf2..534dfe9548c2f73a5275abc4205b6028c5623c6f 100644 (file)
@@ -173,7 +173,7 @@ fn main() {
     let n = if std::env::var_os("RUST_BENCH").is_some() {
         5000000
     } else {
-        std::os::args().get(1)
+        std::env::args().nth(1)
             .and_then(|arg| arg.parse().ok())
             .unwrap_or(1000)
     };
index 9abc808f88770f2a58269e427b523376bdd7b936..a542c81f2394ea2523717305de5956469606a2a9 100644 (file)
 extern crate getopts;
 
 use std::sync::mpsc::{channel, Sender};
-use std::os;
 use std::env;
 use std::result::Result::{Ok, Err};
-use std::thread::Thread;
+use std::thread;
 use std::time::Duration;
 
-fn fib(n: int) -> int {
-    fn pfib(tx: &Sender<int>, n: int) {
+fn fib(n: isize) -> isize {
+    fn pfib(tx: &Sender<isize>, n: isize) {
         if n == 0 {
             tx.send(0).unwrap();
         } else if n <= 2 {
@@ -36,15 +35,15 @@ fn pfib(tx: &Sender<int>, n: int) {
         } else {
             let (tx1, rx) = channel();
             let tx2 = tx1.clone();
-            Thread::spawn(move|| pfib(&tx2, n - 1));
+            thread::spawn(move|| pfib(&tx2, n - 1));
             let tx2 = tx1.clone();
-            Thread::spawn(move|| pfib(&tx2, n - 2));
+            thread::spawn(move|| pfib(&tx2, n - 2));
             tx.send(rx.recv().unwrap() + rx.recv().unwrap());
         }
     }
 
     let (tx, rx) = channel();
-    Thread::spawn(move|| pfib(&tx, n) );
+    thread::spawn(move|| pfib(&tx, n) );
     rx.recv().unwrap()
 }
 
@@ -66,7 +65,7 @@ fn parse_opts(argv: Vec<String> ) -> Config {
     }
 }
 
-fn stress_task(id: int) {
+fn stress_task(id: isize) {
     let mut i = 0;
     loop {
         let n = 15;
@@ -79,7 +78,7 @@ fn stress_task(id: int) {
 fn stress(num_tasks: int) {
     let mut results = Vec::new();
     for i in 0..num_tasks {
-        results.push(Thread::scoped(move|| {
+        results.push(thread::spawn(move|| {
             stress_task(i);
         }));
     }
@@ -89,13 +88,13 @@ fn stress(num_tasks: int) {
 }
 
 fn main() {
-    let args = os::args();
+    let args = env::args();
     let args = if env::var_os("RUST_BENCH").is_some() {
         vec!("".to_string(), "20".to_string())
-    } else if args.len() <= 1u {
+    } else if args.len() <= 1 {
         vec!("".to_string(), "8".to_string())
     } else {
-        args.into_iter().map(|x| x.to_string()).collect()
+        args.map(|x| x.to_string()).collect()
     };
 
     let opts = parse_opts(args.clone());
@@ -103,12 +102,12 @@ fn main() {
     if opts.stress {
         stress(2);
     } else {
-        let max = args[1].parse::<int>().unwrap();
+        let max = args[1].parse::<isize>().unwrap();
 
         let num_trials = 10;
 
         for n in 1..max + 1 {
-            for _ in 0u..num_trials {
+            for _ in 0..num_trials {
                 let mut fibn = None;
                 let dur = Duration::span(|| fibn = Some(fib(n)));
                 let fibn = fibn.unwrap();
index 944383199543f3972925bfc6a50a0325d02d1c4b..33d959dfe93e35f592320a4913dd69d3c7c3a313 100644 (file)
@@ -47,7 +47,7 @@
 use std::old_io::stdio::{stdin_raw, stdout_raw};
 use std::old_io::{IoResult, EndOfFile};
 use std::ptr::{copy_memory, Unique};
-use std::thread::Thread;
+use std::thread;
 
 struct Tables {
     table8: [u8;1 << 8],
@@ -229,21 +229,12 @@ unsafe impl<T: 'static> Send for Racy<T> {}
 
 /// Executes a closure in parallel over the given iterator over mutable slice.
 /// The closure `f` is run in parallel with an element of `iter`.
-fn parallel<'a, I, T, F>(iter: I, f: F)
-        where T: 'a+Send + Sync,
-              I: Iterator<Item=&'a mut [T]>,
-              F: Fn(&mut [T]) + Sync {
-    use std::mem;
-    use std::raw::Repr;
-
-    iter.map(|chunk| {
-        // Need to convert `f` and `chunk` to something that can cross the task
-        // boundary.
-        let f = Racy(&f as *const F as *const uint);
-        let raw = Racy(chunk.repr());
-        Thread::scoped(move|| {
-            let f = f.0 as *const F;
-            unsafe { (*f)(mem::transmute(raw.0)) }
+fn parallel<'a, I: Iterator, F>(iter: I, ref f: F)
+        where I::Item: Send + 'a,
+              F: Fn(I::Item) + Sync + 'a {
+    iter.map(|x| {
+        thread::scoped(move|| {
+            f(x)
         })
     }).collect::<Vec<_>>();
 }
index 8356df8d8a184264390bdf7b342eda454a5d5e88..76ba5acb16ce4718b0523d1211672b87eec74b8b 100644 (file)
@@ -44,7 +44,7 @@
 #![feature(unboxed_closures)]
 
 use std::iter::{repeat, AdditiveIterator};
-use std::thread::Thread;
+use std::thread;
 use std::mem;
 use std::num::Float;
 use std::os;
 use std::simd::f64x2;
 
 fn main() {
-    let args = os::args();
+    let mut args = env::args();
     let answer = spectralnorm(if env::var_os("RUST_BENCH").is_some() {
         5500
     } else if args.len() < 2 {
         2000
     } else {
-        args[1].parse().unwrap()
+        args.nth(1).unwrap().parse().unwrap()
     });
     println!("{:.9}", answer);
 }
@@ -112,26 +112,16 @@ fn dot(v: &[f64], u: &[f64]) -> f64 {
 }
 
 
-struct Racy<T>(T);
-
-unsafe impl<T: 'static> Send for Racy<T> {}
-
 // Executes a closure in parallel over the given mutable slice. The closure `f`
 // is run in parallel and yielded the starting index within `v` as well as a
 // sub-slice of `v`.
-fn parallel<T, F>(v: &mut [T], f: F)
-                  where T: Send + Sync,
-                        F: Fn(uint, &mut [T]) + Sync {
+fn parallel<'a,T, F>(v: &mut [T], ref f: F)
+                  where T: Send + Sync + 'a,
+                        F: Fn(uint, &mut [T]) + Sync + 'a {
     let size = v.len() / os::num_cpus() + 1;
-
     v.chunks_mut(size).enumerate().map(|(i, chunk)| {
-        // Need to convert `f` and `chunk` to something that can cross the task
-        // boundary.
-        let f = Racy(&f as *const _ as *const uint);
-        let raw = Racy(chunk.repr());
-        Thread::scoped(move|| {
-            let f = f.0 as *const F;
-            unsafe { (*f)(i * size, mem::transmute(raw.0)) }
+        thread::scoped(move|| {
+            f(i * size, chunk)
         })
     }).collect::<Vec<_>>();
 }
index 8614f94da89ea87d03fdb2a70bc733876b112065..2653e758a487d256666700f2f7993bc63136902b 100644 (file)
@@ -39,7 +39,7 @@
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
 use std::sync::mpsc::{channel, Sender, Receiver};
-use std::thread::Thread;
+use std::thread;
 
 fn start(n_tasks: i32, token: i32) {
     let (tx, mut rx) = channel();
@@ -48,9 +48,9 @@ fn start(n_tasks: i32, token: i32) {
     for i in 2 .. n_tasks + 1 {
         let (tx, next_rx) = channel();
         let cur_rx = std::mem::replace(&mut rx, next_rx);
-        guards.push(Thread::scoped(move|| roundtrip(i, tx, cur_rx)));
+        guards.push(thread::spawn(move|| roundtrip(i, tx, cur_rx)));
     }
-    let guard = Thread::scoped(move|| roundtrip(1, tx, rx));
+    let guard = thread::spawn(move|| roundtrip(1, tx, rx));
 }
 
 fn roundtrip(id: i32, tx: Sender<i32>, rx: Receiver<i32>) {
@@ -64,13 +64,13 @@ fn roundtrip(id: i32, tx: Sender<i32>, rx: Receiver<i32>) {
 }
 
 fn main() {
-    let args = std::os::args();
+    let mut args = std::env::args();
     let token = if std::env::var_os("RUST_BENCH").is_some() {
         2000000
     } else {
-        args.get(1).and_then(|arg| arg.parse().ok()).unwrap_or(1000)
+        args.nth(1).and_then(|arg| arg.parse().ok()).unwrap_or(1000)
     };
-    let n_tasks = args.get(2)
+    let n_tasks = args.next()
                       .and_then(|arg| arg.parse().ok())
                       .unwrap_or(503);
 
index e6948a1371c9ed401b3de108cbaf0c2554a4b5c3..a54a869412e35483529c1cd943cf6c423e7e298f 100644 (file)
 // Microbenchmark for the smallintmap library
 
 use std::collections::VecMap;
-use std::os;
 use std::env;
 use std::time::Duration;
 
-fn append_sequential(min: uint, max: uint, map: &mut VecMap<uint>) {
+fn append_sequential(min: usize, max: usize, map: &mut VecMap<usize>) {
     for i in min..max {
-        map.insert(i, i + 22u);
+        map.insert(i, i + 22);
     }
 }
 
-fn check_sequential(min: uint, max: uint, map: &VecMap<uint>) {
+fn check_sequential(min: usize, max: usize, map: &VecMap<usize>) {
     for i in min..max {
-        assert_eq!(map[i], i + 22u);
+        assert_eq!(map[i], i + 22);
     }
 }
 
 fn main() {
-    let args = os::args();
+    let args = env::args();
     let args = if env::var_os("RUST_BENCH").is_some() {
         vec!("".to_string(), "100000".to_string(), "100".to_string())
-    } else if args.len() <= 1u {
+    } else if args.len() <= 1 {
         vec!("".to_string(), "10000".to_string(), "50".to_string())
     } else {
-        args.into_iter().collect()
+        args.collect()
     };
-    let max = args[1].parse::<uint>().unwrap();
-    let rep = args[2].parse::<uint>().unwrap();
+    let max = args[1].parse::<usize>().unwrap();
+    let rep = args[2].parse::<usize>().unwrap();
 
     let mut checkf = Duration::seconds(0);
     let mut appendf = Duration::seconds(0);
 
-    for _ in 0u..rep {
+    for _ in 0..rep {
         let mut map = VecMap::new();
-        let d1 = Duration::span(|| append_sequential(0u, max, &mut map));
-        let d2 = Duration::span(|| check_sequential(0u, max, &map));
+        let d1 = Duration::span(|| append_sequential(0, max, &mut map));
+        let d2 = Duration::span(|| check_sequential(0, max, &map));
 
         checkf = checkf + d2;
         appendf = appendf + d1;
index c5a64db95e6a3071632a5a3cfdbae46ab3309f28..ada8efcbf38e15a90090f64bc35e33b5932fac99 100644 (file)
@@ -18,7 +18,7 @@
 use std::old_io;
 use std::iter::repeat;
 use std::num::Int;
-use std::os;
+use std::env;
 
 // Computes a single solution to a given 9x9 sudoku
 //
@@ -269,8 +269,8 @@ fn check_DEFAULT_SUDOKU_solution() {
 }
 
 fn main() {
-    let args        = os::args();
-    let use_default = args.len() == 1u;
+    let args        = env::args();
+    let use_default = args.len() == 1;
     let mut sudoku = if use_default {
         Sudoku::from_vec(&DEFAULT_SUDOKU)
     } else {
index c45efe5f54b2cc9ed4d1a54a177b7139990bd221..6b412c47cd7f81bdf9d0713f8818dbd84aaa1471 100644 (file)
@@ -11,7 +11,7 @@
 #![feature(unsafe_destructor, box_syntax)]
 
 use std::env;
-use std::thread::Thread;
+use std::thread;
 use std::time::Duration;
 
 #[derive(Clone)]
@@ -32,7 +32,7 @@ fn main() {
 fn run(repeat: int, depth: int) {
     for _ in 0..repeat {
         let dur = Duration::span(|| {
-            let _ = Thread::scoped(move|| {
+            let _ = thread::spawn(move|| {
                 recurse_or_panic(depth, None)
             }).join();
         });
index 9edb4201098d6c4a472786205995832a416c051c..e36d685d7c6ea9b73f85d29b147510ec1fc69030 100644 (file)
 // ignore-pretty very bad with line comments
 
 use std::sync::mpsc::{channel, Sender};
-use std::os;
 use std::env;
-use std::thread::Thread;
+use std::thread;
 
 fn child_generation(gens_left: uint, tx: Sender<()>) {
     // This used to be O(n^2) in the number of generations that ever existed.
     // With this code, only as many generations are alive at a time as tasks
     // alive at a time,
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         if gens_left & 1 == 1 {
-            Thread::yield_now(); // shake things up a bit
+            thread::yield_now(); // shake things up a bit
         }
         if gens_left > 0 {
             child_generation(gens_left - 1, tx); // recurse
@@ -39,13 +38,13 @@ fn child_generation(gens_left: uint, tx: Sender<()>) {
 }
 
 fn main() {
-    let args = os::args();
+    let args = env::args();
     let args = if env::var_os("RUST_BENCH").is_some() {
         vec!("".to_string(), "100000".to_string())
     } else if args.len() <= 1 {
         vec!("".to_string(), "100".to_string())
     } else {
-        args.clone().into_iter().collect()
+        args.collect()
     };
 
     let (tx, rx) = channel();
index 279b3fa432a3cb208eefc98c64d476e61209ec01..69b9e89dbc5228c42f3d7f9363ce60397ee499dc 100644 (file)
@@ -8,14 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::os;
 use std::env;
-use std::thread::Thread;
+use std::thread;
 
-fn f(n: uint) {
+fn f(n: usize) {
     let mut i = 0u;
     while i < n {
-        let _ = Thread::scoped(move|| g()).join();
+        let _ = thread::spawn(move|| g()).join();
         i += 1u;
     }
 }
@@ -23,15 +22,15 @@ fn f(n: uint) {
 fn g() { }
 
 fn main() {
-    let args = os::args();
+    let args = env::args();
     let args = if env::var_os("RUST_BENCH").is_some() {
         vec!("".to_string(), "400".to_string())
-    } else if args.len() <= 1u {
+    } else if args.len() <= 1 {
         vec!("".to_string(), "10".to_string())
     } else {
-        args.into_iter().collect()
+        args.collect()
     };
     let n = args[1].parse().unwrap();
-    let mut i = 0u;
-    while i < n { Thread::spawn(move|| f(n) ); i += 1u; }
+    let mut i = 0;
+    while i < n { thread::spawn(move|| f(n) ); i += 1; }
 }
index c9ca6e5326c69474a50fda738f119df4cf0b6502..fd1deffb59d4da94a3f81b8253ee63752b1cb0fc 100644 (file)
@@ -10,7 +10,6 @@
 
 // aux-build:macro_crate_test.rs
 // ignore-stage1
-// ignore-android
 // error-pattern: unknown start of token: \u{0}
 
 // Issue #15750 and #15962 : this test is checking that the standard
index adcdba04cc7823dcb62068d6524d20852e91683f..361840a1618e7b014e6824bb5f676ec1d4d4376a 100644 (file)
@@ -10,7 +10,6 @@
 
 // aux-build:macro_crate_test.rs
 // ignore-stage1
-// ignore-android
 
 #[macro_use] #[no_link]
 extern crate macro_crate_test;
index b5ff8b715563288616a5a0fc5637dd56e100cd13..ba8e20069c1964db8aa1190646157d87ddfff233 100644 (file)
@@ -10,7 +10,6 @@
 
 // aux-build:macro_crate_test.rs
 // ignore-stage1
-// ignore-android
 
 #[macro_use] #[no_link]
 extern crate macro_crate_test;
index 68b27822d3d0d2d3dc5919e814459418e7c705e8..e13ddd13f5d993f29eaee1015b82c1509a59d013 100644 (file)
@@ -10,7 +10,6 @@
 
 // aux-build:macro_crate_MacroRulesTT.rs
 // ignore-stage1
-// ignore-android
 // error-pattern: plugin tried to register a new MacroRulesTT
 
 #![feature(plugin)]
diff --git a/src/test/compile-fail/ascii-only-character-escape.rs b/src/test/compile-fail/ascii-only-character-escape.rs
deleted file mode 100644 (file)
index 1ba25a8..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let x = "\x80"; //~ ERROR may only be used
-    let y = "\xff"; //~ ERROR may only be used
-    let z = "\xe2"; //~ ERROR may only be used
-    let a = b"\x00e2";  // ok because byte literal
-}
-
diff --git a/src/test/compile-fail/asm-gated2.rs b/src/test/compile-fail/asm-gated2.rs
new file mode 100644 (file)
index 0000000..d2ee011
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    unsafe {
+        println!("{}", asm!("")); //~ ERROR inline assembly is not stable
+    }
+}
diff --git a/src/test/compile-fail/attr-before-eof.rs b/src/test/compile-fail/attr-before-eof.rs
deleted file mode 100644 (file)
index e347562..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[derive(Debug)] //~ERROR expected item after attributes
diff --git a/src/test/compile-fail/attr-before-ext.rs b/src/test/compile-fail/attr-before-ext.rs
deleted file mode 100644 (file)
index 098c5aa..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    #[attr] //~ ERROR expected item after attributes
-    println!("hi");
-}
diff --git a/src/test/compile-fail/attr-before-let.rs b/src/test/compile-fail/attr-before-let.rs
deleted file mode 100644 (file)
index acc9aa8..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    #[attr] //~ ERROR expected item
-    let _i = 0;
-}
diff --git a/src/test/compile-fail/attr-before-stmt.rs b/src/test/compile-fail/attr-before-stmt.rs
deleted file mode 100644 (file)
index ec837cd..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern:expected item
-
-fn f() {
-  #[foo = "bar"]
-  let x = 10;
-}
-
-fn main() {
-}
diff --git a/src/test/compile-fail/attr-dangling-in-fn.rs b/src/test/compile-fail/attr-dangling-in-fn.rs
deleted file mode 100644 (file)
index 384622f..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern:expected item
-
-fn f() {
-  #[foo = "bar"]
-}
-
-fn main() {
-}
diff --git a/src/test/compile-fail/attr-dangling-in-mod.rs b/src/test/compile-fail/attr-dangling-in-mod.rs
deleted file mode 100644 (file)
index 59a922e..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern:expected item
-
-fn main() {
-}
-
-#[foo = "bar"]
diff --git a/src/test/compile-fail/attr.rs b/src/test/compile-fail/attr.rs
deleted file mode 100644 (file)
index 4bd6141..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(lang_items)]
-
-fn main() {}
-
-#![lang(foo)] //~ ERROR an inner attribute is not permitted in this context
-fn foo() {}
diff --git a/src/test/compile-fail/attrs-after-extern-mod.rs b/src/test/compile-fail/attrs-after-extern-mod.rs
deleted file mode 100644 (file)
index df74761..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Constants (static variables) can be used to match in patterns, but mutable
-// statics cannot. This ensures that there's some form of error if this is
-// attempted.
-
-extern crate libc;
-
-extern {
-    static mut rust_dbg_static_mut: libc::c_int;
-    pub fn rust_dbg_static_mut_check_four();
-    #[cfg(stage37)] //~ ERROR expected item after attributes
-}
-
-pub fn main() {}
diff --git a/src/test/compile-fail/bad-char-literals.rs b/src/test/compile-fail/bad-char-literals.rs
deleted file mode 100644 (file)
index 2a358ae..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-tidy-cr
-// ignore-tidy-tab
-fn main() {
-    // these literals are just silly.
-    ''';
-    //~^ ERROR: character constant must be escaped: \'
-
-    // note that this is a literal "\n" byte
-    '
-';
-    //~^^ ERROR: character constant must be escaped: \n
-
-    // note that this is a literal "\r" byte
-    '\r'; //~ ERROR: character constant must be escaped: \r
-
-    // note that this is a literal tab character here
-    '  ';
-    //~^ ERROR: character constant must be escaped: \t
-}
diff --git a/src/test/compile-fail/bad-lit-suffixes.rs b/src/test/compile-fail/bad-lit-suffixes.rs
deleted file mode 100644 (file)
index d10337e..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-extern crate
-    "foo"suffix //~ ERROR extern crate name with a suffix is illegal
-     as foo;
-
-extern
-    "C"suffix //~ ERROR ABI spec with a suffix is illegal
-    fn foo() {}
-
-extern
-    "C"suffix //~ ERROR ABI spec with a suffix is illegal
-{}
-
-fn main() {
-    ""suffix; //~ ERROR str literal with a suffix is illegal
-    b""suffix; //~ ERROR binary str literal with a suffix is illegal
-    r#""#suffix; //~ ERROR str literal with a suffix is illegal
-    br#""#suffix; //~ ERROR binary str literal with a suffix is illegal
-    'a'suffix; //~ ERROR char literal with a suffix is illegal
-    b'a'suffix; //~ ERROR byte literal with a suffix is illegal
-
-    1234u1024; //~ ERROR illegal width `1024` for integer literal
-    1234i1024; //~ ERROR illegal width `1024` for integer literal
-    1234f1024; //~ ERROR illegal width `1024` for float literal
-    1234.5f1024; //~ ERROR illegal width `1024` for float literal
-
-    1234suffix; //~ ERROR illegal suffix `suffix` for numeric literal
-    0b101suffix; //~ ERROR illegal suffix `suffix` for numeric literal
-    1.0suffix; //~ ERROR illegal suffix `suffix` for float literal
-    1.0e10suffix; //~ ERROR illegal suffix `suffix` for float literal
-}
diff --git a/src/test/compile-fail/bad-value-ident-false.rs b/src/test/compile-fail/bad-value-ident-false.rs
deleted file mode 100644 (file)
index ca10bdd..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn false() { } //~ ERROR expected identifier, found keyword `false`
-fn main() { }
diff --git a/src/test/compile-fail/bad-value-ident-true.rs b/src/test/compile-fail/bad-value-ident-true.rs
deleted file mode 100644 (file)
index 4508d52..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn true() { } //~ ERROR expected identifier, found keyword `true`
-fn main() { }
index 980c498e39b471c1f02cbfd658733759e7c448ee..7f676f5166f7f77fb77129553870257313bc66ac 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(box_syntax)]
 
-use std::thread::Thread;
+use std::thread;
 
 fn borrow<F>(v: &isize, f: F) where F: FnOnce(&isize) {
     f(v);
@@ -19,7 +19,7 @@ fn borrow<F>(v: &isize, f: F) where F: FnOnce(&isize) {
 fn box_imm() {
     let v = box 3;
     let _w = &v;
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         println!("v={}", *v);
         //~^ ERROR cannot move `v` into closure
     });
@@ -28,7 +28,7 @@ fn box_imm() {
 fn box_imm_explicit() {
     let v = box 3;
     let _w = &v;
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         println!("v={}", *v);
         //~^ ERROR cannot move
     });
index 94e213ae1ae5b00b60af7ffa038b7e8ea44aeb27..9db05d76284e8d23cdc1660fb9e834e3310a9f2f 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(box_syntax)]
 
-use std::thread::Thread;
+use std::thread;
 
 fn borrow<T>(_: &T) { }
 
@@ -19,7 +19,7 @@ fn different_vars_after_borrows() {
     let p1 = &x1;
     let x2 = box 2;
     let p2 = &x2;
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         drop(x1); //~ ERROR cannot move `x1` into closure because it is borrowed
         drop(x2); //~ ERROR cannot move `x2` into closure because it is borrowed
     });
@@ -32,7 +32,7 @@ fn different_vars_after_moves() {
     drop(x1);
     let x2 = box 2;
     drop(x2);
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         drop(x1); //~ ERROR capture of moved value: `x1`
         drop(x2); //~ ERROR capture of moved value: `x2`
     });
@@ -41,7 +41,7 @@ fn different_vars_after_moves() {
 fn same_var_after_borrow() {
     let x = box 1;
     let p = &x;
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         drop(x); //~ ERROR cannot move `x` into closure because it is borrowed
         drop(x); //~ ERROR use of moved value: `x`
     });
@@ -51,7 +51,7 @@ fn same_var_after_borrow() {
 fn same_var_after_move() {
     let x = box 1;
     drop(x);
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         drop(x); //~ ERROR capture of moved value: `x`
         drop(x); //~ ERROR use of moved value: `x`
     });
index c7b75ade5558440ded259a53aaaf115b984904b5..c3fb6a1be8797a811819022975446ca9fabf5711 100644 (file)
@@ -13,7 +13,7 @@
 
 trait Foo : Send { }
 
-impl <'a> Foo for &'a mut () { }
-//~^ ERROR the type `&'a mut ()` does not fulfill the required lifetime
+impl Foo for std::rc::Rc<i8> { }
+//~^ ERROR the trait `core::marker::Send` is not implemented
 
 fn main() { }
index 2ca288b60a33fb8a5530014af74f609d3f3d0917..38730d241f68532b43f35c2dc15f3d1177c46d67 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(optin_builtin_traits)]
+
 use std::marker::Send;
 
 enum TestE {
@@ -16,18 +18,21 @@ enum TestE {
 
 struct MyType;
 
+struct NotSync;
+impl !Sync for NotSync {}
+
 unsafe impl Send for TestE {}
 unsafe impl Send for MyType {}
 unsafe impl Send for (MyType, MyType) {}
 //~^ ERROR builtin traits can only be implemented on structs or enums
 
-unsafe impl Send for &'static MyType {}
+unsafe impl Send for &'static NotSync {}
 //~^ ERROR builtin traits can only be implemented on structs or enums
 
 unsafe impl Send for [MyType] {}
 //~^ ERROR builtin traits can only be implemented on structs or enums
 
-unsafe impl Send for &'static [MyType] {}
+unsafe impl Send for &'static [NotSync] {}
 //~^ ERROR builtin traits can only be implemented on structs or enums
 
 fn is_send<T: Send>() {}
diff --git a/src/test/compile-fail/concat_idents-gate.rs b/src/test/compile-fail/concat_idents-gate.rs
new file mode 100644 (file)
index 0000000..f4d9744
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const XY_1: i32 = 10;
+
+fn main() {
+    const XY_2: i32 = 20;
+    let a = concat_idents!(X, Y_1); //~ ERROR `concat_idents` is not stable
+    let b = concat_idents!(X, Y_2); //~ ERROR `concat_idents` is not stable
+    assert_eq!(a, 10);
+    assert_eq!(b, 20);
+}
diff --git a/src/test/compile-fail/concat_idents-gate2.rs b/src/test/compile-fail/concat_idents-gate2.rs
new file mode 100644 (file)
index 0000000..d8f8f80
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const XY_1: i32 = 10;
+
+fn main() {
+    const XY_2: i32 = 20;
+    assert_eq!(10, concat_idents!(X, Y_1)); //~ ERROR `concat_idents` is not stable
+    assert_eq!(20, concat_idents!(X, Y_2)); //~ ERROR `concat_idents` is not stable
+}
diff --git a/src/test/compile-fail/custom_attribute.rs b/src/test/compile-fail/custom_attribute.rs
new file mode 100644 (file)
index 0000000..193063a
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[foo] //~ ERROR The attribute `foo`
+fn main() {
+
+}
\ No newline at end of file
diff --git a/src/test/compile-fail/doc-before-attr.rs b/src/test/compile-fail/doc-before-attr.rs
deleted file mode 100644 (file)
index bb44a6a..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/// hi
-#[derive(Debug)] //~ERROR expected item after attributes
diff --git a/src/test/compile-fail/doc-before-eof.rs b/src/test/compile-fail/doc-before-eof.rs
deleted file mode 100644 (file)
index e6dd410..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/// hi //~ERROR expected item after doc comment
diff --git a/src/test/compile-fail/doc-before-extern-rbrace.rs b/src/test/compile-fail/doc-before-extern-rbrace.rs
deleted file mode 100644 (file)
index 5afd1b2..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-extern {
-    /// hi
-}
-//~^^ ERROR expected item after doc comment
diff --git a/src/test/compile-fail/doc-before-macro.rs b/src/test/compile-fail/doc-before-macro.rs
deleted file mode 100644 (file)
index 8dc6c54..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    /// hi
-    println!("hi");
-    //~^^ ERROR expected item after doc comment
-}
diff --git a/src/test/compile-fail/doc-before-rbrace.rs b/src/test/compile-fail/doc-before-rbrace.rs
deleted file mode 100644 (file)
index 6d05064..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    println!("Hi"); /// hi
-    //~^ ERROR expected item after doc comment
-}
diff --git a/src/test/compile-fail/doc-before-semi.rs b/src/test/compile-fail/doc-before-semi.rs
deleted file mode 100644 (file)
index 8b0300e..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    /// hi
-    ;
-    //~^^ ERROR expected item after doc comment
-}
diff --git a/src/test/compile-fail/extern-crate-as-no-string-help.rs b/src/test/compile-fail/extern-crate-as-no-string-help.rs
deleted file mode 100644 (file)
index 5cc52f6..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Tests that the proper help is displayed in the error message
-
-extern crate foo as bar;
-//~^ ERROR expected `;`, found `as`
-//~^^ HELP perhaps you meant to enclose the crate name `foo` in a string?
diff --git a/src/test/compile-fail/generic-non-trailing-defaults.rs b/src/test/compile-fail/generic-non-trailing-defaults.rs
deleted file mode 100644 (file)
index 0cfb05b..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-struct Heap;
-
-struct Vec<A = Heap, T>; //~ ERROR type parameters with a default must be trailing
-
-struct Foo<A, B = Vec<C>, C>; //~ ERROR type parameters with a default must be trailing
-
-fn main() {}
diff --git a/src/test/compile-fail/int-literal-too-large-span.rs b/src/test/compile-fail/int-literal-too-large-span.rs
deleted file mode 100644 (file)
index 8a496c9..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// issue #17123
-
-fn main() {
-    100000000000000000000000000000000 //~ ERROR int literal is too large
-
-        ; // the span shouldn't point to this.
-}
diff --git a/src/test/compile-fail/issue-10412.rs b/src/test/compile-fail/issue-10412.rs
deleted file mode 100644 (file)
index 8a99633..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-trait Serializable<'self, T> { //~ ERROR no longer a special lifetime
-    fn serialize(val : &'self T) -> Vec<u8> ; //~ ERROR no longer a special lifetime
-    fn deserialize(repr : &[u8]) -> &'self T; //~ ERROR no longer a special lifetime
-}
-
-impl<'self> Serializable<str> for &'self str { //~ ERROR no longer a special lifetime
-    //~^ ERROR no longer a special lifetime
-    fn serialize(val : &'self str) -> Vec<u8> { //~ ERROR no longer a special lifetime
-        vec!(1)
-    }
-    fn deserialize(repr: &[u8]) -> &'self str { //~ ERROR no longer a special lifetime
-        "hi"
-    }
-}
-
-fn main() {
-    println!("hello");
-    let x = "foo".to_string();
-    let y = x;
-    println!("{}", y);
-}
index 236142a69192171de4547379e037439f6aa12e76..735f529277c360be6c7291d432c54373e65d0446 100644 (file)
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 use std::sync::mpsc::channel;
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
     let (tx, rx) = channel();
-    let _t = Thread::spawn(move|| -> () {
+    let _t = thread::spawn(move|| -> () {
         loop {
             let tx = tx;
             //~^ ERROR: use of moved value: `tx`
diff --git a/src/test/compile-fail/issue-12560-1.rs b/src/test/compile-fail/issue-12560-1.rs
deleted file mode 100644 (file)
index ea2043e..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// For style and consistency reasons, non-parametrized enum variants must
-// be used simply as `ident` instead of `ident ()`.
-// This test-case covers enum declaration.
-
-enum Foo {
-    Bar(), //~ ERROR nullary enum variants are written with no trailing `( )`
-    Baz(), //~ ERROR nullary enum variants are written with no trailing `( )`
-    Bazar
-}
-
-fn main() {
-    println!("{}", match Bar { Bar => 1, Baz => 2, Bazar => 3 })
-}
diff --git a/src/test/compile-fail/issue-14182.rs b/src/test/compile-fail/issue-14182.rs
deleted file mode 100644 (file)
index 364951a..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-test FIXME(japari) remove test
-
-struct Foo {
-    f: for <'b> |&'b isize|:
-      'b -> &'b isize //~ ERROR use of undeclared lifetime name `'b`
-}
-
-fn main() {
-    let mut x: Vec< for <'a> ||
-       :'a //~ ERROR use of undeclared lifetime name `'a`
-    > = Vec::new();
-    x.push(|| {});
-
-    let foo = Foo {
-        f: |x| x
-    };
-}
diff --git a/src/test/compile-fail/issue-17383.rs b/src/test/compile-fail/issue-17383.rs
deleted file mode 100644 (file)
index c71e0ec..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-enum X {
-    A =
-        b'a' //~ ERROR discriminator values can only be used with a c-like enum
-    ,
-    B(isize)
-}
-
-fn main() {}
diff --git a/src/test/compile-fail/issue-17718-const-mut.rs b/src/test/compile-fail/issue-17718-const-mut.rs
deleted file mode 100644 (file)
index 5177ebb..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-const
-mut //~ ERROR: const globals cannot be mutable
-//~^ HELP did you mean to declare a static?
-FOO: usize = 3;
-
-fn main() {
-}
-
diff --git a/src/test/compile-fail/issue-1802-2.rs b/src/test/compile-fail/issue-1802-2.rs
deleted file mode 100644 (file)
index c7aacdf..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern:no valid digits found for number
-fn main() {
-    log(error, 0bu);
-}
diff --git a/src/test/compile-fail/issue-5544-a.rs b/src/test/compile-fail/issue-5544-a.rs
deleted file mode 100644 (file)
index 42a18ba..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let _i = 18446744073709551616; // 2^64
-    //~^ ERROR int literal is too large
-}
diff --git a/src/test/compile-fail/issue-5544-b.rs b/src/test/compile-fail/issue-5544-b.rs
deleted file mode 100644 (file)
index 1f166ec..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let _i = 0xff_ffff_ffff_ffff_ffff_is;
-    //~^ ERROR int literal is too large
-}
index 01bed69fb1de9e23cc3f05ee9172be050c161d95..b6d371e4b119fa932b6a615caee83cd5e50c0878 100644 (file)
@@ -9,47 +9,47 @@
 // except according to those terms.
 
 use std::{int, i8, i16, i32, i64};
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
-    assert!(Thread::scoped(move|| int::MIN / -1).join().is_err());
+    assert!(thread::spawn(move|| { int::MIN / -1; }).join().is_err());
     //~^ ERROR attempted to divide with overflow in a constant expression
-    assert!(Thread::scoped(move|| i8::MIN / -1).join().is_err());
+    assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
     //~^ ERROR attempted to divide with overflow in a constant expression
-    assert!(Thread::scoped(move|| i16::MIN / -1).join().is_err());
+    assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
     //~^ ERROR attempted to divide with overflow in a constant expression
-    assert!(Thread::scoped(move|| i32::MIN / -1).join().is_err());
+    assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
     //~^ ERROR attempted to divide with overflow in a constant expression
-    assert!(Thread::scoped(move|| i64::MIN / -1).join().is_err());
+    assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
     //~^ ERROR attempted to divide with overflow in a constant expression
-    assert!(Thread::scoped(move|| 1is / 0).join().is_err());
+    assert!(thread::spawn(move|| { 1is / 0; }).join().is_err());
     //~^ ERROR attempted to divide by zero in a constant expression
-    assert!(Thread::scoped(move|| 1i8 / 0).join().is_err());
+    assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
     //~^ ERROR attempted to divide by zero in a constant expression
-    assert!(Thread::scoped(move|| 1i16 / 0).join().is_err());
+    assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
     //~^ ERROR attempted to divide by zero in a constant expression
-    assert!(Thread::scoped(move|| 1i32 / 0).join().is_err());
+    assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
     //~^ ERROR attempted to divide by zero in a constant expression
-    assert!(Thread::scoped(move|| 1i64 / 0).join().is_err());
+    assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
     //~^ ERROR attempted to divide by zero in a constant expression
-    assert!(Thread::scoped(move|| int::MIN % -1).join().is_err());
+    assert!(thread::spawn(move|| { int::MIN % -1; }).join().is_err());
     //~^ ERROR attempted remainder with overflow in a constant expression
-    assert!(Thread::scoped(move|| i8::MIN % -1).join().is_err());
+    assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
     //~^ ERROR attempted remainder with overflow in a constant expression
-    assert!(Thread::scoped(move|| i16::MIN % -1).join().is_err());
+    assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
     //~^ ERROR attempted remainder with overflow in a constant expression
-    assert!(Thread::scoped(move|| i32::MIN % -1).join().is_err());
+    assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
     //~^ ERROR attempted remainder with overflow in a constant expression
-    assert!(Thread::scoped(move|| i64::MIN % -1).join().is_err());
+    assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
     //~^ ERROR attempted remainder with overflow in a constant expression
-    assert!(Thread::scoped(move|| 1is % 0).join().is_err());
+    assert!(thread::spawn(move|| { 1is % 0; }).join().is_err());
     //~^ ERROR attempted remainder with a divisor of zero in a constant expression
-    assert!(Thread::scoped(move|| 1i8 % 0).join().is_err());
+    assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
     //~^ ERROR attempted remainder with a divisor of zero in a constant expression
-    assert!(Thread::scoped(move|| 1i16 % 0).join().is_err());
+    assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
     //~^ ERROR attempted remainder with a divisor of zero in a constant expression
-    assert!(Thread::scoped(move|| 1i32 % 0).join().is_err());
+    assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
     //~^ ERROR attempted remainder with a divisor of zero in a constant expression
-    assert!(Thread::scoped(move|| 1i64 % 0).join().is_err());
+    assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
     //~^ ERROR attempted remainder with a divisor of zero in a constant expression
 }
diff --git a/src/test/compile-fail/issue-8537.rs b/src/test/compile-fail/issue-8537.rs
deleted file mode 100644 (file)
index dba9e75..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub extern
-  "invalid-abi" //~ ERROR illegal ABI
-fn foo() {}
-
-fn main() {}
diff --git a/src/test/compile-fail/keyword-as-as-identifier.rs b/src/test/compile-fail/keyword-as-as-identifier.rs
deleted file mode 100644 (file)
index f307b12..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py as'
-
-fn main() {
-    let as = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-break-as-identifier.rs b/src/test/compile-fail/keyword-break-as-identifier.rs
deleted file mode 100644 (file)
index 1e2725e..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py break'
-
-fn main() {
-    let break = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-else-as-identifier.rs b/src/test/compile-fail/keyword-else-as-identifier.rs
deleted file mode 100644 (file)
index 101fd93..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py else'
-
-fn main() {
-    let else = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-enum-as-identifier.rs b/src/test/compile-fail/keyword-enum-as-identifier.rs
deleted file mode 100644 (file)
index ed504cc..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py enum'
-
-fn main() {
-    let enum = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-extern-as-identifier.rs b/src/test/compile-fail/keyword-extern-as-identifier.rs
deleted file mode 100644 (file)
index 3260506..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py extern'
-
-fn main() {
-    let extern = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-fn-as-identifier.rs b/src/test/compile-fail/keyword-fn-as-identifier.rs
deleted file mode 100644 (file)
index 8c98da2..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py fn'
-
-fn main() {
-    let fn = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-for-as-identifier.rs b/src/test/compile-fail/keyword-for-as-identifier.rs
deleted file mode 100644 (file)
index 196a339..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py for'
-
-fn main() {
-    let for = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-if-as-identifier.rs b/src/test/compile-fail/keyword-if-as-identifier.rs
deleted file mode 100644 (file)
index 05f82ec..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py if'
-
-fn main() {
-    let if = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-impl-as-identifier.rs b/src/test/compile-fail/keyword-impl-as-identifier.rs
deleted file mode 100644 (file)
index 1dd2180..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py impl'
-
-fn main() {
-    let impl = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-let-as-identifier.rs b/src/test/compile-fail/keyword-let-as-identifier.rs
deleted file mode 100644 (file)
index 0069a26..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py let'
-
-fn main() {
-    let let = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-loop-as-identifier.rs b/src/test/compile-fail/keyword-loop-as-identifier.rs
deleted file mode 100644 (file)
index 6e469e8..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py loop'
-
-fn main() {
-    let loop = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-match-as-identifier.rs b/src/test/compile-fail/keyword-match-as-identifier.rs
deleted file mode 100644 (file)
index 9155ebc..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py match'
-
-fn main() {
-    let match = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-mod-as-identifier.rs b/src/test/compile-fail/keyword-mod-as-identifier.rs
deleted file mode 100644 (file)
index 02f57e9..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py mod'
-
-fn main() {
-    let mod = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-pub-as-identifier.rs b/src/test/compile-fail/keyword-pub-as-identifier.rs
deleted file mode 100644 (file)
index aa67974..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py pub'
-
-fn main() {
-    let pub = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-return-as-identifier.rs b/src/test/compile-fail/keyword-return-as-identifier.rs
deleted file mode 100644 (file)
index c567644..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py return'
-
-fn main() {
-    let return = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-self-as-identifier.rs b/src/test/compile-fail/keyword-self-as-identifier.rs
deleted file mode 100644 (file)
index 8bb5214..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py self'
-
-fn main() {
-    let self = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-static-as-identifier.rs b/src/test/compile-fail/keyword-static-as-identifier.rs
deleted file mode 100644 (file)
index 7268c4f..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py static'
-
-fn main() {
-    let static = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-struct-as-identifier.rs b/src/test/compile-fail/keyword-struct-as-identifier.rs
deleted file mode 100644 (file)
index bd42eac..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py struct'
-
-fn main() {
-    let struct = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-super-as-identifier.rs b/src/test/compile-fail/keyword-super-as-identifier.rs
deleted file mode 100644 (file)
index 0378c32..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py super'
-
-fn main() {
-    let super = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-super.rs b/src/test/compile-fail/keyword-super.rs
deleted file mode 100644 (file)
index 0c94f76..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let super: isize; //~ ERROR expected identifier, found keyword `super`
-}
diff --git a/src/test/compile-fail/keyword-trait-as-identifier.rs b/src/test/compile-fail/keyword-trait-as-identifier.rs
deleted file mode 100644 (file)
index 95c0d17..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py trait'
-
-fn main() {
-    let trait = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-type-as-identifier.rs b/src/test/compile-fail/keyword-type-as-identifier.rs
deleted file mode 100644 (file)
index 0aaa2a6..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py type'
-
-fn main() {
-    let type = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-unsafe-as-identifier.rs b/src/test/compile-fail/keyword-unsafe-as-identifier.rs
deleted file mode 100644 (file)
index 1b631eb..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py unsafe'
-
-fn main() {
-    let unsafe = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-use-as-identifier.rs b/src/test/compile-fail/keyword-use-as-identifier.rs
deleted file mode 100644 (file)
index e82afd5..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py use'
-
-fn main() {
-    let use = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword-while-as-identifier.rs b/src/test/compile-fail/keyword-while-as-identifier.rs
deleted file mode 100644 (file)
index 95cea65..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py while'
-
-fn main() {
-    let while = "foo"; //~ error: ident
-}
diff --git a/src/test/compile-fail/keyword.rs b/src/test/compile-fail/keyword.rs
deleted file mode 100644 (file)
index 64eac47..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub mod break {
-    //~^ ERROR expected identifier, found keyword `break`
-}
diff --git a/src/test/compile-fail/keywords-followed-by-double-colon.rs b/src/test/compile-fail/keywords-followed-by-double-colon.rs
deleted file mode 100644 (file)
index f69b041..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    struct::foo();  //~ ERROR expected identifier
-    mut::baz(); //~ ERROR expected identifier
-}
-
index de7639c621325cb171fcfe7229f8bc4be192f740..d5276efa8be9812649f978f8ee7da58e6238faa3 100644 (file)
@@ -17,7 +17,7 @@
 
 trait Gettable<T> {}
 
-impl<T: Send + Copy> Gettable<T> for S<T> {}
+impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
 
 fn f<T>(val: T) {
     let t: S<T> = S;
index 7984b3b32c21391abf3ca09b47295a0e80d53b99..570f7ad7fe3bf214adae00a7ac6644053305dd6c 100644 (file)
@@ -20,7 +20,7 @@ trait Message : Send { }
 
 fn object_ref_with_static_bound_not_ok() {
     assert_send::<&'static (Dummy+'static)>();
-    //~^ ERROR the trait `core::marker::Send` is not implemented
+    //~^ ERROR the trait `core::marker::Sync` is not implemented
 }
 
 fn box_object_with_no_bound_not_ok<'a>() {
@@ -28,7 +28,7 @@ fn box_object_with_no_bound_not_ok<'a>() {
 }
 
 fn object_with_send_bound_ok() {
-    assert_send::<&'static (Dummy+Send)>();
+    assert_send::<&'static (Dummy+Sync)>();
     assert_send::<Box<Dummy+Send>>();
 }
 
index 3d47d33d7c35d0af26b75285944093ad380f235b..48d5215b7085be78f389d72df0139f2efa25130e 100644 (file)
 // is broken into two parts because some errors occur in distinct
 // phases in the compiler. See kindck-send-object2.rs as well!
 
-fn assert_send<T:Send>() { }
+fn assert_send<T:Send+'static>() { }
 trait Dummy { }
 
 // careful with object types, who knows what they close over...
 fn test51<'a>() {
     assert_send::<&'a Dummy>();
-    //~^ ERROR the trait `core::marker::Send` is not implemented
+    //~^ ERROR the trait `core::marker::Sync` is not implemented
 }
 fn test52<'a>() {
-    assert_send::<&'a (Dummy+Send)>();
+    assert_send::<&'a (Dummy+Sync)>();
     //~^ ERROR does not fulfill the required lifetime
 }
 
 // ...unless they are properly bounded
 fn test60() {
-    assert_send::<&'static (Dummy+Send)>();
+    assert_send::<&'static (Dummy+Sync)>();
 }
 fn test61() {
     assert_send::<Box<Dummy+Send>>();
index 75bae09b37f17cad3f3961e06a64230970263c91..d3d166e2a6916181d24c32984ed212bca92a07e6 100644 (file)
@@ -14,7 +14,7 @@ fn assert_send<T:Send>() { }
 trait Dummy { }
 
 fn test50() {
-    assert_send::<&'static Dummy>(); //~ ERROR the trait `core::marker::Send` is not implemented
+    assert_send::<&'static Dummy>(); //~ ERROR the trait `core::marker::Sync` is not implemented
 }
 
 fn test53() {
@@ -23,7 +23,7 @@ fn test53() {
 
 // ...unless they are properly bounded
 fn test60() {
-    assert_send::<&'static (Dummy+Send)>();
+    assert_send::<&'static (Dummy+Sync)>();
 }
 fn test61() {
     assert_send::<Box<Dummy+Send>>();
index 266b61566560f12aee08dfbe1138774caf6767dd..406711902a543555547453d1900b5469d74d2ea9 100644 (file)
@@ -18,8 +18,8 @@ fn assert_send<T:Send>() { }
 fn test32() { assert_send::<Vec<isize> >(); }
 
 // but not if they own a bad thing
-fn test40<'a>(_: &'a isize) {
-    assert_send::<Box<&'a isize>>(); //~ ERROR does not fulfill the required lifetime
+fn test40() {
+    assert_send::<Box<*mut u8>>(); //~ ERROR `core::marker::Send` is not implemented
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/kindck-send-region-pointers.rs b/src/test/compile-fail/kindck-send-region-pointers.rs
deleted file mode 100644 (file)
index e2a5b06..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that borrowed pointers are not sendable unless 'static.
-
-fn assert_send<T:Send>() { }
-
-// lifetime pointers with 'static lifetime are ok
-fn test01() { assert_send::<&'static isize>(); }
-fn test02() { assert_send::<&'static str>(); }
-fn test03() { assert_send::<&'static [isize]>(); }
-
-// whether or not they are mutable
-fn test10() { assert_send::<&'static mut isize>(); }
-
-// otherwise lifetime pointers are not ok
-fn test20<'a>(_: &'a isize) {
-    assert_send::<&'a isize>(); //~ ERROR does not fulfill the required lifetime
-}
-fn test21<'a>(_: &'a isize) {
-    assert_send::<&'a str>(); //~ ERROR does not fulfill the required lifetime
-}
-fn test22<'a>(_: &'a isize) {
-    assert_send::<&'a [isize]>(); //~ ERROR does not fulfill the required lifetime
-}
-
-fn main() { }
diff --git a/src/test/compile-fail/lex-bad-numeric-literals.rs b/src/test/compile-fail/lex-bad-numeric-literals.rs
deleted file mode 100644 (file)
index 9a490be..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    0o1.0; //~ ERROR: octal float literal is not supported
-    0o2f32; //~ ERROR: octal float literal is not supported
-    0o3.0f32; //~ ERROR: octal float literal is not supported
-    0o4e4; //~ ERROR: octal float literal is not supported
-    0o5.0e5; //~ ERROR: octal float literal is not supported
-    0o6e6f32; //~ ERROR: octal float literal is not supported
-    0o7.0e7f64; //~ ERROR: octal float literal is not supported
-    0x8.0e+9; //~ ERROR: hexadecimal float literal is not supported
-    0x9.0e-9; //~ ERROR: hexadecimal float literal is not supported
-    0o; //~ ERROR: no valid digits
-    1e+; //~ ERROR: expected at least one digit in exponent
-    0x539.0; //~ ERROR: hexadecimal float literal is not supported
-    99999999999999999999999999999999; //~ ERROR: int literal is too large
-    99999999999999999999999999999999u32; //~ ERROR: int literal is too large
-    0x; //~ ERROR: no valid digits
-    0xu32; //~ ERROR: no valid digits
-    0ou32; //~ ERROR: no valid digits
-    0bu32; //~ ERROR: no valid digits
-    0b; //~ ERROR: no valid digits
-    0o123f64; //~ ERROR: octal float literal is not supported
-    0o123.456; //~ ERROR: octal float literal is not supported
-    0b101f64; //~ ERROR: binary float literal is not supported
-    0b111.101; //~ ERROR: binary float literal is not supported
-}
diff --git a/src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs b/src/test/compile-fail/lex-bare-cr-string-literal-doc-comment.rs
deleted file mode 100644 (file)
index c1e5121..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-tidy-cr
-
-/// doc comment with bare CR: '\r'
-pub fn foo() {}
-//~^^ ERROR: bare CR not allowed in doc-comment
-
-/** block doc comment with bare CR: '\r' */
-pub fn bar() {}
-//~^^ ERROR: bare CR not allowed in block doc-comment
-
-fn main() {
-    // the following string literal has a bare CR in it
-    let _s = "foo\rbar"; //~ ERROR: bare CR not allowed in string
-
-    // the following string literal has a bare CR in it
-    let _s = r"bar\rfoo"; //~ ERROR: bare CR not allowed in raw string
-
-    // the following string literal has a bare CR in it
-    let _s = "foo\\rbar"; //~ ERROR: unknown character escape: \r
-}
diff --git a/src/test/compile-fail/lifetime-no-keyword.rs b/src/test/compile-fail/lifetime-no-keyword.rs
deleted file mode 100644 (file)
index 8ffbcd9..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn foo<'a>(a: &'a isize) { }
-fn bar(a: &'static isize) { }
-fn baz(a: &'let isize) { } //~ ERROR invalid lifetime name
-
-fn main() { }
diff --git a/src/test/compile-fail/lifetime-obsoleted-self.rs b/src/test/compile-fail/lifetime-obsoleted-self.rs
deleted file mode 100644 (file)
index 766922f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn baz(a: &'self isize) { } //~ ERROR invalid lifetime name: 'self is no longer a special lifetime
-
-fn main() { }
index 555cc2b9a7aad95c8c43b10932550e08154b65c8..35f93c13fb5e23792d071df8a27293f168a4fb5d 100644 (file)
@@ -11,4 +11,5 @@
 extern {
     #[linkage = "extern_weak"] static foo: isize;
     //~^ ERROR: the `linkage` attribute is experimental and not portable
+    //~^^ ERROR: the `linkage` attribute is experimental and not portable
 }
index 635d58e04c7ab14142413220c8ba829e25bbd8df..1cf6e90d6c855e079de891b4eedfd0c134c28a97 100644 (file)
@@ -10,6 +10,6 @@
 
 #[linkage = "external"]
 static foo: isize = 0;
-//~^ ERROR: the `linkage` attribute is experimental and not portable
+//~^^ ERROR: the `linkage` attribute is experimental and not portable
 
 fn main() {}
index e4fd042d09845369a6226777abb947d308a0ee09..dd4e1212a00ca0b508a1f820b622f3c302f221da 100644 (file)
@@ -13,6 +13,7 @@
 
 #![deny(unused_attributes)]
 #![allow(dead_code)]
+#![feature(custom_attribute)]
 
 #[abi="stdcall"] extern {} //~ ERROR unused attribute
 
index 5c187176fb2ae9c1654724b13432eedf6639ee89..f9cdfa4f7d685356f7b7d14f17494f796c7ca26b 100644 (file)
@@ -133,6 +133,11 @@ fn test_method_object(foo: &Trait) {
     impl UnstableTrait for S { } //~ WARNING use of unstable library feature
 
     trait LocalTrait : UnstableTrait { } //~ WARNING use of unstable library feature
+
+    impl Trait for S {
+        fn trait_stable(&self) {}
+        fn trait_unstable(&self) {} //~ WARNING use of unstable library feature
+    }
 }
 
 mod inheritance {
index e4cb92477c2997b52ae26c97df6eb3b7c49b8313..af4e81be1951d86d73dcf6a08be63ea973311e80 100644 (file)
@@ -11,6 +11,7 @@
 // When denying at the crate level, be sure to not get random warnings from the
 // injected intrinsics by the compiler.
 
+#![feature(custom_attribute)]
 #![deny(unused_attributes)]
 
 #![mutable_doc] //~ ERROR unused attribute
index 057b8e3acc6e37224fbdab11cd4211cbc59a8d7a..a4f46cbd1874fade8cc21cc143f90a7f5cb0fe2d 100644 (file)
 
 #![allow(dead_code)]
 #![deny(non_snake_case)]
-#![feature(path)]
-#![feature(io)]
 
-use std::old_io::File;
-use std::old_io::IoError;
+mod foo {
+    pub enum Foo { Foo }
+}
 
 struct Something {
     X: usize //~ ERROR structure field `X` should have a snake case name such as `x`
@@ -30,13 +29,11 @@ fn main() {
     let Test: usize = 0; //~ ERROR variable `Test` should have a snake case name such as `test`
     println!("{}", Test);
 
-    let mut f = File::open(&Path::new("something.txt"));
-    let mut buff = [0u8; 16];
-    match f.read(&mut buff) {
-        Ok(cnt) => println!("read this many bytes: {}", cnt),
-        Err(IoError{ kind: EndOfFile, .. }) => println!("Got end of file: {:?}", EndOfFile),
-//~^ ERROR variable `EndOfFile` should have a snake case name such as `end_of_file`
-//~^^ WARN `EndOfFile` is named the same as one of the variants of the type `std::old_io::IoErrorKind`
+    match foo::Foo::Foo {
+        Foo => {}
+//~^ ERROR variable `Foo` should have a snake case name such as `foo`
+//~^^ WARN `Foo` is named the same as one of the variants of the type `foo::Foo`
+//~^^^ WARN unused variable: `Foo`
     }
 
     test(1);
diff --git a/src/test/compile-fail/log-syntax-gate2.rs b/src/test/compile-fail/log-syntax-gate2.rs
new file mode 100644 (file)
index 0000000..bb19e97
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    println!("{}", log_syntax!()); //~ ERROR `log_syntax!` is not stable
+}
index e4fc5bb462700d0d8409e534488bc6e139bd98ba..e76eaea365ea6e0e8707341f54a86e93b421ec1c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(custom_attribute)]
+
 macro_rules! test { ($nm:ident,
                      #[$a:meta],
                      $i:item) => (mod $nm { #![$a] $i }); }
index a0f23c72bc41e0b590f03d55081fb4a3d5b6b27e..cff01f36f3ad72132a4694725a2435fe45b8f82e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(custom_attribute)]
+
 macro_rules! test { ($nm:ident,
                      #[$a:meta],
                      $i:item) => (mod $nm { #[$a] $i }); }
diff --git a/src/test/compile-fail/macros-no-semicolon-items.rs b/src/test/compile-fail/macros-no-semicolon-items.rs
deleted file mode 100644 (file)
index 3142920..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-macro_rules! foo()  //~ ERROR semicolon
-
-fn main() {
-}
index 14dd983161b4a0219a39ed4ea6559414b34dc6ed..cf7a8378b9a9a120391cf88b7298532623c0ae44 100644 (file)
@@ -30,4 +30,4 @@ pub mod bar {
     // #[stable] is not inherited
     pub fn unmarked() {}
     //~^ ERROR This node does not have a stability attribute
-}
\ No newline at end of file
+}
diff --git a/src/test/compile-fail/mod_file_disambig.rs b/src/test/compile-fail/mod_file_disambig.rs
new file mode 100644 (file)
index 0000000..48bd00a
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod mod_file_disambig_aux; //~ ERROR file for module `mod_file_disambig_aux` found at both
+
+fn main() {
+    assert_eq!(mod_file_aux::bar(), 10);
+}
diff --git a/src/test/compile-fail/mod_file_not_owning.rs b/src/test/compile-fail/mod_file_not_owning.rs
new file mode 100644 (file)
index 0000000..adbcedd
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern: cannot declare a new module at this location
+
+mod mod_file_not_owning_aux1;
+
+fn main() {}
index 3f14be2da109a872717f1e12bc012c53041bf0f4..0219f5b6becb3bae271892a3cc559bebacc8ae56 100644 (file)
@@ -18,6 +18,8 @@
 // These are all fairly trivial cases: unused variables or direct
 // drops of substructure.
 
+#![feature(rustc_attrs)]
+
 pub struct D { d: isize }
 impl Drop for D { fn drop(&mut self) { } }
 
index 6c0635d6be93142869bac1f997f0588a21b0b0ae..175488bf2fcd02f38c0c4a926a9aeb858342cd3c 100644 (file)
@@ -18,6 +18,8 @@
 // These are checking that enums are tracked; note that their output
 // paths include "downcasts" of the path to a particular enum.
 
+#![feature(rustc_attrs)]
+
 use self::Lonely::{Zero, One, Two};
 
 pub struct D { d: isize }
index 24d73ec2274ba39dc1444e25dc2346f1bb7863ac..b65921177adaaf145db68235d20778b3f6c6a99c 100644 (file)
@@ -18,6 +18,8 @@
 // This checks the handling of `_` within variants, especially when mixed
 // with bindings.
 
+#![feature(rustc_attrs)]
+
 use self::Lonely::{Zero, One, Two};
 
 pub struct D { d: isize }
index 97e8e45ed06566a56823a2b3fd3d174f2aae1519..191e23a28638b59c8119386ae18525d6f172cc36 100644 (file)
@@ -19,6 +19,8 @@
 // early draft of the code did not properly traverse up through all of
 // the parents of the leaf fragment.)
 
+#![feature(rustc_attrs)]
+
 pub struct D { d: isize }
 impl Drop for D { fn drop(&mut self) { } }
 
index 9f70421fa842563327b4edffdbfc6ce8443eeb92..38a385eacac5c07795c9a19e49c5d9288b3b7e63 100644 (file)
@@ -17,6 +17,8 @@
 
 // This is the first test that checks moving into local variables.
 
+#![feature(rustc_attrs)]
+
 pub struct D { d: isize }
 impl Drop for D { fn drop(&mut self) { } }
 
index b249d0d739789921f80a7c4e153e8835234a1768..122727c3f6b64a0c1cf75e4ca4a216cf51df98b3 100644 (file)
@@ -18,6 +18,8 @@
 // Test that moving into a field (i.e. overwriting it) fragments the
 // receiver.
 
+#![feature(rustc_attrs)]
+
 use std::mem::drop;
 
 pub struct Pair<X,Y> { x: X, y: Y }
index 2af2b2957f8d6d042def30ecc3506c27a30f8715..a2a37208cd6168b61f4dcbdce75f59cf93e4b65d 100644 (file)
@@ -19,6 +19,8 @@
 // both moving out of the structure (i.e. reading `*p.x`) and writing
 // into the container (i.e. writing `*p.x`).
 
+#![feature(rustc_attrs)]
+
 pub struct D { d: isize }
 impl Drop for D { fn drop(&mut self) { } }
 
index 18bf4066076ba54335cac25938f389ce84802263..e57268dbfa32aa985afb154168824b5916186a22 100644 (file)
@@ -22,6 +22,8 @@
 // also that in this case we cannot do a move out of `&T`, so we only
 // test writing `*p.x` here.
 
+#![feature(rustc_attrs)]
+
 pub struct D { d: isize }
 impl Drop for D { fn drop(&mut self) { } }
 
index 426d5fa29a02000aa657a87354dde4af4339e028..350f4169034004620cae6bf2cb6367532dfb27b2 100644 (file)
@@ -14,6 +14,8 @@
 // Note also that the `test_move_array_then_overwrite` tests represent
 // cases that we probably should make illegal.
 
+#![feature(rustc_attrs)]
+
 pub struct D { d: isize }
 impl Drop for D { fn drop(&mut self) { } }
 
index dc90994fcc102e3c2455050dcb88a44538f8c5db..32fa773ec807947f892e274386644f2c748a939a 100644 (file)
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
     let x = "Hello world!".to_string();
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         println!("{}", x);
     });
     println!("{}", x); //~ ERROR use of moved value
diff --git a/src/test/compile-fail/no-binary-float-literal.rs b/src/test/compile-fail/no-binary-float-literal.rs
deleted file mode 100644 (file)
index 2e207f9..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern:binary float literal is not supported
-
-fn main() {
-    0b101010f64;
-    0b101.010;
-    0b101p4f64;
-}
index 939d7c7a5348b84f60d90d0c6fa71a152fbd80ef..7b7b3c414dded597ff769400ee605153b7fa192e 100644 (file)
 // error-pattern: use of moved value
 
 use std::sync::Arc;
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
     let v = vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
     let arc_v = Arc::new(v);
 
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         assert_eq!((*arc_v)[3], 4);
     });
 
diff --git a/src/test/compile-fail/no-hex-float-literal.rs b/src/test/compile-fail/no-hex-float-literal.rs
deleted file mode 100644 (file)
index 4abb609..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern:hexadecimal float literal is not supported
-
-fn main() {
-    0xABC.Df;
-    0x567.89;
-    0xDEAD.BEEFp-2f;
-}
index 730ba9ab9ea71326823536840b62a120c835999a..1720b40c83bbd749256e04179b06e3ae7446f92b 100644 (file)
@@ -9,13 +9,13 @@
 // except according to those terms.
 
 use std::sync::Arc;
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
     let v = vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
     let arc_v = Arc::new(v);
 
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         assert_eq!((*arc_v)[3], 4);
     });
 
index ae2847aab0963fe0dc652f98f438d7913a480b4f..5ebc386109a8bcdf3ce589bf37e840dc0b8757eb 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(unsafe_destructor)]
 
-use std::thread::Thread;
+use std::thread;
 use std::rc::Rc;
 
 #[derive(Debug)]
@@ -35,7 +35,7 @@ fn foo(x: Port<()>) -> foo {
 
     let x = foo(Port(Rc::new(())));
 
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         //~^ ERROR `core::marker::Send` is not implemented
         let y = x;
         println!("{:?}", y);
diff --git a/src/test/compile-fail/no-unsafe-self.rs b/src/test/compile-fail/no-unsafe-self.rs
deleted file mode 100644 (file)
index 0bf73bb..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-trait A {
-    fn foo(*mut self); //~ ERROR cannot pass self by unsafe pointer
-    fn bar(*self); //~ ERROR cannot pass self by unsafe pointer
-}
-
-struct X;
-impl A for X {
-    fn foo(*mut self) { } //~ ERROR cannot pass self by unsafe pointer
-    fn bar(*self) { } //~ ERROR cannot pass self by unsafe pointer
-}
-
-fn main() { }
diff --git a/src/test/compile-fail/non-str-meta.rs b/src/test/compile-fail/non-str-meta.rs
deleted file mode 100644 (file)
index 752f72f..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Issue #623 - non-string meta items are not serialized correctly;
-// for now just forbid them
-
-#[foo = 1] //~ ERROR: non-string literals are not allowed in meta-items
-fn main() { }
index 73f71751ee80f37d35e857e31e86917af0f83381..ac03c085b7b6cc6c3d03bbe8f742daa7677f58a2 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(rustc_attrs)]
+
 #[rustc_object_lifetime_default]
 struct A<T>(T); //~ ERROR None
 
diff --git a/src/test/compile-fail/obsolete-for-sized.rs b/src/test/compile-fail/obsolete-for-sized.rs
deleted file mode 100644 (file)
index 1b86d08..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that we generate obsolete syntax errors around usages of `for Sized?`
-
-trait Foo for Sized? {} //~ ERROR obsolete syntax: for Sized?
-
-trait Bar for ?Sized {} //~ ERROR obsolete syntax: for Sized?
-
-fn main() { }
diff --git a/src/test/compile-fail/obsolete-proc.rs b/src/test/compile-fail/obsolete-proc.rs
deleted file mode 100644 (file)
index 5208cdb..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that we generate obsolete syntax errors around usages of `proc`.
-
-fn foo(p: proc()) { } //~ ERROR obsolete syntax: the `proc` type
-
-fn bar() { proc() 1; } //~ ERROR obsolete syntax: `proc` expression
-
-fn main() { }
diff --git a/src/test/compile-fail/qquote-1.rs b/src/test/compile-fail/qquote-1.rs
deleted file mode 100644 (file)
index deae9a8..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-test Can't use syntax crate here
-
-#![feature(quote)]
-
-extern crate syntax;
-
-use io::*;
-
-use syntax::diagnostic;
-use syntax::ast;
-use syntax::codemap;
-use syntax::parse;
-use syntax::print::*;
-
-
-trait fake_ext_ctxt {
-    fn cfg() -> ast::CrateConfig;
-    fn parse_sess() -> parse::parse_sess;
-    fn call_site() -> span;
-    fn ident_of(st: &str) -> ast::ident;
-}
-
-type fake_session = parse::parse_sess;
-
-impl fake_ext_ctxt for fake_session {
-    fn cfg() -> ast::CrateConfig { Vec::new() }
-    fn parse_sess() -> parse::parse_sess { self }
-    fn call_site() -> span {
-        codemap::span {
-            lo: codemap::BytePos(0),
-            hi: codemap::BytePos(0),
-            expn_id: NO_EXPANSION
-        }
-    }
-    fn ident_of(st: &str) -> ast::ident {
-        self.interner.intern(st)
-    }
-}
-
-fn mk_ctxt() -> fake_ext_ctxt {
-    parse::new_parse_sess(None) as fake_ext_ctxt
-}
-
-
-
-fn main() {
-    let cx = mk_ctxt();
-
-    let abc = quote_expr!(cx, 23);
-    check_pp(abc,  pprust::print_expr, "23");
-
-    let expr3 = quote_expr!(cx, 2 - $abcd + 7); //~ ERROR unresolved name: abcd
-    check_pp(expr3,  pprust::print_expr, "2 - 23 + 7");
-}
-
-fn check_pp<T>(expr: T, f: |pprust::ps, T|, expect: str) {
-    panic!();
-}
diff --git a/src/test/compile-fail/qquote-2.rs b/src/test/compile-fail/qquote-2.rs
deleted file mode 100644 (file)
index 978287a..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-test Can't use syntax crate here
-
-#![feature(quote)]
-
-extern crate syntax;
-
-use syntax::diagnostic;
-use syntax::ast;
-use syntax::codemap;
-use syntax::parse::parser;
-use syntax::print::*;
-
-trait fake_ext_ctxt {
-    fn cfg() -> ast::CrateConfig;
-    fn parse_sess() -> parse::parse_sess;
-    fn call_site() -> span;
-    fn ident_of(st: &str) -> ast::ident;
-}
-
-type fake_session = parse::parse_sess;
-
-impl fake_ext_ctxt for fake_session {
-    fn cfg() -> ast::CrateConfig { Vec::new() }
-    fn parse_sess() -> parse::parse_sess { self }
-    fn call_site() -> span {
-        codemap::span {
-            lo: codemap::BytePos(0),
-            hi: codemap::BytePos(0),
-            expn_id: codemap::NO_EXPANSION
-        }
-    }
-    fn ident_of(st: &str) -> ast::ident {
-        self.interner.intern(st)
-    }
-}
-
-fn mk_ctxt() -> fake_ext_ctxt {
-    parse::new_parse_sess(None) as fake_ext_ctxt
-}
-
-
-fn main() {
-    let cx = mk_ctxt();
-
-    let stmt = quote_stmt!(cx, let x isize = 20;); //~ ERROR expected end-of-string
-    check_pp(*stmt,  pprust::print_stmt, "");
-}
-
-fn check_pp<T>(expr: T, f: |pprust::ps, T|, expect: str) {
-    panic!();
-}
index bb37d55fb08d067157623166d9ee1bce52b813a6..2095fb903b844d7526f33321cb171bac111e5a8f 100644 (file)
@@ -11,6 +11,7 @@
 // Various tests related to testing how region inference works
 // with respect to the object receivers.
 
+#![feature(rustc_attrs)]
 #![allow(warnings)]
 
 trait Foo {
index 7f00334f67e9f750c29fadda423b0b1fdf311d33..097053276c7fb99a52811aa893e2e2dcf12105c2 100644 (file)
@@ -11,6 +11,7 @@
 // Various tests related to testing how region inference works
 // with respect to the object receivers.
 
+#![feature(rustc_attrs)]
 #![allow(warnings)]
 
 trait Foo {
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
new file mode 100644 (file)
index 0000000..fa26c9c
--- /dev/null
@@ -0,0 +1,59 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we are imposing the requirement that every associated
+// type of a bound that appears in the where clause on a struct must
+// outlive the location in which the type appears, even when the
+// associted type is in a supertype. Issue #22246.
+
+#![allow(dead_code)]
+
+use std::mem::transmute;
+use std::ops::Deref;
+
+///////////////////////////////////////////////////////////////////////////
+
+pub trait TheTrait {
+    type TheAssocType;
+
+    fn dummy(&self) { }
+}
+
+pub trait TheSubTrait : TheTrait {
+}
+
+pub struct TheType<'b> {
+    m: [fn(&'b()); 0]
+}
+
+impl<'b> TheTrait for TheType<'b> {
+    type TheAssocType = &'b ();
+}
+
+impl<'b> TheSubTrait for TheType<'b> {
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+pub struct WithAssoc<T:TheSubTrait> {
+    m: [T; 0]
+}
+
+fn with_assoc<'a,'b>() {
+    // For this type to be valid, the rules require that all
+    // associated types of traits that appear in `WithAssoc` must
+    // outlive 'a. In this case, that means TheType<'b>::TheAssocType,
+    // which is &'b (), must outlive 'a.
+
+    let _: &'a WithAssoc<TheType<'b>> = loop { }; //~ ERROR cannot infer
+}
+
+fn main() {
+}
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
new file mode 100644 (file)
index 0000000..7d95506
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-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 structs with higher-ranked where clauses don't generate
+// "outlives" requirements. Issue #22246.
+
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+
+///////////////////////////////////////////////////////////////////////////
+
+pub trait TheTrait<'b> {
+    type TheAssocType;
+
+    fn dummy(&'b self) { }
+}
+
+pub struct TheType<'b> {
+    m: [fn(&'b()); 0]
+}
+
+impl<'a,'b> TheTrait<'a> for TheType<'b> {
+    type TheAssocType = &'b ();
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+pub struct WithHrAssoc<T>
+    where for<'a> T : TheTrait<'a>
+{
+    m: [T; 0]
+}
+
+fn with_assoc<'a,'b>() {
+    // We get no error here because the where clause has a higher-ranked assoc type,
+    // which could not be projected from.
+
+    let _: &'a WithHrAssoc<TheType<'b>> = loop { };
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+pub trait TheSubTrait : for<'a> TheTrait<'a> {
+}
+
+impl<'b> TheSubTrait for TheType<'b> { }
+
+pub struct WithHrAssocSub<T>
+    where T : TheSubTrait
+{
+    m: [T; 0]
+}
+
+fn with_assoc_sub<'a,'b>() {
+    // Same here, because although the where clause is not HR, it
+    // extends a trait in a HR way.
+
+    let _: &'a WithHrAssocSub<TheType<'b>> = loop { };
+}
+
+#[rustc_error]
+fn main() { //~ ERROR compilation successful
+}
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
new file mode 100644 (file)
index 0000000..6ee65fb
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we are imposing the requirement that every associated
+// type of a bound that appears in the where clause on a struct must
+// outlive the location in which the type appears, even when the
+// constraint is in a where clause not a bound. Issue #22246.
+
+#![allow(dead_code)]
+
+use std::mem::transmute;
+use std::ops::Deref;
+
+///////////////////////////////////////////////////////////////////////////
+
+pub trait TheTrait {
+    type TheAssocType;
+
+    fn dummy(&self) { }
+}
+
+pub struct TheType<'b> {
+    m: [fn(&'b()); 0]
+}
+
+impl<'b> TheTrait for TheType<'b> {
+    type TheAssocType = &'b ();
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+pub struct WithAssoc<T> where T : TheTrait {
+    m: [T; 0]
+}
+
+fn with_assoc<'a,'b>() {
+    // For this type to be valid, the rules require that all
+    // associated types of traits that appear in `WithAssoc` must
+    // outlive 'a. In this case, that means TheType<'b>::TheAssocType,
+    // which is &'b (), must outlive 'a.
+
+    let _: &'a WithAssoc<TheType<'b>> = loop { }; //~ ERROR cannot infer
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-outlives-container.rs
new file mode 100644 (file)
index 0000000..49a0726
--- /dev/null
@@ -0,0 +1,91 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we are imposing the requirement that every associated
+// type of a bound that appears in the where clause on a struct must
+// outlive the location in which the type appears. Issue #22246.
+
+#![allow(dead_code)]
+
+use std::mem::transmute;
+use std::ops::Deref;
+
+///////////////////////////////////////////////////////////////////////////
+
+pub trait TheTrait {
+    type TheAssocType;
+
+    fn dummy(&self) { }
+}
+
+pub struct TheType<'b> {
+    m: [fn(&'b()); 0]
+}
+
+impl<'b> TheTrait for TheType<'b> {
+    type TheAssocType = &'b ();
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+pub struct WithAssoc<T:TheTrait> {
+    m: [T; 0]
+}
+
+pub struct WithoutAssoc<T> {
+    m: [T; 0]
+}
+
+fn with_assoc<'a,'b>() {
+    // For this type to be valid, the rules require that all
+    // associated types of traits that appear in `WithAssoc` must
+    // outlive 'a. In this case, that means TheType<'b>::TheAssocType,
+    // which is &'b (), must outlive 'a.
+
+    let _: &'a WithAssoc<TheType<'b>> = loop { }; //~ ERROR cannot infer
+}
+
+fn with_assoc1<'a,'b>() where 'b : 'a {
+    // For this type to be valid, the rules require that all
+    // associated types of traits that appear in `WithAssoc` must
+    // outlive 'a. In this case, that means TheType<'b>::TheAssocType,
+    // which is &'b (), must outlive 'a, so 'b : 'a must hold, and
+    // that is in the where clauses, so we're fine.
+
+    let _: &'a WithAssoc<TheType<'b>> = loop { };
+}
+
+fn without_assoc<'a,'b>() {
+    // Here there are no associated types and the `'b` appearing in
+    // `TheType<'b>` is purely covariant, so there is no requirement
+    // that `'b:'a` holds.
+
+    let _: &'a WithoutAssoc<TheType<'b>> = loop { };
+}
+
+fn call_with_assoc<'a,'b>() {
+    // As `with_assoc`, but just checking that we impose the same rule
+    // on the value supplied for the type argument, even when there is
+    // no data.
+
+    call::<&'a WithAssoc<TheType<'b>>>();
+    //~^ ERROR cannot infer
+}
+
+fn call_without_assoc<'a,'b>() {
+    // As `without_assoc`, but in a distinct scenario.
+
+    call::<&'a WithoutAssoc<TheType<'b>>>();
+}
+
+fn call<T>() { }
+
+fn main() {
+}
diff --git a/src/test/compile-fail/regions-bounded-by-send.rs b/src/test/compile-fail/regions-bounded-by-send.rs
deleted file mode 100644 (file)
index 71254e1..0000000
+++ /dev/null
@@ -1,83 +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 which of the builtin types are considered sendable. The tests
-// in this file all test region bound and lifetime violations that are
-// detected during type check.
-
-extern crate core;
-use core::ptr::Unique;
-
-fn assert_send<T:Send>() { }
-trait Dummy:Send { }
-
-// lifetime pointers with 'static lifetime are ok
-
-fn static_lifime_ok<'a,T,U:Send>(_: &'a isize) {
-    assert_send::<&'static isize>();
-    assert_send::<&'static str>();
-    assert_send::<&'static [isize]>();
-
-    // whether or not they are mutable
-    assert_send::<&'static mut isize>();
-}
-
-// otherwise lifetime pointers are not ok
-
-fn param_not_ok<'a>(x: &'a isize) {
-    assert_send::<&'a isize>(); //~ ERROR does not fulfill the required lifetime
-}
-
-fn param_not_ok1<'a>(_: &'a isize) {
-    assert_send::<&'a str>(); //~ ERROR does not fulfill the required lifetime
-}
-
-fn param_not_ok2<'a>(_: &'a isize) {
-    assert_send::<&'a [isize]>(); //~ ERROR does not fulfill the required lifetime
-}
-
-// boxes are ok
-
-fn box_ok() {
-    assert_send::<Box<isize>>();
-    assert_send::<String>();
-    assert_send::<Vec<isize>>();
-}
-
-// but not if they own a bad thing
-
-fn box_with_region_not_ok<'a>() {
-    assert_send::<Box<&'a isize>>(); //~ ERROR does not fulfill the required lifetime
-}
-
-// objects with insufficient bounds no ok
-
-fn object_with_random_bound_not_ok<'a>() {
-    assert_send::<&'a (Dummy+'a)>();
-    //~^ ERROR reference has a longer lifetime
-}
-
-fn object_with_send_bound_not_ok<'a>() {
-    assert_send::<&'a (Dummy+Send)>();
-    //~^ ERROR does not fulfill the required lifetime
-}
-
-// unsafe pointers are ok unless they point at unsendable things
-
-struct UniqueUnsafePtr(Unique<*const isize>);
-
-unsafe impl Send for UniqueUnsafePtr {}
-
-fn unsafe_ok1<'a>(_: &'a isize) {
-    assert_send::<UniqueUnsafePtr>();
-}
-
-fn main() {
-}
diff --git a/src/test/compile-fail/regions-fn-bound.rs b/src/test/compile-fail/regions-fn-bound.rs
deleted file mode 100644 (file)
index c2b52b7..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-test
-// ignored because the first error does not show up.
-
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn of<T>() -> |T| { panic!(); }
-fn subtype<T>(x: |T|) { panic!(); }
-
-fn test_fn<'x, 'y, 'z, T>(_x: &'x T, _y: &'y T, _z: &'z T) {
-    // Here, x, y, and z are free.  Other letters
-    // are bound.  Note that the arrangement
-    // subtype::<T1>(of::<T2>()) will typecheck
-    // iff T1 <: T2.
-
-    // should be the default:
-    subtype::< ||:'static>(of::<||>());
-    subtype::<||>(of::< ||:'static>());
-
-    //
-    subtype::< <'x> ||>(of::<||>());    //~ ERROR mismatched types
-    subtype::< <'x> ||>(of::< <'y> ||>());  //~ ERROR mismatched types
-
-    subtype::< <'x> ||>(of::< ||:'static>()); //~ ERROR mismatched types
-    subtype::< ||:'static>(of::< <'x> ||>());
-
-}
-
-fn main() {}
index 57ea607cbf623f0cdd5c0bc9b4475a4ab8afb7eb..3401dd1becdd8b141dd5e8940e1af672ac7e68f2 100644 (file)
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn assert_send<T: Send>(_t: T) {}
+fn assert_static<T: 'static>(_t: T) {}
 
 fn main() {
     let line = String::new();
     match [&*line] { //~ ERROR `line` does not live long enough
-        [ word ] => { assert_send(word); }
+        [ word ] => { assert_static(word); }
     }
 }
diff --git a/src/test/compile-fail/require-parens-for-chained-comparison.rs b/src/test/compile-fail/require-parens-for-chained-comparison.rs
deleted file mode 100644 (file)
index f2705f5..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn f<T>() {}
-
-fn main() {
-    false == false == false;
-    //~^ ERROR: chained comparison operators require parentheses
-
-    false == 0 < 2;
-    //~^ ERROR: chained comparison operators require parentheses
-
-    f<X>();
-    //~^ ERROR: chained comparison operators require parentheses
-    //~^^ HELP: use `::<...>` instead of `<...>`
-}
index 6497439c3dc5756d07fa94b410f99d850d8886fb..82f32cbcd14e46028916269eaf210b822e7e54d8 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(rustc_attrs)]
+
 #[rustc_error]
 fn main() {
     //~^ ERROR compilation successful
diff --git a/src/test/compile-fail/send-is-not-static-ensures-scoping.rs b/src/test/compile-fail/send-is-not-static-ensures-scoping.rs
new file mode 100755 (executable)
index 0000000..abbcd7e
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::thread;
+
+fn main() {
+    let bad = {
+        let x = 1;
+        let y = &x;
+
+        thread::scoped(|| { //~ ERROR cannot infer an appropriate lifetime
+            let _z = y;
+        })
+    };
+
+    bad.join();
+}
diff --git a/src/test/compile-fail/struct-no-fields-2.rs b/src/test/compile-fail/struct-no-fields-2.rs
deleted file mode 100644 (file)
index 4f973f8..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-struct Foo;
-
-fn f2() {
-    let _end_stmt     = Foo { };
-    //~^ ERROR: structure literal must either have at least one field
-}
-
-fn main() {}
diff --git a/src/test/compile-fail/struct-no-fields-3.rs b/src/test/compile-fail/struct-no-fields-3.rs
deleted file mode 100644 (file)
index e594683..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-struct Foo;
-
-fn g3() {
-    let _mid_tuple    = (Foo { }, 2);
-    //~^ ERROR: structure literal must either have at least one field
-}
-
-fn main() {}
diff --git a/src/test/compile-fail/struct-no-fields-4.rs b/src/test/compile-fail/struct-no-fields-4.rs
deleted file mode 100644 (file)
index 60a0a85..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-struct Foo;
-
-fn h4() {
-    let _end_of_tuple = (3, Foo { });
-    //~^ ERROR: structure literal must either have at least one field
-}
-
-fn main() {}
diff --git a/src/test/compile-fail/struct-no-fields-5.rs b/src/test/compile-fail/struct-no-fields-5.rs
deleted file mode 100644 (file)
index 940fa9c..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-struct Foo;
-
-fn i5() {
-    let _end_of_block = { Foo { } };
-    //~^ ERROR: structure literal must either have at least one field
-}
-
-fn main() {}
diff --git a/src/test/compile-fail/struct-variant-no-fields.rs b/src/test/compile-fail/struct-variant-no-fields.rs
deleted file mode 100644 (file)
index 41dbbee..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-enum Foo {
-    Bar {} //~ ERROR unit-like struct variant should be written without braces, as `Bar,`
-}
diff --git a/src/test/compile-fail/struct-variant-no-pub.rs b/src/test/compile-fail/struct-variant-no-pub.rs
deleted file mode 100644 (file)
index e62b39a..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-enum Foo {
-    Bar {
-        pub a: isize //~ ERROR: `pub` is not allowed here
-    }
-}
-
-fn main() {}
diff --git a/src/test/compile-fail/syntax-trait-polarity.rs b/src/test/compile-fail/syntax-trait-polarity.rs
deleted file mode 100644 (file)
index 1ab79f5..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(optin_builtin_traits)]
-
-use std::marker::Send;
-
-struct TestType;
-
-impl !TestType {}
-//~^ ERROR inherent implementation can't be negated
-
-trait TestTrait {}
-
-unsafe impl !Send for TestType {}
-impl !TestTrait for TestType {}
-
-struct TestType2<T>;
-
-impl<T> !TestType2<T> {}
-//~^ ERROR inherent implementation can't be negated
-
-unsafe impl<T> !Send for TestType2<T> {}
-impl<T> !TestTrait for TestType2<T> {}
-
-fn main() {}
diff --git a/src/test/compile-fail/tag-variant-disr-non-nullary.rs b/src/test/compile-fail/tag-variant-disr-non-nullary.rs
deleted file mode 100644 (file)
index 207bbe9..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//error-pattern: discriminator values can only be used with a c-like enum
-
-enum color {
-    red = 0xff0000,
-    green = 0x00ff00,
-    blue = 0x0000ff,
-    black = 0x000000,
-    white = 0xffffff,
-    other (str),
-}
diff --git a/src/test/compile-fail/trace_macros-gate.rs b/src/test/compile-fail/trace_macros-gate.rs
new file mode 100644 (file)
index 0000000..6473bce
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that the trace_macros feature gate is on.
+
+fn main() {
+    trace_macros!(); //~ ERROR `trace_macros` is not stable
+    trace_macros!(1); //~ ERROR `trace_macros` is not stable
+    trace_macros!(ident); //~ ERROR `trace_macros` is not stable
+    trace_macros!(for); //~ ERROR `trace_macros` is not stable
+    trace_macros!(true,); //~ ERROR `trace_macros` is not stable
+    trace_macros!(false 1); //~ ERROR `trace_macros` is not stable
+
+    // Errors are signalled early for the above, before expansion.
+    // See trace_macros-gate2 and trace_macros-gate3. for examples
+    // of the below being caught.
+
+    macro_rules! expando {
+        ($x: ident) => { trace_macros!($x) }
+    }
+
+    expando!(true);
+}
diff --git a/src/test/compile-fail/trace_macros-gate2.rs b/src/test/compile-fail/trace_macros-gate2.rs
new file mode 100644 (file)
index 0000000..71cc45e
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that the trace_macros feature gate is on.
+
+fn main() {
+    // (Infrastructure does not attempt to detect uses in macro definitions.)
+    macro_rules! expando {
+        ($x: ident) => { trace_macros!($x) }
+    }
+
+    expando!(true); //~ ERROR `trace_macros` is not stable
+}
diff --git a/src/test/compile-fail/trace_macros-gate3.rs b/src/test/compile-fail/trace_macros-gate3.rs
new file mode 100644 (file)
index 0000000..66d03cf
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that the trace_macros feature gate is on.
+
+pub fn main() {
+    println!("arg: {}", trace_macros!()); //~ ERROR `trace_macros` is not stable
+    println!("arg: {}", trace_macros!(1)); //~ ERROR `trace_macros` is not stable
+    println!("arg: {}", trace_macros!(ident)); //~ ERROR `trace_macros` is not stable
+    println!("arg: {}", trace_macros!(for)); //~ ERROR `trace_macros` is not stable
+    println!("arg: {}", trace_macros!(true,)); //~ ERROR `trace_macros` is not stable
+    println!("arg: {}", trace_macros!(false 1)); //~ ERROR `trace_macros` is not stable
+}
diff --git a/src/test/compile-fail/trailing-carriage-return-in-string.rs b/src/test/compile-fail/trailing-carriage-return-in-string.rs
deleted file mode 100644 (file)
index 8109833..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-tidy-cr
-// Issue #11669
-
-fn main() {
-    // \r\n
-    let ok = "This is \
- a test";
-    // \r only
-    let bad = "This is \\r a test";
-    //~^ ERROR unknown character escape: \r
-    //~^^ HELP this is an isolated carriage return
-
-}
diff --git a/src/test/compile-fail/trailing-plus-in-bounds.rs b/src/test/compile-fail/trailing-plus-in-bounds.rs
deleted file mode 100644 (file)
index e8f9ed4..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::fmt::Show;
-
-fn main() {
-    let x: Box<Show+> = box 3 as Box<Show+>;
-    //~^ ERROR at least one type parameter bound must be specified
-    //~^^ ERROR at least one type parameter bound must be specified
-}
-
index 89e89cf82469391d4de8f1bd89799aea061385e0..79174552ae09c36f5ba136754f7a95cd7d6b6bc0 100644 (file)
@@ -22,7 +22,7 @@ fn c(x: Box<Foo+Sync+Send>) {
 fn d(x: Box<Foo>) {
     a(x); //~  ERROR mismatched types
           //~| expected `Box<Foo + Send>`
-          //~| found `Box<Foo + 'static>`
+          //~| found `Box<Foo>`
           //~| expected bounds `Send`
           //~| found no bounds
 }
diff --git a/src/test/compile-fail/trait-bounds-not-on-impl.rs b/src/test/compile-fail/trait-bounds-not-on-impl.rs
deleted file mode 100644 (file)
index a034352..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-trait Foo {
-}
-
-struct Bar;
-
-impl Foo + Owned for Bar { //~ ERROR not a trait
-}
-
-fn main() { }
diff --git a/src/test/compile-fail/type-parameters-in-field-exprs.rs b/src/test/compile-fail/type-parameters-in-field-exprs.rs
deleted file mode 100644 (file)
index 54ddb3e..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-struct Foo {
-    x: isize,
-    y: isize,
-}
-
-fn main() {
-    let f = Foo {
-        x: 1,
-        y: 2,
-    };
-    f.x::<isize>;
-    //~^ ERROR field expressions may not have type parameters
-}
-
diff --git a/src/test/compile-fail/unsized2.rs b/src/test/compile-fail/unsized2.rs
deleted file mode 100644 (file)
index b2eb206..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test syntax checks for `type` keyword.
-
-fn f<X>() {}
-
-pub fn main() {
-    f<type>();
-    //~^ ERROR expected identifier, found keyword `type`
-    //~^^ ERROR: chained comparison
-    //~^^^ HELP: use `::<
-}
index 50217ff9e5dc6c37826c05e35b4f11c58778a8bf..2d4bc0c857a9a7ad7f8c77f05e77300e3346b644 100644 (file)
@@ -7,9 +7,10 @@
 // <LICENSE-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(unused_attributes)]
 #![allow(dead_code, unused_imports)]
-#![feature(core)]
+#![feature(core, custom_attribute)]
 
 #![foo] //~ ERROR unused attribute
 
index ecb2287769bbd01c045c502512a9d7f72eb780c9..0ed0861d34af1fe7744a6db319611db233e7e1ca 100644 (file)
@@ -11,6 +11,8 @@
 // Test that the variance computation considers types/regions that
 // appear in projections to be invariant.
 
+#![feature(rustc_attrs)]
+
 trait Trait<'a> {
     type Type;
 
index 972ec96f5f27ba0dece011768f6358d95b8bb02a..2b7b05970d90f4c15f8830398eeaa50b76cc1e5d 100644 (file)
@@ -11,6 +11,8 @@
 // Test that Cell is considered invariant with respect to its
 // type.
 
+#![feature(rustc_attrs)]
+
 use std::cell::Cell;
 
 // For better or worse, associated types are invariant, and hence we
index 04389b67dba04c07715b401f5d2b619c041c7ec2..d70305d1106ecd64c8a1535fddea6449fad35320 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we correctly infer variance for region parameters in
 // various self-contained types.
 
+#![feature(rustc_attrs)]
+
 // Regions that just appear in normal spots are contravariant:
 
 #[rustc_variance]
index e2c7958b31decd16187c7061a96c279270bdfb59..4bb329d6304cf3ec1333f980bde394d063ff5f16 100644 (file)
@@ -12,6 +12,8 @@
 // case that involve multiple intricate types.
 // Try enums too.
 
+#![feature(rustc_attrs)]
+
 #[rustc_variance]
 enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[];[]]
     Test8A(extern "Rust" fn(&'a isize)),
index c61f2ff79c0192b5120796fd23e291c0acef6c92..965b9430a5e2d44095266a7b08abf700728e2147 100644 (file)
@@ -14,6 +14,8 @@
 //
 // Issue #18262.
 
+#![feature(rustc_attrs)]
+
 use std::mem;
 
 trait T { fn foo(); }
diff --git a/src/test/compile-fail/virtual-structs.rs b/src/test/compile-fail/virtual-structs.rs
deleted file mode 100644 (file)
index 3b3c7d5..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test diagnostics for the removed struct inheritance feature.
-#![feature(struct_inherit)]
-
-virtual struct SuperStruct { //~ ERROR `virtual` structs have been removed from the language
-    f1: isize,
-}
-
-struct Struct : SuperStruct; //~ ERROR `virtual` structs have been removed from the language
-
-pub fn main() {}
diff --git a/src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs b/src/test/compile-fail/where-clauses-no-bounds-or-predicates.rs
deleted file mode 100644 (file)
index b96c7c2..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn equal1<T>(_: &T, _: &T) -> bool where {
-//~^ ERROR a `where` clause must have at least one predicate in it
-    true
-}
-
-fn equal2<T>(_: &T, _: &T) -> bool where T: {
-//~^ ERROR each predicate in a `where` clause must have at least one bound
-    true
-}
-
-fn main() {
-}
-
index 0f6f0ac6ae7566b76fe5742209ae2876f5d95360..26117e7a13b6f2f1666499e755c988011375de16 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 91e78c820e6ff059b2a0b562f0dbb9de88ec00c8..30a70fe0b374703633a9a4bd9c2cd25701b27a92 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index d37b0f60d3da0e58bbfcec0e70ae8e3707462ac0..cb89879481bcdc4b5e844581d3aa15ce5148cce8 100644 (file)
@@ -14,7 +14,6 @@
 // about UTF-32 character encoding and will print a rust char as only
 // its numerical value.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 3b016f287fbcfa56ff4aeea051fdb6375beb1fcf..0134a058c992bd717f3cfe80db21801879559bf2 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index bc8cdaf8eacc9eb41e6a9c14e9aff8f426ab48c1..7f82878e080ce1c6fe4d0faff181596d4f2e0eab 100644 (file)
@@ -14,7 +14,6 @@
 // about UTF-32 character encoding and will print a rust char as only
 // its numerical value.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index f61f49228cdebf508223b82aaaba685f8dc6f9b2..95483c16783cc8a97679662d4d98c6ac8d7fd831 100644 (file)
@@ -14,7 +14,6 @@
 // about UTF-32 character encoding and will print a rust char as only
 // its numerical value.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index f4c31278cf63be5c83722eee42a9e8ecc004eeee..52e81b7e046a561723be6f5800eb29b9d2a2ee98 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 
 // Gdb doesn't know about UTF-32 character encoding and will print a rust char as only
 // its numerical value.
index c2da58f1583c0b38c239865ce51b30a43d9607f5..ecc70f4d77e2ff4afdd460869797a354af30dc93 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 
 // compile-flags:-g
 // min-lldb-version: 310
index d54869888f182d590c235949d73ac9b4a4ea3f6d..87e9e7fe2da6fc785834174f9b443de6ef986906 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 53d2befc49d063736d2d7699b271eab0ada9f632..2cfc6855e5bc6c9e4b4e08d8a38c4250ad261026 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // compile-flags:-g
 // min-lldb-version: 310
 
index c7e5987fbcfa2532c359b6a2bb6bc47b6d18a62a..768bcc9fc3f8011b497aa63d89057e3355f631cc 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index fc186a0b5b21f3a905117b3fa7574a24a880473d..14a3d008f420db9e090e8a1b5bd07c6d5d7a9139 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // Gdb doesn't know about UTF-32 character encoding and will print a rust char as only
index 6db3dce466880c965fde8be928583dfa3d1ab833..0689a6bc45b683cae489f536b21750db594d35f2 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 6397efa0a96a3a4f0b7765283d07fd8cdf2e2fef..972d6ab12e13fea6c3049e0041a2eaf66f39e9b3 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 8ac8d5970f31857d5d1da5e2405f21a657c7de77..3efda1e2f6aa84f0deb2862595b8074132dfc16d 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 6907313370e1a5edf57f26e6ec3bc158dc9bea1d..2b2a9bf83f1428854a775a0e1178913890393a89 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index f2dfc63d52253edfe7f0211741c0927e4807765c..c7a4daa42fa8094b96d7a067d8b2910c8e40b8d7 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index ad7c860c8b9beacc3290ad3d6682e327c6aba581..2305d7bc5c245039cc603c631ca2ddf6107d1807 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index ea684b1d69c523b97f48d68a6c57c10d620d5e83..b92f5de21b5753d0b815d0db6022ae61c04a0f7d 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 5a56722f0cc5a7f8ff3cade0fad619963a6dffd6..47365b2b9a0f3eea65898b3829604a682c5b997b 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // aux-build:cross_crate_debuginfo_type_uniquing.rs
index 77b29389338bbd35db66f9d687ce1499fa1b5956..51cced204398f45ef99d996e31dd94cb55ffe014 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 37e465e43c3bd2ee83e71b2e0dbc9f4be93bb42d..9f0492f35a344bb4788693d68aceb14d62bc3384 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index eaa2382501b7bd0320d13cd3eb024662f477d46d..cf0ca0b67a7b4db57364314f531531bb268a087e 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index f623a321922b8d7695cd4f7665cab48414a17059..1a9b9f73cba999964d61e3cec3b998a57047219c 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index f9a2b2fef343a282a237aa4f3d8a7d3a1f9770a6..9eadf3cc19b928175253d196ccd6bd57a8fb77f7 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // This test case checks if function arguments already have the correct value when breaking at the
index 01136c11014a343f8764c5ae340f10bcd7f0d1d1..2ab3668abb9dd5ec256024fd1350ac368fdc8cad 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index b9a09867a0048ebd377b27445ef5dbd3fee00c7e..76b7a3e729d2e0035932e11f17e677e57d081818 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 9f6d8a45a995642d88bf2a14c7e16b4138db242e..5f9236038b22eb16aec03d49c10aefdebfa2bceb 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index d94baa637c2d0fd2739f2829d718189238a8150e..8c4eeb27c0f6d5b69c2aefd6e1b10d54233168ed 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 
 // compile-flags:-g
 // min-lldb-version: 310
index 61843a20d055f384aa0d93e340204a6471ff03f4..eb1083f624faaca834221eb4fbf7b76f8cb1b171 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 2faafbd76340c4d88db70423dab0206ad765b28c..455861b1ea1eba65626afb29cd4449506677aaea 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 696d2703bdef4ee04658a4f6aa9d59d0c40bbad4..15982f309c6bbf9c96e93f93edeac81e4516ad6a 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index f9dc9d1f055c82c205a3ae57ab29d2fdde507601..da62e335557a20093d0f50ecc4514da6f84916ff 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 25719a802863d78898283b61a2e2dfa3a0fde9dc..1dead6c2734f886e82c502029aa7b8d6a44e2760 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 5166400029980499da01cafa8a6940c4e2eef8e7..e93704cac34c2ef842ef86987653fa61aa566f2e 100644 (file)
@@ -17,7 +17,6 @@ fn main() {
     ::std::io::println(args[0]);
 }
 
-// ignore-android: FIXME(#10381)
 // ignore-lldb
 
 // This test case checks whether compile unit names are set correctly, so that the correct default
index c6acc9a31fe3c68a0c70d13ac41f48144241b818..424ba50e3c97836da80f1dbaae9e0a2386de9bdc 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // ignore-windows failing on 64-bit bots FIXME #17638
 // ignore-lldb
 
@@ -16,7 +15,7 @@
 
 // gdb-command:run
 // gdb-command:next
-// gdb-check:[...]34[...]s
+// gdb-check:[...]33[...]s
 // gdb-command:continue
 
 #![omit_gdb_pretty_printer_section]
index dd61542b80050508feab5b53bb0ba9dd852f334f..a079ddbd0f507e7c1ab1d09340c8644c7a0239e8 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // aux-build:issue13213aux.rs
index 0fc567f421f34a67b955c692be53582b88a72ff4..3b2d372117d006b11ad6d87327e0aad6231f2386 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index fe5983cbb6a3fc4c26eb98a9982a1ea6c43eeda6..dceb436310fa3a3d0aded48d7f3ac49e1b2494bf 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index c885bfce216d477e91879e1edf698d1d5b93ec8b..08a762fc4e5d8bd4af196ee2557affc0dbfad190 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index c596253560ef4745113103d0f147c37b9d51ee53..c2cddd25768598f67910ee7883feba7a70c6b1f3 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index fb4378d5e8beca68a11c3a6ec569ccb2c7dec547..374df2f094ab6fefeb0af2f22a659613783b17a1 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-C debuginfo=1
index 6cb1218c1233a718f372ddcce6a4d93b7c7f111d..6a909ced818ef53cb4be353c8d827eb11782d126 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 6826bca695b91d080b2f57ad9ac9dca8ab94f5f2..868cea29a7bc3d4ebb7ca3b6f7d41dc36d97db61 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index ba660deeca01a25738224e848a5c2a05bd74d2e8..c0a5a31c9ce38e1237ff0b57c3e1bc329ae6d466 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 40280b469f70799bab4e2f72adaeb41258b52f55..b5f43e7d21f1a1f6b928ac75ba9523c95ec2f730 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index da941979fb661d41ca052d8d8e1f075ab6c3af7b..1dd738c6d512e8b410738c4c69f04b5c74d9f2d0 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 118d096d31b05d377a6ad4c2fe2a100f10f24d16..c1ec837a4b8188383ee8d17189fcb77750abbbc8 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index c8fe76fdbe56a1d2ae1ddb0472f51c0e75c247fd..e51842992ccd36cd3fc15268709a9426586c2956 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 
 // ignore-lldb
 
index f891263697170be6f796fea96234c83979c6db3e..7ad668791d3b899b1ff6f4756c7f2c5fdfdbb5f4 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index fa93eaba2793eea419688f33c1048de9ece70064..6b56a7998c919880a2ba618b9bcd9859a735c361 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 56f79da709efd92c061afba2105cf0a2faa26dd8..e32288a8e7d0362df7765afe467ea62dd3370bd1 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 4fff301eb5f548a60315a55ed5832b1937c3892d..6e9a695720a141b68d0288b26c8c9d4074cfc96b 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 7c4ce211f2fe5edc676f2642ef689259761b4021..cee04e92c2d24e4de671dbb7a5225a1b17a491c2 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index dd0d86bf742e6415adadd180bc6e836bfee08d05..f02e3f2a22bed86f97be0524a58b296114d3c2dc 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 0b2f8ef8181e109a2c9616ee4f4ed5f3dafe0823..5fe0c13e5e4a5a198c35394e2ba9d9967ba16cc5 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 00698ae1dfb433ed361d923c12d3fd6aabfd8b5b..3179a8050d35d1cee49c129eaa775c1fadb2511e 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 8c1a5376dba72af383d8f70628836ba5362356c8..5553d7e496b57eefa705f23c3519dd8905b53bf0 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index f0eaf6acb6138f86ea4f7fec1fb906a0fba6bc9d..44d7c2b1ad23e00076b5c958980b22af681676b4 100644 (file)
@@ -11,7 +11,6 @@
 // LLDB can't handle zero-sized values
 // ignore-lldb
 
-// ignore-android: FIXME(#10381)
 
 // compile-flags:-g
 // gdb-command:run
index dcc1928ae50c91e7ddcf86d312be5c26e816da55..d2b21a648a0b8a95df4d98d49496b3ad87bff178 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // ignore-lldb
 
 // compile-flags:-g
index fdfbcda7421cd91cf245f685b06054934beb60f4..0aef13746593320d0f2fc84fcadc7f352212c5bc 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 84c0b8da02c0610bdfc7d008c48399d48ce87237..8b2f34a99099c5d088b321125858ff4c5a96785e 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 97e6ee79952e8078c0480e6673833f3f3762c594..9f3b7baf83db2c7c37c5b3e86d42cfa019b2dd5c 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 73a68893e933cac81089fa72a0b11d63a88cd2bd..ef1092efa11455a565c4c3a0f93e4c86daf4d3a7 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // ignore-lldb
 
 // compile-flags:-g
index 2cbe9f43789d92a2f9627d83eb8b3031e024cfe2..3b1979337d525fa5d9e1bba910b3fa7a621c19ff 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // ignore-lldb
 
 // compile-flags:-g
index e494973b975bca54dd95fa0a1f94facbad2eea88..cb2b04f4d8695df3f9a116ab144278d3646c8b3c 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 0fe74015611f5914ec5a619307d4b0c41555611f..b96ec3b7b889cc18f815403a47798b3d6fd3b092 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 5b36d32e49fcf440b6cc2b6b8f0ce86f3ceeb228..4d74e6f1084e5a7a012e79c09f387d45a9f2adeb 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 66fd656eaacaff40d031cfe1f95b14222d31f14b..630999677ab1b3a3c1f628a5febbdfdb07b82beb 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 578ea4479ecab5b3fb3e6751b46e6a707a3bf07d..161392c94c8f01e61435478bc307a83c399a6eea 100644 (file)
@@ -11,7 +11,6 @@
 // Need a fix for LLDB first...
 // ignore-lldb
 
-// ignore-android: FIXME(#10381)
 
 // compile-flags:-g
 // gdb-command:run
index 31441db20f10028887140b600a1137fa14ef531c..c1dae7a6d677c3f89b5fa794af1caefa2ec2ae7d 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 3015b16a0aa99ea4ccdda9103f64f83c5aafc3b7..eee3cf55052a346a7e8b455bb21447e6503954e8 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 78184fab7d3904971a6c4e620f75f2e81885b03a..75db47af2463fefca9a652929ab33f0fe61f06be 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 59ee300b3e3b52644a2fa1dc36ebf0c796ba6d84..48db69289c073678a438bf6f6b8be4f69fe85397 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 6f801a7d587d378a9b4b2b5c11d121217c34cbfa..b2971329cc8fb50bfbbb45e2ad661446d89c9b3f 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 3f819c92e1017de50d762f9295522dec5e654e72..8bccb041c9a90d2b9648e6d14eb4195b76e4c761 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index f6d4627082f0e2d37b8b6b009d19be2e936e2e12..d522e9f89105689892a21ddd2f1f0b2e2d2da951 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 743f5ac5ff452c82023504d02ec1e7114ffd0ac3..4c2c9d06ae91caac150ba37849aa7687e5a33340 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index b95190f875a605cd477f589f21c166c530522f3a..f74c9953f7d6cfc83c98908833d9c49f7d7396e6 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 3d28490c0cfd76f3f38eb38b0148d11ff44de2a7..7da1ef2e1189be840e1a62573725fb7c78926a15 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index b1228f7a8846ada1726d3a1b6156e2e3e9c10334..9b4c759ab025f36fd39442be29f04d9ba200b253 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 0960ab5834dd6693b08d8aeec56e3f202c9723e0..e679dac9546606f1cc5318042ac140a8720dd945 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index f205f484f25fb5ba1cd617560af0f293bc702799..7c9760c3a5353c1205aa32ac5bc2b19e36c62886 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 08622b2dca8fbe6fc43fe15d3732cece79934f6a..69b5797007bdb8b689708aa6315a5d9a536fc8be 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 8bcb54af8ba8487e8b625175ae85eb483c23ca62..309848d6cedc9b400e00b9ba55b43cfc543a27c8 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 512df3605bfcdf2ef353c49a839d5555606a6d41..9c9d82249ee317d70764a9f17fdd8067f6a9806e 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index b07c8ffde7f8ff1310340b9ed97459c6da046dd5..6b96556dc2ffff0d4377a44d05e2740ab478a28d 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index ee706c13634f0113aec3ea6ba1fa10d208807459..e3bd1eade7538d9d3c08b429c1962e2e3e90ac99 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
index 9ee18c0d77b7f6df6f0aa1e81b2dc69e79843c6f..f7bdf1bd3faafa33ec6c03923ce7e71183b987f1 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android: FIXME(#10381)
 // min-lldb-version: 310
 
 // compile-flags:-g
diff --git a/src/test/parse-fail/ascii-only-character-escape.rs b/src/test/parse-fail/ascii-only-character-escape.rs
new file mode 100644 (file)
index 0000000..1ba25a8
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let x = "\x80"; //~ ERROR may only be used
+    let y = "\xff"; //~ ERROR may only be used
+    let z = "\xe2"; //~ ERROR may only be used
+    let a = b"\x00e2";  // ok because byte literal
+}
+
diff --git a/src/test/parse-fail/attr-before-eof.rs b/src/test/parse-fail/attr-before-eof.rs
new file mode 100644 (file)
index 0000000..e347562
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[derive(Debug)] //~ERROR expected item after attributes
diff --git a/src/test/parse-fail/attr-before-ext.rs b/src/test/parse-fail/attr-before-ext.rs
new file mode 100644 (file)
index 0000000..098c5aa
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    #[attr] //~ ERROR expected item after attributes
+    println!("hi");
+}
diff --git a/src/test/parse-fail/attr-before-let.rs b/src/test/parse-fail/attr-before-let.rs
new file mode 100644 (file)
index 0000000..acc9aa8
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    #[attr] //~ ERROR expected item
+    let _i = 0;
+}
diff --git a/src/test/parse-fail/attr-before-stmt.rs b/src/test/parse-fail/attr-before-stmt.rs
new file mode 100644 (file)
index 0000000..ec837cd
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern:expected item
+
+fn f() {
+  #[foo = "bar"]
+  let x = 10;
+}
+
+fn main() {
+}
diff --git a/src/test/parse-fail/attr-dangling-in-fn.rs b/src/test/parse-fail/attr-dangling-in-fn.rs
new file mode 100644 (file)
index 0000000..384622f
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern:expected item
+
+fn f() {
+  #[foo = "bar"]
+}
+
+fn main() {
+}
diff --git a/src/test/parse-fail/attr-dangling-in-mod.rs b/src/test/parse-fail/attr-dangling-in-mod.rs
new file mode 100644 (file)
index 0000000..59a922e
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern:expected item
+
+fn main() {
+}
+
+#[foo = "bar"]
diff --git a/src/test/parse-fail/attr.rs b/src/test/parse-fail/attr.rs
new file mode 100644 (file)
index 0000000..4bd6141
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(lang_items)]
+
+fn main() {}
+
+#![lang(foo)] //~ ERROR an inner attribute is not permitted in this context
+fn foo() {}
diff --git a/src/test/parse-fail/attrs-after-extern-mod.rs b/src/test/parse-fail/attrs-after-extern-mod.rs
new file mode 100644 (file)
index 0000000..df74761
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Constants (static variables) can be used to match in patterns, but mutable
+// statics cannot. This ensures that there's some form of error if this is
+// attempted.
+
+extern crate libc;
+
+extern {
+    static mut rust_dbg_static_mut: libc::c_int;
+    pub fn rust_dbg_static_mut_check_four();
+    #[cfg(stage37)] //~ ERROR expected item after attributes
+}
+
+pub fn main() {}
diff --git a/src/test/parse-fail/bad-char-literals.rs b/src/test/parse-fail/bad-char-literals.rs
new file mode 100644 (file)
index 0000000..2a358ae
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-cr
+// ignore-tidy-tab
+fn main() {
+    // these literals are just silly.
+    ''';
+    //~^ ERROR: character constant must be escaped: \'
+
+    // note that this is a literal "\n" byte
+    '
+';
+    //~^^ ERROR: character constant must be escaped: \n
+
+    // note that this is a literal "\r" byte
+    '\r'; //~ ERROR: character constant must be escaped: \r
+
+    // note that this is a literal tab character here
+    '  ';
+    //~^ ERROR: character constant must be escaped: \t
+}
diff --git a/src/test/parse-fail/bad-lit-suffixes.rs b/src/test/parse-fail/bad-lit-suffixes.rs
new file mode 100644 (file)
index 0000000..d10337e
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+extern crate
+    "foo"suffix //~ ERROR extern crate name with a suffix is illegal
+     as foo;
+
+extern
+    "C"suffix //~ ERROR ABI spec with a suffix is illegal
+    fn foo() {}
+
+extern
+    "C"suffix //~ ERROR ABI spec with a suffix is illegal
+{}
+
+fn main() {
+    ""suffix; //~ ERROR str literal with a suffix is illegal
+    b""suffix; //~ ERROR binary str literal with a suffix is illegal
+    r#""#suffix; //~ ERROR str literal with a suffix is illegal
+    br#""#suffix; //~ ERROR binary str literal with a suffix is illegal
+    'a'suffix; //~ ERROR char literal with a suffix is illegal
+    b'a'suffix; //~ ERROR byte literal with a suffix is illegal
+
+    1234u1024; //~ ERROR illegal width `1024` for integer literal
+    1234i1024; //~ ERROR illegal width `1024` for integer literal
+    1234f1024; //~ ERROR illegal width `1024` for float literal
+    1234.5f1024; //~ ERROR illegal width `1024` for float literal
+
+    1234suffix; //~ ERROR illegal suffix `suffix` for numeric literal
+    0b101suffix; //~ ERROR illegal suffix `suffix` for numeric literal
+    1.0suffix; //~ ERROR illegal suffix `suffix` for float literal
+    1.0e10suffix; //~ ERROR illegal suffix `suffix` for float literal
+}
diff --git a/src/test/parse-fail/bad-value-ident-false.rs b/src/test/parse-fail/bad-value-ident-false.rs
new file mode 100644 (file)
index 0000000..ca10bdd
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn false() { } //~ ERROR expected identifier, found keyword `false`
+fn main() { }
diff --git a/src/test/parse-fail/bad-value-ident-true.rs b/src/test/parse-fail/bad-value-ident-true.rs
new file mode 100644 (file)
index 0000000..4508d52
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn true() { } //~ ERROR expected identifier, found keyword `true`
+fn main() { }
diff --git a/src/test/parse-fail/doc-before-attr.rs b/src/test/parse-fail/doc-before-attr.rs
new file mode 100644 (file)
index 0000000..bb44a6a
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/// hi
+#[derive(Debug)] //~ERROR expected item after attributes
diff --git a/src/test/parse-fail/doc-before-eof.rs b/src/test/parse-fail/doc-before-eof.rs
new file mode 100644 (file)
index 0000000..e6dd410
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/// hi //~ERROR expected item after doc comment
diff --git a/src/test/parse-fail/doc-before-extern-rbrace.rs b/src/test/parse-fail/doc-before-extern-rbrace.rs
new file mode 100644 (file)
index 0000000..5afd1b2
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern {
+    /// hi
+}
+//~^^ ERROR expected item after doc comment
diff --git a/src/test/parse-fail/doc-before-macro.rs b/src/test/parse-fail/doc-before-macro.rs
new file mode 100644 (file)
index 0000000..8dc6c54
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    /// hi
+    println!("hi");
+    //~^^ ERROR expected item after doc comment
+}
diff --git a/src/test/parse-fail/doc-before-rbrace.rs b/src/test/parse-fail/doc-before-rbrace.rs
new file mode 100644 (file)
index 0000000..6d05064
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    println!("Hi"); /// hi
+    //~^ ERROR expected item after doc comment
+}
diff --git a/src/test/parse-fail/doc-before-semi.rs b/src/test/parse-fail/doc-before-semi.rs
new file mode 100644 (file)
index 0000000..8b0300e
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    /// hi
+    ;
+    //~^^ ERROR expected item after doc comment
+}
diff --git a/src/test/parse-fail/extern-crate-as-no-string-help.rs b/src/test/parse-fail/extern-crate-as-no-string-help.rs
new file mode 100644 (file)
index 0000000..5cc52f6
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tests that the proper help is displayed in the error message
+
+extern crate foo as bar;
+//~^ ERROR expected `;`, found `as`
+//~^^ HELP perhaps you meant to enclose the crate name `foo` in a string?
diff --git a/src/test/parse-fail/generic-non-trailing-defaults.rs b/src/test/parse-fail/generic-non-trailing-defaults.rs
new file mode 100644 (file)
index 0000000..0cfb05b
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Heap;
+
+struct Vec<A = Heap, T>; //~ ERROR type parameters with a default must be trailing
+
+struct Foo<A, B = Vec<C>, C>; //~ ERROR type parameters with a default must be trailing
+
+fn main() {}
diff --git a/src/test/parse-fail/int-literal-too-large-span.rs b/src/test/parse-fail/int-literal-too-large-span.rs
new file mode 100644 (file)
index 0000000..8a496c9
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// issue #17123
+
+fn main() {
+    100000000000000000000000000000000 //~ ERROR int literal is too large
+
+        ; // the span shouldn't point to this.
+}
diff --git a/src/test/parse-fail/issue-10412.rs b/src/test/parse-fail/issue-10412.rs
new file mode 100644 (file)
index 0000000..8a99633
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+trait Serializable<'self, T> { //~ ERROR no longer a special lifetime
+    fn serialize(val : &'self T) -> Vec<u8> ; //~ ERROR no longer a special lifetime
+    fn deserialize(repr : &[u8]) -> &'self T; //~ ERROR no longer a special lifetime
+}
+
+impl<'self> Serializable<str> for &'self str { //~ ERROR no longer a special lifetime
+    //~^ ERROR no longer a special lifetime
+    fn serialize(val : &'self str) -> Vec<u8> { //~ ERROR no longer a special lifetime
+        vec!(1)
+    }
+    fn deserialize(repr: &[u8]) -> &'self str { //~ ERROR no longer a special lifetime
+        "hi"
+    }
+}
+
+fn main() {
+    println!("hello");
+    let x = "foo".to_string();
+    let y = x;
+    println!("{}", y);
+}
diff --git a/src/test/parse-fail/issue-12560-1.rs b/src/test/parse-fail/issue-12560-1.rs
new file mode 100644 (file)
index 0000000..ea2043e
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// For style and consistency reasons, non-parametrized enum variants must
+// be used simply as `ident` instead of `ident ()`.
+// This test-case covers enum declaration.
+
+enum Foo {
+    Bar(), //~ ERROR nullary enum variants are written with no trailing `( )`
+    Baz(), //~ ERROR nullary enum variants are written with no trailing `( )`
+    Bazar
+}
+
+fn main() {
+    println!("{}", match Bar { Bar => 1, Baz => 2, Bazar => 3 })
+}
diff --git a/src/test/parse-fail/issue-14182.rs b/src/test/parse-fail/issue-14182.rs
new file mode 100644 (file)
index 0000000..364951a
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-test FIXME(japari) remove test
+
+struct Foo {
+    f: for <'b> |&'b isize|:
+      'b -> &'b isize //~ ERROR use of undeclared lifetime name `'b`
+}
+
+fn main() {
+    let mut x: Vec< for <'a> ||
+       :'a //~ ERROR use of undeclared lifetime name `'a`
+    > = Vec::new();
+    x.push(|| {});
+
+    let foo = Foo {
+        f: |x| x
+    };
+}
diff --git a/src/test/parse-fail/issue-17383.rs b/src/test/parse-fail/issue-17383.rs
new file mode 100644 (file)
index 0000000..c71e0ec
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+enum X {
+    A =
+        b'a' //~ ERROR discriminator values can only be used with a c-like enum
+    ,
+    B(isize)
+}
+
+fn main() {}
diff --git a/src/test/parse-fail/issue-17718-const-mut.rs b/src/test/parse-fail/issue-17718-const-mut.rs
new file mode 100644 (file)
index 0000000..5177ebb
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const
+mut //~ ERROR: const globals cannot be mutable
+//~^ HELP did you mean to declare a static?
+FOO: usize = 3;
+
+fn main() {
+}
+
diff --git a/src/test/parse-fail/issue-1802-2.rs b/src/test/parse-fail/issue-1802-2.rs
new file mode 100644 (file)
index 0000000..c7aacdf
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern:no valid digits found for number
+fn main() {
+    log(error, 0bu);
+}
diff --git a/src/test/parse-fail/issue-5544-a.rs b/src/test/parse-fail/issue-5544-a.rs
new file mode 100644 (file)
index 0000000..42a18ba
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let _i = 18446744073709551616; // 2^64
+    //~^ ERROR int literal is too large
+}
diff --git a/src/test/parse-fail/issue-5544-b.rs b/src/test/parse-fail/issue-5544-b.rs
new file mode 100644 (file)
index 0000000..1f166ec
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let _i = 0xff_ffff_ffff_ffff_ffff_is;
+    //~^ ERROR int literal is too large
+}
diff --git a/src/test/parse-fail/issue-8537.rs b/src/test/parse-fail/issue-8537.rs
new file mode 100644 (file)
index 0000000..dba9e75
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub extern
+  "invalid-abi" //~ ERROR illegal ABI
+fn foo() {}
+
+fn main() {}
diff --git a/src/test/parse-fail/keyword-as-as-identifier.rs b/src/test/parse-fail/keyword-as-as-identifier.rs
new file mode 100644 (file)
index 0000000..f307b12
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py as'
+
+fn main() {
+    let as = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-break-as-identifier.rs b/src/test/parse-fail/keyword-break-as-identifier.rs
new file mode 100644 (file)
index 0000000..1e2725e
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py break'
+
+fn main() {
+    let break = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-else-as-identifier.rs b/src/test/parse-fail/keyword-else-as-identifier.rs
new file mode 100644 (file)
index 0000000..101fd93
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py else'
+
+fn main() {
+    let else = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-enum-as-identifier.rs b/src/test/parse-fail/keyword-enum-as-identifier.rs
new file mode 100644 (file)
index 0000000..ed504cc
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py enum'
+
+fn main() {
+    let enum = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-extern-as-identifier.rs b/src/test/parse-fail/keyword-extern-as-identifier.rs
new file mode 100644 (file)
index 0000000..3260506
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py extern'
+
+fn main() {
+    let extern = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-fn-as-identifier.rs b/src/test/parse-fail/keyword-fn-as-identifier.rs
new file mode 100644 (file)
index 0000000..8c98da2
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py fn'
+
+fn main() {
+    let fn = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-for-as-identifier.rs b/src/test/parse-fail/keyword-for-as-identifier.rs
new file mode 100644 (file)
index 0000000..196a339
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py for'
+
+fn main() {
+    let for = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-if-as-identifier.rs b/src/test/parse-fail/keyword-if-as-identifier.rs
new file mode 100644 (file)
index 0000000..05f82ec
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py if'
+
+fn main() {
+    let if = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-impl-as-identifier.rs b/src/test/parse-fail/keyword-impl-as-identifier.rs
new file mode 100644 (file)
index 0000000..1dd2180
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py impl'
+
+fn main() {
+    let impl = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-let-as-identifier.rs b/src/test/parse-fail/keyword-let-as-identifier.rs
new file mode 100644 (file)
index 0000000..0069a26
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py let'
+
+fn main() {
+    let let = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-loop-as-identifier.rs b/src/test/parse-fail/keyword-loop-as-identifier.rs
new file mode 100644 (file)
index 0000000..6e469e8
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py loop'
+
+fn main() {
+    let loop = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-match-as-identifier.rs b/src/test/parse-fail/keyword-match-as-identifier.rs
new file mode 100644 (file)
index 0000000..9155ebc
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py match'
+
+fn main() {
+    let match = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-mod-as-identifier.rs b/src/test/parse-fail/keyword-mod-as-identifier.rs
new file mode 100644 (file)
index 0000000..02f57e9
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py mod'
+
+fn main() {
+    let mod = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-pub-as-identifier.rs b/src/test/parse-fail/keyword-pub-as-identifier.rs
new file mode 100644 (file)
index 0000000..aa67974
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py pub'
+
+fn main() {
+    let pub = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-return-as-identifier.rs b/src/test/parse-fail/keyword-return-as-identifier.rs
new file mode 100644 (file)
index 0000000..c567644
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py return'
+
+fn main() {
+    let return = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-self-as-identifier.rs b/src/test/parse-fail/keyword-self-as-identifier.rs
new file mode 100644 (file)
index 0000000..8bb5214
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py self'
+
+fn main() {
+    let self = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-static-as-identifier.rs b/src/test/parse-fail/keyword-static-as-identifier.rs
new file mode 100644 (file)
index 0000000..7268c4f
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py static'
+
+fn main() {
+    let static = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-struct-as-identifier.rs b/src/test/parse-fail/keyword-struct-as-identifier.rs
new file mode 100644 (file)
index 0000000..bd42eac
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py struct'
+
+fn main() {
+    let struct = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-super-as-identifier.rs b/src/test/parse-fail/keyword-super-as-identifier.rs
new file mode 100644 (file)
index 0000000..0378c32
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py super'
+
+fn main() {
+    let super = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-super.rs b/src/test/parse-fail/keyword-super.rs
new file mode 100644 (file)
index 0000000..0c94f76
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let super: isize; //~ ERROR expected identifier, found keyword `super`
+}
diff --git a/src/test/parse-fail/keyword-trait-as-identifier.rs b/src/test/parse-fail/keyword-trait-as-identifier.rs
new file mode 100644 (file)
index 0000000..95c0d17
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py trait'
+
+fn main() {
+    let trait = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-type-as-identifier.rs b/src/test/parse-fail/keyword-type-as-identifier.rs
new file mode 100644 (file)
index 0000000..0aaa2a6
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py type'
+
+fn main() {
+    let type = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-unsafe-as-identifier.rs b/src/test/parse-fail/keyword-unsafe-as-identifier.rs
new file mode 100644 (file)
index 0000000..1b631eb
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py unsafe'
+
+fn main() {
+    let unsafe = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-use-as-identifier.rs b/src/test/parse-fail/keyword-use-as-identifier.rs
new file mode 100644 (file)
index 0000000..e82afd5
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py use'
+
+fn main() {
+    let use = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword-while-as-identifier.rs b/src/test/parse-fail/keyword-while-as-identifier.rs
new file mode 100644 (file)
index 0000000..95cea65
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This file was auto-generated using 'src/etc/generate-keyword-tests.py while'
+
+fn main() {
+    let while = "foo"; //~ error: ident
+}
diff --git a/src/test/parse-fail/keyword.rs b/src/test/parse-fail/keyword.rs
new file mode 100644 (file)
index 0000000..64eac47
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub mod break {
+    //~^ ERROR expected identifier, found keyword `break`
+}
diff --git a/src/test/parse-fail/keywords-followed-by-double-colon.rs b/src/test/parse-fail/keywords-followed-by-double-colon.rs
new file mode 100644 (file)
index 0000000..f69b041
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    struct::foo();  //~ ERROR expected identifier
+    mut::baz(); //~ ERROR expected identifier
+}
+
diff --git a/src/test/parse-fail/lex-bad-numeric-literals.rs b/src/test/parse-fail/lex-bad-numeric-literals.rs
new file mode 100644 (file)
index 0000000..9a490be
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    0o1.0; //~ ERROR: octal float literal is not supported
+    0o2f32; //~ ERROR: octal float literal is not supported
+    0o3.0f32; //~ ERROR: octal float literal is not supported
+    0o4e4; //~ ERROR: octal float literal is not supported
+    0o5.0e5; //~ ERROR: octal float literal is not supported
+    0o6e6f32; //~ ERROR: octal float literal is not supported
+    0o7.0e7f64; //~ ERROR: octal float literal is not supported
+    0x8.0e+9; //~ ERROR: hexadecimal float literal is not supported
+    0x9.0e-9; //~ ERROR: hexadecimal float literal is not supported
+    0o; //~ ERROR: no valid digits
+    1e+; //~ ERROR: expected at least one digit in exponent
+    0x539.0; //~ ERROR: hexadecimal float literal is not supported
+    99999999999999999999999999999999; //~ ERROR: int literal is too large
+    99999999999999999999999999999999u32; //~ ERROR: int literal is too large
+    0x; //~ ERROR: no valid digits
+    0xu32; //~ ERROR: no valid digits
+    0ou32; //~ ERROR: no valid digits
+    0bu32; //~ ERROR: no valid digits
+    0b; //~ ERROR: no valid digits
+    0o123f64; //~ ERROR: octal float literal is not supported
+    0o123.456; //~ ERROR: octal float literal is not supported
+    0b101f64; //~ ERROR: binary float literal is not supported
+    0b111.101; //~ ERROR: binary float literal is not supported
+}
diff --git a/src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs b/src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs
new file mode 100644 (file)
index 0000000..c1e5121
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-cr
+
+/// doc comment with bare CR: '\r'
+pub fn foo() {}
+//~^^ ERROR: bare CR not allowed in doc-comment
+
+/** block doc comment with bare CR: '\r' */
+pub fn bar() {}
+//~^^ ERROR: bare CR not allowed in block doc-comment
+
+fn main() {
+    // the following string literal has a bare CR in it
+    let _s = "foo\rbar"; //~ ERROR: bare CR not allowed in string
+
+    // the following string literal has a bare CR in it
+    let _s = r"bar\rfoo"; //~ ERROR: bare CR not allowed in raw string
+
+    // the following string literal has a bare CR in it
+    let _s = "foo\\rbar"; //~ ERROR: unknown character escape: \r
+}
diff --git a/src/test/parse-fail/lifetime-no-keyword.rs b/src/test/parse-fail/lifetime-no-keyword.rs
new file mode 100644 (file)
index 0000000..8ffbcd9
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo<'a>(a: &'a isize) { }
+fn bar(a: &'static isize) { }
+fn baz(a: &'let isize) { } //~ ERROR invalid lifetime name
+
+fn main() { }
diff --git a/src/test/parse-fail/lifetime-obsoleted-self.rs b/src/test/parse-fail/lifetime-obsoleted-self.rs
new file mode 100644 (file)
index 0000000..766922f
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn baz(a: &'self isize) { } //~ ERROR invalid lifetime name: 'self is no longer a special lifetime
+
+fn main() { }
diff --git a/src/test/parse-fail/macros-no-semicolon-items.rs b/src/test/parse-fail/macros-no-semicolon-items.rs
new file mode 100644 (file)
index 0000000..3142920
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+macro_rules! foo()  //~ ERROR semicolon
+
+fn main() {
+}
diff --git a/src/test/parse-fail/mod_file_disambig.rs b/src/test/parse-fail/mod_file_disambig.rs
deleted file mode 100644 (file)
index 48bd00a..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-mod mod_file_disambig_aux; //~ ERROR file for module `mod_file_disambig_aux` found at both
-
-fn main() {
-    assert_eq!(mod_file_aux::bar(), 10);
-}
diff --git a/src/test/parse-fail/mod_file_not_owning.rs b/src/test/parse-fail/mod_file_not_owning.rs
deleted file mode 100644 (file)
index adbcedd..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern: cannot declare a new module at this location
-
-mod mod_file_not_owning_aux1;
-
-fn main() {}
diff --git a/src/test/parse-fail/no-binary-float-literal.rs b/src/test/parse-fail/no-binary-float-literal.rs
new file mode 100644 (file)
index 0000000..2e207f9
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern:binary float literal is not supported
+
+fn main() {
+    0b101010f64;
+    0b101.010;
+    0b101p4f64;
+}
diff --git a/src/test/parse-fail/no-hex-float-literal.rs b/src/test/parse-fail/no-hex-float-literal.rs
new file mode 100644 (file)
index 0000000..4abb609
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern:hexadecimal float literal is not supported
+
+fn main() {
+    0xABC.Df;
+    0x567.89;
+    0xDEAD.BEEFp-2f;
+}
diff --git a/src/test/parse-fail/no-unsafe-self.rs b/src/test/parse-fail/no-unsafe-self.rs
new file mode 100644 (file)
index 0000000..0bf73bb
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait A {
+    fn foo(*mut self); //~ ERROR cannot pass self by unsafe pointer
+    fn bar(*self); //~ ERROR cannot pass self by unsafe pointer
+}
+
+struct X;
+impl A for X {
+    fn foo(*mut self) { } //~ ERROR cannot pass self by unsafe pointer
+    fn bar(*self) { } //~ ERROR cannot pass self by unsafe pointer
+}
+
+fn main() { }
diff --git a/src/test/parse-fail/non-str-meta.rs b/src/test/parse-fail/non-str-meta.rs
new file mode 100644 (file)
index 0000000..752f72f
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Issue #623 - non-string meta items are not serialized correctly;
+// for now just forbid them
+
+#[foo = 1] //~ ERROR: non-string literals are not allowed in meta-items
+fn main() { }
diff --git a/src/test/parse-fail/obsolete-for-sized.rs b/src/test/parse-fail/obsolete-for-sized.rs
new file mode 100644 (file)
index 0000000..1b86d08
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we generate obsolete syntax errors around usages of `for Sized?`
+
+trait Foo for Sized? {} //~ ERROR obsolete syntax: for Sized?
+
+trait Bar for ?Sized {} //~ ERROR obsolete syntax: for Sized?
+
+fn main() { }
diff --git a/src/test/parse-fail/obsolete-proc.rs b/src/test/parse-fail/obsolete-proc.rs
new file mode 100644 (file)
index 0000000..5208cdb
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we generate obsolete syntax errors around usages of `proc`.
+
+fn foo(p: proc()) { } //~ ERROR obsolete syntax: the `proc` type
+
+fn bar() { proc() 1; } //~ ERROR obsolete syntax: `proc` expression
+
+fn main() { }
diff --git a/src/test/parse-fail/qquote-1.rs b/src/test/parse-fail/qquote-1.rs
new file mode 100644 (file)
index 0000000..deae9a8
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-test Can't use syntax crate here
+
+#![feature(quote)]
+
+extern crate syntax;
+
+use io::*;
+
+use syntax::diagnostic;
+use syntax::ast;
+use syntax::codemap;
+use syntax::parse;
+use syntax::print::*;
+
+
+trait fake_ext_ctxt {
+    fn cfg() -> ast::CrateConfig;
+    fn parse_sess() -> parse::parse_sess;
+    fn call_site() -> span;
+    fn ident_of(st: &str) -> ast::ident;
+}
+
+type fake_session = parse::parse_sess;
+
+impl fake_ext_ctxt for fake_session {
+    fn cfg() -> ast::CrateConfig { Vec::new() }
+    fn parse_sess() -> parse::parse_sess { self }
+    fn call_site() -> span {
+        codemap::span {
+            lo: codemap::BytePos(0),
+            hi: codemap::BytePos(0),
+            expn_id: NO_EXPANSION
+        }
+    }
+    fn ident_of(st: &str) -> ast::ident {
+        self.interner.intern(st)
+    }
+}
+
+fn mk_ctxt() -> fake_ext_ctxt {
+    parse::new_parse_sess(None) as fake_ext_ctxt
+}
+
+
+
+fn main() {
+    let cx = mk_ctxt();
+
+    let abc = quote_expr!(cx, 23);
+    check_pp(abc,  pprust::print_expr, "23");
+
+    let expr3 = quote_expr!(cx, 2 - $abcd + 7); //~ ERROR unresolved name: abcd
+    check_pp(expr3,  pprust::print_expr, "2 - 23 + 7");
+}
+
+fn check_pp<T>(expr: T, f: |pprust::ps, T|, expect: str) {
+    panic!();
+}
diff --git a/src/test/parse-fail/qquote-2.rs b/src/test/parse-fail/qquote-2.rs
new file mode 100644 (file)
index 0000000..978287a
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-test Can't use syntax crate here
+
+#![feature(quote)]
+
+extern crate syntax;
+
+use syntax::diagnostic;
+use syntax::ast;
+use syntax::codemap;
+use syntax::parse::parser;
+use syntax::print::*;
+
+trait fake_ext_ctxt {
+    fn cfg() -> ast::CrateConfig;
+    fn parse_sess() -> parse::parse_sess;
+    fn call_site() -> span;
+    fn ident_of(st: &str) -> ast::ident;
+}
+
+type fake_session = parse::parse_sess;
+
+impl fake_ext_ctxt for fake_session {
+    fn cfg() -> ast::CrateConfig { Vec::new() }
+    fn parse_sess() -> parse::parse_sess { self }
+    fn call_site() -> span {
+        codemap::span {
+            lo: codemap::BytePos(0),
+            hi: codemap::BytePos(0),
+            expn_id: codemap::NO_EXPANSION
+        }
+    }
+    fn ident_of(st: &str) -> ast::ident {
+        self.interner.intern(st)
+    }
+}
+
+fn mk_ctxt() -> fake_ext_ctxt {
+    parse::new_parse_sess(None) as fake_ext_ctxt
+}
+
+
+fn main() {
+    let cx = mk_ctxt();
+
+    let stmt = quote_stmt!(cx, let x isize = 20;); //~ ERROR expected end-of-string
+    check_pp(*stmt,  pprust::print_stmt, "");
+}
+
+fn check_pp<T>(expr: T, f: |pprust::ps, T|, expect: str) {
+    panic!();
+}
diff --git a/src/test/parse-fail/regions-fn-bound.rs b/src/test/parse-fail/regions-fn-bound.rs
new file mode 100644 (file)
index 0000000..c2b52b7
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-test
+// ignored because the first error does not show up.
+
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn of<T>() -> |T| { panic!(); }
+fn subtype<T>(x: |T|) { panic!(); }
+
+fn test_fn<'x, 'y, 'z, T>(_x: &'x T, _y: &'y T, _z: &'z T) {
+    // Here, x, y, and z are free.  Other letters
+    // are bound.  Note that the arrangement
+    // subtype::<T1>(of::<T2>()) will typecheck
+    // iff T1 <: T2.
+
+    // should be the default:
+    subtype::< ||:'static>(of::<||>());
+    subtype::<||>(of::< ||:'static>());
+
+    //
+    subtype::< <'x> ||>(of::<||>());    //~ ERROR mismatched types
+    subtype::< <'x> ||>(of::< <'y> ||>());  //~ ERROR mismatched types
+
+    subtype::< <'x> ||>(of::< ||:'static>()); //~ ERROR mismatched types
+    subtype::< ||:'static>(of::< <'x> ||>());
+
+}
+
+fn main() {}
diff --git a/src/test/parse-fail/require-parens-for-chained-comparison.rs b/src/test/parse-fail/require-parens-for-chained-comparison.rs
new file mode 100644 (file)
index 0000000..f2705f5
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn f<T>() {}
+
+fn main() {
+    false == false == false;
+    //~^ ERROR: chained comparison operators require parentheses
+
+    false == 0 < 2;
+    //~^ ERROR: chained comparison operators require parentheses
+
+    f<X>();
+    //~^ ERROR: chained comparison operators require parentheses
+    //~^^ HELP: use `::<...>` instead of `<...>`
+}
diff --git a/src/test/parse-fail/struct-no-fields-2.rs b/src/test/parse-fail/struct-no-fields-2.rs
new file mode 100644 (file)
index 0000000..4f973f8
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo;
+
+fn f2() {
+    let _end_stmt     = Foo { };
+    //~^ ERROR: structure literal must either have at least one field
+}
+
+fn main() {}
diff --git a/src/test/parse-fail/struct-no-fields-3.rs b/src/test/parse-fail/struct-no-fields-3.rs
new file mode 100644 (file)
index 0000000..e594683
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo;
+
+fn g3() {
+    let _mid_tuple    = (Foo { }, 2);
+    //~^ ERROR: structure literal must either have at least one field
+}
+
+fn main() {}
diff --git a/src/test/parse-fail/struct-no-fields-4.rs b/src/test/parse-fail/struct-no-fields-4.rs
new file mode 100644 (file)
index 0000000..60a0a85
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo;
+
+fn h4() {
+    let _end_of_tuple = (3, Foo { });
+    //~^ ERROR: structure literal must either have at least one field
+}
+
+fn main() {}
diff --git a/src/test/parse-fail/struct-no-fields-5.rs b/src/test/parse-fail/struct-no-fields-5.rs
new file mode 100644 (file)
index 0000000..940fa9c
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo;
+
+fn i5() {
+    let _end_of_block = { Foo { } };
+    //~^ ERROR: structure literal must either have at least one field
+}
+
+fn main() {}
diff --git a/src/test/parse-fail/struct-variant-no-fields.rs b/src/test/parse-fail/struct-variant-no-fields.rs
new file mode 100644 (file)
index 0000000..41dbbee
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+enum Foo {
+    Bar {} //~ ERROR unit-like struct variant should be written without braces, as `Bar,`
+}
diff --git a/src/test/parse-fail/struct-variant-no-pub.rs b/src/test/parse-fail/struct-variant-no-pub.rs
new file mode 100644 (file)
index 0000000..e62b39a
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+enum Foo {
+    Bar {
+        pub a: isize //~ ERROR: `pub` is not allowed here
+    }
+}
+
+fn main() {}
diff --git a/src/test/parse-fail/syntax-trait-polarity.rs b/src/test/parse-fail/syntax-trait-polarity.rs
new file mode 100644 (file)
index 0000000..1ab79f5
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::Send;
+
+struct TestType;
+
+impl !TestType {}
+//~^ ERROR inherent implementation can't be negated
+
+trait TestTrait {}
+
+unsafe impl !Send for TestType {}
+impl !TestTrait for TestType {}
+
+struct TestType2<T>;
+
+impl<T> !TestType2<T> {}
+//~^ ERROR inherent implementation can't be negated
+
+unsafe impl<T> !Send for TestType2<T> {}
+impl<T> !TestTrait for TestType2<T> {}
+
+fn main() {}
diff --git a/src/test/parse-fail/tag-variant-disr-non-nullary.rs b/src/test/parse-fail/tag-variant-disr-non-nullary.rs
new file mode 100644 (file)
index 0000000..207bbe9
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//error-pattern: discriminator values can only be used with a c-like enum
+
+enum color {
+    red = 0xff0000,
+    green = 0x00ff00,
+    blue = 0x0000ff,
+    black = 0x000000,
+    white = 0xffffff,
+    other (str),
+}
diff --git a/src/test/parse-fail/trailing-carriage-return-in-string.rs b/src/test/parse-fail/trailing-carriage-return-in-string.rs
new file mode 100644 (file)
index 0000000..8109833
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-cr
+// Issue #11669
+
+fn main() {
+    // \r\n
+    let ok = "This is \
+ a test";
+    // \r only
+    let bad = "This is \\r a test";
+    //~^ ERROR unknown character escape: \r
+    //~^^ HELP this is an isolated carriage return
+
+}
diff --git a/src/test/parse-fail/trailing-plus-in-bounds.rs b/src/test/parse-fail/trailing-plus-in-bounds.rs
new file mode 100644 (file)
index 0000000..e8f9ed4
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::fmt::Show;
+
+fn main() {
+    let x: Box<Show+> = box 3 as Box<Show+>;
+    //~^ ERROR at least one type parameter bound must be specified
+    //~^^ ERROR at least one type parameter bound must be specified
+}
+
diff --git a/src/test/parse-fail/trait-bounds-not-on-impl.rs b/src/test/parse-fail/trait-bounds-not-on-impl.rs
new file mode 100644 (file)
index 0000000..a034352
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Foo {
+}
+
+struct Bar;
+
+impl Foo + Owned for Bar { //~ ERROR not a trait
+}
+
+fn main() { }
diff --git a/src/test/parse-fail/type-parameters-in-field-exprs.rs b/src/test/parse-fail/type-parameters-in-field-exprs.rs
new file mode 100644 (file)
index 0000000..54ddb3e
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo {
+    x: isize,
+    y: isize,
+}
+
+fn main() {
+    let f = Foo {
+        x: 1,
+        y: 2,
+    };
+    f.x::<isize>;
+    //~^ ERROR field expressions may not have type parameters
+}
+
diff --git a/src/test/parse-fail/unsized2.rs b/src/test/parse-fail/unsized2.rs
new file mode 100644 (file)
index 0000000..b2eb206
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test syntax checks for `type` keyword.
+
+fn f<X>() {}
+
+pub fn main() {
+    f<type>();
+    //~^ ERROR expected identifier, found keyword `type`
+    //~^^ ERROR: chained comparison
+    //~^^^ HELP: use `::<
+}
diff --git a/src/test/parse-fail/virtual-structs.rs b/src/test/parse-fail/virtual-structs.rs
new file mode 100644 (file)
index 0000000..3b3c7d5
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test diagnostics for the removed struct inheritance feature.
+#![feature(struct_inherit)]
+
+virtual struct SuperStruct { //~ ERROR `virtual` structs have been removed from the language
+    f1: isize,
+}
+
+struct Struct : SuperStruct; //~ ERROR `virtual` structs have been removed from the language
+
+pub fn main() {}
diff --git a/src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs b/src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs
new file mode 100644 (file)
index 0000000..b96c7c2
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn equal1<T>(_: &T, _: &T) -> bool where {
+//~^ ERROR a `where` clause must have at least one predicate in it
+    true
+}
+
+fn equal2<T>(_: &T, _: &T) -> bool where T: {
+//~^ ERROR each predicate in a `where` clause must have at least one bound
+    true
+}
+
+fn main() {
+}
+
index 65dcf90056701835bc7a1daa81fea50350c2d144..79964d2a7bacab9ad9fa7b4cc63ebd28cdc08115 100644 (file)
@@ -13,6 +13,8 @@
 // preserved, and that the first outer item parsed in main is not
 // accidentally carried over to each inner function
 
+#![feature(custom_attribute)]
+
 fn main() {
     #![inner_attr]
     #[outer_attr]
index 816ee84a8410a3b7aab073bb7c7badcc2ed1e911..3a5ac5a10095742c13772734fc3e9f1c8914e458 100644 (file)
 
 // error-pattern:thread '<unnamed>' panicked at 'test'
 
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
-    let r: Result<int,_> = Thread::scoped(move|| {
+    let r: Result<(),_> = thread::spawn(move|| {
         panic!("test");
-        1
     }).join();
     assert!(r.is_ok());
 }
index d48d282c9eb3578d8244c7f11ce12d446c439062..8cab9e05f96e87ca3f6569f7cfe461a284876f14 100644 (file)
@@ -13,9 +13,9 @@
 use std::thread::Builder;
 
 fn main() {
-    let r: Result<int,_> = Builder::new().name("owned name".to_string()).scoped(move|| {
+    let r: () = Builder::new().name("owned name".to_string()).scoped(move|| {
         panic!("test");
-        1
-    }).join();
-    assert!(r.is_ok());
+        ()
+    }).unwrap().join();
+    panic!();
 }
index 446ef6f97e2972cb5e25156ad11fbc075d586148..775d38c8b3044ca917d8729799552664e21e90d2 100644 (file)
@@ -12,7 +12,7 @@
 
 #[macro_use] extern crate log;
 use std::os;
-use std::thread::Thread;
+use std::thread;
 
 struct r {
   x:int,
@@ -35,7 +35,7 @@ fn r(x:int) -> r {
 
 fn main() {
     error!("whatever");
-    let _t = Thread::spawn(move|| {
+    let _t = thread::spawn(move|| {
       let _i = r(5);
     });
     panic!();
index d58148810da1fd22109596710d7035307732943b..406f7dbcb67fec9d95711e32b5e8b5fd68985813 100644 (file)
 
 // error-pattern:Ensure that the child task runs by panicking
 
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
     // the purpose of this test is to make sure that task::spawn()
     // works when provided with a bare function:
-    let r = Thread::scoped(startfn).join();
+    let r = thread::spawn(startfn).join();
     if r.is_err() {
         panic!()
     }
index 5b44e3757047b83db80c3030602f323417f8b5bd..be619e3a82cc6d3a4e50058e9b7f1d926e7433e9 100644 (file)
@@ -11,9 +11,9 @@
 // error-pattern:nonzero
 // exec-env:RUST_NEWRT=1
 
-use std::os;
+use std::env;
 
 fn main() {
-    os::args();
+    env::args();
     panic!("please have a nonzero exit status");
 }
index c8156b95dcfcb4d696db4a2f108a530b31a28f36..89352a16d8ba2fe3792b017c9f66bebae9cd9020 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::os;
+use std::env;
 use std::old_io::{File, Command};
 
 // creates broken.rs, which has the Ident \x00name_0,ctxt_0\x00
@@ -16,7 +16,7 @@
 // provided `rustc`
 
 fn main() {
-    let args = os::args();
+    let args: Vec<String> = env::args().collect();
     let rustc = &args[1];
     let tmpdir = Path::new(&args[2]);
 
index 808417d6521eabb341ce6a27087cf76955f8c7ea..c96210896fd652c94296e47b38ff632c5db31271 100644 (file)
@@ -22,7 +22,7 @@ fn main() {
     fn main() {}
     "#;
 
-    let args = std::os::args();
+    let args: Vec<String> = std::env::args().collect();
 
     if args.len() < 4 {
         panic!("expected rustc path");
index c3fa1a68e164c4e491909effa259f37813083f82..12c72d54c094b54b04e372a2604e28b88fbb0fb3 100644 (file)
@@ -10,7 +10,7 @@
 
 #![crate_type = "rlib"]
 
-pub static mut statik: int = 0;
+pub static mut statik: isize = 0;
 
 struct A;
 impl Drop for A {
index 6d10a247143faf9f5f0b121fd18afe13ea49a289..d325f54d36515bc5622fb4aa6e6b33a75a876d9f 100644 (file)
@@ -10,9 +10,9 @@
 
 extern crate lib;
 
-use std::thread::Thread;
+use std::thread;
 
-static mut statik: int = 0;
+static mut statik: isize = 0;
 
 struct A;
 impl Drop for A {
@@ -22,10 +22,9 @@ fn drop(&mut self) {
 }
 
 fn main() {
-    Thread::scoped(move|| {
+    thread::spawn(move|| {
         let _a = A;
         lib::callback(|| panic!());
-        1
     }).join().err().unwrap();
 
     unsafe {
index f5f622bbcdaa69cb697aad58ac154d4465a1eb61..d7cf7131d73813870609332b89e25813e1b08842 100644 (file)
@@ -2,7 +2,7 @@
     "data-layout": "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32",
     "llvm-target": "i686-unknown-linux-gnu",
     "target-endian": "little",
-    "target-word-size": "32",
+    "target-pointer-width": "32",
     "arch": "x86",
     "os": "linux",
     "morestack": false
index 5005a9ff83960cd1485aa17a1ccefb80c00d35c0..053f2dd63358a9b9e832e5dbaaf7831e5752b445 100644 (file)
@@ -1,7 +1,7 @@
 {
     "data-layout": "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32",
     "target-endian": "little",
-    "target-word-size": "32",
+    "target-pointer-width": "32",
     "arch": "x86",
     "os": "foo",
     "morestack": false
index 5e0f0f40e67bc8e1c95dc939d5a01d4980f4ed07..688bbe46bfaf0593b6df26e2a1035ee0952ee272 100644 (file)
@@ -3,7 +3,7 @@
     "data-layout": "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128",
     "llvm-target": "x86_64-unknown-linux-gnu",
     "target-endian": "little",
-    "target-word-size": "64",
+    "target-pointer-width": "64",
     "arch": "x86_64",
     "os": "linux",
     "morestack": false
index be67e5a066acb90596256545070040c90e7b9d76..759a1d4aff958fa110b46d34bcaf32d6a8cc76fc 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::{char, os};
+use std::{char, env};
 use std::old_io::{File, Command};
 use std::rand::{thread_rng, Rng};
 
@@ -33,7 +33,7 @@ fn random_char() -> char {
 }
 
 fn main() {
-    let args = os::args();
+    let args: Vec<String> = env::args().collect();
     let rustc = &args[1];
     let tmpdir = Path::new(&args[2]);
 
index 95ce57da4e110c60c977e11a2857abf305340c80..5dee9104b0f6989f5fb5f3954330bc0501baa10c 100644 (file)
@@ -11,7 +11,7 @@
 use std::old_io::{File, Command};
 use std::iter::repeat;
 use std::rand::{thread_rng, Rng};
-use std::{char, os};
+use std::{char, env};
 
 // creates a file with `fn main() { <random ident> }` and checks the
 // compiler emits a span of the appropriate length (for the
@@ -33,7 +33,7 @@ fn random_char() -> char {
 }
 
 fn main() {
-    let args = os::args();
+    let args: Vec<String> = env::args().collect();
     let rustc = &args[1];
     let tmpdir = Path::new(&args[2]);
     let main_file = tmpdir.join("span_main.rs");
index c59a3589c04af3eded86a01ca5d88d38038e6e55..c1ffeb7c8e2e96d9262e90d5a84f572545d9f685 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-stage1
-// ignore-android
 // aux-build:issue_16723_multiple_items_syntax_ext.rs
 #![feature(plugin)]
 #![plugin(issue_16723_multiple_items_syntax_ext)]
index 2a65fd9d8a655deed16e76b4998094b4845acc89..951a716879fce782c8f45effa67497ced90d438f 100644 (file)
@@ -10,6 +10,8 @@
 
 // error-pattern:expected item
 
+#![feature(custom_attribute)]
+
 #[foo = "bar"]
 extern crate test;
 
index 5b8e62de6bd820a0d16831458bef2e01c7186f59..ad8ce608bd05dcb30fe4f6067c5f93558cac8798 100644 (file)
@@ -10,6 +10,8 @@
 
 // error-pattern:expected item
 
+#![feature(custom_attribute)]
+
 mod m {
     #[foo = "bar"]
     extern crate test;
index 55ca75b4b7131256a7252a5d57b805a014d1dafa..7980937ce2a159f84aa129871dbeb59b183906c1 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 #![allow(unused_attribute)]
+#![feature(custom_attribute)]
 
 #[foo(bar)]
 mod foo {
index b1cb4d6e42c23f46c1c7a320526cf82fcc143ae6..6f76322cb778d57a0401c4a333619c5dace9418f 100644 (file)
@@ -14,7 +14,6 @@
 #![feature(unboxed_closures)]
 #![feature(unsafe_destructor)]
 
-use std::os;
 use std::env;
 use std::old_io::process::Command;
 use std::str;
@@ -86,8 +85,7 @@ fn runtest(me: &str) {
 }
 
 fn main() {
-    let args = os::args();
-    let args = args;
+    let args: Vec<String> = env::args().collect();
     if args.len() >= 2 && args[1] == "fail" {
         foo();
     } else if args.len() >= 2 && args[1] == "double-fail" {
index 3df9dd25d8681ae0ad27240c8ab1fe066ff8ed9d..379ac12a95424c3ac1880e95e39121cd7c17dfe0 100644 (file)
@@ -22,7 +22,7 @@ trait Foo : Bar { }
 impl <T: Send> Foo for T { }
 impl <T: Send> Bar for T { }
 
-fn foo<T: Foo>(val: T, chan: Sender<T>) {
+fn foo<T: Foo + 'static>(val: T, chan: Sender<T>) {
     chan.send(val).unwrap();
 }
 
index 52b826393e9e352cf26685946c4b242d3ec0e2c6..cd019c21a3d056f1ad291581de645f2ac1cd0448 100644 (file)
@@ -25,7 +25,7 @@
 impl <T: Sync> RequiresShare for X<T> { }
 impl <T: Sync+Send> RequiresRequiresShareAndSend for X<T> { }
 
-fn foo<T: RequiresRequiresShareAndSend>(val: T, chan: Sender<T>) {
+fn foo<T: RequiresRequiresShareAndSend + 'static>(val: T, chan: Sender<T>) {
     chan.send(val).unwrap();
 }
 
index 034e5ff2d3a5c6c224c15c74b9370b2379b2d5f7..dc61508eec4fabf7acbb7bc55c029588ca1d7ac1 100644 (file)
@@ -18,7 +18,7 @@ trait Foo : Send { }
 
 impl <T: Send> Foo for T { }
 
-fn foo<T: Foo>(val: T, chan: Sender<T>) {
+fn foo<T: Foo + 'static>(val: T, chan: Sender<T>) {
     chan.send(val).unwrap();
 }
 
index 1b3070ba3b04d89510556472cf41055040ba35d8..1d05a7baa5352b938af0eee830201e6b023263a2 100644 (file)
 
 use std::sync::mpsc::{Sender, channel};
 
-trait Foo : Send + Sized {
+trait Foo : Send + Sized + 'static {
     fn foo(self, tx: Sender<Self>) {
         tx.send(self).unwrap();
     }
 }
 
-impl <T: Send> Foo for T { }
+impl <T: Send + 'static> Foo for T { }
 
 pub fn main() {
     let (tx, rx) = channel();
index 308b225a344f7b566cb8c452314e69dc503de166..70cc0463a6e11bd927f153491775d0f9b1d070e3 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android (FIXME #11419)
 // exec-env:RUST_LOG=info
 
 #![allow(unknown_features)]
index 9acc0b3a3c52fa656217b68b2010205f9c3180cd..4e05c263a48bafddc0486e40b311ae2e865d62a4 100644 (file)
@@ -11,6 +11,9 @@
 // Static recursion check shouldn't fail when given a foreign item (#18279)
 
 // aux-build:check_static_recursion_foreign_helper.rs
+
+#![feature(custom_attribute)]
+
 extern crate check_static_recursion_foreign_helper;
 extern crate libc;
 
index 28081e5292aaae022b0a8bc039e9cc2690f93be2..5dc27472184d7e72a184094dcd267c37950eb8d9 100644 (file)
@@ -10,6 +10,7 @@
 
 // pp-exact - Make sure we actually print the attributes
 #![allow(unused_attribute)]
+#![feature(custom_attribute)]
 
 struct cat {
     name: String,
index bd62f838444afad24580d6f230e23f6c7238d5cd..cc1b15bcb81cda70c2ce6d4d2dcb5ba2680a0138 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 #![allow(unused_attribute)]
+#![feature(custom_attribute)]
 
 struct cat {
   name: String,
index edb3d72483b471663e7892107ba2e0e8ead5d853..96ae7e3d3368f2fdc5abed5d7c8fbbbdd5f16e85 100644 (file)
@@ -27,7 +27,7 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-use std::thread::Thread;
+use std::thread;
 
 enum Conzabble {
     Bickwick(Foo)
@@ -48,5 +48,5 @@ pub fn fails() {
 }
 
 pub fn main() {
-    Thread::scoped(fails).join();
+    thread::spawn(fails).join();
 }
index b776f098b1db2f550b7850149b1ae97cba083818..59f63a79c3ddf93ffb088eb06443566ba6f69aff 100644 (file)
 
 // Test that cleanups for the RHS of shortcircuiting operators work.
 
-use std::os;
+use std::env;
 
 pub fn main() {
-    let args = os::args();
-    let args = args;
+    let args: Vec<String> = env::args().collect();
 
     // Here, the rvalue `"signal".to_string()` requires cleanup. Older versions
     // of the code had a problem that the cleanup scope for this
index bcb2e492041509a95e899f16f1b97ffebd822772..841aaa94e9b552e9f4de847450136245e7dff80e 100644 (file)
@@ -21,7 +21,7 @@ struct Foo<'a> {
 
 struct Bar;
 
-impl fmt::Writer for Bar {
+impl fmt::Write for Bar {
     fn write_str(&mut self, _: &str) -> fmt::Result {
         Ok(())
     }
@@ -39,7 +39,7 @@ fn main() {
 
     let mut s = Bar;
     {
-        use std::fmt::Writer;
+        use std::fmt::Write;
         write!(&mut s, "test");
     }
 }
index 2474bb8a4f36c12ab0321ab8763164b6afe58168..d52c645730f4532f873dc9bd70324700baf4a7df 100644 (file)
@@ -11,7 +11,7 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-use std::thread::Thread;
+use std::thread;
 use std::sync::mpsc::{channel, Sender};
 
 #[derive(PartialEq, Debug)]
@@ -69,15 +69,16 @@ pub fn main() {
     assert_eq!(receiver.recv().ok(), None);
 
     let (sender, receiver) = channel();
-    let _t = Thread::scoped(move|| {
+    let t = thread::spawn(move|| {
         let v = Foo::FailingVariant { on_drop: SendOnDrop { sender: sender } };
     });
     assert_eq!(receiver.recv().unwrap(), Message::Dropped);
     assert_eq!(receiver.recv().ok(), None);
+    drop(t.join());
 
     let (sender, receiver) = channel();
-    let _t = {
-        Thread::scoped(move|| {
+    let t = {
+        thread::spawn(move|| {
             let mut v = Foo::NestedVariant(box 42u, SendOnDrop {
                 sender: sender.clone()
             }, sender.clone());
@@ -93,4 +94,5 @@ pub fn main() {
     assert_eq!(receiver.recv().unwrap(), Message::DestructorRan);
     assert_eq!(receiver.recv().unwrap(), Message::Dropped);
     assert_eq!(receiver.recv().ok(), None);
+    drop(t.join());
 }
index f99d3eb1c7d498b26800fe3ae6f01874ab3d24e7..3f226a1985e78e5d3ceccb37437d4b96067b9506 100644 (file)
@@ -11,7 +11,7 @@
 extern crate libc;
 
 use std::mem;
-use std::thread::Thread;
+use std::thread;
 
 #[link(name = "rust_test_helpers")]
 extern {
@@ -21,9 +21,9 @@ fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t),
 
 pub fn main() {
     unsafe {
-        Thread::scoped(move|| {
-            let i = &100;
-            rust_dbg_call(callback, mem::transmute(i));
+        thread::spawn(move|| {
+            let i = 100;
+            rust_dbg_call(callback, mem::transmute(&i));
         }).join();
     }
 }
index 5d157d875fa4dbec76c3d25e5853c5c21da5e5f3..e5aade792edf01bd1a20a4f75aff9394cd8e12da 100644 (file)
@@ -165,9 +165,9 @@ pub fn main() {
 }
 
 // Basic test to make sure that we can invoke the `write!` macro with an
-// io::Writer instance.
+// fmt::Write instance.
 fn test_write() {
-    use std::fmt::Writer;
+    use std::fmt::Write;
     let mut buf = String::new();
     write!(&mut buf, "{}", 3);
     {
@@ -194,7 +194,7 @@ fn test_print() {
 // Just make sure that the macros are defined, there's not really a lot that we
 // can do with them just yet (to test the output)
 fn test_format_args() {
-    use std::fmt::Writer;
+    use std::fmt::Write;
     let mut buf = String::new();
     {
         let w = &mut buf;
index 07f021e48d7e7a40de3a0a99def9651e913519c1..bd2f73440cae6db8953d5814a315bb7d49283aab 100644 (file)
@@ -66,7 +66,7 @@ pub fn main() {
 #[cfg(target_os = "android")]
 mod m {
     #[main]
-    #[cfg(target_arch = "arm")]
+    #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
     pub fn main() {
         unsafe {
             assert_eq!(::rusti::pref_align_of::<u64>(), 8u);
index 9150920cf2cc7e5feb79b97ea1649a3c01d50ab1..29e4801d0a9aac66aed21b86449825d18234fd72 100644 (file)
 // Make sure that if a process doesn't have its stdio/stderr descriptors set up
 // that we don't die in a large ball of fire
 
-use std::os;
+use std::env;
 use std::old_io::process;
 
 pub fn main () {
-    let args = os::args();
-    let args = args;
+    let args: Vec<String> = env::args().collect();
     if args.len() > 1 && args[1] == "child" {
         for _ in 0..1000 {
             println!("hello?");
index 38731b8c8daeb579a9694d4280611685bff1b3c8..e66b5d21e17fabf498b081f82d788b015a246802 100644 (file)
@@ -9,10 +9,10 @@
 // except according to those terms.
 
 use std::time::Duration;
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
-    Thread::scoped(move|| customtask()).join().ok().unwrap();
+    thread::spawn(move|| customtask()).join().ok().unwrap();
 }
 
 fn customtask() {
index 4dc824d9068e52043fb20eb0bceed96e466d2fdc..4a7d6be55a1625fa4730c38d3d43a8feaaf8e83b 100644 (file)
 
 // ignore-fast
 
-use std::os;
+use std::env;
 use std::old_io;
 use std::str;
 
 fn main() {
-    let args = os::args();
-    let args = args;
+    let args: Vec<String> = env::args().collect();
     if args.len() > 1 && args[1] == "child" {
         child();
     } else {
@@ -25,8 +24,7 @@ fn main() {
 }
 
 fn parent() {
-    let args = os::args();
-    let args = args;
+    let args: Vec<String> = env::args().collect();
     let mut p = old_io::process::Command::new(&args[0])
                                      .arg("child").spawn().unwrap();
     p.stdin.as_mut().unwrap().write_str("test1\ntest2\ntest3").unwrap();
index 1c8066bc3c98511e35a989ad8729e45d082be66b..723db9485ca6ee110b2ced81aad5f69b60f193ae 100644 (file)
 use std::old_io::process;
 use std::old_io::Command;
 use std::old_io;
-use std::os;
+use std::env;
 
 fn main() {
-    let args = os::args();
+    let args: Vec<String> = env::args().collect();
     if args.len() > 1 && args[1] == "child" {
         return child()
     }
@@ -32,7 +32,7 @@ fn child() {
 }
 
 fn test() {
-    let args = os::args();
+    let args: Vec<String> = env::args().collect();
     let mut p = Command::new(&args[0]).arg("child")
                                      .stdin(process::Ignored)
                                      .stdout(process::Ignored)
index e5fead72bebeb44b5aa4acd15f83c2ad31bc6ce8..ed0e3bddbe515b8d3a5b6abce07d2528ea72ac61 100644 (file)
@@ -8,16 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::os;
+use std::env;
 use std::old_io::{stdio, Command};
 
 fn main() {
-    let args = os::args();
+    let mut args = env::args();
     if args.len() > 1 {
         let mut out = stdio::stdout();
         out.write(&['a' as u8; 128 * 1024]).unwrap();
     } else {
-        let out = Command::new(&args[0]).arg("child").output();
+        let out = Command::new(&args.next().unwrap()).arg("child").output();
         let out = out.unwrap();
         assert!(out.status.success());
     }
index aa45a8c5d5f7f538576fdbcb177f9cfbd84fa902..aa176d5b0f04197fa482b9a929f3df414a539fc4 100644 (file)
 // except according to those terms.
 
 use std::slice::SliceExt;
-use std::old_io::{Command, fs, USER_RWX};
-use std::os;
+use std::old_io::{fs, USER_RWX};
+use std::process;
 use std::env;
 use std::old_path::BytesContainer;
 use std::rand::random;
 
 fn main() {
     // If we're the child, make sure we were invoked correctly
-    let args = os::args();
+    let args: Vec<String> = env::args().collect();
     if args.len() > 1 && args[1] == "child" {
         // FIXME: This should check the whole `args[0]` instead of just
         // checking that it ends_with the executable name. This
         // is needed because of Windows, which has a different behavior.
         // See #15149 for more info.
-        return assert!(args[0].ends_with(&format!("mytest{}", os::consts::EXE_SUFFIX)[]));
+        return assert!(args[0].ends_with(&format!("mytest{}", env::consts::EXE_SUFFIX)[]));
     }
 
     test();
@@ -33,7 +33,7 @@ fn main() {
 
 fn test() {
     // If we're the parent, copy our own binary to a new directory.
-    let my_path = os::self_exe_name().unwrap();
+    let my_path = env::current_exe().unwrap();
     let my_dir  = my_path.dir_path();
 
     let random_u32: u32 = random();
@@ -42,22 +42,24 @@ fn test() {
     fs::mkdir(&child_dir, USER_RWX).unwrap();
 
     let child_path = child_dir.join(format!("mytest{}",
-                                            os::consts::EXE_SUFFIX));
+                                            env::consts::EXE_SUFFIX));
     fs::copy(&my_path, &child_path).unwrap();
 
     // Append the new directory to our own PATH.
-    let mut path = os::split_paths(env::var("PATH").ok().unwrap_or(String::new()));
-    path.push(child_dir.clone());
-    let path = os::join_paths(&path).unwrap();
+    let path = {
+        let mut paths: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap()).collect();
+        paths.push(child_dir.clone());
+        env::join_paths(paths.iter()).unwrap()
+    };
 
-    let child_output = Command::new("mytest").env("PATH", path)
-                                             .arg("child")
-                                             .output().unwrap();
+    let child_output = process::Command::new("mytest").env("PATH", &path)
+                                                      .arg("child")
+                                                      .output().unwrap();
 
     assert!(child_output.status.success(),
             format!("child assertion failed\n child stdout:\n {}\n child stderr:\n {}",
-                    child_output.output.container_as_str().unwrap(),
-                    child_output.error.container_as_str().unwrap()));
+                    child_output.stdout.container_as_str().unwrap(),
+                    child_output.stderr.container_as_str().unwrap()));
 
     fs::rmdir_recursive(&child_dir).unwrap();
 
index d73ca1b11a5555fef9b8d3aca29d3f0e5f65b6ae..3bab78ab0df9f0ca3959ff1ea010a0f9a5ff0b0b 100644 (file)
@@ -9,10 +9,10 @@
 // except according to those terms.
 
 use std::old_io::{process, Command};
-use std::os;
+use std::env;
 
 fn main() {
-    let len = os::args().len();
+    let len = env::args().len();
 
     if len == 1 {
         test();
@@ -22,7 +22,7 @@ fn main() {
 }
 
 fn test() {
-    let status = Command::new(os::self_exe_name().unwrap())
+    let status = Command::new(env::current_exe().unwrap())
                          .arg("foo").arg("")
                          .stdout(process::InheritFd(1))
                          .stderr(process::InheritFd(2))
index ca40b2fe4c7d06fce8db083777c5aa4c88454ab5..9448e605937f728b36c2410841f3ec3d68af1054 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(unboxed_closures)]
 
-use std::thread::Thread;
+use std::thread;
 use std::mem;
 
 fn main() {
@@ -20,7 +20,7 @@ fn main() {
     // Check that both closures are capturing by value
     assert_eq!(1, mem::size_of_val(&closure));
 
-    Thread::scoped(move|| {
+    thread::spawn(move|| {
         let ok = closure;
     }).join().ok().unwrap();
 }
index 124b0205faeb5d39a7d6b1e4c3b20a4060ed23c1..b06c4923c16c1af370ea3f443e1932d4a3a7d475 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android seems to block forever
 
 #![forbid(warnings)]
 
 // A var moved into a proc, that has a mutable loan path should
 // not trigger a misleading unused_mut warning.
 
-use std::thread::Thread;
+use std::thread;
 
 pub fn main() {
     let mut stdin = std::old_io::stdin();
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         let _ = stdin.read_to_end();
     });
 }
index 7a5a86822afda0233e98aa0e2222b44804994ae8..a4b09eb08e0f663392de8cbbdcd25f47e8a01523 100644 (file)
 
 pub trait Promisable: Send + Sync {}
 impl<T: Send + Sync> Promisable for T {}
-pub fn propagate<T, E, F, G>(action: F) -> Thunk<Result<T, E>, Result<T, E>>
+pub fn propagate<'a, T, E, F, G>(action: F) -> Thunk<'a,Result<T, E>, Result<T, E>>
     where
-        T: Promisable + Clone,
-        E: Promisable + Clone,
-        F: FnOnce(&T) -> Result<T, E> + Send,
-        G: FnOnce(Result<T, E>) -> Result<T, E> {
+        T: Promisable + Clone + 'a,
+        E: Promisable + Clone + 'a,
+        F: FnOnce(&T) -> Result<T, E> + Send + 'a,
+        G: FnOnce(Result<T, E>) -> Result<T, E> + 'a {
     Thunk::with_arg(move |result: Result<T, E>| {
         match result {
             Ok(ref t) => action(t),
index 3ef63a53a6dea195780df58473d88e2c6b573b12..4d20e6360ad4fdda2654b0047b475e37b2fcdaac 100644 (file)
 // ignore-windows currently windows requires UTF-8 for spawning processes
 
 use std::old_io::Command;
-use std::os;
+use std::env;
 
 fn main() {
-    if os::args().len() == 1 {
-        assert!(Command::new(os::self_exe_name().unwrap()).arg(b"\xff")
+    if env::args().len() == 1 {
+        assert!(Command::new(env::current_exe().unwrap()).arg(b"\xff")
                         .status().unwrap().success())
     }
 }
index 044d43a57fabad14eea27687b54fa27998dc6981..3cdd57aed5a1ccef3c37438a0981005eee8f1e9a 100644 (file)
@@ -14,7 +14,7 @@ struct DST { a: u32, b: str }
 
 fn main() {
     // get_tydesc should support unsized types
-    assert!(unsafe {(
+    assert_eq!(unsafe {(
         // Slice
         (*std::intrinsics::get_tydesc::<[u8]>()).name,
         // str
@@ -25,5 +25,5 @@ fn main() {
         (*std::intrinsics::get_tydesc::<NT>()).name,
         // DST
         (*std::intrinsics::get_tydesc::<DST>()).name
-    )} == ("[u8]", "str", "core::marker::Copy + 'static", "NT", "DST"));
+    )}, ("[u8]", "str", "core::marker::Copy", "NT", "DST"));
 }
index 810bf385d7e0b0946d1c05921155a6fbc53d922d..3025741694f43b4068850047628e81c0d902257f 100644 (file)
 
 static generations: uint = 1024+256+128+49;
 
-fn spawn(f: Thunk) {
+fn spawn(f: Thunk<'static>) {
     Builder::new().stack_size(32 * 1024).spawn(move|| f.invoke(()));
 }
 
-fn child_no(x: uint) -> Thunk {
+fn child_no(x: uint) -> Thunk<'static> {
     Thunk::new(move|| {
         if x < generations {
             spawn(child_no(x+1));
index ec4cd02e9fd698ea3167e5f7aa889efdb298066a..b40a726a2c397223e3746eba91e9f1be0e09847f 100644 (file)
 
 use std::old_io::println;
 use std::sync::mpsc::channel;
-use std::thread::Thread;
+use std::thread;
 
 pub fn main() {
     let (tx, rx) = channel();
 
     tx.send("hello, world").unwrap();
 
-    Thread::scoped(move|| {
+    thread::spawn(move|| {
         println(rx.recv().unwrap());
     }).join().ok().unwrap();
 }
index a19bfca721a7c2318dc705a183551300c2e808dc..ef30f9182ba69b2dd77f2d810068b61e204366d4 100644 (file)
@@ -9,12 +9,12 @@
 // except according to those terms.
 
 use std::sync::mpsc::channel;
-use std::thread::Thread;
+use std::thread;
 
 pub fn main() {
     let (tx, rx) = channel::<&'static str>();
 
-    let t = Thread::scoped(move|| {
+    let t = thread::spawn(move|| {
         assert_eq!(rx.recv().unwrap(), "hello, world");
     });
 
index f10303e8d8479a1eb433c4dbe1122628e3a84de5..1f090d8b622e05686fe7589b6db102ada1fa3de7 100644 (file)
@@ -9,8 +9,7 @@
 // except according to those terms.
 
 fn parse_args() -> String {
-    let args = ::std::os::args();
-    let args = args;
+    let args: Vec<_> = ::std::env::args().collect();
     let mut n = 0;
 
     while n < args.len() {
index ae72de50d26d838d48999e67fe86ff52288580f7..521e1b40f992e5d1b305172840ee6aaa9257bad0 100644 (file)
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::os;
+use std::env;
 
 pub fn main() {
-    for arg in &os::args() {
-        match (*arg).clone() {
+    for arg in env::args() {
+        match arg.clone() {
             _s => { }
         }
     }
index 4b9ed44c7cd7a93754e5a9cc8874fb69e9d8f769..72a1ec436f307d660d0e0b899e0e77bf8b0b6906 100644 (file)
@@ -9,31 +9,31 @@
 // except according to those terms.
 
 use std::num::Int;
-use std::thread::Thread;
+use std::thread;
 
 // Avoid using constants, which would trigger compile-time errors.
 fn min_val<T: Int>() -> T { Int::min_value() }
 fn zero<T: Int>() -> T { Int::zero() }
 
 fn main() {
-    assert!(Thread::scoped(move|| min_val::<isize>() / -1).join().is_err());
-    assert!(Thread::scoped(move|| min_val::<i8>() / -1).join().is_err());
-    assert!(Thread::scoped(move|| min_val::<i16>() / -1).join().is_err());
-    assert!(Thread::scoped(move|| min_val::<i32>() / -1).join().is_err());
-    assert!(Thread::scoped(move|| min_val::<i64>() / -1).join().is_err());
-    assert!(Thread::scoped(move|| 1is / zero()).join().is_err());
-    assert!(Thread::scoped(move|| 1i8 / zero()).join().is_err());
-    assert!(Thread::scoped(move|| 1i16 / zero()).join().is_err());
-    assert!(Thread::scoped(move|| 1i32 / zero()).join().is_err());
-    assert!(Thread::scoped(move|| 1i64 / zero()).join().is_err());
-    assert!(Thread::scoped(move|| min_val::<isize>() % -1).join().is_err());
-    assert!(Thread::scoped(move|| min_val::<i8>() % -1).join().is_err());
-    assert!(Thread::scoped(move|| min_val::<i16>() % -1).join().is_err());
-    assert!(Thread::scoped(move|| min_val::<i32>() % -1).join().is_err());
-    assert!(Thread::scoped(move|| min_val::<i64>() % -1).join().is_err());
-    assert!(Thread::scoped(move|| 1is % zero()).join().is_err());
-    assert!(Thread::scoped(move|| 1i8 % zero()).join().is_err());
-    assert!(Thread::scoped(move|| 1i16 % zero()).join().is_err());
-    assert!(Thread::scoped(move|| 1i32 % zero()).join().is_err());
-    assert!(Thread::scoped(move|| 1i64 % zero()).join().is_err());
+    assert!(thread::spawn(move|| { min_val::<isize>() / -1; }).join().is_err());
+    assert!(thread::spawn(move|| { min_val::<i8>() / -1; }).join().is_err());
+    assert!(thread::spawn(move|| { min_val::<i16>() / -1; }).join().is_err());
+    assert!(thread::spawn(move|| { min_val::<i32>() / -1; }).join().is_err());
+    assert!(thread::spawn(move|| { min_val::<i64>() / -1; }).join().is_err());
+    assert!(thread::spawn(move|| { 1is / zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i8 / zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i16 / zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i32 / zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i64 / zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { min_val::<isize>() % -1; }).join().is_err());
+    assert!(thread::spawn(move|| { min_val::<i8>() % -1; }).join().is_err());
+    assert!(thread::spawn(move|| { min_val::<i16>() % -1; }).join().is_err());
+    assert!(thread::spawn(move|| { min_val::<i32>() % -1; }).join().is_err());
+    assert!(thread::spawn(move|| { min_val::<i64>() % -1; }).join().is_err());
+    assert!(thread::spawn(move|| { 1is % zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i8 % zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i16 % zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i32 % zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i64 % zero(); }).join().is_err());
 }
diff --git a/src/test/run-pass/issue22008.rs b/src/test/run-pass/issue22008.rs
new file mode 100644 (file)
index 0000000..3e14512
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn main() {
+    let command = "a";
+
+    match command {
+        "foo" => println!("foo"),
+        _     => println!("{}", command),
+    }
+}
index 6c2de471f0f58f90d662a55d1bf9466677e86eac..2aa5a57966672178e924c11630f2cf8fb395cdd2 100644 (file)
@@ -11,6 +11,8 @@
 // These are attributes of the implicit crate. Really this just needs to parse
 // for completeness since .rs files linked from .rc files support this
 // notation to specify their module's attributes
+
+#![feature(custom_attribute)]
 #![allow(unused_attribute)]
 #![attr1 = "val"]
 #![attr2 = "val"]
index 0ba7dcb013be40d3da148507da79f6f21bac3146..5cd741350d57195cd267e0b74a7c7d184c41cf9d 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // ignore-windows
-// ignore-android
 // ignore-macos
 // aux-build:linkage1.rs
 
index 644efe20ded1c0a6895f724b4610527b21bae850..b03c4b5ff47badc1e096c0b85d9298cb9ca0f159 100644 (file)
@@ -13,7 +13,7 @@
 
 use std::cell::Cell;
 use std::fmt;
-use std::thread::Thread;
+use std::thread;
 
 struct Foo(Cell<int>);
 
@@ -27,7 +27,7 @@ fn fmt(&self, _fmt: &mut fmt::Formatter) -> fmt::Result {
 }
 
 pub fn main() {
-    Thread::scoped(move|| {
+    thread::spawn(move|| {
         let mut f = Foo(Cell::new(0));
         println!("{:?}", f);
         let Foo(ref mut f) = f;
index 1be0ee4a285514c4ab5c23db4f92f866a521c083..8526dfe72da134a5c96e16fd7c1459d4db099c56 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android
 // ignore-windows
 // exec-env:RUST_LOG=debug
 
 extern crate log;
 
 use std::old_io::Command;
-use std::os;
+use std::env;
 use std::str;
 
 fn main() {
-    let args = os::args();
-    let args = args;
+    let args: Vec<String> = env::args().collect();
     if args.len() > 1 && args[1] == "child" {
         debug!("foo");
         debug!("bar");
index c015244d520cee80fc484c3ffc7c75825a028d3c..92af96e0d8f2c81068f5958e1bd72ef810c47e73 100644 (file)
@@ -10,6 +10,7 @@
 
 // pp-exact - Make sure we print all the attributes
 #![allow(unused_attribute)]
+#![feature(custom_attribute)]
 
 #[frobable]
 trait frobable {
index c90c6ce87f09d3a712ebdb60b966332d1996aefc..5ce32e4fe2ccb54975d20fe9c3db3dc826ace517 100644 (file)
@@ -10,7 +10,7 @@
 
 // compile-flags: -Z no-landing-pads
 
-use std::thread::Thread;
+use std::thread;
 
 static mut HIT: bool = false;
 
@@ -23,7 +23,7 @@ fn drop(&mut self) {
 }
 
 fn main() {
-    Thread::scoped(move|| -> () {
+    thread::spawn(move|| -> () {
         let _a = A;
         panic!();
     }).join().err().unwrap();
index ca9ee469e38976ec8e49f729de97a428fb17db33..f574259c375fc86886bda5882c28f1987479e760 100644 (file)
@@ -16,7 +16,7 @@
 #![feature(asm)]
 
 use std::old_io::process::Command;
-use std::os;
+use std::env;
 use std::thread::Thread;
 
 // lifted from the test module
@@ -34,8 +34,7 @@ fn recurse() {
 }
 
 fn main() {
-    let args = os::args();
-    let args = args;
+    let args: Vec<String> = env::args().collect();
     if args.len() > 1 && args[1] == "recurse" {
         let _t = Thread::scoped(recurse);
     } else {
index fba86d74816790438fe07d986d7ccf82c49f5ee4..948c4d064d723ef7f9302e763324853c13a14b39 100644 (file)
@@ -17,7 +17,7 @@
 #![feature(asm)]
 
 use std::old_io::process::Command;
-use std::os;
+use std::env;
 
 // lifted from the test module
 // Inlining to avoid llvm turning the recursive functions into tail calls,
@@ -34,7 +34,7 @@ fn recurse() {
 }
 
 fn main() {
-    let args = os::args();
+    let args: Vec<String> = env::args().collect();
     if args.len() > 1 && args[1] == "recurse" {
         recurse();
     } else {
index 7dfd46fb995a207706de5f9326a7c820b1e06275..cc5eb69bb87e39ced535bccb2618f5bf29af23da 100644 (file)
@@ -13,7 +13,7 @@
 #![feature(asm)]
 
 use std::old_io::process::Command;
-use std::os;
+use std::env;
 
 // lifted from the test module
 // Inlining to avoid llvm turning the recursive functions into tail calls,
@@ -34,8 +34,7 @@ fn loud_recurse() {
 }
 
 fn main() {
-    let args = os::args();
-    let args = args;
+    let args: Vec<String> = env::args().collect();
     if args.len() > 1 && args[1] == "silent" {
         silent_recurse();
     } else if args.len() > 1 && args[1] == "loud" {
index 3cc01b967ce6af5d452cc6edad560502e25d7372..6da15b97acaae220453ed519593bd5c2e992251f 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+use std::thread;
 
 static mut dropped: bool = false;
 
@@ -33,7 +33,7 @@ fn drop(&mut self) {
 }
 
 pub fn main() {
-    let ret = Thread::scoped(move|| {
+    let ret = thread::spawn(move|| {
         let _a = A { b: B { foo: 3 } };
     }).join();
     assert!(ret.is_err());
index 15cc128d380db4db7cb62aed971fe25ce7bfb5ce..017784990f4178ece9fcc4dff70c6cbca120b35e 100644 (file)
 use std::old_io::fs;
 use std::old_io::Command;
 use std::os;
+use std::env;
 use std::old_path::Path;
 
 fn main() {
-    let my_args = os::args();
+    let my_args = env::args().collect::<Vec<_>>();
     let my_cwd  = os::getcwd().unwrap();
-    let my_env  = os::env();
+    let my_env  = env::vars().collect::<Vec<_>>();
     let my_path = Path::new(os::self_exe_name().unwrap());
     let my_dir  = my_path.dir_path();
     let my_ext  = my_path.extension_str().unwrap_or("");
index 5330490e54f55394221394d2308a91d9c88218af..0be6e22f60980ac06166b20692752a7103a7fad2 100644 (file)
@@ -72,7 +72,7 @@ pub fn size() -> uint { 16u }
 
 #[cfg(target_os = "android")]
 mod m {
-    #[cfg(target_arch = "arm")]
+    #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
     pub mod m {
         pub fn align() -> uint { 8u }
         pub fn size() -> uint { 16u }
diff --git a/src/test/run-pass/regions-issue-22246.rs b/src/test/run-pass/regions-issue-22246.rs
new file mode 100644 (file)
index 0000000..f5c34d6
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Regression test for issue #22246 -- we should be able to deduce
+// that `&'a B::Owned` implies that `B::Owned : 'a`.
+
+#![allow(dead_code)]
+
+use std::ops::Deref;
+
+pub trait ToOwned {
+    type Owned: Borrow<Self>;
+    fn to_owned(&self) -> Self::Owned;
+}
+
+pub trait Borrow<Borrowed> {
+    fn borrow(&self) -> &Borrowed;
+}
+
+pub struct Foo<B:ToOwned> {
+    owned: B::Owned
+}
+
+fn foo<B:ToOwned>(this: &Foo<B>) -> &B {
+    this.owned.borrow()
+}
+
+fn main() { }
index a2706dca7d3ea3d0edb036e724e9f51479cb1c84..492736c2252a0148612a2e948a6ebb6ceb169bb2 100644 (file)
@@ -9,10 +9,10 @@
 // except according to those terms.
 
 use std::old_io::process::Command;
-use std::os;
+use std::env;
 
 fn main() {
-    let args = os::args();
+    let args: Vec<String> = env::args().collect();
     if args.len() > 1 && args[1] == "segfault" {
         unsafe { *(0 as *mut int) = 1 }; // trigger a segfault
     } else {
diff --git a/src/test/run-pass/send-is-not-static-par-for.rs b/src/test/run-pass/send-is-not-static-par-for.rs
new file mode 100755 (executable)
index 0000000..c6b64d9
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(core, std_misc)]
+use std::thread::Thread;
+use std::sync::Mutex;
+
+fn par_for<I, F>(iter: I, f: F)
+    where I: Iterator,
+          <I as Iterator>::Item: Send,
+          F: Fn(<I as Iterator>::Item) + Sync
+{
+    let f = &f;
+    let _guards: Vec<_> = iter.map(|elem| {
+        Thread::scoped(move || {
+            f(elem)
+        })
+    }).collect();
+
+}
+
+fn sum(x: &[i32]) {
+    let sum_lengths = Mutex::new(0);
+    par_for(x.windows(4), |x| {
+        *sum_lengths.lock().unwrap() += x.len()
+    });
+
+    assert_eq!(*sum_lengths.lock().unwrap(), (x.len() - 3) * 4);
+}
+
+fn main() {
+    let mut elements = [0; 20];
+
+    // iterators over references into this stack frame
+    par_for(elements.iter_mut().enumerate(), |(i, x)| {
+        *x = i as i32
+    });
+
+    sum(&elements)
+}
index ae992a0a358d11b51239398916e2f9b863743625..60093803f0b77745e77c7fde8879d070ab39fbbb 100644 (file)
@@ -16,7 +16,7 @@ struct Command<K, V> {
     val: V
 }
 
-fn cache_server<K:Send,V:Send>(mut tx: Sender<Sender<Command<K, V>>>) {
+fn cache_server<K:Send+'static,V:Send+'static>(mut tx: Sender<Sender<Command<K, V>>>) {
     let (tx1, _rx) = channel();
     tx.send(tx1);
 }
index 6c9707103b9bb91d8026e11eeb7b73e3b807a44d..523b7528103ad55026b10a4306707b69943e052d 100644 (file)
@@ -11,7 +11,7 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-use std::thread::Thread;
+use std::thread;
 
 pub fn main() { test05(); }
 
@@ -25,7 +25,7 @@ fn test05() {
         println!("{}", *three + n); // will copy x into the closure
         assert_eq!(*three, 3);
     };
-    Thread::scoped(move|| {
+    thread::spawn(move|| {
         test05_start(fn_to_send);
     }).join().ok().unwrap();
 }
index 002671ff517a1ff3a93bf67b1a78bd13fbee4761..f0b6a505929c66e9a67bcb6ec08034c3fbdcd4a9 100644 (file)
@@ -11,7 +11,6 @@
 // Check that we can use `-C lto` when linking against libraries that were
 // separately compiled.
 
-// ignore-android linker weridness (see #18800)
 // aux-build:sepcomp_lib.rs
 // compile-flags: -C lto
 // no-prefer-dynamic
index f68dea04a08765f1831c4ccd76acac8ac5ad8df4..21c5a6fc83a123fc54f697b52516677716dfe6fc 100644 (file)
@@ -19,7 +19,7 @@
 // In any case, this test should let us know if enabling parallel codegen ever
 // breaks unwinding.
 
-use std::thread::Thread;
+use std::thread;
 
 fn pad() -> uint { 0 }
 
@@ -36,5 +36,5 @@ pub fn g() {
 }
 
 fn main() {
-    Thread::scoped(move|| { ::b::g() }).join().err().unwrap();
+    thread::spawn(move|| { ::b::g() }).join().err().unwrap();
 }
index 856eb241addc3279eb8131ffb554084ebec1c781..776d897938dd3c5ae556c8043430aae50cd0b90c 100644 (file)
 
 // ignore-windows
 
-use std::os;
+use std::env;
 use std::old_io::process::{Command, ExitSignal, ExitStatus};
 
 pub fn main() {
-    let args = os::args();
-    let args = args;
+    let args: Vec<String> = env::args().collect();
     if args.len() >= 2 && args[1] == "signal" {
         // Raise a segfault.
         unsafe { *(0 as *mut int) = 0; }
index de8f76518fc00c0cbdbe91f0230b2ccd8214dd91..d1428c6be19ef880f06645c74a59908b90dd7b04 100644 (file)
@@ -12,6 +12,7 @@
 // doesn't die in a ball of fire, but rather it's gracefully handled.
 
 use std::os;
+use std::env;
 use std::old_io::PipeStream;
 use std::old_io::Command;
 
@@ -25,8 +26,7 @@ fn test() {
 }
 
 fn main() {
-    let args = os::args();
-    let args = args;
+    let args: Vec<String> = env::args().collect();
     if args.len() > 1 && args[1] == "test" {
         return test();
     }
index b2e3d83ca9b36791513f748c6b3c9e07464c91bf..639ffd56002ec381da9d7c0a10725b0bb11a0193 100644 (file)
@@ -10,7 +10,7 @@
 
 // Test that if a slicing expr[..] fails, the correct cleanups happen.
 
-use std::thread::Thread;
+use std::thread;
 
 struct Foo;
 
@@ -26,6 +26,6 @@ fn foo() {
 }
 
 fn main() {
-    let _ = Thread::scoped(move|| foo()).join();
+    let _ = thread::spawn(move|| foo()).join();
     unsafe { assert!(DTOR_COUNT == 2); }
 }
index dea45e63ab000db72e4614059cc3d40d9e2d60f0..4a2038175d2e63b6ec8bfc7569c41a06813f44d9 100644 (file)
@@ -10,7 +10,7 @@
 
 // Test that if a slicing expr[..] fails, the correct cleanups happen.
 
-use std::thread::Thread;
+use std::thread;
 
 struct Foo;
 
@@ -30,6 +30,6 @@ fn foo() {
 }
 
 fn main() {
-    let _ = Thread::scoped(move|| foo()).join();
+    let _ = thread::spawn(move|| foo()).join();
     unsafe { assert!(DTOR_COUNT == 2); }
 }
index 197890c1277126c1e607c3d4e555dbd7012bdba5..61b2fc8b50f5b6ac13fc49dd14a4aa0368164f52 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android
-
 // Smallest "hello world" with a libc runtime
 
 #![feature(intrinsics, lang_items, start, no_std)]
@@ -34,3 +32,6 @@ fn main(_: int, _: *const *const u8) -> int {
     return 0;
 }
 
+#[cfg(target_os = "android")]
+#[link(name="gcc")]
+extern { }
index eaad2abe8f72e4909c7a541c82be4e155e9079e5..bf2f03b3e6de9bf3da43927036129a99e95d90e4 100644 (file)
@@ -14,7 +14,7 @@
   Arnold.
  */
 
-use std::thread::Thread;
+use std::thread;
 use std::sync::mpsc::{channel, Sender};
 
 type ctx = Sender<int>;
@@ -25,6 +25,6 @@ fn iotask(_tx: &ctx, ip: String) {
 
 pub fn main() {
     let (tx, _rx) = channel::<int>();
-    let t = Thread::scoped(move|| iotask(&tx, "localhost".to_string()) );
+    let t = thread::spawn(move|| iotask(&tx, "localhost".to_string()) );
     t.join().ok().unwrap();
 }
index 8f937afa6b93241ebf5a01316fac9e44256ca702..90b47f4986bfb95ca5726c9220d040ca9184c09c 100644 (file)
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+use std::thread;
 
 pub fn main() {
-    Thread::scoped(move|| child(10)).join().ok().unwrap();
+    thread::spawn(move|| child(10)).join().ok().unwrap();
 }
 
 fn child(i: int) { println!("{}", i); assert!((i == 10)); }
index 75104a4ddef008ebf063383b9d36a94af4981c90..91edb5fd9c1e837e162fd600b7d6e867663b9b0a 100644 (file)
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+use std::thread;
 
 pub fn main() {
-    let t = Thread::scoped(move|| child((10, 20, 30, 40, 50, 60, 70, 80, 90)) );
+    let t = thread::spawn(move|| child((10, 20, 30, 40, 50, 60, 70, 80, 90)) );
     t.join().ok().unwrap();
 }
 
index 5994b24dfdc59334ea8878402808aebf72325c98..1c263b19dd182cb25cba0ada0777b688aaad37df 100644 (file)
@@ -20,9 +20,10 @@ fn main() {
     let mut reader = ChanReader::new(rx);
     let stderr = ChanWriter::new(tx);
 
-    let res = thread::Builder::new().stderr(box stderr as Box<Writer + Send>).scoped(move|| -> () {
+    let res = thread::Builder::new().stderr(box stderr as Box<Writer + Send>)
+                                    .spawn(move|| -> () {
         panic!("Hello, world!")
-    }).join();
+    }).unwrap().join();
     assert!(res.is_err());
 
     let output = reader.read_to_string().unwrap();
index 4df1ff1481042a91b78430029642ee11b0505e09..053df3a57f329361b33707084f23e329b99dc7b8 100644 (file)
@@ -23,7 +23,7 @@
 use std::old_io;
 use std::os;
 use std::sync::mpsc::channel;
-use std::thread::Thread;
+use std::thread;
 
 fn test_tempdir() {
     let path = {
@@ -42,7 +42,7 @@ fn test_rm_tempdir() {
         tx.send(tmp.path().clone()).unwrap();
         panic!("panic to unwind past `tmp`");
     };
-    let _ = Thread::scoped(f).join();
+    thread::spawn(f).join();
     let path = rx.recv().unwrap();
     assert!(!path.exists());
 
@@ -52,7 +52,7 @@ fn test_rm_tempdir() {
         let _tmp = tmp;
         panic!("panic to unwind past `tmp`");
     };
-    let _ = Thread::scoped(f).join();
+    thread::spawn(f).join();
     assert!(!path.exists());
 
     let path;
@@ -61,7 +61,7 @@ fn test_rm_tempdir() {
             TempDir::new("test_rm_tempdir").unwrap()
         };
         // FIXME(#16640) `: TempDir` annotation shouldn't be necessary
-        let tmp: TempDir = Thread::scoped(f).join().ok().expect("test_rm_tmdir");
+        let tmp: TempDir = thread::scoped(f).join();
         path = tmp.path().clone();
         assert!(path.exists());
     }
@@ -85,7 +85,7 @@ fn test_rm_tempdir_close() {
         tmp.close();
         panic!("panic when unwinding past `tmp`");
     };
-    let _ = Thread::scoped(f).join();
+    thread::spawn(f).join();
     let path = rx.recv().unwrap();
     assert!(!path.exists());
 
@@ -96,7 +96,7 @@ fn test_rm_tempdir_close() {
         tmp.close();
         panic!("panic when unwinding past `tmp`");
     };
-    let _ = Thread::scoped(f).join();
+    thread::spawn(f).join();
     assert!(!path.exists());
 
     let path;
@@ -105,7 +105,7 @@ fn test_rm_tempdir_close() {
             TempDir::new("test_rm_tempdir").unwrap()
         };
         // FIXME(#16640) `: TempDir` annotation shouldn't be necessary
-        let tmp: TempDir = Thread::scoped(f).join().ok().expect("test_rm_tmdir");
+        let tmp: TempDir = thread::scoped(f).join();
         path = tmp.path().clone();
         assert!(path.exists());
         tmp.close();
@@ -179,7 +179,7 @@ pub fn test_rmdir_recursive_ok() {
 }
 
 pub fn dont_double_panic() {
-    let r: Result<(), _> = Thread::scoped(move|| {
+    let r: Result<(), _> = thread::spawn(move|| {
         let tmpdir = TempDir::new("test").unwrap();
         // Remove the temporary directory so that TempDir sees
         // an error on drop
index 185edb02cca118debb8206e5ad7bc105952af82c..bef9efa9eb68dc47b99cc01393ab056366732d59 100644 (file)
@@ -12,7 +12,7 @@
 // Issue #787
 // Don't try to clean up uninitialized locals
 
-use std::thread::Thread;
+use std::thread;
 
 fn test_break() { loop { let _x: Box<int> = break; } }
 
 
 fn test_panic() {
     fn f() { let _x: Box<int> = panic!(); }
-    Thread::scoped(move|| f() ).join().err().unwrap();
+    thread::spawn(move|| f() ).join().err().unwrap();
 }
 
 fn test_panic_indirect() {
     fn f() -> ! { panic!(); }
     fn g() { let _x: Box<int> = f(); }
-    Thread::scoped(move|| g() ).join().err().unwrap();
+    thread::spawn(move|| g() ).join().err().unwrap();
 }
 
 pub fn main() {
diff --git a/src/test/run-pass/traits-issue-22110.rs b/src/test/run-pass/traits-issue-22110.rs
new file mode 100644 (file)
index 0000000..9cdcf49
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test an issue where we reported ambiguity between the where-clause
+// and the blanket impl. The only important thing is that compilation
+// succeeds here. Issue #22110.
+
+#![allow(dead_code)]
+
+trait Foo<A> {
+    fn foo(&self, a: A);
+}
+
+impl<A,F:Fn(A)> Foo<A> for F {
+    fn foo(&self, _: A) { }
+}
+
+fn baz<A,F:for<'a> Foo<(&'a A,)>>(_: F) { }
+
+fn components<T,A>(t: fn(&A))
+    where fn(&A) : for<'a> Foo<(&'a A,)>,
+{
+    baz(t)
+}
+
+fn main() {
+}
index f0b634c0d44a752f26a81a464343b9cdec547ad5..08ffe4036962675e5ee10a838fc25770ae176796 100644 (file)
@@ -12,7 +12,7 @@
 #![feature(box_syntax)]
 
 use std::sync::mpsc::{channel, Sender};
-use std::thread::Thread;
+use std::thread;
 
 fn child(tx: &Sender<Box<uint>>, i: uint) {
     tx.send(box i).unwrap();
@@ -25,7 +25,7 @@ pub fn main() {
     let _t = (0u..n).map(|i| {
         expected += i;
         let tx = tx.clone();
-        Thread::scoped(move|| {
+        thread::spawn(move|| {
             child(&tx, i)
         })
     }).collect::<Vec<_>>();
index 0acf736e2ab5c5e8403c0bfd2269a57e8dfa5733..ac46187f03a71d90f09c3859a529b235779a52e7 100644 (file)
@@ -11,7 +11,7 @@
 // Make sure the destructor is run for unit-like structs.
 
 use std::boxed::BoxAny;
-use std::thread::Thread;
+use std::thread;
 
 struct Foo;
 
@@ -22,7 +22,7 @@ fn drop(&mut self) {
 }
 
 pub fn main() {
-    let x = Thread::scoped(move|| {
+    let x = thread::spawn(move|| {
         let _b = Foo;
     }).join();
 
index 159bac101830a4c665c565d0971c97bdf9b443d6..52c09aadfbd7b17a34afa25a7472359f27d0677d 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use std::sync::mpsc::{channel, Sender};
-use std::thread::Thread;
+use std::thread;
 
 struct complainer {
     tx: Sender<bool>,
@@ -37,7 +37,7 @@ fn f(tx: Sender<bool>) {
 
 pub fn main() {
     let (tx, rx) = channel();
-    let _t = Thread::scoped(move|| f(tx.clone()));
+    let _t = thread::spawn(move|| f(tx.clone()));
     println!("hiiiiiiiii");
     assert!(rx.recv().unwrap());
 }
index ea52802d2457857db05c63d8d9eecdf72b4c95e0..d38b6e79eba66bccffd5632e441f5c9c345e31d4 100644 (file)
@@ -11,7 +11,7 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-use std::thread::Thread;
+use std::thread;
 
 fn f() {
     let _a = box 0;
@@ -19,5 +19,5 @@ fn f() {
 }
 
 pub fn main() {
-    let _t = Thread::scoped(f);
+    let _t = thread::spawn(f);
 }
index 88255ad94fd46fb5c6ec44e965886937b18cf014..16dca2db396e7f716d3f13ef35fa5baf1c7eca92 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // pp-exact - Make sure we actually print the attributes
+#![feature(custom_attribute)]
 
 enum crew_of_enterprise_d {
 
index 9e69ecfce4fbea7e967367b496e2f691c582c349..76e7b92ea046b1ae957db05dae51bd9a77c42bdf 100644 (file)
@@ -14,4 +14,9 @@ pub fn main() {
     assert_eq!(vec![1; 2], vec![1, 1]);
     assert_eq!(vec![1; 1], vec![1]);
     assert_eq!(vec![1; 0], vec![]);
+
+    // from_elem syntax (see RFC 832)
+    let el = Box::new(1);
+    let n = 3;
+    assert_eq!(vec![el; n], vec![Box::new(1), Box::new(1), Box::new(1)]);
 }
index d13369b1f5258f9d29dd0a08aa6bd8daa20c5575..da9cf35813b5bd36a3aa0aaddaa02b772b1236d3 100644 (file)
@@ -10,7 +10,7 @@
 
 use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
 use std::rand::{thread_rng, Rng, Rand};
-use std::thread::Thread;
+use std::thread;
 
 const REPEATS: usize = 5;
 const MAX_LEN: usize = 32;
@@ -79,7 +79,7 @@ pub fn main() {
 
                 let v = main.clone();
 
-                let _ = Thread::scoped(move|| {
+                let _ = thread::spawn(move|| {
                     let mut v = v;
                     let mut panic_countdown = panic_countdown;
                     v.sort_by(|a, b| {
index b1c65d322ab2009555e55d08be141b3823a9d722..741e8be02f72c4250d9bfad06ba6d8ac3c797bd7 100644 (file)
 
 extern crate "weak-lang-items" as other;
 
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
-    let _ = Thread::scoped(move|| {
+    let _ = thread::spawn(move|| {
         other::foo()
     });
 }
index 9ad6dd9d2b14213302d6f7e109e776f90d0832f0..45a747509589d85572d18cd8ec40ddd09d502efd 100644 (file)
@@ -8,18 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+use std::thread;
 
 pub fn main() {
-    let mut result = Thread::scoped(child);
+    let mut result = thread::spawn(child);
     println!("1");
-    Thread::yield_now();
+    thread::yield_now();
     println!("2");
-    Thread::yield_now();
+    thread::yield_now();
     println!("3");
     result.join();
 }
 
 fn child() {
-    println!("4"); Thread::yield_now(); println!("5"); Thread::yield_now(); println!("6");
+    println!("4"); thread::yield_now(); println!("5"); thread::yield_now(); println!("6");
 }
index 3d3a36021da1569d405b95fbb4271f28ea9a7ced..69d8431082c2f42995c1479b2dbee192e4d1da29 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+use std::thread;
 
 pub fn main() {
-    let mut result = Thread::scoped(child);
+    let mut result = thread::spawn(child);
     println!("1");
-    Thread::yield_now();
+    thread::yield_now();
     result.join();
 }
 
index 66ad7de0296b1e03ea6f2f8475d0b4c9da955d88..56dc02c6d2e673beab5235236d77d3aa08bf3fc4 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+use std::thread;
 
 pub fn main() {
     let mut i: int = 0;
-    while i < 100 { i = i + 1; println!("{}", i); Thread::yield_now(); }
+    while i < 100 { i = i + 1; println!("{}", i); thread::yield_now(); }
 }