]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #24649 - nham:path_new_examples, r=steveklabnik
authorManish Goregaokar <manishsmail@gmail.com>
Sat, 25 Apr 2015 15:48:47 +0000 (21:18 +0530)
committerManish Goregaokar <manishsmail@gmail.com>
Sat, 25 Apr 2015 15:48:47 +0000 (21:18 +0530)
507 files changed:
configure
mk/main.mk
mk/tests.mk
src/compiletest/runtest.rs
src/doc/grammar.md
src/doc/reference.md
src/doc/style/testing/unit.md
src/doc/trpl/README.md
src/doc/trpl/SUMMARY.md
src/doc/trpl/associated-types.md
src/doc/trpl/attributes.md
src/doc/trpl/casting-between-types.md
src/doc/trpl/closures.md
src/doc/trpl/conditional-compilation.md
src/doc/trpl/const-and-static.md [new file with mode: 0644]
src/doc/trpl/const.md [deleted file]
src/doc/trpl/crates-and-modules.md
src/doc/trpl/debug-and-display.md [deleted file]
src/doc/trpl/deref-coercions.md
src/doc/trpl/enums.md
src/doc/trpl/generics.md
src/doc/trpl/if-let.md
src/doc/trpl/macros.md
src/doc/trpl/match.md
src/doc/trpl/method-syntax.md
src/doc/trpl/mutability.md
src/doc/trpl/operators-and-overloading.md
src/doc/trpl/patterns.md
src/doc/trpl/primitive-types.md
src/doc/trpl/raw-pointers.md [new file with mode: 0644]
src/doc/trpl/slice-patterns.md
src/doc/trpl/static.md [deleted file]
src/doc/trpl/strings.md
src/doc/trpl/structs.md
src/doc/trpl/testing.md
src/doc/trpl/trait-objects.md
src/doc/trpl/traits.md
src/doc/trpl/tuple-structs.md
src/doc/trpl/type-aliases.md
src/doc/trpl/ufcs.md
src/doc/trpl/unsafe-code.md [deleted file]
src/doc/trpl/unsafe.md [new file with mode: 0644]
src/doc/trpl/unsized-types.md
src/doc/trpl/vectors.md
src/etc/mklldeps.py
src/grammar/README.md
src/grammar/RustLexer.g4
src/grammar/check.sh
src/grammar/verify.rs
src/grammar/xidcontinue.g4 [new file with mode: 0644]
src/grammar/xidstart.g4 [new file with mode: 0644]
src/liballoc/arc.rs
src/liballoc/boxed.rs
src/liballoc/heap.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/enum_set.rs
src/libcollections/fmt.rs
src/libcollections/lib.rs
src/libcollections/linked_list.rs
src/libcollections/slice.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollections/vec.rs
src/libcollections/vec_deque.rs
src/libcollections/vec_map.rs
src/libcollectionstest/lib.rs
src/libcollectionstest/str.rs
src/libcore/cmp.rs
src/libcore/convert.rs
src/libcore/default.rs
src/libcore/fmt/float.rs
src/libcore/fmt/mod.rs
src/libcore/fmt/num.rs
src/libcore/hash/mod.rs
src/libcore/hash/sip.rs
src/libcore/iter.rs
src/libcore/lib.rs
src/libcore/marker.rs
src/libcore/nonzero.rs
src/libcore/num/f32.rs
src/libcore/num/f64.rs
src/libcore/num/float_macros.rs
src/libcore/num/mod.rs
src/libcore/num/wrapping.rs
src/libcore/option.rs
src/libcore/prelude.rs
src/libcore/raw.rs
src/libcore/result.rs
src/libcore/slice.rs
src/libcore/str/mod.rs
src/libcoretest/char.rs
src/libcoretest/cmp.rs
src/libcoretest/iter.rs
src/libcoretest/lib.rs
src/libcoretest/num/int_macros.rs
src/libcoretest/num/mod.rs
src/libcoretest/num/uint_macros.rs
src/libgetopts/lib.rs
src/liblibc/lib.rs
src/librand/chacha.rs
src/librand/distributions/exponential.rs
src/librand/distributions/gamma.rs
src/librand/distributions/mod.rs
src/librand/distributions/range.rs
src/librand/isaac.rs
src/librand/reseeding.rs
src/librbml/lib.rs
src/librustc/diagnostics.rs
src/librustc/lib.rs
src/librustc/macros.rs [new file with mode: 0644]
src/librustc/metadata/common.rs
src/librustc/metadata/cstore.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/loader.rs
src/librustc/middle/astencode.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/free_region.rs [new file with mode: 0644]
src/librustc/middle/implicator.rs [new file with mode: 0644]
src/librustc/middle/infer/mod.rs
src/librustc/middle/infer/region_inference/mod.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/stability.rs
src/librustc/middle/traits/mod.rs
src/librustc/middle/traits/select.rs
src/librustc/middle/ty.rs
src/librustc/session/config.rs
src/librustc/util/num.rs [new file with mode: 0644]
src/librustc_back/archive.rs
src/librustc_back/fs.rs
src/librustc_back/lib.rs
src/librustc_back/rpath.rs
src/librustc_back/sha2.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_data_structures/graph/mod.rs
src/librustc_data_structures/graph/test.rs [deleted file]
src/librustc_data_structures/graph/tests.rs [new file with mode: 0644]
src/librustc_data_structures/lib.rs
src/librustc_data_structures/unify/mod.rs
src/librustc_data_structures/unify/test.rs [deleted file]
src/librustc_data_structures/unify/tests.rs [new file with mode: 0644]
src/librustc_driver/test.rs
src/librustc_lint/builtin.rs
src/librustc_llvm/archive_ro.rs
src/librustc_llvm/lib.rs
src/librustc_resolve/lib.rs
src/librustc_trans/back/lto.rs
src/librustc_trans/back/write.rs
src/librustc_trans/trans/adt.rs
src/librustc_trans/trans/asm.rs
src/librustc_trans/trans/context.rs
src/librustc_trans/trans/debuginfo.rs
src/librustc_trans/trans/intrinsic.rs
src/librustc_trans/trans/type_of.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/implicator.rs [deleted file]
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/collect.rs
src/librustc_unicode/lib.rs
src/librustc_unicode/u_str.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/main.js
src/librustdoc/html/toc.rs
src/librustdoc/lib.rs
src/libserialize/hex.rs
src/libserialize/json.rs
src/libstd/ascii.rs
src/libstd/collections/hash/map.rs
src/libstd/collections/hash/set.rs
src/libstd/collections/hash/table.rs
src/libstd/dynamic_lib.rs
src/libstd/env.rs
src/libstd/ffi/mod.rs
src/libstd/ffi/os_str.rs
src/libstd/fs.rs
src/libstd/io/buffered.rs
src/libstd/io/error.rs
src/libstd/io/stdio.rs
src/libstd/io/util.rs
src/libstd/lib.rs
src/libstd/net/mod.rs
src/libstd/num/f32.rs
src/libstd/num/f64.rs
src/libstd/num/mod.rs
src/libstd/num/strconv.rs [deleted file]
src/libstd/num/uint_macros.rs
src/libstd/panicking.rs
src/libstd/path.rs
src/libstd/prelude/v1.rs
src/libstd/rand/os.rs
src/libstd/rand/reader.rs
src/libstd/rt/backtrace.rs
src/libstd/rt/util.rs
src/libstd/sync/condvar.rs
src/libstd/sync/future.rs
src/libstd/sync/mpsc/mod.rs
src/libstd/sync/mpsc/select.rs
src/libstd/sync/mpsc/spsc_queue.rs
src/libstd/sync/mutex.rs
src/libstd/sync/once.rs
src/libstd/sys/common/net.rs [deleted file]
src/libstd/sys/common/net2.rs
src/libstd/sys/common/remutex.rs
src/libstd/sys/common/thread.rs
src/libstd/sys/common/wtf8.rs
src/libstd/sys/unix/condvar.rs
src/libstd/sys/unix/ext.rs
src/libstd/sys/unix/fs2.rs
src/libstd/sys/unix/helper_signal.rs [deleted file]
src/libstd/sys/unix/mod.rs
src/libstd/sys/unix/process2.rs
src/libstd/sys/unix/thread.rs
src/libstd/sys/windows/c.rs
src/libstd/sys/windows/ext.rs
src/libstd/sys/windows/fs2.rs
src/libstd/sys/windows/mod.rs
src/libstd/sys/windows/net.rs
src/libstd/sys/windows/process2.rs
src/libstd/sys/windows/thread.rs
src/libstd/thread/mod.rs
src/libstd/time/duration.rs
src/libstd/tuple.rs
src/libsyntax/ast.rs
src/libsyntax/ast_util.rs
src/libsyntax/codemap.rs
src/libsyntax/config.rs
src/libsyntax/diagnostic.rs
src/libsyntax/diagnostics/plugin.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/deriving/cmp/ord.rs
src/libsyntax/ext/deriving/cmp/partial_eq.rs
src/libsyntax/ext/deriving/cmp/partial_ord.rs
src/libsyntax/ext/deriving/decodable.rs
src/libsyntax/ext/deriving/encodable.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/deriving/generic/ty.rs
src/libsyntax/ext/deriving/hash.rs
src/libsyntax/ext/deriving/primitive.rs
src/libsyntax/ext/deriving/show.rs
src/libsyntax/ext/expand.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/ext/tt/transcribe.rs
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/lib.rs
src/libsyntax/parse/lexer/comments.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pp.rs
src/libsyntax/print/pprust.rs
src/libsyntax/ptr.rs
src/libsyntax/str.rs [new file with mode: 0644]
src/libsyntax/util/parser_testing.rs
src/libsyntax/util/small_vector.rs
src/libterm/terminfo/parm.rs
src/libterm/terminfo/parser/compiled.rs
src/libtest/lib.rs
src/libtest/stats.rs
src/rust-installer
src/rustbook/javascript.rs
src/rustllvm/ExecutionEngineWrapper.cpp
src/rustllvm/PassWrapper.cpp
src/rustllvm/RustWrapper.cpp
src/rustllvm/rustllvm.h
src/test/auxiliary/issue_3907.rs
src/test/auxiliary/linkage-visibility.rs
src/test/auxiliary/private_trait_xc.rs
src/test/auxiliary/rustdoc-default-impl.rs
src/test/auxiliary/svh-a-base.rs
src/test/auxiliary/svh-a-change-lit.rs
src/test/auxiliary/svh-a-change-significant-cfg.rs
src/test/auxiliary/svh-a-change-trait-bound.rs
src/test/auxiliary/svh-a-change-type-arg.rs
src/test/auxiliary/svh-a-change-type-ret.rs
src/test/auxiliary/svh-a-change-type-static.rs
src/test/auxiliary/svh-a-comment.rs
src/test/auxiliary/svh-a-doc.rs
src/test/auxiliary/svh-a-macro.rs
src/test/auxiliary/svh-a-no-change.rs
src/test/auxiliary/svh-a-redundant-cfg.rs
src/test/auxiliary/svh-a-whitespace.rs
src/test/auxiliary/trait_impl_conflict.rs
src/test/auxiliary/typeck_default_trait_impl_cross_crate_coherence_lib.rs
src/test/bench/core-std.rs
src/test/bench/msgsend-ring-mutex-arcs.rs
src/test/bench/noise.rs
src/test/bench/shootout-binarytrees.rs
src/test/bench/shootout-fasta.rs
src/test/bench/shootout-nbody.rs
src/test/bench/shootout-spectralnorm.rs
src/test/bench/sudoku.rs
src/test/compile-fail-fulldeps/macro-crate-rlib.rs
src/test/compile-fail/associated-types-eq-expr-path.rs
src/test/compile-fail/associated-types-issue-17359.rs
src/test/compile-fail/associated-types-multiple-types-one-trait.rs
src/test/compile-fail/associated-types-no-suitable-supertrait-2.rs
src/test/compile-fail/associated-types-no-suitable-supertrait.rs
src/test/compile-fail/associated-types-unconstrained.rs
src/test/compile-fail/bad-sized.rs
src/test/compile-fail/cast-to-unsized-trait-object-suggestion.rs [new file with mode: 0644]
src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs
src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs
src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs
src/test/compile-fail/coherence-default-trait-impl.rs
src/test/compile-fail/coherence_copy_like_err_fundamental_struct_tuple.rs
src/test/compile-fail/coherence_copy_like_err_struct.rs
src/test/compile-fail/coherence_copy_like_err_tuple.rs
src/test/compile-fail/dst-bad-coerce2.rs
src/test/compile-fail/dst-bad-coercions.rs
src/test/compile-fail/feature-gate-negate-unsigned.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-on-unimplemented.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-optin-builtin-traits.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-plugin.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-rustc-attrs.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-rustc-diagnostic-macros.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-slice-patterns.rs [new file with mode: 0644]
src/test/compile-fail/gated-box-patterns.rs [deleted file]
src/test/compile-fail/gated-simd-ffi.rs [deleted file]
src/test/compile-fail/implicit-method-bind.rs
src/test/compile-fail/issue-13853.rs
src/test/compile-fail/issue-14853.rs
src/test/compile-fail/issue-16747.rs
src/test/compile-fail/issue-17441.rs
src/test/compile-fail/issue-18107.rs
src/test/compile-fail/issue-18389.rs
src/test/compile-fail/issue-18611.rs
src/test/compile-fail/issue-18819.rs
src/test/compile-fail/issue-2063.rs
src/test/compile-fail/issue-20831-debruijn.rs
src/test/compile-fail/issue-23080-2.rs
src/test/compile-fail/issue-3702-2.rs
src/test/compile-fail/issue-5035-2.rs
src/test/compile-fail/issue-5883.rs
src/test/compile-fail/issue-6702.rs
src/test/compile-fail/issue-7575.rs
src/test/compile-fail/kindck-copy.rs
src/test/compile-fail/kindck-impl-type-params-2.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/lint-visible-private-types.rs
src/test/compile-fail/loop-labeled-break-value.rs
src/test/compile-fail/loops-reject-duplicate-labels-2.rs [new file with mode: 0644]
src/test/compile-fail/loops-reject-duplicate-labels.rs [new file with mode: 0644]
src/test/compile-fail/loops-reject-labels-shadowing-lifetimes.rs [new file with mode: 0644]
src/test/compile-fail/loops-reject-lifetime-shadowing-label.rs [new file with mode: 0644]
src/test/compile-fail/object-does-not-impl-trait.rs
src/test/compile-fail/object-safety-no-static.rs
src/test/compile-fail/phantom-oibit.rs
src/test/compile-fail/privacy-ns2.rs
src/test/compile-fail/region-bound-extra-bound-in-impl.rs [new file with mode: 0644]
src/test/compile-fail/region-bound-extra-bound-in-inherent-impl.rs [new file with mode: 0644]
src/test/compile-fail/region-bound-same-bounds-in-trait-and-impl.rs [new file with mode: 0644]
src/test/compile-fail/region-object-lifetime-in-coercion.rs
src/test/compile-fail/regions-bound-missing-bound-in-impl.rs
src/test/compile-fail/regions-close-associated-type-into-object.rs
src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs
src/test/compile-fail/shadowed-lifetime.rs
src/test/compile-fail/stability-attribute-non-staged.rs
src/test/compile-fail/trait-as-struct-constructor.rs
src/test/compile-fail/trait-bounds-on-structs-and-enums.rs
src/test/compile-fail/trait-bounds-sugar.rs
src/test/compile-fail/trait-impl-1.rs
src/test/compile-fail/trait-object-reference-without-parens-suggestion.rs [new file with mode: 0644]
src/test/compile-fail/type-params-in-different-spaces-1.rs
src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs
src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs
src/test/compile-fail/typeck-default-trait-impl-negation.rs
src/test/compile-fail/typeck-default-trait-impl-precedence.rs
src/test/compile-fail/typeck-default-trait-impl-superregion.rs
src/test/compile-fail/typeck-default-trait-impl-supertrait.rs
src/test/compile-fail/typeck-default-trait-impl-trait-where-clause.rs
src/test/compile-fail/unsized6.rs
src/test/compile-fail/unsized7.rs
src/test/compile-fail/utf8_idents.rs
src/test/debuginfo/issue13213.rs
src/test/parse-fail/parenthesized-box-expr-message.rs
src/test/pretty/block-comment-wchar.pp
src/test/pretty/block-comment-wchar.rs
src/test/pretty/default-trait-impl.rs
src/test/run-make/archive-duplicate-names/Makefile [new file with mode: 0644]
src/test/run-make/archive-duplicate-names/bar.c [new file with mode: 0644]
src/test/run-make/archive-duplicate-names/bar.rs [new file with mode: 0644]
src/test/run-make/archive-duplicate-names/foo.c [new file with mode: 0644]
src/test/run-make/archive-duplicate-names/foo.rs [new file with mode: 0644]
src/test/run-make/cannot-read-embedded-idents/create_and_compile.rs
src/test/run-make/extern-fn-reachable/main.rs
src/test/run-make/save-analysis/foo.rs
src/test/run-make/simd-ffi/Makefile
src/test/run-pass-fulldeps/compiler-calls.rs
src/test/run-pass-fulldeps/create-dir-all-bare.rs
src/test/run-pass-fulldeps/issue-15149.rs
src/test/run-pass-fulldeps/issue-16992.rs
src/test/run-pass-fulldeps/issue-18763-quote-token-tree.rs
src/test/run-pass-fulldeps/qquote.rs
src/test/run-pass-fulldeps/quote-tokens.rs
src/test/run-pass-fulldeps/quote-unused-sp-no-warning.rs
src/test/run-pass-fulldeps/rename-directory.rs
src/test/run-pass/associated-types-basic.rs
src/test/run-pass/associated-types-issue-20371.rs
src/test/run-pass/associated-types-nested-projections.rs
src/test/run-pass/associated-types-normalize-in-bounds-binding.rs
src/test/run-pass/associated-types-project-from-type-param-via-bound-in-where-clause.rs
src/test/run-pass/byte-literals.rs
src/test/run-pass/closure-reform.rs
src/test/run-pass/const-binops.rs
src/test/run-pass/default-method-supertrait-vtable.rs
src/test/run-pass/derive-no-std.rs
src/test/run-pass/deriving-primitive.rs [deleted file]
src/test/run-pass/drop-with-type-ascription-1.rs
src/test/run-pass/early-ret-binop-add.rs
src/test/run-pass/exponential-notation.rs [deleted file]
src/test/run-pass/extern-methods.rs
src/test/run-pass/float-nan.rs
src/test/run-pass/hygienic-labels-in-let.rs
src/test/run-pass/hygienic-labels.rs
src/test/run-pass/ifmt.rs
src/test/run-pass/intrinsics-math.rs
src/test/run-pass/issue-10626.rs
src/test/run-pass/issue-11736.rs
src/test/run-pass/issue-11881.rs
src/test/run-pass/issue-12582.rs
src/test/run-pass/issue-13027.rs
src/test/run-pass/issue-13105.rs
src/test/run-pass/issue-14940.rs
src/test/run-pass/issue-16597.rs
src/test/run-pass/issue-21245.rs
src/test/run-pass/issue-2718.rs
src/test/run-pass/issue-3683.rs
src/test/run-pass/issue-4759-1.rs
src/test/run-pass/issue-5280.rs
src/test/run-pass/issue-5321-immediates-with-bare-self.rs
src/test/run-pass/issue-8460.rs
src/test/run-pass/lexer-crlf-line-endings-string-literal-doc-comment.rs
src/test/run-pass/linkage-visibility.rs
src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs
src/test/run-pass/logging-separate-lines.rs
src/test/run-pass/match-range.rs
src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs
src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs
src/test/run-pass/multibyte.rs
src/test/run-pass/numeric-method-autoexport.rs
src/test/run-pass/overloaded-autoderef.rs
src/test/run-pass/process-spawn-with-unicode-params.rs
src/test/run-pass/raw-str.rs
src/test/run-pass/running-with-no-runtime.rs
src/test/run-pass/shebang.rs
src/test/run-pass/struct-return.rs
src/test/run-pass/syntax-trait-polarity.rs
src/test/run-pass/task-stderr.rs
src/test/run-pass/trait-bounds-basic.rs
src/test/run-pass/trait-bounds-on-structs-and-enums.rs
src/test/run-pass/trait-bounds-recursion.rs
src/test/run-pass/trait-coercion.rs
src/test/run-pass/trait-inheritance-num.rs
src/test/run-pass/trait-inheritance-num0.rs
src/test/run-pass/trait-inheritance-num1.rs
src/test/run-pass/trait-inheritance-num2.rs
src/test/run-pass/trait-inheritance-num3.rs
src/test/run-pass/trait-inheritance-num5.rs
src/test/run-pass/trait-inheritance-self-in-supertype.rs
src/test/run-pass/trait-inheritance-static2.rs
src/test/run-pass/trait-to-str.rs
src/test/run-pass/trait-with-bounds-default.rs
src/test/run-pass/traits-default-method-self.rs
src/test/run-pass/traits-default-method-trivial.rs
src/test/run-pass/unboxed-closures-infer-argument-types-from-expected-bound.rs
src/test/run-pass/unboxed-closures-infer-argument-types-from-expected-object-type.rs
src/test/run-pass/unboxed-closures-infer-argument-types-with-bound-regions-from-expected-bound.rs
src/test/run-pass/unsized.rs
src/test/run-pass/unsized2.rs
src/test/run-pass/utf8-bom.rs
src/test/run-pass/utf8.rs
src/test/run-pass/utf8_chars.rs
src/test/run-pass/utf8_idents.rs
src/test/rustdoc/default-impl.rs
src/test/rustdoc/extern-default-method.rs
src/test/rustdoc/extern-method.rs
src/test/rustdoc/ffi.rs
src/test/rustdoc/inline-default-methods.rs
src/test/rustdoc/issue-13698.rs
src/test/rustdoc/issue-15318-2.rs
src/test/rustdoc/issue-15318.rs
src/test/rustdoc/issue-17476.rs
src/test/rustdoc/issue-19190-3.rs
src/test/rustdoc/issue-20646.rs
src/test/rustdoc/issue-20727-2.rs
src/test/rustdoc/issue-20727-3.rs
src/test/rustdoc/issue-20727-4.rs
src/test/rustdoc/issue-20727.rs
src/test/rustdoc/issue-21092.rs
src/test/rustdoc/issue-21801.rs
src/test/rustdoc/issue-22025.rs
src/test/rustdoc/issue-23207.rs

index 18fef588936e7ff0b3f1e9ac5fe0013493f2ae04..fc8d57999ffde2415fb36319bcca40f0194cd1ad 100755 (executable)
--- a/configure
+++ b/configure
@@ -337,6 +337,15 @@ to_gnu_triple() {
     esac
 }
 
+# Prints the absolute path of a directory to stdout
+abs_path() {
+    local _path="$1"
+    # Unset CDPATH because it causes havok: it makes the destination unpredictable
+    # and triggers 'cd' to print the path to stdout. Route `cd`'s output to /dev/null
+    # for good measure.
+    (unset CDPATH && cd "$_path" > /dev/null && pwd)
+}
+
 msg "looking for configure programs"
 need_cmd cmp
 need_cmd mkdir
@@ -509,7 +518,7 @@ fi
 
 DEFAULT_BUILD="${CFG_CPUTYPE}-${CFG_OSTYPE}"
 
-CFG_SRC_DIR="$(cd $(dirname $0) && pwd)/"
+CFG_SRC_DIR="$(abs_path $(dirname $0))/"
 CFG_BUILD_DIR="$(pwd)/"
 CFG_SELF="$0"
 CFG_CONFIGURE_ARGS="$@"
index c5b2fc8b9531ed5ac691b2a56c3eb8561b895a8a..c1ce1051d0a86ca7c7d34275b091197016ea1495 100644 (file)
 ######################################################################
 
 # The version number
-CFG_RELEASE_NUM=1.0.0
+CFG_RELEASE_NUM=1.1.0
 
 # An optional number to put after the label, e.g. '.2' -> '-beta.2'
 # NB Make sure it starts with a dot to conform to semver pre-release
 # versions (section 9)
-CFG_PRERELEASE_VERSION=.3
+CFG_PRERELEASE_VERSION=.1
 
 CFG_FILENAME_EXTRA=4e7c5e5c
 
@@ -30,8 +30,12 @@ CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)
 CFG_DISABLE_UNSTABLE_FEATURES=1
 endif
 ifeq ($(CFG_RELEASE_CHANNEL),beta)
-CFG_RELEASE=$(CFG_RELEASE_NUM)-beta$(CFG_PRERELEASE_VERSION)
-CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-beta$(CFG_PRERELEASE_VERSION)
+CFG_RELEASE=$(CFG_RELEASE_NUM)-beta
+# When building beta distributables just reuse the same "beta" name
+# so when we upload we'll always override the previous beta. This
+# doesn't actually impact the version reported by rustc - it's just
+# for file naming.
+CFG_PACKAGE_VERS=beta
 CFG_DISABLE_UNSTABLE_FEATURES=1
 endif
 ifeq ($(CFG_RELEASE_CHANNEL),nightly)
index 0de622f12ea5974a41fec12bf7a37fbbc1b4ca88..5d100958edc92296565b17a382efd439fcfd3fd4 100644 (file)
@@ -753,13 +753,6 @@ PRETTY_DEPS_pretty-rpass-full = $(RPASS_FULL_TESTS)
 PRETTY_DEPS_pretty-rfail = $(RFAIL_TESTS)
 PRETTY_DEPS_pretty-bench = $(BENCH_TESTS)
 PRETTY_DEPS_pretty-pretty = $(PRETTY_TESTS)
-# The stage- and host-specific dependencies are for e.g. macro_crate_test which pulls in
-# external crates.
-PRETTY_DEPS$(1)_H_$(3)_pretty-rpass =
-PRETTY_DEPS$(1)_H_$(3)_pretty-rpass-full = $$(HLIB$(1)_H_$(3))/stamp.syntax $$(HLIB$(1)_H_$(3))/stamp.rustc
-PRETTY_DEPS$(1)_H_$(3)_pretty-rfail =
-PRETTY_DEPS$(1)_H_$(3)_pretty-bench =
-PRETTY_DEPS$(1)_H_$(3)_pretty-pretty =
 PRETTY_DIRNAME_pretty-rpass = run-pass
 PRETTY_DIRNAME_pretty-rpass-valgrind = run-pass-valgrind
 PRETTY_DIRNAME_pretty-rpass-full = run-pass-fulldeps
@@ -767,6 +760,15 @@ PRETTY_DIRNAME_pretty-rfail = run-fail
 PRETTY_DIRNAME_pretty-bench = bench
 PRETTY_DIRNAME_pretty-pretty = pretty
 
+define DEF_PRETTY_FULLDEPS
+PRETTY_DEPS$(1)_T_$(2)_H_$(3)_pretty-rpass-full = $$(CSREQ$(1)_T_$(3)_H_$(3))
+endef
+
+$(foreach host,$(CFG_HOST), \
+ $(foreach target,$(CFG_TARGET), \
+  $(foreach stage,$(STAGES), \
+   $(eval $(call DEF_PRETTY_FULLDEPS,$(stage),$(target),$(host))))))
+
 define DEF_RUN_PRETTY_TEST
 
 PRETTY_ARGS$(1)-T-$(2)-H-$(3)-$(4) := \
@@ -780,7 +782,7 @@ check-stage$(1)-T-$(2)-H-$(3)-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4
 $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
                $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
                $$(PRETTY_DEPS_$(4)) \
-               $$(PRETTY_DEPS$(1)_H_$(3)_$(4))
+               $$(PRETTY_DEPS$(1)_T_$(2)_H_$(3)_$(4))
        @$$(call E, run pretty-rpass [$(2)]: $$<)
        $$(Q)touch $$@.start_time
        $$(Q)$$(call CFG_RUN_CTEST_$(2),$(1),$$<,$(3)) \
index 8ae3639318291a723692c76bf675785458784401..3d4aebad9d69f7d9965de858b7c8601033338047 100644 (file)
@@ -979,6 +979,7 @@ fn continuation( line: &str) -> bool {
     // is the ending point, and * represents ANSI color codes.
     for line in proc_res.stderr.lines() {
         let mut was_expected = false;
+        let mut prev = 0;
         for (i, ee) in expected_errors.iter().enumerate() {
             if !found_flags[i] {
                 debug!("prefix={} ee.kind={} ee.msg={} line={}",
@@ -986,6 +987,17 @@ fn continuation( line: &str) -> bool {
                        ee.kind,
                        ee.msg,
                        line);
+                // Suggestions have no line number in their output, so take on the line number of
+                // the previous expected error
+                if ee.kind == "suggestion" {
+                    assert!(expected_errors[prev].kind == "help",
+                            "SUGGESTIONs must be preceded by a HELP");
+                    if line.contains(&ee.msg) {
+                        found_flags[i] = true;
+                        was_expected = true;
+                        break;
+                    }
+                }
                 if (prefix_matches(line, &prefixes[i]) || continuation(line)) &&
                     line.contains(&ee.kind) &&
                     line.contains(&ee.msg) {
@@ -994,6 +1006,7 @@ fn continuation( line: &str) -> bool {
                     break;
                 }
             }
+            prev = i;
         }
 
         // ignore this msg which gets printed at the end
@@ -1452,7 +1465,7 @@ fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> PathBuf {
 fn aux_output_dir_name(config: &Config, testfile: &Path) -> PathBuf {
     let f = output_base_name(config, testfile);
     let mut fname = f.file_name().unwrap().to_os_string();
-    fname.push("libaux");
+    fname.push(&format!(".{}.libaux", config.mode));
     f.with_file_name(&fname)
 }
 
index 3d9a5bafbd71ea2dba50df0c8c52d4fccd053edb..542815e7afe3ce8522cf278692e2bacfd0f1c1a0 100644 (file)
@@ -152,19 +152,19 @@ token : simple_token | ident | literal | symbol | whitespace token ;
 
 <p id="keyword-table-marker"></p>
 
-|          |          |          |          |        |
-|----------|----------|----------|----------|--------|
-| abstract | alignof  | as       | become   | box    |
-| break    | const    | continue | crate    | do     |
-| else     | enum     | extern   | false    | final  |
-| fn       | for      | if       | impl     | in     |
-| let      | loop     | match    | mod      | move   |
-| mut      | offsetof | once     | override | priv   |
-| proc     | pub      | pure     | ref      | return |
-| sizeof   | static   | self     | struct   | super  |
-| true     | trait    | type     | typeof   | unsafe |
-| unsized  | use      | virtual  | where    | while  |
-| yield    |          |          |          |        |
+|          |          |          |          |         |
+|----------|----------|----------|----------|---------|
+| abstract | alignof  | as       | become   | box     |
+| break    | const    | continue | crate    | do      |
+| else     | enum     | extern   | false    | final   |
+| fn       | for      | if       | impl     | in      |
+| let      | loop     | macro    | match    | mod     |
+| move     | mut      | offsetof | override | priv    |
+| proc     | pub      | pure     | ref      | return  |
+| Self     | self     | sizeof   | static   | struct  |
+| super    | trait    | true     | type     | typeof  |
+| unsafe   | unsized  | use      | virtual  | where   |
+| while    | yield    |          |          |         |
 
 
 Each of these keywords has special meaning in its grammar, and all of them are
@@ -524,6 +524,15 @@ array_elems : [expr [',' expr]*] | [expr ',' ".." expr] ;
 idx_expr : expr '[' expr ']' ;
 ```
 
+### Range expressions
+
+```antlr
+range_expr : expr ".." expr |
+             expr ".." |
+             ".." expr |
+             ".." ;
+```
+
 ### Unary operator expressions
 
 **FIXME:** grammar?
@@ -610,7 +619,7 @@ lambda_expr : '|' ident_list '|' expr ;
 ### While loops
 
 ```antlr
-while_expr : "while" no_struct_literal_expr '{' block '}' ;
+while_expr : [ lifetime ':' ] "while" no_struct_literal_expr '{' block '}' ;
 ```
 
 ### Infinite loops
@@ -634,7 +643,7 @@ continue_expr : "continue" [ lifetime ];
 ### For expressions
 
 ```antlr
-for_expr : "for" pat "in" no_struct_literal_expr '{' block '}' ;
+for_expr : [ lifetime ':' ] "for" pat "in" no_struct_literal_expr '{' block '}' ;
 ```
 
 ### If expressions
index c159f6164c20554f4b19f973357dfeb7b67d3691..13f5e391e4239ff4b08d0d1d6369dccc87b02308 100644 (file)
@@ -29,46 +29,11 @@ You may also be interested in the [grammar].
 
 # Notation
 
-Rust's grammar is defined over Unicode codepoints, each conventionally denoted
-`U+XXXX`, for 4 or more hexadecimal digits `X`. _Most_ of Rust's grammar is
-confined to the ASCII range of Unicode, and is described in this document by a
-dialect of Extended Backus-Naur Form (EBNF), specifically a dialect of EBNF
-supported by common automated LL(k) parsing tools such as `llgen`, rather than
-the dialect given in ISO 14977. The dialect can be defined self-referentially
-as follows:
-
-```{.ebnf .notation}
-grammar : rule + ;
-rule    : nonterminal ':' productionrule ';' ;
-productionrule : production [ '|' production ] * ;
-production : term * ;
-term : element repeats ;
-element : LITERAL | IDENTIFIER | '[' productionrule ']' ;
-repeats : [ '*' | '+' ] NUMBER ? | NUMBER ? | '?' ;
-```
-
-Where:
-
-- Whitespace in the grammar is ignored.
-- Square brackets are used to group rules.
-- `LITERAL` is a single printable ASCII character, or an escaped hexadecimal
-  ASCII code of the form `\xQQ`, in single quotes, denoting the corresponding
-  Unicode codepoint `U+00QQ`.
-- `IDENTIFIER` is a nonempty string of ASCII letters and underscores.
-- The `repeat` forms apply to the adjacent `element`, and are as follows:
-  - `?` means zero or one repetition
-  - `*` means zero or more repetitions
-  - `+` means one or more repetitions
-  - NUMBER trailing a repeat symbol gives a maximum repetition count
-  - NUMBER on its own gives an exact repetition count
-
-This EBNF dialect should hopefully be familiar to many readers.
-
 ## Unicode productions
 
-A few productions in Rust's grammar permit Unicode codepoints outside the ASCII
+A few productions in Rust's grammar permit Unicode code points outside the ASCII
 range. We define these productions in terms of character properties specified
-in the Unicode standard, rather than in terms of ASCII-range codepoints. The
+in the Unicode standard, rather than in terms of ASCII-range code points. The
 section [Special Unicode Productions](#special-unicode-productions) lists these
 productions.
 
@@ -91,10 +56,10 @@ production. See [tokens](#tokens) for more information.
 
 ## Input format
 
-Rust input is interpreted as a sequence of Unicode codepoints encoded in UTF-8.
+Rust input is interpreted as a sequence of Unicode code points encoded in UTF-8.
 Most Rust grammar rules are defined in terms of printable ASCII-range
-codepoints, but a small number are defined in terms of Unicode properties or
-explicit codepoint lists. [^inputformat]
+code points, but a small number are defined in terms of Unicode properties or
+explicit code point lists. [^inputformat]
 
 [^inputformat]: Substitute definitions for the special Unicode productions are
   provided to the grammar verifier, restricted to ASCII range, when verifying the
@@ -132,13 +97,6 @@ Some productions are defined by exclusion of particular Unicode characters:
 
 ## Comments
 
-```{.ebnf .gram}
-comment : block_comment | line_comment ;
-block_comment : "/*" block_comment_body * "*/" ;
-block_comment_body : [block_comment | character] * ;
-line_comment : "//" non_eol * ;
-```
-
 Comments in Rust code follow the general C++ style of line and block-comment
 forms. Nested block comments are supported.
 
@@ -147,21 +105,18 @@ comments beginning with exactly one repeated asterisk in the block-open
 sequence (`/**`), are interpreted as a special syntax for `doc`
 [attributes](#attributes). That is, they are equivalent to writing
 `#[doc="..."]` around the body of the comment (this includes the comment
-characters themselves, ie `/// Foo` turns into `#[doc="/// Foo"]`).
+characters themselves, i.e. `/// Foo` turns into `#[doc="/// Foo"]`).
 
-`//!` comments apply to the parent of the comment, rather than the item that
-follows. `//!` comments are usually used to display information on the crate
-index page.
+Line comments beginning with `//!` and block comments beginning with `/*!` are
+doc comments that apply to the parent of the comment, rather than the item
+that follows.  That is, they are equivalent to writing `#![doc="..."]` around
+the body of the comment. `//!` comments are usually used to display
+information on the crate index page.
 
 Non-doc comments are interpreted as a form of whitespace.
 
 ## Whitespace
 
-```{.ebnf .gram}
-whitespace_char : '\x20' | '\x09' | '\x0a' | '\x0d' ;
-whitespace : [ whitespace_char | comment ] + ;
-```
-
 The `whitespace_char` production is any nonempty Unicode string consisting of
 any of the following Unicode characters: `U+0020` (space, `' '`), `U+0009`
 (tab, `'\t'`), `U+000A` (LF, `'\n'`), `U+000D` (CR, `'\r'`).
@@ -174,40 +129,11 @@ with any other legal whitespace element, such as a single space character.
 
 ## Tokens
 
-```{.ebnf .gram}
-simple_token : keyword | unop | binop ;
-token : simple_token | ident | literal | symbol | whitespace token ;
-```
-
 Tokens are primitive productions in the grammar defined by regular
 (non-recursive) languages. "Simple" tokens are given in [string table
 production](#string-table-productions) form, and occur in the rest of the
 grammar as double-quoted strings. Other tokens have exact rules given.
 
-### Keywords
-
-<p id="keyword-table-marker"></p>
-
-|          |          |          |          |         |
-|----------|----------|----------|----------|---------|
-| abstract | alignof  | as       | become   | box     |
-| break    | const    | continue | crate    | do      |
-| else     | enum     | extern   | false    | final   |
-| fn       | for      | if       | impl     | in      |
-| let      | loop     | macro    | match    | mod     |
-| move     | mut      | offsetof | override | priv    |
-| pub      | pure     | ref      | return   | sizeof  |
-| static   | self     | struct   | super    | true    |
-| trait    | type     | typeof   | unsafe   | unsized |
-| use      | virtual  | where    | while    | yield   |
-
-
-Each of these keywords has special meaning in its grammar, and all of them are
-excluded from the `ident` rule.
-
-Note that some of these keywords are reserved, and do not currently do
-anything.
-
 ### Literals
 
 A literal is an expression consisting of a single token, rather than a sequence
@@ -215,11 +141,6 @@ of tokens, that immediately and directly denotes the value it evaluates to,
 rather than referring to it by name or some other evaluation rule. A literal is
 a form of constant expression, so is evaluated (primarily) at compile time.
 
-```{.ebnf .gram}
-lit_suffix : ident;
-literal : [ string_lit | char_lit | byte_string_lit | byte_lit | num_lit ] lit_suffix ?;
-```
-
 The optional suffix is only used for certain numeric literals, but is
 reserved for future extension, that is, the above gives the lexical
 grammar, but a Rust parser will reject everything but the 12 special
@@ -268,36 +189,10 @@ cases mentioned in [Number literals](#number-literals) below.
 ##### Suffixes
 | Integer | Floating-point |
 |---------|----------------|
-| `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `is` (`isize`), `us` (`usize`) | `f32`, `f64` |
+| `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `isize`, `usize` | `f32`, `f64` |
 
 #### Character and string literals
 
-```{.ebnf .gram}
-char_lit : '\x27' char_body '\x27' ;
-string_lit : '"' string_body * '"' | 'r' raw_string ;
-
-char_body : non_single_quote
-          | '\x5c' [ '\x27' | common_escape | unicode_escape ] ;
-
-string_body : non_double_quote
-            | '\x5c' [ '\x22' | common_escape | unicode_escape ] ;
-raw_string : '"' raw_string_body '"' | '#' raw_string '#' ;
-
-common_escape : '\x5c'
-              | 'n' | 'r' | 't' | '0'
-              | 'x' hex_digit 2
-
-unicode_escape : 'u' '{' hex_digit+ 6 '}';
-
-hex_digit : 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
-          | 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
-          | dec_digit ;
-oct_digit : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' ;
-dec_digit : '0' | nonzero_dec ;
-nonzero_dec: '1' | '2' | '3' | '4'
-           | '5' | '6' | '7' | '8' | '9' ;
-```
-
 ##### Character literals
 
 A _character literal_ is a single Unicode character enclosed within two
@@ -330,14 +225,14 @@ Some additional _escapes_ are available in either character or non-raw string
 literals. An escape starts with a `U+005C` (`\`) and continues with one of the
 following forms:
 
-* An _8-bit codepoint escape_ escape starts with `U+0078` (`x`) and is
-  followed by exactly two _hex digits_. It denotes the Unicode codepoint
+* An _8-bit code point escape_ starts with `U+0078` (`x`) and is
+  followed by exactly two _hex digits_. It denotes the Unicode code point
   equal to the provided hex value.
-* A _24-bit codepoint escape_ starts with `U+0075` (`u`) and is followed
+* A _24-bit code point escape_ starts with `U+0075` (`u`) and is followed
   by up to six _hex digits_ surrounded by braces `U+007B` (`{`) and `U+007D`
-  (`}`). It denotes the Unicode codepoint equal to the provided hex value.
+  (`}`). It denotes the Unicode code point equal to the provided hex value.
 * A _whitespace escape_ is one of the characters `U+006E` (`n`), `U+0072`
-  (`r`), or `U+0074` (`t`), denoting the unicode values `U+000A` (LF),
+  (`r`), or `U+0074` (`t`), denoting the Unicode values `U+000A` (LF),
   `U+000D` (CR) or `U+0009` (HT) respectively.
 * The _backslash escape_ is the character `U+005C` (`\`) which must be
   escaped in order to denote *itself*.
@@ -346,11 +241,10 @@ following forms:
 
 Raw string literals do not process any escapes. They start with the character
 `U+0072` (`r`), followed by zero or more of the character `U+0023` (`#`) and a
-`U+0022` (double-quote) character. The _raw string body_ is not defined in the
-EBNF grammar above: it can contain any sequence of Unicode characters and is
-terminated only by another `U+0022` (double-quote) character, followed by the
-same number of `U+0023` (`#`) characters that preceded the opening `U+0022`
-(double-quote) character.
+`U+0022` (double-quote) character. The _raw string body_ can contain any sequence
+of Unicode characters and is terminated only by another `U+0022` (double-quote)
+character, followed by the same number of `U+0023` (`#`) characters that preceded
+the opening `U+0022` (double-quote) character.
 
 All Unicode characters contained in the raw string body represent themselves,
 the characters `U+0022` (double-quote) (except when followed by at least as
@@ -372,26 +266,14 @@ r##"foo #"# bar"##;                // foo #"# bar
 
 #### Byte and byte string literals
 
-```{.ebnf .gram}
-byte_lit : "b\x27" byte_body '\x27' ;
-byte_string_lit : "b\x22" string_body * '\x22' | "br" raw_byte_string ;
-
-byte_body : ascii_non_single_quote
-          | '\x5c' [ '\x27' | common_escape ] ;
-
-byte_string_body : ascii_non_double_quote
-            | '\x5c' [ '\x22' | common_escape ] ;
-raw_byte_string : '"' raw_byte_string_body '"' | '#' raw_byte_string '#' ;
-
-```
-
 ##### Byte literals
 
 A _byte literal_ is a single ASCII character (in the `U+0000` to `U+007F`
-range) enclosed within two `U+0027` (single-quote) characters, with the
-exception of `U+0027` itself, which must be _escaped_ by a preceding U+005C
-character (`\`), or a single _escape_. It is equivalent to a `u8` unsigned
-8-bit integer _number literal_.
+range) or a single _escape_ preceded by the characters `U+0062` (`b`) and
+`U+0027` (single-quote), and followed by the character `U+0027`. If the character
+`U+0027` is present within the literal, it must be _escaped_ by a preceding
+`U+005C` (`\`) character. It is equivalent to a `u8` unsigned 8-bit integer
+_number literal_.
 
 ##### Byte string literals
 
@@ -400,14 +282,14 @@ preceded by the characters `U+0062` (`b`) and `U+0022` (double-quote), and
 followed by the character `U+0022`. If the character `U+0022` is present within
 the literal, it must be _escaped_ by a preceding `U+005C` (`\`) character.
 Alternatively, a byte string literal can be a _raw byte string literal_, defined
-below. A byte string literal is equivalent to a `&'static [u8]` borrowed array
+below. A byte string literal of length `n` is equivalent to a `&'static [u8; n]` borrowed fixed-sized array
 of unsigned 8-bit integers.
 
 Some additional _escapes_ are available in either byte or non-raw byte string
 literals. An escape starts with a `U+005C` (`\`) and continues with one of the
 following forms:
 
-* An _byte escape_ escape starts with `U+0078` (`x`) and is
+* A _byte escape_ escape starts with `U+0078` (`x`) and is
   followed by exactly two _hex digits_. It denotes the byte
   equal to the provided hex value.
 * A _whitespace escape_ is one of the characters `U+006E` (`n`), `U+0072`
@@ -421,11 +303,10 @@ following forms:
 Raw byte string literals do not process any escapes. They start with the
 character `U+0062` (`b`), followed by `U+0072` (`r`), followed by zero or more
 of the character `U+0023` (`#`), and a `U+0022` (double-quote) character. The
-_raw string body_ is not defined in the EBNF grammar above: it can contain any
-sequence of ASCII characters and is terminated only by another `U+0022`
-(double-quote) character, followed by the same number of `U+0023` (`#`)
-characters that preceded the opening `U+0022` (double-quote) character. A raw
-byte string literal can not contain any non-ASCII byte.
+_raw string body_ can contain any sequence of ASCII characters and is terminated
+only by another `U+0022` (double-quote) character, followed by the same number of
+`U+0023` (`#`) characters that preceded the opening `U+0022` (double-quote)
+character. A raw byte string literal can not contain any non-ASCII byte.
 
 All characters contained in the raw string body represent their ASCII encoding,
 the characters `U+0022` (double-quote) (except when followed by at least as
@@ -447,19 +328,6 @@ b"\\x52"; br"\x52";                  // \x52
 
 #### Number literals
 
-```{.ebnf .gram}
-num_lit : nonzero_dec [ dec_digit | '_' ] * float_suffix ?
-        | '0' [       [ dec_digit | '_' ] * float_suffix ?
-              | 'b'   [ '1' | '0' | '_' ] +
-              | 'o'   [ oct_digit | '_' ] +
-              | 'x'   [ hex_digit | '_' ] +  ] ;
-
-float_suffix : [ exponent | '.' dec_lit exponent ? ] ? ;
-
-exponent : ['E' | 'e'] ['-' | '+' ] ? dec_lit ;
-dec_lit : [ dec_digit | '_' ] + ;
-```
-
 A _number literal_ is either an _integer literal_ or a _floating-point
 literal_. The grammar for recognizing the two kinds of literals is mixed.
 
@@ -537,12 +405,6 @@ The two values of the boolean type are written `true` and `false`.
 
 ### Symbols
 
-```{.ebnf .gram}
-symbol : "::" | "->"
-       | '#' | '[' | ']' | '(' | ')' | '{' | '}'
-       | ',' | ';' ;
-```
-
 Symbols are a general class of printable [token](#tokens) that play structural
 roles in a variety of grammar productions. They are catalogued here for
 completeness as the set of remaining miscellaneous printable tokens that do not
@@ -552,16 +414,6 @@ operators](#binary-operator-expressions), or [keywords](#keywords).
 
 ## Paths
 
-```{.ebnf .gram}
-expr_path : [ "::" ] ident [ "::" expr_path_tail ] + ;
-expr_path_tail : '<' type_expr [ ',' type_expr ] + '>'
-               | expr_path ;
-
-type_path : ident [ type_path_tail ] + ;
-type_path_tail : '<' type_expr [ ',' type_expr ] + '>'
-               | "::" type_path ;
-```
-
 A _path_ is a sequence of one or more path components _logically_ separated by
 a namespace qualifier (`::`). If a path consists of only one component, it may
 refer to either an [item](#items) or a [variable](#variables) in a local control
@@ -657,19 +509,6 @@ Users of `rustc` can define new syntax extensions in two ways:
 
 ## Macros
 
-```{.ebnf .gram}
-expr_macro_rules : "macro_rules" '!' ident '(' macro_rule * ')' ;
-macro_rule : '(' matcher * ')' "=>" '(' transcriber * ')' ';' ;
-matcher : '(' matcher * ')' | '[' matcher * ']'
-        | '{' matcher * '}' | '$' ident ':' ident
-        | '$' '(' matcher * ')' sep_token? [ '*' | '+' ]
-        | non_special_token ;
-transcriber : '(' transcriber * ')' | '[' transcriber * ']'
-            | '{' transcriber * '}' | '$' ident
-            | '$' '(' transcriber * ')' sep_token? [ '*' | '+' ]
-            | non_special_token ;
-```
-
 `macro_rules` allows users to define syntax extension in a declarative way.  We
 call such extensions "macros by example" or simply "macros" — to be distinguished
 from the "procedural macros" defined in [compiler plugins][plugin].
@@ -697,9 +536,9 @@ in macro rules). In the transcriber, the designator is already known, and so
 only the name of a matched nonterminal comes after the dollar sign.
 
 In both the matcher and transcriber, the Kleene star-like operator indicates
-repetition. The Kleene star operator consists of `$` and parens, optionally
+repetition. The Kleene star operator consists of `$` and parentheses, optionally
 followed by a separator token, followed by `*` or `+`. `*` means zero or more
-repetitions, `+` means at least one repetition. The parens are not matched or
+repetitions, `+` means at least one repetition. The parentheses are not matched or
 transcribed. On the matcher side, a name is bound to _all_ of the names it
 matches, in a structure that mimics the structure of the repetition encountered
 on a successful match. The job of the transcriber is to sort that structure
@@ -735,15 +574,26 @@ Rust syntax is restricted in two ways:
 
 # Crates and source files
 
-Rust is a *compiled* language. Its semantics obey a *phase distinction* between
-compile-time and run-time. Those semantic rules that have a *static
+Although Rust, like any other language, can be implemented by an interpreter as
+well as a compiler, the only existing implementation is a compiler &mdash;
+from now on referred to as *the* Rust compiler &mdash; and the language has
+always been designed to be compiled. For these reasons, this section assumes a
+compiler.
+
+Rust's semantics obey a *phase distinction* between compile-time and
+run-time.[^phase-distinction] Those semantic rules that have a *static
 interpretation* govern the success or failure of compilation. Those semantics
 that have a *dynamic interpretation* govern the behavior of the program at
 run-time.
 
+[^phase-distinction]: This distinction would also exist in an interpreter.
+    Static checks like syntactic analysis, type checking, and lints should
+    happen before the program is executed regardless of when it is executed.
+
 The compilation model centers on artifacts called _crates_. Each compilation
 processes a single crate in source form, and if successful, produces a single
-crate in binary form: either an executable or a library.[^cratesourcefile]
+crate in binary form: either an executable or some sort of
+library.[^cratesourcefile]
 
 [^cratesourcefile]: A crate is somewhat analogous to an *assembly* in the
     ECMA-335 CLI model, a *library* in the SML/NJ Compilation Manager, a *unit*
@@ -764,21 +614,25 @@ extension `.rs`.
 A Rust source file describes a module, the name and location of which &mdash;
 in the module tree of the current crate &mdash; are defined from outside the
 source file: either by an explicit `mod_item` in a referencing source file, or
-by the name of the crate itself.
+by the name of the crate itself. Every source file is a module, but not every
+module needs its own source file: [module definitions](#modules) can be nested
+within one file.
 
 Each source file contains a sequence of zero or more `item` definitions, and
-may optionally begin with any number of `attributes` that apply to the
-containing module. Attributes on the anonymous crate module define important
-metadata that influences the behavior of the compiler.
+may optionally begin with any number of [attributes](#Items and attributes)
+that apply to the containing module, most of which influence the behavior of
+the compiler. The anonymous crate module can have additional attributes that
+apply to the crate as a whole.
 
 ```no_run
-// Crate name
+// Specify the crate name.
 #![crate_name = "projx"]
 
-// Specify the output type
+// Specify the type of output artifact.
 #![crate_type = "lib"]
 
-// Turn on a warning
+// Turn on a warning.
+// This can be done in any module, not just the anonymous crate module.
 #![warn(non_camel_case_types)]
 ```
 
@@ -793,12 +647,6 @@ Crates contain [items](#items), each of which may have some number of
 
 ## Items
 
-```{.ebnf .gram}
-item : extern_crate_decl | use_decl | mod_item | fn_item | type_item
-     | struct_item | enum_item | static_item | trait_item | impl_item
-     | extern_block ;
-```
-
 An _item_ is a component of a crate. Items are organized within a crate by a
 nested set of [modules](#modules). Every crate has a single "outermost"
 anonymous module; all further items within the crate have [paths](#paths)
@@ -845,11 +693,6 @@ no notion of type abstraction: there are no first-class "forall" types.
 
 ### Modules
 
-```{.ebnf .gram}
-mod_item : "mod" ident ( ';' | '{' mod '}' );
-mod : item * ;
-```
-
 A module is a container for zero or more [items](#items).
 
 A _module item_ is a module, surrounded in braces, named, and prefixed with the
@@ -910,11 +753,6 @@ mod thread {
 
 ##### Extern crate declarations
 
-```{.ebnf .gram}
-extern_crate_decl : "extern" "crate" crate_name
-crate_name: ident | ( string_lit "as" ident )
-```
-
 An _`extern crate` declaration_ specifies a dependency on an external crate.
 The external crate is then bound into the declaring scope as the `ident`
 provided in the `extern_crate_decl`.
@@ -940,17 +778,6 @@ extern crate std as ruststd; // linking to 'std' under another name
 
 ##### Use declarations
 
-```{.ebnf .gram}
-use_decl : "pub" ? "use" [ path "as" ident
-                          | path_glob ] ;
-
-path_glob : ident [ "::" [ path_glob
-                          | '*' ] ] ?
-          | '{' path_item [ ',' path_item ] * '}' ;
-
-path_item : ident | "self" ;
-```
-
 A _use declaration_ creates one or more local name bindings synonymous with
 some other [path](#paths). Usually a `use` declaration is used to shorten the
 path required to refer to a module item. These declarations may appear at the
@@ -973,8 +800,7 @@ Use declarations support a number of convenient shortcuts:
 
 An example of `use` declarations:
 
-```
-# #![feature(core)]
+```rust
 use std::option::Option::{Some, None};
 use std::collections::hash_map::{self, HashMap};
 
@@ -1031,16 +857,17 @@ declarations.
 An example of what will and will not work for `use` items:
 
 ```
-# #![feature(core)]
 # #![allow(unused_imports)]
-use foo::core::iter;  // good: foo is at the root of the crate
 use foo::baz::foobaz;    // good: foo is at the root of the crate
 
 mod foo {
-    extern crate core;
 
-    use foo::core::iter; // good: foo is at crate root
-//  use core::iter;      // bad:  core is not at the crate root
+    mod example {
+        pub mod iter {}
+    }
+
+    use foo::example::iter; // good: foo is at crate root
+//  use example::iter;      // bad:  core is not at the crate root
     use self::baz::foobaz;  // good: self refers to module 'foo'
     use foo::bar::foobar;   // good: foo is at crate root
 
@@ -1099,40 +926,31 @@ signature. Each type parameter must be explicitly declared, in an
 angle-bracket-enclosed, comma-separated list following the function name.
 
 ```{.ignore}
-fn iter<T>(seq: &[T], f: |T|) {
-    for elt in seq.iter() { f(elt); }
+fn iter<T, F>(seq: &[T], f: F) where T: Copy, F: Fn(T) {
+    for elt in seq { f(*elt); }
 }
-fn map<T, U>(seq: &[T], f: |T| -> U) -> Vec<U> {
+fn map<T, U, F>(seq: &[T], f: F) -> Vec<U> where T: Copy, U: Copy, F: Fn(T) -> U {
     let mut acc = vec![];
-    for elt in seq.iter() { acc.push(f(elt)); }
+    for elt in seq { acc.push(f(*elt)); }
     acc
 }
 ```
 
 Inside the function signature and body, the name of the type parameter can be
-used as a type name.
+used as a type name. [Trait](#traits) bounds can be specified for type parameters
+to allow methods with that trait to be called on values of that type. This is
+specified using the `where` syntax, as in the above example.
 
 When a generic function is referenced, its type is instantiated based on the
 context of the reference. For example, calling the `iter` function defined
 above on `[1, 2]` will instantiate type parameter `T` with `i32`, and require
-the closure parameter to have type `fn(i32)`.
+the closure parameter to have type `Fn(i32)`.
 
 The type parameters can also be explicitly supplied in a trailing
 [path](#paths) component after the function name. This might be necessary if
 there is not sufficient context to determine the type parameters. For example,
 `mem::size_of::<u32>() == 4`.
 
-Since a parameter type is opaque to the generic function, the set of operations
-that can be performed on it is limited. Values of parameter type can only be
-moved, not copied.
-
-```
-fn id<T>(x: T) -> T { x }
-```
-
-Similarly, [trait](#traits) bounds can be specified for type parameters to
-allow methods with that trait to be called on values of that type.
-
 #### Unsafety
 
 Unsafe operations are those that potentially violate the memory-safety
@@ -1209,9 +1027,9 @@ the guarantee that these issues are never caused by safe code.
 
 [noalias]: http://llvm.org/docs/LangRef.html#noalias
 
-##### Behaviour not considered unsafe
+##### Behavior not considered unsafe
 
-This is a list of behaviour not considered *unsafe* in Rust terms, but that may
+This is a list of behavior not considered *unsafe* in Rust terms, but that may
 be undesired.
 
 * Deadlocks
@@ -1304,7 +1122,7 @@ specific type, but may implement several different traits, or be compatible with
 several different type constraints.
 
 For example, the following defines the type `Point` as a synonym for the type
-`(u8, u8)`, the type of pairs of unsigned 8 bit integers.:
+`(u8, u8)`, the type of pairs of unsigned 8 bit integers:
 
 ```
 type Point = (u8, u8);
@@ -1368,9 +1186,7 @@ a = Animal::Cat;
 
 Enumeration constructors can have either named or unnamed fields:
 
-```
-# #![feature(struct_variant)]
-# fn main() {
+```rust
 enum Animal {
     Dog (String, f64),
     Cat { name: String, weight: f64 }
@@ -1378,7 +1194,6 @@ enum Animal {
 
 let mut a: Animal = Animal::Dog("Cocoa".to_string(), 37.2);
 a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 };
-# }
 ```
 
 In this example, `Cat` is a _struct-like enum variant_,
@@ -1407,10 +1222,6 @@ it were `Bar(i32)`, this is disallowed.
 
 ### Constant items
 
-```{.ebnf .gram}
-const_item : "const" ident ':' type '=' expr ';' ;
-```
-
 A *constant item* is a named _constant value_ which is not associated with a
 specific memory location in the program. Constants are essentially inlined
 wherever they are used, meaning that they are copied directly into the relevant
@@ -1447,10 +1258,6 @@ const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings {
 
 ### Static items
 
-```{.ebnf .gram}
-static_item : "static" ident ':' type '=' expr ';' ;
-```
-
 A *static item* is similar to a *constant*, except that it represents a precise
 memory location in the program. A static is never "inlined" at the usage site,
 and all references to it refer to the same memory location. Static items have
@@ -1558,7 +1365,7 @@ fn draw_twice<T: Shape>(surface: Surface, sh: T) {
 }
 ```
 
-Traits also define an [object type](#object-types) with the same name as the
+Traits also define an [trait object](#trait-objects) with the same name as the
 trait. Values of this type are created by [casting](#type-cast-expressions)
 pointer values (pointing to a type for which an implementation of the given
 trait is in scope) to pointers to the trait name, used as a type.
@@ -1705,11 +1512,6 @@ impl Seq<bool> for u32 {
 
 ### External blocks
 
-```{.ebnf .gram}
-extern_block_item : "extern" '{' extern_block '}' ;
-extern_block : [ foreign_fn ] * ;
-```
-
 External blocks form the basis for Rust's foreign function interface.
 Declarations in an external block describe symbols in external, non-Rust
 libraries.
@@ -1718,17 +1520,6 @@ Functions within external blocks are declared in the same way as other Rust
 functions, with the exception that they may not have a body and are instead
 terminated by a semicolon.
 
-```
-# #![feature(libc)]
-extern crate libc;
-use libc::{c_char, FILE};
-
-extern {
-    fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE;
-}
-# fn main() {}
-```
-
 Functions within external blocks may be called by Rust code, just like
 functions defined in Rust. The Rust compiler automatically translates between
 the Rust ABI and the foreign ABI.
@@ -1739,7 +1530,7 @@ By default external blocks assume that the library they are calling uses the
 standard C "cdecl" ABI. Other ABIs may be specified using an `abi` string, as
 shown here:
 
-```{.ignore}
+```ignore
 // Interface to the Windows API
 extern "stdcall" { }
 ```
@@ -1920,13 +1711,6 @@ the namespace hierarchy as it normally would.
 
 ## Attributes
 
-```{.ebnf .gram}
-attribute : '#' '!' ? '[' meta_item ']' ;
-meta_item : ident [ '=' literal
-                  | '(' meta_seq ')' ] ? ;
-meta_seq : meta_item [ ',' meta_seq ] ? ;
-```
-
 Any item declaration may have an _attribute_ applied to it. Attributes in Rust
 are modeled on Attributes in ECMA-335, with the syntax coming from ECMA-334
 (C#). An attribute is a general, free-form metadatum that is interpreted
@@ -1972,7 +1756,7 @@ type int8_t = i8;
 
 ### Crate-only attributes
 
-- `crate_name` - specify the this crate's crate name.
+- `crate_name` - specify the crate's crate name.
 - `crate_type` - see [linkage](#linkage).
 - `feature` - see [compiler features](#compiler-features).
 - `no_builtins` - disable optimizing certain code patterns to invocations of
@@ -2160,7 +1944,7 @@ The following configurations must be defined by the implementation:
   `"unix"` or `"windows"`. The value of this configuration option is defined
   as a configuration itself, like `unix` or `windows`.
 * `target_os = "..."`. Operating system of the target, examples include
-  `"win32"`, `"macos"`, `"linux"`, `"android"`, `"freebsd"`, `"dragonfly"`,
+  `"windows"`, `"macos"`, `"ios"`, `"linux"`, `"android"`, `"freebsd"`, `"dragonfly"`,
   `"bitrig"` or `"openbsd"`.
 * `target_pointer_width = "..."`. Target pointer width in bits. This is set
   to `"32"` for targets with 32-bit pointers, and likewise set to `"64"` for
@@ -2508,7 +2292,7 @@ The currently implemented features of the reference compiler are:
                               terms of encapsulation).
 
 If a feature is promoted to a language feature, then all existing programs will
-start to receive compilation warnings about #[feature] directives which enabled
+start to receive compilation warnings about `#![feature]` directives which enabled
 the new feature (because the directive is no longer necessary). However, if a
 feature is decided to be removed from the language, errors will be issued (if
 there isn't a parser error first). The directive in this case is no longer
@@ -2559,11 +2343,6 @@ in meaning to declaring the item outside the statement block.
 
 #### Variable declarations
 
-```{.ebnf .gram}
-let_decl : "let" pat [':' type ] ? [ init ] ? ';' ;
-init : [ '=' ] expr ;
-```
-
 A _variable declaration_ introduces a new set of variable, given by a pattern. The
 pattern may be followed by a type annotation, and/or an initializer expression.
 When no type annotation is given, the compiler will infer the type, or signal
@@ -2654,7 +2433,7 @@ parentheses. They are used to create [tuple-typed](#tuple-types) values.
 ```{.tuple}
 (0,);
 (0.0, 4.5);
-("a", 4us, true);
+("a", 4usize, true);
 ```
 
 ### Unit expressions
@@ -2664,15 +2443,6 @@ the same name.
 
 ### Structure expressions
 
-```{.ebnf .gram}
-struct_expr : expr_path '{' ident ':' expr
-                      [ ',' ident ':' expr ] *
-                      [ ".." expr ] '}' |
-              expr_path '(' expr
-                      [ ',' expr ] * ')' |
-              expr_path ;
-```
-
 There are several forms of structure expressions. A _structure expression_
 consists of the [path](#paths) of a [structure item](#structures), followed by
 a brace-enclosed list of one or more comma-separated name-value pairs,
@@ -2723,11 +2493,6 @@ Point3d {y: 0, z: 10, .. base};
 
 ### Block expressions
 
-```{.ebnf .gram}
-block_expr : '{' [ stmt ';' | item ] *
-                 [ expr ] '}' ;
-```
-
 A _block expression_ is similar to a module in terms of the declarations that
 are possible. Each block conceptually introduces a new namespace scope. Use
 items can bring new names into scopes and declared items are in scope for only
@@ -2750,22 +2515,14 @@ assert_eq!(5, x);
 
 ### Method-call expressions
 
-```{.ebnf .gram}
-method_call_expr : expr '.' ident paren_expr_list ;
-```
-
 A _method call_ consists of an expression followed by a single dot, an
 identifier, and a parenthesized expression-list. Method calls are resolved to
 methods on specific traits, either statically dispatching to a method if the
 exact `self`-type of the left-hand-side is known, or dynamically dispatching if
-the left-hand-side expression is an indirect [object type](#object-types).
+the left-hand-side expression is an indirect [trait object](#trait-objects).
 
 ### Field expressions
 
-```{.ebnf .gram}
-field_expr : expr '.' ident ;
-```
-
 A _field expression_ consists of an expression followed by a single dot and an
 identifier, when not immediately followed by a parenthesized expression-list
 (the latter is a [method call expression](#method-call-expressions)). A field
@@ -2786,12 +2543,6 @@ automatically dereferenced to make the field access possible.
 
 ### Array expressions
 
-```{.ebnf .gram}
-array_expr : '[' "mut" ? array_elems? ']' ;
-
-array_elems : [expr [',' expr]*] | [expr ';' expr] ;
-```
-
 An [array](#array,-and-slice-types) _expression_ is written by enclosing zero
 or more comma-separated expressions of uniform type in square brackets.
 
@@ -2808,10 +2559,6 @@ constant expression that can be evaluated at compile time, such as a
 
 ### Index expressions
 
-```{.ebnf .gram}
-idx_expr : expr '[' expr ']' ;
-```
-
 [Array](#array,-and-slice-types)-typed expressions can be indexed by
 writing a square-bracket-enclosed expression (the index) after them. When the
 array is mutable, the resulting [lvalue](#lvalues,-rvalues-and-temporaries) can
@@ -2826,6 +2573,26 @@ _panicked state_.
 (["a", "b"])[10]; // panics
 ```
 
+### Range expressions
+
+The `..` operator will construct an object of one of the `std::ops::Range` variants.
+
+```
+1..2;   // std::ops::Range
+3..;    // std::ops::RangeFrom
+..4;    // std::ops::RangeTo
+..;     // std::ops::RangeFull
+```
+
+The following expressions are equivalent.
+
+```
+let x = std::ops::Range {start: 0, end: 10};
+let y = 0..10;
+
+assert_eq!(x,y);
+```
+
 ### Unary operator expressions
 
 Rust defines three unary operators. They are all written as prefix operators,
@@ -2850,10 +2617,6 @@ before the expression they apply to.
 
 ### Binary operator expressions
 
-```{.ebnf .gram}
-binop_expr : expr binop expr ;
-```
-
 Binary operators expressions are given in terms of [operator
 precedence](#operator-precedence).
 
@@ -3014,10 +2777,6 @@ An expression enclosed in parentheses evaluates to the result of the enclosed
 expression. Parentheses can be used to explicitly specify evaluation order
 within an expression.
 
-```{.ebnf .gram}
-paren_expr : '(' expr ')' ;
-```
-
 An example of a parenthesized expression:
 
 ```
@@ -3027,12 +2786,6 @@ let x: i32 = (2 + 3) * 4;
 
 ### Call expressions
 
-```{.ebnf .gram}
-expr_list : [ expr [ ',' expr ]* ] ? ;
-paren_expr_list : '(' expr_list ')' ;
-call_expr : expr paren_expr_list ;
-```
-
 A _call expression_ invokes a function, providing zero or more input variables
 and an optional location to move the function's output into. If the function
 eventually returns, then the expression completes.
@@ -3048,11 +2801,6 @@ let pi: Result<f32, _> = "3.14".parse();
 
 ### Lambda expressions
 
-```{.ebnf .gram}
-ident_list : [ ident [ ',' ident ]* ] ? ;
-lambda_expr : '|' ident_list '|' expr ;
-```
-
 A _lambda expression_ (sometimes called an "anonymous function expression")
 defines a function and denotes it as a value, in a single expression. A lambda
 expression is a pipe-symbol-delimited (`|`) list of identifiers followed by an
@@ -3092,93 +2840,79 @@ fn ten_times<F>(f: F) where F: Fn(i32) {
 ten_times(|j| println!("hello, {}", j));
 ```
 
-### While loops
-
-```{.ebnf .gram}
-while_expr : [ lifetime ':' ] "while" no_struct_literal_expr '{' block '}' ;
-```
-
-A `while` loop begins by evaluating the boolean loop conditional expression.
-If the loop conditional expression evaluates to `true`, the loop body block
-executes and control returns to the loop conditional expression. If the loop
-conditional expression evaluates to `false`, the `while` expression completes.
-
-An example:
-
-```
-let mut i = 0;
-
-while i < 10 {
-    println!("hello");
-    i = i + 1;
-}
-```
-
 ### Infinite loops
 
 A `loop` expression denotes an infinite loop.
 
-```{.ebnf .gram}
-loop_expr : [ lifetime ':' ] "loop" '{' block '}';
-```
-
-A `loop` expression may optionally have a _label_. If a label is present, then
-labeled `break` and `continue` expressions nested within this loop may exit out
-of this loop or return control to its head. See [Break
-expressions](#break-expressions) and [Continue
+A `loop` expression may optionally have a _label_. The label is written as
+a lifetime preceding the loop expression, as in `'foo: loop{ }`. If a
+label is present, then labeled `break` and `continue` expressions nested
+within this loop may exit out of this loop or return control to its head.
+See [Break expressions](#break-expressions) and [Continue
 expressions](#continue-expressions).
 
 ### Break expressions
 
-```{.ebnf .gram}
-break_expr : "break" [ lifetime ];
-```
-
 A `break` expression has an optional _label_. If the label is absent, then
 executing a `break` expression immediately terminates the innermost loop
 enclosing it. It is only permitted in the body of a loop. If the label is
-present, then `break foo` terminates the loop with label `foo`, which need not
+present, then `break 'foo` terminates the loop with label `'foo`, which need not
 be the innermost label enclosing the `break` expression, but must enclose it.
 
 ### Continue expressions
 
-```{.ebnf .gram}
-continue_expr : "continue" [ lifetime ];
-```
-
 A `continue` expression has an optional _label_. If the label is absent, then
 executing a `continue` expression immediately terminates the current iteration
 of the innermost loop enclosing it, returning control to the loop *head*. In
 the case of a `while` loop, the head is the conditional expression controlling
 the loop. In the case of a `for` loop, the head is the call-expression
-controlling the loop. If the label is present, then `continue foo` returns
-control to the head of the loop with label `foo`, which need not be the
+controlling the loop. If the label is present, then `continue 'foo` returns
+control to the head of the loop with label `'foo`, which need not be the
 innermost label enclosing the `break` expression, but must enclose it.
 
 A `continue` expression is only permitted in the body of a loop.
 
-### For expressions
+### While loops
+
+A `while` loop begins by evaluating the boolean loop conditional expression.
+If the loop conditional expression evaluates to `true`, the loop body block
+executes and control returns to the loop conditional expression. If the loop
+conditional expression evaluates to `false`, the `while` expression completes.
+
+An example:
 
-```{.ebnf .gram}
-for_expr : [ lifetime ':' ] "for" pat "in" no_struct_literal_expr '{' block '}' ;
+```
+let mut i = 0;
+
+while i < 10 {
+    println!("hello");
+    i = i + 1;
+}
 ```
 
+Like `loop` expressions, `while` loops can be controlled with `break` or
+`continue`, and may optionally have a _label_. See [infinite
+loops](#infinite-loops), [break expressions](#break-expressions), and
+[continue expressions](#continue-expressions) for more information.
+
+### For expressions
+
 A `for` expression is a syntactic construct for looping over elements provided
-by an implementation of `std::iter::Iterator`.
+by an implementation of `std::iter::IntoIterator`.
 
 An example of a for loop over the contents of an array:
 
 ```
 # type Foo = i32;
-# fn bar(f: Foo) { }
+# fn bar(f: &Foo) { }
 # let a = 0;
 # let b = 0;
 # let c = 0;
 
 let v: &[Foo] = &[a, b, c];
 
-for e in v.iter() {
-    bar(*e);
+for e in v {
+    bar(e);
 }
 ```
 
@@ -3191,15 +2925,12 @@ for i in 0..256 {
 }
 ```
 
-### If expressions
-
-```{.ebnf .gram}
-if_expr : "if" no_struct_literal_expr '{' block '}'
-          else_tail ? ;
+Like `loop` expressions, `for` loops can be controlled with `break` or
+`continue`, and may optionally have a _label_. See [infinite
+loops](#infinite-loops), [break expressions](#break-expressions), and
+[continue expressions](#continue-expressions) for more information.
 
-else_tail : "else" [ if_expr | if_let_expr
-                   | '{' block '}' ] ;
-```
+### If expressions
 
 An `if` expression is a conditional branch in program control. The form of an
 `if` expression is a condition expression, followed by a consequent block, any
@@ -3213,14 +2944,6 @@ if` condition is evaluated. If all `if` and `else if` conditions evaluate to
 
 ### Match expressions
 
-```{.ebnf .gram}
-match_expr : "match" no_struct_literal_expr '{' match_arm * '}' ;
-
-match_arm : attribute * match_pat "=>" [ expr "," | '{' block '}' ] ;
-
-match_pat : pat [ '|' pat ] * [ "if" expr ] ? ;
-```
-
 A `match` expression branches on a *pattern*. The exact form of matching that
 occurs depends on the pattern. Patterns consist of some combination of
 literals, destructured arrays or enum constructors, structures and tuples,
@@ -3231,55 +2954,7 @@ expression.
 
 In a pattern whose head expression has an `enum` type, a placeholder (`_`)
 stands for a *single* data field, whereas a wildcard `..` stands for *all* the
-fields of a particular variant. For example:
-
-```
-#![feature(box_patterns)]
-#![feature(box_syntax)]
-enum List<X> { Nil, Cons(X, Box<List<X>>) }
-
-fn main() {
-    let x: List<i32> = List::Cons(10, box List::Cons(11, box List::Nil));
-
-    match x {
-        List::Cons(_, box List::Nil) => panic!("singleton list"),
-        List::Cons(..)               => return,
-        List::Nil                    => panic!("empty list")
-    }
-}
-```
-
-The first pattern matches lists constructed by applying `Cons` to any head
-value, and a tail value of `box Nil`. The second pattern matches _any_ list
-constructed with `Cons`, ignoring the values of its arguments. The difference
-between `_` and `..` is that the pattern `C(_)` is only type-correct if `C` has
-exactly one argument, while the pattern `C(..)` is type-correct for any enum
-variant `C`, regardless of how many arguments `C` has.
-
-Used inside an array pattern, `..` stands for any number of elements, when the
-`advanced_slice_patterns` feature gate is turned on. This wildcard can be used
-at most once for a given array, which implies that it cannot be used to
-specifically match elements that are at an unknown distance from both ends of a
-array, like `[.., 42, ..]`. If preceded by a variable name, it will bind the
-corresponding slice to the variable. Example:
-
-```
-# #![feature(advanced_slice_patterns, slice_patterns)]
-fn is_symmetric(list: &[u32]) -> bool {
-    match list {
-        [] | [_]                   => true,
-        [x, inside.., y] if x == y => is_symmetric(inside),
-        _                          => false
-    }
-}
-
-fn main() {
-    let sym     = &[0, 1, 4, 2, 4, 1, 0];
-    let not_sym = &[0, 1, 7, 2, 4, 1, 0];
-    assert!(is_symmetric(sym));
-    assert!(!is_symmetric(not_sym));
-}
-```
+fields of a particular variant.
 
 A `match` behaves differently depending on whether or not the head expression
 is an [lvalue or an rvalue](#lvalues,-rvalues-and-temporaries). If the head
@@ -3298,30 +2973,15 @@ the inside of the match.
 An example of a `match` expression:
 
 ```
-#![feature(box_patterns)]
-#![feature(box_syntax)]
-# fn process_pair(a: i32, b: i32) { }
-# fn process_ten() { }
-
-enum List<X> { Nil, Cons(X, Box<List<X>>) }
+let x = 1;
 
-fn main() {
-    let x: List<i32> = List::Cons(10, box List::Cons(11, box List::Nil));
-
-    match x {
-        List::Cons(a, box List::Cons(b, _)) => {
-            process_pair(a, b);
-        }
-        List::Cons(10, _) => {
-            process_ten();
-        }
-        List::Nil => {
-            return;
-        }
-        _ => {
-            panic!();
-        }
-    }
+match x {
+    1 => println!("one"),
+    2 => println!("two"),
+    3 => println!("three"),
+    4 => println!("four"),
+    5 => println!("five"),
+    _ => println!("something else"),
 }
 ```
 
@@ -3334,28 +2994,12 @@ Subpatterns can also be bound to variables by the use of the syntax `variable @
 subpattern`. For example:
 
 ```
-#![feature(box_patterns)]
-#![feature(box_syntax)]
+let x = 1;
 
-enum List { Nil, Cons(u32, Box<List>) }
-
-fn is_sorted(list: &List) -> bool {
-    match *list {
-        List::Nil | List::Cons(_, box List::Nil) => true,
-        List::Cons(x, ref r @ box List::Cons(_, _)) => {
-            match *r {
-                box List::Cons(y, _) => (x <= y) && is_sorted(&**r),
-                _ => panic!()
-            }
-        }
-    }
+match x {
+    e @ 1 ... 5 => println!("got a range element {}", e),
+    _ => println!("anything"),
 }
-
-fn main() {
-    let a = List::Cons(6, box List::Cons(7, box List::Cons(42, box List::Nil)));
-    assert!(is_sorted(&a));
-}
-
 ```
 
 Patterns can also dereference pointers by using the `&`, `&mut` and `box`
@@ -3416,12 +3060,6 @@ let message = match maybe_digit {
 
 ### If let expressions
 
-```{.ebnf .gram}
-if_let_expr : "if" "let" pat '=' expr '{' block '}'
-               else_tail ? ;
-else_tail : "else" [ if_expr | if_let_expr | '{' block '}' ] ;
-```
-
 An `if let` expression is semantically identical to an `if` expression but in place
 of a condition expression it expects a refutable let statement. If the value of the
 expression on the right hand side of the let statement matches the pattern, the corresponding
@@ -3429,10 +3067,6 @@ block will execute, otherwise flow proceeds to the first `else` block that follo
 
 ### While let loops
 
-```{.ebnf .gram}
-while_let_expr : "while" "let" pat '=' expr '{' block '}' ;
-```
-
 A `while let` loop is semantically identical to a `while` loop but in place of a
 condition expression it expects a refutable let statement. If the value of the
 expression on the right hand side of the let statement matches the pattern, the
@@ -3441,10 +3075,6 @@ Otherwise, the while expression completes.
 
 ### Return expressions
 
-```{.ebnf .gram}
-return_expr : "return" expr ? ;
-```
-
 Return expressions are denoted with the keyword `return`. Evaluating a `return`
 expression moves its argument into the designated output location for the
 current function call, destroys the current function activation frame, and
@@ -3476,17 +3106,10 @@ User-defined types have limited capabilities.
 
 The primitive types are the following:
 
-* The "unit" type `()`, having the single "unit" value `()` (occasionally called
-  "nil"). [^unittype]
 * The boolean type `bool` with values `true` and `false`.
 * The machine types.
 * The machine-dependent integer and floating-point types.
 
-[^unittype]: The "unit" value `()` is *not* a sentinel "null pointer" value for
-    reference variables; the "unit" type is the implicit return type from functions
-    otherwise lacking a return type, and can be used in other contexts (such as
-    message-sending or type-parametric code) as a zero-size type.]
-
 #### Machine types
 
 The machine types are the following:
@@ -3525,9 +3148,9 @@ is not a surrogate), represented as a 32-bit unsigned word in the 0x0000 to
 UTF-32 string.
 
 A value of type `str` is a Unicode string, represented as an array of 8-bit
-unsigned bytes holding a sequence of UTF-8 codepoints. Since `str` is of
+unsigned bytes holding a sequence of UTF-8 code points. Since `str` is of
 unknown size, it is not a _first-class_ type, but can only be instantiated
-through a pointer type, such as `&str` or `String`.
+through a pointer type, such as `&str`.
 
 ### Tuple types
 
@@ -3583,7 +3206,7 @@ to an array or slice is always bounds-checked.
 A `struct` *type* is a heterogeneous product of other types, called the
 *fields* of the type.[^structtype]
 
-[^structtype]: `struct` types are analogous `struct` types in C,
+[^structtype]: `struct` types are analogous to `struct` types in C,
     the *record* types of the ML family,
     or the *structure* types of the Lisp family.
 
@@ -3597,7 +3220,7 @@ a corresponding struct *expression*; the resulting `struct` value will always
 have the same memory layout.
 
 The fields of a `struct` may be qualified by [visibility
-modifiers](#re-exporting-and-visibility), to allow access to data in a
+modifiers](#visibility-and-privacy), to allow access to data in a
 structure outside a module.
 
 A _tuple struct_ type is just like a structure type, except that the fields are
@@ -3665,18 +3288,18 @@ varieties of pointer in Rust:
 
 * References (`&`)
   : These point to memory _owned by some other value_.
-    A reference type is written `&type` for some lifetime-variable `f`,
-    or just `&'a type` when you need an explicit lifetime.
+    A reference type is written `&type`,
+    or `&'a type` when you need to specify an explicit lifetime.
     Copying a reference is a "shallow" operation:
     it involves only copying the pointer itself.
-    Releasing a reference typically has no effect on the value it points to,
-    with the exception of temporary values, which are released when the last
-    reference to them is released.
+    Releasing a reference has no effect on the value it points to,
+    but a reference of a temporary value will keep it alive during the scope
+    of the reference itself.
 
 * Raw pointers (`*`)
   : Raw pointers are pointers without safety or liveness guarantees.
     Raw pointers are written as `*const T` or `*mut T`,
-    for example `*const int` means a raw pointer to an integer.
+    for example `*const i32` means a raw pointer to a 32-bit integer.
     Copying or dropping a raw pointer has no effect on the lifecycle of any
     other value. Dereferencing a raw pointer or converting it to any other
     pointer type is an [`unsafe` operation](#unsafe-functions).
@@ -3709,56 +3332,44 @@ x = bo(5,7);
 
 ### Closure types
 
-```{.ebnf .notation}
-closure_type := [ 'unsafe' ] [ '<' lifetime-list '>' ] '|' arg-list '|'
-                [ ':' bound-list ] [ '->' type ]
-lifetime-list := lifetime | lifetime ',' lifetime-list
-arg-list := ident ':' type | ident ':' type ',' arg-list
-bound-list := bound | bound '+' bound-list
-bound := path | lifetime
-```
+A [lambda expression](#lambda-expressions) produces a closure value with
+a unique, anonymous type that cannot be written out.
 
-The type of a closure mapping an input of type `A` to an output of type `B` is
-`|A| -> B`. A closure with no arguments or return values has type `||`.
+Depending on the requirements of the closure, its type implements one or
+more of the closure traits:
 
-An example of creating and calling a closure:
+* `FnOnce`
+  : The closure can be called once. A closure called as `FnOnce`
+    can move out values from its environment.
 
-```rust
-let captured_var = 10;
+* `FnMut`
+  : The closure can be called multiple times as mutable. A closure called as
+    `FnMut` can mutate values from its environment. `FnMut` implies
+    `FnOnce`.
 
-let closure_no_args = || println!("captured_var={}", captured_var);
+* `Fn`
+  : The closure can be called multiple times through a shared reference.
+    A closure called as `Fn` can neither move out from nor mutate values
+    from its environment. `Fn` implies `FnMut` and `FnOnce`.
 
-let closure_args = |arg: i32| -> i32 {
-  println!("captured_var={}, arg={}", captured_var, arg);
-  arg // Note lack of semicolon after 'arg'
-};
-
-fn call_closure<F: Fn(), G: Fn(i32) -> i32>(c1: F, c2: G) {
-  c1();
-  c2(2);
-}
-
-call_closure(closure_no_args, closure_args);
-
-```
 
-### Object types
+### Trait objects
 
 Every trait item (see [traits](#traits)) defines a type with the same name as
-the trait. This type is called the _object type_ of the trait. Object types
+the trait. This type is called the _trait object_ of the trait. Trait objects
 permit "late binding" of methods, dispatched using _virtual method tables_
 ("vtables"). Whereas most calls to trait methods are "early bound" (statically
 resolved) to specific implementations at compile time, a call to a method on an
-object type is only resolved to a vtable entry at compile time. The actual
+trait objects is only resolved to a vtable entry at compile time. The actual
 implementation for each vtable entry can vary on an object-by-object basis.
 
 Given a pointer-typed expression `E` of type `&T` or `Box<T>`, where `T`
 implements trait `R`, casting `E` to the corresponding pointer type `&R` or
-`Box<R>` results in a value of the _object type_ `R`. This result is
+`Box<R>` results in a value of the _trait object_ `R`. This result is
 represented as a pair of pointers: the vtable pointer for the `T`
 implementation of `R`, and the pointer value of `E`.
 
-An example of an object type:
+An example of a trait object:
 
 ```
 trait Printable {
@@ -3778,7 +3389,7 @@ fn main() {
 }
 ```
 
-In this example, the trait `Printable` occurs as an object type in both the
+In this example, the trait `Printable` occurs as a trait object in both the
 type signature of `print`, and the cast expression in `main`.
 
 ### Type parameters
@@ -3787,19 +3398,19 @@ Within the body of an item that has type parameter declarations, the names of
 its type parameters are types:
 
 ```ignore
-fn map<A: Clone, B: Clone>(f: |A| -> B, xs: &[A]) -> Vec<B> {
+fn to_vec<A: Clone>(xs: &[A]) -> Vec<A> {
     if xs.is_empty() {
        return vec![];
     }
-    let first: B = f(xs[0].clone());
-    let mut rest: Vec<B> = map(f, xs.slice(1, xs.len()));
+    let first: A = xs[0].clone();
+    let mut rest: Vec<A> = to_vec(&xs[1..]);
     rest.insert(0, first);
-    return rest;
+    rest
 }
 ```
 
-Here, `first` has type `B`, referring to `map`'s `B` type parameter; and `rest`
-has type `Vec<B>`, a vector type with element type `B`.
+Here, `first` has type `A`, referring to `to_vec`'s `A` type parameter; and `rest`
+has type `Vec<A>`, a vector with element type `A`.
 
 ### Self types
 
index 813660d8fdfb945e90196b3c5518d27688e71ce3..dbbe9fc3ac6da92602304f64de31b07afa01e80a 100644 (file)
@@ -1,10 +1,10 @@
 % 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
+Unit tests should live in a `tests` submodule at the bottom of the module they
+test. Mark the `tests` submodule with `#[cfg(test)]` so it is only compiled when
 testing.
 
-The `test` module should contain:
+The `tests` module should contain:
 
 * Imports needed only for testing.
 * Functions marked with `#[test]` striving for full coverage of the parent module's
@@ -17,7 +17,7 @@ For example:
 // Excerpt from std::str
 
 #[cfg(test)]
-mod test {
+mod tests {
     #[test]
     fn test_eq() {
         assert!((eq(&"".to_owned(), &"".to_owned())));
index 8d3a6ec39864c7256d4cc4d10a69a311c2bf0455..01ef88dde227024c54e050e502f4ed06577025f3 100644 (file)
@@ -24,6 +24,7 @@ is the first. After this:
 * [Syntax and Semantics][ss] - Each bit of Rust, broken down into small chunks.
 * [Nightly Rust][nr] - Cutting-edge features that aren’t in stable builds yet.
 * [Glossary][gl] - A reference of terms used in the book.
+* [Academic Research][ar] - Literature that influenced Rust.
 
 [gs]: getting-started.html
 [lr]: learn-rust.html
@@ -31,6 +32,7 @@ is the first. After this:
 [ss]: syntax-and-semantics.html
 [nr]: nightly-rust.html
 [gl]: glossary.html
+[ar]: academic-research.html
 
 After reading this introduction, you’ll want to dive into either ‘Learn Rust’
 or ‘Syntax and Semantics’, depending on your preference: ‘Learn Rust’ if you
@@ -165,7 +167,7 @@ fn main() {
 
 Rust has [move semantics][move] by default, so if we want to make a copy of some
 data, we call the `clone()` method. In this example, `y` is no longer a reference
-to the vector stored in `x`, but a copy of its first element, `"hello"`. Now
+to the vector stored in `x`, but a copy of its first element, `"Hello"`. Now
 that we don’t have a reference, our `push()` works just fine.
 
 [move]: move-semantics.html
index f2d1666048d89773cb3a5745616edc4e0dc7d30f..695dc42cb6418a7d9694fe07f48235009bcf8c5d 100644 (file)
@@ -7,14 +7,13 @@
 * [Learn Rust](learn-rust.md)
 * [Effective Rust](effective-rust.md)
     * [The Stack and the Heap](the-stack-and-the-heap.md)
-    * [Debug and Display](debug-and-display.md)
     * [Testing](testing.md)
+    * [Conditional Compilation](conditional-compilation.md)
     * [Documentation](documentation.md)
     * [Iterators](iterators.md)
     * [Concurrency](concurrency.md)
     * [Error Handling](error-handling.md)
     * [FFI](ffi.md)
-    * [Deref coercions](deref-coercions.md)
 * [Syntax and Semantics](syntax-and-semantics.md)
     * [Variable Bindings](variable-bindings.md)
     * [Functions](functions.md)
     * [Move semantics](move-semantics.md)
     * [Enums](enums.md)
     * [Match](match.md)
-    * [Patterns](patterns.md)
     * [Structs](structs.md)
+    * [Patterns](patterns.md)
     * [Method Syntax](method-syntax.md)
-    * [Drop](drop.md)
     * [Vectors](vectors.md)
     * [Strings](strings.md)
-    * [Traits](traits.md)
-    * [Operators and Overloading](operators-and-overloading.md)
     * [Generics](generics.md)
+    * [Traits](traits.md)
+    * [Drop](drop.md)
     * [if let](if-let.md)
     * [Trait Objects](trait-objects.md)
     * [Closures](closures.md)
     * [Universal Function Call Syntax](ufcs.md)
     * [Crates and Modules](crates-and-modules.md)
-    * [`static`](static.md)
-    * [`const`](const.md)
+    * [`const` and `static`](const-and-static.md)
     * [Tuple Structs](tuple-structs.md)
     * [Attributes](attributes.md)
-    * [Conditional Compilation](conditional-compilation.md)
     * [`type` aliases](type-aliases.md)
     * [Casting between types](casting-between-types.md)
     * [Associated Types](associated-types.md)
     * [Unsized Types](unsized-types.md)
+    * [Operators and Overloading](operators-and-overloading.md)
+    * [Deref coercions](deref-coercions.md)
     * [Macros](macros.md)
-    * [`unsafe` Code](unsafe-code.md)
+    * [Raw Pointers](raw-pointers.md)
+    * [`unsafe`](unsafe.md)
 * [Nightly Rust](nightly-rust.md)
     * [Compiler Plugins](compiler-plugins.md)
     * [Inline Assembly](inline-assembly.md)
index d59239016d881d998529ecb8716cfd5ef02f2fed..55e2787cc2591032f349e564f06f9bd84e88779f 100644 (file)
@@ -1,8 +1,8 @@
 % Associated Types
 
-Associated types are a powerful part of Rust's type system. They're related to
-the idea of a 'type family', in other words, grouping multiple types together. That
-description is a bit abstract, so let's dive right into an example. If you want
+Associated types are a powerful part of Rust’s type system. They’re related to
+the idea of a ‘type family’, in other words, grouping multiple types together. That
+description is a bit abstract, so lets dive right into an example. If you want
 to write a `Graph` trait, you have two types to be generic over: the node type
 and the edge type. So you might write a trait, `Graph<N, E>`, that looks like
 this:
@@ -48,11 +48,11 @@ fn distance<G: Graph>(graph: &G, start: &G::N, end: &G::N) -> uint { ... }
 
 No need to deal with the `E`dge type here!
 
-Let's go over all this in more detail.
+Lets go over all this in more detail.
 
 ## Defining associated types
 
-Let's build that `Graph` trait. Here's the definition:
+Let’s build that `Graph` trait. Here’s the definition:
 
 ```rust
 trait Graph {
@@ -86,7 +86,7 @@ trait Graph {
 ## Implementing associated types
 
 Just like any trait, traits that use associated types use the `impl` keyword to
-provide implementations. Here's a simple implementation of Graph:
+provide implementations. Heres a simple implementation of Graph:
 
 ```rust
 # trait Graph {
@@ -118,13 +118,13 @@ impl Graph for MyGraph {
 This silly implementation always returns `true` and an empty `Vec<Edge>`, but it
 gives you an idea of how to implement this kind of thing. We first need three
 `struct`s, one for the graph, one for the node, and one for the edge. If it made
-more sense to use a different type, that would work as well, we're just going to
+more sense to use a different type, that would work as well, were just going to
 use `struct`s for all three here.
 
 Next is the `impl` line, which is just like implementing any other trait.
 
 From here, we use `=` to define our associated types. The name the trait uses
-goes on the left of the `=`, and the concrete type we're `impl`ementing this
+goes on the left of the `=`, and the concrete type were `impl`ementing this
 for goes on the right. Finally, we use the concrete types in our function
 declarations.
 
index e699bd85f6ed7309dadf4889ade054d54e493682..54195a5063b7c0b03c3817b59a351c2c7380973e 100644 (file)
@@ -1,3 +1,70 @@
 % Attributes
 
-Coming Soon!
+Declarations can be annotated with ‘attributes’ in Rust. They look like this:
+
+```rust
+#[test]
+# fn foo() {}
+```
+
+or like this:
+
+```rust
+# mod foo {
+#![test]
+# }
+```
+
+The difference between the two is the `!`, which changes what the attribute
+applies to:
+
+```rust,ignore
+#[foo]
+struct Foo;
+
+mod bar {
+    #![bar]
+}
+```
+
+The `#[foo]` attribute applies to the next item, which is the `struct`
+declaration. The `#![bar]` attribute applies to the item enclosing it, which is
+the `mod` declaration. Otherwise, they’re the same. Both change the meaning of
+the item they’re attached to somehow.
+
+For example, consider a function like this:
+
+```rust
+#[test]
+fn check() {
+    assert_eq!(2, 1 + 1);
+}
+```
+
+It is marked with `#[test]`. This means it’s special: when you run
+[tests][tests], this function will execute. When you compile as usual, it won’t
+even be included. This function is now a test function.
+
+[tests]: testing.html
+
+Attributes may also have additional data:
+
+```rust
+#[inline(always)]
+fn super_fast_fn() {
+# }
+```
+
+Or even keys and values:
+
+```rust
+#[cfg(target_os = "macos")]
+mod macos_only {
+# }
+```
+
+Rust attributes are used for a number of different things. There is a full list
+of attributes [in the reference][reference]. Currently, you are not allowed to
+create your own attributes, the Rust compiler defines them.
+
+[reference]: reference.html#attributes
index 8bb0ec6db0256c12b44471258313449b972d2f55..f0c673b561a0ee2f662fd6f0a67b02c8a7eebff2 100644 (file)
@@ -1,3 +1,89 @@
 % Casting Between Types
 
-Coming Soon
+Rust, with its focus on safety, provides two different ways of casting
+different types between each other. The first, `as`, is for safe casts.
+In contrast, `transmute` allows for arbitrary casting, and is one of the
+most dangerous features of Rust!
+
+# `as`
+
+The `as` keyword does basic casting:
+
+```rust
+let x: i32 = 5;
+
+let y = x as i64;
+```
+
+It only allows certain kinds of casting, however:
+
+```rust,ignore
+let a = [0u8, 0u8, 0u8, 0u8];
+
+let b = a as u32; // four eights makes 32
+```
+
+This errors with:
+
+```text
+error: non-scalar cast: `[u8; 4]` as `u32`
+let b = a as u32; // four eights makes 32
+        ^~~~~~~~
+```
+
+It’s a ‘non-scalar cast’ because we have multiple values here: the four
+elements of the array. These kinds of casts are very dangerous, because they
+make assumptions about the way that multiple underlying structures are
+implemented. For this, we need something more dangerous.
+
+# `transmute`
+
+The `transmute` function is provided by a [compiler intrinsic][intrinsics], and
+what it does is very simple, but very scary. It tells Rust to treat a value of
+one type as though it were another type. It does this regardless of the
+typechecking system, and just completely trusts you.
+
+[intrinsic]: intrinsics.html
+
+In our previous example, we know that an array of four `u8`s represents a `u32`
+properly, and so we want to do the cast. Using `transmute` instead of `as`,
+Rust lets us:
+
+```rust
+use std::mem;
+
+unsafe {
+    let a = [0u8, 0u8, 0u8, 0u8];
+
+    let b = mem::transmute::<[u8; 4], u32>(a);
+}
+```
+
+We have to wrap the operation in an `unsafe` block for this to compile
+successfully. Technically, only the `mem::transmute` call itself needs to be in
+the block, but it's nice in this case to enclose everything related, so you
+know where to look. In this case, the details about `a` are also important, and
+so they're in the block. You'll see code in either style, sometimes the context
+is too far away, and wrapping all of the code in `unsafe` isn't a great idea.
+
+While `transmute` does very little checking, it will at least make sure that
+the types are the same size. This errors:
+
+```rust,ignore
+use std::mem;
+
+unsafe {
+    let a = [0u8, 0u8, 0u8, 0u8];
+
+    let b = mem::transmute::<[u8; 4], u64>(a);
+}
+```
+
+with:
+
+```text
+error: transmute called on types with different sizes: [u8; 4] (32 bits) to u64
+(64 bits)
+```
+
+Other than that, you're on your own!
index e3de8eb30be916336b8739545a01783d6bceec18..604dcb739df63812f18e56600fd1978bddc991b8 100644 (file)
@@ -1,9 +1,9 @@
 % Closures
 
 Rust not only has named functions, but anonymous functions as well. Anonymous
-functions that have an associated environment are called 'closures', because they
+functions that have an associated environment are called ‘closures’, because they
 close over an environment. Rust has a really great implementation of them, as
-we'll see.
+well see.
 
 # Syntax
 
@@ -15,7 +15,7 @@ let plus_one = |x: i32| x + 1;
 assert_eq!(2, plus_one(1));
 ```
 
-We create a binding, `plus_one`, and assign it to a closure. The closure's
+We create a binding, `plus_one`, and assign it to a closure. The closures
 arguments go between the pipes (`|`), and the body is an expression, in this
 case, `x + 1`. Remember that `{ }` is an expression, so we can have multi-line
 closures too:
@@ -33,7 +33,7 @@ let plus_two = |x| {
 assert_eq!(4, plus_two(2));
 ```
 
-You'll notice a few things about closures that are a bit different than regular
+Youll notice a few things about closures that are a bit different than regular
 functions defined with `fn`. The first of which is that we did not need to
 annotate the types of arguments the closure takes or the values it returns. We
 can:
@@ -44,13 +44,13 @@ let plus_one = |x: i32| -> i32 { x + 1 };
 assert_eq!(2, plus_one(1));
 ```
 
-But we don't have to. Why is this? Basically, it was chosen for ergonomic reasons.
+But we dont have to. Why is this? Basically, it was chosen for ergonomic reasons.
 While specifying the full type for named functions is helpful with things like
 documentation and type inference, the types of closures are rarely documented
 since they’re anonymous, and they don’t cause the kinds of error-at-a-distance
 that inferring named function types can.
 
-The second is that the syntax is similar, but a bit different. I've added spaces
+The second is that the syntax is similar, but a bit different. Ive added spaces
 here to make them look a little closer:
 
 ```rust
@@ -59,11 +59,11 @@ let plus_one_v2 = |x: i32 | -> i32 { x + 1 };
 let plus_one_v3 = |x: i32 |          x + 1  ;
 ```
 
-Small differences, but they're similar in ways.
+Small differences, but theyre similar in ways.
 
 # Closures and their environment
 
-Closures are called such because they 'close over their environment.' It
+Closures are called such because they ‘close over their environment’. It
 looks like this:
 
 ```rust
@@ -105,7 +105,7 @@ fn main() {
 ^
 ```
 
-A verbose yet helpful error message! As it says, we can't take a mutable borrow
+A verbose yet helpful error message! As it says, we cant take a mutable borrow
 on `num` because the closure is already borrowing it. If we let the closure go
 out of scope, we can:
 
@@ -140,7 +140,7 @@ let takes_nums = || nums;
 ```
 
 `Vec<T>` has ownership over its contents, and therefore, when we refer to it
-in our closure, we have to take ownership of `nums`. It's the same as if we'd
+in our closure, we have to take ownership of `nums`. It’s the same as if we’d
 passed `nums` to a function that took ownership of it.
 
 ## `move` closures
@@ -156,7 +156,7 @@ let owns_num = move |x: i32| x + num;
 
 Now, even though the keyword is `move`, the variables follow normal move semantics.
 In this case, `5` implements `Copy`, and so `owns_num` takes ownership of a copy
-of `num`. So what's the difference?
+of `num`. So whats the difference?
 
 ```rust
 let mut num = 5;
@@ -171,11 +171,11 @@ assert_eq!(10, num);
 ```
 
 So in this case, our closure took a mutable reference to `num`, and then when
-we called `add_num`, it mutated the underlying value, as we'd expect. We also
+we called `add_num`, it mutated the underlying value, as wed expect. We also
 needed to declare `add_num` as `mut` too, because we’re mutating its
 environment.
 
-If we change to a `move` closure, it's different:
+If we change to a `move` closure, its different:
 
 ```rust
 let mut num = 5;
@@ -203,8 +203,8 @@ you tons of control over what your code does, and closures are no different.
 
 # Closure implementation
 
-Rust's implementation of closures is a bit different than other languages. They
-are effectively syntax sugar for traits. You'll want to make sure to have read
+Rusts implementation of closures is a bit different than other languages. They
+are effectively syntax sugar for traits. Youll want to make sure to have read
 the [traits chapter][traits] before this one, as well as the chapter on [trait
 objects][trait-objects].
 
@@ -237,9 +237,9 @@ pub trait FnOnce<Args> {
 # }
 ```
 
-You'll notice a few differences between these traits, but a big one is `self`:
+Youll notice a few differences between these traits, but a big one is `self`:
 `Fn` takes `&self`, `FnMut` takes `&mut self`, and `FnOnce` takes `self`. This
-covers all three kinds of `self` via the usual method call syntax. But we've
+covers all three kinds of `self` via the usual method call syntax. But weve
 split them up into three traits, rather than having a single one. This gives us
 a large amount of control over what kind of closures we can take.
 
@@ -253,7 +253,7 @@ Now that we know that closures are traits, we already know how to accept and
 return closures: just like any other trait!
 
 This also means that we can choose static vs dynamic dispatch as well. First,
-let's write a function which takes something callable, calls it, and returns
+lets write a function which takes something callable, calls it, and returns
 the result:
 
 ```rust
@@ -271,7 +271,7 @@ assert_eq!(3, answer);
 We pass our closure, `|x| x + 2`, to `call_with_one`. It just does what it
 suggests: it calls the closure, giving it `1` as an argument.
 
-Let's examine the signature of `call_with_one` in more depth:
+Lets examine the signature of `call_with_one` in more depth:
 
 ```rust
 fn call_with_one<F>(some_closure: F) -> i32
@@ -280,7 +280,7 @@ fn call_with_one<F>(some_closure: F) -> i32
 ```
 
 We take one parameter, and it has the type `F`. We also return a `i32`. This part
-isn't interesting. The next part is:
+isnt interesting. The next part is:
 
 ```rust
 # fn call_with_one<F>(some_closure: F) -> i32
@@ -292,9 +292,9 @@ Because `Fn` is a trait, we can bound our generic with it. In this case, our clo
 takes a `i32` as an argument and returns an `i32`, and so the generic bound we use
 is `Fn(i32) -> i32`.
 
-There's one other key point here: because we're bounding a generic with a
-trait, this will get monomorphized, and therefore, we'll be doing static
-dispatch into the closure. That's pretty neat. In many langauges, closures are
+There’s one other key point here: because we’re bounding a generic with a
+trait, this will get monomorphized, and therefore, well be doing static
+dispatch into the closure. Thats pretty neat. In many langauges, closures are
 inherently heap allocated, and will always involve dynamic dispatch. In Rust,
 we can stack allocate our closure environment, and statically dispatch the
 call. This happens quite often with iterators and their adapters, which often
@@ -320,7 +320,7 @@ to our closure when we pass it to `call_with_one`, so we use `&||`.
 
 It’s very common for functional-style code to return closures in various
 situations. If you try to return a closure, you may run into an error. At
-first, it may seem strange, but we'll figure it out. Here's how you'd probably
+first, it may seem strange, but we’ll figure it out. Here’s how you’d probably
 try to return a closure from a function:
 
 ```rust,ignore
@@ -361,7 +361,7 @@ In order to return something from a function, Rust needs to know what
 size the return type is. But since `Fn` is a trait, it could be various
 things of various sizes: many different types can implement `Fn`. An easy
 way to give something a size is to take a reference to it, as references
-have a known size. So we'd write this:
+have a known size. So wed write this:
 
 ```rust,ignore
 fn factory() -> &(Fn(i32) -> Vec<i32>) {
@@ -385,7 +385,7 @@ fn factory() -> &(Fn(i32) -> i32) {
 ```
 
 Right. Because we have a reference, we need to give it a lifetime. But
-our `factory()` function takes no arguments, so elision doesn't kick in
+our `factory()` function takes no arguments, so elision doesnt kick in
 here. What lifetime can we choose? `'static`:
 
 ```rust,ignore
@@ -414,7 +414,7 @@ error: mismatched types:
 
 ```
 
-This error is letting us know that we don't have a `&'static Fn(i32) -> i32`,
+This error is letting us know that we dont have a `&'static Fn(i32) -> i32`,
 we have a `[closure <anon>:7:9: 7:20]`. Wait, what?
 
 Because each closure generates its own environment `struct` and implementation
@@ -422,7 +422,7 @@ of `Fn` and friends, these types are anonymous. They exist just solely for
 this closure. So Rust shows them as `closure <anon>`, rather than some
 autogenerated name.
 
-But why doesn't our closure implement `&'static Fn`? Well, as we discussed before,
+But why doesnt our closure implement `&'static Fn`? Well, as we discussed before,
 closures borrow their environment. And in this case, our environment is based
 on a stack-allocated `5`, the `num` variable binding. So the borrow has a lifetime
 of the stack frame. So if we returned this closure, the function call would be
@@ -445,7 +445,7 @@ assert_eq!(6, answer);
 # }
 ```
 
-We use a trait object, by `Box`ing up the `Fn`. There's just one last problem:
+We use a trait object, by `Box`ing up the `Fn`. Theres just one last problem:
 
 ```text
 error: `num` does not live long enough
@@ -471,5 +471,5 @@ assert_eq!(6, answer);
 ```
 
 By making the inner closure a `move Fn`, we create a new stack frame for our
-closure. By `Box`ing it up, we've given it a known size, and allowing it to
+closure. By `Box`ing it up, weve given it a known size, and allowing it to
 escape our stack frame.
index 40367fa844d2ebceae3e5c9874fa1ca094d22779..73eb0101692afb9eec313d7202f69c93489fbf76 100644 (file)
@@ -1,3 +1,93 @@
 % Conditional Compilation
 
-Coming Soon!
+Rust has a special attribute, `#[cfg]`, which allows you to compile code
+based on a flag passed to the compiler. It has two forms:
+
+```rust
+#[cfg(foo)]
+# fn foo() {}
+
+#[cfg(bar = "baz")]
+# fn bar() {}
+```
+
+They also have some helpers:
+
+```rust
+#[cfg(any(unix, windows))]
+# fn foo() {}
+
+#[cfg(all(unix, target_pointer_width = "32"))]
+# fn bar() {}
+
+#[cfg(not(foo))]
+# fn not_foo() {}
+```
+
+These can nest arbitrarily:
+
+```rust
+#[cfg(any(not(unix), all(target_os="macos", target_arch = "powerpc")))]
+# fn foo() {}
+```
+
+As for how to enable or disable these switches, if you’re using Cargo,
+they get set in the [`[features]` section][features] of your `Cargo.toml`:
+
+[features]: http://doc.crates.io/manifest.html#the-[features]-section
+
+```toml
+[features]
+# no features by default
+default = []
+
+# The “secure-password” feature depends on the bcrypt package.
+secure-password = ["bcrypt"]
+```
+
+When you do this, Cargo passes along a flag to `rustc`:
+
+```text
+--cfg feature="${feature_name}"
+```
+
+The sum of these `cfg` flags will determine which ones get activated, and
+therefore, which code gets compiled. Let’s take this code:
+
+```rust
+#[cfg(feature = "foo")]
+mod foo {
+}
+```
+
+If we compile it with `cargo build --features "foo"`, it will send the `--cfg
+feature="foo"` flag to `rustc`, and the output will have the `mod foo` in it.
+If we compile it with a regular `cargo build`, no extra flags get passed on,
+and so, no `foo` module will exist.
+
+# cfg_attr
+
+You can also set another attribute based on a `cfg` variable with `cfg_attr`:
+
+```rust
+#[cfg_attr(a, b)]
+# fn foo() {}
+```
+
+Will be the same as `#[b]` if `a` is set by `cfg` attribute, and nothing otherwise.
+
+# cfg!
+
+The `cfg!` [syntax extension][compilerplugins] lets you use these kinds of flags
+elsewhere in your code, too:
+
+```rust
+if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
+    println!("Think Different!");
+}
+```
+
+[compilerplugins]: compiler-plugins.html
+
+These will be replaced by a `true` or `false` at compile-time, depending on the
+configuration settings.
diff --git a/src/doc/trpl/const-and-static.md b/src/doc/trpl/const-and-static.md
new file mode 100644 (file)
index 0000000..a9d33cc
--- /dev/null
@@ -0,0 +1,86 @@
+% `const` and `static`
+
+Rust has a way of defining constants with the `const` keyword:
+
+```rust
+const N: i32 = 5;
+```
+
+Unlike [`let`][let] bindings, you must annotate the type of a `const`.
+
+[let]: variable-bindings.html
+
+Constants live for the entire lifetime of a program. More specifically,
+constants in Rust have no fixed address in memory. This is because they’re
+effectively inlined to each place that they’re used. References to the same
+constant are not necessarily guaranteed to refer to the same memory address for
+this reason.
+
+# `static`
+
+Rust provides a ‘global variable’ sort of facility in static items. They’re
+similar to [constants][const], but static items aren’t inlined upon use. This
+means that there is only one instance for each value, and it’s at a fixed
+location in memory.
+
+Here’s an example:
+
+```rust
+static N: i32 = 5;
+```
+
+[const]: const.html
+
+Unlike [`let`][let] bindings, you must annotate the type of a `static`.
+
+[let]: variable-bindings.html
+
+Statics live for the entire lifetime of a program, and therefore any
+reference stored in a constant has a [`’static` lifetime][lifetimes]:
+
+```rust
+static NAME: &'static str = "Steve";
+```
+
+[lifetimes]: lifetimes.html
+
+## Mutability
+
+You can introduce mutability with the `mut` keyword:
+
+```rust
+static mut N: i32 = 5;
+```
+
+Because this is mutable, one thread could be updating `N` while another is
+reading it, causing memory unsafety. As such both accessing and mutating a
+`static mut` is [`unsafe`][unsafe], and so must be done in an `unsafe` block:
+
+```rust
+# static mut N: i32 = 5;
+
+unsafe {
+    N += 1;
+
+    println!("N: {}", N);
+}
+```
+
+Furthermore, any type stored in a `static` must be `Sync`.
+
+# Initializing
+
+Both `const` and `static` have requirements for giving them a value. They may
+only be given a value that’s a constant expression. In other words, you cannot
+use the result of a function call or anything similarly complex or at runtime.
+
+# Which construct should I use?
+
+Almost always, if you can choose between the two, choose `const`. It’s pretty
+rare that you actually want a memory location associated with your constant,
+and using a const allows for optimizations like constant propagation not only
+in your crate but downstream crates.
+
+A const can be thought of as a `#define` in C: it has metadata overhead but it
+has no runtime overhead. “Should I use a #define or a static in C,” is largely
+the same question as whether you should use a const or a static in Rust.
diff --git a/src/doc/trpl/const.md b/src/doc/trpl/const.md
deleted file mode 100644 (file)
index 9234c4f..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-% `const`
-
-Coming soon!
index 83e8cc629fd5e3e464b7e7cdc147e10632d024b0..3ab3401e61264d046ddb81a3b8449d796a43e8da 100644 (file)
@@ -1,16 +1,16 @@
 % Crates and Modules
 
-When a project starts getting large, it's considered good software
+When a project starts getting large, its considered good software
 engineering practice to split it up into a bunch of smaller pieces, and then
-fit them together. It's also important to have a well-defined interface, so
+fit them together. Its also important to have a well-defined interface, so
 that some of your functionality is private, and some is public. To facilitate
 these kinds of things, Rust has a module system.
 
 # Basic terminology: Crates and Modules
 
-Rust has two distinct terms that relate to the module system: *crate* and
-*module*. A crate is synonymous with a *library* or *package* in other
-languages. Hence "Cargo" as the name of Rust's package management tool: you
+Rust has two distinct terms that relate to the module system: ‘crate’ and
+‘module’. A crate is synonymous with a ‘library’ or ‘package’ in other
+languages. Hence “Cargo” as the name of Rust’s package management tool: you
 ship your crates to others with Cargo. Crates can produce an executable or a
 library, depending on the project.
 
@@ -18,10 +18,10 @@ Each crate has an implicit *root module* that contains the code for that crate.
 You can then define a tree of sub-modules under that root module. Modules allow
 you to partition your code within the crate itself.
 
-As an example, let's make a *phrases* crate, which will give us various phrases
-in different languages. To keep things simple, we'll stick to "greetings" and
-"farewells" as two kinds of phrases, and use English and Japanese (日本語) as
-two languages for those phrases to be in. We'll use this module layout:
+As an example, lets make a *phrases* crate, which will give us various phrases
+in different languages. To keep things simple, we’ll stick to ‘greetings’ and
+‘farewells’ as two kinds of phrases, and use English and Japanese (日本語) as
+two languages for those phrases to be in. Well use this module layout:
 
 ```text
                                     +-----------+
@@ -47,7 +47,7 @@ In this example, `phrases` is the name of our crate. All of the rest are
 modules.  You can see that they form a tree, branching out from the crate
 *root*, which is the root of the tree: `phrases` itself.
 
-Now that we have a plan, let's define these modules in code. To start,
+Now that we have a plan, lets define these modules in code. To start,
 generate a new crate with Cargo:
 
 ```bash
@@ -72,7 +72,7 @@ above.
 
 # Defining Modules
 
-To define each of our modules, we use the `mod` keyword. Let's make our
+To define each of our modules, we use the `mod` keyword. Lets make our
 `src/lib.rs` look like this:
 
 ```
@@ -101,7 +101,7 @@ Within a given `mod`, you can declare sub-`mod`s. We can refer to sub-modules
 with double-colon (`::`) notation: our four nested modules are
 `english::greetings`, `english::farewells`, `japanese::greetings`, and
 `japanese::farewells`. Because these sub-modules are namespaced under their
-parent module, the names don't conflict: `english::greetings` and
+parent module, the names dont conflict: `english::greetings` and
 `japanese::greetings` are distinct, even though their names are both
 `greetings`.
 
@@ -116,11 +116,11 @@ build  deps  examples  libphrases-a7448e02a0468eaa.rlib  native
 ```
 
 `libphrase-hash.rlib` is the compiled crate. Before we see how to use this
-crate from another crate, let's break it up into multiple files.
+crate from another crate, lets break it up into multiple files.
 
 # Multiple file crates
 
-If each crate were just one file, these files would get very large. It's often
+If each crate were just one file, these files would get very large. Its often
 easier to split up crates into multiple files, and Rust supports this in two
 ways.
 
@@ -141,7 +141,7 @@ mod english;
 If we do that, Rust will expect to find either a `english.rs` file, or a
 `english/mod.rs` file with the contents of our module.
 
-Note that in these files, you don't need to re-declare the module: that's
+Note that in these files, you don’t need to re-declare the module: that’s
 already been done with the initial `mod` declaration.
 
 Using these two techniques, we can break up our crate into two directories and
@@ -180,7 +180,7 @@ mod japanese;
 
 These two declarations tell Rust to look for either `src/english.rs` and
 `src/japanese.rs`, or `src/english/mod.rs` and `src/japanese/mod.rs`, depending
-on our preference. In this case, because our modules have sub-modules, we've
+on our preference. In this case, because our modules have sub-modules, weve
 chosen the second. Both `src/english/mod.rs` and `src/japanese/mod.rs` look
 like this:
 
@@ -192,11 +192,11 @@ mod farewells;
 Again, these declarations tell Rust to look for either
 `src/english/greetings.rs` and `src/japanese/greetings.rs` or
 `src/english/farewells/mod.rs` and `src/japanese/farewells/mod.rs`. Because
-these sub-modules don't have their own sub-modules, we've chosen to make them
+these sub-modules don’t have their own sub-modules, we’ve chosen to make them
 `src/english/greetings.rs` and `src/japanese/farewells.rs`. Whew!
 
 The contents of `src/english/greetings.rs` and `src/japanese/farewells.rs` are
-both empty at the moment. Let's add some functions.
+both empty at the moment. Lets add some functions.
 
 Put this in `src/english/greetings.rs`:
 
@@ -223,7 +223,7 @@ fn hello() -> String {
 ```
 
 Of course, you can copy and paste this from this web page, or just type
-something else. It's not important that you actually put "konnichiwa" to learn
+something else. It’s not important that you actually put ‘konnichiwa’ to learn
 about the module system.
 
 Put this in `src/japanese/farewells.rs`:
@@ -234,17 +234,17 @@ fn goodbye() -> String {
 }
 ```
 
-(This is "Sayōnara", if you're curious.)
+(This is ‘Sayōnara’, if you’re curious.)
 
-Now that we have some functionality in our crate, let's try to use it from
+Now that we have some functionality in our crate, lets try to use it from
 another crate.
 
 # Importing External Crates
 
-We have a library crate. Let's make an executable crate that imports and uses
+We have a library crate. Lets make an executable crate that imports and uses
 our library.
 
-Make a `src/main.rs` and put this in it (it won't quite compile yet):
+Make a `src/main.rs` and put this in it (it wont quite compile yet):
 
 ```rust,ignore
 extern crate phrases;
@@ -259,7 +259,7 @@ fn main() {
 ```
 
 The `extern crate` declaration tells Rust that we need to compile and link to
-the `phrases` crate. We can then use `phrases`' modules in this one. As we
+the `phrases` crate. We can then use `phrases` modules in this one. As we
 mentioned earlier, you can use double colons to refer to sub-modules and the
 functions inside of them.
 
@@ -267,10 +267,10 @@ Also, Cargo assumes that `src/main.rs` is the crate root of a binary crate,
 rather than a library crate. Our package now has two crates: `src/lib.rs` and
 `src/main.rs`. This pattern is quite common for executable crates: most
 functionality is in a library crate, and the executable crate uses that
-library. This way, other programs can also use the library crate, and it's also
+library. This way, other programs can also use the library crate, and its also
 a nice separation of concerns.
 
-This doesn't quite work yet, though. We get four errors that look similar to
+This doesnt quite work yet, though. We get four errors that look similar to
 this:
 
 ```bash
@@ -287,14 +287,14 @@ note: in expansion of format_args!
 phrases/src/main.rs:4:5: 4:76 note: expansion site
 ```
 
-By default, everything is private in Rust. Let's talk about this in some more
+By default, everything is private in Rust. Lets talk about this in some more
 depth.
 
 # Exporting a Public Interface
 
 Rust allows you to precisely control which aspects of your interface are
 public, and so private is the default. To make things public, you use the `pub`
-keyword. Let's focus on the `english` module first, so let's reduce our `src/main.rs`
+keyword. Let’s focus on the `english` module first, so let’s reduce our `src/main.rs`
 to just this:
 
 ```{rust,ignore}
@@ -306,21 +306,21 @@ fn main() {
 }
 ```
 
-In our `src/lib.rs`, let's add `pub` to the `english` module declaration:
+In our `src/lib.rs`, lets add `pub` to the `english` module declaration:
 
 ```{rust,ignore}
 pub mod english;
 mod japanese;
 ```
 
-And in our `src/english/mod.rs`, let's make both `pub`:
+And in our `src/english/mod.rs`, lets make both `pub`:
 
 ```{rust,ignore}
 pub mod greetings;
 pub mod farewells;
 ```
 
-In our `src/english/greetings.rs`, let's add `pub` to our `fn` declaration:
+In our `src/english/greetings.rs`, lets add `pub` to our `fn` declaration:
 
 ```{rust,ignore}
 pub fn hello() -> String {
@@ -358,12 +358,12 @@ Goodbye in English: Goodbye.
 Now that our functions are public, we can use them. Great! However, typing out
 `phrases::english::greetings::hello()` is very long and repetitive. Rust has
 another keyword for importing names into the current scope, so that you can
-refer to them with shorter names. Let's talk about `use`.
+refer to them with shorter names. Lets talk about `use`.
 
 # Importing Modules with `use`
 
 Rust has a `use` keyword, which allows us to import names into our local scope.
-Let's change our `src/main.rs` to look like this:
+Lets change our `src/main.rs` to look like this:
 
 ```{rust,ignore}
 extern crate phrases;
@@ -378,7 +378,7 @@ fn main() {
 ```
 
 The two `use` lines import each module into the local scope, so we can refer to
-the functions by a much shorter name. By convention, when importing functions, it's
+the functions by a much shorter name. By convention, when importing functions, its
 considered best practice to import the module, rather than the function directly. In
 other words, you _can_ do this:
 
@@ -395,7 +395,7 @@ fn main() {
 ```
 
 But it is not idiomatic. This is significantly more likely to introduce a
-naming conflict. In our short program, it's not a big deal, but as it grows, it
+naming conflict. In our short program, its not a big deal, but as it grows, it
 becomes a problem. If we have conflicting names, Rust will give a compilation
 error. For example, if we made the `japanese` functions public, and tried to do
 this:
@@ -423,7 +423,7 @@ error: aborting due to previous error
 Could not compile `phrases`.
 ```
 
-If we're importing multiple names from the same module, we don't have to type it out
+If we’re importing multiple names from the same module, we don’t have to type it out
 twice. Instead of this:
 
 ```{rust,ignore}
@@ -439,11 +439,11 @@ use phrases::english::{greetings, farewells};
 
 ## Re-exporting with `pub use`
 
-You don't just use `use` to shorten identifiers. You can also use it inside of your crate
+You dont just use `use` to shorten identifiers. You can also use it inside of your crate
 to re-export a function inside another module. This allows you to present an external
 interface that may not directly map to your internal code organization.
 
-Let's look at an example. Modify your `src/main.rs` to read like this:
+Lets look at an example. Modify your `src/main.rs` to read like this:
 
 ```{rust,ignore}
 extern crate phrases;
@@ -494,11 +494,11 @@ mod farewells;
 ```
 
 The `pub use` declaration brings the function into scope at this part of our
-module hierarchy. Because we've `pub use`d this inside of our `japanese`
+module hierarchy. Because weve `pub use`d this inside of our `japanese`
 module, we now have a `phrases::japanese::hello()` function and a
 `phrases::japanese::goodbye()` function, even though the code for them lives in
 `phrases::japanese::greetings::hello()` and
-`phrases::japanese::farewells::goodbye()`. Our internal organization doesn't
+`phrases::japanese::farewells::goodbye()`. Our internal organization doesnt
 define our external interface.
 
 Here we have a `pub use` for each function we want to bring into the
@@ -507,13 +507,13 @@ everything from `greetings` into the current scope: `pub use self::greetings::*`
 
 What about the `self`? Well, by default, `use` declarations are absolute paths,
 starting from your crate root. `self` makes that path relative to your current
-place in the hierarchy instead. There's one more special form of `use`: you can
+place in the hierarchy instead. Theres one more special form of `use`: you can
 `use super::` to reach one level up the tree from your current location. Some
-people like to think of `self` as `.` and `super` as `..`, from many shells'
+people like to think of `self` as `.` and `super` as `..`, from many shells
 display for the current directory and the parent directory.
 
 Outside of `use`, paths are relative: `foo::bar()` refers to a function inside
-of `foo` relative to where we are. If that's prefixed with `::`, as in
+of `foo` relative to where we are. If thats prefixed with `::`, as in
 `::foo::bar()`, it refers to a different `foo`, an absolute path from your
 crate root.
 
diff --git a/src/doc/trpl/debug-and-display.md b/src/doc/trpl/debug-and-display.md
deleted file mode 100644 (file)
index 918f4c4..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-% Debug and Display
-
-Coming soon!
index afacd3040552175b17eaed7b74d87697150ae917..b7011100971a88a8a4b96bad37bf7934a9714080 100644 (file)
@@ -1,3 +1,119 @@
 % `Deref` coercions
 
-Coming soon!
+The standard library provides a special trait, [`Deref`][deref]. It’s normally
+used to overload `*`, the dereference operator:
+
+```rust
+use std::ops::Deref;
+
+struct DerefExample<T> {
+    value: T,
+}
+
+impl<T> Deref for DerefExample<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &self.value
+    }
+}
+
+fn main() {
+    let x = DerefExample { value: 'a' };
+    assert_eq!('a', *x);
+}
+```
+
+[deref]: ../std/ops/trait.Deref.html
+
+This is useful for writing custom pointer types. However, there’s a language
+feature related to `Deref`: ‘deref coercions’. Here’s the rule: If you have a
+type `U`, and it implements `Deref<Target=T>`, values of `&U` will
+automatically coerce to a `&T`. Here’s an example:
+
+```rust
+fn foo(s: &str) {
+    // borrow a string for a second
+}
+
+// String implements Deref<Target=str>
+let owned = "Hello".to_string();
+
+// therefore, this works:
+foo(&owned);
+```
+
+Using an ampersand in front of a value takes a reference to it. So `owned` is a
+`String`, `&owned` is an `&String`, and since `impl Deref<Target=str> for
+String`, `&String` will deref to `&str`, which `foo()` takes.
+
+That’s it. This rule is one of the only places in which Rust does an automatic
+conversion for you, but it adds a lot of flexibility. For example, the `Rc<T>`
+type implements `Deref<Target=T>`, so this works:
+
+```rust
+use std::rc::Rc;
+
+fn foo(s: &str) {
+    // borrow a string for a second
+}
+
+// String implements Deref<Target=str>
+let owned = "Hello".to_string();
+let counted = Rc::new(owned);
+
+// therefore, this works:
+foo(&counted);
+```
+
+All we’ve done is wrap our `String` in an `Rc<T>`. But we can now pass the
+`Rc<String>` around anywhere we’d have a `String`. The signature of `foo`
+didn’t change, but works just as well with either type. This example has two
+conversions: `Rc<String>` to `String` and then `String` to `&str`. Rust will do
+this as many times as possible until the types match.
+
+Another very common implementation provided by the standard library is:
+
+```rust
+fn foo(s: &[i32]) {
+    // borrow a slice for a second
+}
+
+// Vec<T> implements Deref<Target=[T]>
+let owned = vec![1, 2, 3];
+
+foo(&owned);
+```
+
+Vectors can `Deref` to a slice.
+
+## Deref and method calls
+
+`Deref` will also kick in when calling a method. In other words, these are
+the same two things in Rust:
+
+```rust
+struct Foo;
+
+impl Foo {
+    fn foo(&self) { println!("Foo"); }
+}
+
+let f = Foo;
+
+f.foo();
+```
+
+Even though `f` isn’t a reference, and `foo` takes `&self`, this works.
+That’s because these things are the same:
+
+```rust,ignore
+f.foo();
+(&f).foo();
+(&&f).foo();
+(&&&&&&&&f).foo();
+```
+
+A value of type `&&&&&&&&&&&&&&&&Foo` can still have methods defined on `Foo`
+called, because the compiler will insert as many * operations as necessary to
+get it right. And since it’s inserting `*`s, that uses `Deref`.
index 504bd099171babc2b95cb8f9013784b084301807..80ea25eb35ce92125c82027c7275bf10bba3353e 100644 (file)
@@ -1,11 +1,9 @@
 % Enums
 
-Finally, Rust has a "sum type", an *enum*. Enums are an incredibly useful
-feature of Rust, and are used throughout the standard library. An `enum` is
-a type which relates a set of alternates to a specific name. For example, below
-we define `Character` to be either a `Digit` or something else. These
-can be used via their fully scoped names: `Character::Other` (more about `::`
-below).
+Rust has a ‘sum type’, an `enum`. Enums are an incredibly useful feature of
+Rust, and are used throughout the standard library. An `enum` is a type which
+relates a set of alternates to a specific name. For example, below we define
+`Character` to be either a `Digit` or something else.
 
 ```rust
 enum Character {
@@ -14,14 +12,14 @@ enum Character {
 }
 ```
 
-Most normal types are allowed as the variant components of an `enum`. Here are
-some examples:
+Most types are allowed as the variant components of an `enum`. Here are some
+examples:
 
 ```rust
 struct Empty;
 struct Color(i32, i32, i32);
 struct Length(i32);
-struct Status { Health: i32, Mana: i32, Attack: i32, Defense: i32 }
+struct Stats { Health: i32, Mana: i32, Attack: i32, Defense: i32 }
 struct HeightDatabase(Vec<i32>);
 ```
 
@@ -30,12 +28,12 @@ In `Character`, for instance, `Digit` gives a meaningful name for an `i32`
 value, where `Other` is only a name. However, the fact that they represent
 distinct categories of `Character` is a very useful property.
 
-As with structures, the variants of an enum by default are not comparable with
-equality operators (`==`, `!=`), have no ordering (`<`, `>=`, etc.), and do not
-support other binary operations such as `*` and `+`. As such, the following code
-is invalid for the example `Character` type:
+The variants of an `enum` by default are not comparable with equality operators
+(`==`, `!=`), have no ordering (`<`, `>=`, etc.), and do not support other
+binary operations such as `*` and `+`. As such, the following code is invalid
+for the example `Character` type:
 
-```{rust,ignore}
+```rust,ignore
 // These assignments both succeed
 let ten  = Character::Digit(10);
 let four = Character::Digit(4);
@@ -50,98 +48,21 @@ let four_is_smaller = four <= ten;
 let four_equals_ten = four == ten;
 ```
 
-This may seem rather limiting, but it's a limitation which we can overcome.
-There are two ways: by implementing equality ourselves, or by pattern matching
-variants with [`match`][match] expressions, which you'll learn in the next
-chapter. We don't know enough about Rust to implement equality yet, but we can
-use the `Ordering` enum from the standard library, which does:
+We use the `::` syntax to use the name of each variant: They’re scoped by the name
+of the `enum` itself. This allows both of these to work:
 
-```
-enum Ordering {
-    Less,
-    Equal,
-    Greater,
-}
-```
-
-Because `Ordering` has already been defined for us, we will import it with the
-`use` keyword. Here's an example of how it is used:
-
-```{rust}
-use std::cmp::Ordering;
-
-fn cmp(a: i32, b: i32) -> Ordering {
-    if a < b { Ordering::Less }
-    else if a > b { Ordering::Greater }
-    else { Ordering::Equal }
-}
-
-fn main() {
-    let x = 5;
-    let y = 10;
-
-    let ordering = cmp(x, y); // ordering: Ordering
-
-    if ordering == Ordering::Less {
-        println!("less");
-    } else if ordering == Ordering::Greater {
-        println!("greater");
-    } else if ordering == Ordering::Equal {
-        println!("equal");
-    }
-}
-```
-
-The `::` symbol is used to indicate a namespace. In this case, `Ordering` lives
-in the `cmp` submodule of the `std` module. We'll talk more about modules later
-in the guide. For now, all you need to know is that you can `use` things from
-the standard library if you need them.
-
-Okay, let's talk about the actual code in the example. `cmp` is a function that
-compares two things, and returns an `Ordering`. We return either
-`Ordering::Less`, `Ordering::Greater`, or `Ordering::Equal`, depending on
-whether the first value is less than, greater than, or equal to the second. Note
-that each variant of the `enum` is namespaced under the `enum` itself: it's
-`Ordering::Greater`, not `Greater`.
-
-The `ordering` variable has the type `Ordering`, and so contains one of the
-three values. We then do a bunch of `if`/`else` comparisons to check which
-one it is.
-
-This `Ordering::Greater` notation is too long. Let's use another form of `use`
-to import the `enum` variants instead. This will avoid full scoping:
-
-```{rust}
-use std::cmp::Ordering::{self, Equal, Less, Greater};
-
-fn cmp(a: i32, b: i32) -> Ordering {
-    if a < b { Less }
-    else if a > b { Greater }
-    else { Equal }
-}
-
-fn main() {
-    let x = 5;
-    let y = 10;
-
-    let ordering = cmp(x, y); // ordering: Ordering
-
-    if ordering == Less { println!("less"); }
-    else if ordering == Greater { println!("greater"); }
-    else if ordering == Equal { println!("equal"); }
-}
+```rust,ignore
+Character::Digit(10);
+Hand::Digit;
 ```
 
-Importing variants is convenient and compact, but can also cause name conflicts,
-so do this with caution. For this reason, it's normally considered better style
-to `use` an enum rather than its variants directly.
+Both variants are named `Digit`, but since they’re scoped to the `enum` name,
 
-As you can see, `enum`s are quite a powerful tool for data representation, and
-are even more useful when they're [generic][generics] across types. Before we
-get to generics, though, let's talk about how to use enums with pattern
-matching, a tool that will let us deconstruct sum types (the type theory term
-for enums) like `Ordering` in a very elegant way that avoids all these messy
-and brittle `if`/`else`s.
+Not supporting these operations may seem rather limiting, but it’s a limitation
+which we can overcome. There are two ways: by implementing equality ourselves,
+or by pattern matching variants with [`match`][match] expressions, which you’ll
+learn in the next section. We don’t know enough about Rust to implement
+equality yet, but we’ll find out in the [`traits`][traits] section.
 
-[match]: ./match.html
-[generics]: ./generics.html
+[match]: match.html
+[traits]: traits.html
index 3e4e0a66eae050a5ca25d169b394752d6fa92899..517a6e6064253295a6292e1a6b2a3e0147f5b2bd 100644 (file)
@@ -1,31 +1,13 @@
 % Generics
 
 Sometimes, when writing a function or data type, we may want it to work for
-multiple types of arguments. For example, remember our `OptionalInt` type?
+multiple types of arguments. Luckily, Rust has a feature that gives us a better
+way: generics. Generics are called ‘parametric polymorphism’ in type theory,
+which means that they are types or functions that have multiple forms (‘poly’
+is multiple, ‘morph’ is form) over a given parameter (‘parametric’).
 
-```{rust}
-enum OptionalInt {
-    Value(i32),
-    Missing,
-}
-```
-
-If we wanted to also have an `OptionalFloat64`, we would need a new enum:
-
-```{rust}
-enum OptionalFloat64 {
-    Valuef64(f64),
-    Missingf64,
-}
-```
-
-This is really unfortunate. Luckily, Rust has a feature that gives us a better
-way: generics. Generics are called *parametric polymorphism* in type theory,
-which means that they are types or functions that have multiple forms (*poly*
-is multiple, *morph* is form) over a given parameter (*parametric*).
-
-Anyway, enough with type theory declarations, let's check out the generic form
-of `OptionalInt`. It is actually provided by Rust itself, and looks like this:
+Anyway, enough with type theory, let’s check out some generic code. Rust’s
+standard library provides a type, `Option<T>`, that’s generic:
 
 ```rust
 enum Option<T> {
@@ -34,41 +16,40 @@ enum Option<T> {
 }
 ```
 
-The `<T>` part, which you've seen a few times before, indicates that this is
+The `<T>` part, which youve seen a few times before, indicates that this is
 a generic data type. Inside the declaration of our enum, wherever we see a `T`,
-we substitute that type for the same type used in the generic. Here's an
+we substitute that type for the same type used in the generic. Heres an
 example of using `Option<T>`, with some extra type annotations:
 
-```{rust}
+```rust
 let x: Option<i32> = Some(5);
 ```
 
 In the type declaration, we say `Option<i32>`. Note how similar this looks to
 `Option<T>`. So, in this particular `Option`, `T` has the value of `i32`. On
 the right-hand side of the binding, we do make a `Some(T)`, where `T` is `5`.
-Since that's an `i32`, the two sides match, and Rust is happy. If they didn't
-match, we'd get an error:
+Since that’s an `i32`, the two sides match, and Rust is happy. If they didn’t
+match, wed get an error:
 
-```{rust,ignore}
+```rust,ignore
 let x: Option<f64> = Some(5);
 // error: mismatched types: expected `core::option::Option<f64>`,
 // found `core::option::Option<_>` (expected f64 but found integral variable)
 ```
 
-That doesn't mean we can't make `Option<T>`s that hold an `f64`! They just have to
-match up:
+That doesn’t mean we can’t make `Option<T>`s that hold an `f64`! They just have
+to match up:
 
-```{rust}
+```rust
 let x: Option<i32> = Some(5);
 let y: Option<f64> = Some(5.0f64);
 ```
 
 This is just fine. One definition, multiple uses.
 
-Generics don't have to only be generic over one type. Consider Rust's built-in
-`Result<T, E>` type:
+Generics don’t have to only be generic over one type. Consider another type from Rust’s standard library that’s similar, `Result<T, E>`:
 
-```{rust}
+```rust
 enum Result<T, E> {
     Ok(T),
     Err(E),
@@ -76,9 +57,9 @@ enum Result<T, E> {
 ```
 
 This type is generic over _two_ types: `T` and `E`. By the way, the capital letters
-can be any letter you'd like. We could define `Result<T, E>` as:
+can be any letter youd like. We could define `Result<T, E>` as:
 
-```{rust}
+```rust
 enum Result<A, Z> {
     Ok(A),
     Err(Z),
@@ -86,92 +67,58 @@ enum Result<A, Z> {
 ```
 
 if we wanted to. Convention says that the first generic parameter should be
-`T`, for 'type,' and that we use `E` for 'error.' Rust doesn't care, however.
+`T`, for ‘type’, and that we use `E` for ‘error’. Rust doesn’t care, however.
 
 The `Result<T, E>` type is intended to be used to return the result of a
-computation, and to have the ability to return an error if it didn't work out.
-Here's an example:
-
-```{rust}
-let x: Result<f64, String> = Ok(2.3f64);
-let y: Result<f64, String> = Err("There was an error.".to_string());
-```
+computation, and to have the ability to return an error if it didn’t work out.
 
-This particular Result will return an `f64` if there's a success, and a
-`String` if there's a failure. Let's write a function that uses `Result<T, E>`:
+## Generic functions
 
-```{rust}
-fn inverse(x: f64) -> Result<f64, String> {
-    if x == 0.0f64 { return Err("x cannot be zero!".to_string()); }
+We can write functions that take generic types with a similar syntax:
 
-    Ok(1.0f64 / x)
+```rust
+fn takes_anything<T>(x: T) {
+    // do something with x
 }
 ```
 
-We don't want to take the inverse of zero, so we check to make sure that we
-weren't passed zero. If we were, then we return an `Err`, with a message. If
-it's okay, we return an `Ok`, with the answer.
+The syntax has two parts: the `<T>` says “this function is generic over one
+type, `T`”, and the `x: T` says “x has the type `T`.”
 
-Why does this matter? Well, remember how `match` does exhaustive matches?
-Here's how this function gets used:
+Multiple arguments can have the same generic type:
 
-```{rust}
-# fn inverse(x: f64) -> Result<f64, String> {
-#     if x == 0.0f64 { return Err("x cannot be zero!".to_string()); }
-#     Ok(1.0f64 / x)
-# }
-let x = inverse(25.0f64);
-
-match x {
-    Ok(x) => println!("The inverse of 25 is {}", x),
-    Err(msg) => println!("Error: {}", msg),
+```rust
+fn takes_two_of_the_same_things<T>(x: T, y: T) {
+    // ...
 }
 ```
 
-The `match` enforces that we handle the `Err` case. In addition, because the
-answer is wrapped up in an `Ok`, we can't just use the result without doing
-the match:
-
-```{rust,ignore}
-let x = inverse(25.0f64);
-println!("{}", x + 2.0f64); // error: binary operation `+` cannot be applied
-           // to type `core::result::Result<f64,collections::string::String>`
-```
-
-This function is great, but there's one other problem: it only works for 64 bit
-floating point values. What if we wanted to handle 32 bit floating point as
-well? We'd have to write this:
+We could write a version that takes multiple types:
 
-```{rust}
-fn inverse32(x: f32) -> Result<f32, String> {
-    if x == 0.0f32 { return Err("x cannot be zero!".to_string()); }
-
-    Ok(1.0f32 / x)
+```rust
+fn takes_two_things<T, U>(x: T, y: U) {
+    // ...
 }
 ```
 
-Bummer. What we need is a *generic function*. Luckily, we can write one!
-However, it won't _quite_ work yet. Before we get into that, let's talk syntax.
-A generic version of `inverse` would look something like this:
+Generic functions are most useful with ‘trait bounds’, which we’ll cover in the
+[section on traits][traits].
 
-```{rust,ignore}
-fn inverse<T>(x: T) -> Result<T, String> {
-    if x == 0.0 { return Err("x cannot be zero!".to_string()); }
+[traits]: traits.html
 
-    Ok(1.0 / x)
-}
-```
+## Generic structs
 
-Just like how we had `Option<T>`, we use a similar syntax for `inverse<T>`.
-We can then use `T` inside the rest of the signature: `x` has type `T`, and half
-of the `Result` has type `T`. However, if we try to compile that example, we'll get
-an error:
+You can store a generic type in a `struct` as well:
 
-```text
-error: binary operation `==` cannot be applied to type `T`
 ```
+struct Point<T> {
+    x: T,
+    y: T,
+}
 
-Because `T` can be _any_ type, it may be a type that doesn't implement `==`,
-and therefore, the first line would be wrong. What do we do?
+let int_origin = Point { x: 0, y: 0 };
+let float_origin = Point { x: 0.0, y: 0.0 };
+```
 
-To fix this example, we need to learn about another Rust feature: traits.
+Similarly to functions, the `<T>` is where we declare the generic parameters,
+and we then use `x: T` in the type declaration, too.
index 9e010b020c1810faa30811880c72672a681eb906..7173303e3b15203109a9b094e62b2ccc989daca4 100644 (file)
@@ -1,3 +1,82 @@
 % if let
 
-COMING SOON
+`if let` allows you to combine `if` and `let` together to reduce the overhead
+of certain kinds of pattern matches.
+
+For example, let’s say we have some sort of `Option<T>`. We want to call a function
+on it if it’s `Some<T>`, but do nothing if it’s `None`. That looks like this:
+
+```rust
+# let option = Some(5);
+# fn foo(x: i32) { }
+match option {
+    Some(x) => { foo(x) },
+    None => {},
+}
+```
+
+We don’t have to use `match` here, for example, we could use `if`:
+
+```rust
+# let option = Some(5);
+# fn foo(x: i32) { }
+if option.is_some() {
+    let x = option.unwrap();
+    foo(x);
+}
+```
+
+Neither of these options is particularly appealing. We can use `if let` to
+do the same thing in a nicer way:
+
+```rust
+# let option = Some(5);
+# fn foo(x: i32) { }
+if let Some(x) = option {
+    foo(x);
+}
+```
+
+If a [pattern][patterns] matches successfully, it binds any appropriate parts of
+the value to the identifiers in the pattern, then evaluates the expression. If
+the pattern doesn’t match, nothing happens.
+
+If you’d rather to do something else when the pattern does not match, you can
+use `else`:
+
+```rust
+# let option = Some(5);
+# fn foo(x: i32) { }
+# fn bar() { }
+if let Some(x) = option {
+    foo(x);
+} else {
+    bar();
+}
+```
+
+## `while let`
+
+In a similar fashion, `while let` can be used when you want to conditionally
+loop as long as a value matches a certain pattern. It turns code like this:
+
+```rust
+# let option: Option<i32> = None;
+loop {
+    match option {
+        Some(x) => println!("{}", x),
+       _ => break,
+    }
+}
+```
+
+Into code like this:
+
+```rust
+# let option: Option<i32> = None;
+while let Some(x) = option {
+    println!("{}", x);
+}
+```
+
+[patterns]: patterns.html
index 713814d9147a7a5cdf0c5d884eef437ac2af4658..9d01f104ddaafcdcb824ccf4241189c743667c58 100644 (file)
@@ -1,20 +1,20 @@
 % Macros
 
-By now you've learned about many of the tools Rust provides for abstracting and
+By now youve 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
+This structure means that Rusts 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
+you visually identify a pattern of repeated code, you may find its difficult
 or cumbersome to express that pattern as a generic function, a trait, or
-anything else within Rust's semantics.
+anything else within Rusts semantics.
 
-Macros allow us to abstract at a *syntactic* level. A macro invocation is
+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.
+patterns of code reuse that Rusts 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
@@ -23,8 +23,8 @@ 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
+These drawbacks make macros something of a "feature of last resort". Thats not
+to say that macros are bad; they are part of Rust because sometimes theyre
 needed for truly concise, well-abstracted code. Just keep this tradeoff in
 mind.
 
@@ -40,7 +40,7 @@ let x: Vec<u32> = vec![1, 2, 3];
 # assert_eq!(x, [1, 2, 3]);
 ```
 
-This can't be an ordinary function, because it takes any number of arguments.
+This cant be an ordinary function, because it takes any number of arguments.
 But we can imagine it as syntactic shorthand for
 
 ```rust
@@ -57,8 +57,7 @@ let x: Vec<u32> = {
 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][].
+           one presented here, for reasons of efficiency and reusability.
 
 ```rust
 macro_rules! vec {
@@ -77,20 +76,20 @@ macro_rules! vec {
 # }
 ```
 
-Whoa, that's a lot of new syntax! Let's break it down.
+Whoa, that’s a lot of new syntax! Let’s break it down.
 
 ```ignore
 macro_rules! vec { ... }
 ```
 
-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
+This says were defining a macro named `vec`, much as `fn vec` would define a
+function named `vec`. In prose, we informally write a macros 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
 
-The macro is defined through a series of *rules*, which are pattern-matching
+The macro is defined through a series of rules, which are pattern-matching
 cases. Above, we had
 
 ```ignore
@@ -99,14 +98,14 @@ cases. Above, we had
 
 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*.
+case. The "pattern" on the left-hand side of `=>` is known as a ‘matcher’.
 These have [their own little grammar] within the language.
 
 [their own little grammar]: ../reference.html#macros
 
 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][].
+to the ‘metavariable’ `$x`. The identifier `expr` is a ‘fragment specifier’;
+the full possibilities are enumerated later in this chapter.
 Surrounding the matcher with `$(...),*` will match zero or more expressions,
 separated by commas.
 
@@ -158,8 +157,8 @@ 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).
 
-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
+Because `$x` was already declared as matching an expression, we dont repeat
+`:expr` on the right-hand side. Also, we dont include a separating comma as
 part of the repetition operator. Instead, we have a terminating semicolon
 within the repeated block.
 
@@ -180,7 +179,7 @@ The outer braces are part of the syntax of `macro_rules!`. In fact, you can use
 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.
+expression, you dont 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
@@ -194,7 +193,7 @@ The repetition operator follows two principal rules:
 1. `$(...)*` walks through one "layer" of repetitions, for all of the `$name`s
    it contains, in lockstep, and
 2. each `$name` must be under at least as many `$(...)*`s as it was matched
-   against. If it is under more, it'll be duplicated, as appropriate.
+   against. If it is under more, itll be duplicated, as appropriate.
 
 This baroque macro illustrates the duplication of variables from outer
 repetition levels.
@@ -219,7 +218,7 @@ fn main() {
 }
 ```
 
-That's most of the matcher syntax. These examples use `$(...)*`, which is a
+Thats 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 `*`.
@@ -244,9 +243,9 @@ int main() {
 ```
 
 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
+than addition. If youve 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.
+dont have to worry about it.
 
 ```rust
 macro_rules! five_times {
@@ -261,8 +260,8 @@ fn main() {
 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.
+Another common problem in macro systems is ‘variable capture’. Here’s a C
+macro, using [a GNU C extension] to emulate Rusts expression blocks.
 
 [a GNU C extension]: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
 
@@ -275,7 +274,7 @@ macro, using [a GNU C extension] to emulate Rust's expression blocks.
 })
 ```
 
-Here's a simple use case that goes terribly wrong:
+Heres a simple use case that goes terribly wrong:
 
 ```text
 const char *state = "reticulating splines";
@@ -315,10 +314,10 @@ fn main() {
 ```
 
 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`
+happens in a distinct ‘syntax context’, and each variable is tagged with the
+syntax context where it was introduced. Its 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.
+the macro, and therefore they dont conflict.
 
 [hygienic macro system]: http://en.wikipedia.org/wiki/Hygienic_macro
 
@@ -336,7 +335,7 @@ fn main() {
 }
 ```
 
-Instead you need to pass the variable name into the invocation, so it's tagged
+Instead you need to pass the variable name into the invocation, so its tagged
 with the right syntax context.
 
 ```rust
@@ -368,7 +367,7 @@ fn main() {
 
 # Recursive macros
 
-A macro's expansion can include more macro invocations, including invocations
+A macros expansion can include more macro invocations, including invocations
 of the very same macro being expanded.  These recursive macros are useful for
 processing tree-structured input, as illustrated by this (simplistic) HTML
 shorthand:
@@ -429,7 +428,7 @@ they are unstable and require feature gates.
 Even when Rust code contains un-expanded macros, it can be parsed as a full
 [syntax tree][ast]. This property can be very useful for editors and other
 tools that process code. It also has a few consequences for the design of
-Rust's macro system.
+Rusts macro system.
 
 [ast]: glossary.html#abstract-syntax-tree
 
@@ -454,13 +453,13 @@ 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*.
+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
+Within a matcher, each metavariable has a ‘fragment specifier’, identifying
 which syntactic form it matches.
 
 * `ident`: an identifier. Examples: `x`; `foo`.
@@ -482,7 +481,7 @@ There are additional rules regarding the next token after a metavariable:
 * `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
+These rules provide some flexibility for Rusts syntax to evolve without
 breaking existing macros.
 
 The macro system does not deal with parse ambiguity at all. For example, the
@@ -500,7 +499,7 @@ 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
+lexical-order traversal of a crates 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.
 
@@ -508,8 +507,8 @@ 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`
+parent module after the childs `mod` item. If the parent also has `macro_use`
+then the macros will be visible in the grandparent after the parents `mod`
 item, and so forth.
 
 The `macro_use` attribute can also appear on `extern crate`. In this context
@@ -524,7 +523,7 @@ 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]`
+To load a crate’s macros without linking it into the output, use `#[no_link]`
 as well.
 
 An example:
@@ -566,7 +565,7 @@ 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).
+attributes](../reference.html#macro-related-attributes).
 
 # The variable `$crate`
 
@@ -619,12 +618,12 @@ only appear at the root of your crate, not inside `mod`. This ensures that
 
 The introductory chapter mentioned recursive macros, but it did not give the
 full story. Recursive macros are useful for another reason: Each recursive
-invocation gives you another opportunity to pattern-match the macro's
+invocation gives you another opportunity to pattern-match the macros
 arguments.
 
 As an extreme example, it is possible, though hardly advisable, to implement
 the [Bitwise Cyclic Tag](http://esolangs.org/wiki/Bitwise_Cyclic_Tag) automaton
-within Rust's macro system.
+within Rusts macro system.
 
 ```rust
 macro_rules! bct {
@@ -653,11 +652,121 @@ macro_rules! bct {
 Exercise: use macros to reduce duplication in the above definition of the
 `bct!` macro.
 
+# Common macros
+
+Here are some common macros you’ll see in Rust code.
+
+## panic!
+
+This macro causes the current thread to panic. You can give it a message
+to panic with:
+
+```rust,no_run
+panic!("oh no!");
+```
+
+## vec!
+
+The `vec!` macro is used throughout the book, so you’ve probably seen it
+already. It creates `Vec<T>`s with ease:
+
+```rust
+let v = vec![1, 2, 3, 4, 5];
+```
+
+It also lets you make vectors with repeating values. For example, a hundred
+zeroes:
+
+```rust
+let v = vec![0; 100];
+```
+
+## assert! and assert_eq!
+
+These two macros are used in tests. `assert!` takes a boolean, and `assert_eq!`
+takes two values and compares them. Truth passes, success `panic!`s. Like
+this:
+
+```rust,no_run
+// A-ok!
+
+assert!(true);
+assert_eq!(5, 3 + 2);
+
+// nope :(
+
+assert!(5 < 3);
+assert_eq!(5, 3);
+```
+## try!
+
+`try!` is used for error handling. It takes something that can return a
+`Result<T, E>`, and gives `T` if it’s a `Ok<T>`, and `return`s with the
+`Err(E)` if it’s that. Like this:
+
+```rust,no_run
+use std::fs::File;
+
+fn foo() -> std::io::Result<()> {
+    let f = try!(File::create("foo.txt"));
+
+    Ok(())
+}
+```
+
+This is cleaner than doing this:
+
+```rust,no_run
+use std::fs::File;
+
+fn foo() -> std::io::Result<()> {
+    let f = File::create("foo.txt");
+
+    let f = match f {
+        Ok(t) => t,
+        Err(e) => return Err(e),
+    };
+
+    Ok(())
+}
+```
+
+## unreachable!
+
+This macro is used when you think some code should never execute:
+
+```rust
+if false {
+    unreachable!();
+}
+```
+
+Sometimes, the compiler may make you have a different branch that you know
+will never, ever run. In these cases, use this macro, so that if you end
+up wrong, you’ll get a `panic!` about it.
+
+```rust
+let x: Option<i32> = None;
+
+match x {
+    Some(_) => unreachable!(),
+    None => println!("I know x is None!"),
+}
+```
+
+## unimplemented!
+
+The `unimplemented!` macro can be used when you’re trying to get your functions
+to typecheck, and don’t want to worry about writing out the body of the
+function. One example of this situation is implementing a trait with multiple
+required methods, where you want to tackle one at a time. Define the others
+as `unimplemented!` until you’re ready to write them.
+
 # Procedural macros
 
-If Rust's macro system can't do what you need, you may want to write a
+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 bugs can be much harder to track down. In exchange you get the
 flexibility of running arbitrary Rust code within the compiler. Syntax
-extension plugins are sometimes called *procedural macros* for this reason.
+extension plugins are sometimes called ‘procedural macros’ for this reason.
index 33d603f326af3a19f09ef9182605ef207c44d04f..2c0c8ea73c03c5b6ec6169b609af0d8a36d615b0 100644 (file)
@@ -1,10 +1,8 @@
 % Match
 
-Often, a simple `if`/`else` isn’t enough, because you have more than two
-possible options. Also, `else` conditions can get incredibly complicated, so
-what’s the solution?
-
-Rust has a keyword, `match`, that allows you to replace complicated `if`/`else`
+Often, a simple [`if`][if]/`else` isn’t enough, because you have more than two
+possible options. Also, conditions can get quite complex. Rust
+has a keyword, `match`, that allows you to replace complicated `if`/`else`
 groupings with something more powerful. Check it out:
 
 ```rust
@@ -20,16 +18,18 @@ match x {
 }
 ```
 
-`match` takes an expression and then branches based on its value. Each *arm* of
+[if]: if.html
+
+`match` takes an expression and then branches based on its value. Each ‘arm’ of
 the branch is of the form `val => expression`. When the value matches, that arm’s
 expression will be evaluated. It’s called `match` because of the term ‘pattern
 matching’, which `match` is an implementation of. There’s an [entire section on
-patterns][patterns] coming up next, that covers all the options that fit here.
+patterns][patterns] that covers all the patterns that are possible here.
 
 [patterns]: patterns.html
 
-So what’s the big advantage here? Well, there are a few. First of all, `match`
-enforces *exhaustiveness checking*. Do you see that last arm, the one with the
+So what’s the big advantage? Well, there are a few. First of all, `match`
+enforces ‘exhaustiveness checking’. Do you see that last arm, the one with the
 underscore (`_`)? If we remove that arm, Rust will give us an error:
 
 ```text
@@ -37,11 +37,12 @@ error: non-exhaustive patterns: `_` not covered
 ```
 
 In other words, Rust is trying to tell us we forgot a value. Because `x` is an
-integer, Rust knows that it can have a number of different values – for example,
-`6`. Without the `_`, however, there is no arm that could match, and so Rust refuses
-to compile. `_` acts like a ‘catch-all arm’. If none of the other arms match,
-the arm with `_` will, and since we have this catch-all arm, we now have an arm
-for every possible value of `x`, and so our program will compile successfully.
+integer, Rust knows that it can have a number of different values – for
+example, `6`. Without the `_`, however, there is no arm that could match, and
+so Rust refuses to compile the code. `_` acts like a ‘catch-all arm’. If none
+of the other arms match, the arm with `_` will, and since we have this
+catch-all arm, we now have an arm for every possible value of `x`, and so our
+program will compile successfully.
 
 `match` is also an expression, which means we can use it on the right-hand
 side of a `let` binding or directly where an expression is used:
@@ -59,4 +60,4 @@ let numer = match x {
 };
 ```
 
-Sometimes, it’s a nice way of converting things.
+Sometimes it’s a nice way of converting something from one type to another.
index ae83a930a187ce78053bf0895b979f58f6c526ea..1445d39fe873876f48632571c306282c8f1eb155 100644 (file)
@@ -3,27 +3,26 @@
 Functions are great, but if you want to call a bunch of them on some data, it
 can be awkward. Consider this code:
 
-```{rust,ignore}
+```rust,ignore
 baz(bar(foo)));
 ```
 
-We would read this left-to right, and so we see "baz bar foo." But this isn't the
-order that the functions would get called in, that's inside-out: "foo bar baz."
-Wouldn't it be nice if we could do this instead?
+We would read this left-to right, and so we see ‘baz bar foo’. But this isn’t the
+order that the functions would get called in, that’s inside-out: ‘foo bar baz’.
+Wouldnt it be nice if we could do this instead?
 
-```{rust,ignore}
+```rust,ignore
 foo.bar().baz();
 ```
 
 Luckily, as you may have guessed with the leading question, you can! Rust provides
-the ability to use this *method call syntax* via the `impl` keyword.
+the ability to use this ‘method call syntax’ via the `impl` keyword.
 
-## Method calls
+# Method calls
 
-Here's how it works:
+Heres how it works:
 
-```{rust}
-# #![feature(core)]
+```rust
 struct Circle {
     x: f64,
     y: f64,
@@ -44,15 +43,23 @@ fn main() {
 
 This will print `12.566371`.
 
-We've made a struct that represents a circle. We then write an `impl` block,
-and inside it, define a method, `area`. Methods take a  special first
-parameter, of which there are three variants: `self`, `&self`, and `&mut self`.
-You can think of this first parameter as being the `foo` in `foo.bar()`. The three
-variants correspond to the three kinds of things `foo` could be: `self` if it's
-just a value on the stack, `&self` if it's a reference, and `&mut self` if it's
-a mutable reference. We should default to using `&self`, as you should prefer
-borrowing over taking ownership, as well as taking immutable references
-over mutable ones. Here's an example of all three variants:
+
+
+We’ve made a struct that represents a circle. We then write an `impl` block,
+and inside it, define a method, `area`.
+
+Methods take a  special first parameter, of which there are three variants:
+`self`, `&self`, and `&mut self`. You can think of this first parameter as
+being the `foo` in `foo.bar()`. The three variants correspond to the three
+kinds of things `foo` could be: `self` if it’s just a value on the stack,
+`&self` if it’s a reference, and `&mut self` if it’s a mutable reference.
+Because we took the `&self` parameter to `area`, we can use it just like any
+other parameter. Because we know it’s a `Circle`, we can access the `radius`
+just like we would with any other struct. 
+
+We should default to using `&self`, as you should prefer borrowing over taking
+ownership, as well as taking immutable references over mutable ones. Here’s an
+example of all three variants:
 
 ```rust
 struct Circle {
@@ -76,20 +83,13 @@ impl Circle {
 }
 ```
 
-Finally, as you may remember, the value of the area of a circle is `π*r²`.
-Because we took the `&self` parameter to `area`, we can use it just like any
-other parameter. Because we know it's a `Circle`, we can access the `radius`
-just like we would with any other struct. An import of π and some
-multiplications later, and we have our area.
-
-## Chaining method calls
+# Chaining method calls
 
 So, now we know how to call a method, such as `foo.bar()`. But what about our
-original example, `foo.bar().baz()`? This is called 'method chaining', and we
+original example, `foo.bar().baz()`? This is called ‘method chaining’, and we
 can do it by returning `self`.
 
 ```
-# #![feature(core)]
 struct Circle {
     x: f64,
     y: f64,
@@ -124,13 +124,13 @@ fn grow(&self) -> Circle {
 # Circle } }
 ```
 
-We just say we're returning a `Circle`. With this method, we can grow a new
+We just say were returning a `Circle`. With this method, we can grow a new
 circle to any arbitrary size.
 
-## Static methods
+# Static methods
 
-You can also define methods that do not take a `self` parameter. Here's a
-pattern that's very common in Rust code:
+You can also define methods that do not take a `self` parameter. Heres a
+pattern thats very common in Rust code:
 
 ```
 struct Circle {
@@ -154,20 +154,19 @@ fn main() {
 }
 ```
 
-This *static method* builds a new `Circle` for us. Note that static methods
+This ‘static method’ builds a new `Circle` for us. Note that static methods
 are called with the `Struct::method()` syntax, rather than the `ref.method()`
 syntax.
 
-## Builder Pattern
+# Builder Pattern
 
-Let's say that we want our users to be able to create Circles, but we will
+Lets say that we want our users to be able to create Circles, but we will
 allow them to only set the properties they care about. Otherwise, the `x`
-and `y` attributes will be `0.0`, and the `radius` will be `1.0`. Rust doesn't
+and `y` attributes will be `0.0`, and the `radius` will be `1.0`. Rust doesnt
 have method overloading, named arguments, or variable arguments. We employ
 the builder pattern instead. It looks like this:
 
 ```
-# #![feature(core)]
 struct Circle {
     x: f64,
     y: f64,
@@ -224,9 +223,9 @@ fn main() {
 }
 ```
 
-What we've done here is make another struct, `CircleBuilder`. We've defined our
-builder methods on it. We've also defined our `area()` method on `Circle`. We
+What we’ve done here is make another struct, `CircleBuilder`. We’ve defined our
+builder methods on it. Weve also defined our `area()` method on `Circle`. We
 also made one more method on `CircleBuilder`: `finalize()`. This method creates
-our final `Circle` from the builder. Now, we've used the type system to enforce
+our final `Circle` from the builder. Now, weve used the type system to enforce
 our concerns: we can use the methods on `CircleBuilder` to constrain making
 `Circle`s in any way we choose.
index ccb03c7f85f693a873d4d91a566b929c18d49426..e7506dfe4fd7dc5c850c59c1c5f07843f800b1e3 100644 (file)
@@ -1,3 +1,179 @@
 % Mutability
 
-Coming Soon
+Mutability, the ability to change something, works a bit differently in Rust
+than in other languages. The first aspect of mutability is its non-default
+status:
+
+```rust,ignore
+let x = 5;
+x = 6; // error!
+```
+
+We can introduce mutability with the `mut` keyword:
+
+```rust
+let mut x = 5;
+
+x = 6; // no problem!
+```
+
+This is a mutable [variable binding][vb]. When a binding is mutable, it means
+you’re allowed to change what the binding points to. So in the above example,
+it’s not so much that the value at `x` is changing, but that the binding
+changed from one `i32` to another.
+
+[vb]: variable-bindings.html
+
+If you want to change what the binding points to, you’ll need a [mutable reference][mr]:
+
+```rust
+let mut x = 5;
+let y = &mut x;
+```
+
+[mr]: references-and-borrowing.html
+
+`y` is an immutable binding to a mutable reference, which means that you can’t
+bind `y` to something else (`y = &mut z`), but you can mutate the thing that’s
+bound to `y`. (`*y = 5`) A subtle distinction.
+
+Of course, if you need both:
+
+```rust
+let mut x = 5;
+let mut y = &mut x;
+```
+
+Now `y` can be bound to another value, and the value it’s referencing can be
+changed.
+
+It’s important to note that `mut` is part of a [pattern][pattern], so you
+can do things like this:
+
+```rust
+let (mut x, y) = (5, 6);
+
+fn foo(mut x: i32) {
+# }
+```
+
+[pattern]: patterns.html
+
+# Interior vs. Exterior Mutability
+
+However, when we say something is ‘immutable’ in Rust, that doesn’t mean that
+it’s not able to be changed: We mean something has ‘exterior mutability’. Consider,
+for example, [`Arc<T>`][arc]:
+
+```rust
+use std::sync::Arc;
+
+let x = Arc::new(5);
+let y = x.clone();
+```
+
+[arc]: ../std/sync/struct.Arc.html
+
+When we call `clone()`, the `Arc<T>` needs to update the reference count. Yet
+we’ve not used any `mut`s here, `x` is an immutable binding, and we didn’t take
+`&mut 5` or anything. So what gives?
+
+To this, we have to go back to the core of Rust’s guiding philosophy, memory
+safety, and the mechanism by which Rust guarantees it, the
+[ownership][ownership] system, and more specifically, [borrowing][borrowing]:
+
+> You may have one or the other of these two kinds of borrows, but not both at
+> the same time:
+> 
+> * 0 to N references (`&T`) to a resource.
+> * exactly one mutable reference (`&mut T`)
+
+[ownership]: ownership.html
+[borrowing]: borrowing.html#The-Rules
+
+So, that’s the real definition of ‘immutability’: is this safe to have two
+pointers to? In `Arc<T>`’s case, yes: the mutation is entirely contained inside
+the structure itself. It’s not user facing. For this reason, it hands out `&T`
+with `clone()`. If it handed out `&mut T`s, though, that would be a problem.
+
+Other types, like the ones in the [`std::cell`][stdcell] module, have the
+opposite: interior mutability. For example:
+
+```rust
+use std::cell::RefCell;
+
+let x = RefCell::new(42);
+
+let y = x.borrow_mut();
+```
+
+[stdcell]: ../std/cell/index.html
+
+RefCell hands out `&mut` references to what’s inside of it with the
+`borrow_mut()` method. Isn’t that dangerous? What if we do:
+
+```rust,ignore
+use std::cell::RefCell;
+
+let x = RefCell::new(42);
+
+let y = x.borrow_mut();
+let z = x.borrow_mut();
+# (y, z);
+```
+
+This will in fact panic, at runtime. This is what `RefCell` does: it enforces
+Rust’s borrowing rules at runtime, and `panic!`s if they’re violated. This
+allows us to get around another aspect of Rust’s mutability rules. Let’s talk
+about it first.
+
+## Field-level mutability
+
+Mutabilty is a property of either a borrow (`&mut`) or a binding (`let mut`).
+This means that, for example, you cannot have a [`struct`][struct] with
+some fields mutable and some immutable:
+
+```rust,ignore
+struct Point {
+    x: i32,
+    mut y: i32, // nope
+}
+```
+
+The mutability of a struct is in its binding:
+
+```rust,ignore
+struct Point {
+    x: i32,
+    y: i32,
+}
+
+let mut a = Point { x: 5, y: 6 };
+
+a.x = 10;
+
+let b = Point { x: 5, y: 6};
+
+b.x = 10; // error: cannot assign to immutable field `b.x`
+```
+
+[struct]: structs.html
+
+However, by using `Cell<T>`, you can emulate field-level mutability:
+
+```
+use std::cell::Cell;
+
+struct Point {
+    x: i32,
+    y: Cell<i32>,
+}
+
+let mut point = Point { x: 5, y: Cell::new(6) };
+
+point.y.set(7);
+
+println!("y: {:?}", point.y);
+```
+
+This will print `y: Cell { value: 7 }`. We’ve successfully updated `y`.
index f6f9d5cae19213d54ae53a5559e3ec5c2684a4ef..6a594659c37d27617cc7899c542de54977c21f9a 100644 (file)
@@ -1,3 +1,83 @@
 % Operators and Overloading
 
-Coming soon!
+Rust allows for a limited form of operator overloading. There are certain
+operators that are able to be overloaded. To support a particular operator
+between types, there’s a specific trait that you can implement, which then
+overloads the operator.
+
+For example, the `+` operator can be overloaded with the `Add` trait:
+
+```rust
+use std::ops::Add;
+
+#[derive(Debug)]
+struct Point {
+    x: i32,
+    y: i32,
+}
+
+impl Add for Point {
+    type Output = Point;
+
+    fn add(self, other: Point) -> Point {
+        Point { x: self.x + other.x, y: self.y + other.y }
+    }
+}
+
+fn main() {
+    let p1 = Point { x: 1, y: 0 };
+    let p2 = Point { x: 2, y: 3 };
+
+    let p3 = p1 + p2;
+
+    println!("{:?}", p3);
+}
+```
+
+In `main`, we can use `+` on our two `Point`s, since we’ve implemented
+`Add<Output=Point>` for `Point`.
+
+There are a number of operators that can be overloaded this way, and all of
+their associated traits live in the [`std::ops`][stdops] module. Check out its
+documentation for the full list.
+
+[stdops]: ../std/ops/index.html
+
+Implementing these traits follows a pattern. Let’s look at [`Add`][add] in more
+detail:
+
+```rust
+# mod foo {
+pub trait Add<RHS = Self> {
+    type Output;
+
+    fn add(self, rhs: RHS) -> Self::Output;
+}
+# }
+```
+
+[add]: ../std/ops/trait.Add.html
+
+There’s three types in total involved here: the type you `impl Add` for, `RHS`,
+which defaults to `Self`, and `Output`. For an expression `let z = x + y`, `x`
+is the `Self` type, `y` is the RHS, and `z` is the `Self::Output` type.
+
+```rust
+# struct Point;
+# use std::ops::Add;
+impl Add<i32> for Point {
+    type Output = f64;
+
+    fn add(self, rhs: i32) -> f64 {
+        // add an i32 to a Point and get an f64
+# 1.0
+    }
+}
+```
+
+will let you do this:
+
+```rust,ignore
+let p: Point = // ...
+let x: f64 = p + 2i32;
+```
index c88e3a0f9edf5f71564270e369c7233455ec2849..97a3dfe8a7640c688070a6e059b570273e43dab2 100644 (file)
@@ -21,6 +21,8 @@ match x {
 }
 ```
 
+This prints `one`.
+
 # Multiple patterns
 
 You can match multiple patterns with `|`:
@@ -35,6 +37,8 @@ match x {
 }
 ```
 
+This prints `one or two`.
+
 # Ranges
 
 You can match a range of values with `...`:
@@ -48,7 +52,21 @@ match x {
 }
 ```
 
-Ranges are mostly used with integers and single characters.
+This prints `one through five`.
+
+Ranges are mostly used with integers and `char`s:
+
+```rust
+let x = '💅';
+
+match x {
+    'a' ... 'j' => println!("early letter"),
+    'k' ... 'z' => println!("late letter"),
+    _ => println!("something else"),
+}
+```
+
+This prints `something else`
 
 # Bindings
 
@@ -64,6 +82,8 @@ match x {
 }
 ```
 
+This prints `got a range element 1`.
+
 # Ignoring variants
 
 If you’re matching on an enum which has variants, you can use `..` to
@@ -83,6 +103,8 @@ match x {
 }
 ```
 
+This prints `Got an int!`.
+
 # Guards
 
 You can introduce ‘match guards’ with `if`:
@@ -102,6 +124,8 @@ match x {
 }
 ```
 
+This prints `Got an int!`
+
 # ref and ref mut
 
 If you want to get a [reference][ref], use the `ref` keyword:
@@ -114,6 +138,8 @@ match x {
 }
 ```
 
+This prints `Got a reference to 5`.
+
 [ref]: references-and-borrowing.html
 
 Here, the `r` inside the `match` has the type `&i32`. In other words, the `ref`
@@ -130,7 +156,7 @@ match x {
 
 # Destructuring
 
-If you have a compound data type, like a `struct`, you can destructure it
+If you have a compound data type, like a [`struct`][struct], you can destructure it
 inside of a pattern:
 
 ```rust
@@ -146,6 +172,8 @@ match origin {
 }
 ```
 
+[struct]: structs.html
+
 If we only care about some of the values, we don’t have to give them all names:
 
 ```rust
@@ -161,6 +189,8 @@ match origin {
 }
 ```
 
+This prints `x is 0`.
+
 You can do this kind of match on any member, not just the first:
 
 ```rust
@@ -176,6 +206,8 @@ match origin {
 }
 ```
 
+This prints `y is 0`.
+
 This ‘destructuring’ behavior works on any compound data type, like
 [tuples][tuples] or [enums][enums].
 
@@ -187,10 +219,10 @@ This ‘destructuring’ behavior works on any compound data type, like
 Whew! That’s a lot of different ways to match things, and they can all be
 mixed and matched, depending on what you’re doing:
 
-```{rust,ignore}
+```rust,ignore
 match x {
     Foo { x: Some(ref name), y: None } => ...
 }
 ```
 
-Patterns are very powerful.  Make good use of them.
+Patterns are very powerful. Make good use of them.
index 811080cd50987ea542df4a2e516119801c0358ff..e4af03869d1d85e2c9e0c976b900f9acb0715a21 100644 (file)
@@ -168,6 +168,7 @@ like arrays:
 ```rust
 let a = [0, 1, 2, 3, 4];
 let middle = &a[1..4]; // A slice of a: just the elements 1, 2, and 3
+let complete = &a[..]; // A slice containing all of the elements in a
 ```
 
 Slices have type `&[T]`. We’ll talk about that `T` when we cover
diff --git a/src/doc/trpl/raw-pointers.md b/src/doc/trpl/raw-pointers.md
new file mode 100644 (file)
index 0000000..ab6ff18
--- /dev/null
@@ -0,0 +1,122 @@
+% Raw Pointers
+
+Rust has a number of different smart pointer types in its standard library, but
+there are two types that are extra-special. Much of Rust’s safety comes from
+compile-time checks, but raw pointers don’t have such guarantees, and are
+[unsafe][unsafe] to use.
+
+`*const T` and `*mut T` are called ‘raw pointers’ in Rust. Sometimes, when
+writing certain kinds of libraries, you’ll need to get around Rust’s safety
+guarantees for some reason. In this case, you can use raw pointers to implement
+your library, while exposing a safe interface for your users. For example, `*`
+pointers are allowed to alias, allowing them to be used to write
+shared-ownership types, and even thread-safe shared memory types (the `Rc<T>`
+and `Arc<T>` types are both implemented entirely in Rust).
+
+Here are some things to remember about raw pointers that are different than
+other pointer types. They:
+
+- are not guaranteed to point to valid memory and are not even
+  guaranteed to be non-null (unlike both `Box` and `&`);
+- do not have any automatic clean-up, unlike `Box`, and so require
+  manual resource management;
+- are plain-old-data, that is, they don't move ownership, again unlike
+  `Box`, hence the Rust compiler cannot protect against bugs like
+  use-after-free;
+- lack any form of lifetimes, unlike `&`, and so the compiler cannot
+  reason about dangling pointers; and
+- have no guarantees about aliasing or mutability other than mutation
+  not being allowed directly through a `*const T`.
+
+# Basics
+
+Creating a raw pointer is perfectly safe:
+
+```rust
+let x = 5;
+let raw = &x as *const i32;
+
+let mut y = 10;
+let raw_mut = &mut y as *mut i32;
+```
+
+However, dereferencing one is not. This won’t work:
+
+```rust,ignore
+let x = 5;
+let raw = &x as *const i32;
+
+println!("raw points at {}", *raw);
+```
+
+It gives this error:
+
+```text
+error: dereference of unsafe pointer requires unsafe function or block [E0133]
+     println!("raw points at{}", *raw);
+                                 ^~~~
+```
+
+When you dereference a raw pointer, you’re taking responsibility that it’s not
+pointing somewhere that would be incorrect. As such, you need `unsafe`:
+
+```rust
+let x = 5;
+let raw = &x as *const i32;
+
+let points_at = unsafe { *raw };
+
+println!("raw points at {}", points_at);
+```
+
+For more operations on raw pointers, see [their API documentation][rawapi].
+
+[unsafe]: unsafe.html
+[rawapi]: ../std/primitive.pointer.html
+
+# FFI
+
+Raw pointers are useful for FFI: Rust’s `*const T` and `*mut T` are similar to
+C’s `const T*` and `T*`, respectfully. For more about this use, consult the
+[FFI chapter][ffi].
+
+[ffi]: ffi.md
+
+# References and raw pointers
+
+At runtime, a raw pointer `*` and a reference pointing to the same piece of
+data have an identical representation. In fact, an `&T` reference will
+implicitly coerce to an `*const T` raw pointer in safe code and similarly for
+the `mut` variants (both coercions can be performed explicitly with,
+respectively, `value as *const T` and `value as *mut T`).
+
+Going the opposite direction, from `*const` to a reference `&`, is not safe. A
+`&T` is always valid, and so, at a minimum, the raw pointer `*const T` has to
+point to a valid instance of type `T`. Furthermore, the resulting pointer must
+satisfy the aliasing and mutability laws of references. The compiler assumes
+these properties are true for any references, no matter how they are created,
+and so any conversion from raw pointers is asserting that they hold. The
+programmer *must* guarantee this.
+
+The recommended method for the conversion is
+
+```rust
+let i: u32 = 1;
+
+// explicit cast
+let p_imm: *const u32 = &i as *const u32;
+let mut m: u32 = 2;
+
+// implicit coercion
+let p_mut: *mut u32 = &mut m;
+
+unsafe {
+    let ref_imm: &u32 = &*p_imm;
+    let ref_mut: &mut u32 = &mut *p_mut;
+}
+```
+
+The `&*x` dereferencing style is preferred to using a `transmute`. The latter
+is far more powerful than necessary, and the more restricted operation is
+harder to use incorrectly; for example, it requires that `x` is a pointer
+(unlike `transmute`).
index 4599333a77a05e88d326126621762f6f27c4388e..de165b70fc4028d5846fa4bc8384bc21dea0d966 100644 (file)
@@ -16,3 +16,27 @@ fn main() {
 }
 ```
 
+The `advanced_slice_patterns` gate lets you use `..` to indicate any number of
+elements inside a pattern matching a slice. This wildcard can only be used once
+for a given array. If there's an identifier before the `..`, the result of the
+slice will be bound to that name. For example:
+
+```rust
+#![feature(advanced_slice_patterns, slice_patterns)]
+
+fn is_symmetric(list: &[u32]) -> bool {
+    match list {
+        [] | [_] => true,
+        [x, inside.., y] if x == y => is_symmetric(inside),
+        _ => false
+    }
+}
+
+fn main() {
+    let sym = &[0, 1, 4, 2, 4, 1, 0];
+    assert!(is_symmetric(sym));
+
+    let not_sym = &[0, 1, 7, 2, 4, 1, 0];
+    assert!(!is_symmetric(not_sym));
+}
+```
diff --git a/src/doc/trpl/static.md b/src/doc/trpl/static.md
deleted file mode 100644 (file)
index b29c495..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-% `static`
-
-Coming soon!
index 2c2e6a8c7c5acdf8079163bf675163a0ea7aff84..6ed4c7cb1b379bea10ec9e1d1e1546cb965ed1c9 100644 (file)
@@ -1,36 +1,34 @@
 % Strings
 
-Strings are an important concept for any programmer to master. Rust's string
+Strings are an important concept for any programmer to master. Rusts string
 handling system is a bit different from other languages, due to its systems
 focus. Any time you have a data structure of variable size, things can get
-tricky, and strings are a re-sizable data structure. That being said, Rust's
+tricky, and strings are a re-sizable data structure. That being said, Rusts
 strings also work differently than in some other systems languages, such as C.
 
-Let's dig into the details. A *string* is a sequence of Unicode scalar values
-encoded as a stream of UTF-8 bytes. All strings are guaranteed to be
-validly encoded UTF-8 sequences. Additionally, strings are not null-terminated
-and can contain null bytes.
+Let’s dig into the details. A ‘string’ is a sequence of Unicode scalar values
+encoded as a stream of UTF-8 bytes. All strings are guaranteed to be a valid
+encoding of UTF-8 sequences. Additionally, unlike some systems languages,
+strings are not null-terminated and can contain null bytes.
 
-Rust has two main types of strings: `&str` and `String`.
+Rust has two main types of strings: `&str` and `String`. Let’s talk about
+`&str` first. These are called ‘string slices’. String literals are of the type
+`&'static str`:
 
-The first kind is a `&str`. These are called *string slices*. String literals
-are of the type `&str`:
-
-```{rust}
-let string = "Hello there."; // string: &str
+```rust
+let string = "Hello there."; // string: &'static str
 ```
 
-This string is statically allocated, meaning that it's saved inside our
+This string is statically allocated, meaning that its saved inside our
 compiled program, and exists for the entire duration it runs. The `string`
 binding is a reference to this statically allocated string. String slices
 have a fixed size, and cannot be mutated.
 
-A `String`, on the other hand, is a heap-allocated string. This string
-is growable, and is also guaranteed to be UTF-8. `String`s are
-commonly created by converting from a string slice using the
-`to_string` method.
+A `String`, on the other hand, is a heap-allocated string. This string is
+growable, and is also guaranteed to be UTF-8. `String`s are commonly created by
+converting from a string slice using the `to_string` method.
 
-```{rust}
+```rust
 let mut s = "Hello".to_string(); // mut s: String
 println!("{}", s);
 
@@ -54,8 +52,78 @@ fn main() {
 Viewing a `String` as a `&str` is cheap, but converting the `&str` to a
 `String` involves allocating memory. No reason to do that unless you have to!
 
-That's the basics of strings in Rust! They're probably a bit more complicated
-than you are used to, if you come from a scripting language, but when the
-low-level details matter, they really matter. Just remember that `String`s
-allocate memory and control their data, while `&str`s are a reference to
-another string, and you'll be all set.
+## Indexing
+
+Because strings are valid UTF-8, strings do not support indexing:
+
+```rust,ignore
+let s = "hello";
+
+println!("The first letter of s is {}", s[0]); // ERROR!!!
+```
+
+Usually, access to a vector with `[]` is very fast. But, because each character
+in a UTF-8 encoded string can be multiple bytes, you have to walk over the
+string to find the nᵗʰ letter of a string. This is a significantly more
+expensive operation, and we don’t want to be misleading. Furthermore, ‘letter’
+isn’t something defined in Unicode, exactly. We can choose to look at a string as
+individual bytes, or as codepoints:
+
+```rust
+let hachiko = "忠犬ハチ公";
+
+for b in hachiko.as_bytes() {
+print!("{}, ", b);
+}
+
+println!("");
+
+for c in hachiko.chars() {
+print!("{}, ", c);
+}
+
+println!("");
+```
+
+This prints:
+
+```text
+229, 191, 160, 231, 138, 172, 227, 131, 143, 227, 131, 129, 229, 133, 172, 
+忠, 犬, ハ, チ, 公, 
+```
+
+As you can see, there are more bytes than `char`s.
+
+You can get something similar to an index like this:
+
+```rust
+# let hachiko = "忠犬ハチ公";
+let dog = hachiko.chars().nth(1); // kinda like hachiko[1]
+```
+
+This emphasizes that we have to go through the whole list of `chars`.
+
+## Concatenation
+
+If you have a `String`, you can concatenate a `&str` to the end of it:
+
+```rust
+let hello = "Hello ".to_string();
+let world = "world!";
+
+let hello_world = hello + world;
+```
+
+But if you have two `String`s, you need an `&`:
+
+```rust
+let hello = "Hello ".to_string();
+let world = "world!".to_string();
+
+let hello_world = hello + &world;
+```
+
+This is because `&String` can automatically coerece to a `&str`. This is a
+feature called ‘[`Deref` coercions][dc]’.
+
+[dc]: deref-coercions.html
index 83d5a15bc2c0a831137e6233df6140e2f2827ba0..fcf928e427c254c1792705d061215e73bc06ad4e 100644 (file)
@@ -1,6 +1,6 @@
 % Structs
 
-Structs are a way of creating more complex datatypes. For example, if we were
+Structs are a way of creating more complex data types. For example, if we were
 doing calculations involving coordinates in 2D space, we would need both an `x`
 and a `y` value:
 
@@ -24,12 +24,12 @@ fn main() {
 }
 ```
 
-There’s a lot going on here, so let’s break it down. We declare a struct with
-the `struct` keyword, and then with a name. By convention, structs begin with a
-capital letter and are also camel cased: `PointInSpace`, not `Point_In_Space`.
+There’s a lot going on here, so let’s break it down. We declare a `struct` with
+the `struct` keyword, and then with a name. By convention, `struct`s begin with
+a capital letter and are camel cased: `PointInSpace`, not `Point_In_Space`.
 
 We can create an instance of our struct via `let`, as usual, but we use a `key:
-value` style syntax to set each field. The order doesn't need to be the same as
+value` style syntax to set each field. The order doesnt need to be the same as
 in the original declaration.
 
 Finally, because fields have names, we can access the field through dot
@@ -87,3 +87,33 @@ fn main() {
     point.y = 6; // this causes an error
 }
 ```
+
+# Update syntax
+
+A `struct` can include `..` to indicate that you want to use a copy of some
+other struct for some of the values. For example:
+
+```rust
+struct Point3d {
+    x: i32,
+    y: i32,
+    z: i32,
+}
+
+let mut point = Point3d { x: 0, y: 0, z: 0 };
+point = Point3d { y: 1, .. point };
+```
+
+This gives `point` a new `y`, but keeps the old `x` and `z` values. It doesn’t
+have to be the same `struct` either, you can use this syntax when making new
+ones, and it will copy the values you don’t specify:
+
+```rust
+# struct Point3d {
+#     x: i32,
+#     y: i32,
+#     z: i32,
+# }
+let origin = Point3d { x: 0, y: 0, z: 0 };
+let point = Point3d { z: 1, x: 2, .. origin };
+```
index 8cf126cad95fbd7e4813c92e10bc52367c17b391..45f87a6740597c6ac892c8732b3df881b16d7b42 100644 (file)
@@ -219,10 +219,10 @@ fn it_works() {
 This is a very common use of `assert_eq!`: call some function with
 some known arguments and compare it to the expected output.
 
-# The `test` module
+# The `tests` module
 
 There is one way in which our existing example is not idiomatic: it's
-missing the test module. The idiomatic way of writing our example
+missing the `tests` module. The idiomatic way of writing our example
 looks like this:
 
 ```{rust,ignore}
@@ -231,7 +231,7 @@ pub fn add_two(a: i32) -> i32 {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use super::add_two;
 
     #[test]
@@ -241,7 +241,7 @@ mod test {
 }
 ```
 
-There's a few changes here. The first is the introduction of a `mod test` with
+There's a few changes here. The first is the introduction of a `mod tests` with
 a `cfg` attribute. The module allows us to group all of our tests together, and
 to also define helper functions if needed, that don't become a part of the rest
 of our crate. The `cfg` attribute only compiles our test code if we're
@@ -260,7 +260,7 @@ pub fn add_two(a: i32) -> i32 {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use super::*;
 
     #[test]
@@ -279,7 +279,7 @@ $ cargo test
      Running target/adder-91b3e234d4ed382a
 
 running 1 test
-test test::it_works ... ok
+test tests::it_works ... ok
 
 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
 
@@ -292,7 +292,7 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 
 It works!
 
-The current convention is to use the `test` module to hold your "unit-style"
+The current convention is to use the `tests` module to hold your "unit-style"
 tests. Anything that just tests one small bit of functionality makes sense to
 go here. But what about "integration-style" tests instead? For that, we have
 the `tests` directory
@@ -325,7 +325,7 @@ $ cargo test
      Running target/adder-91b3e234d4ed382a
 
 running 1 test
-test test::it_works ... ok
+test tests::it_works ... ok
 
 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
 
@@ -346,7 +346,7 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 Now we have three sections: our previous test is also run, as well as our new
 one.
 
-That's all there is to the `tests` directory. The `test` module isn't needed
+That's all there is to the `tests` directory. The `tests` module isn't needed
 here, since the whole thing is focused on tests.
 
 Let's finally check out that third section: documentation tests.
@@ -382,7 +382,7 @@ pub fn add_two(a: i32) -> i32 {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use super::*;
 
     #[test]
@@ -405,7 +405,7 @@ $ cargo test
      Running target/adder-91b3e234d4ed382a
 
 running 1 test
-test test::it_works ... ok
+test tests::it_works ... ok
 
 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
 
index d008d30597fea82e1add2e94ea410b8df6cf4096..52f8cb335a93a0c8eb92953a2432a836320c2755 100644 (file)
@@ -1,15 +1,15 @@
 % Trait Objects
 
 When code involves polymorphism, there needs to be a mechanism to determine
-which specific version is actually run. This is called 'dispatch.' There are
+which specific version is actually run. This is called ‘dispatch’. There are
 two major forms of dispatch: static dispatch and dynamic dispatch. While Rust
 favors static dispatch, it also supports dynamic dispatch through a mechanism
-called 'trait objects.'
+called ‘trait objects’.
 
 ## Background
 
-For the rest of this chapter, we'll need a trait and some implementations.
-Let's make a simple one, `Foo`. It has one method that is expected to return a
+For the rest of this chapter, well need a trait and some implementations.
+Lets make a simple one, `Foo`. It has one method that is expected to return a
 `String`.
 
 ```rust
@@ -18,7 +18,7 @@ trait Foo {
 }
 ```
 
-We'll also implement this trait for `u8` and `String`:
+Well also implement this trait for `u8` and `String`:
 
 ```rust
 # trait Foo { fn method(&self) -> String; }
@@ -53,7 +53,7 @@ fn main() {
 }
 ```
 
-Rust uses 'monomorphization' to perform static dispatch here. This means that
+Rust uses ‘monomorphization’ to perform static dispatch here. This means that
 Rust will create a special version of `do_something()` for both `u8` and
 `String`, and then replace the call sites with calls to these specialized
 functions. In other words, Rust generates something like this:
@@ -82,7 +82,7 @@ fn main() {
 This has a great upside: static dispatch allows function calls to be
 inlined because the callee is known at compile time, and inlining is
 the key to good optimization. Static dispatch is fast, but it comes at
-a tradeoff: 'code bloat', due to many copies of the same function
+a tradeoff: ‘code bloat’, due to many copies of the same function
 existing in the binary, one for each type.
 
 Furthermore, compilers aren’t perfect and may “optimize” code to become slower.
@@ -99,7 +99,7 @@ reason.
 
 ## Dynamic dispatch
 
-Rust provides dynamic dispatch through a feature called 'trait objects.' Trait
+Rust provides dynamic dispatch through a feature called ‘trait objects’. Trait
 objects, like `&Foo` or `Box<Foo>`, are normal values that store a value of
 *any* type that implements the given trait, where the precise type can only be
 known at runtime.
@@ -109,12 +109,12 @@ implements the trait by *casting* it (e.g. `&x as &Foo`) or *coercing* it
 (e.g. using `&x` as an argument to a function that takes `&Foo`).
 
 These trait object coercions and casts also work for pointers like `&mut T` to
-`&mut Foo` and `Box<T>` to `Box<Foo>`, but that's all at the moment. Coercions
+`&mut Foo` and `Box<T>` to `Box<Foo>`, but thats all at the moment. Coercions
 and casts are identical.
 
-This operation can be seen as "erasing" the compiler's knowledge about the
+This operation can be seen as ‘erasing’ the compiler’s knowledge about the
 specific type of the pointer, and hence trait objects are sometimes referred to
-as "type erasure".
+as ‘type erasure’.
 
 Coming back to the example above, we can use the same trait to perform dynamic
 dispatch with trait objects by casting:
@@ -167,7 +167,7 @@ on the heap to store it.
 
 For `Foo`, we would need to have a value that could be at least either a
 `String` (24 bytes) or a `u8` (1 byte), as well as any other type for which
-dependent crates may implement `Foo` (any number of bytes at all). There's no
+dependent crates may implement `Foo` (any number of bytes at all). Theres no
 way to guarantee that this last point can work if the values are stored without
 a pointer, because those other types can be arbitrarily large.
 
@@ -177,14 +177,14 @@ when we are tossing a trait object around, only the size of the pointer itself.
 ### Representation
 
 The methods of the trait can be called on a trait object via a special record
-of function pointers traditionally called a 'vtable' (created and managed by
+of function pointers traditionally called a ‘vtable’ (created and managed by
 the compiler).
 
 Trait objects are both simple and complicated: their core representation and
 layout is quite straight-forward, but there are some curly error messages and
 surprising behaviors to discover.
 
-Let's start simple, with the runtime representation of a trait object. The
+Lets start simple, with the runtime representation of a trait object. The
 `std::raw` module contains structs with layouts that are the same as the
 complicated built-in types, [including trait objects][stdraw]:
 
@@ -199,12 +199,12 @@ pub struct TraitObject {
 
 [stdraw]: ../std/raw/struct.TraitObject.html
 
-That is, a trait object like `&Foo` consists of a "data" pointer and a "vtable"
+That is, a trait object like `&Foo` consists of a ‘data’ pointer and a ‘vtable’
 pointer.
 
 The data pointer addresses the data (of some unknown type `T`) that the trait
-object is storing, and the vtable pointer points to the vtable ("virtual method
-table") corresponding to the implementation of `Foo` for `T`.
+object is storing, and the vtable pointer points to the vtable (virtual method
+table) corresponding to the implementation of `Foo` for `T`.
 
 
 A vtable is essentially a struct of function pointers, pointing to the concrete
@@ -212,7 +212,7 @@ piece of machine code for each method in the implementation. A method call like
 `trait_object.method()` will retrieve the correct pointer out of the vtable and
 then do a dynamic call of it. For example:
 
-```{rust,ignore}
+```rust,ignore
 struct FooVtable {
     destructor: fn(*mut ()),
     size: usize,
@@ -261,7 +261,7 @@ static Foo_for_String_vtable: FooVtable = FooVtable {
 ```
 
 The `destructor` field in each vtable points to a function that will clean up
-any resources of the vtable's type, for `u8` it is trivial, but for `String` it
+any resources of the vtables type, for `u8` it is trivial, but for `String` it
 will free the memory. This is necessary for owning trait objects like
 `Box<Foo>`, which need to clean-up both the `Box` allocation as well as the
 internal type when they go out of scope. The `size` and `align` fields store
@@ -270,11 +270,11 @@ essentially unused at the moment since the information is embedded in the
 destructor, but will be used in the future, as trait objects are progressively
 made more flexible.
 
-Suppose we've got some values that implement `Foo`, then the explicit form of
+Suppose weve got some values that implement `Foo`, then the explicit form of
 construction and use of `Foo` trait objects might look a bit like (ignoring the
-type mismatches: they're all just pointers anyway):
+type mismatches: theyre all just pointers anyway):
 
-```{rust,ignore}
+```rust,ignore
 let a: String = "foo".to_string();
 let x: u8 = 1;
 
index 25f5c7cacc7716bc32f70fec31495a9d090f198e..3e77d3c603bac90909a481f68df961c545b4f566 100644 (file)
@@ -1,10 +1,9 @@
 % Traits
 
-Do you remember the `impl` keyword, used to call a function with method
-syntax?
+Do you remember the `impl` keyword, used to call a function with [method
+syntax][methodsyntax]?
 
-```{rust}
-# #![feature(core)]
+```rust
 struct Circle {
     x: f64,
     y: f64,
@@ -18,11 +17,12 @@ impl Circle {
 }
 ```
 
+[methodsyntax]: method-syntax.html
+
 Traits are similar, except that we define a trait with just the method
 signature, then implement the trait for that struct. Like this:
 
-```{rust}
-# #![feature(core)]
+```rust
 struct Circle {
     x: f64,
     y: f64,
@@ -41,20 +41,13 @@ impl HasArea for Circle {
 ```
 
 As you can see, the `trait` block looks very similar to the `impl` block,
-but we don't define a body, just a type signature. When we `impl` a trait,
+but we dont define a body, just a type signature. When we `impl` a trait,
 we use `impl Trait for Item`, rather than just `impl Item`.
 
-So what's the big deal? Remember the error we were getting with our generic
-`inverse` function?
-
-```text
-error: binary operation `==` cannot be applied to type `T`
-```
-
 We can use traits to constrain our generics. Consider this function, which
 does not compile, and gives us a similar error:
 
-```{rust,ignore}
+```rust,ignore
 fn print_area<T>(shape: T) {
     println!("This shape has an area of {}", shape.area());
 }
@@ -66,11 +59,11 @@ Rust complains:
 error: type `T` does not implement any method in scope named `area`
 ```
 
-Because `T` can be any type, we can't be sure that it implements the `area`
-method. But we can add a *trait constraint* to our generic `T`, ensuring
+Because `T` can be any type, we cant be sure that it implements the `area`
+method. But we can add a ‘trait constraint’ to our generic `T`, ensuring
 that it does:
 
-```{rust}
+```rust
 # trait HasArea {
 #     fn area(&self) -> f64;
 # }
@@ -83,10 +76,9 @@ The syntax `<T: HasArea>` means `any type that implements the HasArea trait`.
 Because traits define function type signatures, we can be sure that any type
 which implements `HasArea` will have an `.area()` method.
 
-Here's an extended example of how this works:
+Heres an extended example of how this works:
 
-```{rust}
-# #![feature(core)]
+```rust
 trait HasArea {
     fn area(&self) -> f64;
 }
@@ -144,10 +136,10 @@ This shape has an area of 3.141593
 This shape has an area of 1
 ```
 
-As you can see, `print_area` is now generic, but also ensures that we
-have passed in the correct types. If we pass in an incorrect type:
+As you can see, `print_area` is now generic, but also ensures that we have
+passed in the correct types. If we pass in an incorrect type:
 
-```{rust,ignore}
+```rust,ignore
 print_area(5);
 ```
 
@@ -157,11 +149,11 @@ We get a compile-time error:
 error: failed to find an implementation of trait main::HasArea for int
 ```
 
-So far, we've only added trait implementations to structs, but you can
-implement a trait for any type. So technically, we _could_ implement
-`HasArea` for `i32`:
+So far, weve only added trait implementations to structs, but you can
+implement a trait for any type. So technically, we _could_ implement `HasArea`
+for `i32`:
 
-```{rust}
+```rust
 trait HasArea {
     fn area(&self) -> f64;
 }
@@ -181,102 +173,57 @@ It is considered poor style to implement methods on such primitive types, even
 though it is possible.
 
 This may seem like the Wild West, but there are two other restrictions around
-implementing traits that prevent this from getting out of hand. First, traits
-must be `use`d in any scope where you wish to use the trait's method. So for
-example, this does not work:
+implementing traits that prevent this from getting out of hand. The first is
+that if the trait isn’t defined in your scope, it doesn’t apply. Here’s an
+example: the standard library provides a [`Write`][write] trait which adds
+extra functionality to `File`s, for doing file I/O. By default, a `File`
+won’t have its methods:
 
-```{rust,ignore}
-mod shapes {
-    use std::f64::consts;
+[write]: ../std/io/trait.Write.html
 
-    trait HasArea {
-        fn area(&self) -> f64;
-    }
-
-    struct Circle {
-        x: f64,
-        y: f64,
-        radius: f64,
-    }
-
-    impl HasArea for Circle {
-        fn area(&self) -> f64 {
-            consts::PI * (self.radius * self.radius)
-        }
-    }
-}
-
-fn main() {
-    let c = shapes::Circle {
-        x: 0.0f64,
-        y: 0.0f64,
-        radius: 1.0f64,
-    };
-
-    println!("{}", c.area());
-}
+```rust,ignore
+let mut f = std::fs::File::open("foo.txt").ok().expect("Couldn’t open foo.txt");
+let result = f.write("whatever".as_bytes());
+# result.unwrap(); // ignore the erorr
 ```
 
-Now that we've moved the structs and traits into their own module, we get an
-error:
+Here’s the error:
 
 ```text
-error: type `shapes::Circle` does not implement any method in scope named `area`
-```
+error: type `std::fs::File` does not implement any method in scope named `write`
 
-If we add a `use` line right above `main` and make the right things public,
-everything is fine:
-
-```{rust}
-# #![feature(core)]
-mod shapes {
-    use std::f64::consts;
-
-    pub trait HasArea {
-        fn area(&self) -> f64;
-    }
-
-    pub struct Circle {
-        pub x: f64,
-        pub y: f64,
-        pub radius: f64,
-    }
-
-    impl HasArea for Circle {
-        fn area(&self) -> f64 {
-            consts::PI * (self.radius * self.radius)
-        }
-    }
-}
+let result = f.write(b”whatever”);
+               ^~~~~~~~~~~~~~~~~~
+```
 
-use shapes::HasArea;
+We need to `use` the `Write` trait first:
 
-fn main() {
-    let c = shapes::Circle {
-        x: 0.0f64,
-        y: 0.0f64,
-        radius: 1.0f64,
-    };
+```rust,ignore
+use std::io::Write;
 
-    println!("{}", c.area());
-}
+let mut f = std::fs::File::open("foo.txt").ok().expect("Couldn’t open foo.txt");
+let result = f.write("whatever".as_bytes());
+# result.unwrap(); // ignore the erorr
 ```
 
+This will compile without error.
+
 This means that even if someone does something bad like add methods to `int`,
-it won't affect you, unless you `use` that trait.
+it wont affect you, unless you `use` that trait.
 
-There's one more restriction on implementing traits. Either the trait or the
-type you're writing the `impl` for must be inside your crate. So, we could
-implement the `HasArea` type for `i32`, because `HasArea` is in our crate.  But
+Theres one more restriction on implementing traits. Either the trait or the
+type you’re writing the `impl` for must be defined by you. So, we could
+implement the `HasArea` type for `i32`, because `HasArea` is in our code. But
 if we tried to implement `Float`, a trait provided by Rust, for `i32`, we could
-not, because both the trait and the type aren't in our crate.
+not, because neither the trait nor the type are in our code.
 
 One last thing about traits: generic functions with a trait bound use
-*monomorphization* (*mono*: one, *morph*: form), so they are statically
-dispatched. What's that mean? Check out the chapter on [trait
-objects](trait-objects.html) for more.
+‘monomorphization’ (mono: one, morph: form), so they are statically dispatched.
+What’s that mean? Check out the chapter on [trait objects][to] for more details.
+
+[to]: trait-objects.html
 
-## Multiple trait bounds
+# Multiple trait bounds
 
 You’ve seen that you can bound a generic type parameter with a trait:
 
@@ -299,10 +246,10 @@ fn foo<T: Clone + Debug>(x: T) {
 
 `T` now needs to be both `Clone` as well as `Debug`.
 
-## Where clause
+# 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
+bounds isnt too bad, but as the number increases, the syntax gets increasingly
 awkward:
 
 ```
@@ -318,7 +265,7 @@ fn foo<T: Clone, K: Clone + Debug>(x: T, y: K) {
 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':
+Rust has a solution, and it’s called a ‘`where` clause’:
 
 ```
 use std::fmt::Debug;
@@ -389,84 +336,9 @@ 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:
-
-```{rust,ignore}
-fn inverse<T>(x: T) -> Result<T, String> {
-    if x == 0.0 { return Err("x cannot be zero!".to_string()); }
-
-    Ok(1.0 / x)
-}
-```
-
-If we try to compile it, we get this error:
-
-```text
-error: binary operation `==` cannot be applied to type `T`
-```
-
-This is because `T` is too generic: we don't know if a random `T` can be
-compared. For that, we can use trait bounds. It doesn't quite work, but try
-this:
-
-```{rust,ignore}
-fn inverse<T: PartialEq>(x: T) -> Result<T, String> {
-    if x == 0.0 { return Err("x cannot be zero!".to_string()); }
-
-    Ok(1.0 / x)
-}
-```
-
-You should get this error:
-
-```text
-error: mismatched types:
- expected `T`,
-    found `_`
-(expected type parameter,
-    found floating-point variable)
-```
-
-So this won't work. While our `T` is `PartialEq`, we expected to have another `T`,
-but instead, we found a floating-point variable. We need a different bound. `Float`
-to the rescue:
-
-```
-# #![feature(std_misc)]
-use std::num::Float;
-
-fn inverse<T: Float>(x: T) -> Result<T, String> {
-    if x == Float::zero() { return Err("x cannot be zero!".to_string()) }
-
-    let one: T = Float::one();
-    Ok(one / x)
-}
-```
-
-We've had to replace our generic `0.0` and `1.0` with the appropriate methods
-from the `Float` trait. Both `f32` and `f64` implement `Float`, so our function
-works just fine:
-
-```
-# #![feature(std_misc)]
-# use std::num::Float;
-# fn inverse<T: Float>(x: T) -> Result<T, String> {
-#     if x == Float::zero() { return Err("x cannot be zero!".to_string()) }
-#     let one: T = Float::one();
-#     Ok(one / x)
-# }
-println!("the inverse of {} is {:?}", 2.0f32, inverse(2.0f32));
-println!("the inverse of {} is {:?}", 2.0f64, inverse(2.0f64));
-
-println!("the inverse of {} is {:?}", 0.0f32, inverse(0.0f32));
-println!("the inverse of {} is {:?}", 0.0f64, inverse(0.0f64));
-```
-
 ## Default methods
 
-There's one last feature of traits we should cover: default methods. It's
+There’s one last feature of traits we should cover: default methods. It’s
 easiest just to show an example:
 
 ```rust
@@ -477,8 +349,8 @@ trait Foo {
 }
 ```
 
-Implementors of the `Foo` trait need to implement `bar()`, but they don't
-need to implement `baz()`. They'll get this default behavior. They can
+Implementors of the `Foo` trait need to implement `bar()`, but they dont
+need to implement `baz()`. Theyll get this default behavior. They can
 override the default if they so choose:
 
 ```rust
@@ -506,3 +378,43 @@ default.baz(); // prints "We called baz."
 let over = OverrideDefault;
 over.baz(); // prints "Override baz!"
 ```
+
+# Inheritance
+
+Sometimes, implementing a trait requires implementing another trait:
+
+```rust
+trait Foo {
+    fn foo(&self);
+}
+
+trait FooBar : Foo {
+    fn foobar(&self);
+}
+```
+
+Implementors of `FooBar` must also implement `Foo`, like this:
+
+```rust
+# trait Foo {
+#     fn foo(&self);
+# }
+# trait FooBar : Foo {
+#     fn foobar(&self);
+# }
+struct Baz;
+
+impl Foo for Baz {
+    fn foo(&self) { println!("foo"); }
+}
+
+impl FooBar for Baz {
+    fn foobar(&self) { println!("foobar"); }
+}
+```
+
+If we forget to implement `Foo`, Rust will tell us:
+
+```text
+error: the trait `main::Foo` is not implemented for the type `main::Baz` [E0277]
+```
index 8fba658fba2cd028ab15ce33b86a095c6cdc0d97..bdaef70711ae418990568151a86fa624d00f135a 100644 (file)
@@ -1,16 +1,20 @@
 % Tuple Structs
 
-Rust has another data type that's like a hybrid between a tuple and a struct,
-called a *tuple struct*. Tuple structs do have a name, but their fields don't:
+Rust has another data type that's like a hybrid between a [tuple][tuple] and a
+[struct][struct], called a ‘tuple struct’. Tuple structs have a name, but
+their fields don’t:
 
-```{rust}
+```rust
 struct Color(i32, i32, i32);
 struct Point(i32, i32, i32);
 ```
 
+[tuple]: primitive-types.html#tuples
+[struct]: structs.html
+
 These two will not be equal, even if they have the same values:
 
-```{rust}
+```rust
 # struct Color(i32, i32, i32);
 # struct Point(i32, i32, i32);
 let black = Color(0, 0, 0);
@@ -20,7 +24,7 @@ let origin = Point(0, 0, 0);
 It is almost always better to use a struct than a tuple struct. We would write
 `Color` and `Point` like this instead:
 
-```{rust}
+```rust
 struct Color {
     red: i32,
     blue: i32,
@@ -37,12 +41,12 @@ struct Point {
 Now, we have actual names, rather than positions. Good names are important,
 and with a struct, we have actual names.
 
-There _is_ one case when a tuple struct is very useful, though, and that's a
-tuple struct with only one element. We call this the *newtype* pattern, because
+There _is_ one case when a tuple struct is very useful, though, and thats a
+tuple struct with only one element. We call this the ‘newtype’ pattern, because
 it allows you to create a new type, distinct from that of its contained value
 and expressing its own semantic meaning:
 
-```{rust}
+```rust
 struct Inches(i32);
 
 let length = Inches(10);
@@ -52,5 +56,5 @@ println!("length is {} inches", integer_length);
 ```
 
 As you can see here, you can extract the inner integer type through a
-destructuring `let`, as we discussed previously in 'tuples.' In this case, the
+destructuring `let`, as we discussed previously in ‘tuples’. In this case, the
 `let Inches(integer_length)` assigns `10` to `integer_length`.
index fffa0ae1383c29ad4fa1f233b8ae9fb43f0de5de..d175da35f5ec97ecd8eeb5305f24d9104ed6090c 100644 (file)
@@ -1,3 +1,76 @@
 % `type` Aliases
 
-Coming soon
+The `type` keyword lets you declare an alias of another type:
+
+```rust
+type Name = String;
+```
+
+You can then use this type as if it were a real type:
+
+```rust
+type Name = String;
+
+let x: Name = "Hello".to_string();
+```
+
+Note, however, that this is an _alias_, not a new type entirely. In other
+words, because Rust is strongly typed, you’d expect a comparison between two
+different types to fail:
+
+```rust,ignore
+let x: i32 = 5;
+let y: i64 = 5;
+
+if x == y {
+   // ...
+}
+```
+
+this gives
+
+```text
+error: mismatched types:
+ expected `i32`,
+    found `i64`
+(expected i32,
+    found i64) [E0308]
+     if x == y {
+             ^
+```
+
+But, if we had an alias:
+
+```rust
+type Num = i32;
+
+let x: i32 = 5;
+let y: Num = 5;
+
+if x == y {
+   // ...
+}
+```
+
+This compiles without error. Values of a `Num` type are the same as a value of
+type `i32`, in every way.
+
+You can also use type aliases with generics:
+
+```rust
+use std::result;
+
+enum ConcreteError {
+    Foo,
+    Bar,
+}
+
+type Result<T> = result::Result<T, ConcreteError>;
+```
+
+This creates a specialized version of the `Result` type, which always has a
+`ConcreteError` for the `E` part of `Result<T, E>`. This is commonly used
+in the standard library to create custom errors for each subsection. For
+example, [io::Result][ioresult].
+
+[ioresult]: ../std/io/type.Result.html
index 6b9a417c43944ae883642c8642a3a5081d2617bf..2d5c742ddb8482312a2ee0661f46808b694c8c50 100644 (file)
@@ -1,3 +1,127 @@
 % Universal Function Call Syntax
 
-Coming soon
+Sometimes, functions can have the same names. Consider this code:
+
+```rust
+trait Foo {
+    fn f(&self);
+}
+
+trait Bar {
+    fn f(&self);
+}
+
+struct Baz;
+
+impl Foo for Baz {
+    fn f(&self) { println!("Baz’s impl of Foo"); }
+}
+
+impl Bar for Baz {
+    fn f(&self) { println!("Baz’s impl of Bar"); }
+}
+
+let b = Baz;
+```
+
+If we were to try to call `b.f()`, we’d get an error:
+
+```text
+error: multiple applicable methods in scope [E0034]
+b.f();
+  ^~~
+note: candidate #1 is defined in an impl of the trait `main::Foo` for the type
+`main::Baz`
+    fn f(&self) { println!("Baz’s impl of Foo"); }
+    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+note: candidate #2 is defined in an impl of the trait `main::Bar` for the type
+`main::Baz`
+    fn f(&self) { println!("Baz’s impl of Bar"); }
+    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+```
+
+We need a way to disambiguate which method we need. This feature is called
+‘universal function call syntax’, and it looks like this:
+
+```rust
+# trait Foo {
+#     fn f(&self);
+# }
+# trait Bar {
+#     fn f(&self);
+# }
+# struct Baz;
+# impl Foo for Baz {
+#     fn f(&self) { println!("Baz’s impl of Foo"); }
+# }
+# impl Bar for Baz {
+#     fn f(&self) { println!("Baz’s impl of Bar"); }
+# }
+# let b = Baz;
+Foo::f(&b);
+Bar::f(&b);
+```
+
+Let’s break it down.
+
+```rust,ignore
+Foo::
+Bar::
+```
+
+These halves of the invocation are the types of the two traits: `Foo` and
+`Bar`. This is what ends up actually doing the disambiguation between the two:
+Rust calls the one from the trait name you use.
+
+```rust,ignore
+f(&b)
+```
+
+When we call a method like `b.f()` using [method syntax][methodsyntax], Rust
+will automatically borrow `b` if `f()` takes `&self`. In this case, Rust will
+not, and so we need to pass an explicit `&b`.
+
+[methodsyntax]: method-syntax.html
+
+# Angle-bracket Form
+
+The form of UFCS we just talked about:
+
+```rust,ignore
+Type::method(args);
+```
+
+Is a short-hand. There’s an expanded form of this that’s needed in some
+situations:
+
+```rust,ignore
+<Type as Trait>::method(args);
+```
+
+The `<>::` syntax is a means of providing a type hint. The type goes inside
+the `<>`s. In this case, the type is `Type as Trait`, indicating that we want
+`Trait`’s version of `method` to be called here. The `as Trait` part is
+optional if it’s not ambiguous. Same with the angle brackets, hence the
+shorter form.
+
+Here’s an example of using the longer form.
+
+```rust
+trait Foo {
+    fn clone(&self);
+}
+
+#[derive(Clone)]
+struct Bar;
+
+impl Foo for Bar {
+    fn clone(&self) {
+        println!("Making a clone of Bar");
+
+        <Bar as Clone>::clone(self);
+    }
+}
+```
+
+This will call the `Clone` trait’s `clone()` method, rather than `Foo`’s.
diff --git a/src/doc/trpl/unsafe-code.md b/src/doc/trpl/unsafe-code.md
deleted file mode 100644 (file)
index b641f2b..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-% Unsafe Code
-
-# Introduction
-
-Rust aims to provide safe abstractions over the low-level details of
-the CPU and operating system, but sometimes one needs to drop down and
-write code at that level. This guide aims to provide an overview of
-the dangers and power one gets with Rust's unsafe subset.
-
-Rust provides an escape hatch in the form of the `unsafe { ... }`
-block which allows the programmer to dodge some of the compiler's
-checks and do a wide range of operations, such as:
-
-- dereferencing [raw pointers](#raw-pointers)
-- calling a function via FFI ([covered by the FFI guide](ffi.html))
-- casting between types bitwise (`transmute`, aka "reinterpret cast")
-- [inline assembly](#inline-assembly)
-
-Note that an `unsafe` block does not relax the rules about lifetimes
-of `&` and the freezing of borrowed data.
-
-Any use of `unsafe` is the programmer saying "I know more than you" to
-the compiler, and, as such, the programmer should be very sure that
-they actually do know more about why that piece of code is valid.  In
-general, one should try to minimize the amount of unsafe code in a
-code base; preferably by using the bare minimum `unsafe` blocks to
-build safe interfaces.
-
-> **Note**: the low-level details of the Rust language are still in
-> flux, and there is no guarantee of stability or backwards
-> compatibility. In particular, there may be changes that do not cause
-> compilation errors, but do cause semantic changes (such as invoking
-> undefined behaviour). As such, extreme care is required.
-
-# Pointers
-
-## References
-
-One of Rust's biggest features is memory safety.  This is achieved in
-part via [the ownership system](ownership.html), which is how the
-compiler can guarantee that every `&` reference is always valid, and,
-for example, never pointing to freed memory.
-
-These restrictions on `&` have huge advantages. However, they also
-constrain how we can use them. For example, `&` doesn't behave
-identically to C's pointers, and so cannot be used for pointers in
-foreign function interfaces (FFI). Additionally, both immutable (`&`)
-and mutable (`&mut`) references have some aliasing and freezing
-guarantees, required for memory safety.
-
-In particular, if you have an `&T` reference, then the `T` must not be
-modified through that reference or any other reference. There are some
-standard library types, e.g. `Cell` and `RefCell`, that provide inner
-mutability by replacing compile time guarantees with dynamic checks at
-runtime.
-
-An `&mut` reference has a different constraint: when an object has an
-`&mut T` pointing into it, then that `&mut` reference must be the only
-such usable path to that object in the whole program. That is, an
-`&mut` cannot alias with any other references.
-
-Using `unsafe` code to incorrectly circumvent and violate these
-restrictions is undefined behaviour. For example, the following
-creates two aliasing `&mut` pointers, and is invalid.
-
-```
-use std::mem;
-let mut x: u8 = 1;
-
-let ref_1: &mut u8 = &mut x;
-let ref_2: &mut u8 = unsafe { mem::transmute(&mut *ref_1) };
-
-// oops, ref_1 and ref_2 point to the same piece of data (x) and are
-// both usable
-*ref_1 = 10;
-*ref_2 = 20;
-```
-
-## Raw pointers
-
-Rust offers two additional pointer types (*raw pointers*), written as
-`*const T` and `*mut T`. They're an approximation of C's `const T*` and `T*`
-respectively; indeed, one of their most common uses is for FFI,
-interfacing with external C libraries.
-
-Raw pointers have much fewer guarantees than other pointer types
-offered by the Rust language and libraries. For example, they
-
-- are not guaranteed to point to valid memory and are not even
-  guaranteed to be non-null (unlike both `Box` and `&`);
-- do not have any automatic clean-up, unlike `Box`, and so require
-  manual resource management;
-- are plain-old-data, that is, they don't move ownership, again unlike
-  `Box`, hence the Rust compiler cannot protect against bugs like
-  use-after-free;
-- lack any form of lifetimes, unlike `&`, and so the compiler cannot
-  reason about dangling pointers; and
-- have no guarantees about aliasing or mutability other than mutation
-  not being allowed directly through a `*const T`.
-
-Fortunately, they come with a redeeming feature: the weaker guarantees
-mean weaker restrictions. The missing restrictions make raw pointers
-appropriate as a building block for implementing things like smart
-pointers and vectors inside libraries. For example, `*` pointers are
-allowed to alias, allowing them to be used to write shared-ownership
-types like reference counted and garbage collected pointers, and even
-thread-safe shared memory types (`Rc` and the `Arc` types are both
-implemented entirely in Rust).
-
-There are two things that you are required to be careful about
-(i.e. require an `unsafe { ... }` block) with raw pointers:
-
-- dereferencing: they can have any value: so possible results include
-  a crash, a read of uninitialised memory, a use-after-free, or
-  reading data as normal.
-- pointer arithmetic via the `offset` [intrinsic](#intrinsics) (or
-  `.offset` method): this intrinsic uses so-called "in-bounds"
-  arithmetic, that is, it is only defined behaviour if the result is
-  inside (or one-byte-past-the-end) of the object from which the
-  original pointer came.
-
-The latter assumption allows the compiler to optimize more
-effectively. As can be seen, actually *creating* a raw pointer is not
-unsafe, and neither is converting to an integer.
-
-### References and raw pointers
-
-At runtime, a raw pointer `*` and a reference pointing to the same
-piece of data have an identical representation. In fact, an `&T`
-reference will implicitly coerce to an `*const T` raw pointer in safe code
-and similarly for the `mut` variants (both coercions can be performed
-explicitly with, respectively, `value as *const T` and `value as *mut T`).
-
-Going the opposite direction, from `*const` to a reference `&`, is not
-safe. A `&T` is always valid, and so, at a minimum, the raw pointer
-`*const T` has to point to a valid instance of type `T`. Furthermore,
-the resulting pointer must satisfy the aliasing and mutability laws of
-references. The compiler assumes these properties are true for any
-references, no matter how they are created, and so any conversion from
-raw pointers is asserting that they hold. The programmer *must*
-guarantee this.
-
-The recommended method for the conversion is
-
-```
-let i: u32 = 1;
-// explicit cast
-let p_imm: *const u32 = &i as *const u32;
-let mut m: u32 = 2;
-// implicit coercion
-let p_mut: *mut u32 = &mut m;
-
-unsafe {
-    let ref_imm: &u32 = &*p_imm;
-    let ref_mut: &mut u32 = &mut *p_mut;
-}
-```
-
-The `&*x` dereferencing style is preferred to using a `transmute`.
-The latter is far more powerful than necessary, and the more
-restricted operation is harder to use incorrectly; for example, it
-requires that `x` is a pointer (unlike `transmute`).
-
-
-
-## Making the unsafe safe(r)
-
-There are various ways to expose a safe interface around some unsafe
-code:
-
-- store pointers privately (i.e. not in public fields of public
-  structs), so that you can see and control all reads and writes to
-  the pointer in one place.
-- use `assert!()` a lot: since you can't rely on the protection of the
-  compiler & type-system to ensure that your `unsafe` code is correct
-  at compile-time, use `assert!()` to verify that it is doing the
-  right thing at run-time.
-- implement the `Drop` for resource clean-up via a destructor, and use
-  RAII (Resource Acquisition Is Initialization). This reduces the need
-  for any manual memory management by users, and automatically ensures
-  that clean-up is always run, even when the thread panics.
-- ensure that any data stored behind a raw pointer is destroyed at the
-  appropriate time.
diff --git a/src/doc/trpl/unsafe.md b/src/doc/trpl/unsafe.md
new file mode 100644 (file)
index 0000000..7fe9a1f
--- /dev/null
@@ -0,0 +1,128 @@
+% Unsafe
+
+Rust’s main draw is its powerful static guarantees about behavior. But safety
+checks are conservative by nature: there are some programs that are actually
+safe, but the compiler is not able to verify this is true. To write these kinds
+of programs, we need to tell the compiler to relax its restrictions a bit. For
+this, Rust has a keyword, `unsafe`. Code using `unsafe` has less restrictions
+than normal code does.
+
+Let’s go over the syntax, and then we’ll talk semantics. `unsafe` is used in
+two contexts. The first one is to mark a function as unsafe:
+
+```rust
+unsafe fn danger_will_robinson() {
+    // scary stuff 
+}
+```
+
+All functions called from [FFI][ffi] must be marked as `unsafe`, for example.
+The second use of `unsafe` is an unsafe block:
+
+[ffi]: ffi.html
+
+```rust
+unsafe {
+    // scary stuff
+}
+```
+
+It’s important to be able to explicitly delineate code that may have bugs that
+cause big problems. If a Rust program segfaults, you can be sure it’s somewhere
+in the sections marked `unsafe`.
+
+# What does ‘safe’ mean?
+
+Safe, in the context of Rust, means “doesn’t do anything unsafe.” Easy!
+
+Okay, let’s try again: what is not safe to do? Here’s a list:
+
+* Data races
+* Dereferencing a null/dangling raw pointer
+* Reads of [undef][undef] (uninitialized) memory
+* Breaking the [pointer aliasing rules][aliasing] with raw pointers.
+* `&mut T` and `&T` follow LLVM’s scoped [noalias][noalias] model, except if
+  the `&T` contains an `UnsafeCell<U>`. Unsafe code must not violate these
+  aliasing guarantees.
+* Mutating an immutable value/reference without `UnsafeCell<U>`
+* Invoking undefined behavior via compiler intrinsics:
+  * Indexing outside of the bounds of an object with `std::ptr::offset`
+    (`offset` intrinsic), with
+    the exception of one byte past the end which is permitted.
+  * Using `std::ptr::copy_nonoverlapping_memory` (`memcpy32`/`memcpy64`
+    intrinsics) on overlapping buffers
+* Invalid values in primitive types, even in private fields/locals:
+  * Null/dangling references or boxes
+  * A value other than `false` (0) or `true` (1) in a `bool`
+  * A discriminant in an `enum` not included in its type definition
+  * A value in a `char` which is a surrogate or above `char::MAX`
+  * Non-UTF-8 byte sequences in a `str`
+* Unwinding into Rust from foreign code or unwinding from Rust into foreign
+  code.
+
+[noalias]: http://llvm.org/docs/LangRef.html#noalias
+[undef]: http://llvm.org/docs/LangRef.html#undefined-values
+[aliasing]: http://llvm.org/docs/LangRef.html#pointer-aliasing-rules
+
+Whew! That’s a bunch of stuff. It’s also important to notice all kinds of
+behaviors that are certainly bad, but are expressly _not_ unsafe:
+
+* Deadlocks
+* Reading data from private fields
+* Leaks due to reference count cycles
+* Exiting without calling destructors
+* Sending signals
+* Accessing/modifying the file system
+* Integer overflow
+
+Rust cannot prevent all kinds of software problems. Buggy code can and will be
+written in Rust. These things aren’t great, but they don’t qualify as `unsafe`
+specifically.
+
+# Unsafe Superpowers
+
+In both unsafe functions and unsafe blocks, Rust will let you do three things
+that you normally can not do. Just three. Here they are:
+
+1. Access or update a [static mutable variable][static].
+2. Dereference a raw pointer.
+3. Call unsafe functions. This is the most powerful ability.
+
+That’s it. It’s important that `unsafe` does not, for example, ‘turn off the
+borrow checker’. Adding `unsafe` to some random Rust code doesn’t change its
+semantics, it won’t just start accepting anything.
+
+But it will let you write things that _do_ break some of the rules. Let’s go
+over these three abilities in order.
+
+## Access or update a `static mut`
+
+Rust has a feature called ‘`static mut`’ which allows for mutable global state.
+Doing so can cause a data race, and as such is inherently not safe. For more
+details, see the [static][static] section of the book.
+
+[static]: static.html
+
+## Dereference a raw pointer
+
+Raw pointers let you do arbitrary pointer arithmetic, and can cause a number of
+different memory safety and security issues. In some senses, the ability to
+dereference an arbitrary pointer is one of the most dangerous things you can
+do. For more on raw pointers, see [their section of the book][rawpointers].
+
+[rawpointers]: raw-pointers.html
+
+## Call unsafe functions
+
+This last ability works with both aspects of `unsafe`: you can only call
+functions marked `unsafe` from inside an unsafe block.
+
+This ability is powerful and varied. Rust exposes some [compiler
+intrinsics][intrinsics] as unsafe functions, and some unsafe functions bypass
+safety checks, trading safety for speed.
+
+I’ll repeat again: even though you _can_ do arbitrary things in unsafe blocks
+and functions doesn’t mean you should. The compiler will act as though you’re
+upholding its invariants, so be careful!
+
+[intrinsics]: intrinsics.html
index f307f23f0116a8479f6d532e09219ca2b542118a..756abeff06d354e3b3598f1b5f9a4b3bd1255e1d 100644 (file)
@@ -1,3 +1,58 @@
 % Unsized Types
 
-Coming Soon!
+Most types have a particular size, in bytes, that is knowable at compile time.
+For example, an `i32` is thirty-two bits big, or four bytes. However, there are
+some types which are useful to express, but do not have a defined size. These are
+called ‘unsized’ or ‘dynamically sized’ types. One example is `[T]`. This type
+represents a certain number of `T` in sequence. But we don’t know how many
+there are, so the size is not known.
+
+Rust understands a few of these types, but they have some restrictions. There
+are three:
+
+1. We can only manipulate an instance of an unsized type via a pointer. An
+   `&[T]` works just fine, but a `[T]` does not.
+2. Variables and arguments cannot have dynamically sized types.
+3. Only the last field in a `struct` may have a dynamically sized type; the
+   other fields must not. Enum variants must not have dynamically sized types as
+   data.
+
+So why bother? Well, because `[T]` can only be used behind a pointer, if we
+didn’t have language support for unsized types, it would be impossible to write
+this:
+
+```rust,ignore
+impl Foo for str {
+```
+
+or
+
+```rust,ignore
+impl<T> Foo for [T] {
+```
+
+Instead, you would have to write:
+
+```rust,ignore
+impl Foo for &str {
+```
+
+Meaning, this implementation would only work for [references][ref], and not
+other types of pointers. With this `impl`, all pointers, including (at some
+point, there are some bugs to fix first) user-defined custom smart pointers,
+can use this `impl`.
+
+# ?Sized
+
+If you want to write a function that accepts a dynamically sized type, you
+can use the special bound, `?Sized`:
+
+```rust
+struct Foo<T: ?Sized> {
+    f: T,
+}
+```
+
+This `?`, read as “T may be `Sized`”,  means that this bound is special: it
+lets us match more kinds, not less. It’s almost like every `T` implicitly has
+`T: Sized`, and the `?` undoes this default.
index 6fa5917ea99ba9a01c720357348f618570f90a30..965cb218c699a1ecec1a4d5a2ed3dc9b675a9b21 100644 (file)
@@ -1,37 +1,58 @@
 % Vectors
 
-A *vector* is a dynamic or "growable" array, implemented as the standard
-library type [`Vec<T>`](../std/vec/) (Where `<T>` is a [Generic](./generics.md)
-statement). Vectors always allocate their data on the heap. Vectors are to
-[slices][slices] what [`String`][string] is to `&str`. You can
-create them with the `vec!` macro:
-
-```{rust}
-let v = vec![1, 2, 3]; // v: Vec<i32>
-```
+A ‘vector’ is a dynamic or ‘growable’ array, implemented as the standard
+library type [`Vec<T>`][vec]. That `<T>` is a [generic][generic], meaning we
+can have vectors of any type. Vectors always allocate their data on the heap.
+You can create them with the `vec!` macro:
 
-[slices]: primitive-types.html#slices
-[string]: strings.html
+```rust
+let v = vec![1, 2, 3, 4, 5]; // v: Vec<i32>
+```
 
-(Notice that unlike the `println!` macro we've used in the past, we use square
-brackets `[]` with `vec!`. Rust allows you to use either in either situation,
+(Notice that unlike the `println!` macro weve used in the past, we use square
+brackets `[]` with `vec!` macro. Rust allows you to use either in either situation,
 this is just convention.)
 
-There's an alternate form of `vec!` for repeating an initial value:
+Theres an alternate form of `vec!` for repeating an initial value:
 
 ```
 let v = vec![0; 10]; // ten zeroes
 ```
 
-You can get the length of, iterate over, and subscript vectors just like
-arrays. In addition, (mutable) vectors can grow automatically:
+## Accessing elements
 
-```{rust}
-let mut nums = vec![1, 2, 3]; // mut nums: Vec<i32>
+To get the value at a particular index in the vector, we use `[]`s:
 
-nums.push(4);
+```rust
+let v = vec![1, 2, 3, 4, 5];
 
-println!("The length of nums is now {}", nums.len()); // Prints 4
+println!("The third element of v is {}", v[2]);
 ```
 
-Vectors have many more useful methods.
+The indices count from `0`, so the third element is `v[2]`.
+
+## Iterating
+
+Once you have a vector, you can iterate through its elements with `for`. There
+are three versions:
+
+```rust
+let mut v = vec![1, 2, 3, 4, 5];
+
+for i in &v {
+    println!("A reference to {}", i);
+}
+
+for i in &mut v {
+    println!("A mutable reference to {}", i);
+}
+
+for i in v {
+    println!("Take ownership of the vector and its element {}", i);
+}
+```
+
+Vectors have many more useful methods, which you can read about in [their
+API documentation][vec].
+
+[vec]: ../std/vec/index.html
index e5e8c9f11bd82691e823583bfc140d4c46d1664c..fe9feb3538d15493fb8f425743b053dd4d84058a 100644 (file)
@@ -46,13 +46,8 @@ def run(args):
 
 f.write("\n")
 
-version = run([llconfig, '--version']).strip()
-
 # LLVM libs
-if version < '3.5':
-    args = [llconfig, '--libs']
-else:
-    args = [llconfig, '--libs', '--system-libs']
+args = [llconfig, '--libs', '--system-libs']
 
 args.extend(components)
 out = run(args)
@@ -73,11 +68,6 @@ for lib in out.strip().replace("\n", ' ').split(' '):
         f.write(", kind = \"static\"")
     f.write(")]\n")
 
-# llvm-config before 3.5 didn't have a system-libs flag
-if version < '3.5':
-    if os == 'win32':
-        f.write("#[link(name = \"imagehlp\")]")
-
 # LLVM ldflags
 out = run([llconfig, '--ldflags'])
 for lib in out.strip().split(' '):
index 1f7923e1caff2b81fa9e0fb9af3be99bc52249a9..6e0cf17a88040beac190bd0e4293442d1b3f1623 100644 (file)
@@ -12,7 +12,7 @@ javac *.java
 rustc -O verify.rs
 for file in ../*/**.rs; do
     echo $file;
-    grun RustLexer tokens -tokens < $file | ./verify $file RustLexer.tokens || break
+    grun RustLexer tokens -tokens < "$file" | ./verify "$file" RustLexer.tokens || break
 done
 ```
 
index 7d071d5e724b4635c2a9640bcb4685b05f4701e3..3d8f3aeb28fa7cbcf60fc1b0f515f15b6b37d245 100644 (file)
@@ -1,5 +1,12 @@
 lexer grammar RustLexer;
 
+@lexer::members {
+  public boolean is_at(int pos) {
+    return _input.index() == pos;
+  }
+}
+
+
 tokens {
     EQ, LT, LE, EQEQ, NE, GE, GT, ANDAND, OROR, NOT, TILDE, PLUT,
     MINUS, STAR, SLASH, PERCENT, CARET, AND, OR, SHL, SHR, BINOP,
@@ -8,14 +15,10 @@ tokens {
     LBRACE, RBRACE, POUND, DOLLAR, UNDERSCORE, LIT_CHAR,
     LIT_INTEGER, LIT_FLOAT, LIT_STR, LIT_STR_RAW, LIT_BINARY,
     LIT_BINARY_RAW, IDENT, LIFETIME, WHITESPACE, DOC_COMMENT,
-    COMMENT
+    COMMENT, SHEBANG
 }
 
-/* Note: due to antlr limitations, we can't represent XID_start and
- * XID_continue properly. ASCII-only substitute. */
-
-fragment XID_start : [_a-zA-Z] ;
-fragment XID_continue : [_a-zA-Z0-9] ;
+import xidstart , xidcontinue;
 
 
 /* Expression-operator symbols */
@@ -90,85 +93,54 @@ fragment CHAR_ESCAPE
   | [xX] HEXIT HEXIT
   | 'u' HEXIT HEXIT HEXIT HEXIT
   | 'U' HEXIT HEXIT HEXIT HEXIT HEXIT HEXIT HEXIT HEXIT
+  | 'u{' HEXIT '}'
+  | 'u{' HEXIT HEXIT '}'
+  | 'u{' HEXIT HEXIT HEXIT '}'
+  | 'u{' HEXIT HEXIT HEXIT HEXIT '}'
+  | 'u{' HEXIT HEXIT HEXIT HEXIT HEXIT '}'
+  | 'u{' HEXIT HEXIT HEXIT HEXIT HEXIT HEXIT '}'
   ;
 
 fragment SUFFIX
   : IDENT
   ;
 
+fragment INTEGER_SUFFIX
+  : { _input.LA(1) != 'e' && _input.LA(1) != 'E' }? SUFFIX
+  ;
+
 LIT_CHAR
-  : '\'' ( '\\' CHAR_ESCAPE | ~[\\'\n\t\r] ) '\'' SUFFIX?
+  : '\'' ( '\\' CHAR_ESCAPE
+         | ~[\\'\n\t\r]
+         | '\ud800' .. '\udbff' '\udc00' .. '\udfff'
+         )
+    '\'' SUFFIX?
   ;
 
 LIT_BYTE
-  : 'b\'' ( '\\' ( [xX] HEXIT HEXIT | [nrt\\'"0] ) | ~[\\'\n\t\r] ) '\'' SUFFIX?
+  : 'b\'' ( '\\' ( [xX] HEXIT HEXIT
+                 | [nrt\\'"0] )
+          | ~[\\'\n\t\r] '\udc00'..'\udfff'?
+          )
+    '\'' SUFFIX?
   ;
 
 LIT_INTEGER
-  : [0-9][0-9_]* SUFFIX?
-  | '0b' [01][01_]* SUFFIX?
-  | '0o' [0-7][0-7_]* SUFFIX?
-  | '0x' [0-9a-fA-F][0-9a-fA-F_]* SUFFIX?
+
+  : [0-9][0-9_]* INTEGER_SUFFIX?
+  | '0b' [01_]+ INTEGER_SUFFIX?
+  | '0o' [0-7_]+ INTEGER_SUFFIX?
+  | '0x' [0-9a-fA-F_]+ INTEGER_SUFFIX?
   ;
 
 LIT_FLOAT
   : [0-9][0-9_]* ('.' {
-        /* dot followed by another dot is a range, no float */
+        /* dot followed by another dot is a range, not a float */
         _input.LA(1) != '.' &&
-        /* dot followed by an identifier is an integer with a function call, no float */
+        /* dot followed by an identifier is an integer with a function call, not a float */
         _input.LA(1) != '_' &&
-        _input.LA(1) != 'a' &&
-        _input.LA(1) != 'b' &&
-        _input.LA(1) != 'c' &&
-        _input.LA(1) != 'd' &&
-        _input.LA(1) != 'e' &&
-        _input.LA(1) != 'f' &&
-        _input.LA(1) != 'g' &&
-        _input.LA(1) != 'h' &&
-        _input.LA(1) != 'i' &&
-        _input.LA(1) != 'j' &&
-        _input.LA(1) != 'k' &&
-        _input.LA(1) != 'l' &&
-        _input.LA(1) != 'm' &&
-        _input.LA(1) != 'n' &&
-        _input.LA(1) != 'o' &&
-        _input.LA(1) != 'p' &&
-        _input.LA(1) != 'q' &&
-        _input.LA(1) != 'r' &&
-        _input.LA(1) != 's' &&
-        _input.LA(1) != 't' &&
-        _input.LA(1) != 'u' &&
-        _input.LA(1) != 'v' &&
-        _input.LA(1) != 'w' &&
-        _input.LA(1) != 'x' &&
-        _input.LA(1) != 'y' &&
-        _input.LA(1) != 'z' &&
-        _input.LA(1) != 'A' &&
-        _input.LA(1) != 'B' &&
-        _input.LA(1) != 'C' &&
-        _input.LA(1) != 'D' &&
-        _input.LA(1) != 'E' &&
-        _input.LA(1) != 'F' &&
-        _input.LA(1) != 'G' &&
-        _input.LA(1) != 'H' &&
-        _input.LA(1) != 'I' &&
-        _input.LA(1) != 'J' &&
-        _input.LA(1) != 'K' &&
-        _input.LA(1) != 'L' &&
-        _input.LA(1) != 'M' &&
-        _input.LA(1) != 'N' &&
-        _input.LA(1) != 'O' &&
-        _input.LA(1) != 'P' &&
-        _input.LA(1) != 'Q' &&
-        _input.LA(1) != 'R' &&
-        _input.LA(1) != 'S' &&
-        _input.LA(1) != 'T' &&
-        _input.LA(1) != 'U' &&
-        _input.LA(1) != 'V' &&
-        _input.LA(1) != 'W' &&
-        _input.LA(1) != 'X' &&
-        _input.LA(1) != 'Y' &&
-        _input.LA(1) != 'Z'
+        !(_input.LA(1) >= 'a' && _input.LA(1) <= 'z') &&
+        !(_input.LA(1) >= 'A' && _input.LA(1) <= 'Z')
   }? | ('.' [0-9][0-9_]*)? ([eE] [-+]? [0-9][0-9_]*)? SUFFIX?)
   ;
 
@@ -176,8 +148,8 @@ LIT_STR
   : '"' ('\\\n' | '\\\r\n' | '\\' CHAR_ESCAPE | .)*? '"' SUFFIX?
   ;
 
-LIT_BINARY : 'b' LIT_STR SUFFIX?;
-LIT_BINARY_RAW : 'rb' LIT_STR_RAW SUFFIX?;
+LIT_BINARY : 'b' LIT_STR ;
+LIT_BINARY_RAW : 'b' LIT_STR_RAW ;
 
 /* this is a bit messy */
 
@@ -197,7 +169,7 @@ LIT_STR_RAW
 
 QUESTION : '?';
 
-IDENT : XID_start XID_continue* ;
+IDENT : XID_Start XID_Continue* ;
 
 fragment QUESTION_IDENTIFIER : QUESTION? IDENT;
 
@@ -205,13 +177,19 @@ LIFETIME : '\'' IDENT ;
 
 WHITESPACE : [ \r\n\t]+ ;
 
-UNDOC_COMMENT     : '////' ~[\r\n]* -> type(COMMENT) ;
+UNDOC_COMMENT     : '////' ~[\n]* -> type(COMMENT) ;
 YESDOC_COMMENT    : '///' ~[\r\n]* -> type(DOC_COMMENT) ;
 OUTER_DOC_COMMENT : '//!' ~[\r\n]* -> type(DOC_COMMENT) ;
-LINE_COMMENT      : '//' ~[\r\n]* -> type(COMMENT) ;
+LINE_COMMENT      : '//' ( ~[/\n] ~[\n]* )? -> type(COMMENT) ;
 
 DOC_BLOCK_COMMENT
   : ('/**' ~[*] | '/*!') (DOC_BLOCK_COMMENT | .)*? '*/' -> type(DOC_COMMENT)
   ;
 
 BLOCK_COMMENT : '/*' (BLOCK_COMMENT | .)*? '*/' -> type(COMMENT) ;
+
+/* these appear at the beginning of a file */
+
+SHEBANG : '#!' { is_at(2) && _input.LA(1) != '[' }? ~[\r\n]* -> type(SHEBANG) ;
+
+UTF8_BOM : '\ufeff' { is_at(1) }? -> skip ;
index b0628303b6601e39e3092647649306783e7446f4..560b6b72471e186c8f31dd421b60b95d94fd76ef 100755 (executable)
@@ -18,13 +18,13 @@ failed=0
 skipped=0
 
 check() {
-    grep --silent "// ignore-lexer-test" $1;
+    grep --silent "// ignore-lexer-test" "$1";
 
     # if it's *not* found...
     if [ $? -eq 1 ]; then
         cd $2 # This `cd` is so java will pick up RustLexer.class. I couldn't
-        # figure out how to wrangle the CLASSPATH, just adding build/grammr didn't
-        # seem to have anny effect.
+        # figure out how to wrangle the CLASSPATH, just adding build/grammar
+        # didn't seem to have any effect.
         if $3 RustLexer tokens -tokens < $1 | $4 $1 $5; then
             echo "pass: $1"
             passed=`expr $passed + 1`
@@ -39,7 +39,7 @@ check() {
 }
 
 for file in $(find $1 -iname '*.rs' ! -path '*/test/compile-fail*'); do
-    check $file $2 $3 $4 $5
+    check "$file" $2 $3 $4 $5
 done
 
 printf "\ntest result: "
index 75b56f54cccc79efc4a5c48f8bd246b8fc986960..dec797747c270a67353294b1251ac5c45082b039 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(plugin)]
+#![feature(plugin, rustc_private, str_char, collections)]
 
 extern crate syntax;
 extern crate rustc;
 extern crate log;
 
 use std::collections::HashMap;
-use std::io::File;
+use std::env;
+use std::fs::File;
+use std::io::{BufRead, Read};
+use std::path::Path;
 
 use syntax::parse;
 use syntax::parse::lexer;
@@ -25,6 +28,8 @@
 
 use syntax::ast;
 use syntax::ast::Name;
+use syntax::codemap;
+use syntax::codemap::Pos;
 use syntax::parse::token;
 use syntax::parse::lexer::TokenAndSpan;
 
@@ -105,6 +110,7 @@ fn id() -> token::Token {
             "LIT_BINARY"        => token::Literal(token::Binary(Name(0)), None),
             "LIT_BINARY_RAW"    => token::Literal(token::BinaryRaw(Name(0), 0), None),
             "QUESTION"          => token::Question,
+            "SHEBANG"           => token::Shebang(Name(0)),
             _                   => continue,
         };
 
@@ -163,23 +169,26 @@ fn count(lit: &str) -> usize {
     lit.chars().take_while(|c| *c == '#').count()
 }
 
-fn parse_antlr_token(s: &str, tokens: &HashMap<String, token::Token>) -> TokenAndSpan {
+fn parse_antlr_token(s: &str, tokens: &HashMap<String, token::Token>, surrogate_pairs_pos: &[usize],
+                     has_bom: bool)
+                     -> TokenAndSpan {
     // old regex:
     // \[@(?P<seq>\d+),(?P<start>\d+):(?P<end>\d+)='(?P<content>.+?)',<(?P<toknum>-?\d+)>,\d+:\d+]
-    let start = s.find_str("[@").unwrap();
-    let comma = start + s[start..].find_str(",").unwrap();
-    let colon = comma + s[comma..].find_str(":").unwrap();
-    let content_start = colon + s[colon..].find_str("='").unwrap();
-    let content_end = content_start + s[content_start..].find_str("',<").unwrap();
-    let toknum_end = content_end + s[content_end..].find_str(">,").unwrap();
+    let start = s.find("[@").unwrap();
+    let comma = start + s[start..].find(",").unwrap();
+    let colon = comma + s[comma..].find(":").unwrap();
+    let content_start = colon + s[colon..].find("='").unwrap();
+    // Use rfind instead of find, because we don't want to stop at the content
+    let content_end = content_start + s[content_start..].rfind("',<").unwrap();
+    let toknum_end = content_end + s[content_end..].find(">,").unwrap();
 
     let start = &s[comma + 1 .. colon];
     let end = &s[colon + 1 .. content_start];
     let content = &s[content_start + 2 .. content_end];
     let toknum = &s[content_end + 3 .. toknum_end];
 
-    let proto_tok = tokens.get(toknum).expect(format!("didn't find token {:?} in the map",
-                                                              toknum));
+    let not_found = format!("didn't find token {:?} in the map", toknum);
+    let proto_tok = tokens.get(toknum).expect(&not_found[..]);
 
     let nm = parse::token::intern(content);
 
@@ -205,17 +214,25 @@ fn parse_antlr_token(s: &str, tokens: &HashMap<String, token::Token>) -> TokenAn
         ref t => t.clone()
     };
 
-    let offset = if real_tok == token::Eof
- {
+    let start_offset = if real_tok == token::Eof {
         1
     } else {
         0
     };
 
-    let sp = syntax::codemap::Span {
-        lo: syntax::codemap::BytePos(start.parse::<u32>().unwrap() - offset),
-        hi: syntax::codemap::BytePos(end.parse::<u32>().unwrap() + 1),
-        expn_id: syntax::codemap::NO_EXPANSION
+    let offset = if has_bom { 1 } else { 0 };
+
+    let mut lo = start.parse::<u32>().unwrap() - start_offset - offset;
+    let mut hi = end.parse::<u32>().unwrap() + 1 - offset;
+
+    // Adjust the span: For each surrogate pair already encountered, subtract one position.
+    lo -= surrogate_pairs_pos.binary_search(&(lo as usize)).unwrap_or_else(|x| x) as u32;
+    hi -= surrogate_pairs_pos.binary_search(&(hi as usize)).unwrap_or_else(|x| x) as u32;
+
+    let sp = codemap::Span {
+        lo: codemap::BytePos(lo),
+        hi: codemap::BytePos(hi),
+        expn_id: codemap::NO_EXPANSION
     };
 
     TokenAndSpan {
@@ -234,24 +251,39 @@ fn tok_cmp(a: &token::Token, b: &token::Token) -> bool {
     }
 }
 
+fn span_cmp(antlr_sp: codemap::Span, rust_sp: codemap::Span, cm: &codemap::CodeMap) -> bool {
+    antlr_sp.expn_id == rust_sp.expn_id &&
+        antlr_sp.lo.to_usize() == cm.bytepos_to_file_charpos(rust_sp.lo).to_usize() &&
+        antlr_sp.hi.to_usize() == cm.bytepos_to_file_charpos(rust_sp.hi).to_usize()
+}
+
 fn main() {
     fn next(r: &mut lexer::StringReader) -> TokenAndSpan {
         use syntax::parse::lexer::Reader;
         r.next_token()
     }
 
-    let args = std::os::args();
+    let mut args = env::args().skip(1);
+    let filename = args.next().unwrap();
+    if filename.find("parse-fail").is_some() {
+        return;
+    }
+
+    // Rust's lexer
+    let mut code = String::new();
+    File::open(&Path::new(&filename)).unwrap().read_to_string(&mut code).unwrap();
 
-    let mut token_file = File::open(&Path::new(args[2]));
-    let token_map = parse_token_list(token_file.read_to_string().unwrap());
+    let surrogate_pairs_pos: Vec<usize> = code.chars().enumerate()
+                                                     .filter(|&(_, c)| c as usize > 0xFFFF)
+                                                     .map(|(n, _)| n)
+                                                     .enumerate()
+                                                     .map(|(x, n)| x + n)
+                                                     .collect();
 
-    let mut stdin = std::io::stdin();
-    let mut lock = stdin.lock();
-    let lines = lock.lines();
-    let mut antlr_tokens = lines.map(|l| parse_antlr_token(l.unwrap().trim(),
-                                                                   &token_map));
+    let has_bom = code.starts_with("\u{feff}");
+
+    debug!("Pairs: {:?}", surrogate_pairs_pos);
 
-    let code = File::open(&Path::new(args[1])).unwrap().read_to_string().unwrap();
     let options = config::basic_options();
     let session = session::build_session(options, None,
                                          syntax::diagnostics::registry::Registry::new(&[]));
@@ -259,6 +291,21 @@ fn next(r: &mut lexer::StringReader) -> TokenAndSpan {
                                            code,
                                            String::from_str("<n/a>"));
     let mut lexer = lexer::StringReader::new(session.diagnostic(), filemap);
+    let ref cm = lexer.span_diagnostic.cm;
+
+    // ANTLR
+    let mut token_file = File::open(&Path::new(&args.next().unwrap())).unwrap();
+    let mut token_list = String::new();
+    token_file.read_to_string(&mut token_list).unwrap();
+    let token_map = parse_token_list(&token_list[..]);
+
+    let stdin = std::io::stdin();
+    let lock = stdin.lock();
+    let lines = lock.lines();
+    let antlr_tokens = lines.map(|l| parse_antlr_token(l.unwrap().trim(),
+                                                       &token_map,
+                                                       &surrogate_pairs_pos[..],
+                                                       has_bom));
 
     for antlr_tok in antlr_tokens {
         let rustc_tok = next(&mut lexer);
@@ -266,7 +313,8 @@ fn next(r: &mut lexer::StringReader) -> TokenAndSpan {
             continue
         }
 
-        assert!(rustc_tok.sp == antlr_tok.sp, "{:?} and {:?} have different spans", rustc_tok,
+        assert!(span_cmp(antlr_tok.sp, rustc_tok.sp, cm), "{:?} and {:?} have different spans",
+                rustc_tok,
                 antlr_tok);
 
         macro_rules! matches {
@@ -282,7 +330,7 @@ macro_rules! matches {
                         }
                         _ => panic!("{:?} is not {:?}", antlr_tok, rustc_tok)
                     },)*
-                    ref c => assert!(c == &antlr_tok.tok, "{:?} is not {:?}", rustc_tok, antlr_tok)
+                    ref c => assert!(c == &antlr_tok.tok, "{:?} is not {:?}", antlr_tok, rustc_tok)
                 }
             )
         }
diff --git a/src/grammar/xidcontinue.g4 b/src/grammar/xidcontinue.g4
new file mode 100644 (file)
index 0000000..f3a1a3b
--- /dev/null
@@ -0,0 +1,473 @@
+lexer grammar Xidcontinue;
+
+fragment XID_Continue:
+      '\u0030' .. '\u0039'
+    | '\u0041' .. '\u005a'
+    | '\u005f'
+    | '\u0061' .. '\u007a'
+    | '\u00aa'
+    | '\u00b5'
+    | '\u00b7'
+    | '\u00ba'
+    | '\u00c0' .. '\u00d6'
+    | '\u00d8' .. '\u00f6'
+    | '\u00f8' .. '\u0236'
+    | '\u0250' .. '\u02c1'
+    | '\u02c6' .. '\u02d1'
+    | '\u02e0' .. '\u02e4'
+    | '\u02ee'
+    | '\u0300' .. '\u0357'
+    | '\u035d' .. '\u036f'
+    | '\u0386'
+    | '\u0388' .. '\u038a'
+    | '\u038c'
+    | '\u038e' .. '\u03a1'
+    | '\u03a3' .. '\u03ce'
+    | '\u03d0' .. '\u03f5'
+    | '\u03f7' .. '\u03fb'
+    | '\u0400' .. '\u0481'
+    | '\u0483' .. '\u0486'
+    | '\u048a' .. '\u04ce'
+    | '\u04d0' .. '\u04f5'
+    | '\u04f8' .. '\u04f9'
+    | '\u0500' .. '\u050f'
+    | '\u0531' .. '\u0556'
+    | '\u0559'
+    | '\u0561' .. '\u0587'
+    | '\u0591' .. '\u05a1'
+    | '\u05a3' .. '\u05b9'
+    | '\u05bb' .. '\u05bd'
+    | '\u05bf'
+    | '\u05c1' .. '\u05c2'
+    | '\u05c4'
+    | '\u05d0' .. '\u05ea'
+    | '\u05f0' .. '\u05f2'
+    | '\u0610' .. '\u0615'
+    | '\u0621' .. '\u063a'
+    | '\u0640' .. '\u0658'
+    | '\u0660' .. '\u0669'
+    | '\u066e' .. '\u06d3'
+    | '\u06d5' .. '\u06dc'
+    | '\u06df' .. '\u06e8'
+    | '\u06ea' .. '\u06fc'
+    | '\u06ff'
+    | '\u0710' .. '\u074a'
+    | '\u074d' .. '\u074f'
+    | '\u0780' .. '\u07b1'
+    | '\u0901' .. '\u0939'
+    | '\u093c' .. '\u094d'
+    | '\u0950' .. '\u0954'
+    | '\u0958' .. '\u0963'
+    | '\u0966' .. '\u096f'
+    | '\u0981' .. '\u0983'
+    | '\u0985' .. '\u098c'
+    | '\u098f' .. '\u0990'
+    | '\u0993' .. '\u09a8'
+    | '\u09aa' .. '\u09b0'
+    | '\u09b2'
+    | '\u09b6' .. '\u09b9'
+    | '\u09bc' .. '\u09c4'
+    | '\u09c7' .. '\u09c8'
+    | '\u09cb' .. '\u09cd'
+    | '\u09d7'
+    | '\u09dc' .. '\u09dd'
+    | '\u09df' .. '\u09e3'
+    | '\u09e6' .. '\u09f1'
+    | '\u0a01' .. '\u0a03'
+    | '\u0a05' .. '\u0a0a'
+    | '\u0a0f' .. '\u0a10'
+    | '\u0a13' .. '\u0a28'
+    | '\u0a2a' .. '\u0a30'
+    | '\u0a32' .. '\u0a33'
+    | '\u0a35' .. '\u0a36'
+    | '\u0a38' .. '\u0a39'
+    | '\u0a3c'
+    | '\u0a3e' .. '\u0a42'
+    | '\u0a47' .. '\u0a48'
+    | '\u0a4b' .. '\u0a4d'
+    | '\u0a59' .. '\u0a5c'
+    | '\u0a5e'
+    | '\u0a66' .. '\u0a74'
+    | '\u0a81' .. '\u0a83'
+    | '\u0a85' .. '\u0a8d'
+    | '\u0a8f' .. '\u0a91'
+    | '\u0a93' .. '\u0aa8'
+    | '\u0aaa' .. '\u0ab0'
+    | '\u0ab2' .. '\u0ab3'
+    | '\u0ab5' .. '\u0ab9'
+    | '\u0abc' .. '\u0ac5'
+    | '\u0ac7' .. '\u0ac9'
+    | '\u0acb' .. '\u0acd'
+    | '\u0ad0'
+    | '\u0ae0' .. '\u0ae3'
+    | '\u0ae6' .. '\u0aef'
+    | '\u0b01' .. '\u0b03'
+    | '\u0b05' .. '\u0b0c'
+    | '\u0b0f' .. '\u0b10'
+    | '\u0b13' .. '\u0b28'
+    | '\u0b2a' .. '\u0b30'
+    | '\u0b32' .. '\u0b33'
+    | '\u0b35' .. '\u0b39'
+    | '\u0b3c' .. '\u0b43'
+    | '\u0b47' .. '\u0b48'
+    | '\u0b4b' .. '\u0b4d'
+    | '\u0b56' .. '\u0b57'
+    | '\u0b5c' .. '\u0b5d'
+    | '\u0b5f' .. '\u0b61'
+    | '\u0b66' .. '\u0b6f'
+    | '\u0b71'
+    | '\u0b82' .. '\u0b83'
+    | '\u0b85' .. '\u0b8a'
+    | '\u0b8e' .. '\u0b90'
+    | '\u0b92' .. '\u0b95'
+    | '\u0b99' .. '\u0b9a'
+    | '\u0b9c'
+    | '\u0b9e' .. '\u0b9f'
+    | '\u0ba3' .. '\u0ba4'
+    | '\u0ba8' .. '\u0baa'
+    | '\u0bae' .. '\u0bb5'
+    | '\u0bb7' .. '\u0bb9'
+    | '\u0bbe' .. '\u0bc2'
+    | '\u0bc6' .. '\u0bc8'
+    | '\u0bca' .. '\u0bcd'
+    | '\u0bd7'
+    | '\u0be7' .. '\u0bef'
+    | '\u0c01' .. '\u0c03'
+    | '\u0c05' .. '\u0c0c'
+    | '\u0c0e' .. '\u0c10'
+    | '\u0c12' .. '\u0c28'
+    | '\u0c2a' .. '\u0c33'
+    | '\u0c35' .. '\u0c39'
+    | '\u0c3e' .. '\u0c44'
+    | '\u0c46' .. '\u0c48'
+    | '\u0c4a' .. '\u0c4d'
+    | '\u0c55' .. '\u0c56'
+    | '\u0c60' .. '\u0c61'
+    | '\u0c66' .. '\u0c6f'
+    | '\u0c82' .. '\u0c83'
+    | '\u0c85' .. '\u0c8c'
+    | '\u0c8e' .. '\u0c90'
+    | '\u0c92' .. '\u0ca8'
+    | '\u0caa' .. '\u0cb3'
+    | '\u0cb5' .. '\u0cb9'
+    | '\u0cbc' .. '\u0cc4'
+    | '\u0cc6' .. '\u0cc8'
+    | '\u0cca' .. '\u0ccd'
+    | '\u0cd5' .. '\u0cd6'
+    | '\u0cde'
+    | '\u0ce0' .. '\u0ce1'
+    | '\u0ce6' .. '\u0cef'
+    | '\u0d02' .. '\u0d03'
+    | '\u0d05' .. '\u0d0c'
+    | '\u0d0e' .. '\u0d10'
+    | '\u0d12' .. '\u0d28'
+    | '\u0d2a' .. '\u0d39'
+    | '\u0d3e' .. '\u0d43'
+    | '\u0d46' .. '\u0d48'
+    | '\u0d4a' .. '\u0d4d'
+    | '\u0d57'
+    | '\u0d60' .. '\u0d61'
+    | '\u0d66' .. '\u0d6f'
+    | '\u0d82' .. '\u0d83'
+    | '\u0d85' .. '\u0d96'
+    | '\u0d9a' .. '\u0db1'
+    | '\u0db3' .. '\u0dbb'
+    | '\u0dbd'
+    | '\u0dc0' .. '\u0dc6'
+    | '\u0dca'
+    | '\u0dcf' .. '\u0dd4'
+    | '\u0dd6'
+    | '\u0dd8' .. '\u0ddf'
+    | '\u0df2' .. '\u0df3'
+    | '\u0e01' .. '\u0e3a'
+    | '\u0e40' .. '\u0e4e'
+    | '\u0e50' .. '\u0e59'
+    | '\u0e81' .. '\u0e82'
+    | '\u0e84'
+    | '\u0e87' .. '\u0e88'
+    | '\u0e8a'
+    | '\u0e8d'
+    | '\u0e94' .. '\u0e97'
+    | '\u0e99' .. '\u0e9f'
+    | '\u0ea1' .. '\u0ea3'
+    | '\u0ea5'
+    | '\u0ea7'
+    | '\u0eaa' .. '\u0eab'
+    | '\u0ead' .. '\u0eb9'
+    | '\u0ebb' .. '\u0ebd'
+    | '\u0ec0' .. '\u0ec4'
+    | '\u0ec6'
+    | '\u0ec8' .. '\u0ecd'
+    | '\u0ed0' .. '\u0ed9'
+    | '\u0edc' .. '\u0edd'
+    | '\u0f00'
+    | '\u0f18' .. '\u0f19'
+    | '\u0f20' .. '\u0f29'
+    | '\u0f35'
+    | '\u0f37'
+    | '\u0f39'
+    | '\u0f3e' .. '\u0f47'
+    | '\u0f49' .. '\u0f6a'
+    | '\u0f71' .. '\u0f84'
+    | '\u0f86' .. '\u0f8b'
+    | '\u0f90' .. '\u0f97'
+    | '\u0f99' .. '\u0fbc'
+    | '\u0fc6'
+    | '\u1000' .. '\u1021'
+    | '\u1023' .. '\u1027'
+    | '\u1029' .. '\u102a'
+    | '\u102c' .. '\u1032'
+    | '\u1036' .. '\u1039'
+    | '\u1040' .. '\u1049'
+    | '\u1050' .. '\u1059'
+    | '\u10a0' .. '\u10c5'
+    | '\u10d0' .. '\u10f8'
+    | '\u1100' .. '\u1159'
+    | '\u115f' .. '\u11a2'
+    | '\u11a8' .. '\u11f9'
+    | '\u1200' .. '\u1206'
+    | '\u1208' .. '\u1246'
+    | '\u1248'
+    | '\u124a' .. '\u124d'
+    | '\u1250' .. '\u1256'
+    | '\u1258'
+    | '\u125a' .. '\u125d'
+    | '\u1260' .. '\u1286'
+    | '\u1288'
+    | '\u128a' .. '\u128d'
+    | '\u1290' .. '\u12ae'
+    | '\u12b0'
+    | '\u12b2' .. '\u12b5'
+    | '\u12b8' .. '\u12be'
+    | '\u12c0'
+    | '\u12c2' .. '\u12c5'
+    | '\u12c8' .. '\u12ce'
+    | '\u12d0' .. '\u12d6'
+    | '\u12d8' .. '\u12ee'
+    | '\u12f0' .. '\u130e'
+    | '\u1310'
+    | '\u1312' .. '\u1315'
+    | '\u1318' .. '\u131e'
+    | '\u1320' .. '\u1346'
+    | '\u1348' .. '\u135a'
+    | '\u1369' .. '\u1371'
+    | '\u13a0' .. '\u13f4'
+    | '\u1401' .. '\u166c'
+    | '\u166f' .. '\u1676'
+    | '\u1681' .. '\u169a'
+    | '\u16a0' .. '\u16ea'
+    | '\u16ee' .. '\u16f0'
+    | '\u1700' .. '\u170c'
+    | '\u170e' .. '\u1714'
+    | '\u1720' .. '\u1734'
+    | '\u1740' .. '\u1753'
+    | '\u1760' .. '\u176c'
+    | '\u176e' .. '\u1770'
+    | '\u1772' .. '\u1773'
+    | '\u1780' .. '\u17b3'
+    | '\u17b6' .. '\u17d3'
+    | '\u17d7'
+    | '\u17dc' .. '\u17dd'
+    | '\u17e0' .. '\u17e9'
+    | '\u180b' .. '\u180d'
+    | '\u1810' .. '\u1819'
+    | '\u1820' .. '\u1877'
+    | '\u1880' .. '\u18a9'
+    | '\u1900' .. '\u191c'
+    | '\u1920' .. '\u192b'
+    | '\u1930' .. '\u193b'
+    | '\u1946' .. '\u196d'
+    | '\u1970' .. '\u1974'
+    | '\u1d00' .. '\u1d6b'
+    | '\u1e00' .. '\u1e9b'
+    | '\u1ea0' .. '\u1ef9'
+    | '\u1f00' .. '\u1f15'
+    | '\u1f18' .. '\u1f1d'
+    | '\u1f20' .. '\u1f45'
+    | '\u1f48' .. '\u1f4d'
+    | '\u1f50' .. '\u1f57'
+    | '\u1f59'
+    | '\u1f5b'
+    | '\u1f5d'
+    | '\u1f5f' .. '\u1f7d'
+    | '\u1f80' .. '\u1fb4'
+    | '\u1fb6' .. '\u1fbc'
+    | '\u1fbe'
+    | '\u1fc2' .. '\u1fc4'
+    | '\u1fc6' .. '\u1fcc'
+    | '\u1fd0' .. '\u1fd3'
+    | '\u1fd6' .. '\u1fdb'
+    | '\u1fe0' .. '\u1fec'
+    | '\u1ff2' .. '\u1ff4'
+    | '\u1ff6' .. '\u1ffc'
+    | '\u203f' .. '\u2040'
+    | '\u2054'
+    | '\u2071'
+    | '\u207f'
+    | '\u20d0' .. '\u20dc'
+    | '\u20e1'
+    | '\u20e5' .. '\u20ea'
+    | '\u2102'
+    | '\u2107'
+    | '\u210a' .. '\u2113'
+    | '\u2115'
+    | '\u2118' .. '\u211d'
+    | '\u2124'
+    | '\u2126'
+    | '\u2128'
+    | '\u212a' .. '\u2131'
+    | '\u2133' .. '\u2139'
+    | '\u213d' .. '\u213f'
+    | '\u2145' .. '\u2149'
+    | '\u2160' .. '\u2183'
+    | '\u3005' .. '\u3007'
+    | '\u3021' .. '\u302f'
+    | '\u3031' .. '\u3035'
+    | '\u3038' .. '\u303c'
+    | '\u3041' .. '\u3096'
+    | '\u3099' .. '\u309a'
+    | '\u309d' .. '\u309f'
+    | '\u30a1' .. '\u30ff'
+    | '\u3105' .. '\u312c'
+    | '\u3131' .. '\u318e'
+    | '\u31a0' .. '\u31b7'
+    | '\u31f0' .. '\u31ff'
+    | '\u3400' .. '\u4db5'
+    | '\u4e00' .. '\u9fa5'
+    | '\ua000' .. '\ua48c'
+    | '\uac00' .. '\ud7a3'
+    | '\uf900' .. '\ufa2d'
+    | '\ufa30' .. '\ufa6a'
+    | '\ufb00' .. '\ufb06'
+    | '\ufb13' .. '\ufb17'
+    | '\ufb1d' .. '\ufb28'
+    | '\ufb2a' .. '\ufb36'
+    | '\ufb38' .. '\ufb3c'
+    | '\ufb3e'
+    | '\ufb40' .. '\ufb41'
+    | '\ufb43' .. '\ufb44'
+    | '\ufb46' .. '\ufbb1'
+    | '\ufbd3' .. '\ufc5d'
+    | '\ufc64' .. '\ufd3d'
+    | '\ufd50' .. '\ufd8f'
+    | '\ufd92' .. '\ufdc7'
+    | '\ufdf0' .. '\ufdf9'
+    | '\ufe00' .. '\ufe0f'
+    | '\ufe20' .. '\ufe23'
+    | '\ufe33' .. '\ufe34'
+    | '\ufe4d' .. '\ufe4f'
+    | '\ufe71'
+    | '\ufe73'
+    | '\ufe77'
+    | '\ufe79'
+    | '\ufe7b'
+    | '\ufe7d'
+    | '\ufe7f' .. '\ufefc'
+    | '\uff10' .. '\uff19'
+    | '\uff21' .. '\uff3a'
+    | '\uff3f'
+    | '\uff41' .. '\uff5a'
+    | '\uff65' .. '\uffbe'
+    | '\uffc2' .. '\uffc7'
+    | '\uffca' .. '\uffcf'
+    | '\uffd2' .. '\uffd7'
+    | '\uffda' .. '\uffdc'
+    | '\ud800' '\udc00' .. '\udc0a'
+    | '\ud800' '\udc0d' .. '\udc25'
+    | '\ud800' '\udc28' .. '\udc39'
+    | '\ud800' '\udc3c' .. '\udc3c'
+    | '\ud800' '\udc3f' .. '\udc4c'
+    | '\ud800' '\udc50' .. '\udc5c'
+    | '\ud800' '\udc80' .. '\udcf9'
+    | '\ud800' '\udf00' .. '\udf1d'
+    | '\ud800' '\udf30' .. '\udf49'
+    | '\ud800' '\udf80' .. '\udf9c'
+    | '\ud801' '\ue000' .. '\ue09c'
+    | '\ud801' '\ue0a0' .. '\ue0a8'
+    | '\ud802' '\ue400' .. '\ue404'
+    | '\ud802' '\u0808'
+    | '\ud802' '\ue40a' .. '\ue434'
+    | '\ud802' '\ue437' .. '\ue437'
+    | '\ud802' '\u083c'
+    | '\ud802' '\u083f'
+    | '\ud834' '\uad65' .. '\uad68'
+    | '\ud834' '\uad6d' .. '\uad71'
+    | '\ud834' '\uad7b' .. '\uad81'
+    | '\ud834' '\uad85' .. '\uad8a'
+    | '\ud834' '\uadaa' .. '\uadac'
+    | '\ud835' '\ub000' .. '\ub053'
+    | '\ud835' '\ub056' .. '\ub09b'
+    | '\ud835' '\ub09e' .. '\ub09e'
+    | '\ud835' '\ud4a2'
+    | '\ud835' '\ub0a5' .. '\ub0a5'
+    | '\ud835' '\ub0a9' .. '\ub0ab'
+    | '\ud835' '\ub0ae' .. '\ub0b8'
+    | '\ud835' '\ud4bb'
+    | '\ud835' '\ub0bd' .. '\ub0c2'
+    | '\ud835' '\ub0c5' .. '\ub104'
+    | '\ud835' '\ub107' .. '\ub109'
+    | '\ud835' '\ub10d' .. '\ub113'
+    | '\ud835' '\ub116' .. '\ub11b'
+    | '\ud835' '\ub11e' .. '\ub138'
+    | '\ud835' '\ub13b' .. '\ub13d'
+    | '\ud835' '\ub140' .. '\ub143'
+    | '\ud835' '\ud546'
+    | '\ud835' '\ub14a' .. '\ub14f'
+    | '\ud835' '\ub152' .. '\ub2a2'
+    | '\ud835' '\ub2a8' .. '\ub2bf'
+    | '\ud835' '\ub2c2' .. '\ub2d9'
+    | '\ud835' '\ub2dc' .. '\ub2f9'
+    | '\ud835' '\ub2fc' .. '\ub313'
+    | '\ud835' '\ub316' .. '\ub333'
+    | '\ud835' '\ub336' .. '\ub34d'
+    | '\ud835' '\ub350' .. '\ub36d'
+    | '\ud835' '\ub370' .. '\ub387'
+    | '\ud835' '\ub38a' .. '\ub3a7'
+    | '\ud835' '\ub3aa' .. '\ub3c1'
+    | '\ud835' '\ub3c4' .. '\ub3c8'
+    | '\ud835' '\ub3ce' .. '\ub3fe'
+    | '\ud840' '\udc00' .. '\udffe'
+    | '\ud841' '\ue000' .. '\ue3fe'
+    | '\ud842' '\ue400' .. '\ue7fe'
+    | '\ud843' '\ue800' .. '\uebfe'
+    | '\ud844' '\uec00' .. '\ueffe'
+    | '\ud845' '\uf000' .. '\uf3fe'
+    | '\ud846' '\uf400' .. '\uf7fe'
+    | '\ud847' '\uf800' .. '\ufbfe'
+    | '\ud848' '\ufc00' .. '\ufffe'
+    | '\ud849' '\u0000' .. '\u03fe'
+    | '\ud84a' '\u0400' .. '\u07fe'
+    | '\ud84b' '\u0800' .. '\u0bfe'
+    | '\ud84c' '\u0c00' .. '\u0ffe'
+    | '\ud84d' '\u1000' .. '\u13fe'
+    | '\ud84e' '\u1400' .. '\u17fe'
+    | '\ud84f' '\u1800' .. '\u1bfe'
+    | '\ud850' '\u1c00' .. '\u1ffe'
+    | '\ud851' '\u2000' .. '\u23fe'
+    | '\ud852' '\u2400' .. '\u27fe'
+    | '\ud853' '\u2800' .. '\u2bfe'
+    | '\ud854' '\u2c00' .. '\u2ffe'
+    | '\ud855' '\u3000' .. '\u33fe'
+    | '\ud856' '\u3400' .. '\u37fe'
+    | '\ud857' '\u3800' .. '\u3bfe'
+    | '\ud858' '\u3c00' .. '\u3ffe'
+    | '\ud859' '\u4000' .. '\u43fe'
+    | '\ud85a' '\u4400' .. '\u47fe'
+    | '\ud85b' '\u4800' .. '\u4bfe'
+    | '\ud85c' '\u4c00' .. '\u4ffe'
+    | '\ud85d' '\u5000' .. '\u53fe'
+    | '\ud85e' '\u5400' .. '\u57fe'
+    | '\ud85f' '\u5800' .. '\u5bfe'
+    | '\ud860' '\u5c00' .. '\u5ffe'
+    | '\ud861' '\u6000' .. '\u63fe'
+    | '\ud862' '\u6400' .. '\u67fe'
+    | '\ud863' '\u6800' .. '\u6bfe'
+    | '\ud864' '\u6c00' .. '\u6ffe'
+    | '\ud865' '\u7000' .. '\u73fe'
+    | '\ud866' '\u7400' .. '\u77fe'
+    | '\ud867' '\u7800' .. '\u7bfe'
+    | '\ud868' '\u7c00' .. '\u7ffe'
+    | '\ud869' '\u8000' .. '\u82d5'
+    | '\ud87e' '\ud400' .. '\ud61c'
+    | '\udb40' '\udd00' .. '\uddee'
+    ;
diff --git a/src/grammar/xidstart.g4 b/src/grammar/xidstart.g4
new file mode 100644 (file)
index 0000000..53fb50f
--- /dev/null
@@ -0,0 +1,379 @@
+lexer grammar Xidstart;
+
+fragment XID_Start :
+      '\u0041' .. '\u005a'
+    | '_'
+    | '\u0061' .. '\u007a'
+    | '\u00aa'
+    | '\u00b5'
+    | '\u00ba'
+    | '\u00c0' .. '\u00d6'
+    | '\u00d8' .. '\u00f6'
+    | '\u00f8' .. '\u0236'
+    | '\u0250' .. '\u02c1'
+    | '\u02c6' .. '\u02d1'
+    | '\u02e0' .. '\u02e4'
+    | '\u02ee'
+    | '\u0386'
+    | '\u0388' .. '\u038a'
+    | '\u038c'
+    | '\u038e' .. '\u03a1'
+    | '\u03a3' .. '\u03ce'
+    | '\u03d0' .. '\u03f5'
+    | '\u03f7' .. '\u03fb'
+    | '\u0400' .. '\u0481'
+    | '\u048a' .. '\u04ce'
+    | '\u04d0' .. '\u04f5'
+    | '\u04f8' .. '\u04f9'
+    | '\u0500' .. '\u050f'
+    | '\u0531' .. '\u0556'
+    | '\u0559'
+    | '\u0561' .. '\u0587'
+    | '\u05d0' .. '\u05ea'
+    | '\u05f0' .. '\u05f2'
+    | '\u0621' .. '\u063a'
+    | '\u0640' .. '\u064a'
+    | '\u066e' .. '\u066f'
+    | '\u0671' .. '\u06d3'
+    | '\u06d5'
+    | '\u06e5' .. '\u06e6'
+    | '\u06ee' .. '\u06ef'
+    | '\u06fa' .. '\u06fc'
+    | '\u06ff'
+    | '\u0710'
+    | '\u0712' .. '\u072f'
+    | '\u074d' .. '\u074f'
+    | '\u0780' .. '\u07a5'
+    | '\u07b1'
+    | '\u0904' .. '\u0939'
+    | '\u093d'
+    | '\u0950'
+    | '\u0958' .. '\u0961'
+    | '\u0985' .. '\u098c'
+    | '\u098f' .. '\u0990'
+    | '\u0993' .. '\u09a8'
+    | '\u09aa' .. '\u09b0'
+    | '\u09b2'
+    | '\u09b6' .. '\u09b9'
+    | '\u09bd'
+    | '\u09dc' .. '\u09dd'
+    | '\u09df' .. '\u09e1'
+    | '\u09f0' .. '\u09f1'
+    | '\u0a05' .. '\u0a0a'
+    | '\u0a0f' .. '\u0a10'
+    | '\u0a13' .. '\u0a28'
+    | '\u0a2a' .. '\u0a30'
+    | '\u0a32' .. '\u0a33'
+    | '\u0a35' .. '\u0a36'
+    | '\u0a38' .. '\u0a39'
+    | '\u0a59' .. '\u0a5c'
+    | '\u0a5e'
+    | '\u0a72' .. '\u0a74'
+    | '\u0a85' .. '\u0a8d'
+    | '\u0a8f' .. '\u0a91'
+    | '\u0a93' .. '\u0aa8'
+    | '\u0aaa' .. '\u0ab0'
+    | '\u0ab2' .. '\u0ab3'
+    | '\u0ab5' .. '\u0ab9'
+    | '\u0abd'
+    | '\u0ad0'
+    | '\u0ae0' .. '\u0ae1'
+    | '\u0b05' .. '\u0b0c'
+    | '\u0b0f' .. '\u0b10'
+    | '\u0b13' .. '\u0b28'
+    | '\u0b2a' .. '\u0b30'
+    | '\u0b32' .. '\u0b33'
+    | '\u0b35' .. '\u0b39'
+    | '\u0b3d'
+    | '\u0b5c' .. '\u0b5d'
+    | '\u0b5f' .. '\u0b61'
+    | '\u0b71'
+    | '\u0b83'
+    | '\u0b85' .. '\u0b8a'
+    | '\u0b8e' .. '\u0b90'
+    | '\u0b92' .. '\u0b95'
+    | '\u0b99' .. '\u0b9a'
+    | '\u0b9c'
+    | '\u0b9e' .. '\u0b9f'
+    | '\u0ba3' .. '\u0ba4'
+    | '\u0ba8' .. '\u0baa'
+    | '\u0bae' .. '\u0bb5'
+    | '\u0bb7' .. '\u0bb9'
+    | '\u0c05' .. '\u0c0c'
+    | '\u0c0e' .. '\u0c10'
+    | '\u0c12' .. '\u0c28'
+    | '\u0c2a' .. '\u0c33'
+    | '\u0c35' .. '\u0c39'
+    | '\u0c60' .. '\u0c61'
+    | '\u0c85' .. '\u0c8c'
+    | '\u0c8e' .. '\u0c90'
+    | '\u0c92' .. '\u0ca8'
+    | '\u0caa' .. '\u0cb3'
+    | '\u0cb5' .. '\u0cb9'
+    | '\u0cbd'
+    | '\u0cde'
+    | '\u0ce0' .. '\u0ce1'
+    | '\u0d05' .. '\u0d0c'
+    | '\u0d0e' .. '\u0d10'
+    | '\u0d12' .. '\u0d28'
+    | '\u0d2a' .. '\u0d39'
+    | '\u0d60' .. '\u0d61'
+    | '\u0d85' .. '\u0d96'
+    | '\u0d9a' .. '\u0db1'
+    | '\u0db3' .. '\u0dbb'
+    | '\u0dbd'
+    | '\u0dc0' .. '\u0dc6'
+    | '\u0e01' .. '\u0e30'
+    | '\u0e32'
+    | '\u0e40' .. '\u0e46'
+    | '\u0e81' .. '\u0e82'
+    | '\u0e84'
+    | '\u0e87' .. '\u0e88'
+    | '\u0e8a'
+    | '\u0e8d'
+    | '\u0e94' .. '\u0e97'
+    | '\u0e99' .. '\u0e9f'
+    | '\u0ea1' .. '\u0ea3'
+    | '\u0ea5'
+    | '\u0ea7'
+    | '\u0eaa' .. '\u0eab'
+    | '\u0ead' .. '\u0eb0'
+    | '\u0eb2'
+    | '\u0ebd'
+    | '\u0ec0' .. '\u0ec4'
+    | '\u0ec6'
+    | '\u0edc' .. '\u0edd'
+    | '\u0f00'
+    | '\u0f40' .. '\u0f47'
+    | '\u0f49' .. '\u0f6a'
+    | '\u0f88' .. '\u0f8b'
+    | '\u1000' .. '\u1021'
+    | '\u1023' .. '\u1027'
+    | '\u1029' .. '\u102a'
+    | '\u1050' .. '\u1055'
+    | '\u10a0' .. '\u10c5'
+    | '\u10d0' .. '\u10f8'
+    | '\u1100' .. '\u1159'
+    | '\u115f' .. '\u11a2'
+    | '\u11a8' .. '\u11f9'
+    | '\u1200' .. '\u1206'
+    | '\u1208' .. '\u1246'
+    | '\u1248'
+    | '\u124a' .. '\u124d'
+    | '\u1250' .. '\u1256'
+    | '\u1258'
+    | '\u125a' .. '\u125d'
+    | '\u1260' .. '\u1286'
+    | '\u1288'
+    | '\u128a' .. '\u128d'
+    | '\u1290' .. '\u12ae'
+    | '\u12b0'
+    | '\u12b2' .. '\u12b5'
+    | '\u12b8' .. '\u12be'
+    | '\u12c0'
+    | '\u12c2' .. '\u12c5'
+    | '\u12c8' .. '\u12ce'
+    | '\u12d0' .. '\u12d6'
+    | '\u12d8' .. '\u12ee'
+    | '\u12f0' .. '\u130e'
+    | '\u1310'
+    | '\u1312' .. '\u1315'
+    | '\u1318' .. '\u131e'
+    | '\u1320' .. '\u1346'
+    | '\u1348' .. '\u135a'
+    | '\u13a0' .. '\u13f4'
+    | '\u1401' .. '\u166c'
+    | '\u166f' .. '\u1676'
+    | '\u1681' .. '\u169a'
+    | '\u16a0' .. '\u16ea'
+    | '\u16ee' .. '\u16f0'
+    | '\u1700' .. '\u170c'
+    | '\u170e' .. '\u1711'
+    | '\u1720' .. '\u1731'
+    | '\u1740' .. '\u1751'
+    | '\u1760' .. '\u176c'
+    | '\u176e' .. '\u1770'
+    | '\u1780' .. '\u17b3'
+    | '\u17d7'
+    | '\u17dc'
+    | '\u1820' .. '\u1877'
+    | '\u1880' .. '\u18a8'
+    | '\u1900' .. '\u191c'
+    | '\u1950' .. '\u196d'
+    | '\u1970' .. '\u1974'
+    | '\u1d00' .. '\u1d6b'
+    | '\u1e00' .. '\u1e9b'
+    | '\u1ea0' .. '\u1ef9'
+    | '\u1f00' .. '\u1f15'
+    | '\u1f18' .. '\u1f1d'
+    | '\u1f20' .. '\u1f45'
+    | '\u1f48' .. '\u1f4d'
+    | '\u1f50' .. '\u1f57'
+    | '\u1f59'
+    | '\u1f5b'
+    | '\u1f5d'
+    | '\u1f5f' .. '\u1f7d'
+    | '\u1f80' .. '\u1fb4'
+    | '\u1fb6' .. '\u1fbc'
+    | '\u1fbe'
+    | '\u1fc2' .. '\u1fc4'
+    | '\u1fc6' .. '\u1fcc'
+    | '\u1fd0' .. '\u1fd3'
+    | '\u1fd6' .. '\u1fdb'
+    | '\u1fe0' .. '\u1fec'
+    | '\u1ff2' .. '\u1ff4'
+    | '\u1ff6' .. '\u1ffc'
+    | '\u2071'
+    | '\u207f'
+    | '\u2102'
+    | '\u2107'
+    | '\u210a' .. '\u2113'
+    | '\u2115'
+    | '\u2118' .. '\u211d'
+    | '\u2124'
+    | '\u2126'
+    | '\u2128'
+    | '\u212a' .. '\u2131'
+    | '\u2133' .. '\u2139'
+    | '\u213d' .. '\u213f'
+    | '\u2145' .. '\u2149'
+    | '\u2160' .. '\u2183'
+    | '\u3005' .. '\u3007'
+    | '\u3021' .. '\u3029'
+    | '\u3031' .. '\u3035'
+    | '\u3038' .. '\u303c'
+    | '\u3041' .. '\u3096'
+    | '\u309d' .. '\u309f'
+    | '\u30a1' .. '\u30fa'
+    | '\u30fc' .. '\u30ff'
+    | '\u3105' .. '\u312c'
+    | '\u3131' .. '\u318e'
+    | '\u31a0' .. '\u31b7'
+    | '\u31f0' .. '\u31ff'
+    | '\u3400' .. '\u4db5'
+    | '\u4e00' .. '\u9fa5'
+    | '\ua000' .. '\ua48c'
+    | '\uac00' .. '\ud7a3'
+    | '\uf900' .. '\ufa2d'
+    | '\ufa30' .. '\ufa6a'
+    | '\ufb00' .. '\ufb06'
+    | '\ufb13' .. '\ufb17'
+    | '\ufb1d'
+    | '\ufb1f' .. '\ufb28'
+    | '\ufb2a' .. '\ufb36'
+    | '\ufb38' .. '\ufb3c'
+    | '\ufb3e'
+    | '\ufb40' .. '\ufb41'
+    | '\ufb43' .. '\ufb44'
+    | '\ufb46' .. '\ufbb1'
+    | '\ufbd3' .. '\ufc5d'
+    | '\ufc64' .. '\ufd3d'
+    | '\ufd50' .. '\ufd8f'
+    | '\ufd92' .. '\ufdc7'
+    | '\ufdf0' .. '\ufdf9'
+    | '\ufe71'
+    | '\ufe73'
+    | '\ufe77'
+    | '\ufe79'
+    | '\ufe7b'
+    | '\ufe7d'
+    | '\ufe7f' .. '\ufefc'
+    | '\uff21' .. '\uff3a'
+    | '\uff41' .. '\uff5a'
+    | '\uff66' .. '\uff9d'
+    | '\uffa0' .. '\uffbe'
+    | '\uffc2' .. '\uffc7'
+    | '\uffca' .. '\uffcf'
+    | '\uffd2' .. '\uffd7'
+    | '\uffda' .. '\uffdc'
+    | '\ud800' '\udc00' .. '\udc0a'
+    | '\ud800' '\udc0d' .. '\udc25'
+    | '\ud800' '\udc28' .. '\udc39'
+    | '\ud800' '\udc3c' .. '\udc3c'
+    | '\ud800' '\udc3f' .. '\udc4c'
+    | '\ud800' '\udc50' .. '\udc5c'
+    | '\ud800' '\udc80' .. '\udcf9'
+    | '\ud800' '\udf00' .. '\udf1d'
+    | '\ud800' '\udf30' .. '\udf49'
+    | '\ud800' '\udf80' .. '\udf9c'
+    | '\ud801' '\ue000' .. '\ue09c'
+    | '\ud802' '\ue400' .. '\ue404'
+    | '\ud802' '\u0808'
+    | '\ud802' '\ue40a' .. '\ue434'
+    | '\ud802' '\ue437' .. '\ue437'
+    | '\ud802' '\u083c'
+    | '\ud802' '\u083f'
+    | '\ud835' '\ub000' .. '\ub053'
+    | '\ud835' '\ub056' .. '\ub09b'
+    | '\ud835' '\ub09e' .. '\ub09e'
+    | '\ud835' '\ud4a2'
+    | '\ud835' '\ub0a5' .. '\ub0a5'
+    | '\ud835' '\ub0a9' .. '\ub0ab'
+    | '\ud835' '\ub0ae' .. '\ub0b8'
+    | '\ud835' '\ud4bb'
+    | '\ud835' '\ub0bd' .. '\ub0c2'
+    | '\ud835' '\ub0c5' .. '\ub104'
+    | '\ud835' '\ub107' .. '\ub109'
+    | '\ud835' '\ub10d' .. '\ub113'
+    | '\ud835' '\ub116' .. '\ub11b'
+    | '\ud835' '\ub11e' .. '\ub138'
+    | '\ud835' '\ub13b' .. '\ub13d'
+    | '\ud835' '\ub140' .. '\ub143'
+    | '\ud835' '\ud546'
+    | '\ud835' '\ub14a' .. '\ub14f'
+    | '\ud835' '\ub152' .. '\ub2a2'
+    | '\ud835' '\ub2a8' .. '\ub2bf'
+    | '\ud835' '\ub2c2' .. '\ub2d9'
+    | '\ud835' '\ub2dc' .. '\ub2f9'
+    | '\ud835' '\ub2fc' .. '\ub313'
+    | '\ud835' '\ub316' .. '\ub333'
+    | '\ud835' '\ub336' .. '\ub34d'
+    | '\ud835' '\ub350' .. '\ub36d'
+    | '\ud835' '\ub370' .. '\ub387'
+    | '\ud835' '\ub38a' .. '\ub3a7'
+    | '\ud835' '\ub3aa' .. '\ub3c1'
+    | '\ud835' '\ub3c4' .. '\ub3c8'
+    | '\ud840' '\udc00' .. '\udffe'
+    | '\ud841' '\ue000' .. '\ue3fe'
+    | '\ud842' '\ue400' .. '\ue7fe'
+    | '\ud843' '\ue800' .. '\uebfe'
+    | '\ud844' '\uec00' .. '\ueffe'
+    | '\ud845' '\uf000' .. '\uf3fe'
+    | '\ud846' '\uf400' .. '\uf7fe'
+    | '\ud847' '\uf800' .. '\ufbfe'
+    | '\ud848' '\ufc00' .. '\ufffe'
+    | '\ud849' '\u0000' .. '\u03fe'
+    | '\ud84a' '\u0400' .. '\u07fe'
+    | '\ud84b' '\u0800' .. '\u0bfe'
+    | '\ud84c' '\u0c00' .. '\u0ffe'
+    | '\ud84d' '\u1000' .. '\u13fe'
+    | '\ud84e' '\u1400' .. '\u17fe'
+    | '\ud84f' '\u1800' .. '\u1bfe'
+    | '\ud850' '\u1c00' .. '\u1ffe'
+    | '\ud851' '\u2000' .. '\u23fe'
+    | '\ud852' '\u2400' .. '\u27fe'
+    | '\ud853' '\u2800' .. '\u2bfe'
+    | '\ud854' '\u2c00' .. '\u2ffe'
+    | '\ud855' '\u3000' .. '\u33fe'
+    | '\ud856' '\u3400' .. '\u37fe'
+    | '\ud857' '\u3800' .. '\u3bfe'
+    | '\ud858' '\u3c00' .. '\u3ffe'
+    | '\ud859' '\u4000' .. '\u43fe'
+    | '\ud85a' '\u4400' .. '\u47fe'
+    | '\ud85b' '\u4800' .. '\u4bfe'
+    | '\ud85c' '\u4c00' .. '\u4ffe'
+    | '\ud85d' '\u5000' .. '\u53fe'
+    | '\ud85e' '\u5400' .. '\u57fe'
+    | '\ud85f' '\u5800' .. '\u5bfe'
+    | '\ud860' '\u5c00' .. '\u5ffe'
+    | '\ud861' '\u6000' .. '\u63fe'
+    | '\ud862' '\u6400' .. '\u67fe'
+    | '\ud863' '\u6800' .. '\u6bfe'
+    | '\ud864' '\u6c00' .. '\u6ffe'
+    | '\ud865' '\u7000' .. '\u73fe'
+    | '\ud866' '\u7400' .. '\u77fe'
+    | '\ud867' '\u7800' .. '\u7bfe'
+    | '\ud868' '\u7c00' .. '\u7ffe'
+    | '\ud869' '\u8000' .. '\u82d5'
+    | '\ud87e' '\ud400' .. '\ud61c'
+    ;
index 0cfdcd2413fd9f8b57bdee9ecb6006b3e050b62b..9d7f9ea89908f21cab8ee01ca16c381028b2f38b 100644 (file)
@@ -77,7 +77,6 @@
 use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst};
 use core::fmt;
 use core::cmp::Ordering;
-use core::default::Default;
 use core::mem::{min_align_of, size_of};
 use core::mem;
 use core::nonzero::NonZero;
 /// use std::thread;
 ///
 /// fn main() {
-///     let numbers: Vec<_> = (0..100u32).map(|i| i as f32).collect();
+///     let numbers: Vec<_> = (0..100u32).collect();
 ///     let shared_numbers = Arc::new(numbers);
 ///
 ///     for _ in 0..10 {
@@ -676,7 +675,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Default + Sync + Send> Default for Arc<T> {
+impl<T: Default> Default for Arc<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn default() -> Arc<T> { Arc::new(Default::default()) }
 }
index 4468e425a852da07088bd0aca40667c98c05546b..7696abd659f02ff24e6e65c0c4e649617650b8f1 100644 (file)
 
 //! A pointer type for heap allocation.
 //!
-//! `Box<T>`, casually referred to as a 'box', provides the simplest form of
-//! heap allocation in Rust. Boxes provide ownership for this allocation, and
-//! drop their contents when they go out of scope.
-//!
-//! Boxes are useful in two situations: recursive data structures, and
-//! occasionally when returning data. [The Pointer chapter of the
-//! Book](../../../book/pointers.html#best-practices-1) explains these cases in
-//! detail.
+//! `Box<T>`, casually referred to as a 'box', provides the simplest form of heap allocation in
+//! Rust. Boxes provide ownership for this allocation, and drop their contents when they go out of
+//! scope.
 //!
 //! # Examples
 //!
 //! ```
 //!
 //! This will print `Cons(1, Box(Cons(2, Box(Nil))))`.
+//!
+//! Recursive structures must be boxed, because if the definition of `Cons` looked like this:
+//!
+//! ```rust,ignore
+//! Cons(T, List<T>),
+//! ```
+//!
+//! It wouldn't work. This is because the size of a `List` depends on how many elements are in the
+//! list, and so we don't know how much memory to allocate for a `Cons`. By introducing a `Box`,
+//! which has a defined size, we know how big `Cons` needs to be.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -50,7 +55,6 @@
 
 use core::any::Any;
 use core::cmp::Ordering;
-use core::default::Default;
 use core::fmt;
 use core::hash::{self, Hash};
 use core::mem;
index 57baa811b9d4740f82be7a272ae0fe2d44eaaad0..9d1d8a7ac24b8a16a8eb7b8422d7d6f65f36ce66 100644 (file)
@@ -133,6 +133,7 @@ unsafe fn exchange_free(ptr: *mut u8, old_size: usize, align: usize) {
 
 #[cfg(feature = "external_funcs")]
 mod imp {
+    #[allow(improper_ctypes)]
     extern {
         fn rust_allocate(size: usize, align: usize) -> *mut u8;
         fn rust_deallocate(ptr: *mut u8, old_size: usize, align: usize);
@@ -383,7 +384,7 @@ pub fn stats_print() {}
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     extern crate test;
     use self::test::Bencher;
     use boxed::Box;
index 67805d10a4a6313736b37bf4eb548cb82f26f3fb..2ee229ab1dfc5fa6bc5ce80c3571accb9291cbb7 100644 (file)
@@ -459,7 +459,6 @@ impl<T: Default> Default for Rc<T> {
     ///
     /// ```
     /// use std::rc::Rc;
-    /// use std::default::Default;
     ///
     /// let x: Rc<i32> = Default::default();
     /// ```
index 3804874a650f6c065e23c78043bbfc8b1c35a168..0f05e5796aa15fb044a173337e989472b7449982 100644 (file)
 
 use core::prelude::*;
 
-use core::default::Default;
-use core::iter::{FromIterator, IntoIterator};
+use core::iter::{FromIterator};
 use core::mem::{zeroed, replace, swap};
 use core::ptr;
 
@@ -250,28 +249,6 @@ pub fn iter(&self) -> Iter<T> {
         Iter { iter: self.data.iter() }
     }
 
-    /// Creates a consuming iterator, that is, one that moves each value out of
-    /// the binary heap in arbitrary order. The binary heap cannot be used
-    /// after calling this.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// # #![feature(collections)]
-    /// use std::collections::BinaryHeap;
-    /// let heap = BinaryHeap::from_vec(vec![1, 2, 3, 4]);
-    ///
-    /// // Print 1, 2, 3, 4 in arbitrary order
-    /// for x in heap.into_iter() {
-    ///     // x has type i32, not &i32
-    ///     println!("{}", x);
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_iter(self) -> IntoIter<T> {
-        IntoIter { iter: self.data.into_iter() }
-    }
-
     /// Returns the greatest item in the binary heap, or `None` if it is empty.
     ///
     /// # Examples
@@ -675,8 +652,25 @@ impl<T: Ord> IntoIterator for BinaryHeap<T> {
     type Item = T;
     type IntoIter = IntoIter<T>;
 
+    /// Creates a consuming iterator, that is, one that moves each value out of
+    /// the binary heap in arbitrary order. The binary heap cannot be used
+    /// after calling this.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(collections)]
+    /// use std::collections::BinaryHeap;
+    /// let heap = BinaryHeap::from_vec(vec![1, 2, 3, 4]);
+    ///
+    /// // Print 1, 2, 3, 4 in arbitrary order
+    /// for x in heap.into_iter() {
+    ///     // x has type i32, not &i32
+    ///     println!("{}", x);
+    /// }
+    /// ```
     fn into_iter(self) -> IntoIter<T> {
-        self.into_iter()
+        IntoIter { iter: self.data.into_iter() }
     }
 }
 
index d12b979e084fc33c8edb75a1c8e6d754c4d770a2..d9151298a35e3165a1dbfe7ad7fc4659dfaac45a 100644 (file)
@@ -40,7 +40,6 @@
 //! ```
 //! # #![feature(collections, core, step_by)]
 //! use std::collections::{BitSet, BitVec};
-//! use std::num::Float;
 //! use std::iter;
 //!
 //! let max_prime = 10000;
 
 use core::cmp::Ordering;
 use core::cmp;
-use core::default::Default;
 use core::fmt;
 use core::hash;
 use core::iter::RandomAccessIterator;
 use core::iter::{Chain, Enumerate, Repeat, Skip, Take, repeat, Cloned};
-use core::iter::{self, FromIterator, IntoIterator};
+use core::iter::{self, FromIterator};
 use core::ops::Index;
 use core::slice;
 use core::{u8, u32, usize};
index ef335e31e08cb8465072488483e2888277feddf4..291b66939e5ef038eab3fc1cb3b4bf4b724b4b8d 100644 (file)
 use core::prelude::*;
 
 use core::cmp::Ordering;
-use core::default::Default;
 use core::fmt::Debug;
 use core::hash::{Hash, Hasher};
-use core::iter::{Map, FromIterator, IntoIterator};
+use core::iter::{Map, FromIterator};
 use core::ops::Index;
 use core::{iter, fmt, mem, usize};
 use Bound::{self, Included, Excluded, Unbounded};
@@ -471,8 +470,32 @@ impl<K, V> IntoIterator for BTreeMap<K, V> {
     type Item = (K, V);
     type IntoIter = IntoIter<K, V>;
 
+    /// Gets an owning iterator over the entries of the map.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut map = BTreeMap::new();
+    /// map.insert(1, "a");
+    /// map.insert(2, "b");
+    /// map.insert(3, "c");
+    ///
+    /// for (key, value) in map.into_iter() {
+    ///     println!("{}: {}", key, value);
+    /// }
+    /// ```
     fn into_iter(self) -> IntoIter<K, V> {
-        self.into_iter()
+        let len = self.len();
+        let mut lca = VecDeque::new();
+        lca.push_back(Traverse::traverse(self.root));
+        IntoIter {
+            inner: AbsIter {
+                traversals: lca,
+                size: len,
+            }
+        }
     }
 }
 
@@ -1263,35 +1286,6 @@ pub fn iter_mut(&mut self) -> IterMut<K, V> {
         }
     }
 
-    /// Gets an owning iterator over the entries of the map.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::BTreeMap;
-    ///
-    /// let mut map = BTreeMap::new();
-    /// map.insert(1, "a");
-    /// map.insert(2, "b");
-    /// map.insert(3, "c");
-    ///
-    /// for (key, value) in map.into_iter() {
-    ///     println!("{}: {}", key, value);
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_iter(self) -> IntoIter<K, V> {
-        let len = self.len();
-        let mut lca = VecDeque::new();
-        lca.push_back(Traverse::traverse(self.root));
-        IntoIter {
-            inner: AbsIter {
-                traversals: lca,
-                size: len,
-            }
-        }
-    }
-
     /// Gets an iterator over the keys of the map.
     ///
     /// # Examples
index 1abd56fd1458d25dab2562ff4d0ea9597831882d..fc346151e0b4bf70415f6d36176e1a70130b2a3f 100644 (file)
 use core::prelude::*;
 
 use core::cmp::Ordering::{self, Less, Greater, Equal};
-use core::default::Default;
 use core::fmt::Debug;
 use core::fmt;
-use core::iter::{Peekable, Map, FromIterator, IntoIterator};
+use core::iter::{Peekable, Map, FromIterator};
 use core::ops::{BitOr, BitAnd, BitXor, Sub};
 
 use borrow::Borrow;
@@ -132,27 +131,6 @@ impl<T> BTreeSet<T> {
     pub fn iter(&self) -> Iter<T> {
         Iter { iter: self.map.keys() }
     }
-
-    /// Gets an iterator for moving out the BtreeSet's contents.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// # #![feature(core)]
-    /// use std::collections::BTreeSet;
-    ///
-    /// let set: BTreeSet<usize> = [1, 2, 3, 4].iter().cloned().collect();
-    ///
-    /// let v: Vec<usize> = set.into_iter().collect();
-    /// assert_eq!(v, [1, 2, 3, 4]);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_iter(self) -> IntoIter<T> {
-        fn first<A, B>((a, _): (A, B)) -> A { a }
-        let first: fn((T, ())) -> T = first; // coerce to fn pointer
-
-        IntoIter { iter: self.map.into_iter().map(first) }
-    }
 }
 
 impl<T: Ord> BTreeSet<T> {
@@ -500,8 +478,24 @@ impl<T> IntoIterator for BTreeSet<T> {
     type Item = T;
     type IntoIter = IntoIter<T>;
 
+    /// Gets an iterator for moving out the BtreeSet's contents.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(core)]
+    /// use std::collections::BTreeSet;
+    ///
+    /// let set: BTreeSet<usize> = [1, 2, 3, 4].iter().cloned().collect();
+    ///
+    /// let v: Vec<usize> = set.into_iter().collect();
+    /// assert_eq!(v, [1, 2, 3, 4]);
+    /// ```
     fn into_iter(self) -> IntoIter<T> {
-        self.into_iter()
+        fn first<A, B>((a, _): (A, B)) -> A { a }
+        let first: fn((T, ())) -> T = first; // coerce to fn pointer
+
+        IntoIter { iter: self.map.into_iter().map(first) }
     }
 }
 
index a3a266669b1bbb6787c97ebd505bcf8fe8a566a5..e6cdb88d3e1746eb90872a1fb7a2a896a06b4e4f 100644 (file)
@@ -16,7 +16,7 @@
 use core::prelude::*;
 use core::marker;
 use core::fmt;
-use core::iter::{FromIterator, IntoIterator};
+use core::iter::{FromIterator};
 use core::ops::{Sub, BitOr, BitAnd, BitXor};
 
 // FIXME(contentions): implement union family of methods? (general design may be wrong here)
index 5f0d9012d1a7d5b6df3fd0a252b9576b978efc59..4480a7d7e0a09fbe2be418082d6a9b9ee8b32f6f 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15679
 
 //! Utilities for formatting and printing strings
 //!
 //! # #![feature(core, std_misc)]
 //! use std::fmt;
 //! use std::f64;
-//! use std::num::Float;
 //!
 //! #[derive(Debug)]
 //! struct Vector2D {
 //!         let magnitude = magnitude.sqrt();
 //!
 //!         // Respect the formatting flags by using the helper method
-//!         // `pad_integral` on the Formatter object. See the method documentation
-//!         // for details, and the function `pad` can be used to pad strings.
+//!         // `pad_integral` on the Formatter object. See the method
+//!         // documentation for details, and the function `pad` can be used
+//!         // to pad strings.
 //!         let decimals = f.precision().unwrap_or(3);
-//!         let string = f64::to_str_exact(magnitude, decimals);
+//!         let string = format!("{:.*}", decimals, magnitude);
 //!         f.pad_integral(true, "", &string)
 //!     }
 //! }
 //!
 //! ```ignore
 //! format!      // described above
-//! write!       // first argument is a &mut old_io::Writer, the destination
+//! write!       // first argument is a &mut io::Write, the destination
 //! writeln!     // same as write but appends a newline
 //! print!       // the format string is printed to the standard output
 //! println!     // same as print but appends a newline
 //! Example usage is:
 //!
 //! ```
-//! # #![feature(old_io)]
 //! # #![allow(unused_must_use)]
 //! use std::io::Write;
 //! let mut w = Vec::new();
 //! off, some example usage is:
 //!
 //! ```
-//! # #![feature(old_io)]
 //! use std::fmt;
 //! use std::io::{self, Write};
 //!
 //!
 //! ## Precision
 //!
-//! For non-numeric types, this can be considered a "maximum width". If the
-//! resulting string is longer than this width, then it is truncated down to
-//! this many characters and only those are emitted.
+//! For non-numeric types, this can be considered a "maximum width". If the resulting string is
+//! longer than this width, then it is truncated down to this many characters and only those are
+//! emitted.
 //!
 //! For integral types, this has no meaning currently.
 //!
-//! For floating-point types, this indicates how many digits after the decimal
-//! point should be printed.
+//! For floating-point types, this indicates how many digits after the decimal point should be
+//! printed.
+//!
+//! There are three possible ways to specify the desired `precision`:
+//!
+//! There are three possible ways to specify the desired `precision`:
+//! 1. An integer `.N`,
+//! 2. an integer followed by dollar sign `.N$`, or
+//! 3. an asterisk `.*`.
+//!
+//! The first specification, `.N`, means the integer `N` itself is the precision.
+//!
+//! The second, `.N$`, means use format *argument* `N` (which must be a `usize`) as the precision.
+//!
+//! Finally,  `.*` means that this `{...}` is associated with *two* format inputs rather than one:
+//! the first input holds the `usize` precision, and the second holds the value to print.  Note
+//! that in this case, if one uses the format string `{<arg>:<spec>.*}`, then the `<arg>` part
+//! refers to the *value* to print, and the `precision` must come in the input preceding `<arg>`.
+//!
+//! For example, these:
+//!
+//! ```
+//! // Hello {arg 0 (x)} is {arg 1 (0.01} with precision specified inline (5)}
+//! println!("Hello {0} is {1:.5}", "x", 0.01);
+//!
+//! // Hello {arg 1 (x)} is {arg 2 (0.01} with precision specified in arg 0 (5)}
+//! println!("Hello {1} is {2:.0$}", 5, "x", 0.01);
+//!
+//! // Hello {arg 0 (x)} is {arg 2 (0.01} with precision specified in arg 1 (5)}
+//! println!("Hello {0} is {2:.1$}", "x", 5, 0.01);
+//!
+//! // Hello {next arg (x)} is {second of next two args (0.01} with precision
+//! //                          specified in first of next two args (5)}
+//! println!("Hello {} is {:.*}",    "x", 5, 0.01);
+//!
+//! // Hello {next arg (x)} is {arg 2 (0.01} with precision
+//! //                          specified in its predecessor (5)}
+//! println!("Hello {} is {2:.*}",   "x", 5, 0.01);
+//! ```
+//!
+//! All print the same thing:
+//!
+//! ```text
+//! Hello x is 0.01000
+//! ```
+//!
+//! While these:
+//!
+//! ```
+//! println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56);
+//! println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56");
+//! ```
+//!
+//! print two significantly different things:
+//!
+//! ```text
+//! Hello, `1234.560` has 3 fractional digits
+//! Hello, `123` has 3 characters
+//! ```
 //!
 //! # Escaping
 //!
index 9a35ac1f6983ecc3480024534a85e9ec25a2e60f..0ea8975bbde1f4b81b447dd09f2454875c30395f 100644 (file)
@@ -38,6 +38,7 @@
 #![feature(unsafe_no_drop_flag, filling_drop)]
 #![feature(step_by)]
 #![feature(str_char)]
+#![feature(str_words)]
 #![feature(slice_patterns)]
 #![feature(debug_builders)]
 #![feature(utf8_error)]
index 391439bcdf2ff93beecabfcf1cc4834d79946aeb..c73a6f9b324a3698aa7b16063ee31aa4e958a702 100644 (file)
 
 use alloc::boxed::Box;
 use core::cmp::Ordering;
-use core::default::Default;
 use core::fmt;
 use core::hash::{Hasher, Hash};
-use core::iter::{self, FromIterator, IntoIterator};
+use core::iter::{self, FromIterator};
 use core::mem;
 use core::ptr;
 
@@ -296,13 +295,6 @@ pub fn iter_mut(&mut self) -> IterMut<T> {
         }
     }
 
-    /// Consumes the list into an iterator yielding elements by value.
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_iter(self) -> IntoIter<T> {
-        IntoIter{list: self}
-    }
-
     /// Returns `true` if the `LinkedList` is empty.
     ///
     /// This operation should compute in O(1) time.
@@ -852,8 +844,10 @@ impl<T> IntoIterator for LinkedList<T> {
     type Item = T;
     type IntoIter = IntoIter<T>;
 
+    /// Consumes the list into an iterator yielding elements by value.
+    #[inline]
     fn into_iter(self) -> IntoIter<T> {
-        self.into_iter()
+        IntoIter{list: self}
     }
 }
 
@@ -939,9 +933,9 @@ fn hash<H: Hasher>(&self, state: &mut H) {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use std::clone::Clone;
-    use std::iter::Iterator;
+    use std::iter::{Iterator, IntoIterator};
     use std::option::Option::{Some, None, self};
     use std::__rand::{thread_rng, Rng};
     use std::thread;
index 5be9739cb32de7ccba1e6dbcf61e4b12f0683a62..6622d8a9c40633a3b1a2bb374056d6cd0f69ec9c 100644 (file)
@@ -98,7 +98,7 @@
 use borrow::{Borrow, BorrowMut, ToOwned};
 use vec::Vec;
 
-pub use core::slice::{Chunks, AsSlice, Windows};
+pub use core::slice::{Chunks, Windows};
 pub use core::slice::{Iter, IterMut};
 pub use core::slice::{IntSliceExt, SplitMut, ChunksMut, Split};
 pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
index 0f902e258b9ca27bd46827f2a6d649604bca4847..db9f526a0f22e368459aacb92c48aba6493aa8f8 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15679
 
 //! Unicode string manipulation (the `str` type).
 //!
@@ -69,7 +67,7 @@
 use vec::Vec;
 use slice::SliceConcatExt;
 
-pub use core::str::{FromStr, Utf8Error, Str};
+pub use core::str::{FromStr, Utf8Error};
 pub use core::str::{Lines, LinesAny, CharRange};
 pub use core::str::{Split, RSplit};
 pub use core::str::{SplitN, RSplitN};
@@ -78,7 +76,7 @@
 pub use core::str::{MatchIndices, RMatchIndices};
 pub use core::str::{from_utf8, Chars, CharIndices, Bytes};
 pub use core::str::{from_utf8_unchecked, ParseBoolError};
-pub use rustc_unicode::str::{Words, Graphemes, GraphemeIndices};
+pub use rustc_unicode::str::{SplitWhitespace, Words, Graphemes, GraphemeIndices};
 pub use core::str::pattern;
 
 /*
@@ -1739,27 +1737,44 @@ pub fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices {
         UnicodeStr::grapheme_indices(&self[..], is_extended)
     }
 
-    /// An iterator over the non-empty words of `self`.
-    ///
-    /// A 'word' is a subsequence separated by any sequence of whitespace.
-    /// Sequences of whitespace
-    /// are collapsed, so empty "words" are not included.
+    /// An iterator over the non-empty substrings of `self` which contain no whitespace,
+    /// and which are separated by any amount of whitespace.
     ///
     /// # Examples
     ///
     /// ```
     /// # #![feature(str_words)]
+    /// # #![allow(deprecated)]
     /// let some_words = " Mary   had\ta little  \n\t lamb";
     /// let v: Vec<&str> = some_words.words().collect();
     ///
     /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
     /// ```
+    #[deprecated(reason = "words() will be removed. Use split_whitespace() instead",
+                 since = "1.1.0")]
     #[unstable(feature = "str_words",
                reason = "the precise algorithm to use is unclear")]
+    #[allow(deprecated)]
     pub fn words(&self) -> Words {
         UnicodeStr::words(&self[..])
     }
 
+    /// An iterator over the non-empty substrings of `self` which contain no whitespace,
+    /// and which are separated by any amount of whitespace.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let some_words = " Mary   had\ta little  \n\t lamb";
+    /// let v: Vec<&str> = some_words.split_whitespace().collect();
+    ///
+    /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
+    /// ```
+    #[stable(feature = "split_whitespace", since = "1.1.0")]
+    pub fn split_whitespace(&self) -> SplitWhitespace {
+        UnicodeStr::split_whitespace(&self[..])
+    }
+
     /// Returns a string's displayed width in columns.
     ///
     /// Control characters have zero width.
index 81710286fde21311ecc577b4e47d1a4ff6d930b7..a37a26ef22ac3af2852ebeb9c106fa799a3445cc 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15679
 
 //! An owned, growable string that enforces that its contents are valid UTF-8.
 
 
 use core::prelude::*;
 
-use core::default::Default;
 use core::fmt;
 use core::hash;
-use core::iter::{IntoIterator, FromIterator};
+use core::iter::FromIterator;
 use core::mem;
 use core::ops::{self, Deref, Add, Index};
 use core::ptr;
@@ -839,15 +836,6 @@ fn eq(&self, other: &Cow<'a, str>) -> bool { PartialEq::eq(&self[..], &other[..]
     fn ne(&self, other: &Cow<'a, str>) -> bool { PartialEq::ne(&self[..], &other[..]) }
 }
 
-#[unstable(feature = "collections", reason = "waiting on Str stabilization")]
-#[allow(deprecated)]
-impl Str for String {
-    #[inline]
-    fn as_slice(&self) -> &str {
-        unsafe { mem::transmute(&*self.vec) }
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Default for String {
     #[inline]
@@ -1069,14 +1057,6 @@ fn into_cow(self) -> Cow<'a, str> {
     }
 }
 
-#[allow(deprecated)]
-impl<'a> Str for Cow<'a, str> {
-    #[inline]
-    fn as_slice<'b>(&'b self) -> &'b str {
-        &**self
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Write for String {
     #[inline]
@@ -1084,4 +1064,10 @@ fn write_str(&mut self, s: &str) -> fmt::Result {
         self.push_str(s);
         Ok(())
     }
+
+    #[inline]
+    fn write_char(&mut self, c: char) -> fmt::Result {
+        self.push(c);
+        Ok(())
+    }
 }
index 4fa91a6a16a526ca9369b7ddfe4bc9b8b0209ddb..526150915a705a0fb0289774776e5aae88c03b42 100644 (file)
 use alloc::heap::{EMPTY, allocate, reallocate, deallocate};
 use core::cmp::max;
 use core::cmp::Ordering;
-use core::default::Default;
 use core::fmt;
 use core::hash::{self, Hash};
 use core::intrinsics::assume;
-use core::iter::{repeat, FromIterator, IntoIterator};
+use core::iter::{repeat, FromIterator};
 use core::marker::PhantomData;
 use core::mem;
 use core::ops::{Index, IndexMut, Deref, Add};
@@ -450,37 +449,6 @@ pub fn as_mut_slice(&mut self) -> &mut [T] {
         &mut self[..]
     }
 
-    /// Creates a consuming iterator, that is, one that moves each value out of
-    /// the vector (from start to end). The vector cannot be used after calling
-    /// this.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let v = vec!["a".to_string(), "b".to_string()];
-    /// for s in v.into_iter() {
-    ///     // s has type String, not &String
-    ///     println!("{}", s);
-    /// }
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_iter(self) -> IntoIter<T> {
-        unsafe {
-            let ptr = *self.ptr;
-            assume(!ptr.is_null());
-            let cap = self.cap;
-            let begin = ptr as *const T;
-            let end = if mem::size_of::<T>() == 0 {
-                (ptr as usize + self.len()) as *const T
-            } else {
-                ptr.offset(self.len() as isize) as *const T
-            };
-            mem::forget(self);
-            IntoIter { allocation: ptr, cap: cap, ptr: begin, end: end }
-        }
-    }
-
     /// Sets the length of a vector.
     ///
     /// This will explicitly set the size of the vector, without actually
@@ -1512,8 +1480,34 @@ impl<T> IntoIterator for Vec<T> {
     type Item = T;
     type IntoIter = IntoIter<T>;
 
+    /// Creates a consuming iterator, that is, one that moves each value out of
+    /// the vector (from start to end). The vector cannot be used after calling
+    /// this.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v = vec!["a".to_string(), "b".to_string()];
+    /// for s in v.into_iter() {
+    ///     // s has type String, not &String
+    ///     println!("{}", s);
+    /// }
+    /// ```
+    #[inline]
     fn into_iter(self) -> IntoIter<T> {
-        self.into_iter()
+        unsafe {
+            let ptr = *self.ptr;
+            assume(!ptr.is_null());
+            let cap = self.cap;
+            let begin = ptr as *const T;
+            let end = if mem::size_of::<T>() == 0 {
+                (ptr as usize + self.len()) as *const T
+            } else {
+                ptr.offset(self.len() as isize) as *const T
+            };
+            mem::forget(self);
+            IntoIter { allocation: ptr, cap: cap, ptr: begin, end: end }
+        }
     }
 }
 
@@ -1597,18 +1591,6 @@ fn cmp(&self, other: &Vec<T>) -> Ordering {
     }
 }
 
-#[unstable(feature = "collections",
-           reason = "will be replaced by slice syntax")]
-#[deprecated(since = "1.0.0", reason = "use &mut s[..] instead")]
-#[allow(deprecated)]
-impl<T> AsSlice<T> for Vec<T> {
-    /// Deprecated: use `&mut s[..]` instead.
-    #[inline]
-    fn as_slice(&self) -> &[T] {
-        self
-    }
-}
-
 #[unstable(feature = "collections",
            reason = "recent addition, needs more experience")]
 impl<'a, T: Clone> Add<&'a [T]> for Vec<T> {
index 858838a3a4ba5e90dc913932d0765b30ea8b139d..61369b30dea1797c25d954883c5f988fee433de7 100644 (file)
@@ -21,9 +21,8 @@
 use core::prelude::*;
 
 use core::cmp::Ordering;
-use core::default::Default;
 use core::fmt;
-use core::iter::{self, repeat, FromIterator, IntoIterator, RandomAccessIterator};
+use core::iter::{self, repeat, FromIterator, RandomAccessIterator};
 use core::mem;
 use core::ops::{Index, IndexMut};
 use core::ptr::{self, Unique};
@@ -557,14 +556,6 @@ pub fn iter_mut(&mut self) -> IterMut<T> {
         }
     }
 
-    /// Consumes the list into a front-to-back iterator yielding elements by value.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_iter(self) -> IntoIter<T> {
-        IntoIter {
-            inner: self,
-        }
-    }
-
     /// Returns a pair of slices which contain, in order, the contents of the
     /// `VecDeque`.
     #[inline]
@@ -1728,8 +1719,12 @@ impl<T> IntoIterator for VecDeque<T> {
     type Item = T;
     type IntoIter = IntoIter<T>;
 
+    /// Consumes the list into a front-to-back iterator yielding elements by
+    /// value.
     fn into_iter(self) -> IntoIter<T> {
-        self.into_iter()
+        IntoIter {
+            inner: self,
+        }
     }
 }
 
@@ -1777,7 +1772,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use core::iter::{Iterator, self};
     use core::option::Option::Some;
 
index 07d783ef46a7ba7f0770fa75cd413491eb6c0e32..d473504d5445470e676f4cce2e142f6c90215115 100644 (file)
 use core::prelude::*;
 
 use core::cmp::{max, Ordering};
-use core::default::Default;
 use core::fmt;
 use core::hash::{Hash, Hasher};
-use core::iter::{Enumerate, FilterMap, Map, FromIterator, IntoIterator};
+use core::iter::{Enumerate, FilterMap, Map, FromIterator};
 use core::iter;
 use core::mem::{replace, swap};
 use core::ops::{Index, IndexMut};
@@ -301,35 +300,6 @@ pub fn iter_mut<'r>(&'r mut self) -> IterMut<'r, V> {
         }
     }
 
-    /// Returns an iterator visiting all key-value pairs in ascending order of
-    /// the keys, consuming the original `VecMap`.
-    /// The iterator's element type is `(usize, &'r V)`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// # #![feature(collections)]
-    /// use std::collections::VecMap;
-    ///
-    /// let mut map = VecMap::new();
-    /// map.insert(1, "a");
-    /// map.insert(3, "c");
-    /// map.insert(2, "b");
-    ///
-    /// let vec: Vec<(usize, &str)> = map.into_iter().collect();
-    ///
-    /// assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_iter(self) -> IntoIter<V> {
-        fn filter<A>((i, v): (usize, Option<A>)) -> Option<(usize, A)> {
-            v.map(|v| (i, v))
-        }
-        let filter: fn((usize, Option<V>)) -> Option<(usize, V)> = filter; // coerce to fn ptr
-
-        IntoIter { iter: self.v.into_iter().enumerate().filter_map(filter) }
-    }
-
     /// Moves all elements from `other` into the map while overwriting existing keys.
     ///
     /// # Examples
@@ -800,8 +770,32 @@ impl<T> IntoIterator for VecMap<T> {
     type Item = (usize, T);
     type IntoIter = IntoIter<T>;
 
+    /// Returns an iterator visiting all key-value pairs in ascending order of
+    /// the keys, consuming the original `VecMap`.
+    /// The iterator's element type is `(usize, &'r V)`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(collections)]
+    /// use std::collections::VecMap;
+    ///
+    /// let mut map = VecMap::new();
+    /// map.insert(1, "a");
+    /// map.insert(3, "c");
+    /// map.insert(2, "b");
+    ///
+    /// let vec: Vec<(usize, &str)> = map.into_iter().collect();
+    ///
+    /// assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]);
+    /// ```
     fn into_iter(self) -> IntoIter<T> {
-        self.into_iter()
+        fn filter<A>((i, v): (usize, Option<A>)) -> Option<(usize, A)> {
+            v.map(|v| (i, v))
+        }
+        let filter: fn((usize, Option<T>)) -> Option<(usize, T)> = filter; // coerce to fn ptr
+
+        IntoIter { iter: self.v.into_iter().enumerate().filter_map(filter) }
     }
 }
 
index 549ff17e4690218fde5c3ba976a4c9fe2193d24c..5c109dc8104f21492347aa57d7a549d1a5028a10 100644 (file)
@@ -14,7 +14,6 @@
 #![feature(hash)]
 #![feature(rand)]
 #![feature(rustc_private)]
-#![feature(str_words)]
 #![feature(test)]
 #![feature(unboxed_closures)]
 #![feature(unicode)]
index e23a8a34b09ce2aadb9cbadf9f02edb27d004a1e..170f49ab15be553d5177122d4033da1e65bbaf85 100644 (file)
@@ -939,9 +939,9 @@ fn test_rsplitn() {
 }
 
 #[test]
-fn test_words() {
+fn test_split_whitespace() {
     let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
-    let words: Vec<&str> = data.words().collect();
+    let words: Vec<&str> = data.split_whitespace().collect();
     assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
 }
 
index efe1179621de5efde5843896c2aabea9faba2e99..dd59ceff577a8c427fc8565761cfdc9697c85157 100644 (file)
 //! 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:
-//!
-//! ```
-//! # #![feature(core)]
-//! struct FuzzyNum {
-//!     num: i32,
-//! }
-//!
-//! impl PartialEq for FuzzyNum {
-//!     // Our custom eq allows numbers which are near each other to be equal! :D
-//!     fn eq(&self, other: &FuzzyNum) -> bool {
-//!         (self.num - other.num).abs() < 5
-//!     }
-//! }
-//!
-//! // Now these binary operators will work when applied!
-//! assert!(FuzzyNum { num: 37 } == FuzzyNum { num: 34 });
-//! assert!(FuzzyNum { num: 25 } != FuzzyNum { num: 57 });
-//! ```
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
index 1c1ad5fd33fb8bdfbaf142e4244853db5b469170..d9cda58d9ebedd6e364bffe388e4c5979b43c8d6 100644 (file)
@@ -11,7 +11,7 @@
 //! Traits for conversions between types.
 //!
 //! The traits in this module provide a general way to talk about conversions from one type to
-//! another. They follow the standard Rust conventions of `as`/`to`/`into`/`from`.
+//! another. They follow the standard Rust conventions of `as`/`into`/`from`.
 //!
 //! Like many traits, these are often used as bounds for generic functions, to support arguments of
 //! multiple types.
index 910cf805f39985b9bc809a7ad0b2dcdb186bf753..f5103d394eef07cdaa04e9dc6ad67a2cec87ce7f 100644 (file)
@@ -24,8 +24,6 @@
 //! How can we define some default values? You can use `Default`:
 //!
 //! ```
-//! use std::default::Default;
-//!
 //! #[derive(Default)]
 //! struct SomeOptions {
 //!     foo: i32,
@@ -42,8 +40,6 @@
 //! If you have your own type, you need to implement `Default` yourself:
 //!
 //! ```
-//! use std::default::Default;
-//!
 //! enum Kind {
 //!     A,
 //!     B,
@@ -70,7 +66,6 @@
 //! If you want to override a particular option, but still retain the other defaults:
 //!
 //! ```
-//! # use std::default::Default;
 //! # #[derive(Default)]
 //! # struct SomeOptions {
 //! #     foo: i32,
@@ -109,8 +104,6 @@ pub trait Default {
     /// Using built-in default values:
     ///
     /// ```
-    /// use std::default::Default;
-    ///
     /// let i: i8 = Default::default();
     /// let (x, y): (Option<String>, f64) = Default::default();
     /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default();
@@ -119,8 +112,6 @@ pub trait Default {
     /// Making your own:
     ///
     /// ```
-    /// use std::default::Default;
-    ///
     /// enum Kind {
     ///     A,
     ///     B,
index 72c25c68040222ffd48913bf88c41b5b23b18332..4b75bd5f67e3d94fd7d07b23a19c4567e0ade186 100644 (file)
 pub use self::ExponentFormat::*;
 pub use self::SignificantDigits::*;
 
-use char::{self, CharExt};
+use prelude::*;
+
+use char;
 use fmt;
-use iter::Iterator;
-use num::{cast, Float, ToPrimitive};
+use num::Float;
 use num::FpCategory as Fp;
-use ops::FnOnce;
-use result::Result::Ok;
-use slice::{self, SliceExt};
-use str::{self, StrExt};
+use ops::{Div, Rem, Mul};
+use slice;
+use str;
 
 /// A flag that specifies whether to use exponential (scientific) notation.
 pub enum ExponentFormat {
@@ -42,6 +42,21 @@ pub enum SignificantDigits {
     DigExact(usize)
 }
 
+#[doc(hidden)]
+pub trait MyFloat: Float + PartialEq + PartialOrd + Div<Output=Self> +
+                   Mul<Output=Self> + Rem<Output=Self> + Copy {
+    fn from_u32(u: u32) -> Self;
+    fn to_i32(&self) -> i32;
+}
+
+macro_rules! doit {
+    ($($t:ident)*) => ($(impl MyFloat for $t {
+        fn from_u32(u: u32) -> $t { u as $t }
+        fn to_i32(&self) -> i32 { *self as i32 }
+    })*)
+}
+doit! { f32 f64 }
+
 /// Converts a float number to its string representation.
 /// This is meant to be a common base implementation for various formatting styles.
 /// The number is assumed to be non-negative, callers use `Formatter::pad_integral`
@@ -63,7 +78,7 @@ pub enum SignificantDigits {
 /// # Panics
 ///
 /// - Panics if `num` is negative.
-pub fn float_to_str_bytes_common<T: Float, U, F>(
+pub fn float_to_str_bytes_common<T: MyFloat, U, F>(
     num: T,
     digits: SignificantDigits,
     exp_format: ExponentFormat,
@@ -72,10 +87,10 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
 ) -> U where
     F: FnOnce(&str) -> U,
 {
-    let _0: T = Float::zero();
-    let _1: T = Float::one();
+    let _0: T = T::zero();
+    let _1: T = T::one();
     let radix: u32 = 10;
-    let radix_f: T = cast(radix).unwrap();
+    let radix_f = T::from_u32(radix);
 
     assert!(num.is_nan() || num >= _0, "float_to_str_bytes_common: number is negative");
 
@@ -99,7 +114,7 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
     let (num, exp) = match exp_format {
         ExpDec if num != _0 => {
             let exp = num.log10().floor();
-            (num / radix_f.powf(exp), cast::<T, i32>(exp).unwrap())
+            (num / radix_f.powf(exp), exp.to_i32())
         }
         _ => (num, 0)
     };
@@ -114,7 +129,7 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
         deccum = deccum / radix_f;
         deccum = deccum.trunc();
 
-        let c = char::from_digit(current_digit.to_isize().unwrap() as u32, radix);
+        let c = char::from_digit(current_digit.to_i32() as u32, radix);
         buf[end] = c.unwrap() as u8;
         end += 1;
 
@@ -158,7 +173,7 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
 
             let current_digit = deccum.trunc();
 
-            let c = char::from_digit(current_digit.to_isize().unwrap() as u32, radix);
+            let c = char::from_digit(current_digit.to_i32() as u32, radix);
             buf[end] = c.unwrap() as u8;
             end += 1;
 
index 80c661b260cbe219a6d9c4ed01130a246cc766d6..0178b321e88c35a68be363b49bf4a91eb4b097c4 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use prelude::*;
+
 use cell::{Cell, RefCell, Ref, RefMut, BorrowState};
-use char::CharExt;
-use clone::Clone;
-use iter::Iterator;
-use marker::{Copy, PhantomData, Sized};
+use marker::PhantomData;
 use mem;
-use num::Float;
-use option::Option;
-use option::Option::{Some, None};
-use result::Result::Ok;
-use ops::{Deref, FnOnce};
+use ops::Deref;
 use result;
-use slice::SliceExt;
+use num::Float;
 use slice;
-use str::{self, StrExt};
+use str;
 use self::rt::v1::Alignment;
 
 pub use self::num::radix;
@@ -83,6 +78,23 @@ pub trait Write {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn write_str(&mut self, s: &str) -> Result;
 
+    /// Writes a `char` into this writer, returning whether the write succeeded.
+    ///
+    /// A single `char` may be encoded as more than one byte.
+    /// This method can only succeed if the entire byte sequence was successfully
+    /// written, and this method will not return until all data has been
+    /// written or an error occurs.
+    ///
+    /// # Errors
+    ///
+    /// This function will return an instance of `FormatError` on error.
+    #[stable(feature = "fmt_write_char", since = "1.1.0")]
+    fn write_char(&mut self, c: char) -> Result {
+        let mut utf_8 = [0u8; 4];
+        let bytes_written = c.encode_utf8(&mut utf_8).unwrap_or(0);
+        self.write_str(unsafe { mem::transmute(&utf_8[..bytes_written]) })
+    }
+
     /// Glue for usage of the `write!` macro with implementers of this trait.
     ///
     /// This method should generally not be invoked manually, but rather through
@@ -912,7 +924,8 @@ fn fmt(&self, f: &mut Formatter) -> Result {
 }
 
 // Common code of floating point Debug and Display.
-fn float_to_str_common<T: Float, F>(num: &T, precision: Option<usize>, post: F) -> Result
+fn float_to_str_common<T: float::MyFloat, F>(num: &T, precision: Option<usize>,
+                                             post: F) -> Result
         where F : FnOnce(&str) -> Result {
     let digits = match precision {
         Some(i) => float::DigExact(i),
@@ -950,8 +963,6 @@ fn fmt(&self, fmt: &mut Formatter) -> Result {
     #[stable(feature = "rust1", since = "1.0.0")]
     impl LowerExp for $ty {
         fn fmt(&self, fmt: &mut Formatter) -> Result {
-            use num::Float;
-
             let digits = match fmt.precision {
                 Some(i) => float::DigExact(i),
                 None => float::DigMax(6),
@@ -969,8 +980,6 @@ fn fmt(&self, fmt: &mut Formatter) -> Result {
     #[stable(feature = "rust1", since = "1.0.0")]
     impl UpperExp for $ty {
         fn fmt(&self, fmt: &mut Formatter) -> Result {
-            use num::Float;
-
             let digits = match fmt.precision {
                 Some(i) => float::DigExact(i),
                 None => float::DigMax(6),
index 76c975902aabb0df47a9b16b0611517b3e6b9b78..122fffc5959056a99c3edbe3d97155ec878c0d66 100644 (file)
 
 #![allow(unsigned_negation)]
 
+use prelude::*;
+
 use fmt;
-use iter::Iterator;
-use num::{Int, cast};
-use slice::SliceExt;
+use num::Zero;
+use ops::{Div, Rem, Sub};
 use str;
 
+#[doc(hidden)]
+trait Int: Zero + PartialEq + PartialOrd + Div<Output=Self> + Rem<Output=Self> +
+           Sub<Output=Self> + Copy {
+    fn from_u8(u: u8) -> Self;
+    fn to_u8(&self) -> u8;
+}
+
+macro_rules! doit {
+    ($($t:ident)*) => ($(impl Int for $t {
+        fn from_u8(u: u8) -> $t { u as $t }
+        fn to_u8(&self) -> u8 { *self as u8 }
+    })*)
+}
+doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
+
 /// A type that represents a specific radix
 #[doc(hidden)]
 trait GenericRadix {
@@ -33,33 +49,32 @@ fn prefix(&self) -> &'static str { "" }
     fn digit(&self, x: u8) -> u8;
 
     /// Format an integer using the radix using a formatter.
-    #[allow(deprecated)] // Int
     fn fmt_int<T: Int>(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result {
         // The radix can be as low as 2, so we need a buffer of at least 64
         // characters for a base 2 number.
-        let zero = Int::zero();
+        let zero = T::zero();
         let is_positive = x >= zero;
         let mut buf = [0; 64];
         let mut curr = buf.len();
-        let base = cast(self.base()).unwrap();
+        let base = T::from_u8(self.base());
         if is_positive {
             // Accumulate each digit of the number from the least significant
             // to the most significant figure.
             for byte in buf.iter_mut().rev() {
-                let n = x % base;                         // Get the current place value.
-                x = x / base;                             // Deaccumulate the number.
-                *byte = self.digit(cast(n).unwrap());     // Store the digit in the buffer.
+                let n = x % base;              // Get the current place value.
+                x = x / base;                  // Deaccumulate the number.
+                *byte = self.digit(n.to_u8()); // Store the digit in the buffer.
                 curr -= 1;
-                if x == zero { break };                   // No more digits left to accumulate.
+                if x == zero { break };        // No more digits left to accumulate.
             }
         } else {
             // Do the same as above, but accounting for two's complement.
             for byte in buf.iter_mut().rev() {
-                let n = zero - (x % base);                // Get the current place value.
-                x = x / base;                             // Deaccumulate the number.
-                *byte = self.digit(cast(n).unwrap());     // Store the digit in the buffer.
+                let n = zero - (x % base);     // Get the current place value.
+                x = x / base;                  // Deaccumulate the number.
+                *byte = self.digit(n.to_u8()); // Store the digit in the buffer.
                 curr -= 1;
-                if x == zero { break };                   // No more digits left to accumulate.
+                if x == zero { break };        // No more digits left to accumulate.
             }
         }
         let buf = unsafe { str::from_utf8_unchecked(&buf[curr..]) };
index 553e0c0dfe6e45c3cf792d70cd0768a80c0a8990..e848a44e01ce0ef267e6f1d7df00c0e7df5c90ab 100644 (file)
@@ -62,7 +62,6 @@
 
 use prelude::*;
 
-use default::Default;
 use mem;
 
 pub use self::sip::SipHasher;
index 6820a7025fca6f171cda155752bf60d6e258bf2d..be419e2cdadb0ed9c33a86eb708c6d513063f029 100644 (file)
@@ -7,15 +7,12 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15883
 
 //! An implementation of SipHash 2-4.
 
 #![allow(deprecated)] // until the next snapshot for inherent wrapping ops
 
 use prelude::*;
-use default::Default;
 use super::Hasher;
 
 /// An implementation of SipHash 2-4.
index 24ef8a6e01ac2b7903869c8890cebb9db22848a5..233ed018119302deceb23bedcdac7e0175a9b0e0 100644 (file)
@@ -64,7 +64,7 @@
 use default::Default;
 use marker;
 use mem;
-use num::{Int, Zero, One};
+use num::{Zero, One};
 use ops::{self, Add, Sub, FnMut, Mul, RangeFrom};
 use option::Option::{self, Some, None};
 use marker::Sized;
@@ -2327,9 +2327,8 @@ fn idx(&mut self, index: usize) -> Option<I::Item> {
 /// An iterator that yields sequential Fibonacci numbers, and stops on overflow.
 ///
 /// ```
-/// # #![feature(core)]
+/// #![feature(core)]
 /// use std::iter::Unfold;
-/// use std::num::Int; // For `.checked_add()`
 ///
 /// // This iterator will yield up to the last Fibonacci number before the max
 /// // value of `u32`. You can simply change `u32` to `u64` in this line if
@@ -2647,80 +2646,6 @@ fn next(&mut self) -> Option<A> {
     }
 }
 
-/// An iterator over the range [start, stop] by `step`. It handles overflow by stopping.
-#[derive(Clone)]
-#[unstable(feature = "core",
-           reason = "likely to be replaced by range notation and adapters")]
-pub struct RangeStepInclusive<A> {
-    state: A,
-    stop: A,
-    step: A,
-    rev: bool,
-    done: bool,
-}
-
-/// Returns an iterator over the range [start, stop] by `step`.
-///
-/// It handles overflow by stopping.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(core)]
-/// use std::iter::range_step_inclusive;
-///
-/// for i in range_step_inclusive(0, 10, 2) {
-///     println!("{}", i);
-/// }
-/// ```
-///
-/// This prints:
-///
-/// ```text
-/// 0
-/// 2
-/// 4
-/// 6
-/// 8
-/// 10
-/// ```
-#[inline]
-#[unstable(feature = "core",
-           reason = "likely to be replaced by range notation and adapters")]
-#[allow(deprecated)]
-pub fn range_step_inclusive<A: Int>(start: A, stop: A, step: A) -> RangeStepInclusive<A> {
-    let rev = step < Int::zero();
-    RangeStepInclusive {
-        state: start,
-        stop: stop,
-        step: step,
-        rev: rev,
-        done: false,
-    }
-}
-
-#[unstable(feature = "core",
-           reason = "likely to be replaced by range notation and adapters")]
-#[allow(deprecated)]
-impl<A: Int> Iterator for RangeStepInclusive<A> {
-    type Item = A;
-
-    #[inline]
-    fn next(&mut self) -> Option<A> {
-        if !self.done && ((self.rev && self.state >= self.stop) ||
-                          (!self.rev && self.state <= self.stop)) {
-            let result = self.state;
-            match self.state.checked_add(self.step) {
-                Some(x) => self.state = x,
-                None => self.done = true
-            }
-            Some(result)
-        } else {
-            None
-        }
-    }
-}
-
 macro_rules! range_exact_iter_impl {
     ($($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
index 164d3e49385e7934a4c3894147afde56d3e06e00..249f0a0c389a3deda580019f845e047ed3aed18d 100644 (file)
 #[path = "num/f32.rs"]   pub mod f32;
 #[path = "num/f64.rs"]   pub mod f64;
 
+#[macro_use]
 pub mod num;
 
 /* The libcore prelude, not as all-encompassing as the libstd prelude */
index d6a7126a883f7fe738dd5fd1124bc7e6f859fce8..fdabdbc5ed4ce0c59c8d2853e662084247d7544c 100644 (file)
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang="send"]
 #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
-#[allow(deprecated)]
+#[cfg(not(stage0))]
+pub unsafe trait Send {
+    // empty.
+}
+
+/// Types able to be transferred across thread boundaries.
+#[stable(feature = "rust1", since = "1.0.0")]
+#[lang="send"]
+#[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
+#[cfg(stage0)]
 pub unsafe trait Send : MarkerTrait {
     // empty.
 }
@@ -51,7 +60,17 @@ impl !Send for Managed { }
 #[lang="sized"]
 #[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"]
 #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
-#[allow(deprecated)]
+#[cfg(not(stage0))]
+pub trait Sized {
+    // Empty.
+}
+
+/// Types with a constant size known at compile-time.
+#[stable(feature = "rust1", since = "1.0.0")]
+#[lang="sized"]
+#[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"]
+#[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+#[cfg(stage0)]
 pub trait Sized : MarkerTrait {
     // Empty.
 }
@@ -199,13 +218,23 @@ pub trait Copy : Clone {
 /// the `sync` crate do ensure that any mutation cannot cause data
 /// races.  Hence these types are `Sync`.
 ///
-/// Any types with interior mutability must also use the `std::cell::UnsafeCell` wrapper around the
-/// value(s) which can be mutated when behind a `&` reference; not doing this is undefined
-/// behaviour (for example, `transmute`-ing from `&T` to `&mut T` is illegal).
+/// Any types with interior mutability must also use the `std::cell::UnsafeCell`
+/// wrapper around the value(s) which can be mutated when behind a `&`
+/// reference; not doing this is undefined behaviour (for example,
+/// `transmute`-ing from `&T` to `&mut T` is illegal).
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[lang="sync"]
+#[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
+pub unsafe trait Sync {
+    // Empty
+}
+
+/// dox
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang="sync"]
 #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
-#[allow(deprecated)]
 pub unsafe trait Sync : MarkerTrait {
     // Empty
 }
@@ -272,42 +301,20 @@ fn clone(&self) -> $t<T> {
         )
 }
 
-/// `MarkerTrait` is deprecated and no longer needed.
+/// dox
 #[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "No longer needed")]
-#[allow(deprecated)]
 #[cfg(stage0)]
 pub trait MarkerTrait : PhantomFn<Self,Self> { }
 
-/// `MarkerTrait` is deprecated and no longer needed.
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "No longer needed")]
-#[allow(deprecated)]
-#[cfg(not(stage0))]
-pub trait MarkerTrait { }
-
-#[allow(deprecated)]
-impl<T:?Sized> MarkerTrait for T { }
+#[cfg(stage0)]
+impl<T: ?Sized> MarkerTrait for T {}
 
-/// `PhantomFn` is a deprecated marker trait that is no longer needed.
+/// dox
 #[lang="phantom_fn"]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "No longer needed")]
 #[cfg(stage0)]
 pub trait PhantomFn<A:?Sized,R:?Sized=()> {
 }
 
-/// `PhantomFn` is a deprecated marker trait that is no longer needed.
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "No longer needed")]
-#[cfg(not(stage0))]
-pub trait PhantomFn<A:?Sized,R:?Sized=()> {
-}
-
-#[allow(deprecated)]
-#[cfg(not(stage0))]
-impl<A:?Sized,R:?Sized,T:?Sized> PhantomFn<A,R> for T { }
-
 /// `PhantomData<T>` allows you to describe that a type acts as if it stores a value of type `T`,
 /// even though it does not. This allows you to inform the compiler about certain safety properties
 /// of your code.
@@ -454,8 +461,14 @@ unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {}
 #[rustc_reflect_like]
 #[unstable(feature = "core", reason = "requires RFC and more experience")]
 #[allow(deprecated)]
-pub trait Reflect : MarkerTrait {
-}
+#[cfg(not(stage0))]
+pub trait Reflect {}
+
+/// dox
+#[rustc_reflect_like]
+#[unstable(feature = "core", reason = "requires RFC and more experience")]
+#[cfg(stage0)]
+pub trait Reflect: MarkerTrait {}
 
 impl Reflect for .. { }
 
index db2d1b2f1fdaa7a686221fe803595a32d4812871..9ea44c39fe9c6382c6a27b441df0f0a028d62a36 100644 (file)
 
 //! Exposes the NonZero lang item which provides optimization hints.
 
-use marker::{Sized, MarkerTrait};
+use marker::Sized;
 use ops::Deref;
+#[cfg(stage0)] use marker::MarkerTrait;
 
 /// Unsafe trait to indicate what types are usable with the NonZero struct
-#[allow(deprecated)]
-pub unsafe trait Zeroable : MarkerTrait {}
+#[cfg(not(stage0))]
+pub unsafe trait Zeroable {}
+
+/// Unsafe trait to indicate what types are usable with the NonZero struct
+#[cfg(stage0)]
+pub unsafe trait Zeroable: MarkerTrait {}
 
 unsafe impl<T:?Sized> Zeroable for *const T {}
 unsafe impl<T:?Sized> Zeroable for *mut T {}
index 12b45a766b63929da94dc01ff5d7d6761451407c..50dd3f1661adf6c0fa632841668af366e683c104 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use prelude::*;
+
 use intrinsics;
 use mem;
-use num::Float;
+use num::{Float, ParseFloatError};
 use num::FpCategory as Fp;
-use option::Option;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const RADIX: u32 = 2;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const EPSILON: f32 = 1.19209290e-07_f32;
 
-/// Smallest finite f32 value
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "use `std::f32::MIN`")]
-pub const MIN_VALUE: f32 = -3.40282347e+38_f32;
-/// Smallest positive, normalized f32 value
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "use `std::f32::MIN_POSITIVE`")]
-pub const MIN_POS_VALUE: f32 = 1.17549435e-38_f32;
-/// Largest finite f32 value
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "use `std::f32::MAX`")]
-pub const MAX_VALUE: f32 = 3.40282347e+38_f32;
-
 /// Smallest finite f32 value
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const MIN: f32 = -3.40282347e+38_f32;
@@ -118,26 +106,14 @@ pub mod consts {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_2_SQRT_PI: f32 = 1.12837916709551257389615890312154517_f32;
 
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[deprecated(since = "1.0.0", reason = "renamed to FRAC_2_SQRT_PI")]
-    pub const FRAC_2_SQRTPI: f32 = 1.12837916709551257389615890312154517_f32;
-
     /// sqrt(2.0)
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const SQRT_2: f32 = 1.41421356237309504880168872420969808_f32;
 
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[deprecated(since = "1.0.0", reason = "renamed to SQRT_2")]
-    pub const SQRT2: f32 = 1.41421356237309504880168872420969808_f32;
-
     /// 1.0/sqrt(2.0)
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_1_SQRT_2: f32 = 0.707106781186547524400844362104849039_f32;
 
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[deprecated(since = "1.0.0", reason = "renamed to FRAC_1_SQRT_2")]
-    pub const FRAC_1_SQRT2: f32 = 0.707106781186547524400844362104849039_f32;
-
     /// Euler's number
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const E: f32 = 2.71828182845904523536028747135266250_f32;
@@ -179,6 +155,8 @@ fn neg_zero() -> f32 { -0.0 }
     #[inline]
     fn one() -> f32 { 1.0 }
 
+    from_str_radix_float_impl! { f32 }
+
     /// Returns `true` if the number is NaN.
     #[inline]
     fn is_nan(self) -> bool { self != self }
@@ -218,56 +196,6 @@ fn classify(self) -> Fp {
         }
     }
 
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn mantissa_digits(_: Option<f32>) -> usize { MANTISSA_DIGITS as usize }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn digits(_: Option<f32>) -> usize { DIGITS as usize }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn epsilon() -> f32 { EPSILON }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn min_exp(_: Option<f32>) -> isize { MIN_EXP as isize }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn max_exp(_: Option<f32>) -> isize { MAX_EXP as isize }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn min_10_exp(_: Option<f32>) -> isize { MIN_10_EXP as isize }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn max_10_exp(_: Option<f32>) -> isize { MAX_10_EXP as isize }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn min_value() -> f32 { MIN }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn min_pos_value(_: Option<f32>) -> f32 { MIN_POSITIVE }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn max_value() -> f32 { MAX }
-
     /// Returns the mantissa, exponent and sign as integers.
     fn integer_decode(self) -> (u64, i16, i8) {
         let bits: u32 = unsafe { mem::transmute(self) };
@@ -310,9 +238,6 @@ fn trunc(self) -> f32 {
     /// The fractional part of the number, satisfying:
     ///
     /// ```
-    /// # #![feature(core)]
-    /// use std::num::Float;
-    ///
     /// let x = 1.65f32;
     /// assert!(x == x.trunc() + x.fract())
     /// ```
index 058acedd9c98889096926ecc1d1873e611ec6cde..62b566e7eb40cb65f8b45d704e0f8c2fa83d22f7 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use prelude::*;
+
 use intrinsics;
 use mem;
-use num::Float;
 use num::FpCategory as Fp;
-use option::Option;
+use num::{Float, ParseFloatError};
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const RADIX: u32 = 2;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const EPSILON: f64 = 2.2204460492503131e-16_f64;
 
-/// Smallest finite f64 value
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "use `std::f64::MIN`")]
-pub const MIN_VALUE: f64 = -1.7976931348623157e+308_f64;
-/// Smallest positive, normalized f64 value
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "use `std::f64::MIN_POSITIVE`")]
-pub const MIN_POS_VALUE: f64 = 2.2250738585072014e-308_f64;
-/// Largest finite f64 value
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "use `std::f64::MAX`")]
-pub const MAX_VALUE: f64 = 1.7976931348623157e+308_f64;
-
 /// Smallest finite f64 value
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const MIN: f64 = -1.7976931348623157e+308_f64;
@@ -118,26 +106,14 @@ pub mod consts {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_2_SQRT_PI: f64 = 1.12837916709551257389615890312154517_f64;
 
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[deprecated(since = "1.0.0", reason = "renamed to FRAC_2_SQRT_PI")]
-    pub const FRAC_2_SQRTPI: f64 = 1.12837916709551257389615890312154517_f64;
-
     /// sqrt(2.0)
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const SQRT_2: f64 = 1.41421356237309504880168872420969808_f64;
 
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[deprecated(since = "1.0.0", reason = "renamed to SQRT_2")]
-    pub const SQRT2: f64 = 1.41421356237309504880168872420969808_f64;
-
     /// 1.0/sqrt(2.0)
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_1_SQRT_2: f64 = 0.707106781186547524400844362104849039_f64;
 
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[deprecated(since = "1.0.0", reason = "renamed to FRAC_1_SQRT_2")]
-    pub const FRAC_1_SQRT2: f64 = 0.707106781186547524400844362104849039_f64;
-
     /// Euler's number
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const E: f64 = 2.71828182845904523536028747135266250_f64;
@@ -179,6 +155,8 @@ fn neg_zero() -> f64 { -0.0 }
     #[inline]
     fn one() -> f64 { 1.0 }
 
+    from_str_radix_float_impl! { f64 }
+
     /// Returns `true` if the number is NaN.
     #[inline]
     fn is_nan(self) -> bool { self != self }
@@ -218,56 +196,6 @@ fn classify(self) -> Fp {
         }
     }
 
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn mantissa_digits(_: Option<f64>) -> usize { MANTISSA_DIGITS as usize }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn digits(_: Option<f64>) -> usize { DIGITS as usize }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn epsilon() -> f64 { EPSILON }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn min_exp(_: Option<f64>) -> isize { MIN_EXP as isize }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn max_exp(_: Option<f64>) -> isize { MAX_EXP as isize }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn min_10_exp(_: Option<f64>) -> isize { MIN_10_EXP as isize }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn max_10_exp(_: Option<f64>) -> isize { MAX_10_EXP as isize }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn min_value() -> f64 { MIN }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn min_pos_value(_: Option<f64>) -> f64 { MIN_POSITIVE }
-
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0")]
-    fn max_value() -> f64 { MAX }
-
     /// Returns the mantissa, exponent and sign as integers.
     fn integer_decode(self) -> (u64, i16, i8) {
         let bits: u64 = unsafe { mem::transmute(self) };
@@ -310,9 +238,6 @@ fn trunc(self) -> f64 {
     /// The fractional part of the number, satisfying:
     ///
     /// ```
-    /// # #![feature(core)]
-    /// use std::num::Float;
-    ///
     /// let x = 1.65f64;
     /// assert!(x == x.trunc() + x.fract())
     /// ```
index b3adef53dabeebc8a7a03ed478fb691dd7ed28d6..5ee0dc19f9bf684ca855056f2a8551e63a6ffc2c 100644 (file)
@@ -18,3 +18,145 @@ macro_rules! assert_approx_eq {
                 "{} is not approximately equal to {}", *a, *b);
     })
 }
+
+macro_rules! from_str_radix_float_impl {
+    ($T:ty) => {
+        fn from_str_radix(src: &str, radix: u32)
+                          -> Result<$T, ParseFloatError> {
+            use num::FloatErrorKind::*;
+            use num::ParseFloatError as PFE;
+
+            // Special values
+            match src {
+                "inf"   => return Ok(Float::infinity()),
+                "-inf"  => return Ok(Float::neg_infinity()),
+                "NaN"   => return Ok(Float::nan()),
+                _       => {},
+            }
+
+            let (is_positive, src) =  match src.slice_shift_char() {
+                None             => return Err(PFE { kind: Empty }),
+                Some(('-', ""))  => return Err(PFE { kind: Empty }),
+                Some(('-', src)) => (false, src),
+                Some((_, _))     => (true,  src),
+            };
+
+            // The significand to accumulate
+            let mut sig = if is_positive { 0.0 } else { -0.0 };
+            // Necessary to detect overflow
+            let mut prev_sig = sig;
+            let mut cs = src.chars().enumerate();
+            // Exponent prefix and exponent index offset
+            let mut exp_info = None::<(char, usize)>;
+
+            // Parse the integer part of the significand
+            for (i, c) in cs.by_ref() {
+                match c.to_digit(radix) {
+                    Some(digit) => {
+                        // shift significand one digit left
+                        sig = sig * (radix as $T);
+
+                        // add/subtract current digit depending on sign
+                        if is_positive {
+                            sig = sig + ((digit as isize) as $T);
+                        } else {
+                            sig = sig - ((digit as isize) as $T);
+                        }
+
+                        // Detect overflow by comparing to last value, except
+                        // if we've not seen any non-zero digits.
+                        if prev_sig != 0.0 {
+                            if is_positive && sig <= prev_sig
+                                { return Ok(Float::infinity()); }
+                            if !is_positive && sig >= prev_sig
+                                { return Ok(Float::neg_infinity()); }
+
+                            // Detect overflow by reversing the shift-and-add process
+                            if is_positive && (prev_sig != (sig - digit as $T) / radix as $T)
+                                { return Ok(Float::infinity()); }
+                            if !is_positive && (prev_sig != (sig + digit as $T) / radix as $T)
+                                { return Ok(Float::neg_infinity()); }
+                        }
+                        prev_sig = sig;
+                    },
+                    None => match c {
+                        'e' | 'E' | 'p' | 'P' => {
+                            exp_info = Some((c, i + 1));
+                            break;  // start of exponent
+                        },
+                        '.' => {
+                            break;  // start of fractional part
+                        },
+                        _ => {
+                            return Err(PFE { kind: Invalid });
+                        },
+                    },
+                }
+            }
+
+            // If we are not yet at the exponent parse the fractional
+            // part of the significand
+            if exp_info.is_none() {
+                let mut power = 1.0;
+                for (i, c) in cs.by_ref() {
+                    match c.to_digit(radix) {
+                        Some(digit) => {
+                            // Decrease power one order of magnitude
+                            power = power / (radix as $T);
+                            // add/subtract current digit depending on sign
+                            sig = if is_positive {
+                                sig + (digit as $T) * power
+                            } else {
+                                sig - (digit as $T) * power
+                            };
+                            // Detect overflow by comparing to last value
+                            if is_positive && sig < prev_sig
+                                { return Ok(Float::infinity()); }
+                            if !is_positive && sig > prev_sig
+                                { return Ok(Float::neg_infinity()); }
+                            prev_sig = sig;
+                        },
+                        None => match c {
+                            'e' | 'E' | 'p' | 'P' => {
+                                exp_info = Some((c, i + 1));
+                                break; // start of exponent
+                            },
+                            _ => {
+                                return Err(PFE { kind: Invalid });
+                            },
+                        },
+                    }
+                }
+            }
+
+            // Parse and calculate the exponent
+            let exp = match exp_info {
+                Some((c, offset)) => {
+                    let base = match c {
+                        'E' | 'e' if radix == 10 => 10.0,
+                        'P' | 'p' if radix == 16 => 2.0,
+                        _ => return Err(PFE { kind: Invalid }),
+                    };
+
+                    // Parse the exponent as decimal integer
+                    let src = &src[offset..];
+                    let (is_positive, exp) = match src.slice_shift_char() {
+                        Some(('-', src)) => (false, src.parse::<usize>()),
+                        Some(('+', src)) => (true,  src.parse::<usize>()),
+                        Some((_, _))     => (true,  src.parse::<usize>()),
+                        None             => return Err(PFE { kind: Invalid }),
+                    };
+
+                    match (is_positive, exp) {
+                        (true,  Ok(exp)) => base.powi(exp as i32),
+                        (false, Ok(exp)) => 1.0 / base.powi(exp as i32),
+                        (_, Err(_))      => return Err(PFE { kind: Invalid }),
+                    }
+                },
+                None => 1.0, // no exponent
+            };
+
+            Ok(sig * exp)
+        }
+    }
+}
index a056e585fee65644beeba413ba9a5accaebb9023..44d5333ce1f46bb582a11b97e2fe08718c52029e 100644 (file)
@@ -7,26 +7,20 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15679
 
 //! Numeric traits and functions for the built-in numeric types.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
 
-use self::wrapping::{OverflowingOps, WrappingOps};
+use self::wrapping::OverflowingOps;
 
 use char::CharExt;
-use clone::Clone;
-use cmp::{PartialEq, Eq, PartialOrd, Ord};
+use cmp::{Eq, PartialOrd};
 use fmt;
 use intrinsics;
-use iter::Iterator;
 use marker::Copy;
 use mem::size_of;
-use ops::{Add, Sub, Mul, Div, Rem, Neg};
-use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
 use option::Option::{self, Some, None};
 use result::Result::{self, Ok, Err};
 use str::{FromStr, StrExt};
@@ -100,407 +94,6 @@ fn one() -> $t { 1.0 }
 }
 zero_one_impl_float! { f32 f64 }
 
-/// A built-in signed or unsigned integer.
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0",
-             reason = "replaced by inherent methods; for generics, use rust-lang/num")]
-#[allow(deprecated)]
-pub trait Int
-    : Copy + Clone
-    + NumCast
-    + PartialOrd + Ord
-    + PartialEq + Eq
-    + Add<Output=Self>
-    + Sub<Output=Self>
-    + Mul<Output=Self>
-    + Div<Output=Self>
-    + Rem<Output=Self>
-    + Not<Output=Self>
-    + BitAnd<Output=Self>
-    + BitOr<Output=Self>
-    + BitXor<Output=Self>
-    + Shl<usize, Output=Self>
-    + Shr<usize, Output=Self>
-    + WrappingOps
-    + OverflowingOps
-{
-    /// Returns the `0` value of this integer type.
-    // FIXME (#5527): Should be an associated constant
-    #[unstable(feature = "core",
-               reason = "unsure about its place in the world")]
-    fn zero() -> Self;
-
-    /// Returns the `1` value of this integer type.
-    // FIXME (#5527): Should be an associated constant
-    #[unstable(feature = "core",
-               reason = "unsure about its place in the world")]
-    fn one() -> Self;
-
-    /// Returns the smallest value that can be represented by this integer type.
-    // FIXME (#5527): Should be and associated constant
-    #[unstable(feature = "core",
-               reason = "unsure about its place in the world")]
-    fn min_value() -> Self;
-
-    /// Returns the largest value that can be represented by this integer type.
-    // FIXME (#5527): Should be and associated constant
-    #[unstable(feature = "core",
-               reason = "unsure about its place in the world")]
-    fn max_value() -> Self;
-
-    /// Returns the number of ones in the binary representation of `self`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// # #![feature(core)]
-    /// use std::num::Int;
-    ///
-    /// let n = 0b01001100u8;
-    ///
-    /// assert_eq!(n.count_ones(), 3);
-    /// ```
-    #[unstable(feature = "core",
-               reason = "pending integer conventions")]
-    fn count_ones(self) -> u32;
-
-    /// Returns the number of zeros in the binary representation of `self`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// # #![feature(core)]
-    /// use std::num::Int;
-    ///
-    /// let n = 0b01001100u8;
-    ///
-    /// assert_eq!(n.count_zeros(), 5);
-    /// ```
-    #[unstable(feature = "core",
-               reason = "pending integer conventions")]
-    #[inline]
-    fn count_zeros(self) -> u32 {
-        (!self).count_ones()
-    }
-
-    /// Returns the number of leading zeros in the binary representation
-    /// of `self`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// # #![feature(core)]
-    /// use std::num::Int;
-    ///
-    /// let n = 0b0101000u16;
-    ///
-    /// assert_eq!(n.leading_zeros(), 10);
-    /// ```
-    #[unstable(feature = "core",
-               reason = "pending integer conventions")]
-    fn leading_zeros(self) -> u32;
-
-    /// Returns the number of trailing zeros in the binary representation
-    /// of `self`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// # #![feature(core)]
-    /// use std::num::Int;
-    ///
-    /// let n = 0b0101000u16;
-    ///
-    /// assert_eq!(n.trailing_zeros(), 3);
-    /// ```
-    #[unstable(feature = "core",
-               reason = "pending integer conventions")]
-    fn trailing_zeros(self) -> u32;
-
-    /// Shifts the bits to the left by a specified amount, `n`, wrapping
-    /// the truncated bits to the end of the resulting integer.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// # #![feature(core)]
-    /// use std::num::Int;
-    ///
-    /// let n = 0x0123456789ABCDEFu64;
-    /// let m = 0x3456789ABCDEF012u64;
-    ///
-    /// assert_eq!(n.rotate_left(12), m);
-    /// ```
-    #[unstable(feature = "core",
-               reason = "pending integer conventions")]
-    fn rotate_left(self, n: u32) -> Self;
-
-    /// Shifts the bits to the right by a specified amount, `n`, wrapping
-    /// the truncated bits to the beginning of the resulting integer.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// # #![feature(core)]
-    /// use std::num::Int;
-    ///
-    /// let n = 0x0123456789ABCDEFu64;
-    /// let m = 0xDEF0123456789ABCu64;
-    ///
-    /// assert_eq!(n.rotate_right(12), m);
-    /// ```
-    #[unstable(feature = "core",
-               reason = "pending integer conventions")]
-    fn rotate_right(self, n: u32) -> Self;
-
-    /// Reverses the byte order of the integer.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::num::Int;
-    ///
-    /// let n = 0x0123456789ABCDEFu64;
-    /// let m = 0xEFCDAB8967452301u64;
-    ///
-    /// assert_eq!(n.swap_bytes(), m);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn swap_bytes(self) -> Self;
-
-    /// Converts an integer from big endian to the target's endianness.
-    ///
-    /// On big endian this is a no-op. On little endian the bytes are swapped.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::num::Int;
-    ///
-    /// let n = 0x0123456789ABCDEFu64;
-    ///
-    /// if cfg!(target_endian = "big") {
-    ///     assert_eq!(Int::from_be(n), n)
-    /// } else {
-    ///     assert_eq!(Int::from_be(n), n.swap_bytes())
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[inline]
-    fn from_be(x: Self) -> Self {
-        if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
-    }
-
-    /// Converts an integer from little endian to the target's endianness.
-    ///
-    /// On little endian this is a no-op. On big endian the bytes are swapped.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::num::Int;
-    ///
-    /// let n = 0x0123456789ABCDEFu64;
-    ///
-    /// if cfg!(target_endian = "little") {
-    ///     assert_eq!(Int::from_le(n), n)
-    /// } else {
-    ///     assert_eq!(Int::from_le(n), n.swap_bytes())
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[inline]
-    fn from_le(x: Self) -> Self {
-        if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
-    }
-
-    /// Converts `self` to big endian from the target's endianness.
-    ///
-    /// On big endian this is a no-op. On little endian the bytes are swapped.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::num::Int;
-    ///
-    /// let n = 0x0123456789ABCDEFu64;
-    ///
-    /// if cfg!(target_endian = "big") {
-    ///     assert_eq!(n.to_be(), n)
-    /// } else {
-    ///     assert_eq!(n.to_be(), n.swap_bytes())
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[inline]
-    fn to_be(self) -> Self { // or not to be?
-        if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
-    }
-
-    /// Converts `self` to little endian from the target's endianness.
-    ///
-    /// On little endian this is a no-op. On big endian the bytes are swapped.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::num::Int;
-    ///
-    /// let n = 0x0123456789ABCDEFu64;
-    ///
-    /// if cfg!(target_endian = "little") {
-    ///     assert_eq!(n.to_le(), n)
-    /// } else {
-    ///     assert_eq!(n.to_le(), n.swap_bytes())
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[inline]
-    fn to_le(self) -> Self {
-        if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
-    }
-
-    /// Checked integer addition. Computes `self + other`, returning `None` if
-    /// overflow occurred.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::num::Int;
-    ///
-    /// assert_eq!(5u16.checked_add(65530), Some(65535));
-    /// assert_eq!(6u16.checked_add(65530), None);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn checked_add(self, other: Self) -> Option<Self>;
-
-    /// Checked integer subtraction. Computes `self - other`, returning `None`
-    /// if underflow occurred.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::num::Int;
-    ///
-    /// assert_eq!((-127i8).checked_sub(1), Some(-128));
-    /// assert_eq!((-128i8).checked_sub(1), None);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn checked_sub(self, other: Self) -> Option<Self>;
-
-    /// Checked integer multiplication. Computes `self * other`, returning
-    /// `None` if underflow or overflow occurred.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::num::Int;
-    ///
-    /// assert_eq!(5u8.checked_mul(51), Some(255));
-    /// assert_eq!(5u8.checked_mul(52), None);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn checked_mul(self, other: Self) -> Option<Self>;
-
-    /// Checked integer division. Computes `self / other`, returning `None` if
-    /// `other == 0` or the operation results in underflow or overflow.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::num::Int;
-    ///
-    /// assert_eq!((-127i8).checked_div(-1), Some(127));
-    /// assert_eq!((-128i8).checked_div(-1), None);
-    /// assert_eq!((1i8).checked_div(0), None);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn checked_div(self, other: Self) -> Option<Self>;
-
-    /// Saturating integer addition. Computes `self + other`, saturating at
-    /// the numeric bounds instead of overflowing.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::num::Int;
-    ///
-    /// assert_eq!(5u16.saturating_add(65534), 65535);
-    /// assert_eq!((-5i16).saturating_add(-32767), -32768);
-    /// assert_eq!(100u32.saturating_add(4294967294), 4294967295);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[inline]
-    fn saturating_add(self, other: Self) -> Self {
-        match self.checked_add(other) {
-            Some(x)                      => x,
-            None if other >= Int::zero() => Int::max_value(),
-            None                         => Int::min_value(),
-        }
-    }
-
-    /// Saturating integer subtraction. Computes `self - other`, saturating at
-    /// the numeric bounds instead of overflowing.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::num::Int;
-    ///
-    /// assert_eq!(5u16.saturating_sub(65534), 0);
-    /// assert_eq!(5i16.saturating_sub(-32767), 32767);
-    /// assert_eq!(100u32.saturating_sub(4294967294), 0);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[inline]
-    fn saturating_sub(self, other: Self) -> Self {
-        match self.checked_sub(other) {
-            Some(x)                      => x,
-            None if other >= Int::zero() => Int::min_value(),
-            None                         => Int::max_value(),
-        }
-    }
-
-    /// Raises self to the power of `exp`, using exponentiation by squaring.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// # #![feature(core)]
-    /// use std::num::Int;
-    ///
-    /// assert_eq!(2.pow(4), 16);
-    /// ```
-    #[unstable(feature = "core",
-               reason = "pending integer conventions")]
-    #[inline]
-    fn pow(self, mut exp: u32) -> Self {
-        let mut base = self;
-        let mut acc: Self = Int::one();
-
-        let mut prev_base = self;
-        let mut base_oflo = false;
-        while exp > 0 {
-            if (exp & 1) == 1 {
-                if base_oflo {
-                    // ensure overflow occurs in the same manner it
-                    // would have otherwise (i.e. signal any exception
-                    // it would have otherwise).
-                    acc = acc * (prev_base * prev_base);
-                } else {
-                    acc = acc * base;
-                }
-            }
-            prev_base = base;
-            let (new_base, new_base_oflo) = base.overflowing_mul(base);
-            base = new_base;
-            base_oflo = new_base_oflo;
-            exp /= 2;
-        }
-        acc
-    }
-}
-
 macro_rules! checked_op {
     ($T:ty, $U:ty, $op:path, $x:expr, $y:expr) => {{
         let (result, overflowed) = unsafe { $op($x as $U, $y as $U) };
@@ -508,328 +101,13 @@ macro_rules! checked_op {
     }}
 }
 
-macro_rules! uint_impl {
-    ($T:ty = $ActualT:ty, $BITS:expr,
-     $ctpop:path,
-     $ctlz:path,
-     $cttz:path,
-     $bswap:path,
-     $add_with_overflow:path,
-     $sub_with_overflow:path,
-     $mul_with_overflow:path) => {
-        #[stable(feature = "rust1", since = "1.0.0")]
-        #[allow(deprecated)]
-        impl Int for $T {
-            #[inline]
-            fn zero() -> $T { 0 }
-
-            #[inline]
-            fn one() -> $T { 1 }
-
-            #[inline]
-            fn min_value() -> $T { 0 }
-
-            #[inline]
-            fn max_value() -> $T { !0 }
-
-            #[inline]
-            fn count_ones(self) -> u32 {
-                unsafe { $ctpop(self as $ActualT) as u32 }
-            }
-
-            #[inline]
-            fn leading_zeros(self) -> u32 {
-                unsafe { $ctlz(self as $ActualT) as u32 }
-            }
-
-            #[inline]
-            fn trailing_zeros(self) -> u32 {
-                unsafe { $cttz(self as $ActualT) as u32 }
-            }
-
-            #[inline]
-            fn rotate_left(self, n: u32) -> $T {
-                // Protect against undefined behaviour for over-long bit shifts
-                let n = n % $BITS;
-                (self << n) | (self >> (($BITS - n) % $BITS))
-            }
-
-            #[inline]
-            fn rotate_right(self, n: u32) -> $T {
-                // Protect against undefined behaviour for over-long bit shifts
-                let n = n % $BITS;
-                (self >> n) | (self << (($BITS - n) % $BITS))
-            }
-
-            #[inline]
-            fn swap_bytes(self) -> $T {
-                unsafe { $bswap(self as $ActualT) as $T }
-            }
-
-            #[inline]
-            fn checked_add(self, other: $T) -> Option<$T> {
-                checked_op!($T, $ActualT, $add_with_overflow, self, other)
-            }
-
-            #[inline]
-            fn checked_sub(self, other: $T) -> Option<$T> {
-                checked_op!($T, $ActualT, $sub_with_overflow, self, other)
-            }
-
-            #[inline]
-            fn checked_mul(self, other: $T) -> Option<$T> {
-                checked_op!($T, $ActualT, $mul_with_overflow, self, other)
-            }
-
-            #[inline]
-            fn checked_div(self, v: $T) -> Option<$T> {
-                match v {
-                    0 => None,
-                    v => Some(self / v),
-                }
-            }
-        }
-    }
-}
-
 /// Swapping a single byte is a no-op. This is marked as `unsafe` for
 /// consistency with the other `bswap` intrinsics.
 unsafe fn bswap8(x: u8) -> u8 { x }
 
-uint_impl! { u8 = u8, 8,
-    intrinsics::ctpop8,
-    intrinsics::ctlz8,
-    intrinsics::cttz8,
-    bswap8,
-    intrinsics::u8_add_with_overflow,
-    intrinsics::u8_sub_with_overflow,
-    intrinsics::u8_mul_with_overflow }
-
-uint_impl! { u16 = u16, 16,
-    intrinsics::ctpop16,
-    intrinsics::ctlz16,
-    intrinsics::cttz16,
-    intrinsics::bswap16,
-    intrinsics::u16_add_with_overflow,
-    intrinsics::u16_sub_with_overflow,
-    intrinsics::u16_mul_with_overflow }
-
-uint_impl! { u32 = u32, 32,
-    intrinsics::ctpop32,
-    intrinsics::ctlz32,
-    intrinsics::cttz32,
-    intrinsics::bswap32,
-    intrinsics::u32_add_with_overflow,
-    intrinsics::u32_sub_with_overflow,
-    intrinsics::u32_mul_with_overflow }
-
-uint_impl! { u64 = u64, 64,
-    intrinsics::ctpop64,
-    intrinsics::ctlz64,
-    intrinsics::cttz64,
-    intrinsics::bswap64,
-    intrinsics::u64_add_with_overflow,
-    intrinsics::u64_sub_with_overflow,
-    intrinsics::u64_mul_with_overflow }
-
-#[cfg(target_pointer_width = "32")]
-uint_impl! { usize = u32, 32,
-    intrinsics::ctpop32,
-    intrinsics::ctlz32,
-    intrinsics::cttz32,
-    intrinsics::bswap32,
-    intrinsics::u32_add_with_overflow,
-    intrinsics::u32_sub_with_overflow,
-    intrinsics::u32_mul_with_overflow }
-
-#[cfg(target_pointer_width = "64")]
-uint_impl! { usize = u64, 64,
-    intrinsics::ctpop64,
-    intrinsics::ctlz64,
-    intrinsics::cttz64,
-    intrinsics::bswap64,
-    intrinsics::u64_add_with_overflow,
-    intrinsics::u64_sub_with_overflow,
-    intrinsics::u64_mul_with_overflow }
-
-macro_rules! int_impl {
-    ($T:ty = $ActualT:ty, $UnsignedT:ty, $BITS:expr,
-     $add_with_overflow:path,
-     $sub_with_overflow:path,
-     $mul_with_overflow:path) => {
-        #[stable(feature = "rust1", since = "1.0.0")]
-        #[allow(deprecated)]
-        impl Int for $T {
-            #[inline]
-            fn zero() -> $T { 0 }
-
-            #[inline]
-            fn one() -> $T { 1 }
-
-            #[inline]
-            fn min_value() -> $T { (-1 as $T) << ($BITS - 1) }
-
-            #[inline]
-            fn max_value() -> $T { let min: $T = Int::min_value(); !min }
-
-            #[inline]
-            fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
-
-            #[inline]
-            fn leading_zeros(self) -> u32 {
-                (self as $UnsignedT).leading_zeros()
-            }
-
-            #[inline]
-            fn trailing_zeros(self) -> u32 {
-                (self as $UnsignedT).trailing_zeros()
-            }
-
-            #[inline]
-            fn rotate_left(self, n: u32) -> $T {
-                (self as $UnsignedT).rotate_left(n) as $T
-            }
-
-            #[inline]
-            fn rotate_right(self, n: u32) -> $T {
-                (self as $UnsignedT).rotate_right(n) as $T
-            }
-
-            #[inline]
-            fn swap_bytes(self) -> $T {
-                (self as $UnsignedT).swap_bytes() as $T
-            }
-
-            #[inline]
-            fn checked_add(self, other: $T) -> Option<$T> {
-                checked_op!($T, $ActualT, $add_with_overflow, self, other)
-            }
-
-            #[inline]
-            fn checked_sub(self, other: $T) -> Option<$T> {
-                checked_op!($T, $ActualT, $sub_with_overflow, self, other)
-            }
-
-            #[inline]
-            fn checked_mul(self, other: $T) -> Option<$T> {
-                checked_op!($T, $ActualT, $mul_with_overflow, self, other)
-            }
-
-            #[inline]
-            fn checked_div(self, v: $T) -> Option<$T> {
-                match v {
-                    0   => None,
-                   -1 if self == Int::min_value()
-                        => None,
-                    v   => Some(self / v),
-                }
-            }
-        }
-    }
-}
-
-int_impl! { i8 = i8, u8, 8,
-    intrinsics::i8_add_with_overflow,
-    intrinsics::i8_sub_with_overflow,
-    intrinsics::i8_mul_with_overflow }
-
-int_impl! { i16 = i16, u16, 16,
-    intrinsics::i16_add_with_overflow,
-    intrinsics::i16_sub_with_overflow,
-    intrinsics::i16_mul_with_overflow }
-
-int_impl! { i32 = i32, u32, 32,
-    intrinsics::i32_add_with_overflow,
-    intrinsics::i32_sub_with_overflow,
-    intrinsics::i32_mul_with_overflow }
-
-int_impl! { i64 = i64, u64, 64,
-    intrinsics::i64_add_with_overflow,
-    intrinsics::i64_sub_with_overflow,
-    intrinsics::i64_mul_with_overflow }
-
-#[cfg(target_pointer_width = "32")]
-int_impl! { isize = i32, u32, 32,
-    intrinsics::i32_add_with_overflow,
-    intrinsics::i32_sub_with_overflow,
-    intrinsics::i32_mul_with_overflow }
-
-#[cfg(target_pointer_width = "64")]
-int_impl! { isize = i64, u64, 64,
-    intrinsics::i64_add_with_overflow,
-    intrinsics::i64_sub_with_overflow,
-    intrinsics::i64_mul_with_overflow }
-
-/// A built-in two's complement integer.
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0",
-             reason = "replaced by inherent methods; for generics, use rust-lang/num")]
-#[allow(deprecated)]
-pub trait SignedInt
-    : Int
-    + Neg<Output=Self>
-{
-    /// Computes the absolute value of `self`. `Int::min_value()` will be
-    /// returned if the number is `Int::min_value()`.
-    #[unstable(feature = "core", reason = "overflow in debug builds?")]
-    fn abs(self) -> Self;
-
-    /// Returns a number representing sign of `self`.
-    ///
-    /// - `0` if the number is zero
-    /// - `1` if the number is positive
-    /// - `-1` if the number is negative
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn signum(self) -> Self;
-
-    /// Returns `true` if `self` is positive and `false` if the number
-    /// is zero or negative.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_positive(self) -> bool;
-
-    /// Returns `true` if `self` is negative and `false` if the number
-    /// is zero or positive.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_negative(self) -> bool;
-}
-
-macro_rules! signed_int_impl {
-    ($T:ty) => {
-        #[stable(feature = "rust1", since = "1.0.0")]
-        #[allow(deprecated)]
-        impl SignedInt for $T {
-            #[inline]
-            fn abs(self) -> $T {
-                if self.is_negative() { -self } else { self }
-            }
-
-            #[inline]
-            fn signum(self) -> $T {
-                match self {
-                    n if n > 0 =>  1,
-                    0          =>  0,
-                    _          => -1,
-                }
-            }
-
-            #[inline]
-            fn is_positive(self) -> bool { self > 0 }
-
-            #[inline]
-            fn is_negative(self) -> bool { self < 0 }
-        }
-    }
-}
-
-signed_int_impl! { i8 }
-signed_int_impl! { i16 }
-signed_int_impl! { i32 }
-signed_int_impl! { i64 }
-signed_int_impl! { isize }
-
 // `Int` + `SignedInt` implemented for signed integers
 macro_rules! int_impl {
-    ($T:ty = $ActualT:ty, $UnsignedT:ty, $BITS:expr,
+    ($T:ident = $ActualT:ty, $UnsignedT:ty, $BITS:expr,
      $add_with_overflow:path,
      $sub_with_overflow:path,
      $mul_with_overflow:path) => {
@@ -842,7 +120,7 @@ pub fn min_value() -> $T {
         /// Returns the largest value that can be represented by this integer type.
         #[stable(feature = "rust1", since = "1.0.0")]
         pub fn max_value() -> $T {
-            let min: $T = Int::min_value(); !min
+            let min = $T::min_value(); !min
         }
 
         /// Converts a string slice in a given base to an integer.
@@ -861,7 +139,7 @@ pub fn max_value() -> $T {
         #[stable(feature = "rust1", since = "1.0.0")]
         #[allow(deprecated)]
         pub fn from_str_radix(src: &str, radix: u32) -> Result<$T, ParseIntError> {
-            <Self as FromStrRadix>::from_str_radix(src, radix)
+            from_str_radix(src, radix)
         }
 
         /// Returns the number of ones in the binary representation of `self`.
@@ -869,9 +147,6 @@ pub fn from_str_radix(src: &str, radix: u32) -> Result<$T, ParseIntError> {
         /// # Examples
         ///
         /// ```rust
-        /// # #![feature(core)]
-        /// use std::num::Int;
-        ///
         /// let n = 0b01001100u8;
         ///
         /// assert_eq!(n.count_ones(), 3);
@@ -885,9 +160,6 @@ pub fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
         /// # Examples
         ///
         /// ```rust
-        /// # #![feature(core)]
-        /// use std::num::Int;
-        ///
         /// let n = 0b01001100u8;
         ///
         /// assert_eq!(n.count_zeros(), 5);
@@ -904,9 +176,6 @@ pub fn count_zeros(self) -> u32 {
         /// # Examples
         ///
         /// ```rust
-        /// # #![feature(core)]
-        /// use std::num::Int;
-        ///
         /// let n = 0b0101000u16;
         ///
         /// assert_eq!(n.leading_zeros(), 10);
@@ -923,9 +192,6 @@ pub fn leading_zeros(self) -> u32 {
         /// # Examples
         ///
         /// ```rust
-        /// # #![feature(core)]
-        /// use std::num::Int;
-        ///
         /// let n = 0b0101000u16;
         ///
         /// assert_eq!(n.trailing_zeros(), 3);
@@ -942,9 +208,6 @@ pub fn trailing_zeros(self) -> u32 {
         /// # Examples
         ///
         /// ```rust
-        /// # #![feature(core)]
-        /// use std::num::Int;
-        ///
         /// let n = 0x0123456789ABCDEFu64;
         /// let m = 0x3456789ABCDEF012u64;
         ///
@@ -963,9 +226,6 @@ pub fn rotate_left(self, n: u32) -> $T {
         /// # Examples
         ///
         /// ```rust
-        /// # #![feature(core)]
-        /// use std::num::Int;
-        ///
         /// let n = 0x0123456789ABCDEFu64;
         /// let m = 0xDEF0123456789ABCu64;
         ///
@@ -982,8 +242,6 @@ pub fn rotate_right(self, n: u32) -> $T {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// let n = 0x0123456789ABCDEFu64;
         /// let m = 0xEFCDAB8967452301u64;
         ///
@@ -1003,14 +261,12 @@ pub fn swap_bytes(self) -> $T {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// let n = 0x0123456789ABCDEFu64;
         ///
         /// if cfg!(target_endian = "big") {
-        ///     assert_eq!(Int::from_be(n), n)
+        ///     assert_eq!(u64::from_be(n), n)
         /// } else {
-        ///     assert_eq!(Int::from_be(n), n.swap_bytes())
+        ///     assert_eq!(u64::from_be(n), n.swap_bytes())
         /// }
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -1027,14 +283,12 @@ pub fn from_be(x: $T) -> $T {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// let n = 0x0123456789ABCDEFu64;
         ///
         /// if cfg!(target_endian = "little") {
-        ///     assert_eq!(Int::from_le(n), n)
+        ///     assert_eq!(u64::from_le(n), n)
         /// } else {
-        ///     assert_eq!(Int::from_le(n), n.swap_bytes())
+        ///     assert_eq!(u64::from_le(n), n.swap_bytes())
         /// }
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -1051,8 +305,6 @@ pub fn from_le(x: $T) -> $T {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// let n = 0x0123456789ABCDEFu64;
         ///
         /// if cfg!(target_endian = "big") {
@@ -1075,8 +327,6 @@ pub fn to_be(self) -> $T { // or not to be?
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// let n = 0x0123456789ABCDEFu64;
         ///
         /// if cfg!(target_endian = "little") {
@@ -1097,8 +347,6 @@ pub fn to_le(self) -> $T {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// assert_eq!(5u16.checked_add(65530), Some(65535));
         /// assert_eq!(6u16.checked_add(65530), None);
         /// ```
@@ -1114,8 +362,6 @@ pub fn checked_add(self, other: $T) -> Option<$T> {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// assert_eq!((-127i8).checked_sub(1), Some(-128));
         /// assert_eq!((-128i8).checked_sub(1), None);
         /// ```
@@ -1131,8 +377,6 @@ pub fn checked_sub(self, other: $T) -> Option<$T> {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// assert_eq!(5u8.checked_mul(51), Some(255));
         /// assert_eq!(5u8.checked_mul(52), None);
         /// ```
@@ -1148,8 +392,6 @@ pub fn checked_mul(self, other: $T) -> Option<$T> {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// assert_eq!((-127i8).checked_div(-1), Some(127));
         /// assert_eq!((-128i8).checked_div(-1), None);
         /// assert_eq!((1i8).checked_div(0), None);
@@ -1441,7 +683,7 @@ pub fn max_value() -> $T { !0 }
         #[stable(feature = "rust1", since = "1.0.0")]
         #[allow(deprecated)]
         pub fn from_str_radix(src: &str, radix: u32) -> Result<$T, ParseIntError> {
-            <Self as FromStrRadix>::from_str_radix(src, radix)
+            from_str_radix(src, radix)
         }
 
         /// Returns the number of ones in the binary representation of `self`.
@@ -1449,9 +691,6 @@ pub fn from_str_radix(src: &str, radix: u32) -> Result<$T, ParseIntError> {
         /// # Examples
         ///
         /// ```rust
-        /// # #![feature(core)]
-        /// use std::num::Int;
-        ///
         /// let n = 0b01001100u8;
         ///
         /// assert_eq!(n.count_ones(), 3);
@@ -1467,9 +706,6 @@ pub fn count_ones(self) -> u32 {
         /// # Examples
         ///
         /// ```rust
-        /// # #![feature(core)]
-        /// use std::num::Int;
-        ///
         /// let n = 0b01001100u8;
         ///
         /// assert_eq!(n.count_zeros(), 5);
@@ -1486,9 +722,6 @@ pub fn count_zeros(self) -> u32 {
         /// # Examples
         ///
         /// ```rust
-        /// # #![feature(core)]
-        /// use std::num::Int;
-        ///
         /// let n = 0b0101000u16;
         ///
         /// assert_eq!(n.leading_zeros(), 10);
@@ -1505,9 +738,6 @@ pub fn leading_zeros(self) -> u32 {
         /// # Examples
         ///
         /// ```rust
-        /// # #![feature(core)]
-        /// use std::num::Int;
-        ///
         /// let n = 0b0101000u16;
         ///
         /// assert_eq!(n.trailing_zeros(), 3);
@@ -1524,9 +754,6 @@ pub fn trailing_zeros(self) -> u32 {
         /// # Examples
         ///
         /// ```rust
-        /// # #![feature(core)]
-        /// use std::num::Int;
-        ///
         /// let n = 0x0123456789ABCDEFu64;
         /// let m = 0x3456789ABCDEF012u64;
         ///
@@ -1547,9 +774,6 @@ pub fn rotate_left(self, n: u32) -> $T {
         /// # Examples
         ///
         /// ```rust
-        /// # #![feature(core)]
-        /// use std::num::Int;
-        ///
         /// let n = 0x0123456789ABCDEFu64;
         /// let m = 0xDEF0123456789ABCu64;
         ///
@@ -1568,8 +792,6 @@ pub fn rotate_right(self, n: u32) -> $T {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// let n = 0x0123456789ABCDEFu64;
         /// let m = 0xEFCDAB8967452301u64;
         ///
@@ -1589,14 +811,12 @@ pub fn swap_bytes(self) -> $T {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// let n = 0x0123456789ABCDEFu64;
         ///
         /// if cfg!(target_endian = "big") {
-        ///     assert_eq!(Int::from_be(n), n)
+        ///     assert_eq!(u64::from_be(n), n)
         /// } else {
-        ///     assert_eq!(Int::from_be(n), n.swap_bytes())
+        ///     assert_eq!(u64::from_be(n), n.swap_bytes())
         /// }
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -1613,14 +833,12 @@ pub fn from_be(x: $T) -> $T {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// let n = 0x0123456789ABCDEFu64;
         ///
         /// if cfg!(target_endian = "little") {
-        ///     assert_eq!(Int::from_le(n), n)
+        ///     assert_eq!(u64::from_le(n), n)
         /// } else {
-        ///     assert_eq!(Int::from_le(n), n.swap_bytes())
+        ///     assert_eq!(u64::from_le(n), n.swap_bytes())
         /// }
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -1637,8 +855,6 @@ pub fn from_le(x: $T) -> $T {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// let n = 0x0123456789ABCDEFu64;
         ///
         /// if cfg!(target_endian = "big") {
@@ -1661,8 +877,6 @@ pub fn to_be(self) -> $T { // or not to be?
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// let n = 0x0123456789ABCDEFu64;
         ///
         /// if cfg!(target_endian = "little") {
@@ -1683,8 +897,6 @@ pub fn to_le(self) -> $T {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// assert_eq!(5u16.checked_add(65530), Some(65535));
         /// assert_eq!(6u16.checked_add(65530), None);
         /// ```
@@ -1700,8 +912,6 @@ pub fn checked_add(self, other: $T) -> Option<$T> {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// assert_eq!((-127i8).checked_sub(1), Some(-128));
         /// assert_eq!((-128i8).checked_sub(1), None);
         /// ```
@@ -1717,8 +927,6 @@ pub fn checked_sub(self, other: $T) -> Option<$T> {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// assert_eq!(5u8.checked_mul(51), Some(255));
         /// assert_eq!(5u8.checked_mul(52), None);
         /// ```
@@ -1734,8 +942,6 @@ pub fn checked_mul(self, other: $T) -> Option<$T> {
         /// # Examples
         ///
         /// ```rust
-        /// use std::num::Int;
-        ///
         /// assert_eq!((-127i8).checked_div(-1), Some(127));
         /// assert_eq!((-128i8).checked_div(-1), None);
         /// assert_eq!((1i8).checked_div(0), None);
@@ -1868,10 +1074,7 @@ pub fn wrapping_shr(self, rhs: u32) -> $T {
         /// # Examples
         ///
         /// ```rust
-        /// # #![feature(core)]
-        /// use std::num::Int;
-        ///
-        /// assert_eq!(2.pow(4), 16);
+        /// assert_eq!(2i32.pow(4), 16);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
@@ -2009,575 +1212,6 @@ impl usize {
         intrinsics::u64_mul_with_overflow }
 }
 
-/// A generic trait for converting a value to a number.
-#[unstable(feature = "core", reason = "trait is likely to be removed")]
-pub trait ToPrimitive {
-    /// Converts the value of `self` to an `isize`.
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0", reason = "use to_isize")]
-    fn to_int(&self) -> Option<isize> {
-        self.to_i64().and_then(|x| x.to_isize())
-    }
-
-    /// Converts the value of `self` to an `isize`.
-    #[inline]
-    fn to_isize(&self) -> Option<isize> {
-        self.to_i64().and_then(|x| x.to_isize())
-    }
-
-    /// Converts the value of `self` to an `i8`.
-    #[inline]
-    fn to_i8(&self) -> Option<i8> {
-        self.to_i64().and_then(|x| x.to_i8())
-    }
-
-    /// Converts the value of `self` to an `i16`.
-    #[inline]
-    fn to_i16(&self) -> Option<i16> {
-        self.to_i64().and_then(|x| x.to_i16())
-    }
-
-    /// Converts the value of `self` to an `i32`.
-    #[inline]
-    fn to_i32(&self) -> Option<i32> {
-        self.to_i64().and_then(|x| x.to_i32())
-    }
-
-    /// Converts the value of `self` to an `i64`.
-    fn to_i64(&self) -> Option<i64>;
-
-    /// Converts the value of `self` to an `usize`.
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0", reason = "use to_usize")]
-    fn to_uint(&self) -> Option<usize> {
-        self.to_u64().and_then(|x| x.to_usize())
-    }
-
-    /// Converts the value of `self` to a `usize`.
-    #[inline]
-    fn to_usize(&self) -> Option<usize> {
-        self.to_u64().and_then(|x| x.to_usize())
-    }
-
-    /// Converts the value of `self` to an `u8`.
-    #[inline]
-    fn to_u8(&self) -> Option<u8> {
-        self.to_u64().and_then(|x| x.to_u8())
-    }
-
-    /// Converts the value of `self` to an `u16`.
-    #[inline]
-    fn to_u16(&self) -> Option<u16> {
-        self.to_u64().and_then(|x| x.to_u16())
-    }
-
-    /// Converts the value of `self` to an `u32`.
-    #[inline]
-    fn to_u32(&self) -> Option<u32> {
-        self.to_u64().and_then(|x| x.to_u32())
-    }
-
-    /// Converts the value of `self` to an `u64`.
-    #[inline]
-    fn to_u64(&self) -> Option<u64>;
-
-    /// Converts the value of `self` to an `f32`.
-    #[inline]
-    fn to_f32(&self) -> Option<f32> {
-        self.to_f64().and_then(|x| x.to_f32())
-    }
-
-    /// Converts the value of `self` to an `f64`.
-    #[inline]
-    fn to_f64(&self) -> Option<f64> {
-        self.to_i64().and_then(|x| x.to_f64())
-    }
-}
-
-macro_rules! impl_to_primitive_int_to_int {
-    ($SrcT:ty, $DstT:ty, $slf:expr) => (
-        {
-            if size_of::<$SrcT>() <= size_of::<$DstT>() {
-                Some($slf as $DstT)
-            } else {
-                let n = $slf as i64;
-                let min_value: $DstT = Int::min_value();
-                let max_value: $DstT = Int::max_value();
-                if min_value as i64 <= n && n <= max_value as i64 {
-                    Some($slf as $DstT)
-                } else {
-                    None
-                }
-            }
-        }
-    )
-}
-
-macro_rules! impl_to_primitive_int_to_uint {
-    ($SrcT:ty, $DstT:ty, $slf:expr) => (
-        {
-            let zero: $SrcT = Int::zero();
-            let max_value: $DstT = Int::max_value();
-            if zero <= $slf && $slf as u64 <= max_value as u64 {
-                Some($slf as $DstT)
-            } else {
-                None
-            }
-        }
-    )
-}
-
-macro_rules! impl_to_primitive_int {
-    ($T:ty) => (
-        impl ToPrimitive for $T {
-            #[inline]
-            fn to_int(&self) -> Option<isize> { impl_to_primitive_int_to_int!($T, isize, *self) }
-            #[inline]
-            fn to_isize(&self) -> Option<isize> { impl_to_primitive_int_to_int!($T, isize, *self) }
-            #[inline]
-            fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8, *self) }
-            #[inline]
-            fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16, *self) }
-            #[inline]
-            fn to_i32(&self) -> Option<i32> { impl_to_primitive_int_to_int!($T, i32, *self) }
-            #[inline]
-            fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64, *self) }
-
-            #[inline]
-            fn to_uint(&self) -> Option<usize> { impl_to_primitive_int_to_uint!($T, usize, *self) }
-            #[inline]
-            fn to_usize(&self) -> Option<usize> { impl_to_primitive_int_to_uint!($T, usize, *self) }
-            #[inline]
-            fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8, *self) }
-            #[inline]
-            fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16, *self) }
-            #[inline]
-            fn to_u32(&self) -> Option<u32> { impl_to_primitive_int_to_uint!($T, u32, *self) }
-            #[inline]
-            fn to_u64(&self) -> Option<u64> { impl_to_primitive_int_to_uint!($T, u64, *self) }
-
-            #[inline]
-            fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
-            #[inline]
-            fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
-        }
-    )
-}
-
-impl_to_primitive_int! { isize }
-impl_to_primitive_int! { i8 }
-impl_to_primitive_int! { i16 }
-impl_to_primitive_int! { i32 }
-impl_to_primitive_int! { i64 }
-
-macro_rules! impl_to_primitive_uint_to_int {
-    ($DstT:ty, $slf:expr) => (
-        {
-            let max_value: $DstT = Int::max_value();
-            if $slf as u64 <= max_value as u64 {
-                Some($slf as $DstT)
-            } else {
-                None
-            }
-        }
-    )
-}
-
-macro_rules! impl_to_primitive_uint_to_uint {
-    ($SrcT:ty, $DstT:ty, $slf:expr) => (
-        {
-            if size_of::<$SrcT>() <= size_of::<$DstT>() {
-                Some($slf as $DstT)
-            } else {
-                let zero: $SrcT = Int::zero();
-                let max_value: $DstT = Int::max_value();
-                if zero <= $slf && $slf as u64 <= max_value as u64 {
-                    Some($slf as $DstT)
-                } else {
-                    None
-                }
-            }
-        }
-    )
-}
-
-macro_rules! impl_to_primitive_uint {
-    ($T:ty) => (
-        impl ToPrimitive for $T {
-            #[inline]
-            fn to_int(&self) -> Option<isize> { impl_to_primitive_uint_to_int!(isize, *self) }
-            #[inline]
-            fn to_isize(&self) -> Option<isize> { impl_to_primitive_uint_to_int!(isize, *self) }
-            #[inline]
-            fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8, *self) }
-            #[inline]
-            fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16, *self) }
-            #[inline]
-            fn to_i32(&self) -> Option<i32> { impl_to_primitive_uint_to_int!(i32, *self) }
-            #[inline]
-            fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64, *self) }
-
-            #[inline]
-            fn to_uint(&self) -> Option<usize> { impl_to_primitive_uint_to_uint!($T, usize, *self) }
-            #[inline]
-            fn to_usize(&self) -> Option<usize> {
-                impl_to_primitive_uint_to_uint!($T, usize, *self)
-            }
-            #[inline]
-            fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8, *self) }
-            #[inline]
-            fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16, *self) }
-            #[inline]
-            fn to_u32(&self) -> Option<u32> { impl_to_primitive_uint_to_uint!($T, u32, *self) }
-            #[inline]
-            fn to_u64(&self) -> Option<u64> { impl_to_primitive_uint_to_uint!($T, u64, *self) }
-
-            #[inline]
-            fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
-            #[inline]
-            fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
-        }
-    )
-}
-
-impl_to_primitive_uint! { usize }
-impl_to_primitive_uint! { u8 }
-impl_to_primitive_uint! { u16 }
-impl_to_primitive_uint! { u32 }
-impl_to_primitive_uint! { u64 }
-
-macro_rules! impl_to_primitive_float_to_float {
-    ($SrcT:ident, $DstT:ident, $slf:expr) => (
-        if size_of::<$SrcT>() <= size_of::<$DstT>() {
-            Some($slf as $DstT)
-        } else {
-            let n = $slf as f64;
-            let max_value: $SrcT = ::$SrcT::MAX;
-            if -max_value as f64 <= n && n <= max_value as f64 {
-                Some($slf as $DstT)
-            } else {
-                None
-            }
-        }
-    )
-}
-
-macro_rules! impl_to_primitive_float {
-    ($T:ident) => (
-        impl ToPrimitive for $T {
-            #[inline]
-            fn to_int(&self) -> Option<isize> { Some(*self as isize) }
-            #[inline]
-            fn to_isize(&self) -> Option<isize> { Some(*self as isize) }
-            #[inline]
-            fn to_i8(&self) -> Option<i8> { Some(*self as i8) }
-            #[inline]
-            fn to_i16(&self) -> Option<i16> { Some(*self as i16) }
-            #[inline]
-            fn to_i32(&self) -> Option<i32> { Some(*self as i32) }
-            #[inline]
-            fn to_i64(&self) -> Option<i64> { Some(*self as i64) }
-
-            #[inline]
-            fn to_uint(&self) -> Option<usize> { Some(*self as usize) }
-            #[inline]
-            fn to_usize(&self) -> Option<usize> { Some(*self as usize) }
-            #[inline]
-            fn to_u8(&self) -> Option<u8> { Some(*self as u8) }
-            #[inline]
-            fn to_u16(&self) -> Option<u16> { Some(*self as u16) }
-            #[inline]
-            fn to_u32(&self) -> Option<u32> { Some(*self as u32) }
-            #[inline]
-            fn to_u64(&self) -> Option<u64> { Some(*self as u64) }
-
-            #[inline]
-            fn to_f32(&self) -> Option<f32> { impl_to_primitive_float_to_float!($T, f32, *self) }
-            #[inline]
-            fn to_f64(&self) -> Option<f64> { impl_to_primitive_float_to_float!($T, f64, *self) }
-        }
-    )
-}
-
-impl_to_primitive_float! { f32 }
-impl_to_primitive_float! { f64 }
-
-/// A generic trait for converting a number to a value.
-#[unstable(feature = "core", reason = "trait is likely to be removed")]
-pub trait FromPrimitive : ::marker::Sized {
-    /// Converts an `isize` to return an optional value of this type. If the
-    /// value cannot be represented by this value, the `None` is returned.
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0", reason = "use from_isize")]
-    fn from_int(n: isize) -> Option<Self> {
-        FromPrimitive::from_i64(n as i64)
-    }
-
-    /// Converts an `isize` to return an optional value of this type. If the
-    /// value cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_isize(n: isize) -> Option<Self> {
-        FromPrimitive::from_i64(n as i64)
-    }
-
-    /// Converts an `i8` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_i8(n: i8) -> Option<Self> {
-        FromPrimitive::from_i64(n as i64)
-    }
-
-    /// Converts an `i16` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_i16(n: i16) -> Option<Self> {
-        FromPrimitive::from_i64(n as i64)
-    }
-
-    /// Converts an `i32` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_i32(n: i32) -> Option<Self> {
-        FromPrimitive::from_i64(n as i64)
-    }
-
-    /// Converts an `i64` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    fn from_i64(n: i64) -> Option<Self>;
-
-    /// Converts an `usize` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0", reason = "use from_usize")]
-    fn from_uint(n: usize) -> Option<Self> {
-        FromPrimitive::from_u64(n as u64)
-    }
-
-    /// Converts a `usize` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_usize(n: usize) -> Option<Self> {
-        FromPrimitive::from_u64(n as u64)
-    }
-
-    /// Converts an `u8` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_u8(n: u8) -> Option<Self> {
-        FromPrimitive::from_u64(n as u64)
-    }
-
-    /// Converts an `u16` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_u16(n: u16) -> Option<Self> {
-        FromPrimitive::from_u64(n as u64)
-    }
-
-    /// Converts an `u32` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_u32(n: u32) -> Option<Self> {
-        FromPrimitive::from_u64(n as u64)
-    }
-
-    /// Converts an `u64` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    fn from_u64(n: u64) -> Option<Self>;
-
-    /// Converts a `f32` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_f32(n: f32) -> Option<Self> {
-        FromPrimitive::from_f64(n as f64)
-    }
-
-    /// Converts a `f64` to return an optional value of this type. If the
-    /// type cannot be represented by this value, the `None` is returned.
-    #[inline]
-    fn from_f64(n: f64) -> Option<Self> {
-        FromPrimitive::from_i64(n as i64)
-    }
-}
-
-/// A utility function that just calls `FromPrimitive::from_int`.
-#[unstable(feature = "core", reason = "likely to be removed")]
-#[deprecated(since = "1.0.0", reason = "use from_isize")]
-pub fn from_int<A: FromPrimitive>(n: isize) -> Option<A> {
-    FromPrimitive::from_isize(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_isize`.
-#[unstable(feature = "core", reason = "likely to be removed")]
-pub fn from_isize<A: FromPrimitive>(n: isize) -> Option<A> {
-    FromPrimitive::from_isize(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_i8`.
-#[unstable(feature = "core", reason = "likely to be removed")]
-pub fn from_i8<A: FromPrimitive>(n: i8) -> Option<A> {
-    FromPrimitive::from_i8(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_i16`.
-#[unstable(feature = "core", reason = "likely to be removed")]
-pub fn from_i16<A: FromPrimitive>(n: i16) -> Option<A> {
-    FromPrimitive::from_i16(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_i32`.
-#[unstable(feature = "core", reason = "likely to be removed")]
-pub fn from_i32<A: FromPrimitive>(n: i32) -> Option<A> {
-    FromPrimitive::from_i32(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_i64`.
-#[unstable(feature = "core", reason = "likely to be removed")]
-pub fn from_i64<A: FromPrimitive>(n: i64) -> Option<A> {
-    FromPrimitive::from_i64(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_uint`.
-#[unstable(feature = "core", reason = "likely to be removed")]
-#[deprecated(since = "1.0.0", reason = "use from_uint")]
-pub fn from_uint<A: FromPrimitive>(n: usize) -> Option<A> {
-    FromPrimitive::from_usize(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_usize`.
-#[unstable(feature = "core", reason = "likely to be removed")]
-pub fn from_usize<A: FromPrimitive>(n: usize) -> Option<A> {
-    FromPrimitive::from_usize(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_u8`.
-#[unstable(feature = "core", reason = "likely to be removed")]
-pub fn from_u8<A: FromPrimitive>(n: u8) -> Option<A> {
-    FromPrimitive::from_u8(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_u16`.
-#[unstable(feature = "core", reason = "likely to be removed")]
-pub fn from_u16<A: FromPrimitive>(n: u16) -> Option<A> {
-    FromPrimitive::from_u16(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_u32`.
-#[unstable(feature = "core", reason = "likely to be removed")]
-pub fn from_u32<A: FromPrimitive>(n: u32) -> Option<A> {
-    FromPrimitive::from_u32(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_u64`.
-#[unstable(feature = "core", reason = "likely to be removed")]
-pub fn from_u64<A: FromPrimitive>(n: u64) -> Option<A> {
-    FromPrimitive::from_u64(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_f32`.
-#[unstable(feature = "core", reason = "likely to be removed")]
-pub fn from_f32<A: FromPrimitive>(n: f32) -> Option<A> {
-    FromPrimitive::from_f32(n)
-}
-
-/// A utility function that just calls `FromPrimitive::from_f64`.
-#[unstable(feature = "core", reason = "likely to be removed")]
-pub fn from_f64<A: FromPrimitive>(n: f64) -> Option<A> {
-    FromPrimitive::from_f64(n)
-}
-
-macro_rules! impl_from_primitive {
-    ($T:ty, $to_ty:ident) => (
-        #[allow(deprecated)]
-        impl FromPrimitive for $T {
-            #[inline] fn from_int(n: isize) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_i16(n: i16) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_i32(n: i32) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_i64(n: i64) -> Option<$T> { n.$to_ty() }
-
-            #[inline] fn from_uint(n: usize) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_u8(n: u8) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_u16(n: u16) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_u32(n: u32) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_u64(n: u64) -> Option<$T> { n.$to_ty() }
-
-            #[inline] fn from_f32(n: f32) -> Option<$T> { n.$to_ty() }
-            #[inline] fn from_f64(n: f64) -> Option<$T> { n.$to_ty() }
-        }
-    )
-}
-
-impl_from_primitive! { isize, to_int }
-impl_from_primitive! { i8, to_i8 }
-impl_from_primitive! { i16, to_i16 }
-impl_from_primitive! { i32, to_i32 }
-impl_from_primitive! { i64, to_i64 }
-impl_from_primitive! { usize, to_uint }
-impl_from_primitive! { u8, to_u8 }
-impl_from_primitive! { u16, to_u16 }
-impl_from_primitive! { u32, to_u32 }
-impl_from_primitive! { u64, to_u64 }
-impl_from_primitive! { f32, to_f32 }
-impl_from_primitive! { f64, to_f64 }
-
-/// Casts from one machine scalar to another.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(core)]
-/// use std::num;
-///
-/// let twenty: f32 = num::cast(0x14).unwrap();
-/// assert_eq!(twenty, 20f32);
-/// ```
-///
-#[inline]
-#[unstable(feature = "core", reason = "likely to be removed")]
-pub fn cast<T: NumCast,U: NumCast>(n: T) -> Option<U> {
-    NumCast::from(n)
-}
-
-/// An interface for casting between machine scalars.
-#[unstable(feature = "core", reason = "trait is likely to be removed")]
-pub trait NumCast: ToPrimitive {
-    /// Creates a number from another value that can be converted into a primitive via the
-    /// `ToPrimitive` trait.
-    fn from<T: ToPrimitive>(n: T) -> Option<Self>;
-}
-
-macro_rules! impl_num_cast {
-    ($T:ty, $conv:ident) => (
-        impl NumCast for $T {
-            #[inline]
-            #[allow(deprecated)]
-            fn from<N: ToPrimitive>(n: N) -> Option<$T> {
-                // `$conv` could be generated using `concat_idents!`, but that
-                // macro seems to be broken at the moment
-                n.$conv()
-            }
-        }
-    )
-}
-
-impl_num_cast! { u8,    to_u8 }
-impl_num_cast! { u16,   to_u16 }
-impl_num_cast! { u32,   to_u32 }
-impl_num_cast! { u64,   to_u64 }
-impl_num_cast! { usize,  to_uint }
-impl_num_cast! { i8,    to_i8 }
-impl_num_cast! { i16,   to_i16 }
-impl_num_cast! { i32,   to_i32 }
-impl_num_cast! { i64,   to_i64 }
-impl_num_cast! { isize,   to_int }
-impl_num_cast! { f32,   to_f32 }
-impl_num_cast! { f64,   to_f64 }
-
 /// Used for representing the classification of floating point numbers
 #[derive(Copy, Clone, PartialEq, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -2604,93 +1238,22 @@ pub enum FpCategory {
 }
 
 /// A built-in floating point number.
-// FIXME(#5527): In a future version of Rust, many of these functions will
-//               become constants.
-//
-// FIXME(#8888): Several of these functions have a parameter named
-//               `unused_self`. Removing it requires #8888 to be fixed.
-#[unstable(feature = "core",
-           reason = "distribution of methods between core/std is unclear")]
 #[doc(hidden)]
-pub trait Float
-    : Copy + Clone
-    + NumCast
-    + PartialOrd
-    + PartialEq
-    + Neg<Output=Self>
-    + Add<Output=Self>
-    + Sub<Output=Self>
-    + Mul<Output=Self>
-    + Div<Output=Self>
-    + Rem<Output=Self>
-{
+pub trait Float {
     /// Returns the NaN value.
     fn nan() -> Self;
     /// Returns the infinite value.
     fn infinity() -> Self;
     /// Returns the negative infinite value.
     fn neg_infinity() -> Self;
-    /// Returns the `0` value.
-    fn zero() -> Self;
     /// Returns -0.0.
     fn neg_zero() -> Self;
-    /// Returns the `1` value.
+    /// Returns 0.0.
+    fn zero() -> Self;
+    /// Returns 1.0.
     fn one() -> Self;
-
-    // FIXME (#5527): These should be associated constants
-
-    /// Returns the number of binary digits of mantissa that this type supports.
-    #[unstable(feature = "core")]
-    #[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>) -> usize;
-    /// Returns the number of base-10 digits of precision that this type supports.
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0",
-                 reason = "use `std::f32::DIGITS` or `std::f64::DIGITS` as appropriate")]
-    fn digits(unused_self: Option<Self>) -> usize;
-    /// Returns the difference between 1.0 and the smallest representable number larger than 1.0.
-    #[unstable(feature = "core")]
-    #[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.
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0",
-                 reason = "use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` as appropriate")]
-    fn min_exp(unused_self: Option<Self>) -> isize;
-    /// Returns the maximum binary exponent that this type can represent.
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0",
-                 reason = "use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` as appropriate")]
-    fn max_exp(unused_self: Option<Self>) -> isize;
-    /// Returns the minimum base-10 exponent that this type can represent.
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0",
-                 reason = "use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` as appropriate")]
-    fn min_10_exp(unused_self: Option<Self>) -> isize;
-    /// Returns the maximum base-10 exponent that this type can represent.
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0",
-                 reason = "use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` as appropriate")]
-    fn max_10_exp(unused_self: Option<Self>) -> isize;
-    /// Returns the smallest finite value that this type can represent.
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0",
-                 reason = "use `std::f32::MIN` or `std::f64::MIN` as appropriate")]
-    fn min_value() -> Self;
-    /// Returns the smallest normalized positive number that this type can represent.
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0",
-                 reason = "use `std::f32::MIN_POSITIVE` or \
-                           `std::f64::MIN_POSITIVE` as appropriate")]
-    fn min_pos_value(unused_self: Option<Self>) -> Self;
-    /// Returns the largest finite value that this type can represent.
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0",
-                 reason = "use `std::f32::MAX` or `std::f64::MAX` as appropriate")]
-    fn max_value() -> Self;
+    /// Parses the string `s` with the radix `r` as a float.
+    fn from_str_radix(s: &str, r: u32) -> Result<Self, ParseFloatError>;
 
     /// Returns true if this value is NaN and false otherwise.
     fn is_nan(self) -> bool;
@@ -2707,16 +1270,16 @@ pub trait Float
     /// Returns the mantissa, exponent and sign as integers, respectively.
     fn integer_decode(self) -> (u64, i16, i8);
 
-    /// Returns the largest integer less than or equal to a number.
+    /// Return the largest integer less than or equal to a number.
     fn floor(self) -> Self;
-    /// Returns the smallest integer greater than or equal to a number.
+    /// Return the smallest integer greater than or equal to a number.
     fn ceil(self) -> Self;
-    /// Returns the nearest integer to a number. Round half-way cases away from
+    /// Return the nearest integer to a number. Round half-way cases away from
     /// `0.0`.
     fn round(self) -> Self;
-    /// Returns the integer part of a number.
+    /// Return the integer part of a number.
     fn trunc(self) -> Self;
-    /// Returns the fractional part of a number.
+    /// Return the fractional part of a number.
     fn fract(self) -> Self;
 
     /// Computes the absolute value of `self`. Returns `Float::nan()` if the
@@ -2739,21 +1302,21 @@ pub trait Float
     /// error. This produces a more accurate result with better performance than
     /// a separate multiplication operation followed by an add.
     fn mul_add(self, a: Self, b: Self) -> Self;
-    /// Takes the reciprocal (inverse) of a number, `1/x`.
+    /// Take the reciprocal (inverse) of a number, `1/x`.
     fn recip(self) -> Self;
 
-    /// Raises a number to an integer power.
+    /// Raise a number to an integer power.
     ///
     /// Using this function is generally faster than using `powf`
     fn powi(self, n: i32) -> Self;
-    /// Raises a number to a floating point power.
+    /// Raise a number to a floating point power.
     fn powf(self, n: Self) -> Self;
 
-    /// Takes the square root of a number.
+    /// Take the square root of a number.
     ///
     /// Returns NaN if `self` is a negative number.
     fn sqrt(self) -> Self;
-    /// Takes the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
+    /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
     fn rsqrt(self) -> Self;
 
     /// Returns `e^(self)`, (the exponential function).
@@ -2769,39 +1332,14 @@ pub trait Float
     /// Returns the base 10 logarithm of the number.
     fn log10(self) -> Self;
 
-    /// Converts radians to degrees.
+    /// Convert radians to degrees.
     fn to_degrees(self) -> Self;
-    /// Converts degrees to radians.
+    /// Convert degrees to radians.
     fn to_radians(self) -> Self;
 }
 
-/// A generic trait for converting a string with a radix (base) to a value
-#[unstable(feature = "core", reason = "needs reevaluation")]
-#[deprecated(since = "1.0.0",
-             reason = "moved to inherent methods; use e.g. i32::from_str_radix")]
-pub trait FromStrRadix {
-    #[unstable(feature = "core", reason = "needs reevaluation")]
-    #[deprecated(since = "1.0.0", reason = "moved to inherent methods")]
-    type Err;
-
-    #[unstable(feature = "core", reason = "needs reevaluation")]
-    #[deprecated(since = "1.0.0",
-                 reason = "moved to inherent methods; use e.g. i32::from_str_radix")]
-    #[allow(deprecated)]
-    fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::Err>;
-}
-
-/// A utility function that just calls `FromStrRadix::from_str_radix`.
-#[unstable(feature = "core", reason = "needs reevaluation")]
-#[deprecated(since = "1.0.0", reason = "use e.g. i32::from_str_radix")]
-#[allow(deprecated)]
-pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: u32)
-                                       -> Result<T, T::Err> {
-    FromStrRadix::from_str_radix(str, radix)
-}
-
-macro_rules! from_str_radix_float_impl {
-    ($T:ty) => {
+macro_rules! from_str_float_impl {
+    ($T:ident) => {
         #[stable(feature = "rust1", since = "1.0.0")]
         impl FromStr for $T {
             type Err = ParseFloatError;
@@ -2829,265 +1367,113 @@ impl FromStr for $T {
             ///
             /// # Return value
             ///
-            /// `Err(ParseFloatError)` if the string did not represent a valid number.
-            /// Otherwise, `Ok(n)` where `n` is the floating-point number represented by `src`.
+            /// `Err(ParseFloatError)` if the string did not represent a valid
+            /// number.  Otherwise, `Ok(n)` where `n` is the floating-point
+            /// number represented by `src`.
             #[inline]
             #[allow(deprecated)]
             fn from_str(src: &str) -> Result<$T, ParseFloatError> {
-                from_str_radix(src, 10)
-            }
-        }
-
-        #[stable(feature = "rust1", since = "1.0.0")]
-        #[allow(deprecated)]
-        impl FromStrRadix for $T {
-            type Err = ParseFloatError;
-
-            /// Converts a string in a given base to a float.
-            ///
-            /// Due to possible conflicts, this function does **not** accept
-            /// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
-            /// does it recognize exponents of any kind.
-            ///
-            /// Leading and trailing whitespace represent an error.
-            ///
-            /// # Arguments
-            ///
-            /// * src - A string
-            /// * radix - The base to use. Must lie in the range [2 .. 36]
-            ///
-            /// # Return value
-            ///
-            /// `Err(ParseFloatError)` if the string did not represent a valid number.
-            /// Otherwise, `Ok(n)` where `n` is the floating-point number represented by `src`.
-            fn from_str_radix(src: &str, radix: u32)
-                              -> Result<$T, ParseFloatError> {
-                use self::FloatErrorKind::*;
-                use self::ParseFloatError as PFE;
-                assert!(radix >= 2 && radix <= 36,
-                       "from_str_radix_float: must lie in the range `[2, 36]` - found {}",
-                       radix);
-
-                // Special values
-                match src {
-                    "inf"   => return Ok(Float::infinity()),
-                    "-inf"  => return Ok(Float::neg_infinity()),
-                    "NaN"   => return Ok(Float::nan()),
-                    _       => {},
-                }
-
-                let (is_positive, src) =  match src.slice_shift_char() {
-                    None             => return Err(PFE { kind: Empty }),
-                    Some(('-', ""))  => return Err(PFE { kind: Empty }),
-                    Some(('-', src)) => (false, src),
-                    Some((_, _))     => (true,  src),
-                };
-
-                // The significand to accumulate
-                let mut sig = if is_positive { 0.0 } else { -0.0 };
-                // Necessary to detect overflow
-                let mut prev_sig = sig;
-                let mut cs = src.chars().enumerate();
-                // Exponent prefix and exponent index offset
-                let mut exp_info = None::<(char, usize)>;
-
-                // Parse the integer part of the significand
-                for (i, c) in cs.by_ref() {
-                    match c.to_digit(radix) {
-                        Some(digit) => {
-                            // shift significand one digit left
-                            sig = sig * (radix as $T);
-
-                            // add/subtract current digit depending on sign
-                            if is_positive {
-                                sig = sig + ((digit as isize) as $T);
-                            } else {
-                                sig = sig - ((digit as isize) as $T);
-                            }
-
-                            // Detect overflow by comparing to last value, except
-                            // if we've not seen any non-zero digits.
-                            if prev_sig != 0.0 {
-                                if is_positive && sig <= prev_sig
-                                    { return Ok(Float::infinity()); }
-                                if !is_positive && sig >= prev_sig
-                                    { return Ok(Float::neg_infinity()); }
-
-                                // Detect overflow by reversing the shift-and-add process
-                                if is_positive && (prev_sig != (sig - digit as $T) / radix as $T)
-                                    { return Ok(Float::infinity()); }
-                                if !is_positive && (prev_sig != (sig + digit as $T) / radix as $T)
-                                    { return Ok(Float::neg_infinity()); }
-                            }
-                            prev_sig = sig;
-                        },
-                        None => match c {
-                            'e' | 'E' | 'p' | 'P' => {
-                                exp_info = Some((c, i + 1));
-                                break;  // start of exponent
-                            },
-                            '.' => {
-                                break;  // start of fractional part
-                            },
-                            _ => {
-                                return Err(PFE { kind: Invalid });
-                            },
-                        },
-                    }
-                }
-
-                // If we are not yet at the exponent parse the fractional
-                // part of the significand
-                if exp_info.is_none() {
-                    let mut power = 1.0;
-                    for (i, c) in cs.by_ref() {
-                        match c.to_digit(radix) {
-                            Some(digit) => {
-                                // Decrease power one order of magnitude
-                                power = power / (radix as $T);
-                                // add/subtract current digit depending on sign
-                                sig = if is_positive {
-                                    sig + (digit as $T) * power
-                                } else {
-                                    sig - (digit as $T) * power
-                                };
-                                // Detect overflow by comparing to last value
-                                if is_positive && sig < prev_sig
-                                    { return Ok(Float::infinity()); }
-                                if !is_positive && sig > prev_sig
-                                    { return Ok(Float::neg_infinity()); }
-                                prev_sig = sig;
-                            },
-                            None => match c {
-                                'e' | 'E' | 'p' | 'P' => {
-                                    exp_info = Some((c, i + 1));
-                                    break; // start of exponent
-                                },
-                                _ => {
-                                    return Err(PFE { kind: Invalid });
-                                },
-                            },
-                        }
-                    }
-                }
-
-                // Parse and calculate the exponent
-                let exp = match exp_info {
-                    Some((c, offset)) => {
-                        let base = match c {
-                            'E' | 'e' if radix == 10 => 10.0,
-                            'P' | 'p' if radix == 16 => 2.0,
-                            _ => return Err(PFE { kind: Invalid }),
-                        };
-
-                        // Parse the exponent as decimal integer
-                        let src = &src[offset..];
-                        let (is_positive, exp) = match src.slice_shift_char() {
-                            Some(('-', src)) => (false, src.parse::<usize>()),
-                            Some(('+', src)) => (true,  src.parse::<usize>()),
-                            Some((_, _))     => (true,  src.parse::<usize>()),
-                            None             => return Err(PFE { kind: Invalid }),
-                        };
-
-                        match (is_positive, exp) {
-                            (true,  Ok(exp)) => base.powi(exp as i32),
-                            (false, Ok(exp)) => 1.0 / base.powi(exp as i32),
-                            (_, Err(_))      => return Err(PFE { kind: Invalid }),
-                        }
-                    },
-                    None => 1.0, // no exponent
-                };
-
-                Ok(sig * exp)
+                $T::from_str_radix(src, 10)
             }
         }
     }
 }
-from_str_radix_float_impl! { f32 }
-from_str_radix_float_impl! { f64 }
+from_str_float_impl!(f32);
+from_str_float_impl!(f64);
 
 macro_rules! from_str_radix_int_impl {
-    ($T:ty) => {
+    ($($T:ident)*) => {$(
         #[stable(feature = "rust1", since = "1.0.0")]
         #[allow(deprecated)]
         impl FromStr for $T {
             type Err = ParseIntError;
-            #[inline]
             fn from_str(src: &str) -> Result<$T, ParseIntError> {
                 from_str_radix(src, 10)
             }
         }
+    )*}
+}
+from_str_radix_int_impl! { isize i8 i16 i32 i64 usize u8 u16 u32 u64 }
 
-        #[stable(feature = "rust1", since = "1.0.0")]
-        #[allow(deprecated)]
-        impl FromStrRadix for $T {
-            type Err = ParseIntError;
-            fn from_str_radix(src: &str, radix: u32)
-                              -> Result<$T, ParseIntError> {
-                use self::IntErrorKind::*;
-                use self::ParseIntError as PIE;
-                assert!(radix >= 2 && radix <= 36,
-                       "from_str_radix_int: must lie in the range `[2, 36]` - found {}",
-                       radix);
-
-                let is_signed_ty = (0 as $T) > Int::min_value();
-
-                match src.slice_shift_char() {
-                    Some(('-', "")) => Err(PIE { kind: Empty }),
-                    Some(('-', src)) if is_signed_ty => {
-                        // The number is negative
-                        let mut result = 0;
-                        for c in src.chars() {
-                            let x = match c.to_digit(radix) {
-                                Some(x) => x,
-                                None => return Err(PIE { kind: InvalidDigit }),
-                            };
-                            result = match result.checked_mul(radix as $T) {
-                                Some(result) => result,
-                                None => return Err(PIE { kind: Underflow }),
-                            };
-                            result = match result.checked_sub(x as $T) {
-                                Some(result) => result,
-                                None => return Err(PIE { kind: Underflow }),
-                            };
-                        }
-                        Ok(result)
-                    },
-                    Some((_, _)) => {
-                        // The number is signed
-                        let mut result = 0;
-                        for c in src.chars() {
-                            let x = match c.to_digit(radix) {
-                                Some(x) => x,
-                                None => return Err(PIE { kind: InvalidDigit }),
-                            };
-                            result = match result.checked_mul(radix as $T) {
-                                Some(result) => result,
-                                None => return Err(PIE { kind: Overflow }),
-                            };
-                            result = match result.checked_add(x as $T) {
-                                Some(result) => result,
-                                None => return Err(PIE { kind: Overflow }),
-                            };
-                        }
-                        Ok(result)
-                    },
-                    None => Err(ParseIntError { kind: Empty }),
-                }
+#[doc(hidden)]
+trait FromStrRadixHelper: PartialOrd + Copy {
+    fn min_value() -> Self;
+    fn from_u32(u: u32) -> Self;
+    fn checked_mul(&self, other: u32) -> Option<Self>;
+    fn checked_sub(&self, other: u32) -> Option<Self>;
+    fn checked_add(&self, other: u32) -> Option<Self>;
+}
+
+macro_rules! doit {
+    ($($t:ident)*) => ($(impl FromStrRadixHelper for $t {
+        fn min_value() -> Self { <$t>::min_value() }
+        fn from_u32(u: u32) -> Self { u as $t }
+        fn checked_mul(&self, other: u32) -> Option<Self> {
+            <$t>::checked_mul(*self, other as $t)
+        }
+        fn checked_sub(&self, other: u32) -> Option<Self> {
+            <$t>::checked_sub(*self, other as $t)
+        }
+        fn checked_add(&self, other: u32) -> Option<Self> {
+            <$t>::checked_add(*self, other as $t)
+        }
+    })*)
+}
+doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
+
+fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32)
+                                         -> Result<T, ParseIntError> {
+    use self::IntErrorKind::*;
+    use self::ParseIntError as PIE;
+    assert!(radix >= 2 && radix <= 36,
+           "from_str_radix_int: must lie in the range `[2, 36]` - found {}",
+           radix);
+
+    let is_signed_ty = T::from_u32(0) > T::min_value();
+
+    match src.slice_shift_char() {
+        Some(('-', "")) => Err(PIE { kind: Empty }),
+        Some(('-', src)) if is_signed_ty => {
+            // The number is negative
+            let mut result = T::from_u32(0);
+            for c in src.chars() {
+                let x = match c.to_digit(radix) {
+                    Some(x) => x,
+                    None => return Err(PIE { kind: InvalidDigit }),
+                };
+                result = match result.checked_mul(radix) {
+                    Some(result) => result,
+                    None => return Err(PIE { kind: Underflow }),
+                };
+                result = match result.checked_sub(x) {
+                    Some(result) => result,
+                    None => return Err(PIE { kind: Underflow }),
+                };
             }
-        }
+            Ok(result)
+        },
+        Some((_, _)) => {
+            // The number is signed
+            let mut result = T::from_u32(0);
+            for c in src.chars() {
+                let x = match c.to_digit(radix) {
+                    Some(x) => x,
+                    None => return Err(PIE { kind: InvalidDigit }),
+                };
+                result = match result.checked_mul(radix) {
+                    Some(result) => result,
+                    None => return Err(PIE { kind: Overflow }),
+                };
+                result = match result.checked_add(x) {
+                    Some(result) => result,
+                    None => return Err(PIE { kind: Overflow }),
+                };
+            }
+            Ok(result)
+        },
+        None => Err(ParseIntError { kind: Empty }),
     }
 }
-from_str_radix_int_impl! { isize }
-from_str_radix_int_impl! { i8 }
-from_str_radix_int_impl! { i16 }
-from_str_radix_int_impl! { i32 }
-from_str_radix_int_impl! { i64 }
-from_str_radix_int_impl! { usize }
-from_str_radix_int_impl! { u8 }
-from_str_radix_int_impl! { u16 }
-from_str_radix_int_impl! { u32 }
-from_str_radix_int_impl! { u64 }
 
 /// An error which can be returned when parsing an integer.
 #[derive(Debug, Clone, PartialEq)]
@@ -3123,11 +1509,10 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 /// An error which can be returned when parsing a float.
 #[derive(Debug, Clone, PartialEq)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct ParseFloatError { kind: FloatErrorKind }
+pub struct ParseFloatError { pub kind: FloatErrorKind }
 
 #[derive(Debug, Clone, PartialEq)]
-enum FloatErrorKind {
+pub enum FloatErrorKind {
     Empty,
     Invalid,
 }
index aa84708816b8717b2eb8d035783eb01a37296721..b7ca497db18637bcd0d1d83a9c1d945a550b5b24 100644 (file)
@@ -15,8 +15,6 @@
 
 use ops::*;
 
-use intrinsics::{overflowing_add, overflowing_sub, overflowing_mul};
-
 use intrinsics::{i8_add_with_overflow, u8_add_with_overflow};
 use intrinsics::{i16_add_with_overflow, u16_add_with_overflow};
 use intrinsics::{i32_add_with_overflow, u32_add_with_overflow};
 
 use ::{i8,i16,i32,i64};
 
-#[unstable(feature = "core", reason = "may be removed, renamed, or relocated")]
-#[deprecated(since = "1.0.0", reason = "moved to inherent methods")]
-pub trait WrappingOps {
-    fn wrapping_add(self, rhs: Self) -> Self;
-    fn wrapping_sub(self, rhs: Self) -> Self;
-    fn wrapping_mul(self, rhs: Self) -> Self;
-}
-
 #[unstable(feature = "core", reason = "may be removed, renamed, or relocated")]
 pub trait OverflowingOps {
     fn overflowing_add(self, rhs: Self) -> (Self, bool);
@@ -99,27 +89,6 @@ macro_rules! sh_impl_all {
 
 macro_rules! wrapping_impl {
     ($($t:ty)*) => ($(
-        impl WrappingOps for $t {
-            #[inline(always)]
-            fn wrapping_add(self, rhs: $t) -> $t {
-                unsafe {
-                    overflowing_add(self, rhs)
-                }
-            }
-            #[inline(always)]
-            fn wrapping_sub(self, rhs: $t) -> $t {
-                unsafe {
-                    overflowing_sub(self, rhs)
-                }
-            }
-            #[inline(always)]
-            fn wrapping_mul(self, rhs: $t) -> $t {
-                unsafe {
-                    overflowing_mul(self, rhs)
-                }
-            }
-        }
-
         #[stable(feature = "rust1", since = "1.0.0")]
         impl Add for Wrapping<$t> {
             type Output = Wrapping<$t>;
index 4c784a579da6b004f83b8f6616b56046f0546181..d1bc24bd9baa5d433906b708c25986302c7c81f4 100644 (file)
@@ -551,25 +551,6 @@ pub fn iter_mut(&mut self) -> IterMut<T> {
         IterMut { inner: Item { opt: self.as_mut() } }
     }
 
-    /// Returns a consuming iterator over the possibly contained value.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let x = Some("string");
-    /// let v: Vec<&str> = x.into_iter().collect();
-    /// assert_eq!(v, ["string"]);
-    ///
-    /// let x = None;
-    /// let v: Vec<&str> = x.into_iter().collect();
-    /// assert!(v.is_empty());
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_iter(self) -> IntoIter<T> {
-        IntoIter { inner: Item { opt: self } }
-    }
-
     /////////////////////////////////////////////////////////////////////////
     // Boolean operations on the values, eager and lazy
     /////////////////////////////////////////////////////////////////////////
@@ -770,6 +751,30 @@ impl<T> Default for Option<T> {
     fn default() -> Option<T> { None }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> IntoIterator for Option<T> {
+    type Item = T;
+    type IntoIter = IntoIter<T>;
+
+    /// Returns a consuming iterator over the possibly contained value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let x = Some("string");
+    /// let v: Vec<&str> = x.into_iter().collect();
+    /// assert_eq!(v, ["string"]);
+    ///
+    /// let x = None;
+    /// let v: Vec<&str> = x.into_iter().collect();
+    /// assert!(v.is_empty());
+    /// ```
+    #[inline]
+    fn into_iter(self) -> IntoIter<T> {
+        IntoIter { inner: Item { opt: self } }
+    }
+}
+
 /////////////////////////////////////////////////////////////////////////////
 // The Option Iterators
 /////////////////////////////////////////////////////////////////////////////
index e60bc49408195644c331d56e35926db606000bb0..a4d529ad47d09036fe32366fd9bd3150db89f4a6 100644 (file)
 pub use clone::Clone;
 pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
 pub use convert::{AsRef, AsMut, Into, From};
+pub use default::Default;
+pub use iter::IntoIterator;
 pub use iter::{Iterator, DoubleEndedIterator, Extend, ExactSizeIterator};
 pub use option::Option::{self, Some, None};
 pub use result::Result::{self, Ok, Err};
 pub use slice::SliceExt;
 pub use str::StrExt;
-
-#[allow(deprecated)] pub use slice::AsSlice;
-#[allow(deprecated)] pub use str::Str;
index 685b3e5c546ddfb097edbf553ed2ae9e0e14a473..ec84ef7986a43b8b8c327954174c566ee6a90548 100644 (file)
@@ -80,7 +80,7 @@ fn clone(&self) -> Slice<T> { *self }
 /// `TraitObject` is guaranteed to match layouts, but it is not the
 /// type of trait objects (e.g. the fields are not directly accessible
 /// on a `&SomeTrait`) nor does it control that layout (changing the
-/// definition will not change the layout of a `&SometTrait`). It is
+/// definition will not change the layout of a `&SomeTrait`). It is
 /// only designed to be used by unsafe code that needs to manipulate
 /// the low-level details.
 ///
index 03894926293af58496255365438cd588d2d9760e..e909946ece40221ffa548666aed832ce44b2e9fd 100644 (file)
 use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSizeIterator, IntoIterator};
 use ops::{FnMut, FnOnce};
 use option::Option::{self, None, Some};
-#[allow(deprecated)]
-use slice::AsSlice;
 use slice;
 
 /// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
@@ -547,25 +545,6 @@ pub fn iter_mut(&mut self) -> IterMut<T> {
         IterMut { inner: self.as_mut().ok() }
     }
 
-    /// Returns a consuming iterator over the possibly contained value.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let x: Result<u32, &str> = Ok(5);
-    /// let v: Vec<u32> = x.into_iter().collect();
-    /// assert_eq!(v, [5]);
-    ///
-    /// let x: Result<u32, &str> = Err("nothing!");
-    /// let v: Vec<u32> = x.into_iter().collect();
-    /// assert_eq!(v, []);
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_iter(self) -> IntoIter<T> {
-        IntoIter { inner: self.ok() }
-    }
-
     ////////////////////////////////////////////////////////////////////////
     // Boolean operations on the values, eager and lazy
     /////////////////////////////////////////////////////////////////////////
@@ -787,23 +766,27 @@ pub fn unwrap_err(self) -> E {
 // Trait implementations
 /////////////////////////////////////////////////////////////////////////////
 
-#[unstable(feature = "core",
-           reason = "waiting on the stability of the trait itself")]
-#[deprecated(since = "1.0.0",
-             reason = "use inherent method instead")]
-#[allow(deprecated)]
-impl<T, E> AsSlice<T> for Result<T, E> {
-    /// Converts from `Result<T, E>` to `&[T]` (without copying)
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T, E> IntoIterator for Result<T, E> {
+    type Item = T;
+    type IntoIter = IntoIter<T>;
+
+    /// Returns a consuming iterator over the possibly contained value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let x: Result<u32, &str> = Ok(5);
+    /// let v: Vec<u32> = x.into_iter().collect();
+    /// assert_eq!(v, [5]);
+    ///
+    /// let x: Result<u32, &str> = Err("nothing!");
+    /// let v: Vec<u32> = x.into_iter().collect();
+    /// assert_eq!(v, []);
+    /// ```
     #[inline]
-    fn as_slice<'a>(&'a self) -> &'a [T] {
-        match *self {
-            Ok(ref x) => slice::ref_slice(x),
-            Err(_) => {
-                // work around lack of implicit coercion from fixed-size array to slice
-                let emp: &[_] = &[];
-                emp
-            }
-        }
+    fn into_iter(self) -> IntoIter<T> {
+        IntoIter { inner: self.ok() }
     }
 }
 
index 4b1742a43482a216772721537c07189b952dc4bb..1e96d761d405a948e3db12b02f4f45f18ca27c19 100644 (file)
@@ -51,7 +51,7 @@
 use ptr;
 use mem;
 use mem::size_of;
-use marker::{Send, Sized, Sync, self};
+use marker::{Send, Sync, self};
 use raw::Repr;
 // Avoid conflicts with *both* the Slice trait (buggy) and the `slice::raw` module.
 use raw::Slice as RawSlice;
@@ -595,37 +595,6 @@ fn index_mut(&mut self, _index: RangeFull) -> &mut [T] {
 // Common traits
 ////////////////////////////////////////////////////////////////////////////////
 
-/// Data that is viewable as a slice.
-#[unstable(feature = "core",
-           reason = "will be replaced by slice syntax")]
-#[deprecated(since = "1.0.0",
-             reason = "use std::convert::AsRef<[T]> instead")]
-pub trait AsSlice<T> {
-    /// Work with `self` as a slice.
-    fn as_slice<'a>(&'a self) -> &'a [T];
-}
-
-#[unstable(feature = "core", reason = "trait is experimental")]
-#[allow(deprecated)]
-impl<T> AsSlice<T> for [T] {
-    #[inline(always)]
-    fn as_slice<'a>(&'a self) -> &'a [T] { self }
-}
-
-#[unstable(feature = "core", reason = "trait is experimental")]
-#[allow(deprecated)]
-impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a U {
-    #[inline(always)]
-    fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) }
-}
-
-#[unstable(feature = "core", reason = "trait is experimental")]
-#[allow(deprecated)]
-impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a mut U {
-    #[inline(always)]
-    fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Default for &'a [T] {
     #[stable(feature = "rust1", since = "1.0.0")]
index 2d6ef39361e8ad5011f67525f0ae4f5bb20ff40b..4d343ea0f1e42c37712371a6b2fc47a70d72d93b 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15679
 
 //! String manipulation
 //!
@@ -27,7 +25,6 @@
 use fmt;
 use iter::ExactSizeIterator;
 use iter::{Map, Iterator, DoubleEndedIterator};
-use marker::Sized;
 use mem;
 use ops::{Fn, FnMut, FnOnce};
 use option::Option::{self, None, Some};
@@ -341,7 +338,7 @@ fn next_back(&mut self) -> Option<(usize, char)> {
 /// External iterator for a string's bytes.
 /// Use with the `std::iter` module.
 ///
-/// Created with `str::bytes`
+/// Created with the method `.bytes()`.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct Bytes<'a>(Map<slice::Iter<'a, u8>, BytesDeref>);
@@ -636,10 +633,10 @@ fn next_back(&mut self) -> Option<&'a str>
 
 generate_pattern_iterators! {
     forward:
-        /// Return type of `str::split()`
+        /// Created with the method `.split()`.
         struct Split;
     reverse:
-        /// Return type of `str::rsplit()`
+        /// Created with the method `.rsplit()`.
         struct RSplit;
     stability:
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -650,10 +647,10 @@ fn next_back(&mut self) -> Option<&'a str>
 
 generate_pattern_iterators! {
     forward:
-        /// Return type of `str::split_terminator()`
+        /// Created with the method `.split_terminator()`.
         struct SplitTerminator;
     reverse:
-        /// Return type of `str::rsplit_terminator()`
+        /// Created with the method `.rsplit_terminator()`.
         struct RSplitTerminator;
     stability:
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -696,10 +693,10 @@ fn next_back(&mut self) -> Option<&'a str>
 
 generate_pattern_iterators! {
     forward:
-        /// Return type of `str::splitn()`
+        /// Created with the method `.splitn()`.
         struct SplitN;
     reverse:
-        /// Return type of `str::rsplitn()`
+        /// Created with the method `.rsplitn()`.
         struct RSplitN;
     stability:
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -730,10 +727,10 @@ fn next_back(&mut self) -> Option<(usize, usize)>
 
 generate_pattern_iterators! {
     forward:
-        /// Return type of `str::match_indices()`
+        /// Created with the method `.match_indices()`.
         struct MatchIndices;
     reverse:
-        /// Return type of `str::rmatch_indices()`
+        /// Created with the method `.rmatch_indices()`.
         struct RMatchIndices;
     stability:
         #[unstable(feature = "core",
@@ -771,10 +768,10 @@ fn next_back(&mut self) -> Option<&'a str>
 
 generate_pattern_iterators! {
     forward:
-        /// Return type of `str::matches()`
+        /// Created with the method `.matches()`.
         struct Matches;
     reverse:
-        /// Return type of `str::rmatches()`
+        /// Created with the method `.rmatches()`.
         struct RMatches;
     stability:
         #[unstable(feature = "core", reason = "type got recently added")]
@@ -783,7 +780,7 @@ fn next_back(&mut self) -> Option<&'a str>
     delegate double ended;
 }
 
-/// Return type of `str::lines()`
+/// Created with the method `.lines()`.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct Lines<'a>(SplitTerminator<'a, char>);
@@ -811,7 +808,7 @@ fn next_back(&mut self) -> Option<&'a str> {
     }
 }
 
-/// Return type of `str::lines_any()`
+/// Created with the method `.lines_any()`.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct LinesAny<'a>(Map<Lines<'a>, LinesAnyMap>);
@@ -1465,30 +1462,6 @@ fn index(&self, _index: ops::RangeFull) -> &str {
     }
 }
 
-/// Any string that can be represented as a slice
-#[unstable(feature = "core",
-           reason = "Instead of taking this bound generically, this trait will be \
-                     replaced with one of slicing syntax (&foo[..]), deref coercions, or \
-                     a more generic conversion trait")]
-#[deprecated(since = "1.0.0",
-             reason = "use std::convert::AsRef<str> instead")]
-pub trait Str {
-    /// Work with `self` as a slice.
-    fn as_slice<'a>(&'a self) -> &'a str;
-}
-
-#[allow(deprecated)]
-impl Str for str {
-    #[inline]
-    fn as_slice<'a>(&'a self) -> &'a str { self }
-}
-
-#[allow(deprecated)]
-impl<'a, S: ?Sized> Str for &'a S where S: Str {
-    #[inline]
-    fn as_slice(&self) -> &str { Str::as_slice(*self) }
-}
-
 /// Methods for string slices
 #[allow(missing_docs)]
 #[doc(hidden)]
index 4939277aa59bcbe017ded0508c1b08e8fd73dfea..b73807aa317588a7500309bc87b2d8912990875a 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15679
 
 #[test]
 fn test_is_lowercase() {
index 9ed1508c3eb7877c23b0831682569562ddea5a5f..e0d396c68b4c4847cb572580b497066de3a00689 100644 (file)
@@ -110,8 +110,6 @@ fn test_partial_max() {
 
 #[test]
 fn test_user_defined_eq() {
-    use core::num::SignedInt;
-
     // Our type.
     struct SketchyNum {
         num : isize
index a56820c61ccbb061adfc1a264465114707c6993d..2866c193c3b1546a99f10736c0f4d11bade8343a 100644 (file)
@@ -11,7 +11,6 @@
 use core::iter::*;
 use core::iter::order::*;
 use core::iter::MinMaxResult::*;
-use core::num::SignedInt;
 use core::usize;
 use core::cmp;
 
@@ -783,16 +782,6 @@ fn test_range_step() {
     assert_eq!((200..200).step_by(1).collect::<Vec<isize>>(), []);
 }
 
-#[test]
-fn test_range_step_inclusive() {
-    assert_eq!(range_step_inclusive(0, 20, 5).collect::<Vec<isize>>(), [0, 5, 10, 15, 20]);
-    assert_eq!(range_step_inclusive(20, 0, -5).collect::<Vec<isize>>(), [20, 15, 10, 5, 0]);
-    assert_eq!(range_step_inclusive(20, 0, -6).collect::<Vec<isize>>(), [20, 14, 8, 2]);
-    assert_eq!(range_step_inclusive(200, 255, 50).collect::<Vec<u8>>(), [200, 250]);
-    assert_eq!(range_step_inclusive(200, -5, 1).collect::<Vec<isize>>(), []);
-    assert_eq!(range_step_inclusive(200, 200, 1).collect::<Vec<isize>>(), [200]);
-}
-
 #[test]
 fn test_reverse() {
     let mut ys = [1, 2, 3, 4, 5];
index 6059e49df197adbccfeca67beeb6fd5e67d3035b..e0e8e46af6cdde2a241b352e7d427013866a9ce9 100644 (file)
@@ -10,8 +10,8 @@
 
 // Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
 #![cfg_attr(stage0, feature(custom_attribute))]
+
 #![feature(box_syntax)]
-#![feature(int_uint)]
 #![feature(unboxed_closures)]
 #![feature(unsafe_destructor)]
 #![feature(core)]
 #![feature(std_misc)]
 #![feature(libc)]
 #![feature(hash)]
-#![feature(io)]
-#![feature(collections)]
 #![feature(debug_builders)]
 #![feature(unique)]
 #![feature(step_by)]
 #![feature(slice_patterns)]
-#![allow(deprecated)] // rand
+#![feature(float_from_str_radix)]
 
 extern crate core;
 extern crate test;
index cb2359873e9dc59ef8e19f09726c6647c1d6fc1e..b1c8aec3c35e9798b9e30e030001b16e4139ee17 100644 (file)
@@ -8,12 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-macro_rules! int_module { ($T:ty, $T_i:ident) => (
+macro_rules! int_module { ($T:ident, $T_i:ident) => (
 #[cfg(test)]
 mod tests {
     use core::$T_i::*;
     use core::isize;
-    use core::num::{FromStrRadix, Int, SignedInt};
     use core::ops::{Shl, Shr, Not, BitXor, BitAnd, BitOr};
     use num;
 
@@ -129,30 +128,30 @@ fn test_swap_bytes() {
 
     #[test]
     fn test_le() {
-        assert_eq!(Int::from_le(A.to_le()), A);
-        assert_eq!(Int::from_le(B.to_le()), B);
-        assert_eq!(Int::from_le(C.to_le()), C);
-        assert_eq!(Int::from_le(_0), _0);
-        assert_eq!(Int::from_le(_1), _1);
+        assert_eq!($T::from_le(A.to_le()), A);
+        assert_eq!($T::from_le(B.to_le()), B);
+        assert_eq!($T::from_le(C.to_le()), C);
+        assert_eq!($T::from_le(_0), _0);
+        assert_eq!($T::from_le(_1), _1);
         assert_eq!(_0.to_le(), _0);
         assert_eq!(_1.to_le(), _1);
     }
 
     #[test]
     fn test_be() {
-        assert_eq!(Int::from_be(A.to_be()), A);
-        assert_eq!(Int::from_be(B.to_be()), B);
-        assert_eq!(Int::from_be(C.to_be()), C);
-        assert_eq!(Int::from_be(_0), _0);
-        assert_eq!(Int::from_be(_1), _1);
+        assert_eq!($T::from_be(A.to_be()), A);
+        assert_eq!($T::from_be(B.to_be()), B);
+        assert_eq!($T::from_be(C.to_be()), C);
+        assert_eq!($T::from_be(_0), _0);
+        assert_eq!($T::from_be(_1), _1);
         assert_eq!(_0.to_be(), _0);
         assert_eq!(_1.to_be(), _1);
     }
 
     #[test]
     fn test_signed_checked_div() {
-        assert!(10.checked_div(2) == Some(5));
-        assert!(5.checked_div(0) == None);
+        assert!((10 as $T).checked_div(2) == Some(5));
+        assert!((5 as $T).checked_div(0) == None);
         assert!(isize::MIN.checked_div(-1) == None);
     }
 
@@ -180,26 +179,26 @@ fn from_str<T: ::std::str::FromStr>(t: &str) -> Option<T> {
 
     #[test]
     fn test_from_str_radix() {
-        assert_eq!(FromStrRadix::from_str_radix("123", 10), Ok(123 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("1001", 2), Ok(9 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("123", 8), Ok(83 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("123", 16), Ok(291 as i32));
-        assert_eq!(FromStrRadix::from_str_radix("ffff", 16), Ok(65535 as i32));
-        assert_eq!(FromStrRadix::from_str_radix("FFFF", 16), Ok(65535 as i32));
-        assert_eq!(FromStrRadix::from_str_radix("z", 36), Ok(35 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("Z", 36), Ok(35 as $T));
-
-        assert_eq!(FromStrRadix::from_str_radix("-123", 10), Ok(-123 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("-1001", 2), Ok(-9 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("-123", 8), Ok(-83 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("-123", 16), Ok(-291 as i32));
-        assert_eq!(FromStrRadix::from_str_radix("-ffff", 16), Ok(-65535 as i32));
-        assert_eq!(FromStrRadix::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
-        assert_eq!(FromStrRadix::from_str_radix("-z", 36), Ok(-35 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("-Z", 36), Ok(-35 as $T));
-
-        assert_eq!(FromStrRadix::from_str_radix("Z", 35).ok(), None::<$T>);
-        assert_eq!(FromStrRadix::from_str_radix("-9", 2).ok(), None::<$T>);
+        assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
+        assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
+        assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
+        assert_eq!(i32::from_str_radix("123", 16), Ok(291 as i32));
+        assert_eq!(i32::from_str_radix("ffff", 16), Ok(65535 as i32));
+        assert_eq!(i32::from_str_radix("FFFF", 16), Ok(65535 as i32));
+        assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
+        assert_eq!($T::from_str_radix("Z", 36), Ok(35 as $T));
+
+        assert_eq!($T::from_str_radix("-123", 10), Ok(-123 as $T));
+        assert_eq!($T::from_str_radix("-1001", 2), Ok(-9 as $T));
+        assert_eq!($T::from_str_radix("-123", 8), Ok(-83 as $T));
+        assert_eq!(i32::from_str_radix("-123", 16), Ok(-291 as i32));
+        assert_eq!(i32::from_str_radix("-ffff", 16), Ok(-65535 as i32));
+        assert_eq!(i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
+        assert_eq!($T::from_str_radix("-z", 36), Ok(-35 as $T));
+        assert_eq!($T::from_str_radix("-Z", 36), Ok(-35 as $T));
+
+        assert_eq!($T::from_str_radix("Z", 35).ok(), None::<$T>);
+        assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>);
     }
 
     #[test]
index 9087b87f640cb77519b19df956e97e8f0cc285ea..0ea9f8afb4e532c140a89d882beaf68b59da42d3 100644 (file)
@@ -10,7 +10,6 @@
 
 use core::cmp::PartialEq;
 use core::fmt::Debug;
-use core::num::{NumCast, cast};
 use core::ops::{Add, Sub, Mul, Div, Rem};
 use core::marker::Copy;
 
 
 /// Helper function for testing numeric operations
 pub fn test_num<T>(ten: T, two: T) where
-    T: PartialEq + NumCast
+    T: PartialEq
      + Add<Output=T> + Sub<Output=T>
      + Mul<Output=T> + Div<Output=T>
      + Rem<Output=T> + Debug
      + Copy
 {
-    assert_eq!(ten.add(two),  cast(12).unwrap());
-    assert_eq!(ten.sub(two),  cast(8).unwrap());
-    assert_eq!(ten.mul(two),  cast(20).unwrap());
-    assert_eq!(ten.div(two),  cast(5).unwrap());
-    assert_eq!(ten.rem(two),  cast(0).unwrap());
-
     assert_eq!(ten.add(two),  ten + two);
     assert_eq!(ten.sub(two),  ten - two);
     assert_eq!(ten.mul(two),  ten * two);
@@ -52,37 +45,37 @@ pub fn test_num<T>(ten: T, two: T) where
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use core::option::Option;
     use core::option::Option::{Some, None};
     use core::num::Float;
-    use core::num::from_str_radix;
 
     #[test]
     fn from_str_issue7588() {
-        let u : Option<u8> = from_str_radix("1000", 10).ok();
+        let u : Option<u8> = u8::from_str_radix("1000", 10).ok();
         assert_eq!(u, None);
-        let s : Option<i16> = from_str_radix("80000", 10).ok();
+        let s : Option<i16> = i16::from_str_radix("80000", 10).ok();
         assert_eq!(s, None);
-        let f : Option<f32> = from_str_radix("10000000000000000000000000000000000000000", 10).ok();
+        let s = "10000000000000000000000000000000000000000";
+        let f : Option<f32> = f32::from_str_radix(s, 10).ok();
         assert_eq!(f, Some(Float::infinity()));
-        let fe : Option<f32> = from_str_radix("1e40", 10).ok();
+        let fe : Option<f32> = f32::from_str_radix("1e40", 10).ok();
         assert_eq!(fe, Some(Float::infinity()));
     }
 
     #[test]
     fn test_from_str_radix_float() {
-        let x1 : Option<f64> = from_str_radix("-123.456", 10).ok();
+        let x1 : Option<f64> = f64::from_str_radix("-123.456", 10).ok();
         assert_eq!(x1, Some(-123.456));
-        let x2 : Option<f32> = from_str_radix("123.456", 10).ok();
+        let x2 : Option<f32> = f32::from_str_radix("123.456", 10).ok();
         assert_eq!(x2, Some(123.456));
-        let x3 : Option<f32> = from_str_radix("-0.0", 10).ok();
+        let x3 : Option<f32> = f32::from_str_radix("-0.0", 10).ok();
         assert_eq!(x3, Some(-0.0));
-        let x4 : Option<f32> = from_str_radix("0.0", 10).ok();
+        let x4 : Option<f32> = f32::from_str_radix("0.0", 10).ok();
         assert_eq!(x4, Some(0.0));
-        let x4 : Option<f32> = from_str_radix("1.0", 10).ok();
+        let x4 : Option<f32> = f32::from_str_radix("1.0", 10).ok();
         assert_eq!(x4, Some(1.0));
-        let x5 : Option<f32> = from_str_radix("-1.0", 10).ok();
+        let x5 : Option<f32> = f32::from_str_radix("-1.0", 10).ok();
         assert_eq!(x5, Some(-1.0));
     }
 
index 5e00692766d90aa052029f70b013e444f12426df..1712345f9d9a7c8316b04f1e8e85e3980873a0fd 100644 (file)
@@ -8,11 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-macro_rules! uint_module { ($T:ty, $T_i:ident) => (
+macro_rules! uint_module { ($T:ident, $T_i:ident) => (
 #[cfg(test)]
 mod tests {
     use core::$T_i::*;
-    use core::num::Int;
     use num;
     use core::ops::{BitOr, BitAnd, BitXor, Shl, Shr, Not};
 
@@ -97,30 +96,30 @@ fn test_swap_bytes() {
 
     #[test]
     fn test_le() {
-        assert_eq!(Int::from_le(A.to_le()), A);
-        assert_eq!(Int::from_le(B.to_le()), B);
-        assert_eq!(Int::from_le(C.to_le()), C);
-        assert_eq!(Int::from_le(_0), _0);
-        assert_eq!(Int::from_le(_1), _1);
+        assert_eq!($T::from_le(A.to_le()), A);
+        assert_eq!($T::from_le(B.to_le()), B);
+        assert_eq!($T::from_le(C.to_le()), C);
+        assert_eq!($T::from_le(_0), _0);
+        assert_eq!($T::from_le(_1), _1);
         assert_eq!(_0.to_le(), _0);
         assert_eq!(_1.to_le(), _1);
     }
 
     #[test]
     fn test_be() {
-        assert_eq!(Int::from_be(A.to_be()), A);
-        assert_eq!(Int::from_be(B.to_be()), B);
-        assert_eq!(Int::from_be(C.to_be()), C);
-        assert_eq!(Int::from_be(_0), _0);
-        assert_eq!(Int::from_be(_1), _1);
+        assert_eq!($T::from_be(A.to_be()), A);
+        assert_eq!($T::from_be(B.to_be()), B);
+        assert_eq!($T::from_be(C.to_be()), C);
+        assert_eq!($T::from_be(_0), _0);
+        assert_eq!($T::from_be(_1), _1);
         assert_eq!(_0.to_be(), _0);
         assert_eq!(_1.to_be(), _1);
     }
 
     #[test]
     fn test_unsigned_checked_div() {
-        assert!(10.checked_div(2) == Some(5));
-        assert!(5.checked_div(0) == None);
+        assert!((10 as $T).checked_div(2) == Some(5));
+        assert!((5 as $T).checked_div(0) == None);
     }
 }
 
index 02c4a2339966f9352379519bc5f91898cbf8ee20..5782c57834eedc6f14ab226aff6ca7f35b1a8b33 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15677
 
 //! Simple getopt alternative.
 //!
@@ -93,7 +91,6 @@
 
 #![deny(missing_docs)]
 #![feature(staged_api)]
-#![feature(str_words)]
 #![feature(str_char)]
 #![cfg_attr(test, feature(rustc_private))]
 
@@ -773,7 +770,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
 
         // Normalize desc to contain words separated by one space character
         let mut desc_normalized_whitespace = String::new();
-        for word in desc.words() {
+        for word in desc.split_whitespace() {
             desc_normalized_whitespace.push_str(word);
             desc_normalized_whitespace.push(' ');
         }
index f7e92d614746c909bc84e60da47cda5e224dea31..4fbcdaa378e25cef101fcc258c5b695266fa536a 100644 (file)
@@ -3296,6 +3296,8 @@ pub mod posix01 {
             pub const F_GETFL : c_int = 3;
             pub const F_SETFL : c_int = 4;
 
+            pub const O_ACCMODE : c_int = 3;
+
             pub const SIGTRAP : c_int = 5;
             pub const SIG_IGN: size_t = 1;
 
@@ -3534,6 +3536,30 @@ pub mod bsd44 {
             pub const IPV6_DROP_MEMBERSHIP: c_int = 21;
 
             pub const TCP_NODELAY: c_int = 1;
+            pub const TCP_MAXSEG: c_int = 2;
+            pub const TCP_CORK: c_int = 3;
+            pub const TCP_KEEPIDLE: c_int = 4;
+            pub const TCP_KEEPINTVL: c_int = 5;
+            pub const TCP_KEEPCNT: c_int = 6;
+            pub const TCP_SYNCNT: c_int = 7;
+            pub const TCP_LINGER2: c_int = 8;
+            pub const TCP_DEFER_ACCEPT: c_int = 9;
+            pub const TCP_WINDOW_CLAMP: c_int = 10;
+            pub const TCP_INFO: c_int = 11;
+            pub const TCP_QUICKACK: c_int = 12;
+            pub const TCP_CONGESTION: c_int = 13;
+            pub const TCP_MD5SIG: c_int = 14;
+            pub const TCP_COOKIE_TRANSACTIONS: c_int = 15;
+            pub const TCP_THIN_LINEAR_TIMEOUTS: c_int = 16;
+            pub const TCP_THIN_DUPACK: c_int = 17;
+            pub const TCP_USER_TIMEOUT: c_int = 18;
+            pub const TCP_REPAIR: c_int = 19;
+            pub const TCP_REPAIR_QUEUE: c_int = 20;
+            pub const TCP_QUEUE_SEQ: c_int = 21;
+            pub const TCP_REPAIR_OPTIONS: c_int = 22;
+            pub const TCP_FASTOPEN: c_int = 23;
+            pub const TCP_TIMESTAMP: c_int = 24;
+
             pub const SOL_SOCKET: c_int = 1;
 
             pub const SO_DEBUG: c_int = 1;
index 44187a4fc99429002d292e679fb4af77bc5260d7..bcb827cb471cacac023c650ae81a78d147ec83d7 100644 (file)
@@ -11,8 +11,6 @@
 //! The ChaCha random number generator.
 
 use core::prelude::*;
-use core::num::Int;
-use core::num::wrapping::WrappingOps;
 use {Rng, SeedableRng, Rand};
 
 const KEY_WORDS    : usize =  8; // 8 words for the 256-bit key
@@ -204,7 +202,7 @@ fn rand<R: Rng>(other: &mut R) -> ChaChaRng {
 
 
 #[cfg(test)]
-mod test {
+mod tests {
     use std::prelude::v1::*;
 
     use core::iter::order;
index 5ba6d8912f2672bcf73c58b0863f54fd18a87167..f46d35a33db1a034b2b6190faedf084180b26fa0 100644 (file)
@@ -82,7 +82,7 @@ fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use std::prelude::v1::*;
 
     use distributions::{Sample, IndependentSample};
index 1125d09653631cd84bdaa134c9ede52289908e7b..2951563934b3c412d273bf4ef91394806fbb41ee 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15679
 
 //! The Gamma and derived distributions.
 
@@ -278,7 +276,7 @@ fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use std::prelude::v1::*;
 
     use distributions::{Sample, IndependentSample};
index 77e53248607ca91abb4c4b67a4ecb8b1e138ea79..4ea81b8e61938b4f9c5f2e54f369a754750ee644 100644 (file)
@@ -18,7 +18,7 @@
 //! that do not need to record state.
 
 use core::prelude::*;
-use core::num::{Float, Int};
+use core::num::Float;
 use core::marker::PhantomData;
 
 use {Rng, Rand};
index 8406c76cc1bbc4b915a1c1d0a694b74da5a4eeda..4916e305b70e369141ad8e7743fe59aebdc78865 100644 (file)
@@ -13,8 +13,6 @@
 // this is surprisingly complicated to be both generic & correct
 
 use core::prelude::PartialOrd;
-use core::num::Int;
-use core::num::wrapping::WrappingOps;
 
 use Rng;
 use distributions::{Sample, IndependentSample};
@@ -73,7 +71,7 @@ pub trait SampleRange {
 }
 
 macro_rules! integer_impl {
-    ($ty:ty, $unsigned:ty) => {
+    ($ty:ident, $unsigned:ident) => {
         impl SampleRange for $ty {
             // we play free and fast with unsigned vs signed here
             // (when $ty is signed), but that's fine, since the
@@ -83,7 +81,7 @@ impl SampleRange for $ty {
 
             fn construct_range(low: $ty, high: $ty) -> Range<$ty> {
                 let range = (high as $unsigned).wrapping_sub(low as $unsigned);
-                let unsigned_max: $unsigned = Int::max_value();
+                let unsigned_max: $unsigned = $unsigned::max_value();
 
                 // this is the largest number that fits into $unsigned
                 // that `range` divides evenly, so, if we've sampled
@@ -148,7 +146,6 @@ fn sample_range<R: Rng>(r: &Range<$ty>, rng: &mut R) -> $ty {
 
 #[cfg(test)]
 mod tests {
-    use std::num::Int;
     use std::prelude::v1::*;
     use distributions::{Sample, IndependentSample};
     use super::Range as Range;
@@ -168,11 +165,11 @@ fn test_range_bad_limits_flipped() {
     fn test_integers() {
         let mut rng = ::test::rng();
         macro_rules! t {
-            ($($ty:ty),*) => {{
+            ($($ty:ident),*) => {{
                 $(
                    let v: &[($ty, $ty)] = &[(0, 10),
                                             (10, 127),
-                                            (Int::min_value(), Int::max_value())];
+                                            ($ty::min_value(), $ty::max_value())];
                    for &(low, high) in v {
                         let mut sampler: Range<$ty> = Range::new(low, high);
                         for _ in 0..1000 {
index a7f7889783f70b775d40791d669efb547023a4bb..22fe46a8bd83a20e9f78a1a81ec2f47fcfc28c37 100644 (file)
@@ -510,7 +510,7 @@ fn rand<R: Rng>(other: &mut R) -> Isaac64Rng {
 
 
 #[cfg(test)]
-mod test {
+mod tests {
     use std::prelude::v1::*;
 
     use core::iter::order;
index 287a23cf1d1b68a90d77ad2633880978f0273130..bb0b13c43756b474cd1603a2d07b329dbdfadd7d 100644 (file)
@@ -14,7 +14,6 @@
 use core::prelude::*;
 
 use {Rng, SeedableRng};
-use core::default::Default;
 
 /// How many bytes of entropy the underling RNG is allowed to generate
 /// before it is reseeded.
@@ -121,12 +120,11 @@ fn default() -> ReseedWithDefault { ReseedWithDefault }
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use std::prelude::v1::*;
 
     use core::iter::{order, repeat};
     use super::{ReseedingRng, ReseedWithDefault};
-    use std::default::Default;
     use {SeedableRng, Rng};
 
     struct Counter {
index e2875ac8ca529479ab904f06a0c843375c880b6e..b7938397038b490d6b02c4b0092ad4ad8b62966a 100644 (file)
@@ -836,7 +836,6 @@ pub mod writer {
     use std::io::prelude::*;
     use std::io::{self, SeekFrom, Cursor};
     use std::slice::bytes;
-    use std::num::ToPrimitive;
 
     use super::{ EsVec, EsMap, EsEnum, EsSub8, EsSub32, EsVecElt, EsMapKey,
         EsU64, EsU32, EsU16, EsU8, EsI64, EsI32, EsI16, EsI8,
@@ -1070,10 +1069,10 @@ pub fn mark_stable_position(&mut self) -> u64 {
     impl<'a> Encoder<'a> {
         // used internally to emit things like the vector length and so on
         fn _emit_tagged_sub(&mut self, v: usize) -> EncodeResult {
-            if let Some(v) = v.to_u8() {
-                self.wr_tagged_raw_u8(EsSub8 as usize, v)
-            } else if let Some(v) = v.to_u32() {
-                self.wr_tagged_raw_u32(EsSub32 as usize, v)
+            if v as u8 as usize == v {
+                self.wr_tagged_raw_u8(EsSub8 as usize, v as u8)
+            } else if v as u32 as usize == v {
+                self.wr_tagged_raw_u32(EsSub32 as usize, v as u32)
             } else {
                 Err(io::Error::new(io::ErrorKind::Other,
                                    &format!("length or variant id too big: {}",
@@ -1101,21 +1100,24 @@ fn emit_uint(&mut self, v: usize) -> EncodeResult {
             self.emit_u64(v as u64)
         }
         fn emit_u64(&mut self, v: u64) -> EncodeResult {
-            match v.to_u32() {
-                Some(v) => self.emit_u32(v),
-                None => self.wr_tagged_raw_u64(EsU64 as usize, v)
+            if v as u32 as u64 == v {
+                self.emit_u32(v as u32)
+            } else {
+                self.wr_tagged_raw_u64(EsU64 as usize, v)
             }
         }
         fn emit_u32(&mut self, v: u32) -> EncodeResult {
-            match v.to_u16() {
-                Some(v) => self.emit_u16(v),
-                None => self.wr_tagged_raw_u32(EsU32 as usize, v)
+            if v as u16 as u32 == v {
+                self.emit_u16(v as u16)
+            } else {
+                self.wr_tagged_raw_u32(EsU32 as usize, v)
             }
         }
         fn emit_u16(&mut self, v: u16) -> EncodeResult {
-            match v.to_u8() {
-                Some(v) => self.emit_u8(v),
-                None => self.wr_tagged_raw_u16(EsU16 as usize, v)
+            if v as u8 as u16 == v {
+                self.emit_u8(v as u8)
+            } else {
+                self.wr_tagged_raw_u16(EsU16 as usize, v)
             }
         }
         fn emit_u8(&mut self, v: u8) -> EncodeResult {
@@ -1126,21 +1128,24 @@ fn emit_int(&mut self, v: isize) -> EncodeResult {
             self.emit_i64(v as i64)
         }
         fn emit_i64(&mut self, v: i64) -> EncodeResult {
-            match v.to_i32() {
-                Some(v) => self.emit_i32(v),
-                None => self.wr_tagged_raw_i64(EsI64 as usize, v)
+            if v as i32 as i64 == v {
+                self.emit_i32(v as i32)
+            } else {
+                self.wr_tagged_raw_i64(EsI64 as usize, v)
             }
         }
         fn emit_i32(&mut self, v: i32) -> EncodeResult {
-            match v.to_i16() {
-                Some(v) => self.emit_i16(v),
-                None => self.wr_tagged_raw_i32(EsI32 as usize, v)
+            if v as i16 as i32 == v {
+                self.emit_i16(v as i16)
+            } else {
+                self.wr_tagged_raw_i32(EsI32 as usize, v)
             }
         }
         fn emit_i16(&mut self, v: i16) -> EncodeResult {
-            match v.to_i8() {
-                Some(v) => self.emit_i8(v),
-                None => self.wr_tagged_raw_i16(EsI16 as usize, v)
+            if v as i8 as i16 == v {
+                self.emit_i8(v as i8)
+            } else {
+                self.wr_tagged_raw_i16(EsI16 as usize, v)
             }
         }
         fn emit_i8(&mut self, v: i8) -> EncodeResult {
index ba226c88e562399a2691b519a569b59230405794..182405a640dbcfb2d506607c6c6194f355c5c06e 100644 (file)
 into a variable called `op_string` while simultaneously requiring the inner
 String to be moved into a variable called `s`.
 
+```
 let x = Some("s".to_string());
 match x {
     op_string @ Some(s) => ...
     None => ...
 }
+```
 
 See also Error 303.
 "##,
 referenced in the pattern guard code. Doing so however would prevent the name
 from being available in the body of the match arm. Consider the following:
 
+```
 match Some("hi".to_string()) {
     Some(s) if s.len() == 0 => // use s.
     ...
 }
+```
 
 The variable `s` has type String, and its use in the guard is as a variable of
 type String. The guard code effectively executes in a separate scope to the body
 innocuous, the problem is most clear when considering functions that take their
 argument by value.
 
+```
 match Some("hi".to_string()) {
     Some(s) if { drop(s); false } => (),
     Some(s) => // use s.
     ...
 }
+```
 
 The value would be dropped in the guard then become unavailable not only in the
 body of that arm but also in all subsequent arms! The solution is to bind by
@@ -208,7 +214,7 @@ fn main() {
     unsafe { f(); }
 }
 
-See also http://doc.rust-lang.org/book/unsafe-code.html
+See also http://doc.rust-lang.org/book/unsafe.html
 "##,
 
 E0152: r##"
@@ -219,8 +225,10 @@ fn main() {
 You can build a free-standing crate by adding `#![no_std]` to the crate
 attributes:
 
+```
 #![feature(no_std)]
 #![no_std]
+```
 
 See also https://doc.rust-lang.org/book/no-stdlib.html
 "##,
@@ -236,11 +244,13 @@ fn main() {
 
 If you want to match against a `static`, consider using a guard instead:
 
+```
 static FORTY_TWO: i32 = 42;
 match Some(42) {
     Some(x) if x == FORTY_TWO => ...
     ...
 }
+```
 "##,
 
 E0161: r##"
@@ -256,6 +266,7 @@ fn main() {
 match was succesful. If the match is irrefutable (when it cannot fail to match),
 use a regular `let`-binding instead. For instance:
 
+```
 struct Irrefutable(i32);
 let irr = Irrefutable(0);
 
@@ -268,6 +279,7 @@ fn main() {
 // Try this instead:
 let Irrefutable(x) = irr;
 foo(x);
+```
 "##,
 
 E0165: r##"
@@ -275,6 +287,7 @@ fn main() {
 match was succesful. If the match is irrefutable (when it cannot fail to match),
 use a regular `let`-binding inside a `loop` instead. For instance:
 
+```
 struct Irrefutable(i32);
 let irr = Irrefutable(0);
 
@@ -288,22 +301,27 @@ fn main() {
     let Irrefutable(x) = irr;
     ...
 }
+```
 "##,
 
 E0170: r##"
 Enum variants are qualified by default. For example, given this type:
 
+```
 enum Method {
     GET,
     POST
 }
+```
 
 you would match it using:
 
+```
 match m {
     Method::GET => ...
     Method::POST => ...
 }
+```
 
 If you don't qualify the names, the code will bind new variables named "GET" and
 "POST" instead. This behavior is likely not what you want, so rustc warns when
@@ -312,8 +330,10 @@ enum Method {
 Qualified names are good practice, and most code works well with them. But if
 you prefer them unqualified, you can import the variants into scope:
 
+```
 use Method::*;
 enum Method { GET, POST }
+```
 "##,
 
 E0267: r##"
@@ -333,7 +353,9 @@ enum Method { GET, POST }
 This error indicates that the given recursion limit could not be parsed. Ensure
 that the value provided is a positive integer between quotes, like so:
 
+```
 #![recursion_limit="1000"]
+```
 "##,
 
 E0297: r##"
@@ -342,6 +364,7 @@ enum Method { GET, POST }
 loop variable, consider using a `match` or `if let` inside the loop body. For
 instance:
 
+```
 // This fails because `None` is not covered.
 for Some(x) in xs {
     ...
@@ -361,6 +384,7 @@ enum Method { GET, POST }
         ...
     }
 }
+```
 "##,
 
 E0301: r##"
@@ -370,11 +394,13 @@ enum Method { GET, POST }
 exhaustive. For instance, the following would not match any arm if mutable
 borrows were allowed:
 
+```
 match Some(()) {
     None => { },
     option if option.take().is_none() => { /* impossible, option is `Some` */ },
     Some(_) => { } // When the previous match failed, the option became `None`.
 }
+```
 "##,
 
 E0302: r##"
@@ -384,11 +410,13 @@ enum Method { GET, POST }
 exhaustive. For instance, the following would not match any arm if assignments
 were allowed:
 
+```
 match Some(()) {
     None => { },
     option if { option = None; false } { },
     Some(_) => { } // When the previous match failed, the option became `None`.
 }
+```
 "##,
 
 E0303: r##"
@@ -396,9 +424,10 @@ enum Method { GET, POST }
 Updates to the borrow checker in a future version of Rust may remove this
 restriction, but for now patterns must be rewritten without sub-bindings.
 
-// Before.
-match Some("hi".to_string()) {
-    ref op_string_ref @ Some(ref s) => ...
+```
+// Code like this...
+match Some(5) {
+    ref op_num @ Some(num) => ...
     None => ...
 }
 
@@ -410,6 +439,7 @@ enum Method { GET, POST }
     }
     None => ...
 }
+```
 
 The `op_string_ref` binding has type &Option<&String> in both cases.
 
index ab5c4e76966018210dd4c09020d23c7beca461dc..d4012f2057b5dac8306e189e3401d6bc9b6a981c 100644 (file)
@@ -38,7 +38,6 @@
 #![feature(staged_api)]
 #![feature(std_misc)]
 #![feature(path_ext)]
-#![feature(str_words)]
 #![feature(str_char)]
 #![feature(into_cow)]
 #![feature(slice_patterns)]
@@ -69,6 +68,9 @@
 
 pub use rustc_llvm as llvm;
 
+#[macro_use]
+mod macros;
+
 // NB: This module needs to be declared first so diagnostics are
 // registered before they are used.
 pub mod diagnostics;
@@ -104,8 +106,10 @@ pub mod middle {
     pub mod entry;
     pub mod expr_use_visitor;
     pub mod fast_reject;
+    pub mod free_region;
     pub mod intrinsicck;
     pub mod infer;
+    pub mod implicator;
     pub mod lang_items;
     pub mod liveness;
     pub mod mem_categorization;
@@ -142,6 +146,7 @@ pub mod util {
     pub mod ppaux;
     pub mod nodemap;
     pub mod lev_distance;
+    pub mod num;
 }
 
 pub mod lib {
diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs
new file mode 100644 (file)
index 0000000..ed764eb
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+macro_rules! enum_from_u32 {
+    ($(#[$attr:meta])* pub enum $name:ident {
+        $($variant:ident = $e:expr,)*
+    }) => {
+        $(#[$attr])*
+        pub enum $name {
+            $($variant = $e),*
+        }
+
+        impl $name {
+            pub fn from_u32(u: u32) -> Option<$name> {
+                $(if u == $name::$variant as u32 {
+                    return Some($name::$variant)
+                })*
+                None
+            }
+        }
+    };
+    ($(#[$attr:meta])* pub enum $name:ident {
+        $($variant:ident,)*
+    }) => {
+        $(#[$attr])*
+        pub enum $name {
+            $($variant,)*
+        }
+
+        impl $name {
+            pub fn from_u32(u: u32) -> Option<$name> {
+                $(if u == $name::$variant as u32 {
+                    return Some($name::$variant)
+                })*
+                None
+            }
+        }
+    }
+}
index cda0084768644a599a98b438b52539d184758109..06a40f1dd277da124749bebf2b9ede7b975b18fa 100644 (file)
@@ -116,37 +116,39 @@ impl items contain tag_item_impl_item elements, and classes
 pub const tag_items_data_item_reexport_name: usize = 0x48;
 
 // used to encode crate_ctxt side tables
-#[derive(Copy, Clone, PartialEq, FromPrimitive)]
-#[repr(usize)]
-pub enum astencode_tag { // Reserves 0x50 -- 0x6f
-    tag_ast = 0x50,
-
-    tag_tree = 0x51,
-
-    tag_id_range = 0x52,
-
-    tag_table = 0x53,
-    // GAP 0x54, 0x55
-    tag_table_def = 0x56,
-    tag_table_node_type = 0x57,
-    tag_table_item_subst = 0x58,
-    tag_table_freevars = 0x59,
-    tag_table_tcache = 0x5a,
-    tag_table_param_defs = 0x5b,
-    tag_table_mutbl = 0x5c,
-    tag_table_last_use = 0x5d,
-    tag_table_spill = 0x5e,
-    tag_table_method_map = 0x5f,
-    tag_table_vtable_map = 0x60,
-    tag_table_adjustments = 0x61,
-    tag_table_moves_map = 0x62,
-    tag_table_capture_map = 0x63,
-    tag_table_closure_tys = 0x64,
-    tag_table_closure_kinds = 0x65,
-    tag_table_upvar_capture_map = 0x66,
-    tag_table_capture_modes = 0x67,
-    tag_table_object_cast_map = 0x68,
-    tag_table_const_qualif = 0x69,
+enum_from_u32! {
+    #[derive(Copy, Clone, PartialEq)]
+    #[repr(usize)]
+    pub enum astencode_tag { // Reserves 0x50 -- 0x6f
+        tag_ast = 0x50,
+
+        tag_tree = 0x51,
+
+        tag_id_range = 0x52,
+
+        tag_table = 0x53,
+        // GAP 0x54, 0x55
+        tag_table_def = 0x56,
+        tag_table_node_type = 0x57,
+        tag_table_item_subst = 0x58,
+        tag_table_freevars = 0x59,
+        tag_table_tcache = 0x5a,
+        tag_table_param_defs = 0x5b,
+        tag_table_mutbl = 0x5c,
+        tag_table_last_use = 0x5d,
+        tag_table_spill = 0x5e,
+        tag_table_method_map = 0x5f,
+        tag_table_vtable_map = 0x60,
+        tag_table_adjustments = 0x61,
+        tag_table_moves_map = 0x62,
+        tag_table_capture_map = 0x63,
+        tag_table_closure_tys = 0x64,
+        tag_table_closure_kinds = 0x65,
+        tag_table_upvar_capture_map = 0x66,
+        tag_table_capture_modes = 0x67,
+        tag_table_object_cast_map = 0x68,
+        tag_table_const_qualif = 0x69,
+    }
 }
 
 pub const tag_item_trait_item_sort: usize = 0x70;
index 811aa21a0b7b986ce8888cf73b83ad0ed2a25184..1f18b13fc46fe26fff04ab9c29d40db0d2f499fd 100644 (file)
@@ -68,11 +68,13 @@ pub enum LinkagePreference {
     RequireStatic,
 }
 
-#[derive(Copy, Clone, PartialEq, FromPrimitive)]
-pub enum NativeLibraryKind {
-    NativeStatic,    // native static library (.a archive)
-    NativeFramework, // OSX-specific
-    NativeUnknown,   // default way to specify a dynamic library
+enum_from_u32! {
+    #[derive(Copy, Clone, PartialEq)]
+    pub enum NativeLibraryKind {
+        NativeStatic,    // native static library (.a archive)
+        NativeFramework, // OSX-specific
+        NativeUnknown,   // default way to specify a dynamic library
+    }
 }
 
 // Where a crate came from on the local filesystem. One of these two options
index 6b3bde409f540091d82718b8be3f477b132891ec..cbd542567709c13f9b114d9949b1fc62784de9d3 100644 (file)
@@ -35,7 +35,6 @@
 use std::hash::{self, Hash, SipHasher};
 use std::io::prelude::*;
 use std::io;
-use std::num::FromPrimitive;
 use std::rc::Rc;
 use std::slice::bytes;
 use std::str;
@@ -1349,7 +1348,7 @@ pub fn get_native_libraries(cdata: Cmd)
         let kind_doc = reader::get_doc(lib_doc, tag_native_libraries_kind);
         let name_doc = reader::get_doc(lib_doc, tag_native_libraries_name);
         let kind: cstore::NativeLibraryKind =
-            FromPrimitive::from_u32(reader::doc_as_u32(kind_doc)).unwrap();
+            cstore::NativeLibraryKind::from_u32(reader::doc_as_u32(kind_doc)).unwrap();
         let name = name_doc.as_str().to_string();
         result.push((kind, name));
         true
@@ -1359,7 +1358,7 @@ pub fn get_native_libraries(cdata: Cmd)
 
 pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<ast::NodeId> {
     reader::maybe_get_doc(rbml::Doc::new(data), tag_plugin_registrar_fn)
-        .map(|doc| FromPrimitive::from_u32(reader::doc_as_u32(doc)).unwrap())
+        .map(|doc| reader::doc_as_u32(doc))
 }
 
 pub fn each_exported_macro<F>(data: &[u8], intr: &IdentInterner, mut f: F) where
@@ -1407,7 +1406,7 @@ pub fn get_missing_lang_items(cdata: Cmd)
     let mut result = Vec::new();
     reader::tagged_docs(items, tag_lang_items_missing, |missing_docs| {
         let item: lang_items::LangItem =
-            FromPrimitive::from_u32(reader::doc_as_u32(missing_docs)).unwrap();
+            lang_items::LangItem::from_u32(reader::doc_as_u32(missing_docs)).unwrap();
         result.push(item);
         true
     });
index 398e4cd33b9434fb7b148f2a66bdbe5789a399ac..bbb2452ca29ee84d7334c1962b52e224859b849e 100644 (file)
@@ -692,11 +692,16 @@ pub fn note_crate_name(diag: &SpanHandler, name: &str) {
 
 impl ArchiveMetadata {
     fn new(ar: ArchiveRO) -> Option<ArchiveMetadata> {
-        let data = match ar.read(METADATA_FILENAME) {
-            Some(data) => data as *const [u8],
-            None => {
-                debug!("didn't find '{}' in the archive", METADATA_FILENAME);
-                return None;
+        let data = {
+            let section = ar.iter().find(|sect| {
+                sect.name() == Some(METADATA_FILENAME)
+            });
+            match section {
+                Some(s) => s.data() as *const [u8],
+                None => {
+                    debug!("didn't find '{}' in the archive", METADATA_FILENAME);
+                    return None;
+                }
             }
         };
 
index 7ee0ea4fd664bac53a1bc146149ce3f8f082311e..ee8373279d976f9f4d95c76cbba2a566121b93f2 100644 (file)
@@ -41,7 +41,6 @@
 use std::cell::Cell;
 use std::io::SeekFrom;
 use std::io::prelude::*;
-use std::num::FromPrimitive;
 use std::rc::Rc;
 use std::fmt::Debug;
 
@@ -1713,7 +1712,8 @@ fn decode_side_tables(dcx: &DecodeContext,
         debug!(">> Side table document with tag 0x{:x} \
                 found for id {} (orig {})",
                tag, id, id0);
-        let decoded_tag: Option<c::astencode_tag> = FromPrimitive::from_usize(tag);
+        let tag = tag as u32;
+        let decoded_tag: Option<c::astencode_tag> = c::astencode_tag::from_u32(tag);
         match decoded_tag {
             None => {
                 dcx.tcx.sess.bug(
index 367bcbbe1d8a972add77a29907999a4cbfaed013..2c6ffb3281fcb4922cd173710578565938bf65d3 100644 (file)
@@ -20,6 +20,7 @@
 use middle::pat_util::def_to_path;
 use middle::ty::{self, Ty};
 use middle::astconv_util::ast_ty_to_prim_ty;
+use util::num::ToPrimitive;
 
 use syntax::ast::{self, Expr};
 use syntax::codemap::Span;
@@ -30,7 +31,6 @@
 
 use std::borrow::{Cow, IntoCow};
 use std::num::wrapping::OverflowingOps;
-use std::num::ToPrimitive;
 use std::cmp::Ordering;
 use std::collections::hash_map::Entry::Vacant;
 use std::{i8, i16, i32, i64};
diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs
new file mode 100644 (file)
index 0000000..0c8a956
--- /dev/null
@@ -0,0 +1,127 @@
+// 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.
+
+//! This file defines
+
+use middle::implicator::Implication;
+use middle::ty::{self, FreeRegion};
+use util::common::can_reach;
+use util::nodemap::FnvHashMap;
+use util::ppaux::Repr;
+
+#[derive(Clone)]
+pub struct FreeRegionMap {
+    /// `free_region_map` maps from a free region `a` to a list of
+    /// free regions `bs` such that `a <= b for all b in bs`
+    map: FnvHashMap<FreeRegion, Vec<FreeRegion>>,
+}
+
+impl FreeRegionMap {
+    pub fn new() -> FreeRegionMap {
+        FreeRegionMap { map: FnvHashMap() }
+    }
+
+    pub fn relate_free_regions_from_implications<'tcx>(&mut self,
+                                                       tcx: &ty::ctxt<'tcx>,
+                                                       implications: &[Implication<'tcx>])
+    {
+        for implication in implications {
+            debug!("implication: {}", implication.repr(tcx));
+            match *implication {
+                Implication::RegionSubRegion(_, ty::ReFree(free_a), ty::ReFree(free_b)) => {
+                    self.relate_free_regions(free_a, free_b);
+                }
+                Implication::RegionSubRegion(..) |
+                Implication::RegionSubClosure(..) |
+                Implication::RegionSubGeneric(..) |
+                Implication::Predicate(..) => {
+                }
+            }
+        }
+    }
+
+    pub fn relate_free_regions_from_predicates<'tcx>(&mut self,
+                                                     tcx: &ty::ctxt<'tcx>,
+                                                     predicates: &[ty::Predicate<'tcx>]) {
+        debug!("relate_free_regions_from_predicates(predicates={})", predicates.repr(tcx));
+        for predicate in predicates {
+            match *predicate {
+                ty::Predicate::Projection(..) |
+                ty::Predicate::Trait(..) |
+                ty::Predicate::Equate(..) |
+                ty::Predicate::TypeOutlives(..) => {
+                    // No region bounds here
+                }
+                ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r_a, r_b))) => {
+                    match (r_a, r_b) {
+                        (ty::ReFree(fr_a), ty::ReFree(fr_b)) => {
+                            // Record that `'a:'b`. Or, put another way, `'b <= 'a`.
+                            self.relate_free_regions(fr_b, fr_a);
+                        }
+                        _ => {
+                            // All named regions are instantiated with free regions.
+                            tcx.sess.bug(
+                                &format!("record_region_bounds: non free region: {} / {}",
+                                         r_a.repr(tcx),
+                                         r_b.repr(tcx)));
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    pub fn relate_free_regions(&mut self, sub: FreeRegion, sup: FreeRegion) {
+        let mut sups = self.map.entry(sub).or_insert(Vec::new());
+        if !sups.contains(&sup) {
+            sups.push(sup);
+        }
+    }
+
+    /// Determines whether two free regions have a subregion relationship
+    /// by walking the graph encoded in `map`.  Note that
+    /// it is possible that `sub != sup` and `sub <= sup` and `sup <= sub`
+    /// (that is, the user can give two different names to the same lifetime).
+    pub fn sub_free_region(&self, sub: FreeRegion, sup: FreeRegion) -> bool {
+        can_reach(&self.map, sub, sup)
+    }
+
+    /// Determines whether one region is a subregion of another.  This is intended to run *after
+    /// inference* and sadly the logic is somewhat duplicated with the code in infer.rs.
+    pub fn is_subregion_of(&self,
+                           tcx: &ty::ctxt,
+                           sub_region: ty::Region,
+                           super_region: ty::Region)
+                           -> bool {
+        debug!("is_subregion_of(sub_region={:?}, super_region={:?})",
+               sub_region, super_region);
+
+        sub_region == super_region || {
+            match (sub_region, super_region) {
+                (ty::ReEmpty, _) |
+                (_, ty::ReStatic) =>
+                    true,
+
+                (ty::ReScope(sub_scope), ty::ReScope(super_scope)) =>
+                    tcx.region_maps.is_subscope_of(sub_scope, super_scope),
+
+                (ty::ReScope(sub_scope), ty::ReFree(ref fr)) =>
+                    tcx.region_maps.is_subscope_of(sub_scope, fr.scope.to_code_extent()),
+
+                (ty::ReFree(sub_fr), ty::ReFree(super_fr)) =>
+                    self.sub_free_region(sub_fr, super_fr),
+
+                _ =>
+                    false,
+            }
+        }
+    }
+}
+
diff --git a/src/librustc/middle/implicator.rs b/src/librustc/middle/implicator.rs
new file mode 100644 (file)
index 0000000..0d6a1df
--- /dev/null
@@ -0,0 +1,487 @@
+// 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 middle::infer::{InferCtxt, GenericKind};
+use middle::subst::Substs;
+use middle::traits;
+use middle::ty::{self, RegionEscape, 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::nodemap::FnvHashSet;
+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>),
+    RegionSubClosure(Option<Ty<'tcx>>, ty::Region, ast::DefId, &'tcx Substs<'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>>,
+    visited: FnvHashSet<Ty<'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(),
+                              visited: FnvHashSet() };
+    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()));
+
+        // When expanding out associated types, we can visit a cyclic
+        // set of types. Issue #23003.
+        if !self.visited.insert(ty) {
+            return;
+        }
+
+        match ty.sty {
+            ty::ty_bool |
+            ty::ty_char |
+            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(def_id, substs) => {
+                let &(r_a, opt_ty) = self.stack.last().unwrap();
+                self.out.push(Implication::RegionSubClosure(opt_ty, r_a, def_id, substs));
+            }
+
+            ty::ty_trait(ref t) => {
+                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().
+            }
+        }
+    }
+
+    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>)
+    {
+        debug!("accumulate_from_assoc_types_transitive({})",
+               data.repr(self.tcx()));
+
+        for poly_trait_ref in traits::supertraits(self.tcx(), data.to_poly_trait_ref()) {
+            match ty::no_late_bound_regions(self.tcx(), &poly_trait_ref) {
+                Some(trait_ref) => { self.accumulate_from_assoc_types(trait_ref); }
+                None => { }
+            }
+        }
+    }
+
+    fn accumulate_from_assoc_types(&mut self,
+                                   trait_ref: Rc<ty::TraitRef<'tcx>>)
+    {
+        debug!("accumulate_from_assoc_types({})",
+               trait_ref.repr(self.tcx()));
+
+        let trait_def_id = trait_ref.def_id;
+        let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
+        let assoc_type_projections: Vec<_> =
+            trait_def.associated_type_names
+                     .iter()
+                     .map(|&name| ty::mk_projection(self.tcx(), trait_ref.clone(), name))
+                     .collect();
+        debug!("accumulate_from_assoc_types: assoc_type_projections={}",
+               assoc_type_projections.repr(self.tcx()));
+        let tys = match self.fully_normalize(&assoc_type_projections) {
+            Ok(tys) => { tys }
+            Err(ErrorReported) => { return; }
+        };
+        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)
+            }
+        }
+    }
+}
+
+/// Given an object type like `SomeTrait+Send`, computes the lifetime
+/// bounds that must hold on the elided self type. These are derived
+/// from the declarations of `SomeTrait`, `Send`, and friends -- if
+/// they declare `trait SomeTrait : 'static`, for example, then
+/// `'static` would appear in the list. The hard work is done by
+/// `ty::required_region_bounds`, see that for more information.
+pub fn object_region_bounds<'tcx>(
+    tcx: &ty::ctxt<'tcx>,
+    principal: &ty::PolyTraitRef<'tcx>,
+    others: ty::BuiltinBounds)
+    -> Vec<ty::Region>
+{
+    // Since we don't actually *know* the self type for an object,
+    // this "open(err)" serves as a kind of dummy standin -- basically
+    // a skolemized type.
+    let open_ty = ty::mk_infer(tcx, ty::FreshTy(0));
+
+    // Note that we preserve the overall binding levels here.
+    assert!(!open_ty.has_escaping_regions());
+    let substs = tcx.mk_substs(principal.0.substs.with_self_ty(open_ty));
+    let trait_refs = vec!(ty::Binder(Rc::new(ty::TraitRef::new(principal.0.def_id, substs))));
+
+    let param_bounds = ty::ParamBounds {
+        region_bounds: Vec::new(),
+        builtin_bounds: others,
+        trait_bounds: trait_refs,
+        projection_bounds: Vec::new(), // not relevant to computing region bounds
+    };
+
+    let predicates = ty::predicates(tcx, open_ty, &param_bounds);
+    ty::required_region_bounds(tcx, open_ty, predicates)
+}
+
+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::RegionSubClosure(_, ref a, ref b, ref c) => {
+                format!("RegionSubClosure({}, {}, {})",
+                        a.repr(tcx),
+                        b.repr(tcx),
+                        c.repr(tcx))
+            }
+
+            Implication::Predicate(ref def_id, ref p) => {
+                format!("Predicate({}, {})",
+                        def_id.repr(tcx),
+                        p.repr(tcx))
+            }
+        }
+    }
+}
index b0921a266f39f9c14a5eaa038b0162ae75d1cbf1..63e4a5c8a2a4aed77adb22daf7868afc5134a85b 100644 (file)
@@ -22,6 +22,7 @@
 pub use self::freshen::TypeFreshener;
 pub use self::region_inference::GenericKind;
 
+use middle::free_region::FreeRegionMap;
 use middle::subst;
 use middle::subst::Substs;
 use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric};
@@ -855,8 +856,10 @@ pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region {
         self.region_vars.new_bound(debruijn)
     }
 
-    pub fn resolve_regions_and_report_errors(&self, subject_node_id: ast::NodeId) {
-        let errors = self.region_vars.resolve_regions(subject_node_id);
+    pub fn resolve_regions_and_report_errors(&self,
+                                             free_regions: &FreeRegionMap,
+                                             subject_node_id: ast::NodeId) {
+        let errors = self.region_vars.resolve_regions(free_regions, subject_node_id);
         self.report_region_errors(&errors); // see error_reporting.rs
     }
 
index e76468131e04d973cf6e6935fd15313de298875a..9de362fe360a625d2b2db0aaa7c41ff8ac8072cb 100644 (file)
@@ -21,6 +21,7 @@
 use super::{RegionVariableOrigin, SubregionOrigin, TypeTrace, MiscVariable};
 
 use rustc_data_structures::graph::{self, Direction, NodeIndex};
+use middle::free_region::FreeRegionMap;
 use middle::region;
 use middle::ty::{self, Ty};
 use middle::ty::{BoundRegion, FreeRegion, Region, RegionVid};
@@ -711,19 +712,19 @@ fn consider_adding_directed_edge(result_set: &mut Vec<Region>,
     /// fixed-point iteration to find region values which satisfy all
     /// constraints, assuming such values can be found; if they cannot,
     /// errors are reported.
-    pub fn resolve_regions(&self, subject_node: ast::NodeId) -> Vec<RegionResolutionError<'tcx>> {
+    pub fn resolve_regions(&self,
+                           free_regions: &FreeRegionMap,
+                           subject_node: ast::NodeId)
+                           -> Vec<RegionResolutionError<'tcx>>
+    {
         debug!("RegionVarBindings: resolve_regions()");
         let mut errors = vec!();
-        let v = self.infer_variable_values(&mut errors, subject_node);
+        let v = self.infer_variable_values(free_regions, &mut errors, subject_node);
         *self.values.borrow_mut() = Some(v);
         errors
     }
 
-    fn is_subregion_of(&self, sub: Region, sup: Region) -> bool {
-        self.tcx.region_maps.is_subregion_of(sub, sup)
-    }
-
-    fn lub_concrete_regions(&self, a: Region, b: Region) -> Region {
+    fn lub_concrete_regions(&self, free_regions: &FreeRegionMap, a: Region, b: Region) -> Region {
         match (a, b) {
           (ReLateBound(..), _) |
           (_, ReLateBound(..)) |
@@ -781,7 +782,7 @@ fn lub_concrete_regions(&self, a: Region, b: Region) -> Region {
           }
 
           (ReFree(ref a_fr), ReFree(ref b_fr)) => {
-             self.lub_free_regions(a_fr, b_fr)
+             self.lub_free_regions(free_regions, a_fr, b_fr)
           }
 
           // For these types, we cannot define any additional
@@ -796,23 +797,25 @@ fn lub_concrete_regions(&self, a: Region, b: Region) -> Region {
     /// Computes a region that encloses both free region arguments. Guarantee that if the same two
     /// regions are given as argument, in any order, a consistent result is returned.
     fn lub_free_regions(&self,
+                        free_regions: &FreeRegionMap,
                         a: &FreeRegion,
                         b: &FreeRegion)
                         -> ty::Region
     {
         return match a.cmp(b) {
-            Less => helper(self, a, b),
-            Greater => helper(self, b, a),
+            Less => helper(self, free_regions, a, b),
+            Greater => helper(self, free_regions, b, a),
             Equal => ty::ReFree(*a)
         };
 
-        fn helper(this: &RegionVarBindings,
+        fn helper(_this: &RegionVarBindings,
+                  free_regions: &FreeRegionMap,
                   a: &FreeRegion,
                   b: &FreeRegion) -> ty::Region
         {
-            if this.tcx.region_maps.sub_free_region(*a, *b) {
+            if free_regions.sub_free_region(*a, *b) {
                 ty::ReFree(*b)
-            } else if this.tcx.region_maps.sub_free_region(*b, *a) {
+            } else if free_regions.sub_free_region(*b, *a) {
                 ty::ReFree(*a)
             } else {
                 ty::ReStatic
@@ -821,6 +824,7 @@ fn helper(this: &RegionVarBindings,
     }
 
     fn glb_concrete_regions(&self,
+                            free_regions: &FreeRegionMap,
                             a: Region,
                             b: Region)
                             -> RelateResult<'tcx, Region>
@@ -878,7 +882,7 @@ fn glb_concrete_regions(&self,
             }
 
             (ReFree(ref a_fr), ReFree(ref b_fr)) => {
-                self.glb_free_regions(a_fr, b_fr)
+                self.glb_free_regions(free_regions, a_fr, b_fr)
             }
 
             // For these types, we cannot define any additional
@@ -898,23 +902,25 @@ fn glb_concrete_regions(&self,
     /// if the same two regions are given as argument, in any order, a consistent result is
     /// returned.
     fn glb_free_regions(&self,
+                        free_regions: &FreeRegionMap,
                         a: &FreeRegion,
                         b: &FreeRegion)
                         -> RelateResult<'tcx, ty::Region>
     {
         return match a.cmp(b) {
-            Less => helper(self, a, b),
-            Greater => helper(self, b, a),
+            Less => helper(self, free_regions, a, b),
+            Greater => helper(self, free_regions, b, a),
             Equal => Ok(ty::ReFree(*a))
         };
 
         fn helper<'a, 'tcx>(this: &RegionVarBindings<'a, 'tcx>,
+                            free_regions: &FreeRegionMap,
                             a: &FreeRegion,
                             b: &FreeRegion) -> RelateResult<'tcx, ty::Region>
         {
-            if this.tcx.region_maps.sub_free_region(*a, *b) {
+            if free_regions.sub_free_region(*a, *b) {
                 Ok(ty::ReFree(*a))
-            } else if this.tcx.region_maps.sub_free_region(*b, *a) {
+            } else if free_regions.sub_free_region(*b, *a) {
                 Ok(ty::ReFree(*b))
             } else {
                 this.intersect_scopes(ty::ReFree(*a), ty::ReFree(*b),
@@ -970,6 +976,7 @@ struct RegionAndOrigin<'tcx> {
 
 impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
     fn infer_variable_values(&self,
+                             free_regions: &FreeRegionMap,
                              errors: &mut Vec<RegionResolutionError<'tcx>>,
                              subject: ast::NodeId) -> Vec<VarValue>
     {
@@ -980,12 +987,13 @@ fn infer_variable_values(&self,
         debug!("----() End constraint listing {:?}---", self.dump_constraints());
         graphviz::maybe_print_constraints_for(self, subject);
 
-        self.expansion(&mut var_data);
-        self.contraction(&mut var_data);
+        self.expansion(free_regions, &mut var_data);
+        self.contraction(free_regions, &mut var_data);
         let values =
-            self.extract_values_and_collect_conflicts(&var_data[..],
+            self.extract_values_and_collect_conflicts(free_regions,
+                                                      &var_data[..],
                                                       errors);
-        self.collect_concrete_region_errors(&values, errors);
+        self.collect_concrete_region_errors(free_regions, &values, errors);
         values
     }
 
@@ -1009,7 +1017,7 @@ fn dump_constraints(&self) {
         }
     }
 
-    fn expansion(&self, var_data: &mut [VarData]) {
+    fn expansion(&self, free_regions: &FreeRegionMap, var_data: &mut [VarData]) {
         self.iterate_until_fixed_point("Expansion", |constraint| {
             debug!("expansion: constraint={} origin={}",
                    constraint.repr(self.tcx),
@@ -1020,14 +1028,14 @@ fn expansion(&self, var_data: &mut [VarData]) {
             match *constraint {
               ConstrainRegSubVar(a_region, b_vid) => {
                 let b_data = &mut var_data[b_vid.index as usize];
-                self.expand_node(a_region, b_vid, b_data)
+                self.expand_node(free_regions, a_region, b_vid, b_data)
               }
               ConstrainVarSubVar(a_vid, b_vid) => {
                 match var_data[a_vid.index as usize].value {
                   NoValue | ErrorValue => false,
                   Value(a_region) => {
                     let b_node = &mut var_data[b_vid.index as usize];
-                    self.expand_node(a_region, b_vid, b_node)
+                    self.expand_node(free_regions, a_region, b_vid, b_node)
                   }
                 }
               }
@@ -1040,6 +1048,7 @@ fn expansion(&self, var_data: &mut [VarData]) {
     }
 
     fn expand_node(&self,
+                   free_regions: &FreeRegionMap,
                    a_region: Region,
                    b_vid: RegionVid,
                    b_data: &mut VarData)
@@ -1072,7 +1081,7 @@ fn expand_node(&self,
           }
 
           Value(cur_region) => {
-            let lub = self.lub_concrete_regions(a_region, cur_region);
+            let lub = self.lub_concrete_regions(free_regions, a_region, cur_region);
             if lub == cur_region {
                 return false;
             }
@@ -1093,6 +1102,7 @@ fn expand_node(&self,
     }
 
     fn contraction(&self,
+                   free_regions: &FreeRegionMap,
                    var_data: &mut [VarData]) {
         self.iterate_until_fixed_point("Contraction", |constraint| {
             debug!("contraction: constraint={} origin={}",
@@ -1111,19 +1121,20 @@ fn contraction(&self,
                   NoValue | ErrorValue => false,
                   Value(b_region) => {
                     let a_data = &mut var_data[a_vid.index as usize];
-                    self.contract_node(a_vid, a_data, b_region)
+                    self.contract_node(free_regions, a_vid, a_data, b_region)
                   }
                 }
               }
               ConstrainVarSubReg(a_vid, b_region) => {
                 let a_data = &mut var_data[a_vid.index as usize];
-                self.contract_node(a_vid, a_data, b_region)
+                self.contract_node(free_regions, a_vid, a_data, b_region)
               }
             }
         })
     }
 
     fn contract_node(&self,
+                     free_regions: &FreeRegionMap,
                      a_vid: RegionVid,
                      a_data: &mut VarData,
                      b_region: Region)
@@ -1143,19 +1154,23 @@ fn contract_node(&self,
 
             Value(a_region) => {
                 match a_data.classification {
-                    Expanding => check_node(self, a_vid, a_data, a_region, b_region),
-                    Contracting => adjust_node(self, a_vid, a_data, a_region, b_region),
+                    Expanding =>
+                        check_node(self, free_regions, a_vid, a_data, a_region, b_region),
+                    Contracting =>
+                        adjust_node(self, free_regions, a_vid, a_data, a_region, b_region),
                 }
             }
         };
 
         fn check_node(this: &RegionVarBindings,
+                      free_regions: &FreeRegionMap,
                       a_vid: RegionVid,
                       a_data: &mut VarData,
                       a_region: Region,
                       b_region: Region)
-                      -> bool {
-            if !this.is_subregion_of(a_region, b_region) {
+                      -> bool
+        {
+            if !free_regions.is_subregion_of(this.tcx, a_region, b_region) {
                 debug!("Setting {:?} to ErrorValue: {} not subregion of {}",
                        a_vid,
                        a_region.repr(this.tcx),
@@ -1166,12 +1181,13 @@ fn check_node(this: &RegionVarBindings,
         }
 
         fn adjust_node(this: &RegionVarBindings,
+                       free_regions: &FreeRegionMap,
                        a_vid: RegionVid,
                        a_data: &mut VarData,
                        a_region: Region,
                        b_region: Region)
                        -> bool {
-            match this.glb_concrete_regions(a_region, b_region) {
+            match this.glb_concrete_regions(free_regions, a_region, b_region) {
                 Ok(glb) => {
                     if glb == a_region {
                         false
@@ -1197,6 +1213,7 @@ fn adjust_node(this: &RegionVarBindings,
     }
 
     fn collect_concrete_region_errors(&self,
+                                      free_regions: &FreeRegionMap,
                                       values: &Vec<VarValue>,
                                       errors: &mut Vec<RegionResolutionError<'tcx>>)
     {
@@ -1204,7 +1221,7 @@ fn collect_concrete_region_errors(&self,
         for verify in &*self.verifys.borrow() {
             match *verify {
                 VerifyRegSubReg(ref origin, sub, sup) => {
-                    if self.is_subregion_of(sub, sup) {
+                    if free_regions.is_subregion_of(self.tcx, sub, sup) {
                         continue;
                     }
 
@@ -1222,7 +1239,7 @@ fn collect_concrete_region_errors(&self,
                     let sub = normalize(values, sub);
                     if sups.iter()
                            .map(|&sup| normalize(values, sup))
-                           .any(|sup| self.is_subregion_of(sub, sup))
+                           .any(|sup| free_regions.is_subregion_of(self.tcx, sub, sup))
                     {
                         continue;
                     }
@@ -1239,6 +1256,7 @@ fn collect_concrete_region_errors(&self,
 
     fn extract_values_and_collect_conflicts(
         &self,
+        free_regions: &FreeRegionMap,
         var_data: &[VarData],
         errors: &mut Vec<RegionResolutionError<'tcx>>)
         -> Vec<VarValue>
@@ -1304,12 +1322,12 @@ fn extract_values_and_collect_conflicts(
                     match var_data[idx].classification {
                         Expanding => {
                             self.collect_error_for_expanding_node(
-                                graph, var_data, &mut dup_vec,
+                                free_regions, graph, var_data, &mut dup_vec,
                                 node_vid, errors);
                         }
                         Contracting => {
                             self.collect_error_for_contracting_node(
-                                graph, var_data, &mut dup_vec,
+                                free_regions, graph, var_data, &mut dup_vec,
                                 node_vid, errors);
                         }
                     }
@@ -1355,13 +1373,13 @@ fn construct_graph(&self) -> RegionGraph {
         return graph;
     }
 
-    fn collect_error_for_expanding_node(
-        &self,
-        graph: &RegionGraph,
-        var_data: &[VarData],
-        dup_vec: &mut [u32],
-        node_idx: RegionVid,
-        errors: &mut Vec<RegionResolutionError<'tcx>>)
+    fn collect_error_for_expanding_node(&self,
+                                        free_regions: &FreeRegionMap,
+                                        graph: &RegionGraph,
+                                        var_data: &[VarData],
+                                        dup_vec: &mut [u32],
+                                        node_idx: RegionVid,
+                                        errors: &mut Vec<RegionResolutionError<'tcx>>)
     {
         // Errors in expanding nodes result from a lower-bound that is
         // not contained by an upper-bound.
@@ -1394,8 +1412,9 @@ fn free_regions_first(a: &RegionAndOrigin,
 
         for lower_bound in &lower_bounds {
             for upper_bound in &upper_bounds {
-                if !self.is_subregion_of(lower_bound.region,
-                                         upper_bound.region) {
+                if !free_regions.is_subregion_of(self.tcx,
+                                                 lower_bound.region,
+                                                 upper_bound.region) {
                     debug!("pushing SubSupConflict sub: {:?} sup: {:?}",
                            lower_bound.region, upper_bound.region);
                     errors.push(SubSupConflict(
@@ -1420,6 +1439,7 @@ fn free_regions_first(a: &RegionAndOrigin,
 
     fn collect_error_for_contracting_node(
         &self,
+        free_regions: &FreeRegionMap,
         graph: &RegionGraph,
         var_data: &[VarData],
         dup_vec: &mut [u32],
@@ -1438,7 +1458,8 @@ fn collect_error_for_contracting_node(
 
         for upper_bound_1 in &upper_bounds {
             for upper_bound_2 in &upper_bounds {
-                match self.glb_concrete_regions(upper_bound_1.region,
+                match self.glb_concrete_regions(free_regions,
+                                                upper_bound_1.region,
                                                 upper_bound_2.region) {
                   Ok(_) => {}
                   Err(_) => {
index 89a8625856c2c61851d1e5258e63899677ea2ab0..c77a43e75cdc089a3dc70f8396bae1675f27619f 100644 (file)
@@ -36,7 +36,6 @@
 use syntax::visit;
 
 use std::iter::Enumerate;
-use std::num::FromPrimitive;
 use std::slice;
 
 // The actual lang items defined come at the end of this file in one handy table.
@@ -46,9 +45,12 @@ macro_rules! lets_do_this {
         $( $variant:ident, $name:expr, $method:ident; )*
     ) => {
 
-#[derive(Copy, Clone, FromPrimitive, PartialEq, Eq, Hash)]
-pub enum LangItem {
-    $($variant),*
+
+enum_from_u32! {
+    #[derive(Copy, Clone, PartialEq, Eq, Hash)]
+    pub enum LangItem {
+        $($variant,)*
+    }
 }
 
 pub struct LanguageItems {
@@ -71,7 +73,7 @@ pub fn items<'a>(&'a self) -> Enumerate<slice::Iter<'a, Option<ast::DefId>>> {
     }
 
     pub fn item_name(index: usize) -> &'static str {
-        let item: Option<LangItem> = FromPrimitive::from_usize(index);
+        let item: Option<LangItem> = LangItem::from_u32(index as u32);
         match item {
             $( Some($variant) => $name, )*
             None => "???"
index 2f7296051c566cb14ab0d40612e9113c5b3425c3..2c510b5f1d3b5d79d7b313dc67851cc15c0b0fa2 100644 (file)
@@ -17,9 +17,8 @@
 //! `middle/typeck/infer/region_inference.rs`
 
 use session::Session;
-use middle::ty::{self, Ty, FreeRegion};
+use middle::ty::{self, Ty};
 use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap};
-use util::common::can_reach;
 
 use std::cell::RefCell;
 use syntax::codemap::{self, Span};
@@ -234,14 +233,6 @@ pub struct RegionMaps {
     /// which that variable is declared.
     var_map: RefCell<NodeMap<CodeExtent>>,
 
-    /// `free_region_map` maps from a free region `a` to a list of
-    /// free regions `bs` such that `a <= b for all b in bs`
-    ///
-    /// NB. the free region map is populated during type check as we
-    /// check each function. See the function `relate_free_regions`
-    /// for more information.
-    free_region_map: RefCell<FnvHashMap<FreeRegion, Vec<FreeRegion>>>,
-
     /// `rvalue_scopes` includes entries for those expressions whose cleanup scope is
     /// larger than the default. The map goes from the expression id
     /// to the cleanup scope id. For rvalues not present in this
@@ -390,13 +381,6 @@ pub fn each_var_scope<E>(&self, mut e:E) where E: FnMut(&ast::NodeId, &CodeExten
             e(child, parent)
         }
     }
-    pub fn each_encl_free_region<E>(&self, mut e:E) where E: FnMut(&FreeRegion, &FreeRegion) {
-        for (child, parents) in self.free_region_map.borrow().iter() {
-            for parent in parents.iter() {
-                e(child, parent)
-            }
-        }
-    }
     pub fn each_rvalue_scope<E>(&self, mut e:E) where E: FnMut(&ast::NodeId, &CodeExtent) {
         for (child, parent) in self.rvalue_scopes.borrow().iter() {
             e(child, parent)
@@ -408,21 +392,6 @@ pub fn each_terminating_scope<E>(&self, mut e:E) where E: FnMut(&CodeExtent) {
         }
     }
 
-    pub fn relate_free_regions(&self, sub: FreeRegion, sup: FreeRegion) {
-        match self.free_region_map.borrow_mut().get_mut(&sub) {
-            Some(sups) => {
-                if !sups.iter().any(|x| x == &sup) {
-                    sups.push(sup);
-                }
-                return;
-            }
-            None => {}
-        }
-
-        debug!("relate_free_regions(sub={:?}, sup={:?})", sub, sup);
-        self.free_region_map.borrow_mut().insert(sub, vec!(sup));
-    }
-
     /// Records that `sub_fn` is defined within `sup_fn`. These ids
     /// should be the id of the block that is the fn body, which is
     /// also the root of the region hierarchy for that fn.
@@ -567,56 +536,6 @@ pub fn is_subscope_of(&self,
         return true;
     }
 
-    /// Determines whether two free regions have a subregion relationship
-    /// by walking the graph encoded in `free_region_map`.  Note that
-    /// it is possible that `sub != sup` and `sub <= sup` and `sup <= sub`
-    /// (that is, the user can give two different names to the same lifetime).
-    pub fn sub_free_region(&self, sub: FreeRegion, sup: FreeRegion) -> bool {
-        can_reach(&*self.free_region_map.borrow(), sub, sup)
-    }
-
-    /// Determines whether one region is a subregion of another.  This is intended to run *after
-    /// inference* and sadly the logic is somewhat duplicated with the code in infer.rs.
-    pub fn is_subregion_of(&self,
-                           sub_region: ty::Region,
-                           super_region: ty::Region)
-                           -> bool {
-        debug!("is_subregion_of(sub_region={:?}, super_region={:?})",
-               sub_region, super_region);
-
-        sub_region == super_region || {
-            match (sub_region, super_region) {
-                (ty::ReEmpty, _) |
-                (_, ty::ReStatic) => {
-                    true
-                }
-
-                (ty::ReScope(sub_scope), ty::ReScope(super_scope)) => {
-                    self.is_subscope_of(sub_scope, super_scope)
-                }
-
-                (ty::ReScope(sub_scope), ty::ReFree(ref fr)) => {
-                    self.is_subscope_of(sub_scope, fr.scope.to_code_extent())
-                }
-
-                (ty::ReFree(sub_fr), ty::ReFree(super_fr)) => {
-                    self.sub_free_region(sub_fr, super_fr)
-                }
-
-                (ty::ReEarlyBound(data_a), ty::ReEarlyBound(data_b)) => {
-                    // This case is used only to make sure that explicitly-
-                    // specified `Self` types match the real self type in
-                    // implementations. Yuck.
-                    data_a == data_b
-                }
-
-                _ => {
-                    false
-                }
-            }
-        }
-    }
-
     /// Finds the nearest common ancestor (if any) of two scopes.  That is, finds the smallest
     /// scope which is greater than or equal to both `scope_a` and `scope_b`.
     pub fn nearest_common_ancestor(&self,
@@ -1291,7 +1210,6 @@ pub fn resolve_crate(sess: &Session, krate: &ast::Crate) -> RegionMaps {
     let maps = RegionMaps {
         scope_map: RefCell::new(FnvHashMap()),
         var_map: RefCell::new(NodeMap()),
-        free_region_map: RefCell::new(FnvHashMap()),
         rvalue_scopes: RefCell::new(NodeMap()),
         terminating_scopes: RefCell::new(FnvHashSet()),
         fn_tree: RefCell::new(NodeMap()),
index a9da92a768fe64c43644c22799012336e6f1e47e..6f40e17855a78255779a033ee4015b32323672f7 100644 (file)
@@ -24,6 +24,7 @@
 use middle::subst;
 use middle::ty;
 use std::fmt;
+use std::mem::replace;
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::parse::token::special_idents;
@@ -70,6 +71,9 @@ struct LifetimeContext<'a> {
 
     // I'm sorry.
     trait_ref_hack: bool,
+
+    // List of labels in the function/method currently under analysis.
+    labels_in_fn: Vec<(ast::Ident, Span)>,
 }
 
 enum ScopeChain<'a> {
@@ -97,6 +101,7 @@ pub fn krate(sess: &Session, krate: &ast::Crate, def_map: &DefMap) -> NamedRegio
         scope: &ROOT_SCOPE,
         def_map: def_map,
         trait_ref_hack: false,
+        labels_in_fn: vec![],
     }, krate);
     sess.abort_if_errors();
     named_region_map
@@ -104,6 +109,10 @@ pub fn krate(sess: &Session, krate: &ast::Crate, def_map: &DefMap) -> NamedRegio
 
 impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
     fn visit_item(&mut self, item: &ast::Item) {
+        // Items save/restore the set of labels. This way innner items
+        // can freely reuse names, be they loop labels or lifetimes.
+        let saved = replace(&mut self.labels_in_fn, vec![]);
+
         // Items always introduce a new root scope
         self.with(RootScope, |_, this| {
             match item.node {
@@ -137,6 +146,9 @@ fn visit_item(&mut self, item: &ast::Item) {
                 }
             }
         });
+
+        // Done traversing the item; restore saved set of labels.
+        replace(&mut self.labels_in_fn, saved);
     }
 
     fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
@@ -144,16 +156,16 @@ fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
         match fk {
             visit::FkItemFn(_, generics, _, _, _) => {
                 self.visit_early_late(subst::FnSpace, generics, |this| {
-                    visit::walk_fn(this, fk, fd, b, s)
+                    this.walk_fn(fk, fd, b, s)
                 })
             }
             visit::FkMethod(_, sig, _) => {
                 self.visit_early_late(subst::FnSpace, &sig.generics, |this| {
-                    visit::walk_fn(this, fk, fd, b, s)
+                    this.walk_fn(fk, fd, b, s)
                 })
             }
             visit::FkFnBlock(..) => {
-                visit::walk_fn(self, fk, fd, b, s)
+                self.walk_fn(fk, fd, b, s)
             }
         }
     }
@@ -190,6 +202,10 @@ fn visit_ty(&mut self, ty: &ast::Ty) {
     }
 
     fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
+        // We reset the labels on every trait item, so that different
+        // methods in an impl can reuse label names.
+        let saved = replace(&mut self.labels_in_fn, vec![]);
+
         if let ast::MethodTraitItem(ref sig, None) = trait_item.node {
             self.visit_early_late(
                 subst::FnSpace, &sig.generics,
@@ -197,6 +213,8 @@ fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
         } else {
             visit::walk_trait_item(self, trait_item);
         }
+
+        replace(&mut self.labels_in_fn, saved);
     }
 
     fn visit_block(&mut self, b: &ast::Block) {
@@ -286,7 +304,170 @@ fn visit_poly_trait_ref(&mut self,
     }
 }
 
+#[derive(Copy, Clone, PartialEq)]
+enum ShadowKind { Label, Lifetime }
+struct Original { kind: ShadowKind, span: Span }
+struct Shadower { kind: ShadowKind, span: Span }
+
+fn original_label(span: Span) -> Original {
+    Original { kind: ShadowKind::Label, span: span }
+}
+fn shadower_label(span: Span) -> Shadower {
+    Shadower { kind: ShadowKind::Label, span: span }
+}
+fn original_lifetime(l: &ast::Lifetime) -> Original {
+    Original { kind: ShadowKind::Lifetime, span: l.span }
+}
+fn shadower_lifetime(l: &ast::Lifetime) -> Shadower {
+    Shadower { kind: ShadowKind::Lifetime, span: l.span }
+}
+
+impl ShadowKind {
+    fn desc(&self) -> &'static str {
+        match *self {
+            ShadowKind::Label => "label",
+            ShadowKind::Lifetime => "lifetime",
+        }
+    }
+}
+
+fn signal_shadowing_problem(
+    sess: &Session, name: ast::Name, orig: Original, shadower: Shadower) {
+    if let (ShadowKind::Lifetime, ShadowKind::Lifetime) = (orig.kind, shadower.kind) {
+        // lifetime/lifetime shadowing is an error
+        sess.span_err(shadower.span,
+                      &format!("{} name `{}` shadows a \
+                                {} name that is already in scope",
+                               shadower.kind.desc(), name, orig.kind.desc()));
+    } else {
+        // shadowing involving a label is only a warning, due to issues with
+        // labels and lifetimes not being macro-hygienic.
+        sess.span_warn(shadower.span,
+                      &format!("{} name `{}` shadows a \
+                                {} name that is already in scope",
+                               shadower.kind.desc(), name, orig.kind.desc()));
+    }
+    sess.span_note(orig.span,
+                   &format!("shadowed {} `{}` declared here",
+                            orig.kind.desc(), name));
+}
+
+// Adds all labels in `b` to `ctxt.labels_in_fn`, signalling a warning
+// if one of the label shadows a lifetime or another label.
+fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v ast::Block) {
+
+    struct GatherLabels<'a> {
+        sess: &'a Session,
+        scope: Scope<'a>,
+        labels_in_fn: &'a mut Vec<(ast::Ident, Span)>,
+    }
+
+    let mut gather = GatherLabels {
+        sess: ctxt.sess,
+        scope: ctxt.scope,
+        labels_in_fn: &mut ctxt.labels_in_fn,
+    };
+    gather.visit_block(b);
+    return;
+
+    impl<'v, 'a> Visitor<'v> for GatherLabels<'a> {
+        fn visit_expr(&mut self, ex: &'v ast::Expr) {
+            if let Some(label) = expression_label(ex) {
+                for &(prior, prior_span) in &self.labels_in_fn[..] {
+                    // FIXME (#24278): non-hygienic comparision
+                    if label.name == prior.name {
+                        signal_shadowing_problem(self.sess,
+                                                 label.name,
+                                                 original_label(prior_span),
+                                                 shadower_label(ex.span));
+                    }
+                }
+
+                check_if_label_shadows_lifetime(self.sess,
+                                                self.scope,
+                                                label,
+                                                ex.span);
+
+                self.labels_in_fn.push((label, ex.span));
+            }
+            visit::walk_expr(self, ex)
+        }
+
+        fn visit_item(&mut self, _: &ast::Item) {
+            // do not recurse into items defined in the block
+        }
+    }
+
+    fn expression_label(ex: &ast::Expr) -> Option<ast::Ident> {
+        match ex.node {
+            ast::ExprWhile(_, _, Some(label))       |
+            ast::ExprWhileLet(_, _, _, Some(label)) |
+            ast::ExprForLoop(_, _, _, Some(label))  |
+            ast::ExprLoop(_, Some(label))          => Some(label),
+            _ => None,
+        }
+    }
+
+    fn check_if_label_shadows_lifetime<'a>(sess: &'a Session,
+                                           mut scope: Scope<'a>,
+                                           label: ast::Ident,
+                                           label_span: Span) {
+        loop {
+            match *scope {
+                BlockScope(_, s) => { scope = s; }
+                RootScope => { return; }
+
+                EarlyScope(_, lifetimes, s) |
+                LateScope(lifetimes, s) => {
+                    for lifetime_def in lifetimes {
+                        // FIXME (#24278): non-hygienic comparision
+                        if label.name == lifetime_def.lifetime.name {
+                            signal_shadowing_problem(
+                                sess,
+                                label.name,
+                                original_lifetime(&lifetime_def.lifetime),
+                                shadower_label(label_span));
+                            return;
+                        }
+                    }
+                    scope = s;
+                }
+            }
+        }
+    }
+}
+
 impl<'a> LifetimeContext<'a> {
+    // This is just like visit::walk_fn, except that it extracts the
+    // labels of the function body and swaps them in before visiting
+    // the function body itself.
+    fn walk_fn<'b>(&mut self,
+                   fk: visit::FnKind,
+                   fd: &ast::FnDecl,
+                   fb: &'b ast::Block,
+                   _span: Span) {
+        match fk {
+            visit::FkItemFn(_, generics, _, _, _) => {
+                visit::walk_fn_decl(self, fd);
+                self.visit_generics(generics);
+            }
+            visit::FkMethod(_, sig, _) => {
+                visit::walk_fn_decl(self, fd);
+                self.visit_generics(&sig.generics);
+                self.visit_explicit_self(&sig.explicit_self);
+            }
+            visit::FkFnBlock(..) => {
+                visit::walk_fn_decl(self, fd);
+            }
+        }
+
+        // After inpsecting the decl, add all labels from the body to
+        // `self.labels_in_fn`.
+        extract_labels(self, fb);
+
+        self.visit_block(fb);
+    }
+
     fn with<F>(&mut self, wrap_scope: ScopeChain, f: F) where
         F: FnOnce(Scope, &mut LifetimeContext),
     {
@@ -297,6 +478,7 @@ fn with<F>(&mut self, wrap_scope: ScopeChain, f: F) where
             scope: &wrap_scope,
             def_map: self.def_map,
             trait_ref_hack: self.trait_ref_hack,
+            labels_in_fn: self.labels_in_fn.clone(),
         };
         debug!("entering scope {:?}", this.scope);
         f(self.scope, &mut this);
@@ -494,6 +676,17 @@ fn check_lifetime_def_for_shadowing(&self,
                                         mut old_scope: Scope,
                                         lifetime: &ast::Lifetime)
     {
+        for &(label, label_span) in &self.labels_in_fn {
+            // FIXME (#24278): non-hygienic comparision
+            if lifetime.name == label.name {
+                signal_shadowing_problem(self.sess,
+                                         lifetime.name,
+                                         original_label(label_span),
+                                         shadower_lifetime(&lifetime));
+                return;
+            }
+        }
+
         loop {
             match *old_scope {
                 BlockScope(_, s) => {
@@ -507,15 +700,11 @@ fn check_lifetime_def_for_shadowing(&self,
                 EarlyScope(_, lifetimes, s) |
                 LateScope(lifetimes, s) => {
                     if let Some((_, lifetime_def)) = search_lifetimes(lifetimes, lifetime) {
-                        self.sess.span_err(
-                            lifetime.span,
-                            &format!("lifetime name `{}` shadows another \
-                                     lifetime name that is already in scope",
-                                     token::get_name(lifetime.name)));
-                        self.sess.span_note(
-                            lifetime_def.span,
-                            &format!("shadowed lifetime `{}` declared here",
-                                     token::get_name(lifetime.name)));
+                        signal_shadowing_problem(
+                            self.sess,
+                            lifetime.name,
+                            original_lifetime(&lifetime_def),
+                            shadower_lifetime(&lifetime));
                         return;
                     }
 
index e7c25d82150933e72d92401659e76304abb7151c..d75dc861e83304a0702fb699333b7df9c3e3185c 100644 (file)
@@ -95,9 +95,9 @@ fn annotate<F>(&mut self, id: NodeId, use_parent: bool,
                 let tag = attr.name();
                 if tag == "unstable" || tag == "stable" || tag == "deprecated" {
                     attr::mark_used(attr);
-                    self.sess.span_warn(attr.span(),
-                                        "stability attributes are deprecated \
-                                         and will soon become errors");
+                    self.sess.span_err(attr.span(),
+                                       "stability attributes may not be used outside \
+                                        of the standard library");
                 }
             }
             f(self);
index 8809abdd70e62b10d664263917bdab2ed643f5b6..b221c4bb685a8e501f40d48d806ff526964cedb6 100644 (file)
@@ -15,6 +15,7 @@
 pub use self::Vtable::*;
 pub use self::ObligationCauseCode::*;
 
+use middle::free_region::FreeRegionMap;
 use middle::subst;
 use middle::ty::{self, HasProjectionTypes, Ty};
 use middle::ty_fold::TypeFoldable;
@@ -424,7 +425,8 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi
         }
     };
 
-    infcx.resolve_regions_and_report_errors(body_id);
+    let free_regions = FreeRegionMap::new();
+    infcx.resolve_regions_and_report_errors(&free_regions, body_id);
     let predicates = match infcx.fully_resolve(&predicates) {
         Ok(predicates) => predicates,
         Err(fixup_err) => {
index ed8a6fb0200a46a5bd9d0b2f7c734097b806e3fe..153ec0ab2b375c439226dd173b3a46c334f757d5 100644 (file)
@@ -532,11 +532,8 @@ pub fn evaluate_impl(&mut self,
                obligation.repr(self.tcx()));
 
         self.infcx.probe(|snapshot| {
-            let (skol_obligation_trait_ref, skol_map) =
-                self.infcx().skolemize_late_bound_regions(&obligation.predicate, snapshot);
-            match self.match_impl(impl_def_id, obligation, snapshot,
-                                  &skol_map, skol_obligation_trait_ref.trait_ref.clone()) {
-                Ok(substs) => {
+            match self.match_impl(impl_def_id, obligation, snapshot) {
+                Ok((substs, skol_map)) => {
                     let vtable_impl = self.vtable_impl(impl_def_id,
                                                        substs,
                                                        obligation.cause.clone(),
@@ -1160,10 +1157,7 @@ fn assemble_candidates_from_impls(&mut self,
         let all_impls = self.all_impls(def_id);
         for &impl_def_id in &all_impls {
             self.infcx.probe(|snapshot| {
-                let (skol_obligation_trait_pred, skol_map) =
-                    self.infcx().skolemize_late_bound_regions(&obligation.predicate, snapshot);
-                match self.match_impl(impl_def_id, obligation, snapshot,
-                                      &skol_map, skol_obligation_trait_pred.trait_ref.clone()) {
+                match self.match_impl(impl_def_id, obligation, snapshot) {
                     Ok(_) => {
                         candidates.vec.push(ImplCandidate(impl_def_id));
                     }
@@ -2115,11 +2109,9 @@ fn confirm_impl_candidate(&mut self,
         // First, create the substitutions by matching the impl again,
         // this time not in a probe.
         self.infcx.commit_if_ok(|snapshot| {
-            let (skol_obligation_trait_ref, skol_map) =
-                self.infcx().skolemize_late_bound_regions(&obligation.predicate, snapshot);
-            let substs =
+            let (substs, skol_map) =
                 self.rematch_impl(impl_def_id, obligation,
-                                  snapshot, &skol_map, skol_obligation_trait_ref.trait_ref);
+                                  snapshot);
             debug!("confirm_impl_candidate substs={}", substs.repr(self.tcx()));
             Ok(self.vtable_impl(impl_def_id, substs, obligation.cause.clone(),
                                 obligation.recursion_depth + 1, skol_map, snapshot))
@@ -2306,14 +2298,11 @@ fn confirm_poly_trait_refs(&mut self,
     fn rematch_impl(&mut self,
                     impl_def_id: ast::DefId,
                     obligation: &TraitObligation<'tcx>,
-                    snapshot: &infer::CombinedSnapshot,
-                    skol_map: &infer::SkolemizationMap,
-                    skol_obligation_trait_ref: Rc<ty::TraitRef<'tcx>>)
-                    -> Normalized<'tcx, Substs<'tcx>>
+                    snapshot: &infer::CombinedSnapshot)
+                    -> (Normalized<'tcx, Substs<'tcx>>, infer::SkolemizationMap)
     {
-        match self.match_impl(impl_def_id, obligation, snapshot,
-                              skol_map, skol_obligation_trait_ref) {
-            Ok(substs) => substs,
+        match self.match_impl(impl_def_id, obligation, snapshot) {
+            Ok((substs, skol_map)) => (substs, skol_map),
             Err(()) => {
                 self.tcx().sess.bug(
                     &format!("Impl {} was matchable against {} but now is not",
@@ -2326,10 +2315,9 @@ fn rematch_impl(&mut self,
     fn match_impl(&mut self,
                   impl_def_id: ast::DefId,
                   obligation: &TraitObligation<'tcx>,
-                  snapshot: &infer::CombinedSnapshot,
-                  skol_map: &infer::SkolemizationMap,
-                  skol_obligation_trait_ref: Rc<ty::TraitRef<'tcx>>)
-                  -> Result<Normalized<'tcx, Substs<'tcx>>, ()>
+                  snapshot: &infer::CombinedSnapshot)
+                  -> Result<(Normalized<'tcx, Substs<'tcx>>,
+                             infer::SkolemizationMap), ()>
     {
         let impl_trait_ref = ty::impl_trait_ref(self.tcx(), impl_def_id).unwrap();
 
@@ -2340,6 +2328,11 @@ fn match_impl(&mut self,
             return Err(());
         }
 
+        let (skol_obligation, skol_map) = self.infcx().skolemize_late_bound_regions(
+            &obligation.predicate,
+            snapshot);
+        let skol_obligation_trait_ref = skol_obligation.trait_ref;
+
         let impl_substs = util::fresh_type_vars_for_impl(self.infcx,
                                                          obligation.cause.span,
                                                          impl_def_id);
@@ -2370,17 +2363,17 @@ fn match_impl(&mut self,
             return Err(());
         }
 
-        if let Err(e) = self.infcx.leak_check(skol_map, snapshot) {
+        if let Err(e) = self.infcx.leak_check(&skol_map, snapshot) {
             debug!("match_impl: failed leak check due to `{}`",
                    ty::type_err_to_str(self.tcx(), &e));
             return Err(());
         }
 
         debug!("match_impl: success impl_substs={}", impl_substs.repr(self.tcx()));
-        Ok(Normalized {
+        Ok((Normalized {
             value: impl_substs,
             obligations: impl_trait_ref.obligations
-        })
+        }, skol_map))
     }
 
     fn fast_reject_trait_refs(&mut self,
index 53c3cdd02af8923f22c232fd10ab74d876ad5e1b..232e962ed4d2372e90d085a5573da718d2203ff1 100644 (file)
 use middle::const_eval;
 use middle::def::{self, DefMap, ExportMap};
 use middle::dependency_format;
+use middle::free_region::FreeRegionMap;
 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
 use middle::mem_categorization as mc;
 use middle::region;
 use middle::resolve_lifetime;
 use middle::infer;
 use middle::pat_util;
+use middle::region::RegionMaps;
 use middle::stability;
 use middle::subst::{self, ParamSpace, Subst, Substs, VecPerParamSpace};
 use middle::traits;
@@ -63,6 +65,7 @@
 use util::common::{memoized, ErrorReported};
 use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
 use util::nodemap::FnvHashMap;
+use util::num::ToPrimitive;
 
 use arena::TypedArena;
 use std::borrow::{Borrow, Cow};
@@ -71,7 +74,6 @@
 use std::fmt;
 use std::hash::{Hash, SipHasher, Hasher};
 use std::mem;
-use std::num::ToPrimitive;
 use std::ops;
 use std::rc::Rc;
 use std::vec::IntoIter;
@@ -620,7 +622,14 @@ pub struct ctxt<'tcx> {
 
     pub named_region_map: resolve_lifetime::NamedRegionMap,
 
-    pub region_maps: middle::region::RegionMaps,
+    pub region_maps: RegionMaps,
+
+    // For each fn declared in the local crate, type check stores the
+    // free-region relationships that were deduced from its where
+    // clauses and parameter types. These are then read-again by
+    // borrowck. (They are not used during trans, and hence are not
+    // serialized or needed for cross-crate fns.)
+    free_region_maps: RefCell<NodeMap<FreeRegionMap>>,
 
     /// Stores the types for various nodes in the AST.  Note that this table
     /// is not guaranteed to be populated until after typeck.  See
@@ -795,6 +804,15 @@ pub fn node_types(&self) -> Ref<NodeMap<Ty<'tcx>>> { self.node_types.borrow() }
     pub fn node_type_insert(&self, id: NodeId, ty: Ty<'tcx>) {
         self.node_types.borrow_mut().insert(id, ty);
     }
+
+    pub fn store_free_region_map(&self, id: NodeId, map: FreeRegionMap) {
+        self.free_region_maps.borrow_mut()
+                             .insert(id, map);
+    }
+
+    pub fn free_region_map(&self, id: NodeId) -> FreeRegionMap {
+        self.free_region_maps.borrow()[&id].clone()
+    }
 }
 
 // Flags that we track on types. These flags are propagated upwards
@@ -2546,7 +2564,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
                      named_region_map: resolve_lifetime::NamedRegionMap,
                      map: ast_map::Map<'tcx>,
                      freevars: RefCell<FreevarMap>,
-                     region_maps: middle::region::RegionMaps,
+                     region_maps: RegionMaps,
                      lang_items: middle::lang_items::LanguageItems,
                      stability: stability::Index) -> ctxt<'tcx>
 {
@@ -2561,11 +2579,12 @@ pub fn mk_ctxt<'tcx>(s: Session,
         region_interner: RefCell::new(FnvHashMap()),
         types: common_types,
         named_region_map: named_region_map,
+        region_maps: region_maps,
+        free_region_maps: RefCell::new(FnvHashMap()),
         item_variance_map: RefCell::new(DefIdMap()),
         variance_computed: Cell::new(false),
         sess: s,
         def_map: def_map,
-        region_maps: region_maps,
         node_types: RefCell::new(FnvHashMap()),
         item_substs: RefCell::new(NodeMap()),
         impl_trait_refs: RefCell::new(NodeMap()),
@@ -6537,14 +6556,6 @@ pub fn construct_parameter_environment<'a,'tcx>(
     let bounds = liberate_late_bound_regions(tcx, free_id_outlive, &ty::Binder(bounds));
     let predicates = bounds.predicates.into_vec();
 
-    //
-    // Compute region bounds. For now, these relations are stored in a
-    // global table on the tcx, so just enter them there. I'm not
-    // crazy about this scheme, but it's convenient, at least.
-    //
-
-    record_region_bounds(tcx, &*predicates);
-
     debug!("construct_parameter_environment: free_id={:?} free_subst={:?} predicates={:?}",
            free_id,
            free_substs.repr(tcx),
@@ -6573,37 +6584,7 @@ pub fn construct_parameter_environment<'a,'tcx>(
     };
 
     let cause = traits::ObligationCause::misc(span, free_id);
-    return traits::normalize_param_env_or_error(unnormalized_env, cause);
-
-    fn record_region_bounds<'tcx>(tcx: &ty::ctxt<'tcx>, predicates: &[ty::Predicate<'tcx>]) {
-        debug!("record_region_bounds(predicates={:?})", predicates.repr(tcx));
-
-        for predicate in predicates {
-            match *predicate {
-                Predicate::Projection(..) |
-                Predicate::Trait(..) |
-                Predicate::Equate(..) |
-                Predicate::TypeOutlives(..) => {
-                    // No region bounds here
-                }
-                Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r_a, r_b))) => {
-                    match (r_a, r_b) {
-                        (ty::ReFree(fr_a), ty::ReFree(fr_b)) => {
-                            // Record that `'a:'b`. Or, put another way, `'b <= 'a`.
-                            tcx.region_maps.relate_free_regions(fr_b, fr_a);
-                        }
-                        _ => {
-                            // All named regions are instantiated with free regions.
-                            tcx.sess.bug(
-                                &format!("record_region_bounds: non free region: {} / {}",
-                                         r_a.repr(tcx),
-                                         r_b.repr(tcx)));
-                        }
-                    }
-                }
-            }
-        }
-    }
+    traits::normalize_param_env_or_error(unnormalized_env, cause)
 }
 
 impl BorrowKind {
index f7ff8b9e6061a3f6fe5c25250f1079853d30bd89..050ccd6471288ae759c4570657b68f624eec40ea 100644 (file)
@@ -418,7 +418,7 @@ fn parse_list(slot: &mut Vec<String>, v: Option<&str>)
                       -> bool {
             match v {
                 Some(s) => {
-                    for s in s.words() {
+                    for s in s.split_whitespace() {
                         slot.push(s.to_string());
                     }
                     true
@@ -431,7 +431,7 @@ fn parse_opt_list(slot: &mut Option<Vec<String>>, v: Option<&str>)
                       -> bool {
             match v {
                 Some(s) => {
-                    let v = s.words().map(|s| s.to_string()).collect();
+                    let v = s.split_whitespace().map(|s| s.to_string()).collect();
                     *slot = Some(v);
                     true
                 },
@@ -1111,7 +1111,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
 
     use session::config::{build_configuration, optgroups, build_session_options};
     use session::build_session;
diff --git a/src/librustc/util/num.rs b/src/librustc/util/num.rs
new file mode 100644 (file)
index 0000000..da04976
--- /dev/null
@@ -0,0 +1,98 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub trait ToPrimitive {
+    fn to_i8(&self) -> Option<i8>;
+    fn to_i16(&self) -> Option<i16>;
+    fn to_i32(&self) -> Option<i32>;
+    fn to_i64(&self) -> Option<i64>;
+    fn to_u8(&self) -> Option<u8>;
+    fn to_u16(&self) -> Option<u16>;
+    fn to_u32(&self) -> Option<u32>;
+    fn to_u64(&self) -> Option<u64>;
+}
+
+impl ToPrimitive for i64 {
+    fn to_i8(&self) -> Option<i8> {
+        if *self < i8::min_value() as i64 || *self > i8::max_value() as i64 {
+            None
+        } else {
+            Some(*self as i8)
+        }
+    }
+    fn to_i16(&self) -> Option<i16> {
+        if *self < i16::min_value() as i64 || *self > i16::max_value() as i64 {
+            None
+        } else {
+            Some(*self as i16)
+        }
+    }
+    fn to_i32(&self) -> Option<i32> {
+        if *self < i32::min_value() as i64 || *self > i32::max_value() as i64 {
+            None
+        } else {
+            Some(*self as i32)
+        }
+    }
+    fn to_i64(&self) -> Option<i64> {
+        Some(*self)
+    }
+    fn to_u8(&self) -> Option<u8> {
+        if *self < 0 || *self > u8::max_value() as i64 {
+            None
+        } else {
+            Some(*self as u8)
+        }
+    }
+    fn to_u16(&self) -> Option<u16> {
+        if *self < 0 || *self > u16::max_value() as i64 {
+            None
+        } else {
+            Some(*self as u16)
+        }
+    }
+    fn to_u32(&self) -> Option<u32> {
+        if *self < 0 || *self > u32::max_value() as i64 {
+            None
+        } else {
+            Some(*self as u32)
+        }
+    }
+    fn to_u64(&self) -> Option<u64> {
+        if *self < 0 {None} else {Some(*self as u64)}
+    }
+}
+
+impl ToPrimitive for u64 {
+    fn to_i8(&self) -> Option<i8> {
+        if *self > i8::max_value() as u64 {None} else {Some(*self as i8)}
+    }
+    fn to_i16(&self) -> Option<i16> {
+        if *self > i16::max_value() as u64 {None} else {Some(*self as i16)}
+    }
+    fn to_i32(&self) -> Option<i32> {
+        if *self > i32::max_value() as u64 {None} else {Some(*self as i32)}
+    }
+    fn to_i64(&self) -> Option<i64> {
+        if *self > i64::max_value() as u64 {None} else {Some(*self as i64)}
+    }
+    fn to_u8(&self) -> Option<u8> {
+        if *self > u8::max_value() as u64 {None} else {Some(*self as u8)}
+    }
+    fn to_u16(&self) -> Option<u16> {
+        if *self > u16::max_value() as u64 {None} else {Some(*self as u16)}
+    }
+    fn to_u32(&self) -> Option<u32> {
+        if *self > u32::max_value() as u64 {None} else {Some(*self as u32)}
+    }
+    fn to_u64(&self) -> Option<u64> {
+        Some(*self)
+    }
+}
index 9f5751c421ecebe39ad56cc1f866e2bd0a916b19..37d784692fd0e48faf035d1168f6a78cba8e6b11 100644 (file)
 //! A helper class for dealing with static archives
 
 use std::env;
-use std::fs;
+use std::fs::{self, File};
 use std::io::prelude::*;
 use std::io;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Output, Stdio};
 use std::str;
 use syntax::diagnostic::Handler as ErrorHandler;
+use rustc_llvm::archive_ro::ArchiveRO;
 
 use tempdir::TempDir;
 
@@ -282,17 +283,14 @@ fn add_archive<F>(&mut self, archive: &Path, name: &str,
                       mut skip: F) -> io::Result<()>
         where F: FnMut(&str) -> bool,
     {
-        let loc = TempDir::new("rsar").unwrap();
-
-        // First, extract the contents of the archive to a temporary directory.
-        // We don't unpack directly into `self.work_dir` due to the possibility
-        // of filename collisions.
-        let archive = env::current_dir().unwrap().join(archive);
-        run_ar(self.archive.handler, &self.archive.maybe_ar_prog,
-               "x", Some(loc.path()), &[&archive]);
+        let archive = match ArchiveRO::open(archive) {
+            Some(ar) => ar,
+            None => return Err(io::Error::new(io::ErrorKind::Other,
+                                              "failed to open archive")),
+        };
 
         // Next, we must rename all of the inputs to "guaranteed unique names".
-        // We move each file into `self.work_dir` under its new unique name.
+        // We write each file into `self.work_dir` under its new unique name.
         // The reason for this renaming is that archives are keyed off the name
         // of the files, so if two files have the same name they will override
         // one another in the archive (bad).
@@ -300,27 +298,46 @@ fn add_archive<F>(&mut self, archive: &Path, name: &str,
         // We skip any files explicitly desired for skipping, and we also skip
         // all SYMDEF files as these are just magical placeholders which get
         // re-created when we make a new archive anyway.
-        let files = try!(fs::read_dir(loc.path()));
-        for file in files {
-            let file = try!(file).path();
-            let filename = file.file_name().unwrap().to_str().unwrap();
-            if skip(filename) { continue }
+        for file in archive.iter() {
+            let filename = match file.name() {
+                Some(s) => s,
+                None => continue,
+            };
             if filename.contains(".SYMDEF") { continue }
+            if skip(filename) { continue }
 
-            let filename = format!("r-{}-{}", name, filename);
-            // LLDB (as mentioned in back::link) crashes on filenames of exactly
-            // 16 bytes in length. If we're including an object file with
-            // exactly 16-bytes of characters, give it some prefix so that it's
-            // not 16 bytes.
-            let filename = if filename.len() == 16 {
-                format!("lldb-fix-{}", filename)
-            } else {
-                filename
-            };
-            let new_filename = self.work_dir.path().join(&filename[..]);
-            try!(fs::rename(&file, &new_filename));
-            self.members.push(PathBuf::from(filename));
+            // An archive can contain files of the same name multiple times, so
+            // we need to be sure to not have them overwrite one another when we
+            // extract them. Consequently we need to find a truly unique file
+            // name for us!
+            let mut new_filename = String::new();
+            for n in 0.. {
+                let n = if n == 0 {String::new()} else {format!("-{}", n)};
+                new_filename = format!("r{}-{}-{}", n, name, filename);
+
+                // LLDB (as mentioned in back::link) crashes on filenames of
+                // exactly
+                // 16 bytes in length. If we're including an object file with
+                //    exactly 16-bytes of characters, give it some prefix so
+                //    that it's not 16 bytes.
+                new_filename = if new_filename.len() == 16 {
+                    format!("lldb-fix-{}", new_filename)
+                } else {
+                    new_filename
+                };
+
+                let present = self.members.iter().filter_map(|p| {
+                    p.file_name().and_then(|f| f.to_str())
+                }).any(|s| s == new_filename);
+                if !present {
+                    break
+                }
+            }
+            let dst = self.work_dir.path().join(&new_filename);
+            try!(try!(File::create(&dst)).write_all(file.data()));
+            self.members.push(PathBuf::from(new_filename));
         }
+
         Ok(())
     }
 }
index 2ab4d7ff78a1d256edc6fad38d6e96b17e308412..37e3efb4d83fe112a39c11be151adffb76fdb93a 100644 (file)
@@ -41,7 +41,7 @@ fn realpath(pathname: *const libc::c_char, resolved: *mut libc::c_char)
 }
 
 #[cfg(all(not(windows), test))]
-mod test {
+mod tests {
     use tempdir::TempDir;
     use std::fs::{self, File};
     use super::realpath;
index 3c54d6631f893897532778033f8481594587a05a..22dea4757ed662a8942c198ab7ac0e7b5a38b655 100644 (file)
@@ -46,6 +46,7 @@
 extern crate syntax;
 extern crate libc;
 extern crate serialize;
+extern crate rustc_llvm;
 #[macro_use] extern crate log;
 
 pub mod abi;
index 58073079d31dffcdaf725bc6d7056bfdaaa9de1a..1daeb1cb223e279670efd5d089a07ef87b19a1a3 100644 (file)
@@ -171,7 +171,7 @@ fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
 }
 
 #[cfg(all(unix, test))]
-mod test {
+mod tests {
     use super::{RPathConfig};
     use super::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output};
     use std::path::{Path, PathBuf};
index 898f20e74518fca23d44b4912ea5da69d2d7eb47..9ed827da8b2e4de2194e8289b282b2b6f6c4e5a0 100644 (file)
 //! use. This implementation is not intended for external use or for any use where security is
 //! important.
 
-#![allow(deprecated)] // to_be32
-
 use std::iter::repeat;
-use std::num::Int;
 use std::slice::bytes::{MutableByteVector, copy_memory};
 use serialize::hex::ToHex;
 
@@ -61,10 +58,10 @@ fn to_bits(self) -> (u64, u64) {
 
 /// Adds the specified number of bytes to the bit count. panic!() if this would cause numeric
 /// overflow.
-fn add_bytes_to_bits<T: Int + ToBits>(bits: T, bytes: T) -> T {
+fn add_bytes_to_bits(bits: u64, bytes: u64) -> u64 {
     let (new_high_bits, new_low_bits) = bytes.to_bits();
 
-    if new_high_bits > T::zero() {
+    if new_high_bits > 0 {
         panic!("numeric overflow occurred.")
     }
 
@@ -543,14 +540,14 @@ mod tests {
     // A normal addition - no overflow occurs
     #[test]
     fn test_add_bytes_to_bits_ok() {
-        assert!(super::add_bytes_to_bits::<u64>(100, 10) == 180);
+        assert!(super::add_bytes_to_bits(100, 10) == 180);
     }
 
     // A simple failure case - adding 1 to the max value
     #[test]
     #[should_panic]
     fn test_add_bytes_to_bits_overflow() {
-        super::add_bytes_to_bits::<u64>(u64::MAX, 1);
+        super::add_bytes_to_bits(u64::MAX, 1);
     }
 
     struct Test {
index 502321d07598cf2e058f49956a7fc529a3838048..aedc0d23cfe1ddee4e21deda1fa07dce51be08de 100644 (file)
 use rustc::middle::dataflow::KillFrom;
 use rustc::middle::expr_use_visitor as euv;
 use rustc::middle::mem_categorization as mc;
+use rustc::middle::free_region::FreeRegionMap;
 use rustc::middle::region;
 use rustc::middle::ty::{self, Ty};
 use rustc::util::ppaux::{note_and_explain_region, Repr, UserString};
+use std::mem;
 use std::rc::Rc;
 use std::string::String;
 use syntax::ast;
 impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> {
     fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl,
                 b: &'v Block, s: Span, id: ast::NodeId) {
-        borrowck_fn(self, fk, fd, b, s, id);
+        match fk {
+            visit::FkItemFn(..) |
+            visit::FkMethod(..) => {
+                let new_free_region_map = self.tcx.free_region_map(id);
+                let old_free_region_map =
+                    mem::replace(&mut self.free_region_map, new_free_region_map);
+                borrowck_fn(self, fk, fd, b, s, id);
+                self.free_region_map = old_free_region_map;
+            }
+
+            visit::FkFnBlock => {
+                borrowck_fn(self, fk, fd, b, s, id);
+            }
+        }
     }
 
     fn visit_item(&mut self, item: &ast::Item) {
@@ -67,6 +82,7 @@ fn visit_item(&mut self, item: &ast::Item) {
 pub fn check_crate(tcx: &ty::ctxt) {
     let mut bccx = BorrowckCtxt {
         tcx: tcx,
+        free_region_map: FreeRegionMap::new(),
         stats: BorrowStats {
             loaned_paths_same: 0,
             loaned_paths_imm: 0,
@@ -129,11 +145,13 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
     let cfg = cfg::CFG::new(this.tcx, body);
     let AnalysisData { all_loans,
                        loans: loan_dfcx,
-                       move_data:flowed_moves } =
+                       move_data: flowed_moves } =
         build_borrowck_dataflow_data(this, fk, decl, &cfg, body, sp, id);
 
     move_data::fragments::instrument_move_fragments(&flowed_moves.move_data,
-                                                    this.tcx, sp, id);
+                                                    this.tcx,
+                                                    sp,
+                                                    id);
 
     check_loans::check_loans(this,
                              &loan_dfcx,
@@ -152,7 +170,9 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
                                           cfg: &cfg::CFG,
                                           body: &ast::Block,
                                           sp: Span,
-                                          id: ast::NodeId) -> AnalysisData<'a, 'tcx> {
+                                          id: ast::NodeId)
+                                          -> AnalysisData<'a, 'tcx>
+{
     // Check the body of fn items.
     let id_range = ast_util::compute_id_range_for_fn_body(fk, decl, body, sp, id);
     let (all_loans, move_data) =
@@ -203,10 +223,13 @@ pub fn from_fn_like(f: &'a FnLikeNode,
 /// the `BorrowckCtxt` itself , e.g. the flowgraph visualizer.
 pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
     tcx: &'a ty::ctxt<'tcx>,
-    input: FnPartsWithCFG<'a>) -> (BorrowckCtxt<'a, 'tcx>, AnalysisData<'a, 'tcx>) {
+    input: FnPartsWithCFG<'a>)
+    -> (BorrowckCtxt<'a, 'tcx>, AnalysisData<'a, 'tcx>)
+{
 
     let mut bccx = BorrowckCtxt {
         tcx: tcx,
+        free_region_map: FreeRegionMap::new(),
         stats: BorrowStats {
             loaned_paths_same: 0,
             loaned_paths_imm: 0,
@@ -234,6 +257,18 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
 pub struct BorrowckCtxt<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
 
+    // Hacky. As we visit various fns, we have to load up the
+    // free-region map for each one. This map is computed by during
+    // typeck for each fn item and stored -- closures just use the map
+    // from the fn item that encloses them. Since we walk the fns in
+    // order, we basically just overwrite this field as we enter a fn
+    // item and restore it afterwards in a stack-like fashion. Then
+    // the borrow checking code can assume that `free_region_map` is
+    // always the correct map for the current fn. Feels like it'd be
+    // better to just recompute this, rather than store it, but it's a
+    // bit of a pain to factor that code out at the moment.
+    free_region_map: FreeRegionMap,
+
     // Statistics:
     stats: BorrowStats
 }
@@ -518,8 +553,9 @@ pub enum MovedValueUseKind {
 
 impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
     pub fn is_subregion_of(&self, r_sub: ty::Region, r_sup: ty::Region)
-                           -> bool {
-        self.tcx.region_maps.is_subregion_of(r_sub, r_sup)
+                           -> bool
+    {
+        self.free_region_map.is_subregion_of(self.tcx, r_sub, r_sup)
     }
 
     pub fn report(&self, err: BckError<'tcx>) {
index 5741544fe5419638d262839ab3c512d8e4ef4a28..17fd0b81536258d5c229c229c34533bc1789558e 100644 (file)
@@ -36,7 +36,7 @@
 use snapshot_vec::{SnapshotVec, SnapshotVecDelegate};
 
 #[cfg(test)]
-mod test;
+mod tests;
 
 pub struct Graph<N,E> {
     nodes: SnapshotVec<Node<N>> ,
diff --git a/src/librustc_data_structures/graph/test.rs b/src/librustc_data_structures/graph/test.rs
deleted file mode 100644 (file)
index 33b2edd..0000000
+++ /dev/null
@@ -1,139 +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.
-
-use graph::*;
-use std::fmt::Debug;
-
-type TestNode = Node<&'static str>;
-type TestEdge = Edge<&'static str>;
-type TestGraph = Graph<&'static str, &'static str>;
-
-fn create_graph() -> TestGraph {
-    let mut graph = Graph::new();
-
-    // Create a simple graph
-    //
-    //    A -+> B --> C
-    //       |  |     ^
-    //       |  v     |
-    //       F  D --> E
-
-    let a = graph.add_node("A");
-    let b = graph.add_node("B");
-    let c = graph.add_node("C");
-    let d = graph.add_node("D");
-    let e = graph.add_node("E");
-    let f = graph.add_node("F");
-
-    graph.add_edge(a, b, "AB");
-    graph.add_edge(b, c, "BC");
-    graph.add_edge(b, d, "BD");
-    graph.add_edge(d, e, "DE");
-    graph.add_edge(e, c, "EC");
-    graph.add_edge(f, b, "FB");
-
-    return graph;
-}
-
-#[test]
-fn each_node() {
-    let graph = create_graph();
-    let expected = ["A", "B", "C", "D", "E", "F"];
-    graph.each_node(|idx, node| {
-        assert_eq!(&expected[idx.0], graph.node_data(idx));
-        assert_eq!(expected[idx.0], node.data);
-        true
-    });
-}
-
-#[test]
-fn each_edge() {
-    let graph = create_graph();
-    let expected = ["AB", "BC", "BD", "DE", "EC", "FB"];
-    graph.each_edge(|idx, edge| {
-        assert_eq!(&expected[idx.0], graph.edge_data(idx));
-        assert_eq!(expected[idx.0], edge.data);
-        true
-    });
-}
-
-fn test_adjacent_edges<N:PartialEq+Debug,E:PartialEq+Debug>(graph: &Graph<N,E>,
-                                                            start_index: NodeIndex,
-                                                            start_data: N,
-                                                            expected_incoming: &[(E,N)],
-                                                            expected_outgoing: &[(E,N)]) {
-    assert!(graph.node_data(start_index) == &start_data);
-
-    let mut counter = 0;
-    for (edge_index, edge) in graph.incoming_edges(start_index) {
-        assert!(graph.edge_data(edge_index) == &edge.data);
-        assert!(counter < expected_incoming.len());
-        debug!("counter={:?} expected={:?} edge_index={:?} edge={:?}",
-               counter, expected_incoming[counter], edge_index, edge);
-        match expected_incoming[counter] {
-            (ref e, ref n) => {
-                assert!(e == &edge.data);
-                assert!(n == graph.node_data(edge.source()));
-                assert!(start_index == edge.target);
-            }
-        }
-        counter += 1;
-    }
-    assert_eq!(counter, expected_incoming.len());
-
-    let mut counter = 0;
-    for (edge_index, edge) in graph.outgoing_edges(start_index) {
-        assert!(graph.edge_data(edge_index) == &edge.data);
-        assert!(counter < expected_outgoing.len());
-        debug!("counter={:?} expected={:?} edge_index={:?} edge={:?}",
-               counter, expected_outgoing[counter], edge_index, edge);
-        match expected_outgoing[counter] {
-            (ref e, ref n) => {
-                assert!(e == &edge.data);
-                assert!(start_index == edge.source);
-                assert!(n == graph.node_data(edge.target));
-            }
-        }
-        counter += 1;
-    }
-    assert_eq!(counter, expected_outgoing.len());
-}
-
-#[test]
-fn each_adjacent_from_a() {
-    let graph = create_graph();
-    test_adjacent_edges(&graph, NodeIndex(0), "A",
-                        &[],
-                        &[("AB", "B")]);
-}
-
-#[test]
-fn each_adjacent_from_b() {
-    let graph = create_graph();
-    test_adjacent_edges(&graph, NodeIndex(1), "B",
-                        &[("FB", "F"), ("AB", "A"),],
-                        &[("BD", "D"), ("BC", "C"),]);
-}
-
-#[test]
-fn each_adjacent_from_c() {
-    let graph = create_graph();
-    test_adjacent_edges(&graph, NodeIndex(2), "C",
-                        &[("EC", "E"), ("BC", "B")],
-                        &[]);
-}
-
-#[test]
-fn each_adjacent_from_d() {
-    let graph = create_graph();
-    test_adjacent_edges(&graph, NodeIndex(3), "D",
-                        &[("BD", "B")],
-                        &[("DE", "E")]);
-}
diff --git a/src/librustc_data_structures/graph/tests.rs b/src/librustc_data_structures/graph/tests.rs
new file mode 100644 (file)
index 0000000..33b2edd
--- /dev/null
@@ -0,0 +1,139 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-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 graph::*;
+use std::fmt::Debug;
+
+type TestNode = Node<&'static str>;
+type TestEdge = Edge<&'static str>;
+type TestGraph = Graph<&'static str, &'static str>;
+
+fn create_graph() -> TestGraph {
+    let mut graph = Graph::new();
+
+    // Create a simple graph
+    //
+    //    A -+> B --> C
+    //       |  |     ^
+    //       |  v     |
+    //       F  D --> E
+
+    let a = graph.add_node("A");
+    let b = graph.add_node("B");
+    let c = graph.add_node("C");
+    let d = graph.add_node("D");
+    let e = graph.add_node("E");
+    let f = graph.add_node("F");
+
+    graph.add_edge(a, b, "AB");
+    graph.add_edge(b, c, "BC");
+    graph.add_edge(b, d, "BD");
+    graph.add_edge(d, e, "DE");
+    graph.add_edge(e, c, "EC");
+    graph.add_edge(f, b, "FB");
+
+    return graph;
+}
+
+#[test]
+fn each_node() {
+    let graph = create_graph();
+    let expected = ["A", "B", "C", "D", "E", "F"];
+    graph.each_node(|idx, node| {
+        assert_eq!(&expected[idx.0], graph.node_data(idx));
+        assert_eq!(expected[idx.0], node.data);
+        true
+    });
+}
+
+#[test]
+fn each_edge() {
+    let graph = create_graph();
+    let expected = ["AB", "BC", "BD", "DE", "EC", "FB"];
+    graph.each_edge(|idx, edge| {
+        assert_eq!(&expected[idx.0], graph.edge_data(idx));
+        assert_eq!(expected[idx.0], edge.data);
+        true
+    });
+}
+
+fn test_adjacent_edges<N:PartialEq+Debug,E:PartialEq+Debug>(graph: &Graph<N,E>,
+                                                            start_index: NodeIndex,
+                                                            start_data: N,
+                                                            expected_incoming: &[(E,N)],
+                                                            expected_outgoing: &[(E,N)]) {
+    assert!(graph.node_data(start_index) == &start_data);
+
+    let mut counter = 0;
+    for (edge_index, edge) in graph.incoming_edges(start_index) {
+        assert!(graph.edge_data(edge_index) == &edge.data);
+        assert!(counter < expected_incoming.len());
+        debug!("counter={:?} expected={:?} edge_index={:?} edge={:?}",
+               counter, expected_incoming[counter], edge_index, edge);
+        match expected_incoming[counter] {
+            (ref e, ref n) => {
+                assert!(e == &edge.data);
+                assert!(n == graph.node_data(edge.source()));
+                assert!(start_index == edge.target);
+            }
+        }
+        counter += 1;
+    }
+    assert_eq!(counter, expected_incoming.len());
+
+    let mut counter = 0;
+    for (edge_index, edge) in graph.outgoing_edges(start_index) {
+        assert!(graph.edge_data(edge_index) == &edge.data);
+        assert!(counter < expected_outgoing.len());
+        debug!("counter={:?} expected={:?} edge_index={:?} edge={:?}",
+               counter, expected_outgoing[counter], edge_index, edge);
+        match expected_outgoing[counter] {
+            (ref e, ref n) => {
+                assert!(e == &edge.data);
+                assert!(start_index == edge.source);
+                assert!(n == graph.node_data(edge.target));
+            }
+        }
+        counter += 1;
+    }
+    assert_eq!(counter, expected_outgoing.len());
+}
+
+#[test]
+fn each_adjacent_from_a() {
+    let graph = create_graph();
+    test_adjacent_edges(&graph, NodeIndex(0), "A",
+                        &[],
+                        &[("AB", "B")]);
+}
+
+#[test]
+fn each_adjacent_from_b() {
+    let graph = create_graph();
+    test_adjacent_edges(&graph, NodeIndex(1), "B",
+                        &[("FB", "F"), ("AB", "A"),],
+                        &[("BD", "D"), ("BC", "C"),]);
+}
+
+#[test]
+fn each_adjacent_from_c() {
+    let graph = create_graph();
+    test_adjacent_edges(&graph, NodeIndex(2), "C",
+                        &[("EC", "E"), ("BC", "B")],
+                        &[]);
+}
+
+#[test]
+fn each_adjacent_from_d() {
+    let graph = create_graph();
+    test_adjacent_edges(&graph, NodeIndex(3), "D",
+                        &[("BD", "B")],
+                        &[("DE", "E")]);
+}
index dc376deebc113f941ff3cfd08a2cf76f05e1b04c..1f8f7694ff90dcf454dc03763108679b78656d7f 100644 (file)
 #![unstable(feature = "rustc_private")]
 #![crate_type = "dylib"]
 #![crate_type = "rlib"]
+#![staged_api]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/")]
 
-#![feature(rustc_private)]
+#![feature(rustc_private, staged_api)]
 #![cfg_attr(test, feature(test))]
 
 #[macro_use] extern crate log;
index 7036c010c6580898d87c3973654f454034e54ece..a899bbacc03016f8c624d68c8d18758f90b57c12 100644 (file)
@@ -14,7 +14,7 @@
 use snapshot_vec as sv;
 
 #[cfg(test)]
-mod test;
+mod tests;
 
 /// This trait is implemented by any type that can serve as a type
 /// variable. We call such variables *unification keys*. For example,
diff --git a/src/librustc_data_structures/unify/test.rs b/src/librustc_data_structures/unify/test.rs
deleted file mode 100644 (file)
index dbe3cfc..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(non_snake_case)]
-
-extern crate test;
-use self::test::Bencher;
-use std::collections::HashSet;
-use unify::{UnifyKey, UnificationTable};
-
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-struct UnitKey(u32);
-
-impl UnifyKey for UnitKey {
-    type Value = ();
-    fn index(&self) -> u32 { self.0 }
-    fn from_index(u: u32) -> UnitKey { UnitKey(u) }
-    fn tag(_: Option<UnitKey>) -> &'static str { "UnitKey" }
-}
-
-#[test]
-fn basic() {
-    let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
-    let k1 = ut.new_key(());
-    let k2 = ut.new_key(());
-    assert_eq!(ut.unioned(k1, k2), false);
-    ut.union(k1, k2);
-    assert_eq!(ut.unioned(k1, k2), true);
-}
-
-#[test]
-fn big_array() {
-    let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
-    let mut keys = Vec::new();
-    const MAX: usize = 1 << 15;
-
-    for _ in 0..MAX {
-        keys.push(ut.new_key(()));
-    }
-
-    for i in 1..MAX {
-        let l = keys[i-1];
-        let r = keys[i];
-        ut.union(l, r);
-    }
-
-    for i in 0..MAX {
-        assert!(ut.unioned(keys[0], keys[i]));
-    }
-}
-
-#[bench]
-fn big_array_bench(b: &mut Bencher) {
-    let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
-    let mut keys = Vec::new();
-    const MAX: usize = 1 << 15;
-
-    for _ in 0..MAX {
-        keys.push(ut.new_key(()));
-    }
-
-
-    b.iter(|| {
-        for i in 1..MAX {
-            let l = keys[i-1];
-            let r = keys[i];
-            ut.union(l, r);
-        }
-
-        for i in 0..MAX {
-            assert!(ut.unioned(keys[0], keys[i]));
-        }
-    })
-}
-
-#[test]
-fn even_odd() {
-    let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
-    let mut keys = Vec::new();
-    const MAX: usize = 1 << 10;
-
-    for i in 0..MAX {
-        let key = ut.new_key(());
-        keys.push(key);
-
-        if i >= 2 {
-            ut.union(key, keys[i-2]);
-        }
-    }
-
-    for i in 1..MAX {
-        assert!(!ut.unioned(keys[i-1], keys[i]));
-    }
-
-    for i in 2..MAX {
-        assert!(ut.unioned(keys[i-2], keys[i]));
-    }
-}
-
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-struct IntKey(u32);
-
-impl UnifyKey for IntKey {
-    type Value = Option<i32>;
-    fn index(&self) -> u32 { self.0 }
-    fn from_index(u: u32) -> IntKey { IntKey(u) }
-    fn tag(_: Option<IntKey>) -> &'static str { "IntKey" }
-}
-
-/// Test unifying a key whose value is `Some(_)`  with a key whose value is `None`.
-/// Afterwards both should be `Some(_)`.
-#[test]
-fn unify_key_Some_key_None() {
-    let mut ut: UnificationTable<IntKey> = UnificationTable::new();
-    let k1 = ut.new_key(Some(22));
-    let k2 = ut.new_key(None);
-    assert!(ut.unify_var_var(k1, k2).is_ok());
-    assert_eq!(ut.probe(k2), Some(22));
-    assert_eq!(ut.probe(k1), Some(22));
-}
-
-/// Test unifying a key whose value is `None`  with a key whose value is `Some(_)`.
-/// Afterwards both should be `Some(_)`.
-#[test]
-fn unify_key_None_key_Some() {
-    let mut ut: UnificationTable<IntKey> = UnificationTable::new();
-    let k1 = ut.new_key(Some(22));
-    let k2 = ut.new_key(None);
-    assert!(ut.unify_var_var(k2, k1).is_ok());
-    assert_eq!(ut.probe(k2), Some(22));
-    assert_eq!(ut.probe(k1), Some(22));
-}
-
-/// Test unifying a key whose value is `Some(x)` with a key whose value is `Some(y)`.
-/// This should yield an error.
-#[test]
-fn unify_key_Some_x_key_Some_y() {
-    let mut ut: UnificationTable<IntKey> = UnificationTable::new();
-    let k1 = ut.new_key(Some(22));
-    let k2 = ut.new_key(Some(23));
-    assert_eq!(ut.unify_var_var(k1, k2), Err((22, 23)));
-    assert_eq!(ut.unify_var_var(k2, k1), Err((23, 22)));
-    assert_eq!(ut.probe(k1), Some(22));
-    assert_eq!(ut.probe(k2), Some(23));
-}
-
-/// Test unifying a key whose value is `Some(x)` with a key whose value is `Some(x)`.
-/// This should be ok.
-#[test]
-fn unify_key_Some_x_key_Some_x() {
-    let mut ut: UnificationTable<IntKey> = UnificationTable::new();
-    let k1 = ut.new_key(Some(22));
-    let k2 = ut.new_key(Some(22));
-    assert!(ut.unify_var_var(k1, k2).is_ok());
-    assert_eq!(ut.probe(k1), Some(22));
-    assert_eq!(ut.probe(k2), Some(22));
-}
-
-/// Test unifying a key whose value is `None` with a value is `x`.
-/// Afterwards key should be `x`.
-#[test]
-fn unify_key_None_val() {
-    let mut ut: UnificationTable<IntKey> = UnificationTable::new();
-    let k1 = ut.new_key(None);
-    assert!(ut.unify_var_value(k1, 22).is_ok());
-    assert_eq!(ut.probe(k1), Some(22));
-}
-
-/// Test unifying a key whose value is `Some(x)` with the value `y`.
-/// This should yield an error.
-#[test]
-fn unify_key_Some_x_val_y() {
-    let mut ut: UnificationTable<IntKey> = UnificationTable::new();
-    let k1 = ut.new_key(Some(22));
-    assert_eq!(ut.unify_var_value(k1, 23), Err((22, 23)));
-    assert_eq!(ut.probe(k1), Some(22));
-}
-
-/// Test unifying a key whose value is `Some(x)` with the value `x`.
-/// This should be ok.
-#[test]
-fn unify_key_Some_x_val_x() {
-    let mut ut: UnificationTable<IntKey> = UnificationTable::new();
-    let k1 = ut.new_key(Some(22));
-    assert!(ut.unify_var_value(k1, 22).is_ok());
-    assert_eq!(ut.probe(k1), Some(22));
-}
-
diff --git a/src/librustc_data_structures/unify/tests.rs b/src/librustc_data_structures/unify/tests.rs
new file mode 100644 (file)
index 0000000..dbe3cfc
--- /dev/null
@@ -0,0 +1,195 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(non_snake_case)]
+
+extern crate test;
+use self::test::Bencher;
+use std::collections::HashSet;
+use unify::{UnifyKey, UnificationTable};
+
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
+struct UnitKey(u32);
+
+impl UnifyKey for UnitKey {
+    type Value = ();
+    fn index(&self) -> u32 { self.0 }
+    fn from_index(u: u32) -> UnitKey { UnitKey(u) }
+    fn tag(_: Option<UnitKey>) -> &'static str { "UnitKey" }
+}
+
+#[test]
+fn basic() {
+    let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
+    let k1 = ut.new_key(());
+    let k2 = ut.new_key(());
+    assert_eq!(ut.unioned(k1, k2), false);
+    ut.union(k1, k2);
+    assert_eq!(ut.unioned(k1, k2), true);
+}
+
+#[test]
+fn big_array() {
+    let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
+    let mut keys = Vec::new();
+    const MAX: usize = 1 << 15;
+
+    for _ in 0..MAX {
+        keys.push(ut.new_key(()));
+    }
+
+    for i in 1..MAX {
+        let l = keys[i-1];
+        let r = keys[i];
+        ut.union(l, r);
+    }
+
+    for i in 0..MAX {
+        assert!(ut.unioned(keys[0], keys[i]));
+    }
+}
+
+#[bench]
+fn big_array_bench(b: &mut Bencher) {
+    let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
+    let mut keys = Vec::new();
+    const MAX: usize = 1 << 15;
+
+    for _ in 0..MAX {
+        keys.push(ut.new_key(()));
+    }
+
+
+    b.iter(|| {
+        for i in 1..MAX {
+            let l = keys[i-1];
+            let r = keys[i];
+            ut.union(l, r);
+        }
+
+        for i in 0..MAX {
+            assert!(ut.unioned(keys[0], keys[i]));
+        }
+    })
+}
+
+#[test]
+fn even_odd() {
+    let mut ut: UnificationTable<UnitKey> = UnificationTable::new();
+    let mut keys = Vec::new();
+    const MAX: usize = 1 << 10;
+
+    for i in 0..MAX {
+        let key = ut.new_key(());
+        keys.push(key);
+
+        if i >= 2 {
+            ut.union(key, keys[i-2]);
+        }
+    }
+
+    for i in 1..MAX {
+        assert!(!ut.unioned(keys[i-1], keys[i]));
+    }
+
+    for i in 2..MAX {
+        assert!(ut.unioned(keys[i-2], keys[i]));
+    }
+}
+
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
+struct IntKey(u32);
+
+impl UnifyKey for IntKey {
+    type Value = Option<i32>;
+    fn index(&self) -> u32 { self.0 }
+    fn from_index(u: u32) -> IntKey { IntKey(u) }
+    fn tag(_: Option<IntKey>) -> &'static str { "IntKey" }
+}
+
+/// Test unifying a key whose value is `Some(_)`  with a key whose value is `None`.
+/// Afterwards both should be `Some(_)`.
+#[test]
+fn unify_key_Some_key_None() {
+    let mut ut: UnificationTable<IntKey> = UnificationTable::new();
+    let k1 = ut.new_key(Some(22));
+    let k2 = ut.new_key(None);
+    assert!(ut.unify_var_var(k1, k2).is_ok());
+    assert_eq!(ut.probe(k2), Some(22));
+    assert_eq!(ut.probe(k1), Some(22));
+}
+
+/// Test unifying a key whose value is `None`  with a key whose value is `Some(_)`.
+/// Afterwards both should be `Some(_)`.
+#[test]
+fn unify_key_None_key_Some() {
+    let mut ut: UnificationTable<IntKey> = UnificationTable::new();
+    let k1 = ut.new_key(Some(22));
+    let k2 = ut.new_key(None);
+    assert!(ut.unify_var_var(k2, k1).is_ok());
+    assert_eq!(ut.probe(k2), Some(22));
+    assert_eq!(ut.probe(k1), Some(22));
+}
+
+/// Test unifying a key whose value is `Some(x)` with a key whose value is `Some(y)`.
+/// This should yield an error.
+#[test]
+fn unify_key_Some_x_key_Some_y() {
+    let mut ut: UnificationTable<IntKey> = UnificationTable::new();
+    let k1 = ut.new_key(Some(22));
+    let k2 = ut.new_key(Some(23));
+    assert_eq!(ut.unify_var_var(k1, k2), Err((22, 23)));
+    assert_eq!(ut.unify_var_var(k2, k1), Err((23, 22)));
+    assert_eq!(ut.probe(k1), Some(22));
+    assert_eq!(ut.probe(k2), Some(23));
+}
+
+/// Test unifying a key whose value is `Some(x)` with a key whose value is `Some(x)`.
+/// This should be ok.
+#[test]
+fn unify_key_Some_x_key_Some_x() {
+    let mut ut: UnificationTable<IntKey> = UnificationTable::new();
+    let k1 = ut.new_key(Some(22));
+    let k2 = ut.new_key(Some(22));
+    assert!(ut.unify_var_var(k1, k2).is_ok());
+    assert_eq!(ut.probe(k1), Some(22));
+    assert_eq!(ut.probe(k2), Some(22));
+}
+
+/// Test unifying a key whose value is `None` with a value is `x`.
+/// Afterwards key should be `x`.
+#[test]
+fn unify_key_None_val() {
+    let mut ut: UnificationTable<IntKey> = UnificationTable::new();
+    let k1 = ut.new_key(None);
+    assert!(ut.unify_var_value(k1, 22).is_ok());
+    assert_eq!(ut.probe(k1), Some(22));
+}
+
+/// Test unifying a key whose value is `Some(x)` with the value `y`.
+/// This should yield an error.
+#[test]
+fn unify_key_Some_x_val_y() {
+    let mut ut: UnificationTable<IntKey> = UnificationTable::new();
+    let k1 = ut.new_key(Some(22));
+    assert_eq!(ut.unify_var_value(k1, 23), Err((22, 23)));
+    assert_eq!(ut.probe(k1), Some(22));
+}
+
+/// Test unifying a key whose value is `Some(x)` with the value `x`.
+/// This should be ok.
+#[test]
+fn unify_key_Some_x_val_x() {
+    let mut ut: UnificationTable<IntKey> = UnificationTable::new();
+    let k1 = ut.new_key(Some(22));
+    assert!(ut.unify_var_value(k1, 22).is_ok());
+    assert_eq!(ut.probe(k1), Some(22));
+}
+
index 12b16e95a71a43601b7448d4a1abdf7541c650c8..a8cf75331799646679480a8a4499ff7b5cceb21a 100644 (file)
@@ -16,6 +16,7 @@
 use rustc_lint;
 use rustc_resolve as resolve;
 use rustc_typeck::middle::lang_items;
+use rustc_typeck::middle::free_region::FreeRegionMap;
 use rustc_typeck::middle::region::{self, CodeExtent, DestructionScopeData};
 use rustc_typeck::middle::resolve_lifetime;
 use rustc_typeck::middle::stability;
@@ -138,7 +139,8 @@ fn test_env<F>(source_string: &str,
                           stability::Index::new(krate));
     let infcx = infer::new_infer_ctxt(&tcx);
     body(Env { infcx: &infcx });
-    infcx.resolve_regions_and_report_errors(ast::CRATE_NODE_ID);
+    let free_regions = FreeRegionMap::new();
+    infcx.resolve_regions_and_report_errors(&free_regions, ast::CRATE_NODE_ID);
     assert_eq!(tcx.sess.err_count(), expected_err_count);
 }
 
index 7f1a4b659edb4059215714f043716e3b6731be65..c12ac501c45a2a14fb510dcb90462a4b63610a65 100644 (file)
@@ -923,6 +923,8 @@ fn is_snake_case(ident: &str) -> bool {
                 allow_underscore = match c {
                     '_' if !allow_underscore => return false,
                     '_' => false,
+                    // It would be more obvious to use `c.is_lowercase()`,
+                    // but some characters do not have a lowercase form
                     c if !c.is_uppercase() => true,
                     _ => return false,
                 };
index 647f4bc6a40fdbe7118dd31349b6de4657af6bae..c8f3e204c4e10d0488d7e89cac812dd6c8f6ac9c 100644 (file)
 
 //! A wrapper around LLVM's archive (.a) code
 
-use libc;
 use ArchiveRef;
 
 use std::ffi::CString;
-use std::slice;
 use std::path::Path;
+use std::slice;
+use std::str;
 
-pub struct ArchiveRO {
-    ptr: ArchiveRef,
+pub struct ArchiveRO { ptr: ArchiveRef }
+
+pub struct Iter<'a> {
+    archive: &'a ArchiveRO,
+    ptr: ::ArchiveIteratorRef,
+}
+
+pub struct Child<'a> {
+    name: Option<&'a str>,
+    data: &'a [u8],
 }
 
 impl ArchiveRO {
@@ -52,18 +60,9 @@ fn path2cstr(p: &Path) -> CString {
         }
     }
 
-    /// Reads a file in the archive
-    pub fn read<'a>(&'a self, file: &str) -> Option<&'a [u8]> {
+    pub fn iter(&self) -> Iter {
         unsafe {
-            let mut size = 0 as libc::size_t;
-            let file = CString::new(file).unwrap();
-            let ptr = ::LLVMRustArchiveReadSection(self.ptr, file.as_ptr(),
-                                                   &mut size);
-            if ptr.is_null() {
-                None
-            } else {
-                Some(slice::from_raw_parts(ptr as *const u8, size as usize))
-            }
+            Iter { ptr: ::LLVMRustArchiveIteratorNew(self.ptr), archive: self }
         }
     }
 }
@@ -75,3 +74,47 @@ fn drop(&mut self) {
         }
     }
 }
+
+impl<'a> Iterator for Iter<'a> {
+    type Item = Child<'a>;
+
+    fn next(&mut self) -> Option<Child<'a>> {
+        unsafe {
+            let ptr = ::LLVMRustArchiveIteratorCurrent(self.ptr);
+            if ptr.is_null() {
+                return None
+            }
+            let mut name_len = 0;
+            let name_ptr = ::LLVMRustArchiveChildName(ptr, &mut name_len);
+            let mut data_len = 0;
+            let data_ptr = ::LLVMRustArchiveChildData(ptr, &mut data_len);
+            let child = Child {
+                name: if name_ptr.is_null() {
+                    None
+                } else {
+                    let name = slice::from_raw_parts(name_ptr as *const u8,
+                                                     name_len as usize);
+                    str::from_utf8(name).ok().map(|s| s.trim())
+                },
+                data: slice::from_raw_parts(data_ptr as *const u8,
+                                            data_len as usize),
+            };
+            ::LLVMRustArchiveIteratorNext(self.ptr);
+            Some(child)
+        }
+    }
+}
+
+#[unsafe_destructor]
+impl<'a> Drop for Iter<'a> {
+    fn drop(&mut self) {
+        unsafe {
+            ::LLVMRustArchiveIteratorFree(self.ptr);
+        }
+    }
+}
+
+impl<'a> Child<'a> {
+    pub fn name(&self) -> Option<&'a str> { self.name }
+    pub fn data(&self) -> &'a [u8] { self.data }
+}
index 7030ee5697954e11944e0108b207e573a8ecb7fc..80e01154655e78ed499961e37d919e7161407c02 100644 (file)
@@ -30,6 +30,7 @@
 #![feature(libc)]
 #![feature(link_args)]
 #![feature(staged_api)]
+#![feature(unsafe_destructor)]
 
 extern crate libc;
 #[macro_use] #[no_link] extern crate rustc_bitflags;
@@ -488,9 +489,12 @@ pub enum Pass_opaque {}
 #[allow(missing_copy_implementations)]
 pub enum TargetMachine_opaque {}
 pub type TargetMachineRef = *mut TargetMachine_opaque;
-#[allow(missing_copy_implementations)]
 pub enum Archive_opaque {}
 pub type ArchiveRef = *mut Archive_opaque;
+pub enum ArchiveIterator_opaque {}
+pub type ArchiveIteratorRef = *mut ArchiveIterator_opaque;
+pub enum ArchiveChild_opaque {}
+pub type ArchiveChildRef = *mut ArchiveChild_opaque;
 #[allow(missing_copy_implementations)]
 pub enum Twine_opaque {}
 pub type TwineRef = *mut Twine_opaque;
@@ -2051,13 +2055,17 @@ pub fn LLVMRustRunRestrictionPass(M: ModuleRef,
     pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef);
 
     pub fn LLVMRustOpenArchive(path: *const c_char) -> ArchiveRef;
-    pub fn LLVMRustArchiveReadSection(AR: ArchiveRef, name: *const c_char,
-                                      out_len: *mut size_t) -> *const c_char;
+    pub fn LLVMRustArchiveIteratorNew(AR: ArchiveRef) -> ArchiveIteratorRef;
+    pub fn LLVMRustArchiveIteratorNext(AIR: ArchiveIteratorRef);
+    pub fn LLVMRustArchiveIteratorCurrent(AIR: ArchiveIteratorRef) -> ArchiveChildRef;
+    pub fn LLVMRustArchiveChildName(ACR: ArchiveChildRef,
+                                    size: *mut size_t) -> *const c_char;
+    pub fn LLVMRustArchiveChildData(ACR: ArchiveChildRef,
+                                    size: *mut size_t) -> *const c_char;
+    pub fn LLVMRustArchiveIteratorFree(AIR: ArchiveIteratorRef);
     pub fn LLVMRustDestroyArchive(AR: ArchiveRef);
 
     pub fn LLVMRustSetDLLExportStorageClass(V: ValueRef);
-    pub fn LLVMVersionMajor() -> c_int;
-    pub fn LLVMVersionMinor() -> c_int;
 
     pub fn LLVMRustGetSectionName(SI: SectionIteratorRef,
                                   data: *mut *const c_char) -> c_int;
index 0058b31088b92b220a84d079fcd38a198ba0cc85..d300045c0ec01c1444f37cca16681a2ef82d1a5e 100644 (file)
@@ -3138,7 +3138,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
                                           uses it like a function name",
                                          path_name));
 
-                        let msg = format!("Did you mean to write: \
+                        let msg = format!("did you mean to write: \
                                            `{} {{ /* fields */ }}`?",
                                           path_name);
                         if self.emit_errors {
@@ -3179,7 +3179,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
                                                 uses it like a function name",
                                                 path_name));
 
-                                let msg = format!("Did you mean to write: \
+                                let msg = format!("did you mean to write: \
                                                      `{} {{ /* fields */ }}`?",
                                                     path_name);
                                 if self.emit_errors {
index 4e099a4ca875e1b6873ad1aa59006b9ea1e58fb2..6457140bcc0f987ba68fef92b00428c45cccc2b9 100644 (file)
@@ -21,9 +21,6 @@
 use flate;
 
 use std::ffi::CString;
-use std::mem;
-#[allow(deprecated)]
-use std::num::Int;
 
 pub fn run(sess: &session::Session, llmod: ModuleRef,
            tm: TargetMachineRef, reachable: &[String]) {
@@ -63,13 +60,13 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
         let file = &file[3..file.len() - 5]; // chop off lib/.rlib
         debug!("reading {}", file);
         for i in 0.. {
-            let bc_encoded = time(sess.time_passes(),
-                                  &format!("check for {}.{}.bytecode.deflate", name, i),
-                                  (),
-                                  |_| {
-                                      archive.read(&format!("{}.{}.bytecode.deflate",
-                                                           file, i))
-                                  });
+            let filename = format!("{}.{}.bytecode.deflate", file, i);
+            let msg = format!("check for {}", filename);
+            let bc_encoded = time(sess.time_passes(), &msg, (), |_| {
+                archive.iter().find(|section| {
+                    section.name() == Some(&filename[..])
+                })
+            });
             let bc_encoded = match bc_encoded {
                 Some(data) => data,
                 None => {
@@ -79,9 +76,10 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
                                            path.display()));
                     }
                     // No more bitcode files to read.
-                    break;
-                },
+                    break
+                }
             };
+            let bc_encoded = bc_encoded.data();
 
             let bc_decoded = if is_versioned_bytecode_format(bc_encoded) {
                 time(sess.time_passes(), &format!("decode {}.{}.bc", file, i), (), |_| {
@@ -198,19 +196,15 @@ fn is_versioned_bytecode_format(bc: &[u8]) -> bool {
 }
 
 fn extract_bytecode_format_version(bc: &[u8]) -> u32 {
-    return read_from_le_bytes::<u32>(bc, link::RLIB_BYTECODE_OBJECT_VERSION_OFFSET);
+    let pos = link::RLIB_BYTECODE_OBJECT_VERSION_OFFSET;
+    let byte_data = &bc[pos..pos + 4];
+    let data = unsafe { *(byte_data.as_ptr() as *const u32) };
+    u32::from_le(data)
 }
 
 fn extract_compressed_bytecode_size_v1(bc: &[u8]) -> u64 {
-    return read_from_le_bytes::<u64>(bc, link::RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET);
-}
-
-#[allow(deprecated)]
-fn read_from_le_bytes<T: Int>(bytes: &[u8], position_in_bytes: usize) -> T {
-    let byte_data = &bytes[position_in_bytes..position_in_bytes + mem::size_of::<T>()];
-    let data = unsafe {
-        *(byte_data.as_ptr() as *const T)
-    };
-
-    Int::from_le(data)
+    let pos = link::RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET;
+    let byte_data = &bc[pos..pos + 8];
+    let data = unsafe { *(byte_data.as_ptr() as *const u64) };
+    u64::from_le(data)
 }
index de21d62651499b1d0de33d9250ee8430525dfe40..488a4a8082f9dc8b24d41a323d73f851a2dafb2c 100644 (file)
@@ -348,7 +348,7 @@ struct HandlerFreeVars<'a> {
 
     match cgcx.lto_ctxt {
         Some((sess, _)) => {
-            sess.codemap().with_expn_info(ExpnId::from_llvm_cookie(cookie), |info| match info {
+            sess.codemap().with_expn_info(ExpnId::from_u32(cookie), |info| match info {
                 Some(ei) => sess.span_err(ei.call_site, msg),
                 None     => sess.err(msg),
             });
index ffa068a2ae44b80f39001abe1370605964416ec7..e2827eeae15d0bbb0cf17ae56fa57d6e4b8fc82f 100644 (file)
@@ -45,8 +45,6 @@
 
 pub use self::Repr::*;
 
-#[allow(deprecated)]
-use std::num::Int;
 use std::rc::Rc;
 
 use llvm::{ValueRef, True, IntEQ, IntNE};
index d6c85e8b173459c5449a60a68dbccc6bdb6d7e99..27128827e267603e0a9b90c155647755093b7dd8 100644 (file)
@@ -138,7 +138,7 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
         let kind = llvm::LLVMGetMDKindIDInContext(bcx.ccx().llcx(),
             key.as_ptr() as *const c_char, key.len() as c_uint);
 
-        let val: llvm::ValueRef = C_i32(bcx.ccx(), ia.expn_id.to_llvm_cookie());
+        let val: llvm::ValueRef = C_i32(bcx.ccx(), ia.expn_id.into_u32() as i32);
 
         llvm::LLVMSetMetadata(r, kind,
             llvm::LLVMMDNodeInContext(bcx.ccx().llcx(), &val, 1));
index e54962dc085524e1b41fc337fc453503379c231d..b8c45d4751ef8894022e26b28a800420b7e17f92 100644 (file)
@@ -878,16 +878,7 @@ macro_rules! mk_struct {
     // were introduced in LLVM 3.4, so we case on that.
     macro_rules! compatible_ifn {
         ($name:expr, $cname:ident ($($arg:expr),*) -> $ret:expr) => (
-            if unsafe { llvm::LLVMVersionMinor() >= 4 } {
-                // The `if key == $name` is already in ifn!
-                ifn!($name, fn($($arg),*) -> $ret);
-            } else if *key == $name {
-                let f = declare::declare_cfn(ccx, stringify!($cname),
-                                             Type::func(&[$($arg),*], &$ret),
-                                             ty::mk_nil(ccx.tcx()));
-                ccx.intrinsics().borrow_mut().insert($name, f.clone());
-                return Some(f);
-            }
+            ifn!($name, fn($($arg),*) -> $ret);
         )
     }
 
index 159b101e85e5ff28e34d9d6219ceb1dbf13704ec..7c769eca74aabe71669823c41cf0febe067acdc4 100644 (file)
@@ -2653,26 +2653,8 @@ fn set_members_of_composite_type(cx: &CrateContext,
         let mut composite_types_completed =
             debug_context(cx).composite_types_completed.borrow_mut();
         if composite_types_completed.contains(&composite_type_metadata) {
-            let (llvm_version_major, llvm_version_minor) = unsafe {
-                (llvm::LLVMVersionMajor(), llvm::LLVMVersionMinor())
-            };
-
-            let actual_llvm_version = llvm_version_major * 1000000 + llvm_version_minor * 1000;
-            let min_supported_llvm_version = 3 * 1000000 + 4 * 1000;
-
-            if actual_llvm_version < min_supported_llvm_version {
-                cx.sess().warn(&format!("This version of rustc was built with LLVM \
-                                        {}.{}. Rustc just ran into a known \
-                                        debuginfo corruption problem thatoften \
-                                        occurs with LLVM versions below 3.4. \
-                                        Please use a rustc built with anewer \
-                                        version of LLVM.",
-                                       llvm_version_major,
-                                       llvm_version_minor));
-            } else {
-                cx.sess().bug("debuginfo::set_members_of_composite_type() - \
-                               Already completed forward declaration re-encountered.");
-            }
+            cx.sess().bug("debuginfo::set_members_of_composite_type() - \
+                           Already completed forward declaration re-encountered.");
         } else {
             composite_types_completed.insert(composite_type_metadata);
         }
index 1e67212871a1e10e3b765e417f51f936afe29a3d..6bfa80f9c40b360f5dd119494dc7987f60b30680 100644 (file)
@@ -746,11 +746,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                     let src = to_arg_ty(bcx, llargs[2], tp_ty);
                     let res = AtomicCmpXchg(bcx, ptr, cmp, src, order,
                                             strongest_failure_ordering);
-                    if unsafe { llvm::LLVMVersionMinor() >= 5 } {
-                        ExtractValue(bcx, res, 0)
-                    } else {
-                        res
-                    }
+                    ExtractValue(bcx, res, 0)
                 }
 
                 "load" => {
index b3ab58e416f7414864745c3219fac86966982f53..9f01521313633360909b34399635ecc7049b589d 100644 (file)
@@ -21,8 +21,6 @@
 
 use trans::type_::Type;
 
-#[allow(deprecated)]
-use std::num::Int;
 use syntax::abi;
 use syntax::ast;
 
index 171c83d00e465240ae906f1a8fa8f5f0e7e7a9a9..9dbf918ddb5c37a471744700910010bc46bd01f0 100644 (file)
@@ -51,6 +51,7 @@
 use middle::astconv_util::{prim_ty_to_ty, check_path_args, NO_TPS, NO_REGIONS};
 use middle::const_eval;
 use middle::def;
+use middle::implicator::object_region_bounds;
 use middle::resolve_lifetime as rl;
 use middle::privacy::{AllPublic, LastMod};
 use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
@@ -66,7 +67,7 @@
 use std::rc::Rc;
 use std::slice;
 use syntax::{abi, ast, ast_util};
-use syntax::codemap::Span;
+use syntax::codemap::{Span, Pos};
 use syntax::parse::token;
 use syntax::print::pprust;
 
@@ -975,21 +976,32 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>,
             span_err!(this.tcx().sess, ty.span, E0178,
                       "expected a path on the left-hand side of `+`, not `{}`",
                       pprust::ty_to_string(ty));
-            match ty.node {
-                ast::TyRptr(None, ref mut_ty) => {
-                    fileline_help!(this.tcx().sess, ty.span,
-                               "perhaps you meant `&{}({} +{})`? (per RFC 438)",
-                               ppaux::mutability_to_string(mut_ty.mutbl),
-                               pprust::ty_to_string(&*mut_ty.ty),
-                               pprust::bounds_to_string(bounds));
+            let hi = bounds.iter().map(|x| match *x {
+                ast::TraitTyParamBound(ref tr, _) => tr.span.hi,
+                ast::RegionTyParamBound(ref r) => r.span.hi,
+            }).max_by(|x| x.to_usize());
+            let full_span = hi.map(|hi| Span {
+                lo: ty.span.lo,
+                hi: hi,
+                expn_id: ty.span.expn_id,
+            });
+            match (&ty.node, full_span) {
+                (&ast::TyRptr(None, ref mut_ty), Some(full_span)) => {
+                    this.tcx().sess
+                        .span_suggestion(full_span, "try adding parentheses (per RFC 438):",
+                                         format!("&{}({} +{})",
+                                                 ppaux::mutability_to_string(mut_ty.mutbl),
+                                                 pprust::ty_to_string(&*mut_ty.ty),
+                                                 pprust::bounds_to_string(bounds)));
                 }
-               ast::TyRptr(Some(ref lt), ref mut_ty) => {
-                    fileline_help!(this.tcx().sess, ty.span,
-                               "perhaps you meant `&{} {}({} +{})`? (per RFC 438)",
-                               pprust::lifetime_to_string(lt),
-                               ppaux::mutability_to_string(mut_ty.mutbl),
-                               pprust::ty_to_string(&*mut_ty.ty),
-                               pprust::bounds_to_string(bounds));
+                (&ast::TyRptr(Some(ref lt), ref mut_ty), Some(full_span)) => {
+                    this.tcx().sess
+                        .span_suggestion(full_span, "try adding parentheses (per RFC 438):",
+                                         format!("&{} {}({} +{})",
+                                                 pprust::lifetime_to_string(lt),
+                                                 ppaux::mutability_to_string(mut_ty.mutbl),
+                                                 pprust::ty_to_string(&*mut_ty.ty),
+                                                 pprust::bounds_to_string(bounds)));
                 }
 
                 _ => {
@@ -2076,39 +2088,6 @@ fn compute_object_lifetime_bound<'tcx>(
     return r;
 }
 
-/// Given an object type like `SomeTrait+Send`, computes the lifetime
-/// bounds that must hold on the elided self type. These are derived
-/// from the declarations of `SomeTrait`, `Send`, and friends -- if
-/// they declare `trait SomeTrait : 'static`, for example, then
-/// `'static` would appear in the list. The hard work is done by
-/// `ty::required_region_bounds`, see that for more information.
-pub fn object_region_bounds<'tcx>(
-    tcx: &ty::ctxt<'tcx>,
-    principal: &ty::PolyTraitRef<'tcx>,
-    others: ty::BuiltinBounds)
-    -> Vec<ty::Region>
-{
-    // Since we don't actually *know* the self type for an object,
-    // this "open(err)" serves as a kind of dummy standin -- basically
-    // a skolemized type.
-    let open_ty = ty::mk_infer(tcx, ty::FreshTy(0));
-
-    // Note that we preserve the overall binding levels here.
-    assert!(!open_ty.has_escaping_regions());
-    let substs = tcx.mk_substs(principal.0.substs.with_self_ty(open_ty));
-    let trait_refs = vec!(ty::Binder(Rc::new(ty::TraitRef::new(principal.0.def_id, substs))));
-
-    let param_bounds = ty::ParamBounds {
-        region_bounds: Vec::new(),
-        builtin_bounds: others,
-        trait_bounds: trait_refs,
-        projection_bounds: Vec::new(), // not relevant to computing region bounds
-    };
-
-    let predicates = ty::predicates(tcx, open_ty, &param_bounds);
-    ty::required_region_bounds(tcx, open_ty, predicates)
-}
-
 pub struct PartitionedBounds<'a> {
     pub builtin_bounds: ty::BuiltinBounds,
     pub trait_bounds: Vec<&'a ast::PolyTraitRef>,
index 532277d75b2e06af52afc2002fffe37f62957b58..c4ee7e79570da570d57deabf1d08e16e42c52ddc 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use middle::free_region::FreeRegionMap;
 use middle::infer;
 use middle::traits;
 use middle::ty::{self};
@@ -354,9 +355,19 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
         Ok(_) => {}
     }
 
-    // Finally, resolve all regions. This catches wily misuses of lifetime
-    // parameters.
-    infcx.resolve_regions_and_report_errors(impl_m_body_id);
+    // Finally, resolve all regions. This catches wily misuses of
+    // lifetime parameters. We have to build up a plausible lifetime
+    // environment based on what we find in the trait. We could also
+    // include the obligations derived from the method argument types,
+    // but I don't think it's necessary -- after all, those are still
+    // in effect when type-checking the body, and all the
+    // where-clauses in the header etc should be implied by the trait
+    // anyway, so it shouldn't be needed there either. Anyway, we can
+    // always add more relations later (it's backwards compat).
+    let mut free_regions = FreeRegionMap::new();
+    free_regions.relate_free_regions_from_predicates(tcx, &trait_param_env.caller_bounds);
+
+    infcx.resolve_regions_and_report_errors(&free_regions, impl_m_body_id);
 
     fn check_region_bounds_on_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
                                                 span: Span,
diff --git a/src/librustc_typeck/check/implicator.rs b/src/librustc_typeck/check/implicator.rs
deleted file mode 100644 (file)
index a4a18c7..0000000
+++ /dev/null
@@ -1,455 +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)]
-
-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::nodemap::FnvHashSet;
-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>),
-    RegionSubClosure(Option<Ty<'tcx>>, ty::Region, ast::DefId, &'tcx Substs<'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>>,
-    visited: FnvHashSet<Ty<'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(),
-                              visited: FnvHashSet() };
-    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()));
-
-        // When expanding out associated types, we can visit a cyclic
-        // set of types. Issue #23003.
-        if !self.visited.insert(ty) {
-            return;
-        }
-
-        match ty.sty {
-            ty::ty_bool |
-            ty::ty_char |
-            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(def_id, substs) => {
-                let &(r_a, opt_ty) = self.stack.last().unwrap();
-                self.out.push(Implication::RegionSubClosure(opt_ty, r_a, def_id, substs));
-            }
-
-            ty::ty_trait(ref t) => {
-                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().
-            }
-        }
-    }
-
-    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>)
-    {
-        debug!("accumulate_from_assoc_types_transitive({})",
-               data.repr(self.tcx()));
-
-        for poly_trait_ref in traits::supertraits(self.tcx(), data.to_poly_trait_ref()) {
-            match ty::no_late_bound_regions(self.tcx(), &poly_trait_ref) {
-                Some(trait_ref) => { self.accumulate_from_assoc_types(trait_ref); }
-                None => { }
-            }
-        }
-    }
-
-    fn accumulate_from_assoc_types(&mut self,
-                                   trait_ref: Rc<ty::TraitRef<'tcx>>)
-    {
-        debug!("accumulate_from_assoc_types({})",
-               trait_ref.repr(self.tcx()));
-
-        let trait_def_id = trait_ref.def_id;
-        let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
-        let assoc_type_projections: Vec<_> =
-            trait_def.associated_type_names
-                     .iter()
-                     .map(|&name| ty::mk_projection(self.tcx(), trait_ref.clone(), name))
-                     .collect();
-        debug!("accumulate_from_assoc_types: assoc_type_projections={}",
-               assoc_type_projections.repr(self.tcx()));
-        let tys = match self.fully_normalize(&assoc_type_projections) {
-            Ok(tys) => { tys }
-            Err(ErrorReported) => { return; }
-        };
-        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::RegionSubClosure(_, ref a, ref b, ref c) => {
-                format!("RegionSubClosure({}, {}, {})",
-                        a.repr(tcx),
-                        b.repr(tcx),
-                        c.repr(tcx))
-            }
-
-            Implication::Predicate(ref def_id, ref p) => {
-                format!("Predicate({}, {})",
-                        def_id.repr(tcx),
-                        p.repr(tcx))
-            }
-        }
-    }
-}
index fa76dc167f2abe2eaf59f2694c185f6583f84359..e87deba280804b5ce889cf0d92190485bafef32e 100644 (file)
 pub mod _match;
 pub mod vtable;
 pub mod writeback;
-pub mod implicator;
 pub mod regionck;
 pub mod coercion;
 pub mod demand;
@@ -1071,7 +1070,16 @@ fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 ast::MutImmutable => ""
             };
             if ty::type_is_trait(t_1) {
-                span_help!(fcx.tcx().sess, t_span, "did you mean `&{}{}`?", mtstr, tstr);
+                match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
+                    Ok(s) => {
+                        fcx.tcx().sess.span_suggestion(t_span,
+                                                       "try casting to a reference instead:",
+                                                       format!("&{}{}", mtstr, s));
+                    },
+                    Err(_) =>
+                        span_help!(fcx.tcx().sess, t_span,
+                                   "did you mean `&{}{}`?", mtstr, tstr),
+                }
             } else {
                 span_help!(fcx.tcx().sess, span,
                            "consider using an implicit coercion to `&{}{}` instead",
@@ -1079,7 +1087,15 @@ fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             }
         }
         ty::ty_uniq(..) => {
-            span_help!(fcx.tcx().sess, t_span, "did you mean `Box<{}>`?", tstr);
+            match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
+                Ok(s) => {
+                    fcx.tcx().sess.span_suggestion(t_span,
+                                                   "try casting to a `Box` instead:",
+                                                   format!("Box<{}>", s));
+                },
+                Err(_) =>
+                    span_help!(fcx.tcx().sess, t_span, "did you mean `Box<{}>`?", tstr),
+            }
         }
         _ => {
             span_help!(fcx.tcx().sess, e_span,
index 6dfc1e0ea6c2651598ba03f01462a3f74102bbf1..2e8c5730e67cb01b7c3c8c6a76d0525113f43d3f 100644 (file)
@@ -85,8 +85,9 @@
 use astconv::AstConv;
 use check::dropck;
 use check::FnCtxt;
-use check::implicator;
 use check::vtable;
+use middle::free_region::FreeRegionMap;
+use middle::implicator;
 use middle::mem_categorization as mc;
 use middle::region::CodeExtent;
 use middle::subst::Substs;
@@ -124,6 +125,8 @@ pub fn regionck_expr(fcx: &FnCtxt, e: &ast::Expr) {
 
 pub fn regionck_item(fcx: &FnCtxt, item: &ast::Item) {
     let mut rcx = Rcx::new(fcx, RepeatingScope(item.id), item.id, Subject(item.id));
+    let tcx = fcx.tcx();
+    rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.param_env.caller_bounds);
     rcx.visit_region_obligations(item.id);
     rcx.resolve_regions_and_report_errors();
 }
@@ -135,12 +138,21 @@ pub fn regionck_fn(fcx: &FnCtxt,
                    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(fn_id, decl, blk, fn_span);
     }
 
+    let tcx = fcx.tcx();
+    rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.param_env.caller_bounds);
+
     rcx.resolve_regions_and_report_errors();
+
+    // For the top-level fn, store the free-region-map. We don't store
+    // any map for closures; they just share the same map as the
+    // function that created them.
+    fcx.tcx().store_free_region_map(fn_id, rcx.free_region_map);
 }
 
 /// Checks that the types in `component_tys` are well-formed. This will add constraints into the
@@ -167,6 +179,8 @@ pub struct Rcx<'a, 'tcx: 'a> {
 
     region_bound_pairs: Vec<(ty::Region, GenericKind<'tcx>)>,
 
+    free_region_map: FreeRegionMap,
+
     // id of innermost fn body id
     body_id: ast::NodeId,
 
@@ -191,7 +205,8 @@ pub fn new(fcx: &'a FnCtxt<'a, 'tcx>,
               repeating_scope: initial_repeating_scope,
               body_id: initial_body_id,
               subject: subject,
-              region_bound_pairs: Vec::new()
+              region_bound_pairs: Vec::new(),
+              free_region_map: FreeRegionMap::new(),
         }
     }
 
@@ -277,13 +292,16 @@ fn visit_fn_body(&mut self,
             }
         };
 
-        let len = self.region_bound_pairs.len();
+        let old_region_bounds_pairs_len = self.region_bound_pairs.len();
+
         let old_body_id = self.set_body_id(body.id);
         self.relate_free_regions(&fn_sig[..], body.id, span);
         link_fn_args(self, CodeExtent::from_node_id(body.id), &fn_decl.inputs[..]);
         self.visit_block(body);
         self.visit_region_obligations(body.id);
-        self.region_bound_pairs.truncate(len);
+
+        self.region_bound_pairs.truncate(old_region_bounds_pairs_len);
+
         self.set_body_id(old_body_id);
     }
 
@@ -340,14 +358,16 @@ fn relate_free_regions(&mut self,
             let body_scope = ty::ReScope(body_scope);
             let implications = implicator::implications(self.fcx.infcx(), self.fcx, body_id,
                                                         ty, body_scope, span);
+
+            // Record any relations between free regions that we observe into the free-region-map.
+            self.free_region_map.relate_free_regions_from_implications(tcx, &implications);
+
+            // But also record other relationships, such as `T:'x`,
+            // that don't go into the free-region-map but which we use
+            // here.
             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);
-                    }
                     implicator::Implication::RegionSubRegion(_,
                                                              ty::ReFree(free_a),
                                                              ty::ReInfer(ty::ReVar(vid_b))) => {
@@ -388,7 +408,8 @@ fn resolve_regions_and_report_errors(&self) {
             }
         };
 
-        self.fcx.infcx().resolve_regions_and_report_errors(subject_node_id);
+        self.fcx.infcx().resolve_regions_and_report_errors(&self.free_region_map,
+                                                           subject_node_id);
     }
 }
 
index 5ed93703d977f25ced3824755210b2a0648739fd..23959d578bf0320a2013f979e88c8cb8536a15d8 100644 (file)
@@ -68,6 +68,7 @@
 use middle::def;
 use constrained_type_params as ctp;
 use middle::lang_items::SizedTraitLangItem;
+use middle::free_region::FreeRegionMap;
 use middle::region;
 use middle::resolve_lifetime;
 use middle::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace};
@@ -2158,7 +2159,16 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
                 format!("mismatched self type: expected `{}`",
                         ppaux::ty_to_string(tcx, required_type))
         }));
-        infcx.resolve_regions_and_report_errors(body_id);
+
+        // We could conceviably add more free-reion relations here,
+        // but since this code is just concerned with checking that
+        // the `&Self` types etc match up, it's not really necessary.
+        // It would just allow people to be more approximate in some
+        // cases. In any case, we can do it later as we feel the need;
+        // I'd like this function to go away eventually.
+        let free_regions = FreeRegionMap::new();
+
+        infcx.resolve_regions_and_report_errors(&free_regions, body_id);
     }
 
     fn liberate_early_bound_regions<'tcx,T>(
index 5c4e643c2a1c5b0fbc0b4bab4a16e806553f3a57..edfa8db311f358d7da8bd1ab0c4a38545b9478eb 100644 (file)
@@ -45,7 +45,7 @@
 pub mod char;
 
 pub mod str {
-    pub use u_str::{UnicodeStr, Words, Graphemes, GraphemeIndices};
+    pub use u_str::{UnicodeStr, SplitWhitespace, Words, Graphemes, GraphemeIndices};
     pub use u_str::{utf8_char_width, is_utf16, Utf16Items, Utf16Item};
     pub use u_str::{utf16_items, Utf16Encoder};
 }
index 09a5feb5fef30b05fba146e20311abe754299322..898844e3bf12ba71db877cdf10c8401bc9d9f165 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15679
 
 //! Unicode-intensive string manipulations.
 //!
 
 use tables::grapheme::GraphemeCat;
 
-/// An iterator over the words of a string, separated by a sequence of whitespace
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Words<'a> {
+#[deprecated(reason = "struct Words is being replaced by struct SplitWhitespace",
+             since = "1.1.0")]
+#[unstable(feature = "str_words",
+           reason = "words() will be replaced by split_whitespace() in 1.1.0")]
+pub type Words<'a> = SplitWhitespace<'a>;
+
+/// An iterator over the non-whitespace substrings of a string,
+/// separated by any amount of whitespace.
+#[stable(feature = "split_whitespace", since = "1.1.0")]
+pub struct SplitWhitespace<'a> {
     inner: Filter<Split<'a, fn(char) -> bool>, fn(&&str) -> bool>,
 }
 
@@ -38,7 +43,9 @@ pub struct Words<'a> {
 pub trait UnicodeStr {
     fn graphemes<'a>(&'a self, is_extended: bool) -> Graphemes<'a>;
     fn grapheme_indices<'a>(&'a self, is_extended: bool) -> GraphemeIndices<'a>;
+    #[allow(deprecated)]
     fn words<'a>(&'a self) -> Words<'a>;
+    fn split_whitespace<'a>(&'a self) -> SplitWhitespace<'a>;
     fn is_whitespace(&self) -> bool;
     fn is_alphanumeric(&self) -> bool;
     fn width(&self, is_cjk: bool) -> usize;
@@ -58,15 +65,21 @@ fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices {
         GraphemeIndices { start_offset: self.as_ptr() as usize, iter: self.graphemes(is_extended) }
     }
 
+    #[allow(deprecated)]
     #[inline]
     fn words(&self) -> Words {
+        self.split_whitespace()
+    }
+
+    #[inline]
+    fn split_whitespace(&self) -> SplitWhitespace {
         fn is_not_empty(s: &&str) -> bool { !s.is_empty() }
         let is_not_empty: fn(&&str) -> bool = is_not_empty; // coerce to fn pointer
 
         fn is_whitespace(c: char) -> bool { c.is_whitespace() }
         let is_whitespace: fn(char) -> bool = is_whitespace; // coerce to fn pointer
 
-        Words { inner: self.split(is_whitespace).filter(is_not_empty) }
+        SplitWhitespace { inner: self.split(is_whitespace).filter(is_not_empty) }
     }
 
     #[inline]
@@ -547,11 +560,11 @@ fn size_hint(&self) -> (usize, Option<usize>) {
     }
 }
 
-impl<'a> Iterator for Words<'a> {
+impl<'a> Iterator for SplitWhitespace<'a> {
     type Item = &'a str;
 
     fn next(&mut self) -> Option<&'a str> { self.inner.next() }
 }
-impl<'a> DoubleEndedIterator for Words<'a> {
+impl<'a> DoubleEndedIterator for SplitWhitespace<'a> {
     fn next_back(&mut self) -> Option<&'a str> { self.inner.next_back() }
 }
index 334f05fb36fa8f0329766b8d8cd93a7827badc27..17053e4f10ad37760d967c79bfb77676b00d8884 100644 (file)
@@ -274,7 +274,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
         };
 
         // Transform the contents of the header into a hyphenated string
-        let id = s.words().map(|s| s.to_ascii_lowercase())
+        let id = s.split_whitespace().map(|s| s.to_ascii_lowercase())
             .collect::<Vec<String>>().connect("-");
 
         // This is a terrible hack working around how hoedown gives us rendered
index 3f3f8201b001954522144fbf331590b604589e55..1993f03efd1fabbc8e7539be2ec4b93f57fe9e55 100644 (file)
@@ -1460,7 +1460,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(fmt, "<span class='out-of-band'>"));
         try!(write!(fmt,
         r##"<span id='render-detail'>
-            <a id="collapse-all" href="#">[-]</a>&nbsp;<a id="expand-all" href="#">[+]</a>
+            <a id="toggle-all-docs" href="#" title="collapse all docs">[-]</a>
         </span>"##));
 
         // Write `src` tag
@@ -1473,8 +1473,8 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
             match self.href(self.cx) {
                 Some(l) => {
                     try!(write!(fmt, "<a id='src-{}' class='srclink' \
-                                       href='{}'>[src]</a>",
-                                self.item.def_id.node, l));
+                                       href='{}' title='{}'>[src]</a>",
+                                self.item.def_id.node, l, "goto source code"));
                 }
                 None => {}
             }
index 0379c04be4d29746acf5329c71653aa4858f9db0..56cea50a502399cae7e4279f07eff6d2852b3c3f 100644 (file)
         window.location = $('.srclink').attr('href');
     }
 
-    $("#expand-all").on("click", function() {
-        $(".docblock").show();
-        $(".toggle-label").hide();
-        $(".toggle-wrapper").removeClass("collapsed");
-        $(".collapse-toggle").children(".inner").html("-");
-    });
-
-    $("#collapse-all").on("click", function() {
-        $(".docblock").hide();
-        $(".toggle-label").show();
-        $(".toggle-wrapper").addClass("collapsed");
-        $(".collapse-toggle").children(".inner").html("+");
+    $("#toggle-all-docs").on("click", function() {
+        var toggle = $("#toggle-all-docs");
+        if (toggle.html() == "[-]") {
+            toggle.html("[+]");
+            toggle.attr("title", "expand all docs");
+            $(".docblock").hide();
+            $(".toggle-label").show();
+            $(".toggle-wrapper").addClass("collapsed");
+            $(".collapse-toggle").children(".inner").html("+");
+        } else {
+            toggle.html("[-]");
+            toggle.attr("title", "collapse all docs");
+            $(".docblock").show();
+            $(".toggle-label").hide();
+            $(".toggle-wrapper").removeClass("collapsed");
+            $(".collapse-toggle").children(".inner").html("-");
+        }
     });
 
     $(document).on("click", ".collapse-toggle", function() {
         var toggle = $(this);
         var relatedDoc = toggle.parent().next();
+        if (relatedDoc.is(".stability")) {
+            relatedDoc = relatedDoc.next();
+        }
         if (relatedDoc.is(".docblock")) {
             if (relatedDoc.is(":visible")) {
                 relatedDoc.slideUp({duration:'fast', easing:'linear'});
             .html("[<span class='inner'>-</span>]");
 
         $(".method").each(function() {
-           if ($(this).next().is(".docblock")) {
-               $(this).children().first().after(toggle.clone());
-           }
+            if ($(this).next().is(".docblock") ||
+                ($(this).next().is(".stability") && $(this).next().next().is(".docblock"))) {
+                    $(this).children().first().after(toggle.clone());
+            }
         });
 
         var mainToggle =
index 78feb6c77c45451f8f2df38420c850651825923c..93aa74d7005f6d8989cbae865218d8d421165596 100644 (file)
@@ -198,7 +198,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use super::{TocBuilder, Toc, TocEntry};
 
     #[test]
index 4389b66b52a0ed587bbd756a812e02e07679b9c6..9c393d6f897372531de74158e42e40d56f4251a9 100644 (file)
@@ -31,7 +31,6 @@
 #![feature(std_misc)]
 #![feature(test)]
 #![feature(unicode)]
-#![feature(str_words)]
 #![feature(path_ext)]
 #![feature(path_relative_from)]
 #![feature(slice_patterns)]
@@ -240,7 +239,7 @@ pub fn main_args(args: &[String]) -> isize {
 
     let test_args = matches.opt_strs("test-args");
     let test_args: Vec<String> = test_args.iter()
-                                          .flat_map(|s| s.words())
+                                          .flat_map(|s| s.split_whitespace())
                                           .map(|s| s.to_string())
                                           .collect();
 
@@ -404,13 +403,13 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
                     }
                     clean::NameValue(ref x, ref value)
                             if "passes" == *x => {
-                        for pass in value.words() {
+                        for pass in value.split_whitespace() {
                             passes.push(pass.to_string());
                         }
                     }
                     clean::NameValue(ref x, ref value)
                             if "plugins" == *x => {
-                        for p in value.words() {
+                        for p in value.split_whitespace() {
                             plugins.push(p.to_string());
                         }
                     }
index 0676edf81696f5647048681cccddb38ad175c81c..87f1dca2caed0dc2213431326320011cde866981 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15679
 
 //! Hex binary-to-text encoding
 
index 4255899aa01e01702c00d336d1abedba6f57cc67..baa6493533d2929c54f486e24d27e97bfb8a1188 100644 (file)
 use std::io;
 use std::mem::swap;
 use std::num::FpCategory as Fp;
-#[allow(deprecated)]
-use std::num::wrapping::WrappingOps;
 use std::ops::Index;
 use std::str::FromStr;
 use std::string;
-use std::{char, f64, fmt, num, str};
+use std::{char, f64, fmt, str};
 use std;
 use rustc_unicode::str as unicode_str;
 use rustc_unicode::str::Utf16Item;
@@ -460,8 +458,8 @@ fn spaces(wr: &mut fmt::Write, mut n: usize) -> EncodeResult {
 fn fmt_number_or_null(v: f64) -> string::String {
     match v.classify() {
         Fp::Nan | Fp::Infinite => string::String::from_str("null"),
-        _ if v.fract() != 0f64 => f64::to_str_digits(v, 6),
-        _ => f64::to_str_digits(v, 6) + ".0",
+        _ if v.fract() != 0f64 => v.to_string(),
+        _ => v.to_string() + ".0",
     }
 }
 
@@ -1165,7 +1163,7 @@ pub fn is_f64(&self) -> bool {
     pub fn as_i64(&self) -> Option<i64> {
         match *self {
             Json::I64(n) => Some(n),
-            Json::U64(n) => num::cast(n),
+            Json::U64(n) => Some(n as i64),
             _ => None
         }
     }
@@ -1174,7 +1172,7 @@ pub fn as_i64(&self) -> Option<i64> {
     /// Returns None otherwise.
     pub fn as_u64(&self) -> Option<u64> {
         match *self {
-            Json::I64(n) => num::cast(n),
+            Json::I64(n) => Some(n as u64),
             Json::U64(n) => Some(n),
             _ => None
         }
@@ -1184,8 +1182,8 @@ pub fn as_u64(&self) -> Option<u64> {
     /// Returns None otherwise.
     pub fn as_f64(&self) -> Option<f64> {
         match *self {
-            Json::I64(n) => num::cast(n),
-            Json::U64(n) => num::cast(n),
+            Json::I64(n) => Some(n as f64),
+            Json::U64(n) => Some(n as f64),
             Json::F64(n) => Some(n),
             _ => None
         }
@@ -1556,7 +1554,7 @@ fn parse_number(&mut self) -> JsonEvent {
 
     #[allow(deprecated)] // possible resolve bug is mapping these to traits
     fn parse_u64(&mut self) -> Result<u64, ParserError> {
-        let mut accum = 0;
+        let mut accum = 0u64;
         let last_accum = 0; // necessary to detect overflow.
 
         match self.ch_or_null() {
@@ -2059,7 +2057,7 @@ fn build_object(&mut self) -> Result<Json, BuilderError> {
     }
 }
 
-/// Decodes a json value from an `&mut old_io::Reader`
+/// Decodes a json value from an `&mut io::Read`
 pub fn from_reader(rdr: &mut Read) -> Result<Json, BuilderError> {
     let mut contents = Vec::new();
     match rdr.read_to_end(&mut contents) {
@@ -2121,14 +2119,8 @@ macro_rules! read_primitive {
     ($name:ident, $ty:ty) => {
         fn $name(&mut self) -> DecodeResult<$ty> {
             match self.pop() {
-                Json::I64(f) => match num::cast(f) {
-                    Some(f) => Ok(f),
-                    None => Err(ExpectedError("Number".to_string(), format!("{}", f))),
-                },
-                Json::U64(f) => match num::cast(f) {
-                    Some(f) => Ok(f),
-                    None => Err(ExpectedError("Number".to_string(), format!("{}", f))),
-                },
+                Json::I64(f) => Ok(f as $ty),
+                Json::U64(f) => Ok(f as $ty),
                 Json::F64(f) => Err(ExpectedError("Integer".to_string(), format!("{}", f))),
                 // re: #12967.. a type w/ numeric keys (ie HashMap<usize, V> etc)
                 // is going to have a string here, as per JSON spec.
index a2ba8c4c1bae07dfb9d494e3eb3c60a54f366b84..ccc56960b02ce111877e9fe6c689988770ef548b 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15679
 
 //! Operations on ASCII strings and characters
 
index 4ac15b7991b32c188f10211bfbee284dd6157b0e..9ba90c470f8ae667776078f2d3a267b998145099 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15883
 
 use self::Entry::*;
 use self::SearchResult::*;
@@ -916,33 +914,6 @@ pub fn iter_mut(&mut self) -> IterMut<K, V> {
         IterMut { inner: self.table.iter_mut() }
     }
 
-    /// Creates a consuming iterator, that is, one that moves each key-value
-    /// pair out of the map in arbitrary order. The map cannot be used after
-    /// calling this.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// map.insert("a", 1);
-    /// map.insert("b", 2);
-    /// map.insert("c", 3);
-    ///
-    /// // Not possible with .iter()
-    /// let vec: Vec<(&str, isize)> = map.into_iter().collect();
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_iter(self) -> IntoIter<K, V> {
-        fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
-        let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two;
-
-        IntoIter {
-            inner: self.table.into_iter().map(last_two)
-        }
-    }
-
     /// Gets the given key's corresponding entry in the map for in-place manipulation.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn entry(&mut self, key: K) -> Entry<K, V> {
@@ -1390,8 +1361,30 @@ impl<K, V, S> IntoIterator for HashMap<K, V, S>
     type Item = (K, V);
     type IntoIter = IntoIter<K, V>;
 
+    /// Creates a consuming iterator, that is, one that moves each key-value
+    /// pair out of the map in arbitrary order. The map cannot be used after
+    /// calling this.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert("a", 1);
+    /// map.insert("b", 2);
+    /// map.insert("c", 3);
+    ///
+    /// // Not possible with .iter()
+    /// let vec: Vec<(&str, isize)> = map.into_iter().collect();
+    /// ```
     fn into_iter(self) -> IntoIter<K, V> {
-        self.into_iter()
+        fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
+        let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two;
+
+        IntoIter {
+            inner: self.table.into_iter().map(last_two)
+        }
     }
 }
 
@@ -1627,7 +1620,7 @@ mod test_map {
 
     use super::HashMap;
     use super::Entry::{Occupied, Vacant};
-    use iter::{range_inclusive, range_step_inclusive, repeat};
+    use iter::{range_inclusive, repeat};
     use cell::RefCell;
     use rand::{thread_rng, Rng};
 
@@ -1863,7 +1856,7 @@ fn test_lots_of_insertions() {
             }
 
             // remove backwards
-            for i in range_step_inclusive(1000, 1, -1) {
+            for i in (1..1001).rev() {
                 assert!(m.remove(&i).is_some());
 
                 for j in range_inclusive(i, 1000) {
index 62c03389b24ae8e28c3c81097f899d07dfd44aa4..f7e43b38539f1b5367ecbf1f824e9b477cfa40bc 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15883
 
 use borrow::Borrow;
 use clone::Clone;
@@ -271,34 +269,6 @@ pub fn iter(&self) -> Iter<T> {
         Iter { iter: self.map.keys() }
     }
 
-    /// Creates a consuming iterator, that is, one that moves each value out
-    /// of the set in arbitrary order. The set cannot be used after calling
-    /// this.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    /// let mut set = HashSet::new();
-    /// set.insert("a".to_string());
-    /// set.insert("b".to_string());
-    ///
-    /// // Not possible to collect to a Vec<String> with a regular `.iter()`.
-    /// let v: Vec<String> = set.into_iter().collect();
-    ///
-    /// // Will print in an arbitrary order.
-    /// for x in v.iter() {
-    ///     println!("{}", x);
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_iter(self) -> IntoIter<T> {
-        fn first<A, B>((a, _): (A, B)) -> A { a }
-        let first: fn((T, ())) -> T = first;
-
-        IntoIter { iter: self.map.into_iter().map(first) }
-    }
-
     /// Visit the values representing the difference.
     ///
     /// # Examples
@@ -850,8 +820,31 @@ impl<T, S> IntoIterator for HashSet<T, S>
     type Item = T;
     type IntoIter = IntoIter<T>;
 
+    /// Creates a consuming iterator, that is, one that moves each value out
+    /// of the set in arbitrary order. The set cannot be used after calling
+    /// this.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    /// let mut set = HashSet::new();
+    /// set.insert("a".to_string());
+    /// set.insert("b".to_string());
+    ///
+    /// // Not possible to collect to a Vec<String> with a regular `.iter()`.
+    /// let v: Vec<String> = set.into_iter().collect();
+    ///
+    /// // Will print in an arbitrary order.
+    /// for x in v.iter() {
+    ///     println!("{}", x);
+    /// }
+    /// ```
     fn into_iter(self) -> IntoIter<T> {
-        self.into_iter()
+        fn first<A, B>((a, _): (A, B)) -> A { a }
+        let first: fn((T, ())) -> T = first;
+
+        IntoIter { iter: self.map.into_iter().map(first) }
     }
 }
 
index dec6d1e2209ad9b982f695ce6f06b2efb50ecd32..3a63e2ab59cc85ed5ddfd4356cac3813eb437c93 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15883
 
 use self::BucketState::*;
 
@@ -19,7 +17,7 @@
 use marker::{Copy, Send, Sync, Sized, self};
 use mem::{min_align_of, size_of};
 use mem;
-use num::wrapping::{OverflowingOps, WrappingOps};
+use num::wrapping::OverflowingOps;
 use ops::{Deref, DerefMut, Drop};
 use option::Option;
 use option::Option::{Some, None};
index c69df6435c49889b8b1181963208ea3c186323e1..ef72cbc96e18f54a67652f83bae7e427618304aa 100644 (file)
@@ -40,14 +40,6 @@ fn drop(&mut self) {
 }
 
 impl DynamicLibrary {
-    // FIXME (#12938): Until DST lands, we cannot decompose &str into
-    // & and str, so we cannot usefully take ToCStr arguments by
-    // reference (without forcing an additional & around &str). So we
-    // are instead temporarily adding an instance for &Path, so that
-    // we can take ToCStr as owned. When DST lands, the &Path instance
-    // should be removed, and arguments bound by ToCStr should be
-    // passed by reference. (Here: in the `open` method.)
-
     /// Lazily open a dynamic library. When passed None it gives a
     /// handle to the calling process
     pub fn open(filename: Option<&Path>) -> Result<DynamicLibrary, String> {
@@ -125,7 +117,7 @@ pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String> {
 }
 
 #[cfg(all(test, not(target_os = "ios")))]
-mod test {
+mod tests {
     use super::*;
     use prelude::v1::*;
     use libc;
@@ -259,19 +251,14 @@ fn dlsym(handle: *mut libc::c_void,
 
 #[cfg(target_os = "windows")]
 mod dl {
+    use prelude::v1::*;
+
     use ffi::OsStr;
-    use iter::Iterator;
     use libc;
     use libc::consts::os::extra::ERROR_CALL_NOT_IMPLEMENTED;
-    use ops::FnOnce;
     use sys::os;
     use os::windows::prelude::*;
-    use option::Option::{self, Some, None};
     use ptr;
-    use result::Result;
-    use result::Result::{Ok, Err};
-    use string::String;
-    use vec::Vec;
     use sys::c::compat::kernel32::SetThreadErrorMode;
 
     pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
index bcc109a71cb0436970c93bec58574d734b1fc75b..114d0dd79a0a3056b338498bd472607fc52292c5 100644 (file)
@@ -18,7 +18,6 @@
 
 use prelude::v1::*;
 
-use iter::IntoIterator;
 use error::Error;
 use ffi::{OsStr, OsString};
 use fmt;
@@ -772,7 +771,7 @@ fn make_rand_name() -> OsString {
     }
 
     fn eq(a: Option<OsString>, b: Option<&str>) {
-        assert_eq!(a.as_ref().map(|s| &**s), b.map(OsStr::from_str).map(|s| &*s));
+        assert_eq!(a.as_ref().map(|s| &**s), b.map(OsStr::new).map(|s| &*s));
     }
 
     #[test]
@@ -895,7 +894,7 @@ fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
     fn join_paths_unix() {
         fn test_eq(input: &[&str], output: &str) -> bool {
             &*join_paths(input.iter().cloned()).unwrap() ==
-                OsStr::from_str(output)
+                OsStr::new(output)
         }
 
         assert!(test_eq(&[], ""));
@@ -911,7 +910,7 @@ fn test_eq(input: &[&str], output: &str) -> bool {
     fn join_paths_windows() {
         fn test_eq(input: &[&str], output: &str) -> bool {
             &*join_paths(input.iter().cloned()).unwrap() ==
-                OsStr::from_str(output)
+                OsStr::new(output)
         }
 
         assert!(test_eq(&[], ""));
index 99becb67a5a7a1e6a78eef3cdaaa2aaa1c6a42af..dfe706e077366c609f2fb43c9ae95d3a12fa2ca3 100644 (file)
 
 mod c_str;
 mod os_str;
-
-// FIXME (#21670): these should be defined in the os_str module
-/// Freely convertible to an `&OsStr` slice.
-#[unstable(feature = "std_misc")]
-pub trait AsOsStr {
-    /// Converts to an `&OsStr` slice.
-    fn as_os_str(&self) -> &OsStr;
-}
index 08b41915d9153930ff8ad4cfabb4a2d3dbeadd35..97bf33335b02a8091af837556176f015ad494508 100644 (file)
@@ -46,7 +46,6 @@
 
 use sys::os_str::{Buf, Slice};
 use sys_common::{AsInner, IntoInner, FromInner};
-use super::AsOsStr;
 
 /// Owned, mutable OS strings.
 #[derive(Clone)]
@@ -226,14 +225,6 @@ pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
         s.as_ref()
     }
 
-    /// Coerces directly from a `&str` slice to a `&OsStr` slice.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[deprecated(since = "1.0.0",
-                 reason = "use `OsStr::new` instead")]
-    pub fn from_str(s: &str) -> &OsStr {
-        unsafe { mem::transmute(Slice::from_str(s)) }
-    }
-
     /// Yields a `&str` slice if the `OsStr` is valid unicode.
     ///
     /// This conversion may entail doing a check for UTF-8 validity.
@@ -378,46 +369,6 @@ impl ToOwned for OsStr {
     fn to_owned(&self) -> OsString { self.to_os_string() }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
-impl<'a, T: AsOsStr + ?Sized> AsOsStr for &'a T {
-    fn as_os_str(&self) -> &OsStr {
-        (*self).as_os_str()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
-impl AsOsStr for OsStr {
-    fn as_os_str(&self) -> &OsStr {
-        self
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
-impl AsOsStr for OsString {
-    fn as_os_str(&self) -> &OsStr {
-        &self[..]
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
-impl AsOsStr for str {
-    fn as_os_str(&self) -> &OsStr {
-        unsafe { mem::transmute(Slice::from_str(self)) }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
-impl AsOsStr for String {
-    fn as_os_str(&self) -> &OsStr {
-        unsafe { mem::transmute(Slice::from_str(self)) }
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl AsRef<OsStr> for OsStr {
     fn as_ref(&self) -> &OsStr {
index 8af3311c42623fec29c616d3042cf896c5487de5..b5dfbf796d3bce212ab4c1053710a8334f27a32a 100644 (file)
@@ -19,6 +19,7 @@
 
 use core::prelude::*;
 
+use fmt;
 use io::{self, Error, ErrorKind, SeekFrom, Seek, Read, Write};
 use path::{Path, PathBuf};
 use sys::fs2 as fs_imp;
@@ -305,6 +306,12 @@ fn from_inner(f: fs_imp::File) -> File {
     }
 }
 
+impl fmt::Debug for File {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.inner.fmt(f)
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Read for File {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
@@ -699,7 +706,7 @@ pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// Given a path, query the file system to get information about a file,
 /// directory, etc.
 ///
-/// This function will traverse soft links to query information about the
+/// This function will traverse symbolic links to query information about the
 /// destination file.
 ///
 /// # Examples
@@ -813,9 +820,13 @@ pub fn hard_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<(
     fs_imp::link(src.as_ref(), dst.as_ref())
 }
 
-/// Creates a new soft link on the filesystem.
+/// Creates a new symbolic link on the filesystem.
 ///
-/// The `dst` path will be a soft link pointing to the `src` path.
+/// The `dst` path will be a symbolic link pointing to the `src` path.
+/// On Windows, this will be a file symlink, not a directory symlink;
+/// for this reason, the platform-specific `std::os::unix::fs::symlink`
+/// and `std::os::windows::fs::{symlink_file, symlink_dir}` should be
+/// used instead to make the intent explicit.
 ///
 /// # Examples
 ///
@@ -827,17 +838,20 @@ pub fn hard_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<(
 /// # Ok(())
 /// # }
 /// ```
+#[deprecated(since = "1.0.0",
+             reason = "replaced with std::os::unix::fs::symlink and \
+                       std::os::windows::fs::{symlink_file, symlink_dir}")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
     fs_imp::symlink(src.as_ref(), dst.as_ref())
 }
 
-/// Reads a soft link, returning the file that the link points to.
+/// Reads a symbolic link, returning the file that the link points to.
 ///
 /// # Errors
 ///
 /// This function will return an error on failure. Failure conditions include
-/// reading a file that does not exist or reading a file that is not a soft
+/// reading a file that does not exist or reading a file that is not a symbolic
 /// link.
 ///
 /// # Examples
@@ -930,8 +944,8 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// Removes a directory at this path, after removing all its contents. Use
 /// carefully!
 ///
-/// This function does **not** follow soft links and it will simply remove the
-/// soft link itself.
+/// This function does **not** follow symbolic links and it will simply remove the
+/// symbolic link itself.
 ///
 /// # Errors
 ///
index bd44a9547b49677591d7b4c75f7eda101649f042..67cac42c35ec2d0a5ee22cad0fbdae38b1366442 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15883
 
 //! Buffering wrappers for I/O traits
 
index 959c15fcfd6c9c331a1c75f4684f23abc4eed00b..97c5a29d308a11c8975611bac9680094f78a153e 100644 (file)
@@ -172,13 +172,6 @@ pub fn from_raw_os_error(code: i32) -> Error {
         Error { repr: Repr::Os(code) }
     }
 
-    /// Creates a new instance of an `Error` from a particular OS error code.
-    #[unstable(feature = "io", reason = "deprecated")]
-    #[deprecated(since = "1.0.0", reason = "renamed to from_raw_os_error")]
-    pub fn from_os_error(code: i32) -> Error {
-        Error { repr: Repr::Os(code) }
-    }
-
     /// Returns the OS error that this error represents (if any).
     ///
     /// If this `Error` was constructed via `last_os_error` then this function
index cd6af77daa9061e00c094979d9bad3f64dc00c45..a9dab8191fd9c90dfa43d3a562e1fc532e6fab84 100644 (file)
@@ -95,6 +95,8 @@ fn flush(&mut self) -> io::Result<()> { Ok(()) }
 ///
 /// This handle implements the `Read` trait, but beware that concurrent reads
 /// of `Stdin` must be executed with care.
+///
+/// Created by the function `io::stdin()`.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stdin {
     inner: Arc<Mutex<BufReader<StdinRaw>>>,
@@ -206,6 +208,8 @@ fn consume(&mut self, n: usize) { self.inner.consume(n) }
 /// Each handle shares a global buffer of data to be written to the standard
 /// output stream. Access is also synchronized via a lock and explicit control
 /// over locking is available via the `lock` method.
+///
+/// Created by the function `io::stdout()`.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stdout {
     // FIXME: this should be LineWriter or BufWriter depending on the state of
@@ -414,7 +418,7 @@ pub fn _print(args: fmt::Arguments) {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use thread;
     use super::*;
 
index c82f9515e8d52813ba494a6b0a48b0b71bc27a65..d797e757a483ecf687d686327ed876a64c987223 100644 (file)
@@ -102,7 +102,7 @@ fn flush(&mut self) -> io::Result<()> { Ok(()) }
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use prelude::v1::*;
 
     use io::prelude::*;
index 4452a4457acda6f9554137e882b2dbaa62cac4e7..96665259a4d0c2d6cbf5328cf7fac00602b3ac13 100644 (file)
 #![feature(std_misc)]
 #![feature(slice_patterns)]
 #![feature(debug_builders)]
+#![feature(zero_one)]
+#![cfg_attr(test, feature(float_from_str_radix))]
 #![cfg_attr(test, feature(test, rustc_private, std_misc))]
 
 // Don't link to std. We are std.
index a152b98822a0bead2e9c337d927ca36d21a8fb02..3bfc764e540b21b900f0a95673a4c3c7288dbd03 100644 (file)
@@ -18,8 +18,6 @@
 use prelude::v1::*;
 
 use io::{self, Error, ErrorKind};
-#[allow(deprecated)] // Int
-use num::Int;
 use sys_common::net2 as net_imp;
 
 pub use self::ip::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
@@ -55,10 +53,21 @@ pub enum Shutdown {
     Both,
 }
 
-#[allow(deprecated)] // Int
-fn hton<I: Int>(i: I) -> I { i.to_be() }
-#[allow(deprecated)] // Int
-fn ntoh<I: Int>(i: I) -> I { Int::from_be(i) }
+#[doc(hidden)]
+trait NetInt {
+    fn from_be(i: Self) -> Self;
+    fn to_be(&self) -> Self;
+}
+macro_rules! doit {
+    ($($t:ident)*) => ($(impl NetInt for $t {
+        fn from_be(i: Self) -> Self { <$t>::from_be(i) }
+        fn to_be(&self) -> Self { <$t>::to_be(*self) }
+    })*)
+}
+doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
+
+fn hton<I: NetInt>(i: I) -> I { i.to_be() }
+fn ntoh<I: NetInt>(i: I) -> I { I::from_be(i) }
 
 fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
     where F: FnMut(&SocketAddr) -> io::Result<T>
index 736f6d2f4f4f834f96894ff98161b1b6ffffef01..0efc04ef83c6874e96f28ef71dcbd2e0bdeea5ad 100644 (file)
 
 use prelude::v1::*;
 
+use core::num;
 use intrinsics;
 use libc::c_int;
-use num::{Float, FpCategory};
-use num::strconv;
-use num::strconv::ExponentFormat::{ExpNone, ExpDec};
-use num::strconv::SignificantDigits::{DigAll, DigMax, DigExact};
-use num::strconv::SignFormat::SignNeg;
-
-use core::num;
+use num::{FpCategory, ParseFloatError};
+use sys_common::FromInner;
 
-pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};
-pub use core::f32::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP};
+pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON};
+pub use core::f32::{MIN_EXP, MAX_EXP, MIN_10_EXP};
 pub use core::f32::{MAX_10_EXP, NAN, INFINITY, NEG_INFINITY};
 pub use core::f32::{MIN, MIN_POSITIVE, MAX};
 pub use core::f32::consts;
@@ -74,294 +70,16 @@ mod cmath {
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-impl Float for f32 {
-    #[inline]
-    fn nan() -> f32 { num::Float::nan() }
-    #[inline]
-    fn infinity() -> f32 { num::Float::infinity() }
-    #[inline]
-    fn neg_infinity() -> f32 { num::Float::neg_infinity() }
-    #[inline]
-    fn zero() -> f32 { num::Float::zero() }
-    #[inline]
-    fn neg_zero() -> f32 { num::Float::neg_zero() }
-    #[inline]
-    fn one() -> f32 { num::Float::one() }
-
-    #[allow(deprecated)]
-    #[inline]
-    fn mantissa_digits(unused_self: Option<f32>) -> usize {
-        num::Float::mantissa_digits(unused_self)
-    }
-    #[allow(deprecated)]
-    #[inline]
-    fn digits(unused_self: Option<f32>) -> usize { num::Float::digits(unused_self) }
-    #[allow(deprecated)]
-    #[inline]
-    fn epsilon() -> f32 { num::Float::epsilon() }
-    #[allow(deprecated)]
-    #[inline]
-    fn min_exp(unused_self: Option<f32>) -> isize { num::Float::min_exp(unused_self) }
-    #[allow(deprecated)]
-    #[inline]
-    fn max_exp(unused_self: Option<f32>) -> isize { num::Float::max_exp(unused_self) }
-    #[allow(deprecated)]
-    #[inline]
-    fn min_10_exp(unused_self: Option<f32>) -> isize { num::Float::min_10_exp(unused_self) }
-    #[allow(deprecated)]
-    #[inline]
-    fn max_10_exp(unused_self: Option<f32>) -> isize { num::Float::max_10_exp(unused_self) }
-    #[allow(deprecated)]
-    #[inline]
-    fn min_value() -> f32 { num::Float::min_value() }
-    #[allow(deprecated)]
-    #[inline]
-    fn min_pos_value(unused_self: Option<f32>) -> f32 { num::Float::min_pos_value(unused_self) }
-    #[allow(deprecated)]
-    #[inline]
-    fn max_value() -> f32 { num::Float::max_value() }
-
-    #[inline]
-    fn is_nan(self) -> bool { num::Float::is_nan(self) }
-    #[inline]
-    fn is_infinite(self) -> bool { num::Float::is_infinite(self) }
-    #[inline]
-    fn is_finite(self) -> bool { num::Float::is_finite(self) }
-    #[inline]
-    fn is_normal(self) -> bool { num::Float::is_normal(self) }
-    #[inline]
-    fn classify(self) -> FpCategory { num::Float::classify(self) }
-
-    #[inline]
-    fn integer_decode(self) -> (u64, i16, i8) { num::Float::integer_decode(self) }
-
-    #[inline]
-    fn floor(self) -> f32 { num::Float::floor(self) }
-    #[inline]
-    fn ceil(self) -> f32 { num::Float::ceil(self) }
-    #[inline]
-    fn round(self) -> f32 { num::Float::round(self) }
-    #[inline]
-    fn trunc(self) -> f32 { num::Float::trunc(self) }
-    #[inline]
-    fn fract(self) -> f32 { num::Float::fract(self) }
-
-    #[inline]
-    fn abs(self) -> f32 { num::Float::abs(self) }
-    #[inline]
-    fn signum(self) -> f32 { num::Float::signum(self) }
-    #[inline]
-    fn is_positive(self) -> bool { num::Float::is_positive(self) }
-    #[inline]
-    fn is_negative(self) -> bool { num::Float::is_negative(self) }
-
-    #[inline]
-    fn mul_add(self, a: f32, b: f32) -> f32 { num::Float::mul_add(self, a, b) }
-    #[inline]
-    fn recip(self) -> f32 { num::Float::recip(self) }
-
-    #[inline]
-    fn powi(self, n: i32) -> f32 { num::Float::powi(self, n) }
-    #[inline]
-    fn powf(self, n: f32) -> f32 { num::Float::powf(self, n) }
-
-    #[inline]
-    fn sqrt(self) -> f32 { num::Float::sqrt(self) }
-    #[inline]
-    fn rsqrt(self) -> f32 { num::Float::rsqrt(self) }
-
-    #[inline]
-    fn exp(self) -> f32 { num::Float::exp(self) }
-    #[inline]
-    fn exp2(self) -> f32 { num::Float::exp2(self) }
-    #[inline]
-    fn ln(self) -> f32 { num::Float::ln(self) }
-    #[inline]
-    fn log(self, base: f32) -> f32 { num::Float::log(self, base) }
-    #[inline]
-    fn log2(self) -> f32 { num::Float::log2(self) }
-    #[inline]
-    fn log10(self) -> f32 { num::Float::log10(self) }
-    #[inline]
-    fn to_degrees(self) -> f32 { num::Float::to_degrees(self) }
-    #[inline]
-    fn to_radians(self) -> f32 { num::Float::to_radians(self) }
-
-    /// Constructs a floating point number by multiplying `x` by 2 raised to the
-    /// power of `exp`
-    #[inline]
-    fn ldexp(self, exp: isize) -> f32 {
-        unsafe { cmath::ldexpf(self, exp as c_int) }
-    }
-
-    /// Breaks the number into a normalized fraction and a base-2 exponent,
-    /// satisfying:
-    ///
-    /// - `self = x * pow(2, exp)`
-    /// - `0.5 <= abs(x) < 1.0`
-    #[inline]
-    fn frexp(self) -> (f32, isize) {
-        unsafe {
-            let mut exp = 0;
-            let x = cmath::frexpf(self, &mut exp);
-            (x, exp as isize)
-        }
-    }
-
-    /// Returns the next representable floating-point value in the direction of
-    /// `other`.
-    #[inline]
-    fn next_after(self, other: f32) -> f32 {
-        unsafe { cmath::nextafterf(self, other) }
-    }
-
-    #[inline]
-    fn max(self, other: f32) -> f32 {
-        unsafe { cmath::fmaxf(self, other) }
-    }
-
-    #[inline]
-    fn min(self, other: f32) -> f32 {
-        unsafe { cmath::fminf(self, other) }
-    }
-
-    #[inline]
-    fn abs_sub(self, other: f32) -> f32 {
-        unsafe { cmath::fdimf(self, other) }
-    }
-
-    #[inline]
-    fn cbrt(self) -> f32 {
-        unsafe { cmath::cbrtf(self) }
-    }
-
-    #[inline]
-    fn hypot(self, other: f32) -> f32 {
-        unsafe { cmath::hypotf(self, other) }
-    }
-
-    #[inline]
-    fn sin(self) -> f32 {
-        unsafe { intrinsics::sinf32(self) }
-    }
-
-    #[inline]
-    fn cos(self) -> f32 {
-        unsafe { intrinsics::cosf32(self) }
-    }
-
-    #[inline]
-    fn tan(self) -> f32 {
-        unsafe { cmath::tanf(self) }
-    }
-
-    #[inline]
-    fn asin(self) -> f32 {
-        unsafe { cmath::asinf(self) }
-    }
-
-    #[inline]
-    fn acos(self) -> f32 {
-        unsafe { cmath::acosf(self) }
-    }
-
-    #[inline]
-    fn atan(self) -> f32 {
-        unsafe { cmath::atanf(self) }
-    }
-
-    #[inline]
-    fn atan2(self, other: f32) -> f32 {
-        unsafe { cmath::atan2f(self, other) }
-    }
-
-    /// Simultaneously computes the sine and cosine of the number
-    #[inline]
-    fn sin_cos(self) -> (f32, f32) {
-        (self.sin(), self.cos())
-    }
-
-    /// Returns the exponential of the number, minus `1`, in a way that is
-    /// accurate even if the number is close to zero
-    #[inline]
-    fn exp_m1(self) -> f32 {
-        unsafe { cmath::expm1f(self) }
-    }
-
-    /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more
-    /// accurately than if the operations were performed separately
-    #[inline]
-    fn ln_1p(self) -> f32 {
-        unsafe { cmath::log1pf(self) }
-    }
-
-    #[inline]
-    fn sinh(self) -> f32 {
-        unsafe { cmath::sinhf(self) }
-    }
-
-    #[inline]
-    fn cosh(self) -> f32 {
-        unsafe { cmath::coshf(self) }
-    }
-
-    #[inline]
-    fn tanh(self) -> f32 {
-        unsafe { cmath::tanhf(self) }
-    }
-
-    /// Inverse hyperbolic sine
-    ///
-    /// # Returns
-    ///
-    /// - on success, the inverse hyperbolic sine of `self` will be returned
-    /// - `self` if `self` is `0.0`, `-0.0`, `INFINITY`, or `NEG_INFINITY`
-    /// - `NAN` if `self` is `NAN`
-    #[inline]
-    fn asinh(self) -> f32 {
-        match self {
-            NEG_INFINITY => NEG_INFINITY,
-            x => (x + ((x * x) + 1.0).sqrt()).ln(),
-        }
-    }
-
-    /// Inverse hyperbolic cosine
-    ///
-    /// # Returns
-    ///
-    /// - on success, the inverse hyperbolic cosine of `self` will be returned
-    /// - `INFINITY` if `self` is `INFINITY`
-    /// - `NAN` if `self` is `NAN` or `self < 1.0` (including `NEG_INFINITY`)
-    #[inline]
-    fn acosh(self) -> f32 {
-        match self {
-            x if x < 1.0 => Float::nan(),
-            x => (x + ((x * x) - 1.0).sqrt()).ln(),
-        }
-    }
-
-    /// Inverse hyperbolic tangent
-    ///
-    /// # Returns
-    ///
-    /// - on success, the inverse hyperbolic tangent of `self` will be returned
-    /// - `self` if `self` is `0.0` or `-0.0`
-    /// - `INFINITY` if `self` is `1.0`
-    /// - `NEG_INFINITY` if `self` is `-1.0`
-    /// - `NAN` if the `self` is `NAN` or outside the domain of `-1.0 <= self <= 1.0`
-    ///   (including `INFINITY` and `NEG_INFINITY`)
-    #[inline]
-    fn atanh(self) -> f32 {
-        0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
-    }
-}
-
 #[cfg(not(test))]
 #[lang = "f32"]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl f32 {
+    /// Parses a float as with a given radix
+    #[unstable(feature = "float_from_str_radix", reason = "recently moved API")]
+    pub fn from_str_radix(s: &str, radix: u32) -> Result<f32, ParseFloatError> {
+        num::Float::from_str_radix(s, radix).map_err(FromInner::from_inner)
+    }
+
     /// Returns `true` if this value is `NaN` and false otherwise.
     ///
     /// ```
@@ -617,11 +335,6 @@ pub fn signum(self) -> f32 { num::Float::signum(self) }
     #[inline]
     pub fn is_sign_positive(self) -> bool { num::Float::is_positive(self) }
 
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[deprecated(since = "1.0.0", reason = "renamed to is_sign_positive")]
-    #[inline]
-    pub fn is_positive(self) -> bool { num::Float::is_positive(self) }
-
     /// Returns `true` if `self`'s sign is negative, including `-0.0`
     /// and `NEG_INFINITY`.
     ///
@@ -641,11 +354,6 @@ pub fn is_positive(self) -> bool { num::Float::is_positive(self) }
     #[inline]
     pub fn is_sign_negative(self) -> bool { num::Float::is_negative(self) }
 
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[deprecated(since = "1.0.0", reason = "renamed to is_sign_negative")]
-    #[inline]
-    pub fn is_negative(self) -> bool { num::Float::is_negative(self) }
-
     /// 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.
@@ -729,24 +437,6 @@ pub fn powf(self, n: f32) -> f32 { num::Float::powf(self, n) }
     #[inline]
     pub fn sqrt(self) -> f32 { num::Float::sqrt(self) }
 
-    /// Takes the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// use std::f32;
-    ///
-    /// let f = 4.0f32;
-    ///
-    /// let abs_difference = (f.rsqrt() - 0.5).abs();
-    ///
-    /// assert!(abs_difference <= f32::EPSILON);
-    /// ```
-    #[unstable(feature = "std_misc",
-               reason = "unsure about its place in the world")]
-    #[deprecated(since = "1.0.0", reason = "use self.sqrt().recip() instead")]
-    #[inline]
-    pub fn rsqrt(self) -> f32 { num::Float::rsqrt(self) }
-
     /// Returns `e^(self)`, (the exponential function).
     ///
     /// ```
@@ -1339,7 +1029,7 @@ pub fn asinh(self) -> f32 {
     #[inline]
     pub fn acosh(self) -> f32 {
         match self {
-            x if x < 1.0 => Float::nan(),
+            x if x < 1.0 => ::f32::NAN,
             x => (x + ((x * x) - 1.0).sqrt()).ln(),
         }
     }
@@ -1363,116 +1053,9 @@ pub fn atanh(self) -> f32 {
     }
 }
 
-//
-// Section: String Conversions
-//
-
-/// Converts a float to a string
-///
-/// # Arguments
-///
-/// * num - The float value
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-#[deprecated(since = "1.0.0", reason = "use the ToString trait instead")]
-pub fn to_string(num: f32) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigAll, ExpNone, false);
-    r
-}
-
-/// Converts a float to a string in hexadecimal format
-///
-/// # Arguments
-///
-/// * num - The float value
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-#[deprecated(since = "1.0.0", reason = "use format! instead")]
-pub fn to_str_hex(num: f32) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 16, true, SignNeg, DigAll, ExpNone, false);
-    r
-}
-
-/// Converts a float to a string in a given radix, and a flag indicating
-/// whether it's a special value
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * radix - The base to use
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-#[deprecated(since = "1.0.0", reason = "use format! instead")]
-pub fn to_str_radix_special(num: f32, rdx: u32) -> (String, bool) {
-    strconv::float_to_str_common(num, rdx, true, SignNeg, DigAll, ExpNone, false)
-}
-
-/// Converts a float to a string with exactly the number of
-/// provided significant digits
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of significant digits
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_exact(num: f32, dig: usize) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigExact(dig), ExpNone, false);
-    r
-}
-
-/// Converts a float to a string with a maximum number of
-/// significant digits
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of significant digits
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_digits(num: f32, dig: usize) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigMax(dig), ExpNone, false);
-    r
-}
-
-/// Converts a float to a string using the exponential notation with exactly the number of
-/// provided digits after the decimal point in the significand
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of digits after the decimal point
-/// * upper - Use `E` instead of `e` for the exponent sign
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_exp_exact(num: f32, dig: usize, upper: bool) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigExact(dig), ExpDec, upper);
-    r
-}
-
-/// Converts a float to a string using the exponential notation with the maximum number of
-/// digits after the decimal point in the significand
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of digits after the decimal point
-/// * upper - Use `E` instead of `e` for the exponent sign
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_exp_digits(num: f32, dig: usize, upper: bool) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigMax(dig), ExpDec, upper);
-    r
-}
-
 #[cfg(test)]
 mod tests {
+    use f32;
     use f32::*;
     use num::*;
     use num::FpCategory as Fp;
@@ -1496,7 +1079,7 @@ fn test_max_nan() {
 
     #[test]
     fn test_nan() {
-        let nan: f32 = Float::nan();
+        let nan: f32 = f32::NAN;
         assert!(nan.is_nan());
         assert!(!nan.is_infinite());
         assert!(!nan.is_finite());
@@ -1508,7 +1091,7 @@ fn test_nan() {
 
     #[test]
     fn test_infinity() {
-        let inf: f32 = Float::infinity();
+        let inf: f32 = f32::INFINITY;
         assert!(inf.is_infinite());
         assert!(!inf.is_finite());
         assert!(inf.is_sign_positive());
@@ -1520,7 +1103,7 @@ fn test_infinity() {
 
     #[test]
     fn test_neg_infinity() {
-        let neg_inf: f32 = Float::neg_infinity();
+        let neg_inf: f32 = f32::NEG_INFINITY;
         assert!(neg_inf.is_infinite());
         assert!(!neg_inf.is_finite());
         assert!(!neg_inf.is_sign_positive());
@@ -1532,7 +1115,7 @@ fn test_neg_infinity() {
 
     #[test]
     fn test_zero() {
-        let zero: f32 = Float::zero();
+        let zero: f32 = 0.0f32;
         assert_eq!(0.0, zero);
         assert!(!zero.is_infinite());
         assert!(zero.is_finite());
@@ -1545,7 +1128,7 @@ fn test_zero() {
 
     #[test]
     fn test_neg_zero() {
-        let neg_zero: f32 = Float::neg_zero();
+        let neg_zero: f32 = -0.0;
         assert_eq!(0.0, neg_zero);
         assert!(!neg_zero.is_infinite());
         assert!(neg_zero.is_finite());
@@ -1558,7 +1141,7 @@ fn test_neg_zero() {
 
     #[test]
     fn test_one() {
-        let one: f32 = Float::one();
+        let one: f32 = 1.0f32;
         assert_eq!(1.0, one);
         assert!(!one.is_infinite());
         assert!(one.is_finite());
@@ -1571,9 +1154,9 @@ fn test_one() {
 
     #[test]
     fn test_is_nan() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = f32::NAN;
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
         assert!(nan.is_nan());
         assert!(!0.0f32.is_nan());
         assert!(!5.3f32.is_nan());
@@ -1584,9 +1167,9 @@ fn test_is_nan() {
 
     #[test]
     fn test_is_infinite() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = f32::NAN;
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
         assert!(!nan.is_infinite());
         assert!(inf.is_infinite());
         assert!(neg_inf.is_infinite());
@@ -1597,9 +1180,9 @@ fn test_is_infinite() {
 
     #[test]
     fn test_is_finite() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = f32::NAN;
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
         assert!(!nan.is_finite());
         assert!(!inf.is_finite());
         assert!(!neg_inf.is_finite());
@@ -1610,11 +1193,11 @@ fn test_is_finite() {
 
     #[test]
     fn test_is_normal() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let zero: f32 = Float::zero();
-        let neg_zero: f32 = Float::neg_zero();
+        let nan: f32 = f32::NAN;
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
+        let zero: f32 = 0.0f32;
+        let neg_zero: f32 = -0.0;
         assert!(!nan.is_normal());
         assert!(!inf.is_normal());
         assert!(!neg_inf.is_normal());
@@ -1627,11 +1210,11 @@ fn test_is_normal() {
 
     #[test]
     fn test_classify() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let zero: f32 = Float::zero();
-        let neg_zero: f32 = Float::neg_zero();
+        let nan: f32 = f32::NAN;
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
+        let zero: f32 = 0.0f32;
+        let neg_zero: f32 = -0.0;
         assert_eq!(nan.classify(), Fp::Nan);
         assert_eq!(inf.classify(), Fp::Infinite);
         assert_eq!(neg_inf.classify(), Fp::Infinite);
@@ -1774,9 +1357,9 @@ fn test_is_sign_negative() {
 
     #[test]
     fn test_mul_add() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = f32::NAN;
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
         assert_approx_eq!(12.3f32.mul_add(4.5, 6.7), 62.05);
         assert_approx_eq!((-12.3f32).mul_add(-4.5, -6.7), 48.65);
         assert_approx_eq!(0.0f32.mul_add(8.9, 1.2), 1.2);
@@ -1790,9 +1373,9 @@ fn test_mul_add() {
 
     #[test]
     fn test_recip() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = f32::NAN;
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
         assert_eq!(1.0f32.recip(), 1.0);
         assert_eq!(2.0f32.recip(), 0.5);
         assert_eq!((-0.4f32).recip(), -2.5);
@@ -1804,9 +1387,9 @@ fn test_recip() {
 
     #[test]
     fn test_powi() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = f32::NAN;
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
         assert_eq!(1.0f32.powi(1), 1.0);
         assert_approx_eq!((-3.1f32).powi(2), 9.61);
         assert_approx_eq!(5.9f32.powi(-2), 0.028727);
@@ -1818,9 +1401,9 @@ fn test_powi() {
 
     #[test]
     fn test_powf() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = f32::NAN;
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
         assert_eq!(1.0f32.powf(1.0), 1.0);
         assert_approx_eq!(3.4f32.powf(4.5), 246.408218);
         assert_approx_eq!(2.7f32.powf(-3.2), 0.041652);
@@ -1843,30 +1426,15 @@ fn test_sqrt_domain() {
         assert_eq!(INFINITY.sqrt(), INFINITY);
     }
 
-    #[test]
-    fn test_rsqrt() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        assert!(nan.rsqrt().is_nan());
-        assert_eq!(inf.rsqrt(), 0.0);
-        assert!(neg_inf.rsqrt().is_nan());
-        assert!((-1.0f32).rsqrt().is_nan());
-        assert_eq!((-0.0f32).rsqrt(), neg_inf);
-        assert_eq!(0.0f32.rsqrt(), inf);
-        assert_eq!(1.0f32.rsqrt(), 1.0);
-        assert_eq!(4.0f32.rsqrt(), 0.5);
-    }
-
     #[test]
     fn test_exp() {
         assert_eq!(1.0, 0.0f32.exp());
         assert_approx_eq!(2.718282, 1.0f32.exp());
         assert_approx_eq!(148.413162, 5.0f32.exp());
 
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let nan: f32 = Float::nan();
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
+        let nan: f32 = f32::NAN;
         assert_eq!(inf, inf.exp());
         assert_eq!(0.0, neg_inf.exp());
         assert!(nan.exp().is_nan());
@@ -1877,9 +1445,9 @@ fn test_exp2() {
         assert_eq!(32.0, 5.0f32.exp2());
         assert_eq!(1.0, 0.0f32.exp2());
 
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let nan: f32 = Float::nan();
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
+        let nan: f32 = f32::NAN;
         assert_eq!(inf, inf.exp2());
         assert_eq!(0.0, neg_inf.exp2());
         assert!(nan.exp2().is_nan());
@@ -1887,9 +1455,9 @@ fn test_exp2() {
 
     #[test]
     fn test_ln() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = f32::NAN;
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
         assert_approx_eq!(1.0f32.exp().ln(), 1.0);
         assert!(nan.ln().is_nan());
         assert_eq!(inf.ln(), inf);
@@ -1902,12 +1470,12 @@ fn test_ln() {
 
     #[test]
     fn test_log() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = f32::NAN;
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
         assert_eq!(10.0f32.log(10.0), 1.0);
         assert_approx_eq!(2.3f32.log(3.5), 0.664858);
-        assert_eq!(1.0f32.exp().log(1.0.exp()), 1.0);
+        assert_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0);
         assert!(1.0f32.log(1.0).is_nan());
         assert!(1.0f32.log(-13.9).is_nan());
         assert!(nan.log(2.3).is_nan());
@@ -1920,9 +1488,9 @@ fn test_log() {
 
     #[test]
     fn test_log2() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = f32::NAN;
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
         assert_approx_eq!(10.0f32.log2(), 3.321928);
         assert_approx_eq!(2.3f32.log2(), 1.201634);
         assert_approx_eq!(1.0f32.exp().log2(), 1.442695);
@@ -1936,9 +1504,9 @@ fn test_log2() {
 
     #[test]
     fn test_log10() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = f32::NAN;
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
         assert_eq!(10.0f32.log10(), 1.0);
         assert_approx_eq!(2.3f32.log10(), 0.361728);
         assert_approx_eq!(1.0f32.exp().log10(), 0.434294);
@@ -1954,9 +1522,9 @@ fn test_log10() {
     #[test]
     fn test_to_degrees() {
         let pi: f32 = consts::PI;
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = f32::NAN;
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
         assert_eq!(0.0f32.to_degrees(), 0.0);
         assert_approx_eq!((-5.8f32).to_degrees(), -332.315521);
         assert_eq!(pi.to_degrees(), 180.0);
@@ -1968,9 +1536,9 @@ fn test_to_degrees() {
     #[test]
     fn test_to_radians() {
         let pi: f32 = consts::PI;
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = f32::NAN;
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
         assert_eq!(0.0f32.to_radians(), 0.0);
         assert_approx_eq!(154.6f32.to_radians(), 2.698279);
         assert_approx_eq!((-332.31f32).to_radians(), -5.799903);
@@ -1984,40 +1552,40 @@ fn test_to_radians() {
     fn test_ldexp() {
         // We have to use from_str until base-2 exponents
         // are supported in floating-point literals
-        let f1: f32 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
-        let f2: f32 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
-        let f3: f32 = FromStrRadix::from_str_radix("1.Cp-12", 16).unwrap();
-        assert_eq!(1f32.ldexp(-123), f1);
-        assert_eq!(1f32.ldexp(-111), f2);
-        assert_eq!(Float::ldexp(1.75f32, -12), f3);
+        let f1: f32 = f32::from_str_radix("1p-123", 16).unwrap();
+        let f2: f32 = f32::from_str_radix("1p-111", 16).unwrap();
+        let f3: f32 = f32::from_str_radix("1.Cp-12", 16).unwrap();
+        assert_eq!(f32::ldexp(1f32, -123), f1);
+        assert_eq!(f32::ldexp(1f32, -111), f2);
+        assert_eq!(f32::ldexp(1.75f32, -12), f3);
 
-        assert_eq!(Float::ldexp(0f32, -123), 0f32);
-        assert_eq!(Float::ldexp(-0f32, -123), -0f32);
+        assert_eq!(f32::ldexp(0f32, -123), 0f32);
+        assert_eq!(f32::ldexp(-0f32, -123), -0f32);
 
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let nan: f32 = Float::nan();
-        assert_eq!(Float::ldexp(inf, -123), inf);
-        assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
-        assert!(Float::ldexp(nan, -123).is_nan());
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
+        let nan: f32 = f32::NAN;
+        assert_eq!(f32::ldexp(inf, -123), inf);
+        assert_eq!(f32::ldexp(neg_inf, -123), neg_inf);
+        assert!(f32::ldexp(nan, -123).is_nan());
     }
 
     #[test]
     fn test_frexp() {
         // We have to use from_str until base-2 exponents
         // are supported in floating-point literals
-        let f1: f32 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
-        let f2: f32 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
-        let f3: f32 = FromStrRadix::from_str_radix("1.Cp-123", 16).unwrap();
+        let f1: f32 = f32::from_str_radix("1p-123", 16).unwrap();
+        let f2: f32 = f32::from_str_radix("1p-111", 16).unwrap();
+        let f3: f32 = f32::from_str_radix("1.Cp-123", 16).unwrap();
         let (x1, exp1) = f1.frexp();
         let (x2, exp2) = f2.frexp();
         let (x3, exp3) = f3.frexp();
         assert_eq!((x1, exp1), (0.5f32, -122));
         assert_eq!((x2, exp2), (0.5f32, -110));
         assert_eq!((x3, exp3), (0.875f32, -122));
-        assert_eq!(Float::ldexp(x1, exp1), f1);
-        assert_eq!(Float::ldexp(x2, exp2), f2);
-        assert_eq!(Float::ldexp(x3, exp3), f3);
+        assert_eq!(f32::ldexp(x1, exp1), f1);
+        assert_eq!(f32::ldexp(x2, exp2), f2);
+        assert_eq!(f32::ldexp(x3, exp3), f3);
 
         assert_eq!(0f32.frexp(), (0f32, 0));
         assert_eq!((-0f32).frexp(), (-0f32, 0));
@@ -2025,9 +1593,9 @@ fn test_frexp() {
 
     #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
     fn test_frexp_nowin() {
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let nan: f32 = Float::nan();
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
+        let nan: f32 = f32::NAN;
         assert_eq!(match inf.frexp() { (x, _) => x }, inf);
         assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
         assert!(match nan.frexp() { (x, _) => x.is_nan() })
@@ -2056,9 +1624,9 @@ fn test_asinh() {
         assert_eq!(0.0f32.asinh(), 0.0f32);
         assert_eq!((-0.0f32).asinh(), -0.0f32);
 
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let nan: f32 = Float::nan();
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
+        let nan: f32 = f32::NAN;
         assert_eq!(inf.asinh(), inf);
         assert_eq!(neg_inf.asinh(), neg_inf);
         assert!(nan.asinh().is_nan());
@@ -2071,9 +1639,9 @@ fn test_acosh() {
         assert_eq!(1.0f32.acosh(), 0.0f32);
         assert!(0.999f32.acosh().is_nan());
 
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let nan: f32 = Float::nan();
+        let inf: f32 = f32::INFINITY;
+        let neg_inf: f32 = f32::NEG_INFINITY;
+        let nan: f32 = f32::NAN;
         assert_eq!(inf.acosh(), inf);
         assert!(neg_inf.acosh().is_nan());
         assert!(nan.acosh().is_nan());
@@ -2086,17 +1654,17 @@ fn test_atanh() {
         assert_eq!(0.0f32.atanh(), 0.0f32);
         assert_eq!((-0.0f32).atanh(), -0.0f32);
 
-        let inf32: f32 = Float::infinity();
-        let neg_inf32: f32 = Float::neg_infinity();
+        let inf32: f32 = f32::INFINITY;
+        let neg_inf32: f32 = f32::NEG_INFINITY;
         assert_eq!(1.0f32.atanh(), inf32);
         assert_eq!((-1.0f32).atanh(), neg_inf32);
 
         assert!(2f64.atanh().atanh().is_nan());
         assert!((-2f64).atanh().atanh().is_nan());
 
-        let inf64: f32 = Float::infinity();
-        let neg_inf64: f32 = Float::neg_infinity();
-        let nan32: f32 = Float::nan();
+        let inf64: f32 = f32::INFINITY;
+        let neg_inf64: f32 = f32::NEG_INFINITY;
+        let nan32: f32 = f32::NAN;
         assert!(inf64.atanh().is_nan());
         assert!(neg_inf64.atanh().is_nan());
         assert!(nan32.atanh().is_nan());
@@ -2118,9 +1686,9 @@ fn test_real_consts() {
         let frac_pi_8: f32 = consts::FRAC_PI_8;
         let frac_1_pi: f32 = consts::FRAC_1_PI;
         let frac_2_pi: f32 = consts::FRAC_2_PI;
-        let frac_2_sqrtpi: f32 = consts::FRAC_2_SQRTPI;
-        let sqrt2: f32 = consts::SQRT2;
-        let frac_1_sqrt2: f32 = consts::FRAC_1_SQRT2;
+        let frac_2_sqrtpi: f32 = consts::FRAC_2_SQRT_PI;
+        let sqrt2: f32 = consts::SQRT_2;
+        let frac_1_sqrt2: f32 = consts::FRAC_1_SQRT_2;
         let e: f32 = consts::E;
         let log2_e: f32 = consts::LOG2_E;
         let log10_e: f32 = consts::LOG10_E;
index bb9067eca13dd85557bf6d88f75a26c126bedd51..e1497f3958dabf1bd897c62f0c2598fcd3763999 100644 (file)
 
 use prelude::v1::*;
 
+use core::num;
 use intrinsics;
 use libc::c_int;
-use num::{Float, FpCategory};
-use num::strconv;
-use num::strconv::ExponentFormat::{ExpNone, ExpDec};
-use num::strconv::SignificantDigits::{DigAll, DigMax, DigExact};
-use num::strconv::SignFormat::SignNeg;
-
-use core::num;
+use num::{FpCategory, ParseFloatError};
+use sys_common::FromInner;
 
-pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};
-pub use core::f64::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP};
+pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON};
+pub use core::f64::{MIN_EXP, MAX_EXP, MIN_10_EXP};
 pub use core::f64::{MAX_10_EXP, NAN, INFINITY, NEG_INFINITY};
 pub use core::f64::{MIN, MIN_POSITIVE, MAX};
 pub use core::f64::consts;
@@ -82,295 +78,16 @@ mod cmath {
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-impl Float for f64 {
-    // inlined methods from `num::Float`
-    #[inline]
-    fn nan() -> f64 { num::Float::nan() }
-    #[inline]
-    fn infinity() -> f64 { num::Float::infinity() }
-    #[inline]
-    fn neg_infinity() -> f64 { num::Float::neg_infinity() }
-    #[inline]
-    fn zero() -> f64 { num::Float::zero() }
-    #[inline]
-    fn neg_zero() -> f64 { num::Float::neg_zero() }
-    #[inline]
-    fn one() -> f64 { num::Float::one() }
-
-
-    #[allow(deprecated)]
-    #[inline]
-    fn mantissa_digits(unused_self: Option<f64>) -> usize {
-        num::Float::mantissa_digits(unused_self)
-    }
-    #[allow(deprecated)]
-    #[inline]
-    fn digits(unused_self: Option<f64>) -> usize { num::Float::digits(unused_self) }
-    #[allow(deprecated)]
-    #[inline]
-    fn epsilon() -> f64 { num::Float::epsilon() }
-    #[allow(deprecated)]
-    #[inline]
-    fn min_exp(unused_self: Option<f64>) -> isize { num::Float::min_exp(unused_self) }
-    #[allow(deprecated)]
-    #[inline]
-    fn max_exp(unused_self: Option<f64>) -> isize { num::Float::max_exp(unused_self) }
-    #[allow(deprecated)]
-    #[inline]
-    fn min_10_exp(unused_self: Option<f64>) -> isize { num::Float::min_10_exp(unused_self) }
-    #[allow(deprecated)]
-    #[inline]
-    fn max_10_exp(unused_self: Option<f64>) -> isize { num::Float::max_10_exp(unused_self) }
-    #[allow(deprecated)]
-    #[inline]
-    fn min_value() -> f64 { num::Float::min_value() }
-    #[allow(deprecated)]
-    #[inline]
-    fn min_pos_value(unused_self: Option<f64>) -> f64 { num::Float::min_pos_value(unused_self) }
-    #[allow(deprecated)]
-    #[inline]
-    fn max_value() -> f64 { num::Float::max_value() }
-
-    #[inline]
-    fn is_nan(self) -> bool { num::Float::is_nan(self) }
-    #[inline]
-    fn is_infinite(self) -> bool { num::Float::is_infinite(self) }
-    #[inline]
-    fn is_finite(self) -> bool { num::Float::is_finite(self) }
-    #[inline]
-    fn is_normal(self) -> bool { num::Float::is_normal(self) }
-    #[inline]
-    fn classify(self) -> FpCategory { num::Float::classify(self) }
-
-    #[inline]
-    fn integer_decode(self) -> (u64, i16, i8) { num::Float::integer_decode(self) }
-
-    #[inline]
-    fn floor(self) -> f64 { num::Float::floor(self) }
-    #[inline]
-    fn ceil(self) -> f64 { num::Float::ceil(self) }
-    #[inline]
-    fn round(self) -> f64 { num::Float::round(self) }
-    #[inline]
-    fn trunc(self) -> f64 { num::Float::trunc(self) }
-    #[inline]
-    fn fract(self) -> f64 { num::Float::fract(self) }
-
-    #[inline]
-    fn abs(self) -> f64 { num::Float::abs(self) }
-    #[inline]
-    fn signum(self) -> f64 { num::Float::signum(self) }
-    #[inline]
-    fn is_positive(self) -> bool { num::Float::is_positive(self) }
-    #[inline]
-    fn is_negative(self) -> bool { num::Float::is_negative(self) }
-
-    #[inline]
-    fn mul_add(self, a: f64, b: f64) -> f64 { num::Float::mul_add(self, a, b) }
-    #[inline]
-    fn recip(self) -> f64 { num::Float::recip(self) }
-
-    #[inline]
-    fn powi(self, n: i32) -> f64 { num::Float::powi(self, n) }
-    #[inline]
-    fn powf(self, n: f64) -> f64 { num::Float::powf(self, n) }
-
-    #[inline]
-    fn sqrt(self) -> f64 { num::Float::sqrt(self) }
-    #[inline]
-    fn rsqrt(self) -> f64 { num::Float::rsqrt(self) }
-
-    #[inline]
-    fn exp(self) -> f64 { num::Float::exp(self) }
-    #[inline]
-    fn exp2(self) -> f64 { num::Float::exp2(self) }
-    #[inline]
-    fn ln(self) -> f64 { num::Float::ln(self) }
-    #[inline]
-    fn log(self, base: f64) -> f64 { num::Float::log(self, base) }
-    #[inline]
-    fn log2(self) -> f64 { num::Float::log2(self) }
-    #[inline]
-    fn log10(self) -> f64 { num::Float::log10(self) }
-
-    #[inline]
-    fn to_degrees(self) -> f64 { num::Float::to_degrees(self) }
-    #[inline]
-    fn to_radians(self) -> f64 { num::Float::to_radians(self) }
-
-    #[inline]
-    fn ldexp(self, exp: isize) -> f64 {
-        unsafe { cmath::ldexp(self, exp as c_int) }
-    }
-
-    /// Breaks the number into a normalized fraction and a base-2 exponent,
-    /// satisfying:
-    ///
-    /// - `self = x * pow(2, exp)`
-    /// - `0.5 <= abs(x) < 1.0`
-    #[inline]
-    fn frexp(self) -> (f64, isize) {
-        unsafe {
-            let mut exp = 0;
-            let x = cmath::frexp(self, &mut exp);
-            (x, exp as isize)
-        }
-    }
-
-    /// Returns the next representable floating-point value in the direction of
-    /// `other`.
-    #[inline]
-    fn next_after(self, other: f64) -> f64 {
-        unsafe { cmath::nextafter(self, other) }
-    }
-
-    #[inline]
-    fn max(self, other: f64) -> f64 {
-        unsafe { cmath::fmax(self, other) }
-    }
-
-    #[inline]
-    fn min(self, other: f64) -> f64 {
-        unsafe { cmath::fmin(self, other) }
-    }
-
-    #[inline]
-    fn abs_sub(self, other: f64) -> f64 {
-        unsafe { cmath::fdim(self, other) }
-    }
-
-    #[inline]
-    fn cbrt(self) -> f64 {
-        unsafe { cmath::cbrt(self) }
-    }
-
-    #[inline]
-    fn hypot(self, other: f64) -> f64 {
-        unsafe { cmath::hypot(self, other) }
-    }
-
-    #[inline]
-    fn sin(self) -> f64 {
-        unsafe { intrinsics::sinf64(self) }
-    }
-
-    #[inline]
-    fn cos(self) -> f64 {
-        unsafe { intrinsics::cosf64(self) }
-    }
-
-    #[inline]
-    fn tan(self) -> f64 {
-        unsafe { cmath::tan(self) }
-    }
-
-    #[inline]
-    fn asin(self) -> f64 {
-        unsafe { cmath::asin(self) }
-    }
-
-    #[inline]
-    fn acos(self) -> f64 {
-        unsafe { cmath::acos(self) }
-    }
-
-    #[inline]
-    fn atan(self) -> f64 {
-        unsafe { cmath::atan(self) }
-    }
-
-    #[inline]
-    fn atan2(self, other: f64) -> f64 {
-        unsafe { cmath::atan2(self, other) }
-    }
-
-    /// Simultaneously computes the sine and cosine of the number
-    #[inline]
-    fn sin_cos(self) -> (f64, f64) {
-        (self.sin(), self.cos())
-    }
-
-    /// Returns the exponential of the number, minus `1`, in a way that is
-    /// accurate even if the number is close to zero
-    #[inline]
-    fn exp_m1(self) -> f64 {
-        unsafe { cmath::expm1(self) }
-    }
-
-    /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more
-    /// accurately than if the operations were performed separately
-    #[inline]
-    fn ln_1p(self) -> f64 {
-        unsafe { cmath::log1p(self) }
-    }
-
-    #[inline]
-    fn sinh(self) -> f64 {
-        unsafe { cmath::sinh(self) }
-    }
-
-    #[inline]
-    fn cosh(self) -> f64 {
-        unsafe { cmath::cosh(self) }
-    }
-
-    #[inline]
-    fn tanh(self) -> f64 {
-        unsafe { cmath::tanh(self) }
-    }
-
-    /// Inverse hyperbolic sine
-    ///
-    /// # Returns
-    ///
-    /// - on success, the inverse hyperbolic sine of `self` will be returned
-    /// - `self` if `self` is `0.0`, `-0.0`, `INFINITY`, or `NEG_INFINITY`
-    /// - `NAN` if `self` is `NAN`
-    #[inline]
-    fn asinh(self) -> f64 {
-        match self {
-            NEG_INFINITY => NEG_INFINITY,
-            x => (x + ((x * x) + 1.0).sqrt()).ln(),
-        }
-    }
-
-    /// Inverse hyperbolic cosine
-    ///
-    /// # Returns
-    ///
-    /// - on success, the inverse hyperbolic cosine of `self` will be returned
-    /// - `INFINITY` if `self` is `INFINITY`
-    /// - `NAN` if `self` is `NAN` or `self < 1.0` (including `NEG_INFINITY`)
-    #[inline]
-    fn acosh(self) -> f64 {
-        match self {
-            x if x < 1.0 => Float::nan(),
-            x => (x + ((x * x) - 1.0).sqrt()).ln(),
-        }
-    }
-
-    /// Inverse hyperbolic tangent
-    ///
-    /// # Returns
-    ///
-    /// - on success, the inverse hyperbolic tangent of `self` will be returned
-    /// - `self` if `self` is `0.0` or `-0.0`
-    /// - `INFINITY` if `self` is `1.0`
-    /// - `NEG_INFINITY` if `self` is `-1.0`
-    /// - `NAN` if the `self` is `NAN` or outside the domain of `-1.0 <= self <= 1.0`
-    ///   (including `INFINITY` and `NEG_INFINITY`)
-    #[inline]
-    fn atanh(self) -> f64 {
-        0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
-    }
-}
-
 #[cfg(not(test))]
 #[lang = "f64"]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl f64 {
+    /// Parses a float as with a given radix
+    #[unstable(feature = "float_from_str_radix", reason = "recently moved API")]
+    pub fn from_str_radix(s: &str, radix: u32) -> Result<f64, ParseFloatError> {
+        num::Float::from_str_radix(s, radix).map_err(FromInner::from_inner)
+    }
+
     /// Returns `true` if this value is `NaN` and false otherwise.
     ///
     /// ```
@@ -726,22 +443,6 @@ pub fn powf(self, n: f64) -> f64 { num::Float::powf(self, n) }
     #[inline]
     pub fn sqrt(self) -> f64 { num::Float::sqrt(self) }
 
-    /// Takes the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// let f = 4.0_f64;
-    ///
-    /// let abs_difference = (f.rsqrt() - 0.5).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    #[unstable(feature = "std_misc",
-               reason = "unsure about its place in the world")]
-    #[deprecated(since = "1.0.0", reason = "use self.sqrt().recip() instead")]
-    #[inline]
-    pub fn rsqrt(self) -> f64 { num::Float::rsqrt(self) }
-
     /// Returns `e^(self)`, (the exponential function).
     ///
     /// ```
@@ -1304,7 +1005,7 @@ pub fn asinh(self) -> f64 {
     #[inline]
     pub fn acosh(self) -> f64 {
         match self {
-            x if x < 1.0 => Float::nan(),
+            x if x < 1.0 => NAN,
             x => (x + ((x * x) - 1.0).sqrt()).ln(),
         }
     }
@@ -1328,116 +1029,9 @@ pub fn atanh(self) -> f64 {
     }
 }
 
-//
-// Section: String Conversions
-//
-
-/// Converts a float to a string
-///
-/// # Arguments
-///
-/// * num - The float value
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-#[deprecated(since = "1.0.0", reason = "use the ToString trait instead")]
-pub fn to_string(num: f64) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigAll, ExpNone, false);
-    r
-}
-
-/// Converts a float to a string in hexadecimal format
-///
-/// # Arguments
-///
-/// * num - The float value
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-#[deprecated(since = "1.0.0", reason = "use format! instead")]
-pub fn to_str_hex(num: f64) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 16, true, SignNeg, DigAll, ExpNone, false);
-    r
-}
-
-/// Converts a float to a string in a given radix, and a flag indicating
-/// whether it's a special value
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * radix - The base to use
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-#[deprecated(since = "1.0.0", reason = "use format! instead")]
-pub fn to_str_radix_special(num: f64, rdx: u32) -> (String, bool) {
-    strconv::float_to_str_common(num, rdx, true, SignNeg, DigAll, ExpNone, false)
-}
-
-/// Converts a float to a string with exactly the number of
-/// provided significant digits
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of significant digits
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_exact(num: f64, dig: usize) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigExact(dig), ExpNone, false);
-    r
-}
-
-/// Converts a float to a string with a maximum number of
-/// significant digits
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of significant digits
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_digits(num: f64, dig: usize) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigMax(dig), ExpNone, false);
-    r
-}
-
-/// Converts a float to a string using the exponential notation with exactly the number of
-/// provided digits after the decimal point in the significand
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of digits after the decimal point
-/// * upper - Use `E` instead of `e` for the exponent sign
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_exp_exact(num: f64, dig: usize, upper: bool) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigExact(dig), ExpDec, upper);
-    r
-}
-
-/// Converts a float to a string using the exponential notation with the maximum number of
-/// digits after the decimal point in the significand
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of digits after the decimal point
-/// * upper - Use `E` instead of `e` for the exponent sign
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_exp_digits(num: f64, dig: usize, upper: bool) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigMax(dig), ExpDec, upper);
-    r
-}
-
 #[cfg(test)]
 mod tests {
+    use f64;
     use f64::*;
     use num::*;
     use num::FpCategory as Fp;
@@ -1461,7 +1055,7 @@ fn test_max_nan() {
 
     #[test]
     fn test_nan() {
-        let nan: f64 = Float::nan();
+        let nan: f64 = NAN;
         assert!(nan.is_nan());
         assert!(!nan.is_infinite());
         assert!(!nan.is_finite());
@@ -1473,7 +1067,7 @@ fn test_nan() {
 
     #[test]
     fn test_infinity() {
-        let inf: f64 = Float::infinity();
+        let inf: f64 = INFINITY;
         assert!(inf.is_infinite());
         assert!(!inf.is_finite());
         assert!(inf.is_sign_positive());
@@ -1485,7 +1079,7 @@ fn test_infinity() {
 
     #[test]
     fn test_neg_infinity() {
-        let neg_inf: f64 = Float::neg_infinity();
+        let neg_inf: f64 = NEG_INFINITY;
         assert!(neg_inf.is_infinite());
         assert!(!neg_inf.is_finite());
         assert!(!neg_inf.is_sign_positive());
@@ -1497,7 +1091,7 @@ fn test_neg_infinity() {
 
     #[test]
     fn test_zero() {
-        let zero: f64 = Float::zero();
+        let zero: f64 = 0.0f64;
         assert_eq!(0.0, zero);
         assert!(!zero.is_infinite());
         assert!(zero.is_finite());
@@ -1510,7 +1104,7 @@ fn test_zero() {
 
     #[test]
     fn test_neg_zero() {
-        let neg_zero: f64 = Float::neg_zero();
+        let neg_zero: f64 = -0.0;
         assert_eq!(0.0, neg_zero);
         assert!(!neg_zero.is_infinite());
         assert!(neg_zero.is_finite());
@@ -1523,7 +1117,7 @@ fn test_neg_zero() {
 
     #[test]
     fn test_one() {
-        let one: f64 = Float::one();
+        let one: f64 = 1.0f64;
         assert_eq!(1.0, one);
         assert!(!one.is_infinite());
         assert!(one.is_finite());
@@ -1536,9 +1130,9 @@ fn test_one() {
 
     #[test]
     fn test_is_nan() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = NAN;
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
         assert!(nan.is_nan());
         assert!(!0.0f64.is_nan());
         assert!(!5.3f64.is_nan());
@@ -1549,9 +1143,9 @@ fn test_is_nan() {
 
     #[test]
     fn test_is_infinite() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = NAN;
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
         assert!(!nan.is_infinite());
         assert!(inf.is_infinite());
         assert!(neg_inf.is_infinite());
@@ -1562,9 +1156,9 @@ fn test_is_infinite() {
 
     #[test]
     fn test_is_finite() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = NAN;
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
         assert!(!nan.is_finite());
         assert!(!inf.is_finite());
         assert!(!neg_inf.is_finite());
@@ -1575,11 +1169,11 @@ fn test_is_finite() {
 
     #[test]
     fn test_is_normal() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let zero: f64 = Float::zero();
-        let neg_zero: f64 = Float::neg_zero();
+        let nan: f64 = NAN;
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
+        let zero: f64 = 0.0f64;
+        let neg_zero: f64 = -0.0;
         assert!(!nan.is_normal());
         assert!(!inf.is_normal());
         assert!(!neg_inf.is_normal());
@@ -1592,11 +1186,11 @@ fn test_is_normal() {
 
     #[test]
     fn test_classify() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let zero: f64 = Float::zero();
-        let neg_zero: f64 = Float::neg_zero();
+        let nan: f64 = NAN;
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
+        let zero: f64 = 0.0f64;
+        let neg_zero: f64 = -0.0;
         assert_eq!(nan.classify(), Fp::Nan);
         assert_eq!(inf.classify(), Fp::Infinite);
         assert_eq!(neg_inf.classify(), Fp::Infinite);
@@ -1738,9 +1332,9 @@ fn test_is_sign_negative() {
 
     #[test]
     fn test_mul_add() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = NAN;
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
         assert_approx_eq!(12.3f64.mul_add(4.5, 6.7), 62.05);
         assert_approx_eq!((-12.3f64).mul_add(-4.5, -6.7), 48.65);
         assert_approx_eq!(0.0f64.mul_add(8.9, 1.2), 1.2);
@@ -1754,9 +1348,9 @@ fn test_mul_add() {
 
     #[test]
     fn test_recip() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = NAN;
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
         assert_eq!(1.0f64.recip(), 1.0);
         assert_eq!(2.0f64.recip(), 0.5);
         assert_eq!((-0.4f64).recip(), -2.5);
@@ -1768,9 +1362,9 @@ fn test_recip() {
 
     #[test]
     fn test_powi() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = NAN;
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
         assert_eq!(1.0f64.powi(1), 1.0);
         assert_approx_eq!((-3.1f64).powi(2), 9.61);
         assert_approx_eq!(5.9f64.powi(-2), 0.028727);
@@ -1782,9 +1376,9 @@ fn test_powi() {
 
     #[test]
     fn test_powf() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = NAN;
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
         assert_eq!(1.0f64.powf(1.0), 1.0);
         assert_approx_eq!(3.4f64.powf(4.5), 246.408183);
         assert_approx_eq!(2.7f64.powf(-3.2), 0.041652);
@@ -1807,30 +1401,15 @@ fn test_sqrt_domain() {
         assert_eq!(INFINITY.sqrt(), INFINITY);
     }
 
-    #[test]
-    fn test_rsqrt() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        assert!(nan.rsqrt().is_nan());
-        assert_eq!(inf.rsqrt(), 0.0);
-        assert!(neg_inf.rsqrt().is_nan());
-        assert!((-1.0f64).rsqrt().is_nan());
-        assert_eq!((-0.0f64).rsqrt(), neg_inf);
-        assert_eq!(0.0f64.rsqrt(), inf);
-        assert_eq!(1.0f64.rsqrt(), 1.0);
-        assert_eq!(4.0f64.rsqrt(), 0.5);
-    }
-
     #[test]
     fn test_exp() {
         assert_eq!(1.0, 0.0f64.exp());
         assert_approx_eq!(2.718282, 1.0f64.exp());
         assert_approx_eq!(148.413159, 5.0f64.exp());
 
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let nan: f64 = Float::nan();
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
+        let nan: f64 = NAN;
         assert_eq!(inf, inf.exp());
         assert_eq!(0.0, neg_inf.exp());
         assert!(nan.exp().is_nan());
@@ -1841,9 +1420,9 @@ fn test_exp2() {
         assert_eq!(32.0, 5.0f64.exp2());
         assert_eq!(1.0, 0.0f64.exp2());
 
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let nan: f64 = Float::nan();
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
+        let nan: f64 = NAN;
         assert_eq!(inf, inf.exp2());
         assert_eq!(0.0, neg_inf.exp2());
         assert!(nan.exp2().is_nan());
@@ -1851,9 +1430,9 @@ fn test_exp2() {
 
     #[test]
     fn test_ln() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = NAN;
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
         assert_approx_eq!(1.0f64.exp().ln(), 1.0);
         assert!(nan.ln().is_nan());
         assert_eq!(inf.ln(), inf);
@@ -1866,12 +1445,12 @@ fn test_ln() {
 
     #[test]
     fn test_log() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = NAN;
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
         assert_eq!(10.0f64.log(10.0), 1.0);
         assert_approx_eq!(2.3f64.log(3.5), 0.664858);
-        assert_eq!(1.0f64.exp().log(1.0.exp()), 1.0);
+        assert_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0);
         assert!(1.0f64.log(1.0).is_nan());
         assert!(1.0f64.log(-13.9).is_nan());
         assert!(nan.log(2.3).is_nan());
@@ -1884,9 +1463,9 @@ fn test_log() {
 
     #[test]
     fn test_log2() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = NAN;
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
         assert_approx_eq!(10.0f64.log2(), 3.321928);
         assert_approx_eq!(2.3f64.log2(), 1.201634);
         assert_approx_eq!(1.0f64.exp().log2(), 1.442695);
@@ -1900,9 +1479,9 @@ fn test_log2() {
 
     #[test]
     fn test_log10() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = NAN;
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
         assert_eq!(10.0f64.log10(), 1.0);
         assert_approx_eq!(2.3f64.log10(), 0.361728);
         assert_approx_eq!(1.0f64.exp().log10(), 0.434294);
@@ -1918,9 +1497,9 @@ fn test_log10() {
     #[test]
     fn test_to_degrees() {
         let pi: f64 = consts::PI;
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = NAN;
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
         assert_eq!(0.0f64.to_degrees(), 0.0);
         assert_approx_eq!((-5.8f64).to_degrees(), -332.315521);
         assert_eq!(pi.to_degrees(), 180.0);
@@ -1932,9 +1511,9 @@ fn test_to_degrees() {
     #[test]
     fn test_to_radians() {
         let pi: f64 = consts::PI;
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = NAN;
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
         assert_eq!(0.0f64.to_radians(), 0.0);
         assert_approx_eq!(154.6f64.to_radians(), 2.698279);
         assert_approx_eq!((-332.31f64).to_radians(), -5.799903);
@@ -1948,40 +1527,40 @@ fn test_to_radians() {
     fn test_ldexp() {
         // We have to use from_str until base-2 exponents
         // are supported in floating-point literals
-        let f1: f64 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
-        let f2: f64 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
-        let f3: f64 = FromStrRadix::from_str_radix("1.Cp-12", 16).unwrap();
-        assert_eq!(1f64.ldexp(-123), f1);
-        assert_eq!(1f64.ldexp(-111), f2);
-        assert_eq!(Float::ldexp(1.75f64, -12), f3);
+        let f1: f64 = f64::from_str_radix("1p-123", 16).unwrap();
+        let f2: f64 = f64::from_str_radix("1p-111", 16).unwrap();
+        let f3: f64 = f64::from_str_radix("1.Cp-12", 16).unwrap();
+        assert_eq!(f64::ldexp(1f64, -123), f1);
+        assert_eq!(f64::ldexp(1f64, -111), f2);
+        assert_eq!(f64::ldexp(1.75f64, -12), f3);
 
-        assert_eq!(Float::ldexp(0f64, -123), 0f64);
-        assert_eq!(Float::ldexp(-0f64, -123), -0f64);
+        assert_eq!(f64::ldexp(0f64, -123), 0f64);
+        assert_eq!(f64::ldexp(-0f64, -123), -0f64);
 
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let nan: f64 = Float::nan();
-        assert_eq!(Float::ldexp(inf, -123), inf);
-        assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
-        assert!(Float::ldexp(nan, -123).is_nan());
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
+        let nan: f64 = NAN;
+        assert_eq!(f64::ldexp(inf, -123), inf);
+        assert_eq!(f64::ldexp(neg_inf, -123), neg_inf);
+        assert!(f64::ldexp(nan, -123).is_nan());
     }
 
     #[test]
     fn test_frexp() {
         // We have to use from_str until base-2 exponents
         // are supported in floating-point literals
-        let f1: f64 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
-        let f2: f64 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
-        let f3: f64 = FromStrRadix::from_str_radix("1.Cp-123", 16).unwrap();
+        let f1: f64 = f64::from_str_radix("1p-123", 16).unwrap();
+        let f2: f64 = f64::from_str_radix("1p-111", 16).unwrap();
+        let f3: f64 = f64::from_str_radix("1.Cp-123", 16).unwrap();
         let (x1, exp1) = f1.frexp();
         let (x2, exp2) = f2.frexp();
         let (x3, exp3) = f3.frexp();
         assert_eq!((x1, exp1), (0.5f64, -122));
         assert_eq!((x2, exp2), (0.5f64, -110));
         assert_eq!((x3, exp3), (0.875f64, -122));
-        assert_eq!(Float::ldexp(x1, exp1), f1);
-        assert_eq!(Float::ldexp(x2, exp2), f2);
-        assert_eq!(Float::ldexp(x3, exp3), f3);
+        assert_eq!(f64::ldexp(x1, exp1), f1);
+        assert_eq!(f64::ldexp(x2, exp2), f2);
+        assert_eq!(f64::ldexp(x3, exp3), f3);
 
         assert_eq!(0f64.frexp(), (0f64, 0));
         assert_eq!((-0f64).frexp(), (-0f64, 0));
@@ -1989,9 +1568,9 @@ fn test_frexp() {
 
     #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
     fn test_frexp_nowin() {
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let nan: f64 = Float::nan();
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
+        let nan: f64 = NAN;
         assert_eq!(match inf.frexp() { (x, _) => x }, inf);
         assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
         assert!(match nan.frexp() { (x, _) => x.is_nan() })
@@ -2020,9 +1599,9 @@ fn test_asinh() {
         assert_eq!(0.0f64.asinh(), 0.0f64);
         assert_eq!((-0.0f64).asinh(), -0.0f64);
 
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let nan: f64 = Float::nan();
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
+        let nan: f64 = NAN;
         assert_eq!(inf.asinh(), inf);
         assert_eq!(neg_inf.asinh(), neg_inf);
         assert!(nan.asinh().is_nan());
@@ -2035,9 +1614,9 @@ fn test_acosh() {
         assert_eq!(1.0f64.acosh(), 0.0f64);
         assert!(0.999f64.acosh().is_nan());
 
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let nan: f64 = Float::nan();
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
+        let nan: f64 = NAN;
         assert_eq!(inf.acosh(), inf);
         assert!(neg_inf.acosh().is_nan());
         assert!(nan.acosh().is_nan());
@@ -2050,9 +1629,9 @@ fn test_atanh() {
         assert_eq!(0.0f64.atanh(), 0.0f64);
         assert_eq!((-0.0f64).atanh(), -0.0f64);
 
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let nan: f64 = Float::nan();
+        let inf: f64 = INFINITY;
+        let neg_inf: f64 = NEG_INFINITY;
+        let nan: f64 = NAN;
         assert_eq!(1.0f64.atanh(), inf);
         assert_eq!((-1.0f64).atanh(), neg_inf);
         assert!(2f64.atanh().atanh().is_nan());
@@ -2076,9 +1655,9 @@ fn test_real_consts() {
         let frac_pi_8: f64 = consts::FRAC_PI_8;
         let frac_1_pi: f64 = consts::FRAC_1_PI;
         let frac_2_pi: f64 = consts::FRAC_2_PI;
-        let frac_2_sqrtpi: f64 = consts::FRAC_2_SQRTPI;
-        let sqrt2: f64 = consts::SQRT2;
-        let frac_1_sqrt2: f64 = consts::FRAC_1_SQRT2;
+        let frac_2_sqrtpi: f64 = consts::FRAC_2_SQRT_PI;
+        let sqrt2: f64 = consts::SQRT_2;
+        let frac_1_sqrt2: f64 = consts::FRAC_1_SQRT_2;
         let e: f64 = consts::E;
         let log2_e: f64 = consts::LOG2_E;
         let log10_e: f64 = consts::LOG10_E;
index e0b9c720dbbed82b9be59c9e95ffd81df227ee33..cd26be013c41eaa814ec13e728f33290146b4cf1 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
-#![allow(deprecated)]
 
-#[cfg(test)] use fmt::Debug;
-use ops::{Add, Sub, Mul, Div, Rem, Neg};
+use fmt;
+use core::num;
 
-use marker::Copy;
-use clone::Clone;
-use cmp::{PartialOrd, PartialEq};
-
-pub use core::num::{Int, SignedInt, Zero, One};
-pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive};
-pub use core::num::{from_int, from_i8, from_i16, from_i32, from_i64};
-pub use core::num::{from_uint, from_u8, from_u16, from_u32, from_u64};
-pub use core::num::{from_f32, from_f64};
-pub use core::num::{FromStrRadix, from_str_radix};
-pub use core::num::{FpCategory, ParseIntError, ParseFloatError};
+pub use core::num::{Zero, One};
+pub use core::num::{FpCategory, ParseIntError};
 pub use core::num::{wrapping, Wrapping};
 
-use option::Option;
-
-#[unstable(feature = "std_misc", reason = "likely to be removed")]
-pub mod strconv;
-
-/// Mathematical operations on primitive floating point numbers.
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0",
-             reason = "replaced by inherent methods; use rust-lang/num for generics")]
-pub trait Float
-    : Copy + Clone
-    + NumCast
-    + PartialOrd
-    + PartialEq
-    + Neg<Output=Self>
-    + Add<Output=Self>
-    + Sub<Output=Self>
-    + Mul<Output=Self>
-    + Div<Output=Self>
-    + Rem<Output=Self>
-{
-    // inlined methods from `num::Float`
-    /// Returns the `NaN` value.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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 `0.0`.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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`.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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 `1.0`.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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
-
-    /// 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>) -> usize;
-    /// Deprecated: use `std::f32::DIGITS` or `std::f64::DIGITS` instead.
-    #[unstable(feature = "std_misc")]
-    #[deprecated(since = "1.0.0",
-                 reason = "use `std::f32::DIGITS` or `std::f64::DIGITS` as appropriate")]
-    fn digits(unused_self: Option<Self>) -> usize;
-    /// 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;
-    /// 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>) -> isize;
-    /// Deprecated: use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` instead.
-    #[unstable(feature = "std_misc")]
-    #[deprecated(since = "1.0.0",
-                 reason = "use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` as appropriate")]
-    fn max_exp(unused_self: Option<Self>) -> isize;
-    /// Deprecated: use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` instead.
-    #[unstable(feature = "std_misc")]
-    #[deprecated(since = "1.0.0",
-                 reason = "use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` as appropriate")]
-    fn min_10_exp(unused_self: Option<Self>) -> isize;
-    /// Deprecated: use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` instead.
-    #[unstable(feature = "std_misc")]
-    #[deprecated(since = "1.0.0",
-                 reason = "use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` as appropriate")]
-    fn max_10_exp(unused_self: Option<Self>) -> isize;
-
-    /// Returns the smallest finite value that this type can represent.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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;
-    /// Returns the smallest normalized positive number that this type can represent.
-    #[unstable(feature = "std_misc",
-               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.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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
-    /// false otherwise.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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`.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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 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 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, base 2 exponent, and sign as integers, respectively.
-    /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`.
-    /// The floating point encoding is documented in the [Reference][floating-point].
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// use std::num::Float;
-    ///
-    /// let num = 2.0f32;
-    ///
-    /// // (8388608, -22, 1)
-    /// let (mantissa, exponent, sign) = num.integer_decode();
-    /// let sign_f = sign as f32;
-    /// let mantissa_f = mantissa as f32;
-    /// let exponent_f = num.powf(exponent as f32);
-    ///
-    /// // 1 * 8388608 * 2^(-22) == 2
-    /// let abs_difference = (sign_f * mantissa_f * exponent_f - num).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    /// [floating-point]: ../../../../../reference.html#machine-types
-    #[unstable(feature = "std_misc", reason = "signature is undecided")]
-    fn integer_decode(self) -> (u64, i16, i8);
-
-    /// 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;
-    /// 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;
-    /// 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;
-    /// Returns 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;
-    /// 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`.
-    ///
-    /// - `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.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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;
-    /// Takes the reciprocal (inverse) of a number, `1/x`.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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;
-
-    /// Raises 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;
-    /// Raises 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;
-    /// Takes the square root of a number.
-    ///
-    /// Returns NaN if `self` is a negative number.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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;
-
-    /// Takes the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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^(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;
-
-    /// Converts 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;
-    /// Converts degrees to radians.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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 of `x*2^exp`.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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(self, exp: isize) -> Self;
-    /// Breaks the number into a normalized fraction and a base-2 exponent,
-    /// satisfying:
-    ///
-    ///  * `self = x * 2^exp`
-    ///  * `0.5 <= abs(x) < 1.0`
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// use std::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, isize);
-    /// Returns the next representable floating-point value in the direction of
-    /// `other`.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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.
-    ///
-    /// * If `self <= other`: `0:0`
-    /// * Else: `self - other`
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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;
-    /// Takes the cubic root of a number.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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;
-    /// Calculates the length of the hypotenuse of a right-angle triangle given
-    /// legs of length `x` and `y`.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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 `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 `e^(self) - 1` in a way that is accurate even if the
-    /// number is close to zero.
-    ///
-    /// ```
-    /// # #![feature(std_misc)]
-    /// 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 `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;
-}
+#[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem};
+#[cfg(test)] use cmp::PartialEq;
+#[cfg(test)] use marker::Copy;
 
 /// Helper function for testing numeric operations
 #[cfg(test)]
 pub fn test_num<T>(ten: T, two: T) where
-    T: PartialEq + NumCast
+    T: PartialEq
      + Add<Output=T> + Sub<Output=T>
      + Mul<Output=T> + Div<Output=T>
-     + Rem<Output=T> + Debug
+     + Rem<Output=T> + fmt::Debug
      + Copy
 {
-    assert_eq!(ten.add(two),  cast(12).unwrap());
-    assert_eq!(ten.sub(two),  cast(8).unwrap());
-    assert_eq!(ten.mul(two),  cast(20).unwrap());
-    assert_eq!(ten.div(two),  cast(5).unwrap());
-    assert_eq!(ten.rem(two),  cast(0).unwrap());
-
     assert_eq!(ten.add(two),  ten + two);
     assert_eq!(ten.sub(two),  ten - two);
     assert_eq!(ten.mul(two),  ten * two);
@@ -1133,6 +43,31 @@ pub fn test_num<T>(ten: T, two: T) where
     assert_eq!(ten.rem(two),  ten % two);
 }
 
+/// An error which can be returned when parsing a float.
+#[derive(Debug, Clone, PartialEq)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ParseFloatError { inner: num::ParseFloatError }
+
+impl ::sys_common::FromInner<num::ParseFloatError> for ParseFloatError {
+    fn from_inner(inner: num::ParseFloatError) -> ParseFloatError {
+        ParseFloatError { inner: inner }
+    }
+}
+
+impl ParseFloatError {
+    #[unstable(feature = "core", reason = "available through Error trait")]
+    pub fn description(&self) -> &str {
+        self.inner.description()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for ParseFloatError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.description().fmt(f)
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use core::prelude::*;
@@ -1148,432 +83,7 @@ mod tests {
     use u64;
     use usize;
     use string::ToString;
-
-    macro_rules! test_cast_20 {
-        ($_20:expr) => ({
-            let _20 = $_20;
-
-            assert_eq!(20usize, _20.to_uint().unwrap());
-            assert_eq!(20u8,    _20.to_u8().unwrap());
-            assert_eq!(20u16,   _20.to_u16().unwrap());
-            assert_eq!(20u32,   _20.to_u32().unwrap());
-            assert_eq!(20u64,   _20.to_u64().unwrap());
-            assert_eq!(20,      _20.to_int().unwrap());
-            assert_eq!(20i8,    _20.to_i8().unwrap());
-            assert_eq!(20i16,   _20.to_i16().unwrap());
-            assert_eq!(20i32,   _20.to_i32().unwrap());
-            assert_eq!(20i64,   _20.to_i64().unwrap());
-            assert_eq!(20f32,   _20.to_f32().unwrap());
-            assert_eq!(20f64,   _20.to_f64().unwrap());
-
-            assert_eq!(_20, NumCast::from(20usize).unwrap());
-            assert_eq!(_20, NumCast::from(20u8).unwrap());
-            assert_eq!(_20, NumCast::from(20u16).unwrap());
-            assert_eq!(_20, NumCast::from(20u32).unwrap());
-            assert_eq!(_20, NumCast::from(20u64).unwrap());
-            assert_eq!(_20, NumCast::from(20).unwrap());
-            assert_eq!(_20, NumCast::from(20i8).unwrap());
-            assert_eq!(_20, NumCast::from(20i16).unwrap());
-            assert_eq!(_20, NumCast::from(20i32).unwrap());
-            assert_eq!(_20, NumCast::from(20i64).unwrap());
-            assert_eq!(_20, NumCast::from(20f32).unwrap());
-            assert_eq!(_20, NumCast::from(20f64).unwrap());
-
-            assert_eq!(_20, cast(20usize).unwrap());
-            assert_eq!(_20, cast(20u8).unwrap());
-            assert_eq!(_20, cast(20u16).unwrap());
-            assert_eq!(_20, cast(20u32).unwrap());
-            assert_eq!(_20, cast(20u64).unwrap());
-            assert_eq!(_20, cast(20).unwrap());
-            assert_eq!(_20, cast(20i8).unwrap());
-            assert_eq!(_20, cast(20i16).unwrap());
-            assert_eq!(_20, cast(20i32).unwrap());
-            assert_eq!(_20, cast(20i64).unwrap());
-            assert_eq!(_20, cast(20f32).unwrap());
-            assert_eq!(_20, cast(20f64).unwrap());
-        })
-    }
-
-    #[test] fn test_u8_cast()    { test_cast_20!(20u8)    }
-    #[test] fn test_u16_cast()   { test_cast_20!(20u16)   }
-    #[test] fn test_u32_cast()   { test_cast_20!(20u32)   }
-    #[test] fn test_u64_cast()   { test_cast_20!(20u64)   }
-    #[test] fn test_uint_cast()  { test_cast_20!(20usize) }
-    #[test] fn test_i8_cast()    { test_cast_20!(20i8)    }
-    #[test] fn test_i16_cast()   { test_cast_20!(20i16)   }
-    #[test] fn test_i32_cast()   { test_cast_20!(20i32)   }
-    #[test] fn test_i64_cast()   { test_cast_20!(20i64)   }
-    #[test] fn test_int_cast()   { test_cast_20!(20)      }
-    #[test] fn test_f32_cast()   { test_cast_20!(20f32)   }
-    #[test] fn test_f64_cast()   { test_cast_20!(20f64)   }
-
-    #[test]
-    fn test_cast_range_int_min() {
-        assert_eq!(isize::MIN.to_int(),  Some(isize::MIN as isize));
-        assert_eq!(isize::MIN.to_i8(),   None);
-        assert_eq!(isize::MIN.to_i16(),  None);
-        // isize::MIN.to_i32() is word-size specific
-        assert_eq!(isize::MIN.to_i64(),  Some(isize::MIN as i64));
-        assert_eq!(isize::MIN.to_uint(), None);
-        assert_eq!(isize::MIN.to_u8(),   None);
-        assert_eq!(isize::MIN.to_u16(),  None);
-        assert_eq!(isize::MIN.to_u32(),  None);
-        assert_eq!(isize::MIN.to_u64(),  None);
-
-        #[cfg(target_pointer_width = "32")]
-        fn check_word_size() {
-            assert_eq!(isize::MIN.to_i32(), Some(isize::MIN as i32));
-        }
-
-        #[cfg(target_pointer_width = "64")]
-        fn check_word_size() {
-            assert_eq!(isize::MIN.to_i32(), None);
-        }
-
-        check_word_size();
-    }
-
-    #[test]
-    fn test_cast_range_i8_min() {
-        assert_eq!(i8::MIN.to_int(),  Some(i8::MIN as isize));
-        assert_eq!(i8::MIN.to_i8(),   Some(i8::MIN as i8));
-        assert_eq!(i8::MIN.to_i16(),  Some(i8::MIN as i16));
-        assert_eq!(i8::MIN.to_i32(),  Some(i8::MIN as i32));
-        assert_eq!(i8::MIN.to_i64(),  Some(i8::MIN as i64));
-        assert_eq!(i8::MIN.to_uint(), None);
-        assert_eq!(i8::MIN.to_u8(),   None);
-        assert_eq!(i8::MIN.to_u16(),  None);
-        assert_eq!(i8::MIN.to_u32(),  None);
-        assert_eq!(i8::MIN.to_u64(),  None);
-    }
-
-    #[test]
-    fn test_cast_range_i16_min() {
-        assert_eq!(i16::MIN.to_int(),  Some(i16::MIN as isize));
-        assert_eq!(i16::MIN.to_i8(),   None);
-        assert_eq!(i16::MIN.to_i16(),  Some(i16::MIN as i16));
-        assert_eq!(i16::MIN.to_i32(),  Some(i16::MIN as i32));
-        assert_eq!(i16::MIN.to_i64(),  Some(i16::MIN as i64));
-        assert_eq!(i16::MIN.to_uint(), None);
-        assert_eq!(i16::MIN.to_u8(),   None);
-        assert_eq!(i16::MIN.to_u16(),  None);
-        assert_eq!(i16::MIN.to_u32(),  None);
-        assert_eq!(i16::MIN.to_u64(),  None);
-    }
-
-    #[test]
-    fn test_cast_range_i32_min() {
-        assert_eq!(i32::MIN.to_int(),  Some(i32::MIN as isize));
-        assert_eq!(i32::MIN.to_i8(),   None);
-        assert_eq!(i32::MIN.to_i16(),  None);
-        assert_eq!(i32::MIN.to_i32(),  Some(i32::MIN as i32));
-        assert_eq!(i32::MIN.to_i64(),  Some(i32::MIN as i64));
-        assert_eq!(i32::MIN.to_uint(), None);
-        assert_eq!(i32::MIN.to_u8(),   None);
-        assert_eq!(i32::MIN.to_u16(),  None);
-        assert_eq!(i32::MIN.to_u32(),  None);
-        assert_eq!(i32::MIN.to_u64(),  None);
-    }
-
-    #[test]
-    fn test_cast_range_i64_min() {
-        // i64::MIN.to_int() is word-size specific
-        assert_eq!(i64::MIN.to_i8(),   None);
-        assert_eq!(i64::MIN.to_i16(),  None);
-        assert_eq!(i64::MIN.to_i32(),  None);
-        assert_eq!(i64::MIN.to_i64(),  Some(i64::MIN as i64));
-        assert_eq!(i64::MIN.to_uint(), None);
-        assert_eq!(i64::MIN.to_u8(),   None);
-        assert_eq!(i64::MIN.to_u16(),  None);
-        assert_eq!(i64::MIN.to_u32(),  None);
-        assert_eq!(i64::MIN.to_u64(),  None);
-
-        #[cfg(target_pointer_width = "32")]
-        fn check_word_size() {
-            assert_eq!(i64::MIN.to_int(), None);
-        }
-
-        #[cfg(target_pointer_width = "64")]
-        fn check_word_size() {
-            assert_eq!(i64::MIN.to_int(), Some(i64::MIN as isize));
-        }
-
-        check_word_size();
-    }
-
-    #[test]
-    fn test_cast_range_int_max() {
-        assert_eq!(isize::MAX.to_int(),  Some(isize::MAX as isize));
-        assert_eq!(isize::MAX.to_i8(),   None);
-        assert_eq!(isize::MAX.to_i16(),  None);
-        // isize::MAX.to_i32() is word-size specific
-        assert_eq!(isize::MAX.to_i64(),  Some(isize::MAX as i64));
-        assert_eq!(isize::MAX.to_u8(),   None);
-        assert_eq!(isize::MAX.to_u16(),  None);
-        // isize::MAX.to_u32() is word-size specific
-        assert_eq!(isize::MAX.to_u64(),  Some(isize::MAX as u64));
-
-        #[cfg(target_pointer_width = "32")]
-        fn check_word_size() {
-            assert_eq!(isize::MAX.to_i32(), Some(isize::MAX as i32));
-            assert_eq!(isize::MAX.to_u32(), Some(isize::MAX as u32));
-        }
-
-        #[cfg(target_pointer_width = "64")]
-        fn check_word_size() {
-            assert_eq!(isize::MAX.to_i32(), None);
-            assert_eq!(isize::MAX.to_u32(), None);
-        }
-
-        check_word_size();
-    }
-
-    #[test]
-    fn test_cast_range_i8_max() {
-        assert_eq!(i8::MAX.to_int(),  Some(i8::MAX as isize));
-        assert_eq!(i8::MAX.to_i8(),   Some(i8::MAX as i8));
-        assert_eq!(i8::MAX.to_i16(),  Some(i8::MAX as i16));
-        assert_eq!(i8::MAX.to_i32(),  Some(i8::MAX as i32));
-        assert_eq!(i8::MAX.to_i64(),  Some(i8::MAX as i64));
-        assert_eq!(i8::MAX.to_uint(), Some(i8::MAX as usize));
-        assert_eq!(i8::MAX.to_u8(),   Some(i8::MAX as u8));
-        assert_eq!(i8::MAX.to_u16(),  Some(i8::MAX as u16));
-        assert_eq!(i8::MAX.to_u32(),  Some(i8::MAX as u32));
-        assert_eq!(i8::MAX.to_u64(),  Some(i8::MAX as u64));
-    }
-
-    #[test]
-    fn test_cast_range_i16_max() {
-        assert_eq!(i16::MAX.to_int(),  Some(i16::MAX as isize));
-        assert_eq!(i16::MAX.to_i8(),   None);
-        assert_eq!(i16::MAX.to_i16(),  Some(i16::MAX as i16));
-        assert_eq!(i16::MAX.to_i32(),  Some(i16::MAX as i32));
-        assert_eq!(i16::MAX.to_i64(),  Some(i16::MAX as i64));
-        assert_eq!(i16::MAX.to_uint(), Some(i16::MAX as usize));
-        assert_eq!(i16::MAX.to_u8(),   None);
-        assert_eq!(i16::MAX.to_u16(),  Some(i16::MAX as u16));
-        assert_eq!(i16::MAX.to_u32(),  Some(i16::MAX as u32));
-        assert_eq!(i16::MAX.to_u64(),  Some(i16::MAX as u64));
-    }
-
-    #[test]
-    fn test_cast_range_i32_max() {
-        assert_eq!(i32::MAX.to_int(),  Some(i32::MAX as isize));
-        assert_eq!(i32::MAX.to_i8(),   None);
-        assert_eq!(i32::MAX.to_i16(),  None);
-        assert_eq!(i32::MAX.to_i32(),  Some(i32::MAX as i32));
-        assert_eq!(i32::MAX.to_i64(),  Some(i32::MAX as i64));
-        assert_eq!(i32::MAX.to_uint(), Some(i32::MAX as usize));
-        assert_eq!(i32::MAX.to_u8(),   None);
-        assert_eq!(i32::MAX.to_u16(),  None);
-        assert_eq!(i32::MAX.to_u32(),  Some(i32::MAX as u32));
-        assert_eq!(i32::MAX.to_u64(),  Some(i32::MAX as u64));
-    }
-
-    #[test]
-    fn test_cast_range_i64_max() {
-        // i64::MAX.to_int() is word-size specific
-        assert_eq!(i64::MAX.to_i8(),   None);
-        assert_eq!(i64::MAX.to_i16(),  None);
-        assert_eq!(i64::MAX.to_i32(),  None);
-        assert_eq!(i64::MAX.to_i64(),  Some(i64::MAX as i64));
-        // i64::MAX.to_uint() is word-size specific
-        assert_eq!(i64::MAX.to_u8(),   None);
-        assert_eq!(i64::MAX.to_u16(),  None);
-        assert_eq!(i64::MAX.to_u32(),  None);
-        assert_eq!(i64::MAX.to_u64(),  Some(i64::MAX as u64));
-
-        #[cfg(target_pointer_width = "32")]
-        fn check_word_size() {
-            assert_eq!(i64::MAX.to_int(),  None);
-            assert_eq!(i64::MAX.to_uint(), None);
-        }
-
-        #[cfg(target_pointer_width = "64")]
-        fn check_word_size() {
-            assert_eq!(i64::MAX.to_int(),  Some(i64::MAX as isize));
-            assert_eq!(i64::MAX.to_uint(), Some(i64::MAX as usize));
-        }
-
-        check_word_size();
-    }
-
-    #[test]
-    fn test_cast_range_uint_min() {
-        assert_eq!(usize::MIN.to_int(),  Some(usize::MIN as isize));
-        assert_eq!(usize::MIN.to_i8(),   Some(usize::MIN as i8));
-        assert_eq!(usize::MIN.to_i16(),  Some(usize::MIN as i16));
-        assert_eq!(usize::MIN.to_i32(),  Some(usize::MIN as i32));
-        assert_eq!(usize::MIN.to_i64(),  Some(usize::MIN as i64));
-        assert_eq!(usize::MIN.to_uint(), Some(usize::MIN as usize));
-        assert_eq!(usize::MIN.to_u8(),   Some(usize::MIN as u8));
-        assert_eq!(usize::MIN.to_u16(),  Some(usize::MIN as u16));
-        assert_eq!(usize::MIN.to_u32(),  Some(usize::MIN as u32));
-        assert_eq!(usize::MIN.to_u64(),  Some(usize::MIN as u64));
-    }
-
-    #[test]
-    fn test_cast_range_u8_min() {
-        assert_eq!(u8::MIN.to_int(),  Some(u8::MIN as isize));
-        assert_eq!(u8::MIN.to_i8(),   Some(u8::MIN as i8));
-        assert_eq!(u8::MIN.to_i16(),  Some(u8::MIN as i16));
-        assert_eq!(u8::MIN.to_i32(),  Some(u8::MIN as i32));
-        assert_eq!(u8::MIN.to_i64(),  Some(u8::MIN as i64));
-        assert_eq!(u8::MIN.to_uint(), Some(u8::MIN as usize));
-        assert_eq!(u8::MIN.to_u8(),   Some(u8::MIN as u8));
-        assert_eq!(u8::MIN.to_u16(),  Some(u8::MIN as u16));
-        assert_eq!(u8::MIN.to_u32(),  Some(u8::MIN as u32));
-        assert_eq!(u8::MIN.to_u64(),  Some(u8::MIN as u64));
-    }
-
-    #[test]
-    fn test_cast_range_u16_min() {
-        assert_eq!(u16::MIN.to_int(),  Some(u16::MIN as isize));
-        assert_eq!(u16::MIN.to_i8(),   Some(u16::MIN as i8));
-        assert_eq!(u16::MIN.to_i16(),  Some(u16::MIN as i16));
-        assert_eq!(u16::MIN.to_i32(),  Some(u16::MIN as i32));
-        assert_eq!(u16::MIN.to_i64(),  Some(u16::MIN as i64));
-        assert_eq!(u16::MIN.to_uint(), Some(u16::MIN as usize));
-        assert_eq!(u16::MIN.to_u8(),   Some(u16::MIN as u8));
-        assert_eq!(u16::MIN.to_u16(),  Some(u16::MIN as u16));
-        assert_eq!(u16::MIN.to_u32(),  Some(u16::MIN as u32));
-        assert_eq!(u16::MIN.to_u64(),  Some(u16::MIN as u64));
-    }
-
-    #[test]
-    fn test_cast_range_u32_min() {
-        assert_eq!(u32::MIN.to_int(),  Some(u32::MIN as isize));
-        assert_eq!(u32::MIN.to_i8(),   Some(u32::MIN as i8));
-        assert_eq!(u32::MIN.to_i16(),  Some(u32::MIN as i16));
-        assert_eq!(u32::MIN.to_i32(),  Some(u32::MIN as i32));
-        assert_eq!(u32::MIN.to_i64(),  Some(u32::MIN as i64));
-        assert_eq!(u32::MIN.to_uint(), Some(u32::MIN as usize));
-        assert_eq!(u32::MIN.to_u8(),   Some(u32::MIN as u8));
-        assert_eq!(u32::MIN.to_u16(),  Some(u32::MIN as u16));
-        assert_eq!(u32::MIN.to_u32(),  Some(u32::MIN as u32));
-        assert_eq!(u32::MIN.to_u64(),  Some(u32::MIN as u64));
-    }
-
-    #[test]
-    fn test_cast_range_u64_min() {
-        assert_eq!(u64::MIN.to_int(),  Some(u64::MIN as isize));
-        assert_eq!(u64::MIN.to_i8(),   Some(u64::MIN as i8));
-        assert_eq!(u64::MIN.to_i16(),  Some(u64::MIN as i16));
-        assert_eq!(u64::MIN.to_i32(),  Some(u64::MIN as i32));
-        assert_eq!(u64::MIN.to_i64(),  Some(u64::MIN as i64));
-        assert_eq!(u64::MIN.to_uint(), Some(u64::MIN as usize));
-        assert_eq!(u64::MIN.to_u8(),   Some(u64::MIN as u8));
-        assert_eq!(u64::MIN.to_u16(),  Some(u64::MIN as u16));
-        assert_eq!(u64::MIN.to_u32(),  Some(u64::MIN as u32));
-        assert_eq!(u64::MIN.to_u64(),  Some(u64::MIN as u64));
-    }
-
-    #[test]
-    fn test_cast_range_uint_max() {
-        assert_eq!(usize::MAX.to_int(),  None);
-        assert_eq!(usize::MAX.to_i8(),   None);
-        assert_eq!(usize::MAX.to_i16(),  None);
-        assert_eq!(usize::MAX.to_i32(),  None);
-        // usize::MAX.to_i64() is word-size specific
-        assert_eq!(usize::MAX.to_u8(),   None);
-        assert_eq!(usize::MAX.to_u16(),  None);
-        // usize::MAX.to_u32() is word-size specific
-        assert_eq!(usize::MAX.to_u64(),  Some(usize::MAX as u64));
-
-        #[cfg(target_pointer_width = "32")]
-        fn check_word_size() {
-            assert_eq!(usize::MAX.to_u32(), Some(usize::MAX as u32));
-            assert_eq!(usize::MAX.to_i64(), Some(usize::MAX as i64));
-        }
-
-        #[cfg(target_pointer_width = "64")]
-        fn check_word_size() {
-            assert_eq!(usize::MAX.to_u32(), None);
-            assert_eq!(usize::MAX.to_i64(), None);
-        }
-
-        check_word_size();
-    }
-
-    #[test]
-    fn test_cast_range_u8_max() {
-        assert_eq!(u8::MAX.to_int(),  Some(u8::MAX as isize));
-        assert_eq!(u8::MAX.to_i8(),   None);
-        assert_eq!(u8::MAX.to_i16(),  Some(u8::MAX as i16));
-        assert_eq!(u8::MAX.to_i32(),  Some(u8::MAX as i32));
-        assert_eq!(u8::MAX.to_i64(),  Some(u8::MAX as i64));
-        assert_eq!(u8::MAX.to_uint(), Some(u8::MAX as usize));
-        assert_eq!(u8::MAX.to_u8(),   Some(u8::MAX as u8));
-        assert_eq!(u8::MAX.to_u16(),  Some(u8::MAX as u16));
-        assert_eq!(u8::MAX.to_u32(),  Some(u8::MAX as u32));
-        assert_eq!(u8::MAX.to_u64(),  Some(u8::MAX as u64));
-    }
-
-    #[test]
-    fn test_cast_range_u16_max() {
-        assert_eq!(u16::MAX.to_int(),  Some(u16::MAX as isize));
-        assert_eq!(u16::MAX.to_i8(),   None);
-        assert_eq!(u16::MAX.to_i16(),  None);
-        assert_eq!(u16::MAX.to_i32(),  Some(u16::MAX as i32));
-        assert_eq!(u16::MAX.to_i64(),  Some(u16::MAX as i64));
-        assert_eq!(u16::MAX.to_uint(), Some(u16::MAX as usize));
-        assert_eq!(u16::MAX.to_u8(),   None);
-        assert_eq!(u16::MAX.to_u16(),  Some(u16::MAX as u16));
-        assert_eq!(u16::MAX.to_u32(),  Some(u16::MAX as u32));
-        assert_eq!(u16::MAX.to_u64(),  Some(u16::MAX as u64));
-    }
-
-    #[test]
-    fn test_cast_range_u32_max() {
-        // u32::MAX.to_int() is word-size specific
-        assert_eq!(u32::MAX.to_i8(),   None);
-        assert_eq!(u32::MAX.to_i16(),  None);
-        assert_eq!(u32::MAX.to_i32(),  None);
-        assert_eq!(u32::MAX.to_i64(),  Some(u32::MAX as i64));
-        assert_eq!(u32::MAX.to_uint(), Some(u32::MAX as usize));
-        assert_eq!(u32::MAX.to_u8(),   None);
-        assert_eq!(u32::MAX.to_u16(),  None);
-        assert_eq!(u32::MAX.to_u32(),  Some(u32::MAX as u32));
-        assert_eq!(u32::MAX.to_u64(),  Some(u32::MAX as u64));
-
-        #[cfg(target_pointer_width = "32")]
-        fn check_word_size() {
-            assert_eq!(u32::MAX.to_int(),  None);
-        }
-
-        #[cfg(target_pointer_width = "64")]
-        fn check_word_size() {
-            assert_eq!(u32::MAX.to_int(),  Some(u32::MAX as isize));
-        }
-
-        check_word_size();
-    }
-
-    #[test]
-    fn test_cast_range_u64_max() {
-        assert_eq!(u64::MAX.to_int(),  None);
-        assert_eq!(u64::MAX.to_i8(),   None);
-        assert_eq!(u64::MAX.to_i16(),  None);
-        assert_eq!(u64::MAX.to_i32(),  None);
-        assert_eq!(u64::MAX.to_i64(),  None);
-        // u64::MAX.to_uint() is word-size specific
-        assert_eq!(u64::MAX.to_u8(),   None);
-        assert_eq!(u64::MAX.to_u16(),  None);
-        assert_eq!(u64::MAX.to_u32(),  None);
-        assert_eq!(u64::MAX.to_u64(),  Some(u64::MAX as u64));
-
-        #[cfg(target_pointer_width = "32")]
-        fn check_word_size() {
-            assert_eq!(u64::MAX.to_uint(), None);
-        }
-
-        #[cfg(target_pointer_width = "64")]
-        fn check_word_size() {
-            assert_eq!(u64::MAX.to_uint(), Some(u64::MAX as usize));
-        }
-
-        check_word_size();
-    }
+    use ops::Mul;
 
     #[test]
     fn test_saturating_add_uint() {
@@ -1596,23 +106,23 @@ fn test_saturating_sub_uint() {
     #[test]
     fn test_saturating_add_int() {
         use isize::{MIN,MAX};
-        assert_eq!(3.saturating_add(5), 8);
-        assert_eq!(3.saturating_add(MAX-1), MAX);
+        assert_eq!(3i32.saturating_add(5), 8);
+        assert_eq!(3isize.saturating_add(MAX-1), MAX);
         assert_eq!(MAX.saturating_add(MAX), MAX);
         assert_eq!((MAX-2).saturating_add(1), MAX-1);
-        assert_eq!(3.saturating_add(-5), -2);
+        assert_eq!(3i32.saturating_add(-5), -2);
         assert_eq!(MIN.saturating_add(-1), MIN);
-        assert_eq!((-2).saturating_add(-MAX), MIN);
+        assert_eq!((-2isize).saturating_add(-MAX), MIN);
     }
 
     #[test]
     fn test_saturating_sub_int() {
         use isize::{MIN,MAX};
-        assert_eq!(3.saturating_sub(5), -2);
+        assert_eq!(3i32.saturating_sub(5), -2);
         assert_eq!(MIN.saturating_sub(1), MIN);
-        assert_eq!((-2).saturating_sub(MAX), MIN);
-        assert_eq!(3.saturating_sub(-5), 8);
-        assert_eq!(3.saturating_sub(-(MAX-1)), MAX);
+        assert_eq!((-2isize).saturating_sub(MAX), MIN);
+        assert_eq!(3i32.saturating_sub(-5), 8);
+        assert_eq!(3isize.saturating_sub(-(MAX-1)), MAX);
         assert_eq!(MAX.saturating_sub(-MAX), MAX);
         assert_eq!((MAX-2).saturating_sub(-1), MAX-1);
     }
@@ -1716,56 +226,10 @@ fn $test_name() {
     test_checked_next_power_of_two! { test_checked_next_power_of_two_u64, u64 }
     test_checked_next_power_of_two! { test_checked_next_power_of_two_uint, usize }
 
-    #[derive(PartialEq, Debug)]
-    struct Value { x: isize }
-
-    impl ToPrimitive for Value {
-        fn to_i64(&self) -> Option<i64> { self.x.to_i64() }
-        fn to_u64(&self) -> Option<u64> { self.x.to_u64() }
-    }
-
-    impl FromPrimitive for Value {
-        fn from_i64(n: i64) -> Option<Value> { Some(Value { x: n as isize }) }
-        fn from_u64(n: u64) -> Option<Value> { Some(Value { x: n as isize }) }
-    }
-
-    #[test]
-    fn test_to_primitive() {
-        let value = Value { x: 5 };
-        assert_eq!(value.to_int(),  Some(5));
-        assert_eq!(value.to_i8(),   Some(5));
-        assert_eq!(value.to_i16(),  Some(5));
-        assert_eq!(value.to_i32(),  Some(5));
-        assert_eq!(value.to_i64(),  Some(5));
-        assert_eq!(value.to_uint(), Some(5));
-        assert_eq!(value.to_u8(),   Some(5));
-        assert_eq!(value.to_u16(),  Some(5));
-        assert_eq!(value.to_u32(),  Some(5));
-        assert_eq!(value.to_u64(),  Some(5));
-        assert_eq!(value.to_f32(),  Some(5f32));
-        assert_eq!(value.to_f64(),  Some(5f64));
-    }
-
-    #[test]
-    fn test_from_primitive() {
-        assert_eq!(from_int(5),    Some(Value { x: 5 }));
-        assert_eq!(from_i8(5),     Some(Value { x: 5 }));
-        assert_eq!(from_i16(5),    Some(Value { x: 5 }));
-        assert_eq!(from_i32(5),    Some(Value { x: 5 }));
-        assert_eq!(from_i64(5),    Some(Value { x: 5 }));
-        assert_eq!(from_uint(5),   Some(Value { x: 5 }));
-        assert_eq!(from_u8(5),     Some(Value { x: 5 }));
-        assert_eq!(from_u16(5),    Some(Value { x: 5 }));
-        assert_eq!(from_u32(5),    Some(Value { x: 5 }));
-        assert_eq!(from_u64(5),    Some(Value { x: 5 }));
-        assert_eq!(from_f32(5f32), Some(Value { x: 5 }));
-        assert_eq!(from_f64(5f64), Some(Value { x: 5 }));
-    }
-
     #[test]
     fn test_pow() {
-        fn naive_pow<T: Int>(base: T, exp: usize) -> T {
-            let one: T = Int::one();
+        fn naive_pow<T: Mul<Output=T> + One + Copy>(base: T, exp: usize) -> T {
+            let one: T = T::one();
             (0..exp).fold(one, |acc, _| acc * base)
         }
         macro_rules! assert_pow {
@@ -1775,11 +239,11 @@ macro_rules! assert_pow {
                 assert_eq!(result, naive_pow($num, $exp));
             }}
         }
-        assert_pow!((3,     0 ) => 1);
-        assert_pow!((5,     1 ) => 5);
-        assert_pow!((-4,    2 ) => 16);
-        assert_pow!((8,     3 ) => 512);
-        assert_pow!((2u64,   50) => 1125899906842624);
+        assert_pow!((3u32,     0 ) => 1);
+        assert_pow!((5u32,     1 ) => 5);
+        assert_pow!((-4i32,    2 ) => 16);
+        assert_pow!((8u32,     3 ) => 512);
+        assert_pow!((2u64,     50) => 1125899906842624);
     }
 
     #[test]
@@ -1854,12 +318,11 @@ fn test_uint_from_str_overflow() {
 mod bench {
     extern crate test;
     use self::test::Bencher;
-    use num::Int;
     use prelude::v1::*;
 
     #[bench]
     fn bench_pow_function(b: &mut Bencher) {
-        let v = (0..1024).collect::<Vec<_>>();
-        b.iter(|| {v.iter().fold(0, |old, new| old.pow(*new as u32));});
+        let v = (0..1024).collect::<Vec<u32>>();
+        b.iter(|| {v.iter().fold(0u32, |old, new| old.pow(*new as u32));});
     }
 }
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
deleted file mode 100644 (file)
index 8ab66f2..0000000
+++ /dev/null
@@ -1,558 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-//
-// ignore-lexer-test FIXME #15679
-
-#![allow(missing_docs)]
-#![allow(deprecated)]
-
-use self::ExponentFormat::*;
-use self::SignificantDigits::*;
-use self::SignFormat::*;
-
-use char;
-use num::{self, Int, Float, ToPrimitive};
-use num::FpCategory as Fp;
-use ops::FnMut;
-use string::String;
-use vec::Vec;
-
-/// A flag that specifies whether to use exponential (scientific) notation.
-#[derive(Copy, Clone)]
-pub enum ExponentFormat {
-    /// Do not use exponential notation.
-    ExpNone,
-    /// Use exponential notation with the exponent having a base of 10 and the
-    /// exponent sign being `e` or `E`. For example, 1000 would be printed
-    /// 1e3.
-    ExpDec,
-    /// Use exponential notation with the exponent having a base of 2 and the
-    /// exponent sign being `p` or `P`. For example, 8 would be printed 1p3.
-    ExpBin,
-}
-
-/// The number of digits used for emitting the fractional part of a number, if
-/// any.
-#[derive(Copy, Clone)]
-pub enum SignificantDigits {
-    /// All calculable digits will be printed.
-    ///
-    /// Note that bignums or fractions may cause a surprisingly large number
-    /// of digits to be printed.
-    DigAll,
-
-    /// At most the given number of digits will be printed, truncating any
-    /// trailing zeroes.
-    DigMax(usize),
-
-    /// Precisely the given number of digits will be printed.
-    DigExact(usize)
-}
-
-/// How to emit the sign of a number.
-#[derive(Copy, Clone)]
-pub enum SignFormat {
-    /// No sign will be printed. The exponent sign will also be emitted.
-    SignNone,
-    /// `-` will be printed for negative values, but no sign will be emitted
-    /// for positive numbers.
-    SignNeg,
-    /// `+` will be printed for positive values, and `-` will be printed for
-    /// negative values.
-    SignAll,
-}
-
-/// Converts an integral number to its string representation as a byte vector.
-/// This is meant to be a common base implementation for all integral string
-/// conversion functions like `to_string()` or `to_str_radix()`.
-///
-/// # Arguments
-///
-/// - `num`           - The number to convert. Accepts any number that
-///                     implements the numeric traits.
-/// - `radix`         - Base to use. Accepts only the values 2-36.
-/// - `sign`          - How to emit the sign. Options are:
-///     - `SignNone`: No sign at all. Basically emits `abs(num)`.
-///     - `SignNeg`:  Only `-` on negative values.
-///     - `SignAll`:  Both `+` on positive, and `-` on negative numbers.
-/// - `f`             - a callback which will be invoked for each ascii character
-///                     which composes the string representation of this integer
-///
-/// # Panics
-///
-/// - Panics if `radix` < 2 or `radix` > 36.
-fn int_to_str_bytes_common<T, F>(num: T, radix: usize, sign: SignFormat, mut f: F) where
-    T: Int,
-    F: FnMut(u8),
-{
-    assert!(2 <= radix && radix <= 36);
-
-    let _0: T = Int::zero();
-
-    let neg = num < _0;
-    let radix_gen: T = num::cast(radix).unwrap();
-
-    let mut deccum = num;
-    // This is just for integral types, the largest of which is a u64. The
-    // smallest base that we can have is 2, so the most number of digits we're
-    // ever going to have is 64
-    let mut buf = [0; 64];
-    let mut cur = 0;
-
-    // Loop at least once to make sure at least a `0` gets emitted.
-    loop {
-        // Calculate the absolute value of each digit instead of only
-        // doing it once for the whole number because a
-        // representable negative number doesn't necessary have an
-        // representable additive inverse of the same type
-        // (See twos complement). But we assume that for the
-        // numbers [-35 .. 0] we always have [0 .. 35].
-        let current_digit_signed = deccum % radix_gen;
-        let current_digit = if current_digit_signed < _0 {
-            _0 - current_digit_signed
-        } else {
-            current_digit_signed
-        };
-        buf[cur] = match current_digit.to_u8().unwrap() {
-            i @ 0...9 => b'0' + i,
-            i         => b'a' + (i - 10),
-        };
-        cur += 1;
-
-        deccum = deccum / radix_gen;
-        // No more digits to calculate for the non-fractional part -> break
-        if deccum == _0 { break; }
-    }
-
-    // Decide what sign to put in front
-    match sign {
-        SignNeg | SignAll if neg => { f(b'-'); }
-        SignAll => { f(b'+'); }
-        _ => ()
-    }
-
-    // We built the number in reverse order, so un-reverse it here
-    while cur > 0 {
-        cur -= 1;
-        f(buf[cur]);
-    }
-}
-
-/// Converts a number to its string representation as a byte vector.
-/// This is meant to be a common base implementation for all numeric string
-/// conversion functions like `to_string()` or `to_str_radix()`.
-///
-/// # Arguments
-///
-/// - `num`           - The number to convert. Accepts any number that
-///                     implements the numeric traits.
-/// - `radix`         - Base to use. Accepts only the values 2-36. If the exponential notation
-///                     is used, then this base is only used for the significand. The exponent
-///                     itself always printed using a base of 10.
-/// - `negative_zero` - Whether to treat the special value `-0` as
-///                     `-0` or as `+0`.
-/// - `sign`          - How to emit the sign. See `SignFormat`.
-/// - `digits`        - The amount of digits to use for emitting the fractional
-///                     part, if any. See `SignificantDigits`.
-/// - `exp_format`   - Whether or not to use the exponential (scientific) notation.
-///                    See `ExponentFormat`.
-/// - `exp_capital`   - Whether or not to use a capital letter for the exponent sign, if
-///                     exponential notation is desired.
-///
-/// # Return value
-///
-/// A tuple containing the byte vector, and a boolean flag indicating
-/// whether it represents a special value like `inf`, `-inf`, `NaN` or not.
-/// It returns a tuple because there can be ambiguity between a special value
-/// and a number representation at higher bases.
-///
-/// # Panics
-///
-/// - Panics if `radix` < 2 or `radix` > 36.
-/// - Panics if `radix` > 14 and `exp_format` is `ExpDec` due to conflict
-///   between digit and exponent sign `'e'`.
-/// - Panics if `radix` > 25 and `exp_format` is `ExpBin` due to conflict
-///   between digit and exponent sign `'p'`.
-pub fn float_to_str_bytes_common<T: Float>(
-        num: T, radix: u32, negative_zero: bool,
-        sign: SignFormat, digits: SignificantDigits, exp_format: ExponentFormat, exp_upper: bool
-        ) -> (Vec<u8>, bool) {
-    assert!(2 <= radix && radix <= 36);
-    match exp_format {
-        ExpDec if radix >= DIGIT_E_RADIX       // decimal exponent 'e'
-          => panic!("float_to_str_bytes_common: radix {} incompatible with \
-                    use of 'e' as decimal exponent", radix),
-        ExpBin if radix >= DIGIT_P_RADIX       // binary exponent 'p'
-          => panic!("float_to_str_bytes_common: radix {} incompatible with \
-                    use of 'p' as binary exponent", radix),
-        _ => ()
-    }
-
-    let _0: T = Float::zero();
-    let _1: T = Float::one();
-
-    match num.classify() {
-        Fp::Nan => { return (b"NaN".to_vec(), true); }
-        Fp::Infinite if num > _0 => {
-            return match sign {
-                SignAll => (b"+inf".to_vec(), true),
-                _       => (b"inf".to_vec(), true)
-            };
-        }
-        Fp::Infinite if num < _0 => {
-            return match sign {
-                SignNone => (b"inf".to_vec(), true),
-                _        => (b"-inf".to_vec(), true),
-            };
-        }
-        _ => {}
-    }
-
-    let neg = num < _0 || (negative_zero && _1 / num == Float::neg_infinity());
-    let mut buf = Vec::new();
-    let radix_gen: T = num::cast(radix as isize).unwrap();
-
-    let (num, exp) = match exp_format {
-        ExpNone => (num, 0),
-        ExpDec | ExpBin => {
-            if num == _0 {
-                (num, 0)
-            } else {
-                let (exp, exp_base) = match exp_format {
-                    ExpDec => (num.abs().log10().floor(), num::cast::<f64, T>(10.0f64).unwrap()),
-                    ExpBin => (num.abs().log2().floor(), num::cast::<f64, T>(2.0f64).unwrap()),
-                    ExpNone => unreachable!()
-                };
-
-                (num / exp_base.powf(exp), num::cast::<T, i32>(exp).unwrap())
-            }
-        }
-    };
-
-    // First emit the non-fractional part, looping at least once to make
-    // sure at least a `0` gets emitted.
-    let mut deccum = num.trunc();
-    loop {
-        // Calculate the absolute value of each digit instead of only
-        // doing it once for the whole number because a
-        // representable negative number doesn't necessary have an
-        // representable additive inverse of the same type
-        // (See twos complement). But we assume that for the
-        // numbers [-35 .. 0] we always have [0 .. 35].
-        let current_digit = (deccum % radix_gen).abs();
-
-        // Decrease the deccumulator one digit at a time
-        deccum = deccum / radix_gen;
-        deccum = deccum.trunc();
-
-        buf.push(char::from_digit(current_digit.to_isize().unwrap() as u32, radix)
-             .unwrap() as u8);
-
-        // No more digits to calculate for the non-fractional part -> break
-        if deccum == _0 { break; }
-    }
-
-    // If limited digits, calculate one digit more for rounding.
-    let (limit_digits, digit_count, exact) = match digits {
-        DigAll          => (false, 0,       false),
-        DigMax(count)   => (true,  count+1, false),
-        DigExact(count) => (true,  count+1, true)
-    };
-
-    // Decide what sign to put in front
-    match sign {
-        SignNeg | SignAll if neg => {
-            buf.push(b'-');
-        }
-        SignAll => {
-            buf.push(b'+');
-        }
-        _ => ()
-    }
-
-    buf.reverse();
-
-    // Remember start of the fractional digits.
-    // Points one beyond end of buf if none get generated,
-    // or at the '.' otherwise.
-    let start_fractional_digits = buf.len();
-
-    // Now emit the fractional part, if any
-    deccum = num.fract();
-    if deccum != _0 || (limit_digits && exact && digit_count > 0) {
-        buf.push(b'.');
-        let mut dig = 0;
-
-        // calculate new digits while
-        // - there is no limit and there are digits left
-        // - or there is a limit, it's not reached yet and
-        //   - it's exact
-        //   - or it's a maximum, and there are still digits left
-        while (!limit_digits && deccum != _0)
-           || (limit_digits && dig < digit_count && (
-                   exact
-                || (!exact && deccum != _0)
-              )
-        ) {
-            // Shift first fractional digit into the integer part
-            deccum = deccum * radix_gen;
-
-            // Calculate the absolute value of each digit.
-            // See note in first loop.
-            let current_digit = deccum.trunc().abs();
-
-            buf.push(char::from_digit(
-                current_digit.to_isize().unwrap() as u32, radix).unwrap() as u8);
-
-            // Decrease the deccumulator one fractional digit at a time
-            deccum = deccum.fract();
-            dig += 1;
-        }
-
-        // If digits are limited, and that limit has been reached,
-        // cut off the one extra digit, and depending on its value
-        // round the remaining ones.
-        if limit_digits && dig == digit_count {
-            let ascii2value = |chr: u8| {
-                (chr as char).to_digit(radix).unwrap()
-            };
-            let value2ascii = |val: u32| {
-                char::from_digit(val, radix).unwrap() as u8
-            };
-
-            let extra_digit = ascii2value(buf.pop().unwrap());
-            if extra_digit >= radix / 2 { // -> need to round
-                let mut i: isize = buf.len() as isize - 1;
-                loop {
-                    // If reached left end of number, have to
-                    // insert additional digit:
-                    if i < 0
-                    || buf[i as usize] == b'-'
-                    || buf[i as usize] == b'+' {
-                        buf.insert((i + 1) as usize, value2ascii(1));
-                        break;
-                    }
-
-                    // Skip the '.'
-                    if buf[i as usize] == b'.' { i -= 1; continue; }
-
-                    // Either increment the digit,
-                    // or set to 0 if max and carry the 1.
-                    let current_digit = ascii2value(buf[i as usize]);
-                    if current_digit < (radix - 1) {
-                        buf[i as usize] = value2ascii(current_digit+1);
-                        break;
-                    } else {
-                        buf[i as usize] = value2ascii(0);
-                        i -= 1;
-                    }
-                }
-            }
-        }
-    }
-
-    // if number of digits is not exact, remove all trailing '0's up to
-    // and including the '.'
-    if !exact {
-        let buf_max_i = buf.len() - 1;
-
-        // index to truncate from
-        let mut i = buf_max_i;
-
-        // discover trailing zeros of fractional part
-        while i > start_fractional_digits && buf[i] == b'0' {
-            i -= 1;
-        }
-
-        // Only attempt to truncate digits if buf has fractional digits
-        if i >= start_fractional_digits {
-            // If buf ends with '.', cut that too.
-            if buf[i] == b'.' { i -= 1 }
-
-            // only resize buf if we actually remove digits
-            if i < buf_max_i {
-                buf = buf[.. (i + 1)].to_vec();
-            }
-        }
-    } // If exact and trailing '.', just cut that
-    else {
-        let max_i = buf.len() - 1;
-        if buf[max_i] == b'.' {
-            buf = buf[.. max_i].to_vec();
-        }
-    }
-
-    match exp_format {
-        ExpNone => (),
-        _ => {
-            buf.push(match exp_format {
-                ExpDec if exp_upper => 'E',
-                ExpDec if !exp_upper => 'e',
-                ExpBin if exp_upper => 'P',
-                ExpBin if !exp_upper => 'p',
-                _ => unreachable!()
-            } as u8);
-
-            int_to_str_bytes_common(exp, 10, sign, |c| buf.push(c));
-        }
-    }
-
-    (buf, false)
-}
-
-/// Converts a number to its string representation. This is a wrapper for
-/// `to_str_bytes_common()`, for details see there.
-#[inline]
-pub fn float_to_str_common<T: Float>(
-        num: T, radix: u32, negative_zero: bool,
-        sign: SignFormat, digits: SignificantDigits, exp_format: ExponentFormat, exp_capital: bool
-        ) -> (String, bool) {
-    let (bytes, special) = float_to_str_bytes_common(num, radix,
-                               negative_zero, sign, digits, exp_format, exp_capital);
-    (String::from_utf8(bytes).unwrap(), special)
-}
-
-// Some constants for from_str_bytes_common's input validation,
-// they define minimum radix values for which the character is a valid digit.
-const DIGIT_P_RADIX: u32 = ('p' as u32) - ('a' as u32) + 11;
-const DIGIT_E_RADIX: u32 = ('e' as u32) - ('a' as u32) + 11;
-
-#[cfg(test)]
-mod tests {
-    use core::num::wrapping::WrappingOps;
-    use string::ToString;
-
-    #[test]
-    fn test_int_to_str_overflow() {
-        let mut i8_val: i8 = 127;
-        assert_eq!(i8_val.to_string(), "127");
-
-        i8_val = i8_val.wrapping_add(1);
-        assert_eq!(i8_val.to_string(), "-128");
-
-        let mut i16_val: i16 = 32_767;
-        assert_eq!(i16_val.to_string(), "32767");
-
-        i16_val = i16_val.wrapping_add(1);
-        assert_eq!(i16_val.to_string(), "-32768");
-
-        let mut i32_val: i32 = 2_147_483_647;
-        assert_eq!(i32_val.to_string(), "2147483647");
-
-        i32_val = i32_val.wrapping_add(1);
-        assert_eq!(i32_val.to_string(), "-2147483648");
-
-        let mut i64_val: i64 = 9_223_372_036_854_775_807;
-        assert_eq!(i64_val.to_string(), "9223372036854775807");
-
-        i64_val = i64_val.wrapping_add(1);
-        assert_eq!(i64_val.to_string(), "-9223372036854775808");
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    #![allow(deprecated)] // rand
-    extern crate test;
-
-    mod usize {
-        use super::test::Bencher;
-        use rand::{thread_rng, Rng};
-        use std::fmt;
-
-        #[inline]
-        fn to_string(x: usize, base: u8) {
-            format!("{}", fmt::radix(x, base));
-        }
-
-        #[bench]
-        fn to_str_bin(b: &mut Bencher) {
-            let mut rng = thread_rng();
-            b.iter(|| { to_string(rng.gen::<usize>(), 2); })
-        }
-
-        #[bench]
-        fn to_str_oct(b: &mut Bencher) {
-            let mut rng = thread_rng();
-            b.iter(|| { to_string(rng.gen::<usize>(), 8); })
-        }
-
-        #[bench]
-        fn to_str_dec(b: &mut Bencher) {
-            let mut rng = thread_rng();
-            b.iter(|| { to_string(rng.gen::<usize>(), 10); })
-        }
-
-        #[bench]
-        fn to_str_hex(b: &mut Bencher) {
-            let mut rng = thread_rng();
-            b.iter(|| { to_string(rng.gen::<usize>(), 16); })
-        }
-
-        #[bench]
-        fn to_str_base_36(b: &mut Bencher) {
-            let mut rng = thread_rng();
-            b.iter(|| { to_string(rng.gen::<usize>(), 36); })
-        }
-    }
-
-    mod isize {
-        use super::test::Bencher;
-        use rand::{thread_rng, Rng};
-        use std::fmt;
-
-        #[inline]
-        fn to_string(x: isize, base: u8) {
-            format!("{}", fmt::radix(x, base));
-        }
-
-        #[bench]
-        fn to_str_bin(b: &mut Bencher) {
-            let mut rng = thread_rng();
-            b.iter(|| { to_string(rng.gen::<isize>(), 2); })
-        }
-
-        #[bench]
-        fn to_str_oct(b: &mut Bencher) {
-            let mut rng = thread_rng();
-            b.iter(|| { to_string(rng.gen::<isize>(), 8); })
-        }
-
-        #[bench]
-        fn to_str_dec(b: &mut Bencher) {
-            let mut rng = thread_rng();
-            b.iter(|| { to_string(rng.gen::<isize>(), 10); })
-        }
-
-        #[bench]
-        fn to_str_hex(b: &mut Bencher) {
-            let mut rng = thread_rng();
-            b.iter(|| { to_string(rng.gen::<isize>(), 16); })
-        }
-
-        #[bench]
-        fn to_str_base_36(b: &mut Bencher) {
-            let mut rng = thread_rng();
-            b.iter(|| { to_string(rng.gen::<isize>(), 36); })
-        }
-    }
-
-    mod f64 {
-        use super::test::Bencher;
-        use rand::{thread_rng, Rng};
-        use f64;
-
-        #[bench]
-        fn float_to_string(b: &mut Bencher) {
-            let mut rng = thread_rng();
-            b.iter(|| { f64::to_string(rng.gen()); })
-        }
-    }
-}
index c9e6a8f66d1d25cb01e50a4a67c9f20873cdfbbb..96b0ba1c77f8da8c600cf02a16eebabe43fe0960 100644 (file)
 #![doc(hidden)]
 #![allow(unsigned_negation)]
 
-macro_rules! uint_module { ($T:ty) => (
+macro_rules! uint_module { ($T:ident) => (
 
 #[cfg(test)]
 mod tests {
     use prelude::v1::*;
-    use num::FromStrRadix;
 
     fn from_str<T: ::str::FromStr>(t: &str) -> Option<T> {
         ::str::FromStr::from_str(t).ok()
@@ -38,15 +37,15 @@ pub fn test_from_str() {
 
     #[test]
     pub fn test_parse_bytes() {
-        assert_eq!(FromStrRadix::from_str_radix("123", 10), Ok(123 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("1001", 2), Ok(9 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("123", 8), Ok(83 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("123", 16), Ok(291 as u16));
-        assert_eq!(FromStrRadix::from_str_radix("ffff", 16), Ok(65535 as u16));
-        assert_eq!(FromStrRadix::from_str_radix("z", 36), Ok(35 as $T));
-
-        assert_eq!(FromStrRadix::from_str_radix("Z", 10).ok(), None::<$T>);
-        assert_eq!(FromStrRadix::from_str_radix("_", 2).ok(), None::<$T>);
+        assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
+        assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
+        assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
+        assert_eq!(u16::from_str_radix("123", 16), Ok(291 as u16));
+        assert_eq!(u16::from_str_radix("ffff", 16), Ok(65535 as u16));
+        assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
+
+        assert_eq!($T::from_str_radix("Z", 10).ok(), None::<$T>);
+        assert_eq!($T::from_str_radix("_", 2).ok(), None::<$T>);
     }
 }
 
index a498e634185f213240b4fd8af53de44c8933f815..11b057d0094ae1d0674b22db405f03307eb35a47 100644 (file)
@@ -19,7 +19,6 @@
 use sys::stdio::Stderr;
 use thread;
 
-// Defined in this module instead of old_io::stdio so that the unwinding
 thread_local! {
     pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
         RefCell::new(None)
index 0a13c77018f71e598ad5f8b660c5e6523f750fab..a52a3dbbef9a5f75956e914cd55e9cb7cce05147 100644 (file)
 use ascii::*;
 use borrow::{Borrow, IntoCow, ToOwned, Cow};
 use cmp;
-use iter::{self, IntoIterator};
+use iter;
 use mem;
 use ops::{self, Deref};
 use string::String;
 use vec::Vec;
 use fmt;
 
-use ffi::{OsStr, OsString, AsOsStr};
+use ffi::{OsStr, OsString};
 
 use self::platform::{is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix};
 
@@ -1184,14 +1184,6 @@ fn as_ref(&self) -> &OsStr {
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
-impl AsOsStr for PathBuf {
-    fn as_os_str(&self) -> &OsStr {
-        &self.inner[..]
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Into<OsString> for PathBuf {
     fn into(self) -> OsString {
@@ -1660,14 +1652,6 @@ fn as_ref(&self) -> &OsStr {
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
-impl AsOsStr for Path {
-    fn as_os_str(&self) -> &OsStr {
-        &self.inner
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Debug for Path {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
@@ -1719,22 +1703,6 @@ fn cmp(&self, other: &Path) -> cmp::Ordering {
     }
 }
 
-/// Freely convertible to a `Path`.
-#[unstable(feature = "std_misc")]
-#[deprecated(since = "1.0.0", reason = "use std::convert::AsRef<Path> instead")]
-pub trait AsPath {
-    /// Converts to a `Path`.
-    #[unstable(feature = "std_misc")]
-    fn as_path(&self) -> &Path;
-}
-
-#[unstable(feature = "std_misc")]
-#[deprecated(since = "1.0.0", reason = "use std::convert::AsRef<Path> instead")]
-#[allow(deprecated)]
-impl<T: AsOsStr + ?Sized> AsPath for T {
-    fn as_path(&self) -> &Path { Path::new(self.as_os_str()) }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl AsRef<Path> for Path {
     fn as_ref(&self) -> &Path { self }
index c93fc13284b44ac8ef25acbf470a3c56262aa58a..6dc11c505a914a6f76b597e3fa53d8d5c194a8cf 100644 (file)
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use boxed::Box;
 #[stable(feature = "rust1", since = "1.0.0")]
+#[doc(no_inline)] pub use borrow::ToOwned;
+#[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use clone::Clone;
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
-#[unstable(feature = "convert")]
+#[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use convert::{AsRef, AsMut, Into, From};
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use iter::DoubleEndedIterator;
+#[doc(no_inline)] pub use default::Default;
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use iter::ExactSizeIterator;
+#[doc(no_inline)] pub use iter::{Iterator, Extend, IntoIterator};
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use iter::{Iterator, Extend};
+#[doc(no_inline)] pub use iter::{DoubleEndedIterator, ExactSizeIterator};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use option::Option::{self, Some, None};
 #[stable(feature = "rust1", since = "1.0.0")]
index 30d5ae5c6008beb7ba02865df4f745d18c4d6b36..a04bb6705b32167c9329bbce4c1b2d94f065d3d5 100644 (file)
@@ -346,7 +346,7 @@ fn drop(&mut self) {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use prelude::v1::*;
 
     use sync::mpsc::channel;
index f8dd6a00c7f1d9c21577cbbc7e2804d38c9242f8..d19bc5b617f8462e62f0ddc5f1c618ccd74d6d0a 100644 (file)
@@ -63,11 +63,10 @@ fn fill_bytes(&mut self, mut v: &mut [u8]) {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use prelude::v1::*;
 
     use super::ReaderRng;
-    use num::Int;
     use rand::Rng;
 
     #[test]
@@ -78,18 +77,18 @@ fn test_reader_rng_u64() {
                   0,   0, 0, 0, 0, 0, 0, 3][..];
         let mut rng = ReaderRng::new(v);
 
-        assert_eq!(rng.next_u64(), 1.to_be());
-        assert_eq!(rng.next_u64(), 2.to_be());
-        assert_eq!(rng.next_u64(), 3.to_be());
+        assert_eq!(rng.next_u64(), 1u64.to_be());
+        assert_eq!(rng.next_u64(), 2u64.to_be());
+        assert_eq!(rng.next_u64(), 3u64.to_be());
     }
     #[test]
     fn test_reader_rng_u32() {
         let v = &[0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3][..];
         let mut rng = ReaderRng::new(v);
 
-        assert_eq!(rng.next_u32(), 1.to_be());
-        assert_eq!(rng.next_u32(), 2.to_be());
-        assert_eq!(rng.next_u32(), 3.to_be());
+        assert_eq!(rng.next_u32(), 1u32.to_be());
+        assert_eq!(rng.next_u32(), 2u32.to_be());
+        assert_eq!(rng.next_u32(), 3u32.to_be());
     }
     #[test]
     fn test_reader_rng_fill_bytes() {
index ced84d7551eef349989e897afd1598264288d366..72cbe2b533bb7fc6b62cf366861085d55945e186 100644 (file)
@@ -38,7 +38,7 @@ pub fn log_enabled() -> bool {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use prelude::v1::*;
     use sys_common;
     macro_rules! t { ($a:expr, $b:expr) => ({
index 9919238c208dab8063e05adf4cab6875457f011b..31e970a9550c4316a74a3fc3f1a3aad25d0eb3e1 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15677
 
 use io::prelude::*;
 
index fcb0d2c0b2d38bbe60e00117b1315e1515c15d90..c2964b7a4f12506d15033e15ef93833f2c14c937 100644 (file)
@@ -161,14 +161,6 @@ pub fn wait_timeout_ms<'a, T>(&self, guard: MutexGuard<'a, T>, ms: u32)
         }
     }
 
-    /// Deprecated: use `wait_timeout_ms` instead.
-    #[unstable(feature = "std_misc")]
-    #[deprecated(since = "1.0.0", reason = "use wait_timeout_ms instead")]
-    pub fn wait_timeout<'a, T>(&self, guard: MutexGuard<'a, T>, dur: Duration)
-                               -> LockResult<(MutexGuard<'a, T>, bool)> {
-        self.wait_timeout_ms(guard, dur.num_milliseconds() as u32)
-    }
-
     /// Waits on this condition variable for a notification, timing out after a
     /// specified duration.
     ///
index 2cdde1aca9e682c7696d67ffad62c8f45adaa043..2d281eb4e249ca2be556107d114a100b9c6523f1 100644 (file)
@@ -155,7 +155,7 @@ pub fn spawn<F>(blk: F) -> Future<A>
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use prelude::v1::*;
     use sync::mpsc::channel;
     use sync::Future;
index 422439fadc1a1b77255d220977b180936a6593f4..74e85db1a06ff1eba3517292ea35281c167ee984 100644 (file)
@@ -306,6 +306,14 @@ pub struct Iter<'a, T: 'a> {
     rx: &'a Receiver<T>
 }
 
+/// An owning iterator over messages on a receiver, this iterator will block
+/// whenever `next` is called, waiting for a new message, and `None` will be
+/// returned when the corresponding channel has hung up.
+#[stable(feature = "receiver_into_iter", since = "1.1.0")]
+pub struct IntoIter<T> {
+    rx: Receiver<T>
+}
+
 /// The sending-half of Rust's asynchronous channel type. This half can only be
 /// owned by one task, but it can be cloned to send to other tasks.
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -899,6 +907,29 @@ impl<'a, T> Iterator for Iter<'a, T> {
     fn next(&mut self) -> Option<T> { self.rx.recv().ok() }
 }
 
+#[stable(feature = "receiver_into_iter", since = "1.1.0")]
+impl<'a, T> IntoIterator for &'a Receiver<T> {
+    type Item = T;
+    type IntoIter = Iter<'a, T>;
+
+    fn into_iter(self) -> Iter<'a, T> { self.iter() }
+}
+
+impl<T> Iterator for IntoIter<T> {
+    type Item = T;
+    fn next(&mut self) -> Option<T> { self.rx.recv().ok() }
+}
+
+#[stable(feature = "receiver_into_iter", since = "1.1.0")]
+impl <T> IntoIterator for Receiver<T> {
+    type Item = T;
+    type IntoIter = IntoIter<T>;
+
+    fn into_iter(self) -> IntoIter<T> {
+        IntoIter { rx: self }
+    }
+}
+
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Drop for Receiver<T> {
@@ -1034,7 +1065,7 @@ fn cause(&self) -> Option<&error::Error> {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use prelude::v1::*;
 
     use std::env;
@@ -1507,6 +1538,32 @@ fn test_recv_iter_break() {
         assert_eq!(count_rx.recv().unwrap(), 4);
     }
 
+    #[test]
+    fn test_recv_into_iter_owned() {
+        let mut iter = {
+          let (tx, rx) = channel::<i32>();
+          tx.send(1).unwrap();
+          tx.send(2).unwrap();
+
+          rx.into_iter()
+        };
+        assert_eq!(iter.next().unwrap(), 1);
+        assert_eq!(iter.next().unwrap(), 2);
+        assert_eq!(iter.next().is_none(), true);
+    }
+
+    #[test]
+    fn test_recv_into_iter_borrowed() {
+        let (tx, rx) = channel::<i32>();
+        tx.send(1).unwrap();
+        tx.send(2).unwrap();
+        drop(tx);
+        let mut iter = (&rx).into_iter();
+        assert_eq!(iter.next().unwrap(), 1);
+        assert_eq!(iter.next().unwrap(), 2);
+        assert_eq!(iter.next().is_none(), true);
+    }
+
     #[test]
     fn try_recv_states() {
         let (tx1, rx1) = channel::<i32>();
index b8ad92841f2de65a8a7e8ef3df3a17886829fb6e..58f16a83ba9353d164ec01515f5fd52b6ba391d8 100644 (file)
@@ -346,7 +346,7 @@ fn next(&mut self) -> Option<*mut Handle<'static, ()>> {
 
 #[cfg(test)]
 #[allow(unused_imports)]
-mod test {
+mod tests {
     use prelude::v1::*;
 
     use thread;
index c75ac13080866ce2a0f3376a91cf830af7691ac0..4dd84364fa80ef0634832e194cf4242e04cd9272 100644 (file)
@@ -241,7 +241,7 @@ fn drop(&mut self) {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use prelude::v1::*;
 
     use sync::Arc;
index 7896870ea07e0c5060019da93ded747edc094a52..caf011c54f27a1c82b7b766f2a71c5d0bef5441c 100644 (file)
@@ -161,7 +161,7 @@ pub struct StaticMutex {
 /// dropped (falls out of scope), the lock will be unlocked.
 ///
 /// The data protected by the mutex can be access through this guard via its
-/// Deref and DerefMut implementations
+/// `Deref` and `DerefMut` implementations
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct MutexGuard<'a, T: 'a> {
@@ -361,7 +361,7 @@ pub fn guard_poison<'a, T>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use prelude::v1::*;
 
     use sync::mpsc::channel;
index 948965f5efa9d157dca85f7e0121eba169546dc0..2ce974c1271aad77cb09b89ddb404caa829075d0 100644 (file)
@@ -121,7 +121,7 @@ pub fn call_once<F>(&'static self, f: F) where F: FnOnce() {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use prelude::v1::*;
 
     use thread;
diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs
deleted file mode 100644 (file)
index fc21eff..0000000
+++ /dev/null
@@ -1,971 +0,0 @@
-// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(deprecated)]
-
-use prelude::v1::*;
-use self::SocketStatus::*;
-use self::InAddr::*;
-
-use ffi::{CString, CStr};
-use old_io::net::addrinfo;
-use old_io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr};
-use old_io::{IoResult, IoError};
-use libc::{self, c_char, c_int};
-use mem;
-use num::Int;
-use ptr::{self, null, null_mut};
-use str;
-use sys::{self, retry, c, sock_t, last_error, last_net_error, last_gai_error, close_sock,
-          wrlen, msglen_t, os, wouldblock, set_nonblocking, timer, ms_to_timeval,
-          decode_error_detailed};
-use sync::{Arc, Mutex};
-#[cfg(not(target_os = "linux"))]
-use sync::MutexGuard;
-use sys_common::{self, keep_going, short_write, timeout};
-use cmp;
-use old_io;
-
-// FIXME: move uses of Arc and deadline tracking to std::io
-
-#[derive(Debug)]
-pub enum SocketStatus {
-    Readable,
-    Writable,
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// sockaddr and misc bindings
-////////////////////////////////////////////////////////////////////////////////
-
-pub fn htons(u: u16) -> u16 {
-    u.to_be()
-}
-pub fn ntohs(u: u16) -> u16 {
-    Int::from_be(u)
-}
-
-pub enum InAddr {
-    In4Addr(libc::in_addr),
-    In6Addr(libc::in6_addr),
-}
-
-pub fn ip_to_inaddr(ip: IpAddr) -> InAddr {
-    match ip {
-        Ipv4Addr(a, b, c, d) => {
-            let ip = ((a as u32) << 24) |
-                     ((b as u32) << 16) |
-                     ((c as u32) <<  8) |
-                     ((d as u32) <<  0);
-            In4Addr(libc::in_addr {
-                s_addr: Int::from_be(ip)
-            })
-        }
-        Ipv6Addr(a, b, c, d, e, f, g, h) => {
-            In6Addr(libc::in6_addr {
-                s6_addr: [
-                    htons(a),
-                    htons(b),
-                    htons(c),
-                    htons(d),
-                    htons(e),
-                    htons(f),
-                    htons(g),
-                    htons(h),
-                ]
-            })
-        }
-    }
-}
-
-pub fn addr_to_sockaddr(addr: SocketAddr,
-                    storage: &mut libc::sockaddr_storage)
-                    -> libc::socklen_t {
-    unsafe {
-        let len = match ip_to_inaddr(addr.ip) {
-            In4Addr(inaddr) => {
-                let storage = storage as *mut _ as *mut libc::sockaddr_in;
-                (*storage).sin_family = libc::AF_INET as libc::sa_family_t;
-                (*storage).sin_port = htons(addr.port);
-                (*storage).sin_addr = inaddr;
-                mem::size_of::<libc::sockaddr_in>()
-            }
-            In6Addr(inaddr) => {
-                let storage = storage as *mut _ as *mut libc::sockaddr_in6;
-                (*storage).sin6_family = libc::AF_INET6 as libc::sa_family_t;
-                (*storage).sin6_port = htons(addr.port);
-                (*storage).sin6_addr = inaddr;
-                mem::size_of::<libc::sockaddr_in6>()
-            }
-        };
-        return len as libc::socklen_t;
-    }
-}
-
-pub fn socket(addr: SocketAddr, ty: libc::c_int) -> IoResult<sock_t> {
-    unsafe {
-        let fam = match addr.ip {
-            Ipv4Addr(..) => libc::AF_INET,
-            Ipv6Addr(..) => libc::AF_INET6,
-        };
-        match libc::socket(fam, ty, 0) as i32 {
-            -1 => Err(last_net_error()),
-            fd => Ok(fd as sock_t),
-        }
-    }
-}
-
-pub fn setsockopt<T>(fd: sock_t, opt: libc::c_int, val: libc::c_int,
-                 payload: T) -> IoResult<()> {
-    unsafe {
-        let payload = &payload as *const T as *const libc::c_void;
-        let ret = libc::setsockopt(fd, opt, val,
-                                   payload,
-                                   mem::size_of::<T>() as libc::socklen_t);
-        if ret != 0 {
-            Err(last_net_error())
-        } else {
-            Ok(())
-        }
-    }
-}
-
-pub fn getsockopt<T: Copy>(fd: sock_t, opt: libc::c_int,
-                           val: libc::c_int) -> IoResult<T> {
-    unsafe {
-        let mut slot: T = mem::zeroed();
-        let mut len = mem::size_of::<T>() as libc::socklen_t;
-        let ret = c::getsockopt(fd, opt, val,
-                                &mut slot as *mut _ as *mut _,
-                                &mut len);
-        if ret != 0 {
-            Err(last_net_error())
-        } else {
-            assert!(len as usize == mem::size_of::<T>());
-            Ok(slot)
-        }
-    }
-}
-
-pub fn sockname(fd: sock_t,
-            f: unsafe extern "system" fn(sock_t, *mut libc::sockaddr,
-                                         *mut libc::socklen_t) -> libc::c_int)
-    -> IoResult<SocketAddr>
-{
-    let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
-    let mut len = mem::size_of::<libc::sockaddr_storage>() as libc::socklen_t;
-    unsafe {
-        let storage = &mut storage as *mut libc::sockaddr_storage;
-        let ret = f(fd,
-                    storage as *mut libc::sockaddr,
-                    &mut len as *mut libc::socklen_t);
-        if ret != 0 {
-            return Err(last_net_error())
-        }
-    }
-    return sockaddr_to_addr(&storage, len as usize);
-}
-
-pub fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
-                        len: usize) -> IoResult<SocketAddr> {
-    match storage.ss_family as libc::c_int {
-        libc::AF_INET => {
-            assert!(len as usize >= mem::size_of::<libc::sockaddr_in>());
-            let storage: &libc::sockaddr_in = unsafe {
-                mem::transmute(storage)
-            };
-            let ip = (storage.sin_addr.s_addr as u32).to_be();
-            let a = (ip >> 24) as u8;
-            let b = (ip >> 16) as u8;
-            let c = (ip >>  8) as u8;
-            let d = (ip >>  0) as u8;
-            Ok(SocketAddr {
-                ip: Ipv4Addr(a, b, c, d),
-                port: ntohs(storage.sin_port),
-            })
-        }
-        libc::AF_INET6 => {
-            assert!(len as usize >= mem::size_of::<libc::sockaddr_in6>());
-            let storage: &libc::sockaddr_in6 = unsafe {
-                mem::transmute(storage)
-            };
-            let a = ntohs(storage.sin6_addr.s6_addr[0]);
-            let b = ntohs(storage.sin6_addr.s6_addr[1]);
-            let c = ntohs(storage.sin6_addr.s6_addr[2]);
-            let d = ntohs(storage.sin6_addr.s6_addr[3]);
-            let e = ntohs(storage.sin6_addr.s6_addr[4]);
-            let f = ntohs(storage.sin6_addr.s6_addr[5]);
-            let g = ntohs(storage.sin6_addr.s6_addr[6]);
-            let h = ntohs(storage.sin6_addr.s6_addr[7]);
-            Ok(SocketAddr {
-                ip: Ipv6Addr(a, b, c, d, e, f, g, h),
-                port: ntohs(storage.sin6_port),
-            })
-        }
-        _ => {
-            Err(IoError {
-                kind: old_io::InvalidInput,
-                desc: "invalid argument",
-                detail: None,
-            })
-        }
-    }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// get_host_addresses
-////////////////////////////////////////////////////////////////////////////////
-
-extern "system" {
-    fn getaddrinfo(node: *const c_char, service: *const c_char,
-                   hints: *const libc::addrinfo,
-                   res: *mut *mut libc::addrinfo) -> c_int;
-    fn freeaddrinfo(res: *mut libc::addrinfo);
-}
-
-pub fn get_host_addresses(host: Option<&str>, servname: Option<&str>,
-                          hint: Option<addrinfo::Hint>)
-                          -> Result<Vec<addrinfo::Info>, IoError>
-{
-    sys::init_net();
-
-    assert!(host.is_some() || servname.is_some());
-
-    let c_host = match host {
-        Some(x) => Some(try!(CString::new(x))),
-        None => None,
-    };
-    let c_host = c_host.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
-    let c_serv = match servname {
-        Some(x) => Some(try!(CString::new(x))),
-        None => None,
-    };
-    let c_serv = c_serv.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
-
-    let hint = hint.map(|hint| {
-        libc::addrinfo {
-            ai_flags: hint.flags as c_int,
-            ai_family: hint.family as c_int,
-            ai_socktype: 0,
-            ai_protocol: 0,
-            ai_addrlen: 0,
-            ai_canonname: null_mut(),
-            ai_addr: null_mut(),
-            ai_next: null_mut()
-        }
-    });
-
-    let hint_ptr = hint.as_ref().map_or(null(), |x| {
-        x as *const libc::addrinfo
-    });
-    let mut res = null_mut();
-
-    // Make the call
-    let s = unsafe {
-        getaddrinfo(c_host, c_serv, hint_ptr, &mut res)
-    };
-
-    // Error?
-    if s != 0 {
-        return Err(last_gai_error(s));
-    }
-
-    // Collect all the results we found
-    let mut addrs = Vec::new();
-    let mut rp = res;
-    while !rp.is_null() {
-        unsafe {
-            let addr = try!(sockaddr_to_addr(mem::transmute((*rp).ai_addr),
-                                             (*rp).ai_addrlen as usize));
-            addrs.push(addrinfo::Info {
-                address: addr,
-                family: (*rp).ai_family as usize,
-                socktype: None,
-                protocol: None,
-                flags: (*rp).ai_flags as usize
-            });
-
-            rp = (*rp).ai_next as *mut libc::addrinfo;
-        }
-    }
-
-    unsafe { freeaddrinfo(res); }
-
-    Ok(addrs)
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// get_address_name
-////////////////////////////////////////////////////////////////////////////////
-
-extern "system" {
-    fn getnameinfo(sa: *const libc::sockaddr, salen: libc::socklen_t,
-        host: *mut c_char, hostlen: libc::size_t,
-        serv: *mut c_char, servlen: libc::size_t,
-        flags: c_int) -> c_int;
-}
-
-const NI_MAXHOST: usize = 1025;
-
-pub fn get_address_name(addr: IpAddr) -> Result<String, IoError> {
-    let addr = SocketAddr{ip: addr, port: 0};
-
-    let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
-    let len = addr_to_sockaddr(addr, &mut storage);
-
-    let mut hostbuf = [0 as c_char; NI_MAXHOST];
-
-    let res = unsafe {
-        getnameinfo(&storage as *const _ as *const libc::sockaddr, len,
-            hostbuf.as_mut_ptr(), NI_MAXHOST as libc::size_t,
-            ptr::null_mut(), 0,
-            0)
-    };
-
-    if res != 0 {
-        return Err(last_gai_error(res));
-    }
-
-    unsafe {
-        let data = CStr::from_ptr(hostbuf.as_ptr());
-        Ok(str::from_utf8(data.to_bytes()).unwrap().to_string())
-    }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Timeout helpers
-//
-// The read/write functions below are the helpers for reading/writing a socket
-// with a possible deadline specified. This is generally viewed as a timed out
-// I/O operation.
-//
-// From the application's perspective, timeouts apply to the I/O object, not to
-// the underlying file descriptor (it's one timeout per object). This means that
-// we can't use the SO_RCVTIMEO and corresponding send timeout option.
-//
-// The next idea to implement timeouts would be to use nonblocking I/O. An
-// invocation of select() would wait (with a timeout) for a socket to be ready.
-// Once its ready, we can perform the operation. Note that the operation *must*
-// be nonblocking, even though select() says the socket is ready. This is
-// because some other thread could have come and stolen our data (handles can be
-// cloned).
-//
-// To implement nonblocking I/O, the first option we have is to use the
-// O_NONBLOCK flag. Remember though that this is a global setting, affecting all
-// I/O objects, so this was initially viewed as unwise.
-//
-// It turns out that there's this nifty MSG_DONTWAIT flag which can be passed to
-// send/recv, but the niftiness wears off once you realize it only works well on
-// Linux [1] [2]. This means that it's pretty easy to get a nonblocking
-// operation on Linux (no flag fiddling, no affecting other objects), but not on
-// other platforms.
-//
-// To work around this constraint on other platforms, we end up using the
-// original strategy of flipping the O_NONBLOCK flag. As mentioned before, this
-// could cause other objects' blocking operations to suddenly become
-// nonblocking. To get around this, a "blocking operation" which returns EAGAIN
-// falls back to using the same code path as nonblocking operations, but with an
-// infinite timeout (select + send/recv). This helps emulate blocking
-// reads/writes despite the underlying descriptor being nonblocking, as well as
-// optimizing the fast path of just hitting one syscall in the good case.
-//
-// As a final caveat, this implementation uses a mutex so only one thread is
-// doing a nonblocking operation at at time. This is the operation that comes
-// after the select() (at which point we think the socket is ready). This is
-// done for sanity to ensure that the state of the O_NONBLOCK flag is what we
-// expect (wouldn't want someone turning it on when it should be off!). All
-// operations performed in the lock are *nonblocking* to avoid holding the mutex
-// forever.
-//
-// So, in summary, Linux uses MSG_DONTWAIT and doesn't need mutexes, everyone
-// else uses O_NONBLOCK and mutexes with some trickery to make sure blocking
-// reads/writes are still blocking.
-//
-// Fun, fun!
-//
-// [1] http://twistedmatrix.com/pipermail/twisted-commits/2012-April/034692.html
-// [2] http://stackoverflow.com/questions/19819198/does-send-msg-dontwait
-
-pub fn read<T, L, R>(fd: sock_t, deadline: u64, mut lock: L, mut read: R) -> IoResult<usize> where
-    L: FnMut() -> T,
-    R: FnMut(bool) -> libc::c_int,
-{
-    let mut ret = -1;
-    if deadline == 0 {
-        ret = retry(|| read(false));
-    }
-
-    if deadline != 0 || (ret == -1 && wouldblock()) {
-        let deadline = match deadline {
-            0 => None,
-            n => Some(n),
-        };
-        loop {
-            // With a timeout, first we wait for the socket to become
-            // readable using select(), specifying the relevant timeout for
-            // our previously set deadline.
-            try!(await(&[fd], deadline, Readable));
-
-            // At this point, we're still within the timeout, and we've
-            // determined that the socket is readable (as returned by
-            // select). We must still read the socket in *nonblocking* mode
-            // because some other thread could come steal our data. If we
-            // fail to read some data, we retry (hence the outer loop) and
-            // wait for the socket to become readable again.
-            let _guard = lock();
-            match retry(|| read(deadline.is_some())) {
-                -1 if wouldblock() => {}
-                -1 => return Err(last_net_error()),
-               n => { ret = n; break }
-            }
-        }
-    }
-
-    match ret {
-        0 => Err(sys_common::eof()),
-        n if n < 0 => Err(last_net_error()),
-        n => Ok(n as usize)
-    }
-}
-
-pub fn write<T, L, W>(fd: sock_t,
-                      deadline: u64,
-                      buf: &[u8],
-                      write_everything: bool,
-                      mut lock: L,
-                      mut write: W) -> IoResult<usize> where
-    L: FnMut() -> T,
-    W: FnMut(bool, *const u8, usize) -> i64,
-{
-    let mut ret = -1;
-    let mut written = 0;
-    if deadline == 0 {
-        if write_everything {
-            ret = keep_going(buf, |inner, len| {
-                written = buf.len() - len;
-                write(false, inner, len)
-            });
-        } else {
-            ret = retry(|| { write(false, buf.as_ptr(), buf.len()) });
-            if ret > 0 { written = ret as usize; }
-        }
-    }
-
-    if deadline != 0 || (ret == -1 && wouldblock()) {
-        let deadline = match deadline {
-            0 => None,
-            n => Some(n),
-        };
-        while written < buf.len() && (write_everything || written == 0) {
-            // As with read(), first wait for the socket to be ready for
-            // the I/O operation.
-            match await(&[fd], deadline, Writable) {
-                Err(ref e) if e.kind == old_io::EndOfFile && written > 0 => {
-                    assert!(deadline.is_some());
-                    return Err(short_write(written, "short write"))
-                }
-                Err(e) => return Err(e),
-                Ok(()) => {}
-            }
-
-            // Also as with read(), we use MSG_DONTWAIT to guard ourselves
-            // against unforeseen circumstances.
-            let _guard = lock();
-            let ptr = buf[written..].as_ptr();
-            let len = buf.len() - written;
-            match retry(|| write(deadline.is_some(), ptr, len)) {
-                -1 if wouldblock() => {}
-                -1 => return Err(last_net_error()),
-                n => { written += n as usize; }
-            }
-        }
-        ret = 0;
-    }
-    if ret < 0 {
-        Err(last_net_error())
-    } else {
-        Ok(written)
-    }
-}
-
-// See http://developerweb.net/viewtopic.php?id=3196 for where this is
-// derived from.
-pub fn connect_timeout(fd: sock_t,
-                       addrp: *const libc::sockaddr,
-                       len: libc::socklen_t,
-                       timeout_ms: u64) -> IoResult<()> {
-    #[cfg(unix)]    use libc::EINPROGRESS as INPROGRESS;
-    #[cfg(windows)] use libc::WSAEINPROGRESS as INPROGRESS;
-    #[cfg(unix)]    use libc::EWOULDBLOCK as WOULDBLOCK;
-    #[cfg(windows)] use libc::WSAEWOULDBLOCK as WOULDBLOCK;
-
-    // Make sure the call to connect() doesn't block
-    set_nonblocking(fd, true);
-
-    let ret = match unsafe { libc::connect(fd, addrp, len) } {
-        // If the connection is in progress, then we need to wait for it to
-        // finish (with a timeout). The current strategy for doing this is
-        // to use select() with a timeout.
-        -1 if os::errno() as isize == INPROGRESS as isize ||
-              os::errno() as isize == WOULDBLOCK as isize => {
-            let mut set: c::fd_set = unsafe { mem::zeroed() };
-            c::fd_set(&mut set, fd);
-            match await(fd, &mut set, timeout_ms) {
-                0 => Err(timeout("connection timed out")),
-                -1 => Err(last_net_error()),
-                _ => {
-                    let err: libc::c_int = try!(
-                        getsockopt(fd, libc::SOL_SOCKET, libc::SO_ERROR));
-                    if err == 0 {
-                        Ok(())
-                    } else {
-                        Err(decode_error_detailed(err))
-                    }
-                }
-            }
-        }
-
-        -1 => Err(last_net_error()),
-        _ => Ok(()),
-    };
-
-    // be sure to turn blocking I/O back on
-    set_nonblocking(fd, false);
-    return ret;
-
-    #[cfg(unix)]
-    fn await(fd: sock_t, set: &mut c::fd_set, timeout: u64) -> libc::c_int {
-        let start = timer::now();
-        retry(|| unsafe {
-            // Recalculate the timeout each iteration (it is generally
-            // undefined what the value of the 'tv' is after select
-            // returns EINTR).
-            let mut tv = ms_to_timeval(timeout - (timer::now() - start));
-            c::select(fd + 1, ptr::null_mut(), set as *mut _,
-                      ptr::null_mut(), &mut tv)
-        })
-    }
-    #[cfg(windows)]
-    fn await(_fd: sock_t, set: &mut c::fd_set, timeout: u64) -> libc::c_int {
-        let mut tv = ms_to_timeval(timeout);
-        unsafe { c::select(1, ptr::null_mut(), set, ptr::null_mut(), &mut tv) }
-    }
-}
-
-pub fn await(fds: &[sock_t], deadline: Option<u64>,
-             status: SocketStatus) -> IoResult<()> {
-    let mut set: c::fd_set = unsafe { mem::zeroed() };
-    let mut max = 0;
-    for &fd in fds {
-        c::fd_set(&mut set, fd);
-        max = cmp::max(max, fd + 1);
-    }
-    if cfg!(windows) {
-        max = fds.len() as sock_t;
-    }
-
-    let (read, write) = match status {
-        Readable => (&mut set as *mut _, ptr::null_mut()),
-        Writable => (ptr::null_mut(), &mut set as *mut _),
-    };
-    let mut tv: libc::timeval = unsafe { mem::zeroed() };
-
-    match retry(|| {
-        let now = timer::now();
-        let tvp = match deadline {
-            None => ptr::null_mut(),
-            Some(deadline) => {
-                // If we're past the deadline, then pass a 0 timeout to
-                // select() so we can poll the status
-                let ms = if deadline < now {0} else {deadline - now};
-                tv = ms_to_timeval(ms);
-                &mut tv as *mut _
-            }
-        };
-        let r = unsafe {
-            c::select(max as libc::c_int, read, write, ptr::null_mut(), tvp)
-        };
-        r
-    }) {
-        -1 => Err(last_net_error()),
-        0 => Err(timeout("timed out")),
-        _ => Ok(()),
-    }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Basic socket representation
-////////////////////////////////////////////////////////////////////////////////
-
-struct Inner {
-    fd: sock_t,
-
-    // Unused on Linux, where this lock is not necessary.
-    #[allow(dead_code)]
-    lock: Mutex<()>,
-}
-
-impl Inner {
-    fn new(fd: sock_t) -> Inner {
-        Inner { fd: fd, lock: Mutex::new(()) }
-    }
-}
-
-impl Drop for Inner {
-    fn drop(&mut self) { unsafe { close_sock(self.fd); } }
-}
-
-#[cfg(not(target_os = "linux"))]
-pub struct Guard<'a> {
-    pub fd: sock_t,
-    pub guard: MutexGuard<'a, ()>,
-}
-
-#[cfg(not(target_os = "linux"))]
-#[unsafe_destructor]
-impl<'a> Drop for Guard<'a> {
-    fn drop(&mut self) {
-        set_nonblocking(self.fd, false);
-    }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// TCP streams
-////////////////////////////////////////////////////////////////////////////////
-
-pub struct TcpStream {
-    inner: Arc<Inner>,
-    read_deadline: u64,
-    write_deadline: u64,
-}
-
-impl TcpStream {
-    pub fn connect(addr: SocketAddr, timeout: Option<u64>) -> IoResult<TcpStream> {
-        sys::init_net();
-
-        let fd = try!(socket(addr, libc::SOCK_STREAM));
-        let ret = TcpStream::new(fd);
-
-        let mut storage = unsafe { mem::zeroed() };
-        let len = addr_to_sockaddr(addr, &mut storage);
-        let addrp = &storage as *const _ as *const libc::sockaddr;
-
-        match timeout {
-            Some(timeout) => {
-                try!(connect_timeout(fd, addrp, len, timeout));
-                Ok(ret)
-            },
-            None => {
-                match retry(|| unsafe { libc::connect(fd, addrp, len) }) {
-                    -1 => Err(last_error()),
-                    _ => Ok(ret),
-                }
-            }
-        }
-    }
-
-    pub fn new(fd: sock_t) -> TcpStream {
-        TcpStream {
-            inner: Arc::new(Inner::new(fd)),
-            read_deadline: 0,
-            write_deadline: 0,
-        }
-    }
-
-    pub fn fd(&self) -> sock_t { self.inner.fd }
-
-    pub fn set_nodelay(&mut self, nodelay: bool) -> IoResult<()> {
-        setsockopt(self.fd(), libc::IPPROTO_TCP, libc::TCP_NODELAY,
-                   nodelay as libc::c_int)
-    }
-
-    pub fn set_keepalive(&mut self, seconds: Option<usize>) -> IoResult<()> {
-        let ret = setsockopt(self.fd(), libc::SOL_SOCKET, libc::SO_KEEPALIVE,
-                             seconds.is_some() as libc::c_int);
-        match seconds {
-            Some(n) => ret.and_then(|()| self.set_tcp_keepalive(n)),
-            None => ret,
-        }
-    }
-
-    #[cfg(any(target_os = "macos", target_os = "ios"))]
-    fn set_tcp_keepalive(&mut self, seconds: usize) -> IoResult<()> {
-        setsockopt(self.fd(), libc::IPPROTO_TCP, libc::TCP_KEEPALIVE,
-                   seconds as libc::c_int)
-    }
-    #[cfg(any(target_os = "freebsd",
-              target_os = "dragonfly"))]
-    fn set_tcp_keepalive(&mut self, seconds: usize) -> IoResult<()> {
-        setsockopt(self.fd(), libc::IPPROTO_TCP, libc::TCP_KEEPIDLE,
-                   seconds as libc::c_int)
-    }
-    #[cfg(target_os = "openbsd")]
-    fn set_tcp_keepalive(&mut self, seconds: usize) -> IoResult<()> {
-        setsockopt(self.fd(), libc::IPPROTO_TCP, libc::SO_KEEPALIVE,
-                   seconds as libc::c_int)
-    }
-    #[cfg(not(any(target_os = "macos",
-                  target_os = "ios",
-                  target_os = "freebsd",
-                  target_os = "dragonfly",
-                  target_os = "openbsd")))]
-    fn set_tcp_keepalive(&mut self, _seconds: usize) -> IoResult<()> {
-        Ok(())
-    }
-
-    #[cfg(target_os = "linux")]
-    fn lock_nonblocking(&self) {}
-
-    #[cfg(not(target_os = "linux"))]
-    fn lock_nonblocking<'a>(&'a self) -> Guard<'a> {
-        let ret = Guard {
-            fd: self.fd(),
-            guard: self.inner.lock.lock().unwrap(),
-        };
-        set_nonblocking(self.fd(), true);
-        ret
-    }
-
-    pub fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
-        let fd = self.fd();
-        let dolock = || self.lock_nonblocking();
-        let doread = |nb| unsafe {
-            let flags = if nb {c::MSG_DONTWAIT} else {0};
-            libc::recv(fd,
-                       buf.as_mut_ptr() as *mut libc::c_void,
-                       buf.len() as wrlen,
-                       flags) as libc::c_int
-        };
-        read(fd, self.read_deadline, dolock, doread)
-    }
-
-    pub fn write(&mut self, buf: &[u8]) -> IoResult<()> {
-        let fd = self.fd();
-        let dolock = || self.lock_nonblocking();
-        let dowrite = |nb: bool, buf: *const u8, len: usize| unsafe {
-            let flags = if nb {c::MSG_DONTWAIT} else {0};
-            libc::send(fd,
-                       buf as *const _,
-                       len as wrlen,
-                       flags) as i64
-        };
-        write(fd, self.write_deadline, buf, true, dolock, dowrite).map(|_| ())
-    }
-    pub fn peer_name(&mut self) -> IoResult<SocketAddr> {
-        sockname(self.fd(), libc::getpeername)
-    }
-
-    pub fn close_write(&mut self) -> IoResult<()> {
-        super::mkerr_libc(unsafe { libc::shutdown(self.fd(), libc::SHUT_WR) })
-    }
-    pub fn close_read(&mut self) -> IoResult<()> {
-        super::mkerr_libc(unsafe { libc::shutdown(self.fd(), libc::SHUT_RD) })
-    }
-
-    pub fn set_timeout(&mut self, timeout: Option<u64>) {
-        let deadline = timeout.map(|a| timer::now() + a).unwrap_or(0);
-        self.read_deadline = deadline;
-        self.write_deadline = deadline;
-    }
-    pub fn set_read_timeout(&mut self, timeout: Option<u64>) {
-        self.read_deadline = timeout.map(|a| timer::now() + a).unwrap_or(0);
-    }
-    pub fn set_write_timeout(&mut self, timeout: Option<u64>) {
-        self.write_deadline = timeout.map(|a| timer::now() + a).unwrap_or(0);
-    }
-
-    pub fn socket_name(&mut self) -> IoResult<SocketAddr> {
-        sockname(self.fd(), libc::getsockname)
-    }
-}
-
-impl Clone for TcpStream {
-    fn clone(&self) -> TcpStream {
-        TcpStream {
-            inner: self.inner.clone(),
-            read_deadline: 0,
-            write_deadline: 0,
-        }
-    }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// UDP
-////////////////////////////////////////////////////////////////////////////////
-
-pub struct UdpSocket {
-    inner: Arc<Inner>,
-    read_deadline: u64,
-    write_deadline: u64,
-}
-
-impl UdpSocket {
-    pub fn bind(addr: SocketAddr) -> IoResult<UdpSocket> {
-        sys::init_net();
-
-        let fd = try!(socket(addr, libc::SOCK_DGRAM));
-        let ret = UdpSocket {
-            inner: Arc::new(Inner::new(fd)),
-            read_deadline: 0,
-            write_deadline: 0,
-        };
-
-        let mut storage = unsafe { mem::zeroed() };
-        let len = addr_to_sockaddr(addr, &mut storage);
-        let addrp = &storage as *const _ as *const libc::sockaddr;
-
-        match unsafe { libc::bind(fd, addrp, len) } {
-            -1 => Err(last_error()),
-            _ => Ok(ret),
-        }
-    }
-
-    pub fn fd(&self) -> sock_t { self.inner.fd }
-
-    pub fn set_broadcast(&mut self, on: bool) -> IoResult<()> {
-        setsockopt(self.fd(), libc::SOL_SOCKET, libc::SO_BROADCAST,
-                   on as libc::c_int)
-    }
-
-    pub fn set_multicast_loop(&mut self, on: bool) -> IoResult<()> {
-        setsockopt(self.fd(), libc::IPPROTO_IP, libc::IP_MULTICAST_LOOP,
-                   on as libc::c_int)
-    }
-
-    pub fn set_membership(&mut self, addr: IpAddr, opt: libc::c_int) -> IoResult<()> {
-        match ip_to_inaddr(addr) {
-            In4Addr(addr) => {
-                let mreq = libc::ip_mreq {
-                    imr_multiaddr: addr,
-                    // interface == INADDR_ANY
-                    imr_interface: libc::in_addr { s_addr: 0x0 },
-                };
-                setsockopt(self.fd(), libc::IPPROTO_IP, opt, mreq)
-            }
-            In6Addr(addr) => {
-                let mreq = libc::ip6_mreq {
-                    ipv6mr_multiaddr: addr,
-                    ipv6mr_interface: 0,
-                };
-                setsockopt(self.fd(), libc::IPPROTO_IPV6, opt, mreq)
-            }
-        }
-    }
-
-    #[cfg(target_os = "linux")]
-    fn lock_nonblocking(&self) {}
-
-    #[cfg(not(target_os = "linux"))]
-    fn lock_nonblocking<'a>(&'a self) -> Guard<'a> {
-        let ret = Guard {
-            fd: self.fd(),
-            guard: self.inner.lock.lock().unwrap(),
-        };
-        set_nonblocking(self.fd(), true);
-        ret
-    }
-
-    pub fn socket_name(&mut self) -> IoResult<SocketAddr> {
-        sockname(self.fd(), libc::getsockname)
-    }
-
-    pub fn recv_from(&mut self, buf: &mut [u8]) -> IoResult<(usize, SocketAddr)> {
-        let fd = self.fd();
-        let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
-        let storagep = &mut storage as *mut _ as *mut libc::sockaddr;
-        let mut addrlen: libc::socklen_t =
-                mem::size_of::<libc::sockaddr_storage>() as libc::socklen_t;
-
-        let dolock = || self.lock_nonblocking();
-        let n = try!(read(fd, self.read_deadline, dolock, |nb| unsafe {
-            let flags = if nb {c::MSG_DONTWAIT} else {0};
-            libc::recvfrom(fd,
-                           buf.as_mut_ptr() as *mut libc::c_void,
-                           buf.len() as msglen_t,
-                           flags,
-                           storagep,
-                           &mut addrlen) as libc::c_int
-        }));
-        Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize).unwrap()))
-    }
-
-    pub fn send_to(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()> {
-        let mut storage = unsafe { mem::zeroed() };
-        let dstlen = addr_to_sockaddr(dst, &mut storage);
-        let dstp = &storage as *const _ as *const libc::sockaddr;
-
-        let fd = self.fd();
-        let dolock = || self.lock_nonblocking();
-        let dowrite = |nb, buf: *const u8, len: usize| unsafe {
-            let flags = if nb {c::MSG_DONTWAIT} else {0};
-            libc::sendto(fd,
-                         buf as *const libc::c_void,
-                         len as msglen_t,
-                         flags,
-                         dstp,
-                         dstlen) as i64
-        };
-
-        let n = try!(write(fd, self.write_deadline, buf, false, dolock, dowrite));
-        assert!(n == buf.len(), "UDP packet not completely written.");
-        Ok(())
-    }
-
-    pub fn join_multicast(&mut self, multi: IpAddr) -> IoResult<()> {
-        match multi {
-            Ipv4Addr(..) => {
-                self.set_membership(multi, libc::IP_ADD_MEMBERSHIP)
-            }
-            Ipv6Addr(..) => {
-                self.set_membership(multi, libc::IPV6_ADD_MEMBERSHIP)
-            }
-        }
-    }
-    pub fn leave_multicast(&mut self, multi: IpAddr) -> IoResult<()> {
-        match multi {
-            Ipv4Addr(..) => {
-                self.set_membership(multi, libc::IP_DROP_MEMBERSHIP)
-            }
-            Ipv6Addr(..) => {
-                self.set_membership(multi, libc::IPV6_DROP_MEMBERSHIP)
-            }
-        }
-    }
-
-    pub fn multicast_time_to_live(&mut self, ttl: isize) -> IoResult<()> {
-        setsockopt(self.fd(), libc::IPPROTO_IP, libc::IP_MULTICAST_TTL,
-                   ttl as libc::c_int)
-    }
-    pub fn time_to_live(&mut self, ttl: isize) -> IoResult<()> {
-        setsockopt(self.fd(), libc::IPPROTO_IP, libc::IP_TTL, ttl as libc::c_int)
-    }
-
-    pub fn set_timeout(&mut self, timeout: Option<u64>) {
-        let deadline = timeout.map(|a| timer::now() + a).unwrap_or(0);
-        self.read_deadline = deadline;
-        self.write_deadline = deadline;
-    }
-    pub fn set_read_timeout(&mut self, timeout: Option<u64>) {
-        self.read_deadline = timeout.map(|a| timer::now() + a).unwrap_or(0);
-    }
-    pub fn set_write_timeout(&mut self, timeout: Option<u64>) {
-        self.write_deadline = timeout.map(|a| timer::now() + a).unwrap_or(0);
-    }
-}
-
-impl Clone for UdpSocket {
-    fn clone(&self) -> UdpSocket {
-        UdpSocket {
-            inner: self.inner.clone(),
-            read_deadline: 0,
-            write_deadline: 0,
-        }
-    }
-}
index 7d42d65d360f548db50943439b54c8908ffd6854..2b2c31d92edad45f151998aa7bc124fe26d3c644 100644 (file)
@@ -202,15 +202,19 @@ fn set_tcp_keepalive(&self, seconds: u32) -> io::Result<()> {
         setsockopt(&self.inner, libc::IPPROTO_TCP, libc::TCP_KEEPALIVE,
                    seconds as c_int)
     }
-    #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
+    #[cfg(any(target_os = "freebsd",
+              target_os = "dragonfly",
+              target_os = "linux"))]
     fn set_tcp_keepalive(&self, seconds: u32) -> io::Result<()> {
         setsockopt(&self.inner, libc::IPPROTO_TCP, libc::TCP_KEEPIDLE,
                    seconds as c_int)
     }
+
     #[cfg(not(any(target_os = "macos",
                   target_os = "ios",
                   target_os = "freebsd",
-                  target_os = "dragonfly")))]
+                  target_os = "dragonfly",
+                  target_os = "linux")))]
     fn set_tcp_keepalive(&self, _seconds: u32) -> io::Result<()> {
         Ok(())
     }
index b35063c0e234126757410e5d75e97b79f39ca385..00238500c3a85ae77b83230edd26fb3e8e89da5d 100644 (file)
@@ -151,7 +151,7 @@ fn drop(&mut self) {
 
 
 #[cfg(test)]
-mod test {
+mod tests {
     use prelude::v1::*;
     use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
     use cell::RefCell;
index 1845b6266ed8d1aa405ad7581278205ef5a30546..d19ef11c01fc7855f84d36c8f275f2cf2645d257 100644 (file)
 
 use prelude::v1::*;
 
-use usize;
+use alloc::boxed::FnBox;
 use libc;
-use thunk::Thunk;
-use sys_common::stack;
 use sys::stack_overflow;
+use sys_common::stack;
+use usize;
 
-// This is the starting point of rust os threads. The first thing we do
-// is make sure that we don't trigger __morestack (also why this has a
-// no_stack_check annotation), and then we extract the main function
-// and invoke it.
 #[no_stack_check]
-pub fn start_thread(main: *mut libc::c_void) {
-    unsafe {
-        stack::record_os_managed_stack_bounds(0, usize::MAX);
-        let _handler = stack_overflow::Handler::new();
-        let main: Box<Thunk> = Box::from_raw(main as *mut Thunk);
-        main();
-    }
+pub unsafe fn start_thread(main: *mut libc::c_void) {
+    // First ensure that we don't trigger __morestack (also why this has a
+    // no_stack_check annotation).
+    stack::record_os_managed_stack_bounds(0, usize::MAX);
+
+    // Next, set up our stack overflow handler which may get triggered if we run
+    // out of stack.
+    let _handler = stack_overflow::Handler::new();
+
+    // Finally, let's run some code.
+    Box::from_raw(main as *mut Box<FnBox()>)()
 }
index aa035a1843725147034c11c64f51f35985058c88..56a952e6a7ef6e0d291e34c74cd853507917b7b0 100644 (file)
 use cmp;
 use fmt;
 use hash::{Hash, Hasher};
-use iter::{FromIterator, IntoIterator};
+use iter::FromIterator;
 use mem;
-#[allow(deprecated)] // Int
-use num::Int;
 use ops;
 use slice;
 use str;
index 90dfebc4c454c7735808255c52a5994e08452f34..ed6382e000ac90278a0c2e5b852e4c3cd154a2e2 100644 (file)
@@ -17,7 +17,6 @@
 use sys::time;
 use sys::sync as ffi;
 use time::Duration;
-use num::{Int, NumCast};
 
 pub struct Condvar { inner: UnsafeCell<ffi::pthread_cond_t> }
 
@@ -70,8 +69,8 @@ pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
         let r = ffi::gettimeofday(&mut sys_now, ptr::null_mut());
         debug_assert_eq!(r, 0);
 
-        let seconds = NumCast::from(dur.num_seconds());
-        let timeout = match seconds.and_then(|s| sys_now.tv_sec.checked_add(s)) {
+        let seconds = dur.num_seconds() as libc::time_t;
+        let timeout = match sys_now.tv_sec.checked_add(seconds) {
             Some(sec) => {
                 libc::timespec {
                     tv_sec: sec,
@@ -81,7 +80,7 @@ pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
             }
             None => {
                 libc::timespec {
-                    tv_sec: Int::max_value(),
+                    tv_sec: <libc::time_t>::max_value(),
                     tv_nsec: 1_000_000_000 - 1,
                 }
             }
index 032fd33b1d348589d29fd706f8971cfbb7301f5c..66aaf26b09b72e1ff58b82002e463b7110732160 100644 (file)
@@ -189,8 +189,12 @@ fn as_bytes(&self) -> &[u8] {
 #[unstable(feature = "fs_ext",
            reason = "may want a more useful mode abstraction")]
 pub mod fs {
+    use sys;
     use sys_common::{FromInner, AsInner, AsInnerMut};
     use fs::{Permissions, OpenOptions};
+    use path::Path;
+    use convert::AsRef;
+    use io;
 
     /// Unix-specific extensions to `Permissions`
     pub trait PermissionsExt {
@@ -220,6 +224,37 @@ fn mode(&mut self, mode: i32) -> &mut OpenOptions {
             self.as_inner_mut().mode(mode); self
         }
     }
+
+    /// Creates a new symbolic link on the filesystem.
+    ///
+    /// The `dst` path will be a symbolic link pointing to the `src` path.
+    ///
+    /// # Note
+    ///
+    /// On Windows, you must specify whether a symbolic link points to a file
+    /// or directory.  Use `os::windows::fs::symlink_file` to create a
+    /// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
+    /// symbolic link to a directory.  Additionally, the process must have
+    /// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
+    /// symbolic link.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(fs_ext)]
+    /// use std::os::unix::fs;
+    ///
+    /// # fn foo() -> std::io::Result<()> {
+    /// try!(fs::symlink("a.txt", "b.txt"));
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
+    {
+        sys::fs2::symlink(src.as_ref(), dst.as_ref())
+    }
+
 }
 
 ////////////////////////////////////////////////////////////////////////////////
index ac121f1c82e09ddedade920cbea8f2e6a8300935..8eb84b26f22f2f33d604b380cd57732b20f2664d 100644 (file)
@@ -13,6 +13,7 @@
 use os::unix::prelude::*;
 
 use ffi::{CString, CStr, OsString, OsStr};
+use fmt;
 use io::{self, Error, SeekFrom};
 use libc::{self, c_int, size_t, off_t, c_char, mode_t};
 use mem;
@@ -294,6 +295,54 @@ fn from_inner(fd: c_int) -> File {
     }
 }
 
+impl fmt::Debug for File {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        #[cfg(target_os = "linux")]
+        fn get_path(fd: c_int) -> Option<PathBuf> {
+            use string::ToString;
+            let mut p = PathBuf::from("/proc/self/fd");
+            p.push(&fd.to_string());
+            readlink(&p).ok()
+        }
+
+        #[cfg(not(target_os = "linux"))]
+        fn get_path(_fd: c_int) -> Option<PathBuf> {
+            // FIXME(#24570): implement this for other Unix platforms
+            None
+        }
+
+        #[cfg(target_os = "linux")]
+        fn get_mode(fd: c_int) -> Option<(bool, bool)> {
+            let mode = unsafe { libc::fcntl(fd, libc::F_GETFL) };
+            if mode == -1 {
+                return None;
+            }
+            match mode & libc::O_ACCMODE {
+                libc::O_RDONLY => Some((true, false)),
+                libc::O_RDWR => Some((true, true)),
+                libc::O_WRONLY => Some((false, true)),
+                _ => None
+            }
+        }
+
+        #[cfg(not(target_os = "linux"))]
+        fn get_mode(_fd: c_int) -> Option<(bool, bool)> {
+            // FIXME(#24570): implement this for other Unix platforms
+            None
+        }
+
+        let fd = self.0.raw();
+        let mut b = f.debug_struct("File").field("fd", &fd);
+        if let Some(path) = get_path(fd) {
+            b = b.field("path", &path);
+        }
+        if let Some((read, write)) = get_mode(fd) {
+            b = b.field("read", &read).field("write", &write);
+        }
+        b.finish()
+    }
+}
+
 pub fn mkdir(p: &Path) -> io::Result<()> {
     let p = try!(cstr(p));
     try!(cvt(unsafe { libc::mkdir(p.as_ptr(), 0o777) }));
diff --git a/src/libstd/sys/unix/helper_signal.rs b/src/libstd/sys/unix/helper_signal.rs
deleted file mode 100644 (file)
index fe0ede8..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(deprecated)]
-
-use libc;
-use sys::os;
-
-use sys::fs::FileDesc;
-
-pub type signal = libc::c_int;
-
-pub fn new() -> (signal, signal) {
-    let (a, b) = unsafe { os::pipe().unwrap() };
-    (a.unwrap(), b.unwrap())
-}
-
-pub fn signal(fd: libc::c_int) {
-    FileDesc::new(fd, false).write(&[0]).unwrap();
-}
-
-pub fn close(fd: libc::c_int) {
-    let _fd = FileDesc::new(fd, true);
-}
index a8a6219f3981deb2cdf952973448016be13bf301..d99753a6a4c800c47b0237b23fa2b5dfb328d652 100644 (file)
@@ -15,7 +15,8 @@
 
 use io::{self, ErrorKind};
 use libc;
-use num::{Int, SignedInt};
+use num::One;
+use ops::Neg;
 
 pub mod backtrace;
 pub mod c;
@@ -63,23 +64,8 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
     }
 }
 
-#[inline]
-#[allow(deprecated)]
-pub fn retry<T, F> (mut f: F) -> T where
-    T: SignedInt,
-    F: FnMut() -> T,
-{
-    let one: T = Int::one();
-    loop {
-        let n = f();
-        if n == -one && os::errno() == libc::EINTR as i32 { }
-        else { return n }
-    }
-}
-
-#[allow(deprecated)]
-pub fn cvt<T: SignedInt>(t: T) -> io::Result<T> {
-    let one: T = Int::one();
+pub fn cvt<T: One + PartialEq + Neg<Output=T>>(t: T) -> io::Result<T> {
+    let one: T = T::one();
     if t == -one {
         Err(io::Error::last_os_error())
     } else {
@@ -89,7 +75,7 @@ pub fn cvt<T: SignedInt>(t: T) -> io::Result<T> {
 
 #[allow(deprecated)]
 pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
-    where T: SignedInt, F: FnMut() -> T
+    where T: One + PartialEq + Neg<Output=T>, F: FnMut() -> T
 {
     loop {
         match cvt(f()) {
index caa7b4eb29c7bb558ac65a50d6ec1433a81f6a14..4e7c4d241f53209b2f0acbf99aef8a467d2d7ea8 100644 (file)
@@ -19,7 +19,7 @@
 use libc::{self, pid_t, c_void, c_int, gid_t, uid_t};
 use ptr;
 use sys::pipe2::AnonPipe;
-use sys::{self, retry, c, cvt};
+use sys::{self, c, cvt, cvt_r};
 use sys::fs2::{File, OpenOptions};
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -273,7 +273,7 @@ fn fail(output: &mut AnonPipe) -> ! {
                     }
                 }
             };
-            retry(|| libc::dup2(fd.raw(), dst)) != -1
+            cvt_r(|| libc::dup2(fd.raw(), dst)).is_ok()
         };
 
         if !setup(in_fd, libc::STDIN_FILENO) { fail(&mut output) }
@@ -317,19 +317,19 @@ fn fail(output: &mut AnonPipe) -> ! {
 
     pub fn wait(&self) -> io::Result<ExitStatus> {
         let mut status = 0 as c_int;
-        try!(cvt(retry(|| unsafe { c::waitpid(self.pid, &mut status, 0) })));
+        try!(cvt_r(|| unsafe { c::waitpid(self.pid, &mut status, 0) }));
         Ok(translate_status(status))
     }
 
     pub fn try_wait(&self) -> Option<ExitStatus> {
         let mut status = 0 as c_int;
-        match retry(|| unsafe {
+        match cvt_r(|| unsafe {
             c::waitpid(self.pid, &mut status, c::WNOHANG)
         }) {
-            n if n == self.pid => Some(translate_status(status)),
-            0 => None,
-            n => panic!("unknown waitpid error `{}`: {}", n,
-                       io::Error::last_os_error()),
+            Ok(0) => None,
+            Ok(n) if n == self.pid => Some(translate_status(status)),
+            Ok(n) => panic!("unkown pid: {}", n),
+            Err(e) => panic!("unknown waitpid error: {}", e),
         }
     }
 }
index 73d6cd73621ad6ed39be674112663e01a2ff8bb5..281ac37e671152845bc3caaddf807f9e4a533133 100644 (file)
@@ -10,8 +10,9 @@
 
 #![allow(dead_code)]
 
-use core::prelude::*;
+use prelude::v1::*;
 
+use alloc::boxed::FnBox;
 use cmp;
 use ffi::CString;
 use io;
 use mem;
 use ptr;
 use sys::os;
-use thunk::Thunk;
 use time::Duration;
 
 use sys_common::stack::RED_ZONE;
 use sys_common::thread::*;
 
-pub type rust_thread = libc::pthread_t;
+pub struct Thread {
+    id: libc::pthread_t,
+}
+
+// Some platforms may have pthread_t as a pointer in which case we still want
+// a thread to be Send/Sync
+unsafe impl Send for Thread {}
+unsafe impl Sync for Thread {}
+
+impl Thread {
+    pub unsafe fn new<'a>(stack: usize, p: Box<FnBox() + 'a>)
+                          -> io::Result<Thread> {
+        let p = box p;
+        let mut native: libc::pthread_t = mem::zeroed();
+        let mut attr: libc::pthread_attr_t = mem::zeroed();
+        assert_eq!(pthread_attr_init(&mut attr), 0);
+
+        // Reserve room for the red zone, the runtime's stack of last resort.
+        let stack_size = cmp::max(stack, RED_ZONE + min_stack_size(&attr));
+        match pthread_attr_setstacksize(&mut attr, stack_size as libc::size_t) {
+            0 => {}
+            n => {
+                assert_eq!(n, libc::EINVAL);
+                // EINVAL means |stack_size| is either too small or not a
+                // multiple of the system page size.  Because it's definitely
+                // >= PTHREAD_STACK_MIN, it must be an alignment issue.
+                // Round up to the nearest page and try again.
+                let page_size = os::page_size();
+                let stack_size = (stack_size + page_size - 1) &
+                                 (-(page_size as isize - 1) as usize - 1);
+                let stack_size = stack_size as libc::size_t;
+                assert_eq!(pthread_attr_setstacksize(&mut attr, stack_size), 0);
+            }
+        };
+
+        let ret = pthread_create(&mut native, &attr, thread_start,
+                                 &*p as *const _ as *mut _);
+        assert_eq!(pthread_attr_destroy(&mut attr), 0);
+
+        return if ret != 0 {
+            Err(io::Error::from_raw_os_error(ret))
+        } else {
+            mem::forget(p); // ownership passed to pthread_create
+            Ok(Thread { id: native })
+        };
+
+        #[no_stack_check]
+        extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
+            unsafe { start_thread(main); }
+            0 as *mut _
+        }
+    }
+
+    pub fn yield_now() {
+        let ret = unsafe { sched_yield() };
+        debug_assert_eq!(ret, 0);
+    }
+
+    #[cfg(any(target_os = "linux", target_os = "android"))]
+    pub fn set_name(name: &str) {
+        // pthread wrapper only appeared in glibc 2.12, so we use syscall
+        // directly.
+        extern {
+            fn prctl(option: libc::c_int, arg2: libc::c_ulong,
+                     arg3: libc::c_ulong, arg4: libc::c_ulong,
+                     arg5: libc::c_ulong) -> libc::c_int;
+        }
+        const PR_SET_NAME: libc::c_int = 15;
+        let cname = CString::new(name).unwrap_or_else(|_| {
+            panic!("thread name may not contain interior null bytes")
+        });
+        unsafe {
+            prctl(PR_SET_NAME, cname.as_ptr() as libc::c_ulong, 0, 0, 0);
+        }
+    }
+
+    #[cfg(any(target_os = "freebsd",
+              target_os = "dragonfly",
+              target_os = "bitrig",
+              target_os = "openbsd"))]
+    pub fn set_name(name: &str) {
+        extern {
+            fn pthread_set_name_np(tid: libc::pthread_t,
+                                   name: *const libc::c_char);
+        }
+        let cname = CString::new(name).unwrap();
+        unsafe {
+            pthread_set_name_np(pthread_self(), cname.as_ptr());
+        }
+    }
+
+    #[cfg(any(target_os = "macos", target_os = "ios"))]
+    pub fn set_name(name: &str) {
+        extern {
+            fn pthread_setname_np(name: *const libc::c_char) -> libc::c_int;
+        }
+        let cname = CString::new(name).unwrap();
+        unsafe {
+            pthread_setname_np(cname.as_ptr());
+        }
+    }
+
+    pub fn sleep(dur: Duration) {
+        if dur < Duration::zero() {
+            return Thread::yield_now()
+        }
+        let seconds = dur.num_seconds();
+        let ns = dur - Duration::seconds(seconds);
+        let mut ts = libc::timespec {
+            tv_sec: seconds as libc::time_t,
+            tv_nsec: ns.num_nanoseconds().unwrap() as libc::c_long,
+        };
+
+        // If we're awoken with a signal then the return value will be -1 and
+        // nanosleep will fill in `ts` with the remaining time.
+        unsafe {
+            while libc::nanosleep(&ts, &mut ts) == -1 {
+                assert_eq!(os::errno(), libc::EINTR);
+            }
+        }
+    }
+
+    pub fn join(self) {
+        unsafe {
+            let ret = pthread_join(self.id, ptr::null_mut());
+            mem::forget(self);
+            debug_assert_eq!(ret, 0);
+        }
+    }
+}
+
+impl Drop for Thread {
+    fn drop(&mut self) {
+        let ret = unsafe { pthread_detach(self.id) };
+        debug_assert_eq!(ret, 0);
+    }
+}
 
 #[cfg(all(not(target_os = "linux"),
           not(target_os = "macos"),
@@ -183,128 +319,6 @@ fn pthread_attr_getstack(attr: *const libc::pthread_attr_t,
     }
 }
 
-pub unsafe fn create(stack: usize, p: Thunk) -> io::Result<rust_thread> {
-    let p = box p;
-    let mut native: libc::pthread_t = mem::zeroed();
-    let mut attr: libc::pthread_attr_t = mem::zeroed();
-    assert_eq!(pthread_attr_init(&mut attr), 0);
-
-    // Reserve room for the red zone, the runtime's stack of last resort.
-    let stack_size = cmp::max(stack, RED_ZONE + min_stack_size(&attr) as usize);
-    match pthread_attr_setstacksize(&mut attr, stack_size as libc::size_t) {
-        0 => {}
-        n => {
-            assert_eq!(n, libc::EINVAL);
-            // EINVAL means |stack_size| is either too small or not a
-            // multiple of the system page size.  Because it's definitely
-            // >= PTHREAD_STACK_MIN, it must be an alignment issue.
-            // Round up to the nearest page and try again.
-            let page_size = os::page_size();
-            let stack_size = (stack_size + page_size - 1) &
-                             (-(page_size as isize - 1) as usize - 1);
-            assert_eq!(pthread_attr_setstacksize(&mut attr,
-                                                 stack_size as libc::size_t), 0);
-        }
-    };
-
-    let ret = pthread_create(&mut native, &attr, thread_start,
-                             &*p as *const _ as *mut _);
-    assert_eq!(pthread_attr_destroy(&mut attr), 0);
-
-    return if ret != 0 {
-        Err(io::Error::from_raw_os_error(ret))
-    } else {
-        mem::forget(p); // ownership passed to pthread_create
-        Ok(native)
-    };
-
-    #[no_stack_check]
-    extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
-        start_thread(main);
-        0 as *mut _
-    }
-}
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-pub unsafe fn set_name(name: &str) {
-    // pthread wrapper only appeared in glibc 2.12, so we use syscall directly.
-    extern {
-        fn prctl(option: libc::c_int, arg2: libc::c_ulong, arg3: libc::c_ulong,
-                 arg4: libc::c_ulong, arg5: libc::c_ulong) -> libc::c_int;
-    }
-    const PR_SET_NAME: libc::c_int = 15;
-    let cname = CString::new(name).unwrap_or_else(|_| {
-        panic!("thread name may not contain interior null bytes")
-    });
-    prctl(PR_SET_NAME, cname.as_ptr() as libc::c_ulong, 0, 0, 0);
-}
-
-#[cfg(any(target_os = "freebsd",
-          target_os = "dragonfly",
-          target_os = "bitrig",
-          target_os = "openbsd"))]
-pub unsafe fn set_name(name: &str) {
-    extern {
-        fn pthread_set_name_np(tid: libc::pthread_t, name: *const libc::c_char);
-    }
-    let cname = CString::new(name).unwrap();
-    pthread_set_name_np(pthread_self(), cname.as_ptr());
-}
-
-#[cfg(any(target_os = "macos", target_os = "ios"))]
-pub unsafe fn set_name(name: &str) {
-    extern {
-        fn pthread_setname_np(name: *const libc::c_char) -> libc::c_int;
-    }
-    let cname = CString::new(name).unwrap();
-    pthread_setname_np(cname.as_ptr());
-}
-
-pub unsafe fn join(native: rust_thread) {
-    assert_eq!(pthread_join(native, ptr::null_mut()), 0);
-}
-
-pub unsafe fn detach(native: rust_thread) {
-    assert_eq!(pthread_detach(native), 0);
-}
-
-pub unsafe fn yield_now() {
-    assert_eq!(sched_yield(), 0);
-}
-
-pub fn sleep(dur: Duration) {
-    unsafe {
-        if dur < Duration::zero() {
-            return yield_now()
-        }
-        let seconds = dur.num_seconds();
-        let ns = dur - Duration::seconds(seconds);
-        let mut ts = libc::timespec {
-            tv_sec: seconds as libc::time_t,
-            tv_nsec: ns.num_nanoseconds().unwrap() as libc::c_long,
-        };
-        // If we're awoken with a signal then the return value will be -1 and
-        // nanosleep will fill in `ts` with the remaining time.
-        while dosleep(&mut ts) == -1 {
-            assert_eq!(os::errno(), libc::EINTR);
-        }
-    }
-
-    #[cfg(target_os = "linux")]
-    unsafe fn dosleep(ts: *mut libc::timespec) -> libc::c_int {
-        extern {
-            fn clock_nanosleep(clock_id: libc::c_int, flags: libc::c_int,
-                               request: *const libc::timespec,
-                               remain: *mut libc::timespec) -> libc::c_int;
-        }
-        clock_nanosleep(libc::CLOCK_MONOTONIC, 0, ts, ts)
-    }
-    #[cfg(not(target_os = "linux"))]
-    unsafe fn dosleep(ts: *mut libc::timespec) -> libc::c_int {
-        libc::nanosleep(ts, ts)
-    }
-}
-
 // glibc >= 2.15 has a __pthread_get_minstack() function that returns
 // PTHREAD_STACK_MIN plus however many bytes are needed for thread-local
 // storage.  We need that information to avoid blowing up when a small stack
@@ -319,7 +333,7 @@ unsafe fn dosleep(ts: *mut libc::timespec) -> libc::c_int {
 // but that caused Debian to detect an unnecessarily strict versioned
 // dependency on libc6 (#23628).
 #[cfg(target_os = "linux")]
-fn min_stack_size(attr: *const libc::pthread_attr_t) -> libc::size_t {
+fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
     use dynamic_lib::DynamicLibrary;
     use sync::{Once, ONCE_INIT};
 
@@ -337,16 +351,16 @@ fn min_stack_size(attr: *const libc::pthread_attr_t) -> libc::size_t {
     });
 
     match unsafe { __pthread_get_minstack } {
-        None => PTHREAD_STACK_MIN,
-        Some(f) => unsafe { f(attr) },
+        None => PTHREAD_STACK_MIN as usize,
+        Some(f) => unsafe { f(attr) as usize },
     }
 }
 
 // No point in looking up __pthread_get_minstack() on non-glibc
 // platforms.
 #[cfg(not(target_os = "linux"))]
-fn min_stack_size(_: *const libc::pthread_attr_t) -> libc::size_t {
-    PTHREAD_STACK_MIN
+fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
+    PTHREAD_STACK_MIN as usize
 }
 
 extern {
index 45f389f0aebf8bb369b0513bfb55115036c466f6..b07d063de45c992630cd76c61459b1c08ac7823e 100644 (file)
@@ -54,6 +54,8 @@
 pub const FSCTL_GET_REPARSE_POINT: libc::DWORD = 0x900a8;
 pub const IO_REPARSE_TAG_SYMLINK: libc::DWORD = 0xa000000c;
 
+pub const SYMBOLIC_LINK_FLAG_DIRECTORY: libc::DWORD = 0x1;
+
 // Note that these are not actually HANDLEs, just values to pass to GetStdHandle
 pub const STD_INPUT_HANDLE: libc::DWORD = -10i32 as libc::DWORD;
 pub const STD_OUTPUT_HANDLE: libc::DWORD = -11i32 as libc::DWORD;
@@ -469,6 +471,17 @@ pub fn CreatePipe(hReadPipe: libc::LPHANDLE,
                       hWritePipe: libc::LPHANDLE,
                       lpPipeAttributes: libc::LPSECURITY_ATTRIBUTES,
                       nSize: libc::DWORD) -> libc::BOOL;
+    pub fn CreateThread(lpThreadAttributes: libc::LPSECURITY_ATTRIBUTES,
+                        dwStackSize: libc::SIZE_T,
+                        lpStartAddress: extern "system" fn(*mut libc::c_void)
+                                                           -> libc::DWORD,
+                        lpParameter: libc::LPVOID,
+                        dwCreationFlags: libc::DWORD,
+                        lpThreadId: libc::LPDWORD) -> libc::HANDLE;
+    pub fn WaitForSingleObject(hHandle: libc::HANDLE,
+                               dwMilliseconds: libc::DWORD) -> libc::DWORD;
+    pub fn SwitchToThread() -> libc::BOOL;
+    pub fn Sleep(dwMilliseconds: libc::DWORD);
 }
 
 #[link(name = "userenv")]
index 90548dcefb4830b9fac6bee44095642f26f6ed52..dd747d202a04b7195692ee03112419e4a95def47 100644 (file)
@@ -191,7 +191,11 @@ fn encode_wide(&self) -> EncodeWide {
 #[unstable(feature = "fs_ext", reason = "may require more thought/methods")]
 pub mod fs {
     use fs::OpenOptions;
+    use sys;
     use sys_common::AsInnerMut;
+    use path::Path;
+    use convert::AsRef;
+    use io;
 
     /// Windows-specific extensions to `OpenOptions`
     pub trait OpenOptionsExt {
@@ -235,6 +239,52 @@ fn share_mode(&mut self, access: i32) -> &mut OpenOptions {
             self.as_inner_mut().share_mode(access); self
         }
     }
+
+    /// Creates a new file symbolic link on the filesystem.
+    ///
+    /// The `dst` path will be a file symbolic link pointing to the `src`
+    /// path.
+    ///
+    /// # Examples
+    ///
+    /// ```ignore
+    /// #![feature(fs_ext)]
+    /// use std::os::windows::fs;
+    ///
+    /// # fn foo() -> std::io::Result<()> {
+    /// try!(fs::symlink_file("a.txt", "b.txt"));
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q)
+                                                        -> io::Result<()>
+    {
+        sys::fs2::symlink_inner(src.as_ref(), dst.as_ref(), false)
+    }
+
+    /// Creates a new directory symlink on the filesystem.
+    ///
+    /// The `dst` path will be a directory symbolic link pointing to the `src`
+    /// path.
+    ///
+    /// # Examples
+    ///
+    /// ```ignore
+    /// #![feature(fs_ext)]
+    /// use std::os::windows::fs;
+    ///
+    /// # fn foo() -> std::io::Result<()> {
+    /// try!(fs::symlink_file("a", "b"));
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn symlink_dir<P: AsRef<Path>, Q: AsRef<Path>> (src: P, dst: Q)
+                                                        -> io::Result<()>
+    {
+        sys::fs2::symlink_inner(src.as_ref(), dst.as_ref(), true)
+    }
 }
 
 /// A prelude for conveniently writing platform-specific code.
index 9645c51ec0b2343f085b63c6135d9773a3828f60..5ac9a0ace5801ba08d6b914935d5bea27f72792b 100644 (file)
@@ -12,8 +12,8 @@
 use io::prelude::*;
 use os::windows::prelude::*;
 
-use default::Default;
-use ffi::{OsString, AsOsStr};
+use ffi::OsString;
+use fmt;
 use io::{self, Error, SeekFrom};
 use libc::{self, HANDLE};
 use mem;
@@ -271,6 +271,15 @@ fn from_inner(handle: libc::HANDLE) -> File {
     }
 }
 
+impl fmt::Debug for File {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        // FIXME(#24570): add more info here (e.g. path, mode)
+        f.debug_struct("File")
+            .field("handle", &self.handle.raw())
+            .finish()
+    }
+}
+
 pub fn to_utf16(s: &Path) -> Vec<u16> {
     s.as_os_str().encode_wide().chain(Some(0).into_iter()).collect()
 }
@@ -402,11 +411,16 @@ pub fn readlink(p: &Path) -> io::Result<PathBuf> {
 }
 
 pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
+    symlink_inner(src, dst, false)
+}
+
+pub fn symlink_inner(src: &Path, dst: &Path, dir: bool) -> io::Result<()> {
     use sys::c::compat::kernel32::CreateSymbolicLinkW;
     let src = to_utf16(src);
     let dst = to_utf16(dst);
+    let flags = if dir { c::SYMBOLIC_LINK_FLAG_DIRECTORY } else { 0 };
     try!(cvt(unsafe {
-        CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(), 0) as libc::BOOL
+        CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(), flags) as libc::BOOL
     }));
     Ok(())
 }
index 1171c6c068b12077b2ad92328cf035149266a189..5ae5f6f201bad0bcffb03d7f8e978544bb60ba52 100644 (file)
@@ -17,8 +17,7 @@
 use ffi::{OsStr, OsString};
 use io::{self, ErrorKind};
 use libc;
-#[allow(deprecated)]
-use num::Int;
+use num::Zero;
 use os::windows::ffi::{OsStrExt, OsStringExt};
 use path::PathBuf;
 
@@ -144,9 +143,8 @@ pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
     }
 }
 
-#[allow(deprecated)]
-fn cvt<I: Int>(i: I) -> io::Result<I> {
-    if i == Int::zero() {
+fn cvt<I: PartialEq + Zero>(i: I) -> io::Result<I> {
+    if i == I::zero() {
         Err(io::Error::last_os_error())
     } else {
         Ok(i)
index cbc3876dbb116d7971ed37cccdeaa2b32b3a6a9b..6bbcd968157aba084deecae84dbe9fad92a8456a 100644 (file)
@@ -15,8 +15,8 @@
 use libc::{self, c_int, c_void};
 use mem;
 use net::SocketAddr;
-#[allow(deprecated)]
-use num::{SignedInt, Int};
+use num::One;
+use ops::Neg;
 use rt;
 use sync::{Once, ONCE_INIT};
 use sys::c;
@@ -49,11 +49,8 @@ fn last_error() -> io::Error {
 /// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1)
 /// and if so, returns the last error from the Windows socket interface. . This
 /// function must be called before another call to the socket API is made.
-///
-/// FIXME: generics needed?
-#[allow(deprecated)]
-pub fn cvt<T: SignedInt>(t: T) -> io::Result<T> {
-    let one: T = Int::one();
+pub fn cvt<T: One + Neg<Output=T> + PartialEq>(t: T) -> io::Result<T> {
+    let one: T = T::one();
     if t == -one {
         Err(last_error())
     } else {
@@ -70,7 +67,9 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
 
 /// Provides the functionality of `cvt` for a closure.
 #[allow(deprecated)]
-pub fn cvt_r<T: SignedInt, F>(mut f: F) -> io::Result<T> where F: FnMut() -> T {
+pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
+    where F: FnMut() -> T, T: One + Neg<Output=T> + PartialEq
+{
     cvt(f())
 }
 
index 16c2a9125eaa711efabbcdb884ac827e6a1efe4e..5ddcf3d1ea2991f9f62ce90b436b2d6a3510b005 100644 (file)
@@ -140,7 +140,7 @@ pub fn spawn(cfg: &Command,
         // read the *child's* PATH if one is provided. See #15149 for more details.
         let program = cfg.env.as_ref().and_then(|env| {
             for (key, v) in env {
-                if OsStr::from_str("PATH") != &**key { continue }
+                if OsStr::new("PATH") != &**key { continue }
 
                 // Split the value and test each path to see if the
                 // program exists.
@@ -463,7 +463,7 @@ mod tests {
     fn test_make_command_line() {
         fn test_wrapper(prog: &str, args: &[&str]) -> String {
             String::from_utf16(
-                &make_command_line(OsStr::from_str(prog),
+                &make_command_line(OsStr::new(prog),
                                    &args.iter()
                                         .map(|a| OsString::from(a))
                                         .collect::<Vec<OsString>>())).unwrap()
index 98e4a737c7b178a8fcf0a02d7746752e5351ac23..797f45f8702e7d00a6fe8159e9aafd4dbadfad49 100644 (file)
 
 use prelude::v1::*;
 
+use alloc::boxed::FnBox;
 use cmp;
 use io;
-use libc::{self, c_void};
-use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES, SIZE_T, BOOL,
-                                   LPVOID, DWORD, LPDWORD, HANDLE};
+use libc::{self, c_void, DWORD};
 use mem;
 use ptr;
+use sys::c;
+use sys::handle::Handle;
 use sys_common::stack::RED_ZONE;
 use sys_common::thread::*;
-use thunk::Thunk;
 use time::Duration;
 
-pub type rust_thread = HANDLE;
-
-pub mod guard {
-    pub unsafe fn main() -> usize { 0 }
-    pub unsafe fn current() -> usize { 0 }
-    pub unsafe fn init() {}
+pub struct Thread {
+    handle: Handle
 }
 
-pub unsafe fn create(stack: usize, p: Thunk) -> io::Result<rust_thread> {
-    let p = box p;
-    // FIXME On UNIX, we guard against stack sizes that are too small but
-    // that's because pthreads enforces that stacks are at least
-    // PTHREAD_STACK_MIN bytes big.  Windows has no such lower limit, it's
-    // just that below a certain threshold you can't do anything useful.
-    // That threshold is application and architecture-specific, however.
-    // For now, the only requirement is that it's big enough to hold the
-    // red zone.  Round up to the next 64 kB because that's what the NT
-    // kernel does, might as well make it explicit.  With the current
-    // 20 kB red zone, that makes for a 64 kB minimum stack.
-    let stack_size = (cmp::max(stack, RED_ZONE) + 0xfffe) & (-0xfffe - 1);
-    let ret = CreateThread(ptr::null_mut(), stack_size as libc::size_t,
-                           thread_start, &*p as *const _ as *mut _,
-                           0, ptr::null_mut());
+impl Thread {
+    pub unsafe fn new<'a>(stack: usize, p: Box<FnBox() + 'a>)
+                          -> io::Result<Thread> {
+        let p = box p;
 
-    return if ret as usize == 0 {
-        Err(io::Error::last_os_error())
-    } else {
-        mem::forget(p); // ownership passed to CreateThread
-        Ok(ret)
-    };
+        // FIXME On UNIX, we guard against stack sizes that are too small but
+        // that's because pthreads enforces that stacks are at least
+        // PTHREAD_STACK_MIN bytes big.  Windows has no such lower limit, it's
+        // just that below a certain threshold you can't do anything useful.
+        // That threshold is application and architecture-specific, however.
+        // For now, the only requirement is that it's big enough to hold the
+        // red zone.  Round up to the next 64 kB because that's what the NT
+        // kernel does, might as well make it explicit.  With the current
+        // 20 kB red zone, that makes for a 64 kB minimum stack.
+        let stack_size = (cmp::max(stack, RED_ZONE) + 0xfffe) & (-0xfffe - 1);
+        let ret = c::CreateThread(ptr::null_mut(), stack_size as libc::size_t,
+                                  thread_start, &*p as *const _ as *mut _,
+                                  0, ptr::null_mut());
 
-    #[no_stack_check]
-    extern "system" fn thread_start(main: *mut libc::c_void) -> DWORD {
-        start_thread(main);
-        0
-    }
-}
+        return if ret as usize == 0 {
+            Err(io::Error::last_os_error())
+        } else {
+            mem::forget(p); // ownership passed to CreateThread
+            Ok(Thread { handle: Handle::new(ret) })
+        };
 
-pub unsafe fn set_name(_name: &str) {
-    // Windows threads are nameless
-    // The names in MSVC debugger are obtained using a "magic" exception,
-    // which requires a use of MS C++ extensions.
-    // See https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
-}
+        #[no_stack_check]
+        extern "system" fn thread_start(main: *mut libc::c_void) -> DWORD {
+            unsafe { start_thread(main); }
+            0
+        }
+    }
 
-pub unsafe fn join(native: rust_thread) {
-    use libc::consts::os::extra::INFINITE;
-    WaitForSingleObject(native, INFINITE);
-}
+    pub fn set_name(_name: &str) {
+        // Windows threads are nameless
+        // The names in MSVC debugger are obtained using a "magic" exception,
+        // which requires a use of MS C++ extensions.
+        // See https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
+    }
 
-pub unsafe fn detach(native: rust_thread) {
-    assert!(libc::CloseHandle(native) != 0);
-}
+    pub fn join(self) {
+        use libc::consts::os::extra::INFINITE;
+        unsafe { c::WaitForSingleObject(self.handle.raw(), INFINITE); }
+    }
 
-pub unsafe fn yield_now() {
-    // This function will return 0 if there are no other threads to execute,
-    // but this also means that the yield was useless so this isn't really a
-    // case that needs to be worried about.
-    SwitchToThread();
-}
+    pub fn yield_now() {
+        // This function will return 0 if there are no other threads to execute,
+        // but this also means that the yield was useless so this isn't really a
+        // case that needs to be worried about.
+        unsafe { c::SwitchToThread(); }
+    }
 
-pub fn sleep(dur: Duration) {
-    unsafe {
-        if dur < Duration::zero() {
-            return yield_now()
+    pub fn sleep(dur: Duration) {
+        unsafe {
+            if dur < Duration::zero() {
+                return Thread::yield_now()
+            }
+            let ms = dur.num_milliseconds();
+            // if we have a fractional number of milliseconds then add an extra
+            // millisecond to sleep for
+            let extra = dur - Duration::milliseconds(ms);
+            let ms = ms + if extra.is_zero() {0} else {1};
+            c::Sleep(ms as DWORD);
         }
-        let ms = dur.num_milliseconds();
-        // if we have a fractional number of milliseconds then add an extra
-        // millisecond to sleep for
-        let extra = dur - Duration::milliseconds(ms);
-        let ms = ms + if extra.is_zero() {0} else {1};
-        Sleep(ms as DWORD);
     }
 }
 
-#[allow(non_snake_case)]
-extern "system" {
-    fn CreateThread(lpThreadAttributes: LPSECURITY_ATTRIBUTES,
-                    dwStackSize: SIZE_T,
-                    lpStartAddress: extern "system" fn(*mut c_void) -> DWORD,
-                    lpParameter: LPVOID,
-                    dwCreationFlags: DWORD,
-                    lpThreadId: LPDWORD) -> HANDLE;
-    fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
-    fn SwitchToThread() -> BOOL;
-    fn Sleep(dwMilliseconds: DWORD);
+pub mod guard {
+    pub unsafe fn main() -> usize { 0 }
+    pub unsafe fn current() -> usize { 0 }
+    pub unsafe fn init() {}
 }
index 4fd0340f09ac0ef533feff7194203883603a11ab..9168a716d43801a4304287a81018c18bbb0c48ea 100644 (file)
 
 use prelude::v1::*;
 
+use alloc::boxed::FnBox;
 use any::Any;
 use cell::UnsafeCell;
 use fmt;
 use sync::{Mutex, Condvar, Arc};
 use sys::thread as imp;
 use sys_common::{stack, thread_info};
-use thunk::Thunk;
 use time::Duration;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -276,7 +276,9 @@ pub fn stack_size(mut self, size: usize) -> Builder {
     pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
         F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
     {
-        self.spawn_inner(Box::new(f)).map(|i| JoinHandle(i))
+        unsafe {
+            self.spawn_inner(Box::new(f)).map(JoinHandle)
+        }
     }
 
     /// Spawns a new child thread that must be joined within a given
@@ -299,12 +301,18 @@ pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
     pub fn scoped<'a, T, F>(self, f: F) -> io::Result<JoinGuard<'a, T>> where
         T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
     {
-        self.spawn_inner(Box::new(f)).map(|inner| {
-            JoinGuard { inner: inner, _marker: PhantomData }
-        })
+        unsafe {
+            self.spawn_inner(Box::new(f)).map(|inner| {
+                JoinGuard { inner: inner, _marker: PhantomData }
+            })
+        }
     }
 
-    fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> io::Result<JoinInner<T>> {
+    // NB: this function is unsafe as the lifetime parameter of the code to run
+    //     in the new thread is not tied into the return value, and the return
+    //     value must not outlast that lifetime.
+    unsafe fn spawn_inner<'a, T: Send>(self, f: Box<FnBox() -> T + Send + 'a>)
+                                       -> io::Result<JoinInner<T>> {
         let Builder { name, stack_size } = self;
 
         let stack_size = stack_size.unwrap_or(rt::min_stack());
@@ -312,8 +320,8 @@ fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> io::Result<JoinInner<T>> {
         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());
+        let my_packet = Arc::new(UnsafeCell::new(None));
+        let their_packet = my_packet.clone();
 
         // Spawning a new OS thread guarantees that __morestack will never get
         // triggered, but we must manually set up the actual stack bounds once
@@ -326,48 +334,27 @@ fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> io::Result<JoinInner<T>> {
             let addr = &something_around_the_top_of_the_stack as *const i32;
             let my_stack_top = addr as usize;
             let my_stack_bottom = my_stack_top - stack_size + 1024;
-            unsafe {
-                if let Some(name) = their_thread.name() {
-                    imp::set_name(name);
-                }
-                stack::record_os_managed_stack_bounds(my_stack_bottom,
-                                                      my_stack_top);
-                thread_info::set(imp::guard::current(), their_thread);
+            stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
+
+            if let Some(name) = their_thread.name() {
+                imp::Thread::set_name(name);
             }
+            thread_info::set(imp::guard::current(), their_thread);
 
-            let mut output: Option<T> = None;
+            let mut output = None;
             let try_result = {
                 let ptr = &mut output;
-
-                // There are two primary reasons that general try/catch is
-                // unsafe. The first is that we do not support nested
-                // try/catch. The fact that this is happening in a newly-spawned
-                // thread suffices. The second is that unwinding while unwinding
-                // is not defined.  We take care of that by having an
-                // 'unwinding' flag in the thread itself. For these reasons,
-                // this unsafety should be ok.
-                unsafe {
-                    unwind::try(move || {
-                        let f: Thunk<(), T> = f;
-                        let v: T = f();
-                        *ptr = Some(v)
-                    })
-                }
+                unwind::try(move || *ptr = Some(f()))
             };
-            unsafe {
-                *their_packet.0.get() = Some(match (output, try_result) {
-                    (Some(data), Ok(_)) => Ok(data),
-                    (None, Err(cause)) => Err(cause),
-                    _ => unreachable!()
-                });
-            }
+            *their_packet.get() = Some(try_result.map(|()| {
+                output.unwrap()
+            }));
         };
 
         Ok(JoinInner {
-            native: try!(unsafe { imp::create(stack_size, Box::new(main)) }),
+            native: Some(try!(imp::Thread::new(stack_size, Box::new(main)))),
             thread: my_thread,
-            packet: my_packet,
-            joined: false,
+            packet: Packet(my_packet),
         })
     }
 }
@@ -427,7 +414,7 @@ pub fn current() -> Thread {
 /// Cooperatively gives up a timeslice to the OS scheduler.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn yield_now() {
-    unsafe { imp::yield_now() }
+    imp::Thread::yield_now()
 }
 
 /// Determines whether the current thread is unwinding because of panic.
@@ -494,16 +481,7 @@ pub fn catch_panic<F, R>(f: F) -> Result<R>
 /// spurious wakeup.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn sleep_ms(ms: u32) {
-    imp::sleep(Duration::milliseconds(ms as i64))
-}
-
-/// Deprecated: use `sleep_ms` instead.
-#[unstable(feature = "thread_sleep",
-           reason = "recently added, needs an RFC, and `Duration` itself is \
-                     unstable")]
-#[deprecated(since = "1.0.0", reason = "use sleep_ms instead")]
-pub fn sleep(dur: Duration) {
-    imp::sleep(dur)
+    imp::Thread::sleep(Duration::milliseconds(ms as i64))
 }
 
 /// Blocks unless or until the current thread's token is made available (may wake spuriously).
@@ -546,13 +524,6 @@ pub fn park_timeout_ms(ms: u32) {
     *guard = false;
 }
 
-/// Deprecated: use `park_timeout_ms`
-#[unstable(feature = "std_misc", reason = "recently introduced, depends on Duration")]
-#[deprecated(since = "1.0.0", reason = "use park_timeout_ms instead")]
-pub fn park_timeout(duration: Duration) {
-    park_timeout_ms(duration.num_milliseconds() as u32)
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // Thread
 ////////////////////////////////////////////////////////////////////////////////
@@ -564,8 +535,6 @@ struct Inner {
     cvar: Condvar,
 }
 
-unsafe impl Sync for Inner {}
-
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 /// A handle to a thread.
@@ -626,24 +595,33 @@ fn new(name: Option<String>) -> Thread { Thread::new(name) }
 #[stable(feature = "rust1", since = "1.0.0")]
 pub type Result<T> = ::result::Result<T, Box<Any + Send + 'static>>;
 
+// This packet is used to communicate the return value between the child thread
+// and the parent thread. Memory is shared through the `Arc` within and there's
+// no need for a mutex here because synchronization happens with `join()` (the
+// parent thread never reads this packet until the child has exited).
+//
+// This packet itself is then stored into a `JoinInner` which in turns is placed
+// in `JoinHandle` and `JoinGuard`. Due to the usage of `UnsafeCell` we need to
+// manually worry about impls like Send and Sync. The type `T` should
+// already always be Send (otherwise the thread could not have been created) and
+// this type is inherently Sync because no methods take &self. Regardless,
+// however, we add inheriting impls for Send/Sync to this type to ensure it's
+// Send/Sync and that future modifications will still appropriately classify it.
 struct Packet<T>(Arc<UnsafeCell<Option<Result<T>>>>);
 
-unsafe impl<T:Send> Send for Packet<T> {}
-unsafe impl<T> Sync for Packet<T> {}
+unsafe impl<T: Send> Send for Packet<T> {}
+unsafe impl<T: Sync> Sync for Packet<T> {}
 
 /// Inner representation for JoinHandle and JoinGuard
 struct JoinInner<T> {
-    native: imp::rust_thread,
+    native: Option<imp::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;
+        self.native.take().unwrap().join();
         unsafe {
             (*self.packet.0.get()).take().unwrap()
         }
@@ -678,16 +656,6 @@ pub fn join(mut self) -> Result<T> {
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-#[unsafe_destructor]
-impl<T> Drop for JoinHandle<T> {
-    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.
@@ -736,20 +704,25 @@ pub fn join(mut self) -> T {
            reason = "memory unsafe if destructor is avoided, see #24292")]
 impl<'a, T: Send + 'a> Drop for JoinGuard<'a, T> {
     fn drop(&mut self) {
-        if !self.inner.joined {
-            if self.inner.join().is_err() {
-                panic!("child thread {:?} panicked", self.thread());
-            }
+        if self.inner.native.is_some() && self.inner.join().is_err() {
+            panic!("child thread {:?} panicked", self.thread());
         }
     }
 }
 
+fn _assert_sync_and_send() {
+    fn _assert_both<T: Send + Sync>() {}
+    _assert_both::<JoinHandle<()>>();
+    _assert_both::<JoinGuard<()>>();
+    _assert_both::<Thread>();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Tests
 ////////////////////////////////////////////////////////////////////////////////
 
 #[cfg(test)]
-mod test {
+mod tests {
     use prelude::v1::*;
 
     use any::Any;
index 9b79b483b28cfbc77b27c21ee4ac2f9395ca1ebf..636a0dd697a2bb6003f0a15d87e9f1e2f09bfdd2 100644 (file)
 
 #![unstable(feature = "std_misc")]
 
+use prelude::v1::*;
+
 use {fmt, i64};
-use ops::{Add, Sub, Mul, Div, Neg, FnOnce};
-use option::Option;
-use option::Option::{Some, None};
-#[allow(deprecated)] // Int
-use num::Int;
-use result::Result::Ok;
+use ops::{Add, Sub, Mul, Div, Neg};
 
 /// The number of nanoseconds in a microsecond.
 const NANOS_PER_MICRO: i32 = 1000;
index 41b70889c9f276f96735a7d473b56960bb8f64dd..26c1597f3a01a6ea687988e801e847d63286c80a 100644 (file)
@@ -43,8 +43,6 @@
 //! Using traits implemented for tuples:
 //!
 //! ```
-//! use std::default::Default;
-//!
 //! let a = (1, 2);
 //! let b = (3, 4);
 //! assert!(a != b);
index 26463df1871225f08e193d3ed15c3cf925a9e620..94dc36b16ba0f53b0282a7410f29db059c95ee50 100644 (file)
@@ -66,8 +66,6 @@
 use ptr::P;
 
 use std::fmt;
-#[allow(deprecated)]
-use std::num::Int;
 use std::rc::Rc;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
@@ -1142,16 +1140,24 @@ pub enum Sign {
 }
 
 impl Sign {
-    #[allow(deprecated)] // Int
-    pub fn new<T:Int>(n: T) -> Sign {
-        if n < Int::zero() {
-            Minus
-        } else {
-            Plus
-        }
+    pub fn new<T: IntSign>(n: T) -> Sign {
+        n.sign()
     }
 }
 
+pub trait IntSign {
+    fn sign(&self) -> Sign;
+}
+macro_rules! doit {
+    ($($t:ident)*) => ($(impl IntSign for $t {
+        #[allow(unused_comparisons)]
+        fn sign(&self) -> Sign {
+            if *self < 0 {Minus} else {Plus}
+        }
+    })*)
+}
+doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
+
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
 pub enum LitIntType {
     SignedIntLit(IntTy, Sign),
@@ -1863,7 +1869,7 @@ pub struct MacroDef {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use serialize;
     use super::*;
 
index 0ad75c5ec8cbcddba43adf03c83500b18e06f297..720b2095a908af8274da5de043e156d8e589d88d 100644 (file)
@@ -238,7 +238,7 @@ pub fn name_to_dummy_lifetime(name: Name) -> Lifetime {
 pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: Option<&Ty>) -> Ident {
     let mut pretty = match ty {
         Some(t) => pprust::ty_to_string(t),
-        None => String::from_str("..")
+        None => String::from("..")
     };
 
     match *trait_ref {
@@ -632,7 +632,7 @@ pub fn lit_is_str(lit: &Lit) -> bool {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use ast::*;
     use super::*;
 
index a0bde8f6c525e9dfadedaff51974a3ebd2f6091c..5e0cb647c8b41072ff2242d9c4dc9fcc7208f454 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15679
 
 //! The CodeMap tracks all the source code used within a single crate, mapping
 //! from integer byte positions to the original source code location. Each bit
 pub use self::MacroFormat::*;
 
 use std::cell::RefCell;
-use std::num::ToPrimitive;
 use std::ops::{Add, Sub};
 use std::rc::Rc;
 
 use std::fmt;
 
-use libc::c_uint;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
 
@@ -289,13 +285,12 @@ pub struct ExpnInfo {
 pub const COMMAND_LINE_EXPN: ExpnId = ExpnId(!1);
 
 impl ExpnId {
-    pub fn from_llvm_cookie(cookie: c_uint) -> ExpnId {
-        ExpnId(cookie)
+    pub fn from_u32(id: u32) -> ExpnId {
+        ExpnId(id)
     }
 
-    pub fn to_llvm_cookie(self) -> i32 {
-        let ExpnId(cookie) = self;
-        cookie as i32
+    pub fn into_u32(self) -> u32 {
+        self.0
     }
 }
 
@@ -559,9 +554,9 @@ pub fn new_filemap(&self, filename: FileName, src: String) -> Rc<FileMap> {
         // FIXME #12884: no efficient/safe way to remove from the start of a string
         // and reuse the allocation.
         let mut src = if src.starts_with("\u{feff}") {
-            String::from_str(&src[3..])
+            String::from(&src[3..])
         } else {
-            String::from_str(&src[..])
+            String::from(&src[..])
         };
 
         // Append '\n' in case it's not already there.
@@ -596,8 +591,8 @@ pub fn new_filemap(&self, filename: FileName, src: String) -> Rc<FileMap> {
     pub fn new_imported_filemap(&self,
                                 filename: FileName,
                                 source_len: usize,
-                                file_local_lines: Vec<BytePos>,
-                                file_local_multibyte_chars: Vec<MultiByteChar>)
+                                mut file_local_lines: Vec<BytePos>,
+                                mut file_local_multibyte_chars: Vec<MultiByteChar>)
                                 -> Rc<FileMap> {
         let mut files = self.files.borrow_mut();
         let start_pos = match files.last() {
@@ -608,19 +603,21 @@ pub fn new_imported_filemap(&self,
         let end_pos = Pos::from_usize(start_pos + source_len);
         let start_pos = Pos::from_usize(start_pos);
 
-        let lines = file_local_lines.map_in_place(|pos| pos + start_pos);
-        let multibyte_chars = file_local_multibyte_chars.map_in_place(|mbc| MultiByteChar {
-            pos: mbc.pos + start_pos,
-            bytes: mbc.bytes
-        });
+        for pos in &mut file_local_lines {
+            *pos = *pos + start_pos;
+        }
+
+        for mbc in &mut file_local_multibyte_chars {
+            mbc.pos = mbc.pos + start_pos;
+        }
 
         let filemap = Rc::new(FileMap {
             name: filename,
             src: None,
             start_pos: start_pos,
             end_pos: end_pos,
-            lines: RefCell::new(lines),
-            multibyte_chars: RefCell::new(multibyte_chars),
+            lines: RefCell::new(file_local_lines),
+            multibyte_chars: RefCell::new(file_local_multibyte_chars),
         });
 
         files.push(filemap.clone());
@@ -864,7 +861,11 @@ fn lookup_pos(&self, pos: BytePos) -> Loc {
     pub fn record_expansion(&self, expn_info: ExpnInfo) -> ExpnId {
         let mut expansions = self.expansions.borrow_mut();
         expansions.push(expn_info);
-        ExpnId(expansions.len().to_u32().expect("too many ExpnInfo's!") - 1)
+        let len = expansions.len();
+        if len > u32::max_value() as usize {
+            panic!("too many ExpnInfo's!");
+        }
+        ExpnId(len as u32 - 1)
     }
 
     pub fn with_expn_info<T, F>(&self, id: ExpnId, f: F) -> T where
@@ -948,7 +949,7 @@ pub struct MalformedCodemapPositions {
 //
 
 #[cfg(test)]
-mod test {
+mod tests {
     use super::*;
     use std::rc::Rc;
 
index 489a7721d7ba770a117add88db41d25b25353fe8..366806bc19b4962882552eb27725679acb9d1177 100644 (file)
@@ -284,8 +284,15 @@ fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
             return fold::noop_fold_attribute(attr, self);
         }
 
-        let (cfg, mi) = match attr.meta_item_list() {
-            Some([ref cfg, ref mi]) => (cfg, mi),
+        let attr_list = match attr.meta_item_list() {
+            Some(attr_list) => attr_list,
+            None => {
+                self.diag.span_err(attr.span, "expected `#[cfg_attr(<cfg pattern>, <attr>)]`");
+                return None;
+            }
+        };
+        let (cfg, mi) = match (attr_list.len(), attr_list.get(0), attr_list.get(1)) {
+            (2, Some(cfg), Some(mi)) => (cfg, mi),
             _ => {
                 self.diag.span_err(attr.span, "expected `#[cfg_attr(<cfg pattern>, <attr>)]`");
                 return None;
index 620a8927134bae4e36d84db37b5661e00a3bcb2f..a7453636c445c6c6d7d546e022d5f06b68760dee 100644 (file)
@@ -644,7 +644,7 @@ fn highlight_lines(err: &mut EmitterWriter,
             }
 
             try!(write!(&mut err.dst, "{}", s));
-            let mut s = String::from_str("^");
+            let mut s = String::from("^");
             let count = match lastc {
                 // Most terminals have a tab stop every eight columns by default
                 '\t' => 8 - col%8,
index 6fcf39f0b174bf5ec4b57626740b707fc4fe9029..6de4edafa0bf5cafaadd4457d54aeca6d6093bcd 100644 (file)
@@ -54,8 +54,8 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
                                    span: Span,
                                    token_tree: &[TokenTree])
                                    -> Box<MacResult+'cx> {
-    let code = match token_tree {
-        [ast::TtToken(_, token::Ident(code, _))] => code,
+    let code = match (token_tree.len(), token_tree.get(0)) {
+        (1, Some(&ast::TtToken(_, token::Ident(code, _)))) => code,
         _ => unreachable!()
     };
     with_used_diagnostics(|diagnostics| {
@@ -77,20 +77,25 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
             ));
         }
     });
-    MacEager::expr(quote_expr!(ecx, ()))
+    MacEager::expr(ecx.expr_tuple(span, Vec::new()))
 }
 
 pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
                                        span: Span,
                                        token_tree: &[TokenTree])
                                        -> Box<MacResult+'cx> {
-    let (code, description) = match token_tree {
-        [ast::TtToken(_, token::Ident(ref code, _))] => {
+    let (code, description) = match (
+        token_tree.len(),
+        token_tree.get(0),
+        token_tree.get(1),
+        token_tree.get(2)
+    ) {
+        (1, Some(&ast::TtToken(_, token::Ident(ref code, _))), None, None) => {
             (code, None)
         },
-        [ast::TtToken(_, token::Ident(ref code, _)),
-         ast::TtToken(_, token::Comma),
-         ast::TtToken(_, token::Literal(token::StrRaw(description, _), None))] => {
+        (3, Some(&ast::TtToken(_, token::Ident(ref code, _))),
+            Some(&ast::TtToken(_, token::Comma)),
+            Some(&ast::TtToken(_, token::Literal(token::StrRaw(description, _), None)))) => {
             (code, Some(description))
         }
         _ => unreachable!()
@@ -123,15 +128,23 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
     let sym = Ident::new(token::gensym(&(
         "__register_diagnostic_".to_string() + &token::get_ident(*code)
     )));
-    MacEager::items(SmallVector::many(vec![quote_item!(ecx, mod $sym {}).unwrap()]))
+    MacEager::items(SmallVector::many(vec![
+        ecx.item_mod(
+            span,
+            span,
+            sym,
+            Vec::new(),
+            Vec::new()
+        )
+    ]))
 }
 
 pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
                                           span: Span,
                                           token_tree: &[TokenTree])
                                           -> Box<MacResult+'cx> {
-    let name = match token_tree {
-        [ast::TtToken(_, token::Ident(ref name, _))] => name,
+    let name = match (token_tree.len(), token_tree.get(0)) {
+        (1, Some(&ast::TtToken(_, token::Ident(ref name, _)))) => name,
         _ => unreachable!()
     };
 
@@ -148,7 +161,37 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
             (descriptions.len(), ecx.expr_vec(span, descriptions))
         });
 
-    MacEager::items(SmallVector::many(vec![quote_item!(ecx,
-        pub static $name: [(&'static str, &'static str); $count] = $expr;
-    ).unwrap()]))
+    let static_ = ecx.lifetime(span, ecx.name_of("'static"));
+    let ty_str = ecx.ty_rptr(
+        span,
+        ecx.ty_ident(span, ecx.ident_of("str")),
+        Some(static_),
+        ast::MutImmutable,
+    );
+
+    let ty = ecx.ty(
+        span,
+        ast::TyFixedLengthVec(
+            ecx.ty(
+                span,
+                ast::TyTup(vec![ty_str.clone(), ty_str])
+            ),
+            ecx.expr_usize(span, count),
+        ),
+    );
+
+    MacEager::items(SmallVector::many(vec![
+        P(ast::Item {
+            ident: name.clone(),
+            attrs: Vec::new(),
+            id: ast::DUMMY_NODE_ID,
+            node: ast::ItemStatic(
+                ty,
+                ast::MutImmutable,
+                expr,
+            ),
+            vis: ast::Public,
+            span: span,
+        })
+    ]))
 }
index 55afac1a1de43da428d6c9c18ddbedaab577d659..50ab430f148ca7ece5e5f4468913e78b6ab95586 100644 (file)
@@ -262,10 +262,10 @@ pub struct MacEager {
         impl MacEager {
             $(
                 pub fn $fld(v: $t) -> Box<MacResult> {
-                    box MacEager {
+                    Box::new(MacEager {
                         $fld: Some(v),
                         ..Default::default()
-                    }
+                    })
                 }
             )*
         }
@@ -331,7 +331,7 @@ impl DummyResult {
     /// Use this as a return value after hitting any errors and
     /// calling `span_err`.
     pub fn any(sp: Span) -> Box<MacResult+'static> {
-        box DummyResult { expr_only: false, span: sp }
+        Box::new(DummyResult { expr_only: false, span: sp })
     }
 
     /// Create a default MacResult that can only be an expression.
@@ -340,7 +340,7 @@ pub fn any(sp: Span) -> Box<MacResult+'static> {
     /// if an error is encountered internally, the user will receive
     /// an error that they also used it in the wrong place.
     pub fn expr(sp: Span) -> Box<MacResult+'static> {
-        box DummyResult { expr_only: true, span: sp }
+        Box::new(DummyResult { expr_only: true, span: sp })
     }
 
     /// A plain dummy expression.
index b2a4ef1dafbc8ee7415e499e562122684b72cfd3..94cc0d9c493f21dc0abfe6e09b1082138fb26f27 100644 (file)
@@ -106,8 +106,8 @@ pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
             // }
 
             let new = {
-                let other_f = match other_fs {
-                    [ref o_f] => o_f,
+                let other_f = match (other_fs.len(), other_fs.get(0)) {
+                    (1, Some(o_f)) => o_f,
                     _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`"),
                 };
 
index f02e5ee14126d57c77ff5eff8e83920a07d7d97d..61eb81c6755e2663e37baf05b61c1804dd5f6902 100644 (file)
@@ -29,8 +29,8 @@ fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
         cs_fold(
             true,  // use foldl
             |cx, span, subexpr, self_f, other_fs| {
-                let other_f = match other_fs {
-                    [ref o_f] => o_f,
+                let other_f = match (other_fs.len(), other_fs.get(0)) {
+                    (1, Some(o_f)) => o_f,
                     _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialEq)`")
                 };
 
@@ -46,8 +46,8 @@ fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
         cs_fold(
             true,  // use foldl
             |cx, span, subexpr, self_f, other_fs| {
-                let other_f = match other_fs {
-                    [ref o_f] => o_f,
+                let other_f = match (other_fs.len(), other_fs.get(0)) {
+                    (1, Some(o_f)) => o_f,
                     _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialEq)`")
                 };
 
index 9da2db25f7ea2d94e1741b88397848e39f221414..dbb779decace27715f6eab03ff5ac36299a91a58 100644 (file)
@@ -47,7 +47,7 @@ macro_rules! md {
     let ordering_ty = Literal(path_std!(cx, core::cmp::Ordering));
     let ret_ty = Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                     None,
-                                    vec![box ordering_ty],
+                                    vec![Box::new(ordering_ty)],
                                     true));
 
     let inline = cx.meta_word(span, InternedString::new("inline"));
@@ -150,8 +150,8 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
             // }
 
             let new = {
-                let other_f = match other_fs {
-                    [ref o_f] => o_f,
+                let other_f = match (other_fs.len(), other_fs.get(0)) {
+                    (1, Some(o_f)) => o_f,
                     _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`"),
                 };
 
@@ -208,8 +208,8 @@ fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt,
             get use the binops to avoid auto-deref dereferencing too many
             layers of pointers, if the type includes pointers.
             */
-            let other_f = match other_fs {
-                [ref o_f] => o_f,
+            let other_f = match (other_fs.len(), other_fs.get(0)) {
+                (1, Some(o_f)) => o_f,
                 _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
             };
 
index 14f0004101c818cfd31cb420f357633284739271..0b31f06f87d0676c19615d079c461f87ef4fe30f 100644 (file)
@@ -68,14 +68,14 @@ fn expand_deriving_decodable_imp(cx: &mut ExtCtxt,
                                     vec!(), true))))
                 },
                 explicit_self: None,
-                args: vec!(Ptr(box Literal(Path::new_local("__D")),
+                args: vec!(Ptr(Box::new(Literal(Path::new_local("__D"))),
                             Borrowed(None, MutMutable))),
                 ret_ty: Literal(Path::new_(
                     pathvec_std!(cx, core::result::Result),
                     None,
-                    vec!(box Self_, box Literal(Path::new_(
+                    vec!(Box::new(Self_), Box::new(Literal(Path::new_(
                         vec!["__D", "Error"], None, vec![], false
-                    ))),
+                    )))),
                     true
                 )),
                 attributes: Vec::new(),
index 175f986f6dda89cc8d0e79a6814c6c5a92b58acd..92944d649332f04617e1dea75f8cd75d10687090 100644 (file)
@@ -144,14 +144,14 @@ fn expand_deriving_encodable_imp(cx: &mut ExtCtxt,
                                     vec!(), true))))
                 },
                 explicit_self: borrowed_explicit_self(),
-                args: vec!(Ptr(box Literal(Path::new_local("__S")),
+                args: vec!(Ptr(Box::new(Literal(Path::new_local("__S"))),
                             Borrowed(None, MutMutable))),
                 ret_ty: Literal(Path::new_(
                     pathvec_std!(cx, core::result::Result),
                     None,
-                    vec!(box Tuple(Vec::new()), box Literal(Path::new_(
+                    vec!(Box::new(Tuple(Vec::new())), Box::new(Literal(Path::new_(
                         vec!["__S", "Error"], None, vec![], false
-                    ))),
+                    )))),
                     true
                 )),
                 attributes: Vec::new(),
index 4685b4b295417f6f18111c253812e6df17334f56..4c05cd973ff6f3252751ee7c2a96e644010b9840 100644 (file)
@@ -807,7 +807,7 @@ fn split_self_nonself_args(&self,
                 Self_ if nonstatic  => {
                     self_args.push(arg_expr);
                 }
-                Ptr(box Self_, _) if nonstatic => {
+                Ptr(ref ty, _) if **ty == Self_ && nonstatic => {
                     self_args.push(cx.expr_deref(trait_.span, arg_expr))
                 }
                 _ => {
@@ -1103,7 +1103,7 @@ fn build_enum_match_tuple(
                     subpats.push(p);
                     idents
                 };
-                for self_arg_name in self_arg_names.tail() {
+                for self_arg_name in &self_arg_names[1..] {
                     let (p, idents) = mk_self_pat(cx, &self_arg_name[..]);
                     subpats.push(p);
                     self_pats_idents.push(idents);
index ec13b86a8ae2eb0fff69558347e72486d617ad62..9e8e68c0b8cce1e49c80434939b7bc42dba67984 100644 (file)
@@ -24,7 +24,7 @@
 use ptr::P;
 
 /// The types of pointers
-#[derive(Clone)]
+#[derive(Clone, Eq, PartialEq)]
 pub enum PtrTy<'a> {
     /// &'lifetime mut
     Borrowed(Option<&'a str>, ast::Mutability),
@@ -34,7 +34,7 @@ pub enum PtrTy<'a> {
 
 /// A path, e.g. `::std::option::Option::<i32>` (global). Has support
 /// for type parameters and a lifetime.
-#[derive(Clone)]
+#[derive(Clone, Eq, PartialEq)]
 pub struct Path<'a> {
     pub path: Vec<&'a str> ,
     pub lifetime: Option<&'a str>,
@@ -85,7 +85,7 @@ pub fn to_path(&self,
 }
 
 /// A type. Supports pointers, Self, and literals
-#[derive(Clone)]
+#[derive(Clone, Eq, PartialEq)]
 pub enum Ty<'a> {
     Self_,
     /// &/Box/ Ty
@@ -109,7 +109,7 @@ pub fn borrowed_explicit_self<'r>() -> Option<Option<PtrTy<'r>>> {
 }
 
 pub fn borrowed_self<'r>() -> Ty<'r> {
-    borrowed(box Self_)
+    borrowed(Box::new(Self_))
 }
 
 pub fn nil_ty<'r>() -> Ty<'r> {
index 2f6734b1a1433d6bbe9a3a34e4e93cca566fc05e..b9835eda791f7f004589c170bc7b600d76eb1fab 100644 (file)
@@ -41,7 +41,7 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
                                   vec![path_std!(cx, core::hash::Hasher)])],
                 },
                 explicit_self: borrowed_explicit_self(),
-                args: vec!(Ptr(box Literal(arg), Borrowed(None, MutMutable))),
+                args: vec!(Ptr(Box::new(Literal(arg)), Borrowed(None, MutMutable))),
                 ret_ty: nil_ty(),
                 attributes: vec![],
                 combine_substructure: combine_substructure(Box::new(|a, b, c| {
@@ -56,8 +56,8 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
 }
 
 fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
-    let state_expr = match substr.nonself_args {
-        [ref state_expr] => state_expr,
+    let state_expr = match (substr.nonself_args.len(), substr.nonself_args.get(0)) {
+        (1, Some(o_f)) => o_f,
         _ => cx.span_bug(trait_span, "incorrect number of arguments in `derive(Hash)`")
     };
     let call_hash = |span, thing_expr| {
index 625f759fcedf8e12eed0a4bb5a79ec43bc11247c..a972cfe135511d99f6961edc9bc6fc37ad5a4dd7 100644 (file)
@@ -40,7 +40,7 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                 args: vec!(Literal(path_local!(i64))),
                 ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                            None,
-                                           vec!(box Self_),
+                                           vec!(Box::new(Self_)),
                                            true)),
                 // #[inline] liable to cause code-bloat
                 attributes: attrs.clone(),
@@ -55,7 +55,7 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                 args: vec!(Literal(path_local!(u64))),
                 ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                            None,
-                                           vec!(box Self_),
+                                           vec!(Box::new(Self_)),
                                            true)),
                 // #[inline] liable to cause code-bloat
                 attributes: attrs,
@@ -71,8 +71,8 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
 }
 
 fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
-    let n = match substr.nonself_args {
-        [ref n] => n,
+    let n = match (substr.nonself_args.len(), substr.nonself_args.get(0)) {
+        (1, Some(o_f)) => o_f,
         _ => cx.span_bug(trait_span, "incorrect number of arguments in `derive(FromPrimitive)`")
     };
 
index f3b0e8a768126fa7752180df7dd7b8e28a07b330..3ce1f6f12ceab58ac7cbf5a01cc3d4bd2a3764ef 100644 (file)
@@ -25,7 +25,7 @@ pub fn expand_deriving_show(cx: &mut ExtCtxt,
                             push: &mut FnMut(P<Item>))
 {
     // &mut ::std::fmt::Formatter
-    let fmtr = Ptr(box Literal(path_std!(cx, core::fmt::Formatter)),
+    let fmtr = Ptr(Box::new(Literal(path_std!(cx, core::fmt::Formatter))),
                    Borrowed(None, ast::MutMutable));
 
     let trait_def = TraitDef {
index 0945f8dd02103ac026565878beb0df6f24995a08..4ea2d4e5c686c8b53115fcf1c2f2aa187c7adedd 100644 (file)
@@ -1553,7 +1553,7 @@ fn visit_mac(&mut self, mac: &ast::Mac) {
 
 
 #[cfg(test)]
-mod test {
+mod tests {
     use super::{pattern_bindings, expand_crate};
     use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer, ExpansionConfig};
     use ast;
@@ -1962,8 +1962,8 @@ fn fmt_in_macro_used_inside_module_macro() {
                 "xx" == string
             }).collect();
         let cxbinds: &[&ast::Ident] = &cxbinds[..];
-        let cxbind = match cxbinds {
-            [b] => b,
+        let cxbind = match (cxbinds.len(), cxbinds.get(0)) {
+            (1, Some(b)) => *b,
             _ => panic!("expected just one binding for ext_cx")
         };
         let resolved_binding = mtwt::resolve(*cxbind);
index d91659bafe4f04c0ce3e03120c87f2434737c16c..08bb4ca106486207cc377ed8c57175b1832b5101 100644 (file)
@@ -128,7 +128,7 @@ fn make_items(mut self: Box<ExpandResult<'a>>)
         }
     }
 
-    box ExpandResult { p: p }
+    Box::new(ExpandResult { p: p })
 }
 
 // include_str! : read the given file, insert it as a literal string expr
index 3fcc6a8d69241b7cb2bfa80258589457f176dcf5..646e6fec405534de3f62a18ae55dc8f57b6ff83c 100644 (file)
@@ -28,12 +28,11 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt,
         return base::DummyResult::any(sp);
     }
 
-
-    match tt {
-        [ast::TtToken(_, ref tok)] if tok.is_keyword(keywords::True) => {
+    match (tt.len(), tt.first()) {
+        (1, Some(&ast::TtToken(_, ref tok))) if tok.is_keyword(keywords::True) => {
             cx.set_trace_macros(true);
         }
-        [ast::TtToken(_, ref tok)] if tok.is_keyword(keywords::False) => {
+        (1, Some(&ast::TtToken(_, ref tok))) if tok.is_keyword(keywords::False) => {
             cx.set_trace_macros(false);
         }
         _ => cx.span_err(sp, "trace_macros! accepts only `true` or `false`"),
index 9c3a556b210f9edb84f0910a90413bd697bca545..5521c68e75c6950f513c3519411d009983f1f490 100644 (file)
@@ -7,8 +7,6 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-//
-// ignore-lexer-test FIXME #15679
 
 //! This is an Earley-like parser, without support for in-grammar nonterminals,
 //! only by calling out to the main rust parser for named nonterminals (which it
@@ -167,7 +165,7 @@ pub fn initial_matcher_pos(ms: Rc<Vec<TokenTree>>, sep: Option<Token>, lo: ByteP
                            -> Box<MatcherPos> {
     let match_idx_hi = count_names(&ms[..]);
     let matches: Vec<_> = (0..match_idx_hi).map(|_| Vec::new()).collect();
-    box MatcherPos {
+    Box::new(MatcherPos {
         stack: vec![],
         top_elts: TtSeq(ms),
         sep: sep,
@@ -178,7 +176,7 @@ pub fn initial_matcher_pos(ms: Rc<Vec<TokenTree>>, sep: Option<Token>, lo: ByteP
         match_cur: 0,
         match_hi: match_idx_hi,
         sp_lo: lo
-    }
+    })
 }
 
 /// NamedMatch is a pattern-match result for a single token::MATCH_NONTERMINAL:
@@ -398,7 +396,7 @@ pub fn parse(sess: &ParseSess,
                         let matches: Vec<_> = (0..ei.matches.len())
                             .map(|_| Vec::new()).collect();
                         let ei_t = ei;
-                        cur_eis.push(box MatcherPos {
+                        cur_eis.push(Box::new(MatcherPos {
                             stack: vec![],
                             sep: seq.separator.clone(),
                             idx: 0,
@@ -409,7 +407,7 @@ pub fn parse(sess: &ParseSess,
                             up: Some(ei_t),
                             sp_lo: sp.lo,
                             top_elts: Tt(TtSequence(sp, seq)),
-                        });
+                        }));
                     }
                     TtToken(_, MatchNt(..)) => {
                         // Built-in nonterminals never start with these tokens,
@@ -535,7 +533,7 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
       "ty" => token::NtTy(p.parse_ty()),
       // this could be handled like a token, since it is one
       "ident" => match p.token {
-        token::Ident(sn,b) => { panictry!(p.bump()); token::NtIdent(box sn,b) }
+        token::Ident(sn,b) => { panictry!(p.bump()); token::NtIdent(Box::new(sn),b) }
         _ => {
             let token_str = pprust::token_to_string(&p.token);
             panic!(p.fatal(&format!("expected ident, found {}",
@@ -543,7 +541,7 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
         }
       },
       "path" => {
-        token::NtPath(box panictry!(p.parse_path(LifetimeAndTypesWithoutColons)))
+        token::NtPath(Box::new(panictry!(p.parse_path(LifetimeAndTypesWithoutColons))))
       }
       "meta" => token::NtMeta(p.parse_meta_item()),
       _ => {
index 730da6cc59419f3ea71566d1edf2b36fe9ecb711..27a00290ee01ea81e8502b256102eca808ec7f17 100644 (file)
@@ -192,7 +192,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                 panictry!(p.check_unknown_macro_variable());
                 // Let the context choose how to interpret the result.
                 // Weird, but useful for X-macros.
-                return box ParserAnyMacro {
+                return Box::new(ParserAnyMacro {
                     parser: RefCell::new(p),
 
                     // Pass along the original expansion site and the name of the macro
@@ -200,7 +200,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                     // macro leaves unparsed tokens.
                     site_span: sp,
                     macro_ident: name
-                }
+                })
               }
               Failure(sp, ref msg) => if sp.lo >= best_fail_spot.lo {
                 best_fail_spot = sp;
@@ -281,12 +281,12 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
         _ => cx.span_bug(def.span, "wrong-structured rhs")
     };
 
-    let exp: Box<_> = box MacroRulesMacroExpander {
+    let exp: Box<_> = Box::new(MacroRulesMacroExpander {
         name: def.ident,
         imported_from: def.imported_from,
         lhses: lhses,
         rhses: rhses,
-    };
+    });
 
     NormalTT(exp, Some(def.span), def.allow_internal_unstable)
 }
index e39b46a2d3e11962aa90ed8af91f6e61e9c849f8..368a9f0c27e56fd3e721693bd308702c82d5c75f 100644 (file)
@@ -294,9 +294,9 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
                             // sidestep the interpolation tricks for ident because
                             // (a) idents can be in lots of places, so it'd be a pain
                             // (b) we actually can, since it's a token.
-                            MatchedNonterminal(NtIdent(box sn, b)) => {
+                            MatchedNonterminal(NtIdent(ref sn, b)) => {
                                 r.cur_span = sp;
-                                r.cur_tok = token::Ident(sn, b);
+                                r.cur_tok = token::Ident(**sn, b);
                                 return ret_val;
                             }
                             MatchedNonterminal(ref other_whole_nt) => {
index d0975c76e9351ad10d5cd9fba0be61d33d3f2ae3..fa95f667c15afc1d1119bf49b1ee19abd7ef8b03 100644 (file)
@@ -394,7 +394,7 @@ fn check_attribute(&self, attr: &ast::Attribute) {
                                are reserved for internal compiler diagnostics");
         } else if name.starts_with("derive_") {
             self.gate_feature("custom_derive", attr.span,
-                              "attributes of the form `#[derive_*]` are reserved
+                              "attributes of the form `#[derive_*]` are reserved \
                                for the compiler");
         } else {
             self.gate_feature("custom_attribute", attr.span,
@@ -620,7 +620,7 @@ fn visit_pat(&mut self, pattern: &ast::Pat) {
                                   pattern.span,
                                   "multiple-element slice matches anywhere \
                                    but at the end of a slice (e.g. \
-                                   `[0, ..xs, 0]` are experimental")
+                                   `[0, ..xs, 0]`) are experimental")
             }
             ast::PatVec(..) => {
                 self.gate_feature("slice_patterns",
index d7033ce7e48a490af6dc69555dd4564a5e2c1643..c857d4403cbf86b30204307e173d03c91b478f98 100644 (file)
@@ -677,10 +677,10 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T)
         token::NtPat(pat) => token::NtPat(fld.fold_pat(pat)),
         token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)),
         token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)),
-        token::NtIdent(box id, is_mod_name) =>
-            token::NtIdent(box fld.fold_ident(id), is_mod_name),
+        token::NtIdent(id, is_mod_name) =>
+            token::NtIdent(Box::new(fld.fold_ident(*id)), is_mod_name),
         token::NtMeta(meta_item) => token::NtMeta(fld.fold_meta_item(meta_item)),
-        token::NtPath(box path) => token::NtPath(box fld.fold_path(path)),
+        token::NtPath(path) => token::NtPath(Box::new(fld.fold_path(*path))),
         token::NtTT(tt) => token::NtTT(P(fld.fold_tt(&*tt))),
     }
 }
@@ -1343,7 +1343,7 @@ pub fn noop_fold_stmt<T: Folder>(Spanned {node, span}: Stmt, folder: &mut T)
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use std::io;
     use ast;
     use util::parser_testing::{string_to_crate, matches_codepattern};
index 3f36d0e8eda0f8ebd8246b3b45e246102cd1b12b..d8beeb6a5503b2e9599de4369d7571536a8cb60e 100644 (file)
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 
-#![feature(box_patterns)]
-#![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
 #![feature(libc)]
-#![feature(quote, unsafe_destructor)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(unicode)]
-#![feature(path_ext)]
 #![feature(str_char)]
-#![feature(into_cow)]
-#![feature(slice_patterns)]
 
 extern crate arena;
 extern crate fmt_macros;
@@ -98,6 +92,7 @@ pub mod syntax {
 pub mod ptr;
 pub mod show_span;
 pub mod std_inject;
+pub mod str;
 pub mod test;
 pub mod visit;
 
index bda01d5a6541c72822ea517c21ad2e3858376f2d..1577b50ad760caad882cbbcc98abc894293669e9 100644 (file)
 use ast;
 use codemap::{BytePos, CharPos, CodeMap, Pos};
 use diagnostic;
-use parse::lexer::{is_whitespace, Reader};
-use parse::lexer::{StringReader, TokenAndSpan};
 use parse::lexer::is_block_doc_comment;
+use parse::lexer::{StringReader, TokenAndSpan};
+use parse::lexer::{is_whitespace, Reader};
 use parse::lexer;
 use print::pprust;
+use str::char_at;
 
 use std::io::Read;
 use std::usize;
@@ -209,7 +210,7 @@ fn all_whitespace(s: &str, col: CharPos) -> Option<usize> {
     let mut col = col.to_usize();
     let mut cursor: usize = 0;
     while col > 0 && cursor < len {
-        let ch = s.char_at(cursor);
+        let ch = char_at(s, cursor);
         if !ch.is_whitespace() {
             return None;
         }
@@ -246,7 +247,7 @@ fn read_block_comment(rdr: &mut StringReader,
     rdr.bump();
     rdr.bump();
 
-    let mut curr_line = String::from_str("/*");
+    let mut curr_line = String::from("/*");
 
     // doc-comments are not really comments, they are attributes
     if (rdr.curr_is('*') && !rdr.nextch_is('*')) || rdr.curr_is('!') {
@@ -382,7 +383,7 @@ pub fn gather_comments_and_literals(span_diagnostic: &diagnostic::SpanHandler,
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use super::*;
 
     #[test] fn test_block_doc_comment_1() {
index f891318659a87e6a492ae6314da78ff1870f0904..d13ab65d72b2bcd9fb580fd7d1455df01b5bb2c8 100644 (file)
 use codemap;
 use diagnostic::SpanHandler;
 use ext::tt::transcribe::tt_next_token;
-use parse::token;
 use parse::token::str_to_ident;
+use parse::token;
+use str::char_at;
 
-use std::borrow::{IntoCow, Cow};
+use std::borrow::Cow;
 use std::char;
 use std::fmt;
 use std::mem::replace;
@@ -289,11 +290,11 @@ fn translate_crlf<'b>(&self, start: BytePos,
                           s: &'b str, errmsg: &'b str) -> Cow<'b, str> {
         let mut i = 0;
         while i < s.len() {
-            let ch = s.char_at(i);
+            let ch = char_at(s, i);
             let next = i + ch.len_utf8();
             if ch == '\r' {
-                if next < s.len() && s.char_at(next) == '\n' {
-                    return translate_crlf_(self, start, s, errmsg, i).into_cow();
+                if next < s.len() && char_at(s, next) == '\n' {
+                    return translate_crlf_(self, start, s, errmsg, i).into();
                 }
                 let pos = start + BytePos(i as u32);
                 let end_pos = start + BytePos(next as u32);
@@ -301,19 +302,19 @@ fn translate_crlf<'b>(&self, start: BytePos,
             }
             i = next;
         }
-        return s.into_cow();
+        return s.into();
 
         fn translate_crlf_(rdr: &StringReader, start: BytePos,
                         s: &str, errmsg: &str, mut i: usize) -> String {
             let mut buf = String::with_capacity(s.len());
             let mut j = 0;
             while i < s.len() {
-                let ch = s.char_at(i);
+                let ch = char_at(s, i);
                 let next = i + ch.len_utf8();
                 if ch == '\r' {
                     if j < i { buf.push_str(&s[j..i]); }
                     j = next;
-                    if next >= s.len() || s.char_at(next) != '\n' {
+                    if next >= s.len() || char_at(s, next) != '\n' {
                         let pos = start + BytePos(i as u32);
                         let end_pos = start + BytePos(next as u32);
                         rdr.err_span_(pos, end_pos, errmsg);
@@ -335,7 +336,7 @@ pub fn bump(&mut self) {
         if current_byte_offset < self.source_text.len() {
             assert!(self.curr.is_some());
             let last_char = self.curr.unwrap();
-            let ch = self.source_text.char_at(current_byte_offset);
+            let ch = char_at(&self.source_text, current_byte_offset);
             let next = current_byte_offset + ch.len_utf8();
             let byte_offset_diff = next - current_byte_offset;
             self.pos = self.pos + Pos::from_usize(byte_offset_diff);
@@ -357,7 +358,7 @@ pub fn bump(&mut self) {
     pub fn nextch(&self) -> Option<char> {
         let offset = self.byte_offset(self.pos).to_usize();
         if offset < self.source_text.len() {
-            Some(self.source_text.char_at(offset))
+            Some(char_at(&self.source_text, offset))
         } else {
             None
         }
@@ -371,9 +372,9 @@ pub fn nextnextch(&self) -> Option<char> {
         let offset = self.byte_offset(self.pos).to_usize();
         let s = &self.source_text[..];
         if offset >= s.len() { return None }
-        let next = offset + s.char_at(offset).len_utf8();
+        let next = offset + char_at(s, offset).len_utf8();
         if next < s.len() {
-            Some(s.char_at(next))
+            Some(char_at(s, next))
         } else {
             None
         }
@@ -564,7 +565,7 @@ fn scan_block_comment(&mut self) -> Option<TokenAndSpan> {
                 let string = if has_cr {
                     self.translate_crlf(start_bpos, string,
                                         "bare CR not allowed in block doc-comment")
-                } else { string.into_cow() };
+                } else { string.into() };
                 token::DocComment(token::intern(&string[..]))
             } else {
                 token::Comment
@@ -1500,7 +1501,7 @@ fn ident_continue(c: Option<char>) -> bool {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use super::*;
 
     use codemap::{BytePos, CodeMap, Span, NO_EXPANSION};
index 4b7b7b66582e13bde12ba61af908ede683692e55..dee3e5fee74df918b50fdca691266b75c1979092 100644 (file)
 use parse::attr::ParserAttr;
 use parse::parser::Parser;
 use ptr::P;
-
+use str::char_at;
 
 use std::cell::{Cell, RefCell};
 use std::fs::File;
 use std::io::Read;
 use std::iter;
-#[allow(deprecated)] // Int
-use std::num::Int;
 use std::path::{Path, PathBuf};
 use std::rc::Rc;
 use std::str;
@@ -288,7 +286,7 @@ pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc<FileMap>)
     // parsing tt's probably shouldn't require a parser at all.
     let cfg = Vec::new();
     let srdr = lexer::StringReader::new(&sess.span_diagnostic, filemap);
-    let mut p1 = Parser::new(sess, cfg, box srdr);
+    let mut p1 = Parser::new(sess, cfg, Box::new(srdr));
     panictry!(p1.parse_all_token_trees())
 }
 
@@ -297,7 +295,7 @@ pub fn tts_to_parser<'a>(sess: &'a ParseSess,
                          tts: Vec<ast::TokenTree>,
                          cfg: ast::CrateConfig) -> Parser<'a> {
     let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, None, tts);
-    let mut p = Parser::new(sess, cfg, box trdr);
+    let mut p = Parser::new(sess, cfg, Box::new(trdr));
     panictry!(p.check_unknown_macro_variable());
     p
 }
@@ -360,7 +358,7 @@ fn filemap_to_tts(sess: &ParseSess, filemap: Rc<FileMap>)
         use super::lexer::make_reader_with_embedded_idents as make_reader;
         let cfg = Vec::new();
         let srdr = make_reader(&sess.span_diagnostic, filemap);
-        let mut p1 = Parser::new(sess, cfg, box srdr);
+        let mut p1 = Parser::new(sess, cfg, Box::new(srdr));
         panictry!(p1.parse_all_token_trees())
     }
 }
@@ -536,7 +534,7 @@ pub fn raw_str_lit(lit: &str) -> String {
 // check if `s` looks like i32 or u1234 etc.
 fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
     s.len() > 1 &&
-        first_chars.contains(&s.char_at(0)) &&
+        first_chars.contains(&char_at(s, 0)) &&
         s[1..].chars().all(|c| '0' <= c && c <= '9')
 }
 
@@ -673,8 +671,8 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) ->
     let orig = s;
     let mut ty = ast::UnsuffixedIntLit(ast::Plus);
 
-    if s.char_at(0) == '0' && s.len() > 1 {
-        match s.char_at(1) {
+    if char_at(s, 0) == '0' && s.len() > 1 {
+        match char_at(s, 1) {
             'x' => base = 16,
             'o' => base = 8,
             'b' => base = 2,
@@ -763,7 +761,7 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) ->
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use super::*;
     use std::rc::Rc;
     use codemap::{Span, BytePos, Pos, Spanned, NO_EXPANSION};
@@ -834,28 +832,44 @@ fn sp(a: u32, b: u32) -> Span {
     fn string_to_tts_macro () {
         let tts = string_to_tts("macro_rules! zip (($a)=>($a))".to_string());
         let tts: &[ast::TokenTree] = &tts[..];
-        match tts {
-            [ast::TtToken(_, token::Ident(name_macro_rules, token::Plain)),
-             ast::TtToken(_, token::Not),
-             ast::TtToken(_, token::Ident(name_zip, token::Plain)),
-             ast::TtDelimited(_, ref macro_delimed)]
+
+        match (tts.len(), tts.get(0), tts.get(1), tts.get(2), tts.get(3)) {
+            (
+                4,
+                Some(&ast::TtToken(_, token::Ident(name_macro_rules, token::Plain))),
+                Some(&ast::TtToken(_, token::Not)),
+                Some(&ast::TtToken(_, token::Ident(name_zip, token::Plain))),
+                Some(&ast::TtDelimited(_, ref macro_delimed)),
+            )
             if name_macro_rules.as_str() == "macro_rules"
             && name_zip.as_str() == "zip" => {
-                match &macro_delimed.tts[..] {
-                    [ast::TtDelimited(_, ref first_delimed),
-                     ast::TtToken(_, token::FatArrow),
-                     ast::TtDelimited(_, ref second_delimed)]
+                let tts = &macro_delimed.tts[..];
+                match (tts.len(), tts.get(0), tts.get(1), tts.get(2)) {
+                    (
+                        3,
+                        Some(&ast::TtDelimited(_, ref first_delimed)),
+                        Some(&ast::TtToken(_, token::FatArrow)),
+                        Some(&ast::TtDelimited(_, ref second_delimed)),
+                    )
                     if macro_delimed.delim == token::Paren => {
-                        match &first_delimed.tts[..] {
-                            [ast::TtToken(_, token::Dollar),
-                             ast::TtToken(_, token::Ident(name, token::Plain))]
+                        let tts = &first_delimed.tts[..];
+                        match (tts.len(), tts.get(0), tts.get(1)) {
+                            (
+                                2,
+                                Some(&ast::TtToken(_, token::Dollar)),
+                                Some(&ast::TtToken(_, token::Ident(name, token::Plain))),
+                            )
                             if first_delimed.delim == token::Paren
                             && name.as_str() == "a" => {},
                             _ => panic!("value 3: {:?}", **first_delimed),
                         }
-                        match &second_delimed.tts[..] {
-                            [ast::TtToken(_, token::Dollar),
-                             ast::TtToken(_, token::Ident(name, token::Plain))]
+                        let tts = &second_delimed.tts[..];
+                        match (tts.len(), tts.get(0), tts.get(1)) {
+                            (
+                                2,
+                                Some(&ast::TtToken(_, token::Dollar)),
+                                Some(&ast::TtToken(_, token::Ident(name, token::Plain))),
+                            )
                             if second_delimed.delim == token::Paren
                             && name.as_str() == "a" => {},
                             _ => panic!("value 4: {:?}", **second_delimed),
index 0515d1ae945bda170e818902f935145042f740ff..68006a8979a6468c702fe7d0497a869d830c9e52 100644 (file)
@@ -78,6 +78,7 @@
 use diagnostic::FatalError;
 
 use std::collections::HashSet;
+use std::fs;
 use std::io::prelude::*;
 use std::mem;
 use std::path::{Path, PathBuf};
@@ -436,10 +437,11 @@ fn tokens_to_string(tokens: &[TokenType]) -> String {
             // leave it in the input
             Ok(())
         } else {
-            let mut expected = edible.iter().map(|x| TokenType::Token(x.clone()))
-                                            .collect::<Vec<_>>();
-            expected.extend(inedible.iter().map(|x| TokenType::Token(x.clone())));
-            expected.push_all(&*self.expected_tokens);
+            let mut expected = edible.iter()
+                .map(|x| TokenType::Token(x.clone()))
+                .chain(inedible.iter().map(|x| TokenType::Token(x.clone())))
+                .chain(self.expected_tokens.iter().cloned())
+                .collect::<Vec<_>>();
             expected.sort_by(|a, b| a.to_string().cmp(&b.to_string()));
             expected.dedup();
             let expect = tokens_to_string(&expected[..]);
@@ -490,8 +492,10 @@ pub fn commit_expr(&mut self, e: &Expr, edible: &[token::Token],
         debug!("commit_expr {:?}", e);
         if let ExprPath(..) = e.node {
             // might be unit-struct construction; check for recoverableinput error.
-            let mut expected = edible.iter().cloned().collect::<Vec<_>>();
-            expected.push_all(inedible);
+            let expected = edible.iter()
+                .cloned()
+                .chain(inedible.iter().cloned())
+                .collect::<Vec<_>>();
             try!(self.check_for_erroneous_unit_struct_expecting(&expected[..]));
         }
         self.expect_one_of(edible, inedible)
@@ -509,8 +513,10 @@ pub fn commit_stmt(&mut self, edible: &[token::Token],
         if self.last_token
                .as_ref()
                .map_or(false, |t| t.is_ident() || t.is_path()) {
-            let mut expected = edible.iter().cloned().collect::<Vec<_>>();
-            expected.push_all(&inedible);
+            let expected = edible.iter()
+                .cloned()
+                .chain(inedible.iter().cloned())
+                .collect::<Vec<_>>();
             try!(self.check_for_erroneous_unit_struct_expecting(&expected));
         }
         self.expect_one_of(edible, inedible)
@@ -897,7 +903,7 @@ pub fn bump(&mut self) -> PResult<()> {
         self.last_span = self.span;
         // Stash token for error recovery (sometimes; clone is not necessarily cheap).
         self.last_token = if self.token.is_ident() || self.token.is_path() {
-            Some(box self.token.clone())
+            Some(Box::new(self.token.clone()))
         } else {
             None
         };
@@ -972,6 +978,9 @@ pub fn span_note(&self, sp: Span, m: &str) {
     pub fn span_help(&self, sp: Span, m: &str) {
         self.sess.span_diagnostic.span_help(sp, m)
     }
+    pub fn span_suggestion(&self, sp: Span, m: &str, n: String) {
+        self.sess.span_diagnostic.span_suggestion(sp, m, n)
+    }
     pub fn fileline_help(&self, sp: Span, m: &str) {
         self.sess.span_diagnostic.fileline_help(sp, m)
     }
@@ -1142,8 +1151,8 @@ pub fn parse_trait_items(&mut self) -> PResult<Vec<P<TraitItem>>> {
             &token::CloseDelim(token::Brace),
             seq_sep_none(),
             |p| {
-            let lo = p.span.lo;
             let mut attrs = p.parse_outer_attributes();
+            let lo = p.span.lo;
 
             let (name, node) = if try!(p.eat_keyword(keywords::Type)) {
                 let TyParam {ident, bounds, default, ..} = try!(p.parse_ty_param());
@@ -1187,7 +1196,7 @@ pub fn parse_trait_items(&mut self) -> PResult<Vec<P<TraitItem>>> {
                     debug!("parse_trait_methods(): parsing provided method");
                     let (inner_attrs, body) =
                         try!(p.parse_inner_attrs_and_block());
-                    attrs.push_all(&inner_attrs[..]);
+                    attrs.extend(inner_attrs.iter().cloned());
                     Some(body)
                   }
 
@@ -1578,8 +1587,8 @@ pub fn parse_path(&mut self, mode: PathParsingMode) -> PResult<ast::Path> {
             token::Interpolated(token::NtPath(_)) => Some(try!(self.bump_and_get())),
             _ => None,
         };
-        if let Some(token::Interpolated(token::NtPath(box path))) = found {
-            return Ok(path);
+        if let Some(token::Interpolated(token::NtPath(path))) = found {
+            return Ok(*path);
         }
 
         let lo = self.span.lo;
@@ -2594,6 +2603,7 @@ pub fn parse_prefix_expr(&mut self) -> PResult<P<Expr>> {
             }
 
             let lo = self.span.lo;
+            let box_hi = self.span.hi;
 
             try!(self.bump());
 
@@ -2610,9 +2620,10 @@ pub fn parse_prefix_expr(&mut self) -> PResult<P<Expr>> {
                         self.span_err(span,
                                       &format!("expected expression, found `{}`",
                                               this_token_to_string));
-                        let box_span = mk_sp(lo, self.last_span.hi);
-                        self.span_help(box_span,
-                                       "perhaps you meant `box() (foo)` instead?");
+                        let box_span = mk_sp(lo, box_hi);
+                        self.span_suggestion(box_span,
+                                             "try using `box()` instead:",
+                                             "box()".to_string());
                         self.abort_if_errors();
                     }
                     let subexpression = try!(self.parse_prefix_expr());
@@ -3398,8 +3409,8 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
             }
         }
 
-        let lo = self.span.lo;
         let attrs = self.parse_outer_attributes();
+        let lo = self.span.lo;
 
         Ok(Some(if self.check_keyword(keywords::Let) {
             check_expected_item(self, &attrs);
@@ -3882,7 +3893,7 @@ pub fn parse_where_clause(&mut self) -> PResult<ast::WhereClause> {
                     let bounds =
                         try!(self.parse_lifetimes(token::BinOp(token::Plus)));
 
-                    let hi = self.span.hi;
+                    let hi = self.last_span.hi;
                     let span = mk_sp(lo, hi);
 
                     where_clause.predicates.push(ast::WherePredicate::RegionPredicate(
@@ -3911,7 +3922,7 @@ pub fn parse_where_clause(&mut self) -> PResult<ast::WhereClause> {
 
                     if try!(self.eat(&token::Colon) ){
                         let bounds = try!(self.parse_ty_param_bounds(BoundParsingMode::Bare));
-                        let hi = self.span.hi;
+                        let hi = self.last_span.hi;
                         let span = mk_sp(lo, hi);
 
                         if bounds.is_empty() {
@@ -3931,7 +3942,7 @@ pub fn parse_where_clause(&mut self) -> PResult<ast::WhereClause> {
                         parsed_something = true;
                     } else if try!(self.eat(&token::Eq) ){
                         // let ty = try!(self.parse_ty_nopanic());
-                        let hi = self.span.hi;
+                        let hi = self.last_span.hi;
                         let span = mk_sp(lo, hi);
                         // where_clause.predicates.push(
                         //     ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
@@ -4293,8 +4304,8 @@ fn parse_item_fn(&mut self, unsafety: Unsafety, abi: abi::Abi) -> PResult<ItemIn
 
     /// Parse an impl item.
     pub fn parse_impl_item(&mut self) -> PResult<P<ImplItem>> {
-        let lo = self.span.lo;
         let mut attrs = self.parse_outer_attributes();
+        let lo = self.span.lo;
         let vis = try!(self.parse_visibility());
         let (name, node) = if try!(self.eat_keyword(keywords::Type)) {
             let name = try!(self.parse_ident());
@@ -4770,8 +4781,8 @@ fn eval_src_mod(&mut self,
                 let secondary_path_str = format!("{}/mod.rs", mod_name);
                 let default_path = dir_path.join(&default_path_str[..]);
                 let secondary_path = dir_path.join(&secondary_path_str[..]);
-                let default_exists = default_path.exists();
-                let secondary_exists = secondary_path.exists();
+                let default_exists = fs::metadata(&default_path).is_ok();
+                let secondary_exists = fs::metadata(&secondary_path).is_ok();
 
                 if !self.owns_directory {
                     self.span_err(id_sp,
@@ -4834,7 +4845,7 @@ fn eval_src_mod_from_path(&mut self,
         let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
         match included_mod_stack.iter().position(|p| *p == path) {
             Some(i) => {
-                let mut err = String::from_str("circular modules: ");
+                let mut err = String::from("circular modules: ");
                 let len = included_mod_stack.len();
                 for p in &included_mod_stack[i.. len] {
                     err.push_str(&p.to_string_lossy());
@@ -5369,9 +5380,8 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
 
     /// Parse a foreign item.
     fn parse_foreign_item(&mut self) -> PResult<Option<P<ForeignItem>>> {
-        let lo = self.span.lo;
-
         let attrs = self.parse_outer_attributes();
+        let lo = self.span.lo;
         let visibility = try!(self.parse_visibility());
 
         if self.check_keyword(keywords::Static) {
index 2bb74944ce91abf0b085cd932ceb4439e985ae62..538aa3843277ae0ef91978b24aa820859b062613 100644 (file)
@@ -746,7 +746,7 @@ pub fn fresh_mark() -> ast::Mrk {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use super::*;
     use ast;
     use ext::mtwt;
index 3fd4e31b4771ee8aac8ea64fa38453e8cf52ca7c..15aaf9cf390fd18c0110aed288fdec802858cc29 100644 (file)
@@ -131,7 +131,7 @@ pub fn buf_str(toks: &[Token],
     assert_eq!(n, szs.len());
     let mut i = left;
     let mut l = lim;
-    let mut s = string::String::from_str("[");
+    let mut s = string::String::from("[");
     while i != right && l != 0 {
         l -= 1;
         if i != left {
index c51b5d039784d4009ff091d183485fdd0e0906c7..980ce720026c32e5e4c380df1711163aee2f1b2e 100644 (file)
@@ -28,7 +28,7 @@
 use ptr::P;
 use std_inject;
 
-use std::{ascii, mem};
+use std::ascii;
 use std::io::{self, Write, Read};
 use std::iter;
 
@@ -187,18 +187,13 @@ pub fn new(cm: &'a CodeMap,
 pub fn to_string<F>(f: F) -> String where
     F: FnOnce(&mut State) -> io::Result<()>,
 {
-    use std::raw::TraitObject;
-    let mut s = rust_printer(box Vec::new());
-    f(&mut s).unwrap();
-    eof(&mut s.s).unwrap();
-    let wr = unsafe {
-        // FIXME(pcwalton): A nasty function to extract the string from an `Write`
-        // that we "know" to be a `Vec<u8>` that works around the lack of checked
-        // downcasts.
-        let obj: &TraitObject = mem::transmute(&s.s.out);
-        mem::transmute::<*mut (), &Vec<u8>>(obj.data)
-    };
-    String::from_utf8(wr.clone()).unwrap()
+    let mut wr = Vec::new();
+    {
+        let mut printer = rust_printer(Box::new(&mut wr));
+        f(&mut printer).unwrap();
+        eof(&mut printer.s).unwrap();
+    }
+    String::from_utf8(wr).unwrap()
 }
 
 pub fn binop_to_string(op: BinOpToken) -> &'static str {
@@ -2799,13 +2794,13 @@ pub fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> {
         match lit.node {
             ast::LitStr(ref st, style) => self.print_string(&st, style),
             ast::LitByte(byte) => {
-                let mut res = String::from_str("b'");
+                let mut res = String::from("b'");
                 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("'");
+                let mut res = String::from("'");
                 res.extend(ch.escape_default());
                 res.push('\'');
                 word(&mut self.s, &res[..])
@@ -3013,7 +3008,7 @@ pub fn print_unsafety(&mut self, s: ast::Unsafety) -> io::Result<()> {
 fn repeat(s: &str, n: usize) -> String { iter::repeat(s).take(n).collect() }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use super::*;
 
     use ast;
index 5032cd57eeb376772caf416f74966e961e2a5887..83e321f110c5875dfb39694307fbde3afd1f94f1 100644 (file)
@@ -52,7 +52,7 @@ pub struct P<T> {
 /// Construct a `P<T>` from a `T` value.
 pub fn P<T: 'static>(value: T) -> P<T> {
     P {
-        ptr: box value
+        ptr: Box::new(value)
     }
 }
 
diff --git a/src/libsyntax/str.rs b/src/libsyntax/str.rs
new file mode 100644 (file)
index 0000000..d0f4762
--- /dev/null
@@ -0,0 +1,13 @@
+// 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.
+
+pub fn char_at(s: &str, byte: usize) -> char {
+    s[byte..].chars().next().unwrap()
+}
index c6646fe93a21bb1902665efb5acb08fff73aef46..d016eb39239f68a64e0154ad5f491b671e5234b6 100644 (file)
@@ -15,6 +15,7 @@
 use parse::parser::Parser;
 use parse::token;
 use ptr::P;
+use str::char_at;
 
 /// Map a string to tts, using a made-up filename:
 pub fn string_to_tts(source_str: String) -> Vec<ast::TokenTree> {
@@ -96,24 +97,24 @@ pub fn matches_codepattern(a : &str, b : &str) -> bool {
         else if idx_a == a.len() {return false;}
         else if idx_b == b.len() {
             // maybe the stuff left in a is all ws?
-            if is_whitespace(a.char_at(idx_a)) {
+            if is_whitespace(char_at(a, idx_a)) {
                 return scan_for_non_ws_or_end(a,idx_a) == a.len();
             } else {
                 return false;
             }
         }
         // ws in both given and pattern:
-        else if is_whitespace(a.char_at(idx_a))
-           && is_whitespace(b.char_at(idx_b)) {
+        else if is_whitespace(char_at(a, idx_a))
+           && is_whitespace(char_at(b, idx_b)) {
             idx_a = scan_for_non_ws_or_end(a,idx_a);
             idx_b = scan_for_non_ws_or_end(b,idx_b);
         }
         // ws in given only:
-        else if is_whitespace(a.char_at(idx_a)) {
+        else if is_whitespace(char_at(a, idx_a)) {
             idx_a = scan_for_non_ws_or_end(a,idx_a);
         }
         // *don't* silently eat ws in expected only.
-        else if a.char_at(idx_a) == b.char_at(idx_b) {
+        else if char_at(a, idx_a) == char_at(b, idx_b) {
             idx_a += 1;
             idx_b += 1;
         }
@@ -129,7 +130,7 @@ pub fn matches_codepattern(a : &str, b : &str) -> bool {
 fn scan_for_non_ws_or_end(a : &str, idx: usize) -> usize {
     let mut i = idx;
     let len = a.len();
-    while (i < len) && (is_whitespace(a.char_at(i))) {
+    while (i < len) && (is_whitespace(char_at(a, i))) {
         i += 1;
     }
     i
@@ -141,7 +142,7 @@ pub fn is_whitespace(c: char) -> bool {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use super::*;
 
     #[test] fn eqmodws() {
index 6b864d5294766fabffa4448c4440f997c32d6d22..5353d12b67813fe483dee91c92409ab2da067a5b 100644 (file)
@@ -64,7 +64,10 @@ pub fn as_slice<'a>(&'a self) -> &'a [T] {
                 let result: &[T] = &[];
                 result
             }
-            One(ref v) => slice::ref_slice(v),
+            One(ref v) => {
+                // FIXME: Could be replaced with `slice::ref_slice(v)` when it is stable.
+                unsafe { slice::from_raw_parts(v, 1) }
+            }
             Many(ref vs) => vs
         }
     }
@@ -201,7 +204,7 @@ fn move_map<F>(self, mut f: F) -> SmallVector<T> where F: FnMut(T) -> T {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use super::*;
 
     #[test]
index c9ad08bb8523485ae9eb9478dfe97fd71fd8a493..2b8c24741ae7ccb0e2c6b94c61f2f628aed8dbad 100644 (file)
@@ -573,7 +573,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8> ,String> {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
     use super::{expand,Param,Words,Variables,Number};
     use std::result::Result::Ok;
 
index 01d191f30147b23450942f367135dac8b16d583f..ef42d8c2506b38ecd8d2b9624f2ce8d84063ea1e 100644 (file)
@@ -345,7 +345,7 @@ pub fn msys_terminfo() -> Box<TermInfo> {
 }
 
 #[cfg(test)]
-mod test {
+mod tests {
 
     use super::{boolnames, boolfnames, numnames, numfnames, stringnames, stringfnames};
 
@@ -355,11 +355,4 @@ fn test_veclens() {
         assert_eq!(numfnames.len(), numnames.len());
         assert_eq!(stringfnames.len(), stringnames.len());
     }
-
-    #[test]
-    #[ignore(reason = "no ncurses on buildbots, needs a bundled terminfo file to test against")]
-    fn test_parse() {
-        // FIXME #6870: Distribute a compiled file in src/tests and test there
-        // parse(old_io::fs_reader(&p("/usr/share/terminfo/r/rxvt-256color")).unwrap(), false);
-    }
 }
index 5c967747104306c26a82886b30a907a9993b75a4..b68b1d28b356750787384c625202a81552fd2c26 100644 (file)
@@ -43,7 +43,6 @@
 #![feature(std_misc)]
 #![feature(libc)]
 #![feature(set_stdio)]
-#![cfg_attr(test, feature(old_io))]
 
 extern crate getopts;
 extern crate serialize;
@@ -75,7 +74,6 @@
 use std::io::prelude::*;
 use std::io;
 use std::iter::repeat;
-use std::num::{Float, Int};
 use std::path::PathBuf;
 use std::sync::mpsc::{channel, Sender};
 use std::sync::{Arc, Mutex};
@@ -413,7 +411,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
 
 #[derive(Clone, PartialEq)]
 pub struct BenchSamples {
-    ns_iter_summ: stats::Summary<f64>,
+    ns_iter_summ: stats::Summary,
     mb_s: usize,
 }
 
@@ -1066,7 +1064,7 @@ pub fn bench_n<F>(&mut self, n: u64, f: F) where F: FnOnce(&mut Bencher) {
     }
 
     // This is a more statistics-driven benchmark algorithm
-    pub fn auto_bench<F>(&mut self, mut f: F) -> stats::Summary<f64> where F: FnMut(&mut Bencher) {
+    pub fn auto_bench<F>(&mut self, mut f: F) -> stats::Summary where F: FnMut(&mut Bencher) {
         // Initial bench run to get ballpark figure.
         let mut n = 1;
         self.bench_n(n, |x| f(x));
index 06e0de76eafd8df7cc69c3449b99b23f5635cf79..c1ba1260f67e120fdd058c04f6fbf68fc0f13b4a 100644 (file)
@@ -13,9 +13,8 @@
 
 use std::cmp::Ordering::{self, Less, Greater, Equal};
 use std::mem;
-use std::num::{Float, FromPrimitive};
 
-fn local_cmp<T:Float>(x: T, y: T) -> Ordering {
+fn local_cmp(x: f64, y: f64) -> Ordering {
     // arbitrarily decide that NaNs are larger than everything.
     if y.is_nan() {
         Less
@@ -30,12 +29,12 @@ fn local_cmp<T:Float>(x: T, y: T) -> Ordering {
     }
 }
 
-fn local_sort<T: Float>(v: &mut [T]) {
-    v.sort_by(|x: &T, y: &T| local_cmp(*x, *y));
+fn local_sort(v: &mut [f64]) {
+    v.sort_by(|x: &f64, y: &f64| local_cmp(*x, *y));
 }
 
 /// Trait that provides simple descriptive statistics on a univariate set of numeric samples.
-pub trait Stats <T: Float + FromPrimitive> {
+pub trait Stats {
 
     /// Sum of the samples.
     ///
@@ -43,24 +42,24 @@ pub trait Stats <T: Float + FromPrimitive> {
     /// Depends on IEEE-754 arithmetic guarantees. See proof of correctness at:
     /// ["Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric Predicates"]
     /// (http://www.cs.cmu.edu/~quake-papers/robust-arithmetic.ps)
-    fn sum(&self) -> T;
+    fn sum(&self) -> f64;
 
     /// Minimum value of the samples.
-    fn min(&self) -> T;
+    fn min(&self) -> f64;
 
     /// Maximum value of the samples.
-    fn max(&self) -> T;
+    fn max(&self) -> f64;
 
     /// Arithmetic mean (average) of the samples: sum divided by sample-count.
     ///
     /// See: https://en.wikipedia.org/wiki/Arithmetic_mean
-    fn mean(&self) -> T;
+    fn mean(&self) -> f64;
 
     /// Median of the samples: value separating the lower half of the samples from the higher half.
     /// Equal to `self.percentile(50.0)`.
     ///
     /// See: https://en.wikipedia.org/wiki/Median
-    fn median(&self) -> T;
+    fn median(&self) -> f64;
 
     /// Variance of the samples: bias-corrected mean of the squares of the differences of each
     /// sample from the sample mean. Note that this calculates the _sample variance_ rather than the
@@ -69,7 +68,7 @@ pub trait Stats <T: Float + FromPrimitive> {
     /// than `n`.
     ///
     /// See: https://en.wikipedia.org/wiki/Variance
-    fn var(&self) -> T;
+    fn var(&self) -> f64;
 
     /// Standard deviation: the square root of the sample variance.
     ///
@@ -77,13 +76,13 @@ pub trait Stats <T: Float + FromPrimitive> {
     /// `median_abs_dev` for unknown distributions.
     ///
     /// See: https://en.wikipedia.org/wiki/Standard_deviation
-    fn std_dev(&self) -> T;
+    fn std_dev(&self) -> f64;
 
     /// Standard deviation as a percent of the mean value. See `std_dev` and `mean`.
     ///
     /// Note: this is not a robust statistic for non-normal distributions. Prefer the
     /// `median_abs_dev_pct` for unknown distributions.
-    fn std_dev_pct(&self) -> T;
+    fn std_dev_pct(&self) -> f64;
 
     /// Scaled median of the absolute deviations of each sample from the sample median. This is a
     /// robust (distribution-agnostic) estimator of sample variability. Use this in preference to
@@ -92,10 +91,10 @@ pub trait Stats <T: Float + FromPrimitive> {
     /// deviation.
     ///
     /// See: http://en.wikipedia.org/wiki/Median_absolute_deviation
-    fn median_abs_dev(&self) -> T;
+    fn median_abs_dev(&self) -> f64;
 
     /// Median absolute deviation as a percent of the median. See `median_abs_dev` and `median`.
-    fn median_abs_dev_pct(&self) -> T;
+    fn median_abs_dev_pct(&self) -> f64;
 
     /// Percentile: the value below which `pct` percent of the values in `self` fall. For example,
     /// percentile(95.0) will return the value `v` such that 95% of the samples `s` in `self`
@@ -104,7 +103,7 @@ pub trait Stats <T: Float + FromPrimitive> {
     /// Calculated by linear interpolation between closest ranks.
     ///
     /// See: http://en.wikipedia.org/wiki/Percentile
-    fn percentile(&self, pct: T) -> T;
+    fn percentile(&self, pct: f64) -> f64;
 
     /// Quartiles of the sample: three values that divide the sample into four equal groups, each
     /// with 1/4 of the data. The middle value is the median. See `median` and `percentile`. This
@@ -112,36 +111,36 @@ pub trait Stats <T: Float + FromPrimitive> {
     /// is otherwise equivalent.
     ///
     /// See also: https://en.wikipedia.org/wiki/Quartile
-    fn quartiles(&self) -> (T,T,T);
+    fn quartiles(&self) -> (f64,f64,f64);
 
     /// Inter-quartile range: the difference between the 25th percentile (1st quartile) and the 75th
     /// percentile (3rd quartile). See `quartiles`.
     ///
     /// See also: https://en.wikipedia.org/wiki/Interquartile_range
-    fn iqr(&self) -> T;
+    fn iqr(&self) -> f64;
 }
 
 /// Extracted collection of all the summary statistics of a sample set.
 #[derive(Clone, PartialEq)]
 #[allow(missing_docs)]
-pub struct Summary<T> {
-    pub sum: T,
-    pub min: T,
-    pub max: T,
-    pub mean: T,
-    pub median: T,
-    pub var: T,
-    pub std_dev: T,
-    pub std_dev_pct: T,
-    pub median_abs_dev: T,
-    pub median_abs_dev_pct: T,
-    pub quartiles: (T,T,T),
-    pub iqr: T,
+pub struct Summary {
+    pub sum: f64,
+    pub min: f64,
+    pub max: f64,
+    pub mean: f64,
+    pub median: f64,
+    pub var: f64,
+    pub std_dev: f64,
+    pub std_dev_pct: f64,
+    pub median_abs_dev: f64,
+    pub median_abs_dev_pct: f64,
+    pub quartiles: (f64,f64,f64),
+    pub iqr: f64,
 }
 
-impl<T: Float + FromPrimitive> Summary<T> {
+impl Summary {
     /// Construct a new summary of a sample set.
-    pub fn new(samples: &[T]) -> Summary<T> {
+    pub fn new(samples: &[f64]) -> Summary {
         Summary {
             sum: samples.sum(),
             min: samples.min(),
@@ -159,9 +158,9 @@ pub fn new(samples: &[T]) -> Summary<T> {
     }
 }
 
-impl<T: Float + FromPrimitive> Stats<T> for [T] {
+impl Stats for [f64] {
     // FIXME #11059 handle NaN, inf and overflow
-    fn sum(&self) -> T {
+    fn sum(&self) -> f64 {
         let mut partials = vec![];
 
         for &x in self {
@@ -170,7 +169,7 @@ fn sum(&self) -> T {
             // This inner loop applies `hi`/`lo` summation to each
             // partial so that the list of partial sums remains exact.
             for i in 0..partials.len() {
-                let mut y: T = partials[i];
+                let mut y: f64 = partials[i];
                 if x.abs() < y.abs() {
                     mem::swap(&mut x, &mut y);
                 }
@@ -178,7 +177,7 @@ fn sum(&self) -> T {
                 // `lo`. Together `hi+lo` are exactly equal to `x+y`.
                 let hi = x + y;
                 let lo = y - (hi - x);
-                if lo != Float::zero() {
+                if lo != 0.0 {
                     partials[j] = lo;
                     j += 1;
                 }
@@ -191,35 +190,35 @@ fn sum(&self) -> T {
                 partials.truncate(j+1);
             }
         }
-        let zero: T = Float::zero();
+        let zero: f64 = 0.0;
         partials.iter().fold(zero, |p, q| p + *q)
     }
 
-    fn min(&self) -> T {
+    fn min(&self) -> f64 {
         assert!(!self.is_empty());
         self.iter().fold(self[0], |p, q| p.min(*q))
     }
 
-    fn max(&self) -> T {
+    fn max(&self) -> f64 {
         assert!(!self.is_empty());
         self.iter().fold(self[0], |p, q| p.max(*q))
     }
 
-    fn mean(&self) -> T {
+    fn mean(&self) -> f64 {
         assert!(!self.is_empty());
-        self.sum() / FromPrimitive::from_usize(self.len()).unwrap()
+        self.sum() / (self.len() as f64)
     }
 
-    fn median(&self) -> T {
-        self.percentile(FromPrimitive::from_usize(50).unwrap())
+    fn median(&self) -> f64 {
+        self.percentile(50 as f64)
     }
 
-    fn var(&self) -> T {
+    fn var(&self) -> f64 {
         if self.len() < 2 {
-            Float::zero()
+            0.0
         } else {
             let mean = self.mean();
-            let mut v: T = Float::zero();
+            let mut v: f64 = 0.0;
             for s in self {
                 let x = *s - mean;
                 v = v + x*x;
@@ -227,53 +226,53 @@ fn var(&self) -> T {
             // NB: this is _supposed to be_ len-1, not len. If you
             // change it back to len, you will be calculating a
             // population variance, not a sample variance.
-            let denom = FromPrimitive::from_usize(self.len()-1).unwrap();
+            let denom = (self.len() - 1) as f64;
             v/denom
         }
     }
 
-    fn std_dev(&self) -> T {
+    fn std_dev(&self) -> f64 {
         self.var().sqrt()
     }
 
-    fn std_dev_pct(&self) -> T {
-        let hundred = FromPrimitive::from_usize(100).unwrap();
+    fn std_dev_pct(&self) -> f64 {
+        let hundred = 100 as f64;
         (self.std_dev() / self.mean()) * hundred
     }
 
-    fn median_abs_dev(&self) -> T {
+    fn median_abs_dev(&self) -> f64 {
         let med = self.median();
-        let abs_devs: Vec<T> = self.iter().map(|&v| (med - v).abs()).collect();
+        let abs_devs: Vec<f64> = self.iter().map(|&v| (med - v).abs()).collect();
         // This constant is derived by smarter statistics brains than me, but it is
         // consistent with how R and other packages treat the MAD.
-        let number = FromPrimitive::from_f64(1.4826).unwrap();
+        let number = 1.4826;
         abs_devs.median() * number
     }
 
-    fn median_abs_dev_pct(&self) -> T {
-        let hundred = FromPrimitive::from_usize(100).unwrap();
+    fn median_abs_dev_pct(&self) -> f64 {
+        let hundred = 100 as f64;
         (self.median_abs_dev() / self.median()) * hundred
     }
 
-    fn percentile(&self, pct: T) -> T {
+    fn percentile(&self, pct: f64) -> f64 {
         let mut tmp = self.to_vec();
         local_sort(&mut tmp);
         percentile_of_sorted(&tmp, pct)
     }
 
-    fn quartiles(&self) -> (T,T,T) {
+    fn quartiles(&self) -> (f64,f64,f64) {
         let mut tmp = self.to_vec();
         local_sort(&mut tmp);
-        let first = FromPrimitive::from_usize(25).unwrap();
+        let first = 25f64;
         let a = percentile_of_sorted(&tmp, first);
-        let secound = FromPrimitive::from_usize(50).unwrap();
+        let secound = 50f64;
         let b = percentile_of_sorted(&tmp, secound);
-        let third = FromPrimitive::from_usize(75).unwrap();
+        let third = 75f64;
         let c = percentile_of_sorted(&tmp, third);
         (a,b,c)
     }
 
-    fn iqr(&self) -> T {
+    fn iqr(&self) -> f64 {
         let (a,_,c) = self.quartiles();
         c - a
     }
@@ -282,41 +281,41 @@ fn iqr(&self) -> T {
 
 // Helper function: extract a value representing the `pct` percentile of a sorted sample-set, using
 // linear interpolation. If samples are not sorted, return nonsensical value.
-fn percentile_of_sorted<T: Float + FromPrimitive>(sorted_samples: &[T],
-                                                             pct: T) -> T {
+fn percentile_of_sorted(sorted_samples: &[f64], pct: f64) -> f64 {
     assert!(!sorted_samples.is_empty());
     if sorted_samples.len() == 1 {
         return sorted_samples[0];
     }
-    let zero: T = Float::zero();
+    let zero: f64 = 0.0;
     assert!(zero <= pct);
-    let hundred = FromPrimitive::from_usize(100).unwrap();
+    let hundred = 100f64;
     assert!(pct <= hundred);
     if pct == hundred {
         return sorted_samples[sorted_samples.len() - 1];
     }
-    let length = FromPrimitive::from_usize(sorted_samples.len() - 1).unwrap();
+    let length = (sorted_samples.len() - 1) as f64;
     let rank = (pct / hundred) * length;
     let lrank = rank.floor();
     let d = rank - lrank;
-    let n = lrank.to_usize().unwrap();
+    let n = lrank as usize;
     let lo = sorted_samples[n];
     let hi = sorted_samples[n+1];
     lo + (hi - lo) * d
 }
 
 
-/// Winsorize a set of samples, replacing values above the `100-pct` percentile and below the `pct`
-/// percentile with those percentiles themselves. This is a way of minimizing the effect of
-/// outliers, at the cost of biasing the sample. It differs from trimming in that it does not
-/// change the number of samples, just changes the values of those that are outliers.
+/// Winsorize a set of samples, replacing values above the `100-pct` percentile
+/// and below the `pct` percentile with those percentiles themselves. This is a
+/// way of minimizing the effect of outliers, at the cost of biasing the sample.
+/// It differs from trimming in that it does not change the number of samples,
+/// just changes the values of those that are outliers.
 ///
 /// See: http://en.wikipedia.org/wiki/Winsorising
-pub fn winsorize<T: Float + FromPrimitive>(samples: &mut [T], pct: T) {
+pub fn winsorize(samples: &mut [f64], pct: f64) {
     let mut tmp = samples.to_vec();
     local_sort(&mut tmp);
     let lo = percentile_of_sorted(&tmp, pct);
-    let hundred: T = FromPrimitive::from_usize(100).unwrap();
+    let hundred = 100 as f64;
     let hi = percentile_of_sorted(&tmp, hundred-pct);
     for samp in samples {
         if *samp > hi {
@@ -339,14 +338,13 @@ mod tests {
 
     macro_rules! assert_approx_eq {
         ($a:expr, $b:expr) => ({
-            use std::num::Float;
             let (a, b) = (&$a, &$b);
             assert!((*a - *b).abs() < 1.0e-6,
                     "{} is not approximately equal to {}", *a, *b);
         })
     }
 
-    fn check(samples: &[f64], summ: &Summary<f64>) {
+    fn check(samples: &[f64], summ: &Summary) {
 
         let summ2 = Summary::new(samples);
 
index ebc6b04c29591108d3f28e724b4b9b74cd1232e6..e54d4823d26cdb3f98e5a1b17e1c257cd329aa61 160000 (submodule)
@@ -1 +1 @@
-Subproject commit ebc6b04c29591108d3f28e724b4b9b74cd1232e6
+Subproject commit e54d4823d26cdb3f98e5a1b17e1c257cd329aa61
index d5483593aa8888f3e487d145f7cd0e01b7b510de..26303d13b6cfcb61542d1d46ff45d29186a405a1 100644 (file)
@@ -52,7 +52,7 @@
   }
 
   for (var i = 0; i < toc.length; i++) {
-    if (toc[i].attributes['href'].value === href) {
+    if (toc[i].attributes['href'].value.split('/').pop() === href) {
       var nav = document.createElement('p');
       if (i > 0) {
         var prevNode = toc[i-1].cloneNode(true);
index 8ca81ab3d68eadd3edf1b48e832c7d50cfa1fb8c..7e0630fd242d39c83dfff871136a8d0118950208 100644 (file)
@@ -89,12 +89,12 @@ extern "C" LLVMExecutionEngineRef LLVMBuildExecutionEngine(
     options.NoFramePointerElim = true;
 
     ExecutionEngine *ee =
-    #if LLVM_VERSION_MINOR <= 5
-        EngineBuilder(unwrap(mod))
-            .setMCJITMemoryManager(unwrap(mref))
-    #else
+    #if LLVM_VERSION_MINOR >= 6
         EngineBuilder(std::unique_ptr<Module>(unwrap(mod)))
             .setMCJITMemoryManager(std::unique_ptr<RustJITMemoryManager>(unwrap(mref)))
+    #else
+        EngineBuilder(unwrap(mod))
+            .setMCJITMemoryManager(unwrap(mref))
     #endif
             .setEngineKind(EngineKind::JIT)
             .setErrorStr(&error_str)
index b205d87598cfe5648912e48f9fda838de5e415aa..a2ab8040198ff7a3266bd58194556d2d7255fd31 100644 (file)
@@ -92,9 +92,6 @@ LLVMRustCreateTargetMachine(const char *triple,
     TargetOptions Options;
     Options.PositionIndependentExecutable = PositionIndependentExecutable;
     Options.NoFramePointerElim = NoFramePointerElim;
-#if LLVM_VERSION_MINOR < 5
-    Options.EnableSegmentedStacks = EnableSegmentedStacks;
-#endif
     Options.FloatABIType = FloatABI::Default;
     Options.UseSoftFloat = UseSoftFloat;
     if (UseSoftFloat) {
@@ -128,10 +125,8 @@ LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
     PassManagerBase *PM = unwrap(PMR);
 #if LLVM_VERSION_MINOR >= 6
     PM->add(new DataLayoutPass());
-#elif LLVM_VERSION_MINOR == 5
-    PM->add(new DataLayoutPass(unwrap(M)));
 #else
-    PM->add(new DataLayout(unwrap(M)));
+    PM->add(new DataLayoutPass(unwrap(M)));
 #endif
     unwrap(TM)->addAnalysisPasses(*PM);
 }
@@ -202,10 +197,8 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
   raw_fd_ostream OS(path, EC, sys::fs::F_None);
   if (EC)
     ErrorInfo = EC.message();
-#elif LLVM_VERSION_MINOR >= 4
-  raw_fd_ostream OS(path, ErrorInfo, sys::fs::F_None);
 #else
-  raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary);
+  raw_fd_ostream OS(path, ErrorInfo, sys::fs::F_None);
 #endif
   if (ErrorInfo != "") {
     LLVMRustSetLastError(ErrorInfo.c_str());
@@ -230,19 +223,13 @@ LLVMRustPrintModule(LLVMPassManagerRef PMR,
   raw_fd_ostream OS(path, EC, sys::fs::F_None);
   if (EC)
     ErrorInfo = EC.message();
-#elif LLVM_VERSION_MINOR >= 4
-  raw_fd_ostream OS(path, ErrorInfo, sys::fs::F_None);
 #else
-  raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary);
+  raw_fd_ostream OS(path, ErrorInfo, sys::fs::F_None);
 #endif
 
   formatted_raw_ostream FOS(OS);
 
-#if LLVM_VERSION_MINOR >= 5
   PM->add(createPrintModulePass(FOS));
-#else
-  PM->add(createPrintModulePass(&FOS));
-#endif
 
   PM->run(*unwrap(M));
 }
index 31f75ae03b0998688132ec9c75a311dac3e806ba..fe0a7b454c17da8740caf1fe6d4765d0f3467fd2 100644 (file)
@@ -412,7 +412,7 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateStaticVariable(
     bool isLocalToUnit,
     LLVMValueRef Val,
     LLVMMetadataRef Decl = NULL) {
-#if LLVM_VERSION_MINOR == 6
+#if LLVM_VERSION_MINOR >= 6
     return wrap(Builder->createGlobalVariable(unwrapDI<DIDescriptor>(Context),
 #else
     return wrap(Builder->createStaticVariable(unwrapDI<DIDescriptor>(Context),
@@ -440,7 +440,7 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateVariable(
     int64_t* AddrOps,
     unsigned AddrOpsCount,
     unsigned ArgNo) {
-#if LLVM_VERSION_MINOR < 6
+#if LLVM_VERSION_MINOR == 5
     if (AddrOpsCount > 0) {
         SmallVector<llvm::Value *, 16> addr_ops;
         llvm::Type *Int64Ty = Type::getInt64Ty(unwrap<MDNode>(Scope)->getContext());
@@ -707,12 +707,12 @@ extern "C" void LLVMWriteValueToString(LLVMValueRef Value, RustStringRef str) {
 extern "C" bool
 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
     Module *Dst = unwrap(dst);
-#if LLVM_VERSION_MINOR == 5
-    MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
-    ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
-#else
+#if LLVM_VERSION_MINOR >= 6
     std::unique_ptr<MemoryBuffer> buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
     ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
+#else
+    MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
+    ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
 #endif
     if (!Src) {
         LLVMRustSetLastError(Src.getError().message().c_str());
@@ -770,53 +770,74 @@ LLVMRustOpenArchive(char *path) {
     return ret;
 }
 
-extern "C" const char*
 #if LLVM_VERSION_MINOR >= 6
-LLVMRustArchiveReadSection(OwningBinary<Archive> *ob, char *name, size_t *size) {
-
-    Archive *ar = ob->getBinary();
+typedef OwningBinary<Archive> RustArchive;
+#define GET_ARCHIVE(a) ((a)->getBinary())
 #else
-LLVMRustArchiveReadSection(Archive *ar, char *name, size_t *size) {
+typedef Archive RustArchive;
+#define GET_ARCHIVE(a) (a)
 #endif
 
-    Archive::child_iterator child = ar->child_begin(),
-                              end = ar->child_end();
-    for (; child != end; ++child) {
-        ErrorOr<StringRef> name_or_err = child->getName();
-        if (name_or_err.getError()) continue;
-        StringRef sect_name = name_or_err.get();
-        if (sect_name.trim(" ") == name) {
-            StringRef buf = child->getBuffer();
-            *size = buf.size();
-            return buf.data();
-        }
-    }
-    return NULL;
+extern "C" void
+LLVMRustDestroyArchive(RustArchive *ar) {
+    delete ar;
+}
+
+struct RustArchiveIterator {
+    Archive::child_iterator cur;
+    Archive::child_iterator end;
+};
+
+extern "C" RustArchiveIterator*
+LLVMRustArchiveIteratorNew(RustArchive *ra) {
+    Archive *ar = GET_ARCHIVE(ra);
+    RustArchiveIterator *rai = new RustArchiveIterator();
+    rai->cur = ar->child_begin();
+    rai->end = ar->child_end();
+    return rai;
+}
+
+extern "C" const Archive::Child*
+LLVMRustArchiveIteratorCurrent(RustArchiveIterator *rai) {
+    if (rai->cur == rai->end)
+        return NULL;
+    const Archive::Child &ret = *rai->cur;
+    return &ret;
 }
 
 extern "C" void
-#if LLVM_VERSION_MINOR >= 6
-LLVMRustDestroyArchive(OwningBinary<Archive> *ar) {
-#else
-LLVMRustDestroyArchive(Archive *ar) {
-#endif
-    delete ar;
+LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) {
+    if (rai->cur == rai->end)
+        return;
+    ++rai->cur;
 }
 
 extern "C" void
-LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) {
-    GlobalValue *V = unwrap<GlobalValue>(Value);
-    V->setDLLStorageClass(GlobalValue::DLLExportStorageClass);
+LLVMRustArchiveIteratorFree(RustArchiveIterator *rai) {
+    delete rai;
 }
 
-extern "C" int
-LLVMVersionMinor() {
-    return LLVM_VERSION_MINOR;
+extern "C" const char*
+LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) {
+    ErrorOr<StringRef> name_or_err = child->getName();
+    if (name_or_err.getError())
+        return NULL;
+    StringRef name = name_or_err.get();
+    *size = name.size();
+    return name.data();
 }
 
-extern "C" int
-LLVMVersionMajor() {
-    return LLVM_VERSION_MAJOR;
+extern "C" const char*
+LLVMRustArchiveChildData(Archive::Child *child, size_t *size) {
+    StringRef buf = child->getBuffer();
+    *size = buf.size();
+    return buf.data();
+}
+
+extern "C" void
+LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) {
+    GlobalValue *V = unwrap<GlobalValue>(Value);
+    V->setDLLStorageClass(GlobalValue::DLLExportStorageClass);
 }
 
 // Note that the two following functions look quite similar to the
index 33dec63a728e1d874df2f75efbd18cf10571a5c8..8a4330acf43417e831690e9f564207685de03e5e 100644 (file)
 #include "llvm-c/ExecutionEngine.h"
 #include "llvm-c/Object.h"
 
-#if LLVM_VERSION_MINOR >= 5
 #include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DIBuilder.h"
 #include "llvm/Linker/Linker.h"
-#else
-#include "llvm/Assembly/PrintModulePass.h"
-#include "llvm/DebugInfo.h"
-#include "llvm/DIBuilder.h"
-#include "llvm/Linker.h"
-#endif
 
 // Used by RustMCJITMemoryManager::getPointerToNamedFunction()
 // to get around glibc issues. See the function for more information.
index 3d5e52d709df3ec4c1966eafc87252acd368efc0..6472c08c222965b6a6ba1a4e411747d3b26bc0ee 100644 (file)
@@ -8,10 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(core)]
-
-use std::marker::MarkerTrait;
-
-pub trait Foo : MarkerTrait {
+pub trait Foo {
     fn bar();
 }
index d96dfd848f3f0e3b8968c6086abcba5628228477..6cc2d427c25dcc6a41cdb3362e94147ad42a483c 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(std_misc, old_path)]
+#![feature(std_misc)]
 
 use std::dynamic_lib::DynamicLibrary;
 
index dc08033602c99dfa9a6f9f3aed31ce6ddf1c7412..37ee10c8d37333ec6e64793919ab8a1f504e14ca 100644 (file)
@@ -8,6 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(core)]
-
-trait Foo : ::std::marker::MarkerTrait {}
+trait Foo {}
index 8f11629be6cc83c054a577b22e3618b00e05112b..c2ff7a0054f19712bf95d0c3c34c0c5f4cf5d8e8 100644 (file)
@@ -14,7 +14,7 @@
 pub mod bar {
     use std::marker;
 
-    pub trait Bar: marker::MarkerTrait + 'static {}
+    pub trait Bar: 'static {}
 
     impl Bar for .. {}
 
index 7e10d2158ede08bda3eeba69d6cc8729f5b8c8b5..31a97f695f06cdbfcf20cd27edf87cb961020bb0 100644 (file)
 //! (#14132).
 
 #![crate_name = "a"]
-#![feature(core)]
-
-use std::marker::MarkerTrait;
 
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U : MarkerTrait {}
-pub trait V : MarkerTrait {}
+pub trait U {}
+pub trait V {}
 impl U for () {}
 impl V for () {}
 
index c5f38805511650925110d59c68159481bf2d0028..5339fc8295c6f57f56cfd7820e41cdb3d88be0fc 100644 (file)
 //! (#14132).
 
 #![crate_name = "a"]
-#![feature(core)]
-
-use std::marker::MarkerTrait;
 
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U : MarkerTrait {}
-pub trait V : MarkerTrait {}
+pub trait U {}
+pub trait V {}
 impl U for () {}
 impl V for () {}
 
index 3168e747eb6e694c6222848a08c389458f23ef14..2a5d9446f879ac65f8d8a4dff31c9616e89c7993 100644 (file)
 //! (#14132).
 
 #![crate_name = "a"]
-#![feature(core)]
-
-use std::marker::MarkerTrait;
 
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U : MarkerTrait {}
-pub trait V : MarkerTrait {}
+pub trait U {}
+pub trait V {}
 impl U for () {}
 impl V for () {}
 
index f86a43494f78e740718e55b9306b5d6758550f98..61f2f2803ab1891dc586ab781cea0158d513b8ed 100644 (file)
 //! (#14132).
 
 #![crate_name = "a"]
-#![feature(core)]
-
-use std::marker::MarkerTrait;
 
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U : MarkerTrait {}
-pub trait V : MarkerTrait {}
+pub trait U {}
+pub trait V {}
 impl U for () {}
 impl V for () {}
 
index dc412b700447beade18887dd4b577e60b3a393c4..270ce95be2bb62d70a0366920373362fb5a8e2ae 100644 (file)
 //! (#14132).
 
 #![crate_name = "a"]
-#![feature(core)]
-
-use std::marker::MarkerTrait;
 
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U : MarkerTrait {}
-pub trait V : MarkerTrait {}
+pub trait U {}
+pub trait V {}
 impl U for () {}
 impl V for () {}
 
index 0cfcbbb0554e684f7304a64001ad78234195afec..de4cc85a7dc4746bc238bbf344b797eb212de426 100644 (file)
 //! (#14132).
 
 #![crate_name = "a"]
-#![feature(core)]
-
-use std::marker::MarkerTrait;
 
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U : MarkerTrait {}
-pub trait V : MarkerTrait {}
+pub trait U {}
+pub trait V {}
 impl U for () {}
 impl V for () {}
 
index e1e32095b5cb40d4e4c9dc5582ae5679dec65234..62f7986f1c3bd729b67c8f50677d01395f20914e 100644 (file)
 #![crate_name = "a"]
 #![feature(core)]
 
-use std::marker::MarkerTrait;
-
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U : MarkerTrait {}
-pub trait V : MarkerTrait {}
+pub trait U {}
+pub trait V {}
 impl U for () {}
 impl V for () {}
 
index 9fd97376b6681232843fcea84aa0b42d06ec2ce9..22e40822eecfc8b52055dbeece2d9b99e58e88e4 100644 (file)
 //! (#14132).
 
 #![crate_name = "a"]
-#![feature(core)]
-
-use std::marker::MarkerTrait;
 
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U : MarkerTrait {}
-pub trait V : MarkerTrait {}
+pub trait U {}
+pub trait V {}
 impl U for () {}
 impl V for () {}
 
index e64bde096b0169b0a334ce420492f434f6a17e32..3d8a728967a4a64bcc274b11818dedc1690d5a2f 100644 (file)
 //! (#14132).
 
 #![crate_name = "a"]
-#![feature(core)]
-
-use std::marker::MarkerTrait;
 
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U : MarkerTrait {}
-pub trait V : MarkerTrait {}
+pub trait U {}
+pub trait V {}
 impl U for () {}
 impl V for () {}
 
index b16338f1e128c87d0bb3d6b7b44e41f1fb38b8e3..41d7eb7b18645f3ee181fee3406ec62aaea899fd 100644 (file)
 //! (#14132).
 
 #![crate_name = "a"]
-#![feature(core)]
-
-use std::marker::MarkerTrait;
 
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U : MarkerTrait {}
-pub trait V : MarkerTrait {}
+pub trait U {}
+pub trait V {}
 impl U for () {}
 impl V for () {}
 
index 7e10d2158ede08bda3eeba69d6cc8729f5b8c8b5..31a97f695f06cdbfcf20cd27edf87cb961020bb0 100644 (file)
 //! (#14132).
 
 #![crate_name = "a"]
-#![feature(core)]
-
-use std::marker::MarkerTrait;
 
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U : MarkerTrait {}
-pub trait V : MarkerTrait {}
+pub trait U {}
+pub trait V {}
 impl U for () {}
 impl V for () {}
 
index 8cadd7bdf4174e1faeca675ebde218ea6563c8e0..e405c337abe4aeb7ef7214625a275c5fc4931b75 100644 (file)
 //! (#14132).
 
 #![crate_name = "a"]
-#![feature(core)]
-
-use std::marker::MarkerTrait;
 
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U : MarkerTrait {}
-pub trait V : MarkerTrait {}
+pub trait U {}
+pub trait V {}
 impl U for () {}
 impl V for () {}
 
index fcaf77909554dd8bad665175ef690055b2540a61..9ef788c98427392bfa95bf1156149d7df9a99232 100644 (file)
 //! (#14132).
 
 #![crate_name = "a"]
-#![feature(core)]
-
-use std::marker::MarkerTrait;
 
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U : MarkerTrait {}
-pub trait V : MarkerTrait {}
+pub trait U {}
+pub trait V {}
 impl U for () {}
 impl V for () {}
 
index 0adedfd4eeb22c9f61c96b88c94b04fdc6d0f02b..c3ecbb014dc6b0aac1dfa9e077383a15e86b79cd 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(core)]
-
-pub trait Foo : ::std::marker::MarkerTrait {
+pub trait Foo {
 }
 
 impl Foo for isize {
index 5a7a3e7bcc6942ac1b5a7495bd8a569990674cd1..2e425ac96c55f9de510c0358e93105c48424d3ba 100644 (file)
@@ -11,9 +11,7 @@
 #![feature(optin_builtin_traits, core)]
 #![crate_type = "rlib"]
 
-use std::marker::MarkerTrait;
-
-pub trait DefaultedTrait : MarkerTrait { }
+pub trait DefaultedTrait { }
 impl DefaultedTrait for .. { }
 
 pub struct Something<T> { t: T }
index 46caed6f9f5f59c482bf879de7af0abdf2427c47..19f83c7817c7c384d2c3853ddfdcda82d6188d19 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-lexer-test FIXME #15679
 // Microbenchmarks for various functions in std and extra
 
 #![feature(rand, collections, std_misc)]
index c87cdb617a477732e093a26d53fefa3b622d6245..8048f3dde96826bc36b9fe17b1a24b5e551336e2 100644 (file)
@@ -16,7 +16,6 @@
 // This also serves as a pipes test, because Arcs are implemented with pipes.
 
 // no-pretty-expanded FIXME #15189
-// ignore-lexer-test FIXME #15679
 
 #![feature(std_misc)]
 
index c21470d4bb3e7f48e82ccf4f5b2c998382730d44..efbb5dfb5491ebe855be1249909590a2031c055a 100644 (file)
 
 // Multi-language Perlin noise benchmark.
 // See https://github.com/nsf/pnoise for timings and alternative implementations.
-// ignore-lexer-test FIXME #15679
 
 #![feature(rand, core)]
 
 use std::f32::consts::PI;
-use std::num::Float;
 use std::__rand::{Rng, thread_rng};
 
 #[derive(Copy, Clone)]
index 61fe6593dc398dd72381c5691bf9b5aa51d4e5f6..c576eea3602cb6b95669ac88c29ba6564d4f92c2 100644 (file)
@@ -109,8 +109,7 @@ fn main() {
     let long_lived_tree = bottom_up_tree(&long_lived_arena, 0, max_depth);
 
     let messages = (min_depth..max_depth + 1).step_by(2).map(|depth| {
-        use std::num::Int;
-        let iterations = 2.pow((max_depth - depth + min_depth) as u32);
+        let iterations = 2i32.pow((max_depth - depth + min_depth) as u32);
         thread::spawn(move || inner(depth, iterations))
     }).collect::<Vec<_>>();
 
index 0474cfb6fc8193c90356172d713afac0b17f32d2..accf525b4e6386ffe1e97faf4ea3189dd2c6f405 100644 (file)
@@ -43,7 +43,6 @@
 use std::fs::File;
 use std::io::{self, BufWriter};
 use std::io::prelude::*;
-use std::num::Float;
 
 const LINE_LENGTH: usize = 60;
 const IM: u32 = 139968;
index de7fb737958f2a1f3434b205aa411fe218d10471..368dbbb931c269e5b48e8041526b7c7ada882873 100644 (file)
@@ -38,9 +38,7 @@
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#![feature(core)]
-
-use std::num::Float;
+use std::mem;
 
 const PI: f64 = 3.141592653589793;
 const SOLAR_MASS: f64 = 4.0 * PI * PI;
@@ -193,16 +191,9 @@ fn main() {
 /// longer contain the mutable reference. This is a safe operation because the
 /// two mutable borrows are entirely disjoint.
 fn shift_mut_ref<'a, T>(r: &mut &'a mut [T]) -> Option<&'a mut T> {
-    use std::mem;
-    use std::raw::Repr;
-
-    if r.is_empty() { return None }
-    unsafe {
-        let mut raw = r.repr();
-        let ret = raw.data as *mut T;
-        raw.data = raw.data.offset(1);
-        raw.len -= 1;
-        *r = mem::transmute(raw);
-        Some({ &mut *ret })
-    }
+    let res = mem::replace(r, &mut []);
+    if res.is_empty() { return None }
+    let (a, b) = res.split_at_mut(1);
+    *r = b;
+    Some(&mut a[0])
 }
index b0e8c39567323b4b32ec5d5d8503c57095051995..0fa22abde3cbd9ee695ec1b392bd9aa6d415b9c1 100644 (file)
@@ -46,7 +46,6 @@
 use std::iter::repeat;
 use std::thread;
 use std::mem;
-use std::num::Float;
 use std::os;
 use std::env;
 use std::raw::Repr;
index 3913de3a3f99f49a5202859b11eef6e9016d76bb..16742f0a6e1a56f5ad2520beaeb591ffd597cb1b 100644 (file)
@@ -16,7 +16,6 @@
 use std::io::prelude::*;
 use std::io;
 use std::iter::repeat;
-use std::num::Int;
 use std::env;
 
 // Computes a single solution to a given 9x9 sudoku
index 7a362994b8db6fe6948a3cd8bfef77b0e324118b..396b1c1de3aa0e735bb108f89a28ad6c1fc339cc 100644 (file)
@@ -11,7 +11,6 @@
 // aux-build:rlib_crate_test.rs
 // ignore-stage1
 // ignore-tidy-linelength
-// ignore-android
 // ignore-cross-compile gives a different error message
 
 #![feature(plugin)]
index 0d68b960f31356d2227f227ced2ff65ff402a2f8..1f9dfdb18470b3718b97289e62345b762f748e65 100644 (file)
@@ -10,7 +10,7 @@
 
 // Check that an associated type cannot be bound in an expression path.
 
-trait Foo : ::std::marker::MarkerTrait {
+trait Foo {
     type A;
     fn bar() -> isize;
 }
index 5c36e3356a5c026c8d3175fc64d567eae3355179..82258f124d3233da297edae2e9447118e814e45a 100644 (file)
@@ -11,7 +11,7 @@
 // Test that we do not ICE when an impl is missing an associated type (and that we report
 // a useful error, of course).
 
-trait Trait : ::std::marker::MarkerTrait {
+trait Trait {
     type Type;
 }
 
index 5632f148da67ce2e1d00f4f0738c07406c00f88d..9436f825de89dd4b95a51cc7e6f7ce4ad320bcdd 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo : ::std::marker::MarkerTrait {
+trait Foo {
     type X;
     type Y;
 }
index 5f1cd2444d3c4870ad7295fc0df47162a576e307..bda16c8a85de15d03c00c2470688bb3cb34b158a 100644 (file)
@@ -19,7 +19,7 @@
 // which checks that the trait interface itself is not considered an
 // error as long as all impls satisfy the constraint.
 
-trait Get : ::std::marker::MarkerTrait {
+trait Get {
     type Value;
 }
 
index 24429a482057c7e71067a70137f1457f58dbf570..233532a6085803400c5ae04f9edbf1d70b4f94a9 100644 (file)
@@ -19,7 +19,7 @@
 // which checks that the trait interface itself is not considered an
 // error as long as all impls satisfy the constraint.
 
-trait Get : ::std::marker::MarkerTrait {
+trait Get {
     type Value;
 }
 
index 8832028f9aba1e87781545bb2426653882439b3c..aecbf217a5b25e916155829b81188bf7401049ac 100644 (file)
@@ -10,7 +10,7 @@
 
 // Check that an associated type cannot be bound in an expression path.
 
-trait Foo : ::std::marker::MarkerTrait {
+trait Foo {
     type A;
     fn bar() -> isize;
 }
index 5878e9a9f649be3b1e80adb796ba44f634305bb5..fca74e457c21e17be2a9889919730ee6926c32d4 100644 (file)
@@ -10,7 +10,7 @@
 
 use std::cell::RefCell;
 
-trait Trait : ::std::marker::MarkerTrait {}
+trait Trait {}
 
 pub fn main() {
     let x: Vec<Trait + Sized> = Vec::new();
diff --git a/src/test/compile-fail/cast-to-unsized-trait-object-suggestion.rs b/src/test/compile-fail/cast-to-unsized-trait-object-suggestion.rs
new file mode 100644 (file)
index 0000000..4e6ae96
--- /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.
+
+fn main() {
+    &1 as Copy;
+    //~^ ERROR cast to unsized type
+    //~| HELP try casting to a reference instead:
+    //~| SUGGESTION &1 as &Copy;
+    Box::new(1) as Copy;
+    //~^ ERROR cast to unsized type
+    //~| HELP try casting to a `Box` instead:
+    //~| SUGGESTION Box::new(1) as Box<Copy>;
+}
index 98a9c713e84c331c9d305a63ff0ffa0cb79cec4f..b771b959d3e507ef1cf5001777109b9f1cef7e94 100644 (file)
@@ -10,7 +10,6 @@
 
 use std::fmt::Debug;
 use std::default::Default;
-use std::marker::MarkerTrait;
 
 // Test that two blanket impls conflict (at least without negative
 // bounds).  After all, some other crate could implement Even or Odd
@@ -20,9 +19,9 @@ trait MyTrait {
     fn get(&self) -> usize;
 }
 
-trait Even : MarkerTrait { }
+trait Even { }
 
-trait Odd : MarkerTrait { }
+trait Odd { }
 
 impl Even for isize { }
 
index 57d25a3bf586dcab40fe8df4857095ca8db25ed7..d3b0e7f10b91bc815a32a1f21384bc2bfd9fd5e9 100644 (file)
@@ -19,9 +19,9 @@ trait MyTrait {
     fn get(&self) -> usize;
 }
 
-trait Even : ::std::marker::MarkerTrait { }
+trait Even {}
 
-trait Odd : ::std::marker::MarkerTrait { }
+trait Odd {}
 
 impl<T:Even> MyTrait for T { //~ ERROR E0119
     fn get(&self) -> usize { 0 }
index a225f6cf473041387b09124fbe54803d4f65f645..55c9ba2a0e89aeda6cfb43ea13f0bdd4e8ba049f 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(optin_builtin_traits)]
 
-trait MyTrait : ::std::marker::MarkerTrait {}
+trait MyTrait {}
 
 struct TestType<T>(::std::marker::PhantomData<T>);
 
index 062a4a43b694b14ae86ef57172f3032a5b25e286..cccc8b05b3038b8ae719f192badcb5906edc43b5 100644 (file)
 
 #![feature(optin_builtin_traits)]
 
-use std::marker::MarkerTrait;
-
-trait MyTrait: MarkerTrait {}
+trait MyTrait {}
 
 impl MyTrait for .. {}
 
 impl MyTrait for .. {}
 //~^ ERROR conflicting implementations for trait `MyTrait`
 
-trait MySafeTrait: MarkerTrait {}
+trait MySafeTrait {}
 
 unsafe impl MySafeTrait for .. {}
 //~^ ERROR implementing the trait `MySafeTrait` is not unsafe
 
-unsafe trait MyUnsafeTrait: MarkerTrait {}
+unsafe trait MyUnsafeTrait {}
 
 impl MyUnsafeTrait for .. {}
 //~^ ERROR the trait `MyUnsafeTrait` requires an `unsafe impl` declaration
index c4e95e772356a8f471b59632b41914ccf459ed98..a6b62d17bc4e6aa9ac34540d80911fa8b0865294 100644 (file)
 
 extern crate coherence_copy_like_lib as lib;
 
-use std::marker::MarkerTrait;
-
 struct MyType { x: i32 }
 
-trait MyTrait : MarkerTrait { }
+trait MyTrait { }
 
 impl<T: lib::MyCopy> MyTrait for T { } //~ ERROR E0119
 
index f768a475ee820701332512b21ed921a36fd433e0..5a9f440f8bb6a98900bb406b1976d6a056232c1b 100644 (file)
 
 extern crate coherence_copy_like_lib as lib;
 
-use std::marker::MarkerTrait;
-
 struct MyType { x: i32 }
 
-trait MyTrait : MarkerTrait { }
+trait MyTrait { }
 impl<T: lib::MyCopy> MyTrait for T { } //~ ERROR E0119
 
 // `MyStruct` is not declared fundamental, therefore this would
index 0c78fffd2dfab2ca1a7094eb6fcf21508143f2ef..ee0d5550fd61f0ea8e514bec49a723935cf31ac6 100644 (file)
 
 extern crate coherence_copy_like_lib as lib;
 
-use std::marker::MarkerTrait;
-
 struct MyType { x: i32 }
 
-trait MyTrait : MarkerTrait { }
+trait MyTrait { }
 impl<T: lib::MyCopy> MyTrait for T { } //~ ERROR E0119
 
 // Tuples are not fundamental, therefore this would require that
index aa687266acb8f701c9bae3461bb8b71c1c63c3e8..160197368d6d983c673f924eb1508fbd62e1a3b1 100644 (file)
@@ -15,7 +15,7 @@ struct Fat<T: ?Sized> {
 }
 
 struct Foo;
-trait Bar : ::std::marker::MarkerTrait {}
+trait Bar {}
 impl Bar for Foo {}
 
 pub fn main() {
index 8ec1034bc4d28abda4abda17968fad6296a7f160..b30eada162b84707134573888de917956f8ca50c 100644 (file)
 
 // Test implicit coercions involving DSTs and raw pointers.
 
-use std::marker::MarkerTrait;
-
 struct S;
-trait T : MarkerTrait {}
+trait T {}
 impl T for S {}
 
 struct Foo<T: ?Sized> {
diff --git a/src/test/compile-fail/feature-gate-negate-unsigned.rs b/src/test/compile-fail/feature-gate-negate-unsigned.rs
new file mode 100644 (file)
index 0000000..7dc654f
--- /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 negating unsigned integers is gated by `negate_unsigned` feature
+// gate
+
+const MAX: usize = -1;
+//~^ ERROR unary negation of unsigned integers may be removed in the future
+
+fn main() {}
diff --git a/src/test/compile-fail/feature-gate-on-unimplemented.rs b/src/test/compile-fail/feature-gate-on-unimplemented.rs
new file mode 100644 (file)
index 0000000..5d32bba
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that `#[rustc_on_unimplemented]` is gated by `on_unimplemented` feature
+// gate.
+
+#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"]
+//~^ ERROR the `#[rustc_on_unimplemented]` attribute is an experimental feature
+trait Foo<Bar>
+{}
+
+fn main() {}
diff --git a/src/test/compile-fail/feature-gate-optin-builtin-traits.rs b/src/test/compile-fail/feature-gate-optin-builtin-traits.rs
new file mode 100644 (file)
index 0000000..59d7473
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that default and negative trait implementations are gated by
+// `optin_builtin_traits` feature gate
+
+struct DummyStruct;
+
+trait DummyTrait {
+    fn dummy(&self) {}
+}
+
+impl DummyTrait for .. {}
+//~^ ERROR default trait implementations are experimental and possibly buggy
+
+impl !DummyTrait for DummyStruct {}
+//~^ ERROR negative trait bounds are not yet fully implemented; use marker types for now
+
+fn main() {}
diff --git a/src/test/compile-fail/feature-gate-plugin.rs b/src/test/compile-fail/feature-gate-plugin.rs
new file mode 100644 (file)
index 0000000..3b5d762
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that `#![plugin(...)]` attribute is gated by `plugin` feature gate
+
+#![plugin(foo)]
+//~^ ERROR compiler plugins are experimental and possibly buggy
+
+fn main() {}
diff --git a/src/test/compile-fail/feature-gate-rustc-attrs.rs b/src/test/compile-fail/feature-gate-rustc-attrs.rs
new file mode 100644 (file)
index 0000000..dab44b6
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-linelength
+
+// Test that `#[rustc_*]` attributes are gated by `rustc_attrs` feature gate.
+
+#[rustc_variance] //~ ERROR the `#[rustc_variance]` attribute is an experimental feature
+#[rustc_error] //~ ERROR the `#[rustc_error]` attribute is an experimental feature
+#[rustc_move_fragments] //~ ERROR the `#[rustc_move_fragments]` attribute is an experimental feature
+#[rustc_foo]
+//~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics
+
+fn main() {}
diff --git a/src/test/compile-fail/feature-gate-rustc-diagnostic-macros.rs b/src/test/compile-fail/feature-gate-rustc-diagnostic-macros.rs
new file mode 100644 (file)
index 0000000..8286d83
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that diagnostic macros are gated by `rustc_diagnostic_macros` feature
+// gate
+
+__register_diagnostic!(E0001);
+//~^ ERROR macro undefined: '__register_diagnostic!'
+
+fn main() {
+    __diagnostic_used!(E0001);
+    //~^ ERROR macro undefined: '__diagnostic_used!'
+}
+
+__build_diagnostic_array!(DIAGNOSTICS);
+//~^ ERROR macro undefined: '__build_diagnostic_array!'
diff --git a/src/test/compile-fail/feature-gate-slice-patterns.rs b/src/test/compile-fail/feature-gate-slice-patterns.rs
new file mode 100644 (file)
index 0000000..625cb2d
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that slice pattern syntax is gated by `slice_patterns` feature gate
+
+fn main() {
+    let x = [1, 2, 3, 4, 5];
+    match x {
+        [1, 2, xs..] => {} //~ ERROR slice pattern syntax is experimental
+    }
+}
diff --git a/src/test/compile-fail/gated-box-patterns.rs b/src/test/compile-fail/gated-box-patterns.rs
deleted file mode 100644 (file)
index d82d0de..0000000
+++ /dev/null
@@ -1,21 +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 patterns including the box syntax are gated by `box_patterns` feature gate.
-
-fn main() {
-    let x = Box::new(1);
-
-    match x {
-        box 1 => (),
-        //~^ box pattern syntax is experimental
-        _     => ()
-    };
-}
diff --git a/src/test/compile-fail/gated-simd-ffi.rs b/src/test/compile-fail/gated-simd-ffi.rs
deleted file mode 100644 (file)
index 883e1be..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that the use of smid types in the ffi is gated by `smid_ffi` feature gate.
-
-#![feature(simd)]
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-#[simd]
-pub struct f32x4(f32, f32, f32, f32);
-
-#[allow(dead_code)]
-extern {
-    fn foo(x: f32x4);
-    //~^ ERROR use of SIMD type `f32x4` in FFI is highly experimental and may result in invalid code
-    //~| HELP add #![feature(simd_ffi)] to the crate attributes to enable
-}
-
-fn main() {}
index 6a9c30480527470f6f6e20c018822761bf9ca44f..e116966670d2b7bda22c03def4a8c3f930e065f3 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::num::SignedInt;
-
 fn main() {
-    let _f = 10.abs; //~ ERROR attempted to take value of method
+    let _f = 10i32.abs; //~ ERROR attempted to take value of method
 }
index cd3f337c4ab658e2194dc2ab8686eaaac2105eb7..251da2c6b3ee979c020bf7e21c55d490c5a4dadd 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::marker::MarkerTrait;
-
-trait Node : MarkerTrait {
+trait Node {
     fn zomg();
 }
 
index 0b846651acf46dbf0e51056e8d31742859ddeb4c..51deb99a4f2cda7747feae6e2df16f83c0f80e9e 100644 (file)
@@ -9,9 +9,8 @@
 // except according to those terms.
 
 use std::fmt::Debug;
-use std::marker::MarkerTrait;
 
-trait Str : MarkerTrait {}
+trait Str {}
 
 trait Something {
     fn yay<T: Debug>(_: Option<Self>, thing: &[T]);
index b4abef0bd280b914aa20d155a0ac18f07740f432..a3529c9ea90b671d21d9274c51166f826da4aa34 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::marker::MarkerTrait;
-
-trait ListItem<'a> : MarkerTrait {
+trait ListItem<'a> {
     fn list_name() -> &'a str;
 }
 
index 68ddef671887852f14b200910d6a2529ccf9be92..46a64f99354c61c98ef48a0ed056f1a9bc29369c 100644 (file)
@@ -16,7 +16,7 @@ fn main() {
     // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
     let _bar = Box::new(1_usize) as std::fmt::Debug;
     //~^ ERROR cast to unsized type: `Box<usize>` as `core::fmt::Debug`
-    //~^^ HELP did you mean `Box<core::fmt::Debug>`?
+    //~^^ HELP try casting to a `Box` instead
 
     let _baz = 1_usize as std::fmt::Debug;
     //~^ ERROR cast to unsized type: `usize` as `core::fmt::Debug`
index 60ab616d5983bf25a4dcad218fa39f5a321caf18..6300a1dc15d6015cec6aea8b0c34743a529f13f4 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::marker::MarkerTrait;
-
-pub trait AbstractRenderer : MarkerTrait {}
+pub trait AbstractRenderer {}
 
 fn _create_render(_: &()) ->
     AbstractRenderer
index 271c31bd375484c6ef7c763e8c67f5079433ce75..41be78dd7b96eede5f0c9aa46bf702cad8fe9ca1 100644 (file)
@@ -8,14 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(unboxed_closures)]
-
 use std::any::Any;
 use std::any::TypeId;
-use std::marker::MarkerTrait;
 
-pub trait Pt : MarkerTrait {}
-pub trait Rt : MarkerTrait {}
+pub trait Pt {}
+pub trait Rt {}
 
 trait Private<P: Pt, R: Rt> {
     fn call(&self, p: P, r: R);
index e81a576fa63d50d9267acf4e1eb82d70ba183fd0..a662e9ca98ee812086e338e874234fd0a00a1f91 100644 (file)
@@ -8,13 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::marker::MarkerTrait;
-
 fn add_state(op: <isize as HasState>::State) {
 //~^ ERROR the trait `HasState` is not implemented for the type `isize`
 }
 
-trait HasState : MarkerTrait {
+trait HasState {
     type State;
 }
 
index 01fc4fef03b1ddd5a4112662992e37df184108e4..d89b2c6ce8cb0221e9a64a922e4e8f683909da57 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::marker::MarkerTrait;
-
-trait Foo : MarkerTrait {
+trait Foo {
     type Item;
 }
 
index 9e63cc203f4d5951a024d3cfe350d1f7f26bb9de..20bd8af7c3ef5ecf3e18cee657cfdc24276765e3 100644 (file)
 // cause compiler to loop.  Note that no instances
 // of such a type could ever be constructed.
 
-use std::marker::MarkerTrait;
-
 struct t(Box<t>); //~ ERROR this type cannot be instantiated
 
-trait to_str_2 : MarkerTrait {
+trait to_str_2 {
     fn my_to_string() -> String;
 }
 
index 5b623ac377b21260948f9ddbbb34a95dab1998f5..a38278eae2411f1c92871586e0d33d907f51faab 100644 (file)
 // away.
 
 use std::cell::RefCell;
-use std::marker::MarkerTrait;
 use std::ops::{Shl, Shr};
 
-pub trait Subscriber : MarkerTrait {
+pub trait Subscriber {
     type Input;
 }
 
index ff5ac9de8d9443872de7b03f350ba1f0c3652dc4..b77230a8b340d1dfb145b608b7c034409b9eeec3 100644 (file)
@@ -12,9 +12,7 @@
 
 #![feature(optin_builtin_traits)]
 
-use std::marker::MarkerTrait;
-
-unsafe trait Trait: MarkerTrait {
+unsafe trait Trait {
 //~^ error: traits with default impls (`e.g. unsafe impl Trait for ..`) must have no methods or associated items
     type Output;
 }
index 2b732899ea42fb222bcd21faa287520dbd955e61..026ee89c0b2b5a4dd940e0ec690a6412891516aa 100644 (file)
@@ -8,7 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::num::ToPrimitive;
+pub trait ToPrimitive {
+    fn to_int(&self) -> isize { 0 }
+}
+
+impl ToPrimitive for i32 {}
+impl ToPrimitive for isize {}
 
 trait Add {
     fn to_int(&self) -> isize;
index d316b44794ad6e38c1a6749aad984e84060b8ace..9e324cdd61eb0e82f40308131b51c72d1d1ce360 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::marker::MarkerTrait;
-
-trait I : MarkerTrait {}
+trait I {}
 type K = I+'static;
 
 fn foo(_x: K) {} //~ ERROR: the trait `core::marker::Sized` is not implemented
index b0db990619535534dc4bf8b7c5baebef9bab6203..9ff957b6e6deac4904d0d5066390bd4dd53e2803 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::marker::MarkerTrait;
-
-trait A : MarkerTrait {}
+trait A {}
 
 struct Struct {
     r: A+'static
@@ -22,6 +20,6 @@ fn new_struct(r: A+'static)
     Struct { r: r }
 }
 
-trait Curve : MarkerTrait {}
+trait Curve {}
 enum E {X(Curve+'static)}
 fn main() {}
index d035c615ec3781a5d16f08da9bc10d479884593d..e464ddf54c2d998fcb08370ae315a552bee56af6 100644 (file)
@@ -15,5 +15,5 @@ struct Monster {
 
 fn main() {
     let _m = Monster(); //~ ERROR `Monster` is a structure name, but
-    //~^ HELP Did you mean to write: `Monster { /* fields */ }`?
+    //~^ HELP did you mean to write: `Monster { /* fields */ }`?
 }
index 9c019f6ec47fb91a1d17733f737fd44083f7cc58..6b320f400a8091dcc9e8f5e31c1f7a26d009fe39 100644 (file)
 
 // Test the mechanism for warning about possible missing `self` declarations.
 
-use std::marker::MarkerTrait;
-
 trait CtxtFn {
     fn f8(self, usize) -> usize;
     fn f9(usize) -> usize; //~ NOTE candidate
 }
 
-trait OtherTrait : MarkerTrait {
+trait OtherTrait {
     fn f9(usize) -> usize; //~ NOTE candidate
 }
 
@@ -26,7 +24,7 @@ trait OtherTrait : MarkerTrait {
 // declaration to match against, so we wind up prisizeing it as a
 // candidate. This seems not unreasonable -- perhaps the user meant to
 // implement it, after all.
-trait UnusedTrait : MarkerTrait {
+trait UnusedTrait {
     fn f9(usize) -> usize; //~ NOTE candidate
 }
 
@@ -54,7 +52,7 @@ fn fff(i: isize) -> isize { //~ NOTE candidate
     }
 }
 
-trait ManyImplTrait : MarkerTrait {
+trait ManyImplTrait {
     fn is_str() -> bool { //~ NOTE candidate
         false
     }
index 1925caf6870eef80aab0daa80651683ffbbe46d8..d43ddff6b9500af1b7a8d0abcd056e7f9c418945 100644 (file)
 
 // Test which of the builtin types are considered POD.
 
-use std::marker::MarkerTrait;
 use std::rc::Rc;
 
 fn assert_copy<T:Copy>() { }
 
-trait Dummy : MarkerTrait { }
+trait Dummy { }
 
 #[derive(Copy, Clone)]
 struct MyStruct {
index fd0789421e0045fb4a5c45f25076c139a8ac7e2c..66297d70ef505cccb7e3f7f9f7c0a1dfa22bad8a 100644 (file)
@@ -10,9 +10,7 @@
 
 #![feature(box_syntax)]
 
-use std::marker::MarkerTrait;
-
-trait Foo : MarkerTrait {
+trait Foo {
 }
 
 impl<T:Copy> Foo for T {
index 0c68401bb2b955222bbd712a92ee02f8603ae50e..570f7ad7fe3bf214adae00a7ac6644053305dd6c 100644 (file)
 // in this file all test the "kind" violates detected during kindck.
 // See all `regions-bounded-by-send.rs`
 
-use std::marker::MarkerTrait;
-
 fn assert_send<T:Send>() { }
-trait Dummy : MarkerTrait { }
+trait Dummy { }
 trait Message : Send { }
 
 // careful with object types, who knows what they close over...
index f86eac8b16bd2bcfdb158fbb58315b6dd1d4c2d8..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!
 
-use std::marker::MarkerTrait;
-
 fn assert_send<T:Send+'static>() { }
-trait Dummy : MarkerTrait { }
+trait Dummy { }
 
 // careful with object types, who knows what they close over...
 fn test51<'a>() {
index 08516e67318ce2b5ff0e31efd4a9ef16a0eb8445..d3d166e2a6916181d24c32984ed212bca92a07e6 100644 (file)
 
 // Continue kindck-send-object1.rs.
 
-use std::marker::MarkerTrait;
-
 fn assert_send<T:Send>() { }
-trait Dummy : MarkerTrait { }
+trait Dummy { }
 
 fn test50() {
     assert_send::<&'static Dummy>(); //~ ERROR the trait `core::marker::Sync` is not implemented
index 918b4ee209ca7ac6106a3fcd18d3b7d17e7185ea..c6dc3b70bef37d881f3e12196ecb84b493cc0045 100644 (file)
@@ -105,7 +105,7 @@ impl PrivTrait for (Private<isize>,) {
     fn bar(&self) -> Private<isize> { panic!() }
 }
 
-pub trait ParamTrait<T> : marker::MarkerTrait {
+pub trait ParamTrait<T> {
     fn foo() -> T;
 }
 
index e1ae3ae464f98bd2c052a0e8a0fc2272a40438e2..f0792c145d2a20ff4850aece15fe3602eafc547d 100644 (file)
@@ -16,6 +16,6 @@ fn main() {
         let _: i32 = 'inner: loop { break 'inner }; //~ ERROR mismatched types
     }
     loop {
-        let _: i32 = 'inner: loop { loop { break 'inner } }; //~ ERROR mismatched types
+        let _: i32 = 'inner2: loop { loop { break 'inner2 } }; //~ ERROR mismatched types
     }
 }
diff --git a/src/test/compile-fail/loops-reject-duplicate-labels-2.rs b/src/test/compile-fail/loops-reject-duplicate-labels-2.rs
new file mode 100644 (file)
index 0000000..68627ec
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(rustc_attrs)]
+
+// ignore-tidy-linelength
+
+// Issue #21633: reject duplicate loop labels in function bodies.
+//
+// This is testing the generalization (to the whole function body)
+// discussed here:
+// http://internals.rust-lang.org/t/psa-rejecting-duplicate-loop-labels/1833
+
+pub fn foo() {
+    { 'fl: for _ in 0..10 { break; } }   //~ NOTE shadowed label `'fl` declared here
+    { 'fl: loop { break; } }             //~ WARN label name `'fl` shadows a label name that is already in scope
+
+    { 'lf: loop { break; } }             //~ NOTE shadowed label `'lf` declared here
+    { 'lf: for _ in 0..10 { break; } }   //~ WARN label name `'lf` shadows a label name that is already in scope
+
+    { 'wl: while 2 > 1 { break; } }      //~ NOTE shadowed label `'wl` declared here
+    { 'wl: loop { break; } }             //~ WARN label name `'wl` shadows a label name that is already in scope
+
+    { 'lw: loop { break; } }             //~ NOTE shadowed label `'lw` declared here
+    { 'lw: while 2 > 1 { break; } }      //~ WARN label name `'lw` shadows a label name that is already in scope
+
+    { 'fw: for _ in 0..10 { break; } }   //~ NOTE shadowed label `'fw` declared here
+    { 'fw: while 2 > 1 { break; } }      //~ WARN label name `'fw` shadows a label name that is already in scope
+
+    { 'wf: while 2 > 1 { break; } }      //~ NOTE shadowed label `'wf` declared here
+    { 'wf: for _ in 0..10 { break; } }   //~ WARN label name `'wf` shadows a label name that is already in scope
+
+    { 'tl: while let Some(_) = None::<i32> { break; } } //~ NOTE shadowed label `'tl` declared here
+    { 'tl: loop { break; } }             //~ WARN label name `'tl` shadows a label name that is already in scope
+
+    { 'lt: loop { break; } }             //~ NOTE shadowed label `'lt` declared here
+    { 'lt: while let Some(_) = None::<i32> { break; } }
+                                        //~^ WARN label name `'lt` shadows a label name that is already in scope
+}
+
+#[rustc_error]
+pub fn main() { //~ ERROR compilation successful
+    foo();
+}
diff --git a/src/test/compile-fail/loops-reject-duplicate-labels.rs b/src/test/compile-fail/loops-reject-duplicate-labels.rs
new file mode 100644 (file)
index 0000000..15446bf
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(rustc_attrs)]
+
+// ignore-tidy-linelength
+
+// Issue #21633: reject duplicate loop labels in function bodies.
+// This is testing the exact cases that are in the issue description.
+
+fn foo() {
+    'fl: for _ in 0..10 { break; } //~ NOTE shadowed label `'fl` declared here
+    'fl: loop { break; }           //~ WARN label name `'fl` shadows a label name that is already in scope
+
+    'lf: loop { break; }           //~ NOTE shadowed label `'lf` declared here
+    'lf: for _ in 0..10 { break; } //~ WARN label name `'lf` shadows a label name that is already in scope
+
+    'wl: while 2 > 1 { break; }    //~ NOTE shadowed label `'wl` declared here
+    'wl: loop { break; }           //~ WARN label name `'wl` shadows a label name that is already in scope
+
+    'lw: loop { break; }           //~ NOTE shadowed label `'lw` declared here
+    'lw: while 2 > 1 { break; }    //~ WARN label name `'lw` shadows a label name that is already in scope
+
+    'fw: for _ in 0..10 { break; } //~ NOTE shadowed label `'fw` declared here
+    'fw: while 2 > 1 { break; }    //~ WARN label name `'fw` shadows a label name that is already in scope
+
+    'wf: while 2 > 1 { break; }    //~ NOTE shadowed label `'wf` declared here
+    'wf: for _ in 0..10 { break; } //~ WARN label name `'wf` shadows a label name that is already in scope
+
+    'tl: while let Some(_) = None::<i32> { break; } //~ NOTE shadowed label `'tl` declared here
+    'tl: loop { break; }           //~ WARN label name `'tl` shadows a label name that is already in scope
+
+    'lt: loop { break; }           //~ NOTE shadowed label `'lt` declared here
+    'lt: while let Some(_) = None::<i32> { break; }
+                                  //~^ WARN label name `'lt` shadows a label name that is already in scope
+}
+
+// Note however that it is okay for the same label to be reused in
+// different methods of one impl, as illustrated here.
+
+struct S;
+impl S {
+    fn m1(&self) { 'okay: loop { break 'okay; } }
+    fn m2(&self) { 'okay: loop { break 'okay; } }
+}
+
+#[rustc_error]
+pub fn main() { //~ ERROR compilation successful
+    let s = S;
+    s.m1();
+    s.m2();
+    foo();
+}
diff --git a/src/test/compile-fail/loops-reject-labels-shadowing-lifetimes.rs b/src/test/compile-fail/loops-reject-labels-shadowing-lifetimes.rs
new file mode 100644 (file)
index 0000000..bbdd077
--- /dev/null
@@ -0,0 +1,120 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Issue #21633: reject duplicate loop labels in function bodies.
+// This is testing interaction between lifetime-params and labels.
+
+#![feature(rustc_attrs)]
+
+#![allow(dead_code, unused_variables)]
+
+fn foo() {
+    fn foo<'a>() { //~ NOTE shadowed lifetime `'a` declared here
+        'a: loop { break 'a; }
+        //~^ WARN label name `'a` shadows a lifetime name that is already in scope
+    }
+
+    struct Struct<'b, 'c> { _f: &'b i8, _g: &'c i8 }
+    enum Enum<'d, 'e> { A(&'d i8), B(&'e i8) }
+
+    impl<'d, 'e> Struct<'d, 'e> {
+        fn meth_okay() {
+            'a: loop { break 'a; }
+            'b: loop { break 'b; }
+            'c: loop { break 'c; }
+        }
+    }
+
+    impl <'d, 'e> Enum<'d, 'e> {
+        fn meth_okay() {
+            'a: loop { break 'a; }
+            'b: loop { break 'b; }
+            'c: loop { break 'c; }
+        }
+    }
+
+    impl<'bad, 'c> Struct<'bad, 'c> { //~ NOTE shadowed lifetime `'bad` declared here
+        fn meth_bad(&self) {
+            'bad: loop { break 'bad; }
+            //~^ WARN label name `'bad` shadows a lifetime name that is already in scope
+        }
+    }
+
+    impl<'b, 'bad> Struct<'b, 'bad> { //~ NOTE shadowed lifetime `'bad` declared here
+        fn meth_bad2(&self) {
+            'bad: loop { break 'bad; }
+            //~^ WARN label name `'bad` shadows a lifetime name that is already in scope
+        }
+    }
+
+    impl<'b, 'c> Struct<'b, 'c> {
+        fn meth_bad3<'bad>(x: &'bad i8) { //~ NOTE shadowed lifetime `'bad` declared here
+            'bad: loop { break 'bad; }
+            //~^ WARN label name `'bad` shadows a lifetime name that is already in scope
+        }
+
+        fn meth_bad4<'a,'bad>(x: &'a i8, y: &'bad i8) {
+            //~^ NOTE shadowed lifetime `'bad` declared here
+            'bad: loop { break 'bad; }
+            //~^ WARN label name `'bad` shadows a lifetime name that is already in scope
+        }
+    }
+
+    impl <'bad, 'e> Enum<'bad, 'e> { //~ NOTE shadowed lifetime `'bad` declared here
+        fn meth_bad(&self) {
+            'bad: loop { break 'bad; }
+            //~^ WARN label name `'bad` shadows a lifetime name that is already in scope
+        }
+    }
+    impl <'d, 'bad> Enum<'d, 'bad> { //~ NOTE shadowed lifetime `'bad` declared here
+        fn meth_bad2(&self) {
+            'bad: loop { break 'bad; }
+            //~^ WARN label name `'bad` shadows a lifetime name that is already in scope
+        }
+    }
+    impl <'d, 'e> Enum<'d, 'e> {
+        fn meth_bad3<'bad>(x: &'bad i8) { //~ NOTE shadowed lifetime `'bad` declared here
+            'bad: loop { break 'bad; }
+            //~^ WARN label name `'bad` shadows a lifetime name that is already in scope
+        }
+
+        fn meth_bad4<'a,'bad>(x: &'bad i8) { //~ NOTE shadowed lifetime `'bad` declared here
+            'bad: loop { break 'bad; }
+            //~^ WARN label name `'bad` shadows a lifetime name that is already in scope
+        }
+    }
+
+    trait HasDefaultMethod1<'bad> { //~ NOTE shadowed lifetime `'bad` declared here
+        fn meth_okay() {
+            'c: loop { break 'c; }
+        }
+        fn meth_bad(&self) {
+            'bad: loop { break 'bad; }
+            //~^ WARN label name `'bad` shadows a lifetime name that is already in scope
+        }
+    }
+    trait HasDefaultMethod2<'a,'bad> { //~ NOTE shadowed lifetime `'bad` declared here
+        fn meth_bad(&self) {
+            'bad: loop { break 'bad; }
+            //~^ WARN label name `'bad` shadows a lifetime name that is already in scope
+        }
+    }
+    trait HasDefaultMethod3<'a,'b> {
+        fn meth_bad<'bad>(&self) { //~ NOTE shadowed lifetime `'bad` declared here
+            'bad: loop { break 'bad; }
+            //~^ WARN label name `'bad` shadows a lifetime name that is already in scope
+        }
+    }
+}
+
+#[rustc_error]
+pub fn main() { //~ ERROR compilation successful
+    foo();
+}
diff --git a/src/test/compile-fail/loops-reject-lifetime-shadowing-label.rs b/src/test/compile-fail/loops-reject-lifetime-shadowing-label.rs
new file mode 100644 (file)
index 0000000..2344d25
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(rustc_attrs)]
+
+#![allow(dead_code, unused_variables)]
+
+// Issue #21633:  reject duplicate loop labels in function bodies.
+//
+// Test rejection of lifetimes in *expressions* that shadow loop labels.
+
+fn foo() {
+    // Reusing lifetime `'a` in function item is okay.
+    fn foo<'a>(x: &'a i8) -> i8 { *x }
+
+    // So is reusing `'a` in struct item
+    struct S1<'a> { x: &'a i8 } impl<'a> S1<'a> { fn m(&self) {} }
+    // and a method item
+    struct S2; impl S2 { fn m<'a>(&self) {} }
+
+    let z = 3_i8;
+
+    'a: loop { //~ NOTE shadowed label `'a` declared here
+        let b = Box::new(|x: &i8| *x) as Box<for <'a> Fn(&'a i8) -> i8>;
+        //~^ WARN lifetime name `'a` shadows a label name that is already in scope
+        assert_eq!((*b)(&z), z);
+        break 'a;
+    }
+}
+
+#[rustc_error]
+pub fn main() { //~ ERROR compilation successful
+    foo();
+}
index 607ab13d122015d6f8ff42e92c56a5a3d5ed8062..efbf3782f9796a4b34ed979e293f60837032e67e 100644 (file)
@@ -11,9 +11,7 @@
 // Test that an object type `Box<Foo>` is not considered to implement the
 // trait `Foo`. Issue #5087.
 
-use std::marker::MarkerTrait;
-
-trait Foo : MarkerTrait {}
+trait Foo {}
 fn take_foo<F:Foo>(f: F) {}
 fn take_object(f: Box<Foo>) { take_foo(f); }
 //~^ ERROR the trait `Foo` is not implemented
index aae829ec7b5636c124b55bd953b59f78cbcff1fe..6a010d49692d26450a4d95225eb3695c4509b0cd 100644 (file)
@@ -11,7 +11,7 @@
 // Check that we correctly prevent users from making trait objects
 // from traits with static methods.
 
-trait Foo : ::std::marker::MarkerTrait {
+trait Foo {
     fn foo();
 }
 
index c912d084daa86f1ad4ddf3b09b7f452d6f9f1f58..071b4db40f86f5c7a60a4869093715f993a6d90f 100644 (file)
@@ -14,9 +14,9 @@
 
 #![feature(optin_builtin_traits)]
 
-use std::marker::{MarkerTrait, PhantomData};
+use std::marker::{PhantomData};
 
-unsafe trait Zen: MarkerTrait {}
+unsafe trait Zen {}
 
 unsafe impl Zen for .. {}
 
index 67bb566ea682c07b1568202a6c213156d3a92d46..7fe0574ab7d9a663902dd9433fcc6a01145f3b4c 100644 (file)
@@ -17,9 +17,7 @@
 
 // public type, private value
 pub mod foo1 {
-    use std::marker::MarkerTrait;
-
-    pub trait Bar : MarkerTrait {
+    pub trait Bar {
     }
     pub struct Baz;
 
@@ -41,7 +39,7 @@ fn test_list1() {
 
 // private type, public value
 pub mod foo2 {
-    trait Bar : ::std::marker::MarkerTrait {
+    trait Bar {
     }
     pub struct Baz;
 
@@ -62,7 +60,7 @@ fn test_list2() {
 
 // neither public
 pub mod foo3 {
-    trait Bar : ::std::marker::MarkerTrait {
+    trait Bar {
     }
     pub struct Baz;
 
diff --git a/src/test/compile-fail/region-bound-extra-bound-in-impl.rs b/src/test/compile-fail/region-bound-extra-bound-in-impl.rs
new file mode 100644 (file)
index 0000000..5bcc6be
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Regression test for issue #22779. An extra where clause was
+// permitted on the impl that is not present on the trait.
+
+trait Tr<'a, T> {
+    fn renew<'b: 'a>(self) -> &'b mut [T];
+}
+
+impl<'a, T> Tr<'a, T> for &'a mut [T] {
+    fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b {
+        //~^ ERROR lifetime bound not satisfied
+        &mut self[..]
+    }
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/region-bound-extra-bound-in-inherent-impl.rs b/src/test/compile-fail/region-bound-extra-bound-in-inherent-impl.rs
new file mode 100644 (file)
index 0000000..c1df057
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test related to #22779. In this case, the impl is an inherent impl,
+// so it doesn't have to match any trait, so no error results.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+struct MySlice<'a, T:'a>(&'a mut [T]);
+
+impl<'a, T> MySlice<'a, T> {
+    fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b {
+        &mut self.0[..]
+    }
+}
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/region-bound-same-bounds-in-trait-and-impl.rs b/src/test/compile-fail/region-bound-same-bounds-in-trait-and-impl.rs
new file mode 100644 (file)
index 0000000..3115e5a
--- /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.
+
+// Test related to #22779, but where the `'a:'b` relation
+// appears in the trait too. No error here.
+
+#![feature(rustc_attrs)]
+
+trait Tr<'a, T> {
+    fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b;
+}
+
+impl<'a, T> Tr<'a, T> for &'a mut [T] {
+    fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b {
+        &mut self[..]
+    }
+}
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
index 1bb2bb5a15450f3aa774ded692b1ac6f0e610626..f95ee405895a9c78cd286b54e98e09ea255d2fc5 100644 (file)
@@ -11,7 +11,7 @@
 // Test that attempts to implicitly coerce a value into an
 // object respect the lifetime bound on the object type.
 
-trait Foo : ::std::marker::MarkerTrait {}
+trait Foo {}
 impl<'a> Foo for &'a [u8] {}
 
 // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
index 278ccd3c11936f3b931d0cd2ce64912ec55cc0c5..abffd33e3f83e857a192aa63a1264621be8f52a5 100644 (file)
@@ -50,7 +50,9 @@ fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
     fn okay_bound<'b,'c,'e:'b+'c>(self, b: Inv<'b>, c: Inv<'c>, e: Inv<'e>) {
     }
 
-    fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) {}
+    fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) {
+        //~^ ERROR lifetime bound not satisfied
+    }
 }
 
 fn main() { }
index f80b0ffa5aadf09eb20cc9447601b900dc949f3c..fdc97ecaf21e271949bed51a125266d3cefb9781 100644 (file)
@@ -12,9 +12,7 @@
 
 // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
 
-use std::marker::MarkerTrait;
-
-trait X : MarkerTrait {}
+trait X {}
 
 trait Iter {
     type Item: X;
index 2341d2397c9b04d5f635fe6ade7e86c675ae5853..25b8137d29cade512868ecfdaa54e2a228611ea8 100644 (file)
@@ -10,9 +10,7 @@
 
 #![feature(box_syntax)]
 
-use std::marker::MarkerTrait;
-
-trait Foo : MarkerTrait { }
+trait Foo { }
 
 impl<'a> Foo for &'a isize { }
 
index 110b1a0d90c22dbf9ddeb83ec23a112d436fa87d..8cbab5f8308098d149bbce068fe189bee1f8b88e 100644 (file)
 impl<'a> Foo<'a> {
     //~^ NOTE shadowed lifetime `'a` declared here
     fn shadow_in_method<'a>(&'a self) -> &'a isize {
-        //~^ ERROR lifetime name `'a` shadows another lifetime name that is already in scope
+        //~^ ERROR lifetime name `'a` shadows a lifetime name that is already in scope
         self.0
     }
 
     fn shadow_in_type<'b>(&'b self) -> &'b isize {
         //~^ NOTE shadowed lifetime `'b` declared here
         let x: for<'b> fn(&'b isize) = panic!();
-        //~^ ERROR lifetime name `'b` shadows another lifetime name that is already in scope
+        //~^ ERROR lifetime name `'b` shadows a lifetime name that is already in scope
         self.0
     }
 
index db16e7c0138242e298e7c687af5aef9462204463..b0efdfd1818bdb453dcdafee58266531487b2617 100644 (file)
@@ -8,11 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// These two generate an error to satisfy the compile-fail test
-#![deny(warnings)]
-#![feature(blah)] //~ ERROR
-
-#[unstable] //~ WARNING: stability attributes are deprecated
-#[stable] //~ WARNING: stability attributes are deprecated
-#[deprecated] //~ WARNING: stability attributes are deprecated
+#[unstable] //~ ERROR: stability attributes may not be used
+#[stable] //~ ERROR: stability attributes may not be used
+#[deprecated] //~ ERROR: stability attributes may not be used
 fn main() { }
index 1fd711ca4fb2c4eb898df30eaacf112ae0307693..b864e6ca9578b7878d0b62a1bb6d7279a3173ad3 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait TraitNotAStruct : ::std::marker::MarkerTrait { }
+trait TraitNotAStruct {}
 
 fn main() {
     TraitNotAStruct{ value: 0 };
index ce0a7d3bb36cf1bca80b0de8ba253f9450c2335d..c18c5b386e8b21816be1abd6ff4e38818ea86978 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::marker::MarkerTrait;
-
-trait Trait : MarkerTrait {}
+trait Trait {}
 
 struct Foo<T:Trait> {
     x: T,
index e4058a0943aadb770f92e4edfe031b2fd91c18f7..0a36fcbed690513e6137d88b715b87db25dd8de6 100644 (file)
@@ -10,9 +10,7 @@
 
 // Tests for "default" bounds inferred for traits with no bounds list.
 
-use std::marker::MarkerTrait;
-
-trait Foo : MarkerTrait {}
+trait Foo {}
 
 fn a(_x: Box<Foo+Send>) {
 }
index 2f4793b4d888f094ea5eaf8fa4594608d640def9..dadcbd5bce710291c706ad4a4209374352549d1b 100644 (file)
@@ -12,9 +12,7 @@
 // trait impl is only applied to a trait object, not concrete types which implement
 // the trait.
 
-use std::marker::MarkerTrait;
-
-trait T : MarkerTrait {}
+trait T {}
 
 impl<'a> T+'a {
     fn foo(&self) {}
diff --git a/src/test/compile-fail/trait-object-reference-without-parens-suggestion.rs b/src/test/compile-fail/trait-object-reference-without-parens-suggestion.rs
new file mode 100644 (file)
index 0000000..fc2ed83
--- /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.
+
+fn main() {
+    let _: &Copy + 'static;
+    //~^ ERROR expected a path
+    //~| HELP try adding parentheses
+    //~| SUGGESTION let _: &(Copy + 'static);
+    let _: &'static Copy + 'static;
+    //~^ ERROR expected a path
+    //~| HELP try adding parentheses
+    //~| SUGGESTION let _: &'static (Copy + 'static);
+}
index 88d8788d63a3de54bdcdc0f8dc3b1313558f709a..155b835bbc6e0704d4e24657cb40398c6d7f7615 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::num::Int;
+use std::ops::Add;
 
-trait BrokenAdd: Int {
+trait BrokenAdd: Copy + Add<Output=Self> {
     fn broken_add<T>(&self, rhs: T) -> Self {
         *self + rhs //~  ERROR mismatched types
                     //~| expected `Self`
@@ -20,7 +20,7 @@ fn broken_add<T>(&self, rhs: T) -> Self {
     }
 }
 
-impl<T: Int> BrokenAdd for T {}
+impl<T: Copy + Add<Output=T>> BrokenAdd for T {}
 
 pub fn main() {
     let foo: u8 = 0;
index 0f3453da43137ef6892aed003a15005e7c0fed69..a27f7f7ebbe0f4b405d5d701bbb8309bd9de464f 100644 (file)
@@ -10,9 +10,7 @@
 
 #![feature(optin_builtin_traits)]
 
-use std::marker::MarkerTrait;
-
-trait MyTrait: MarkerTrait {}
+trait MyTrait {}
 
 impl MyTrait for .. {}
 
index 524f467e017002c21a36e0f92530ffb5fa0c36e6..24819bb4f08d63a51f7db7752df8bfbdf14766f3 100644 (file)
@@ -10,9 +10,7 @@
 
 #![feature(optin_builtin_traits)]
 
-use std::marker::MarkerTrait;
-
-trait MyTrait: MarkerTrait {}
+trait MyTrait {}
 
 impl MyTrait for .. {}
 impl<T> !MyTrait for *mut T {}
index a1ca0e3e0fada28d79303481a32dedf925a282e1..4b91d0b7a736c6f1c1f5d4b692c23fa854333894 100644 (file)
 
 #![feature(optin_builtin_traits)]
 
-use std::marker::MarkerTrait;
-
-trait MyTrait: MarkerTrait {}
+trait MyTrait {}
 
 impl MyTrait for .. {}
 
-unsafe trait MyUnsafeTrait: MarkerTrait {}
+unsafe trait MyUnsafeTrait {}
 
 unsafe impl MyUnsafeTrait for .. {}
 
index 4006eb2e83ed92383d1e755b09c398c2b24e459b..c67fc92313c3a58d29e714db80e0b8003cb55419 100644 (file)
 
 #![feature(optin_builtin_traits)]
 
-use std::marker::MarkerTrait;
-
-trait Defaulted : MarkerTrait { }
+trait Defaulted { }
 impl Defaulted for .. { }
 impl<'a,T:Signed> Defaulted for &'a T { }
 impl<'a,T:Signed> Defaulted for &'a mut T { }
 fn is_defaulted<T:Defaulted>() { }
 
-trait Signed : MarkerTrait { }
+trait Signed { }
 impl Signed for i32 { }
 
 fn main() {
index 4a6a77ac7b440950c3c7b4df4a337977ae1bb4cf..aa918119fbceef87840dcd9cb859562c23a51442 100644 (file)
@@ -13,8 +13,6 @@
 
 #![feature(optin_builtin_traits)]
 
-use std::marker::MarkerTrait;
-
 trait MyTrait : 'static {}
 
 impl MyTrait for .. {}
index 7f24058e475facaae3e247488dae5a3e89d06299..c9bfdff6c0e495cd78a089e0d4b2d96fcc2fe421 100644 (file)
@@ -13,9 +13,7 @@
 
 #![feature(optin_builtin_traits)]
 
-use std::marker::MarkerTrait;
-
-trait NotImplemented: MarkerTrait { }
+trait NotImplemented { }
 
 trait MyTrait : NotImplemented {}
 
index c970aaaf5d471ce69254c4338234d0ea206499db..4f572e87639f051208ba7efa78d14a961e8e35ab 100644 (file)
 
 #![feature(optin_builtin_traits)]
 
-use std::marker::MarkerTrait;
+trait NotImplemented { }
 
-trait NotImplemented: MarkerTrait { }
-
-trait MyTrait: MarkerTrait
+trait MyTrait
     where Option<Self> : NotImplemented
 {}
 
index f31a6ffdc0d7caed0084f23af4f661bd4df45f64..3f18f359d306e711ee4be2c654e0382d38a8d8c7 100644 (file)
@@ -10,9 +10,7 @@
 
 // Test `?Sized` local variables.
 
-use std::marker;
-
-trait T : marker::MarkerTrait { }
+trait T {}
 
 fn f1<X: ?Sized>(x: &X) {
     let _: X; // <-- this is OK, no bindings created, no initializer.
index 6ea3d0720eeeb716e3ae07325963865ce5d70b0e..0245a1b5cf2c8628e39abbf80b87c47d5c868b88 100644 (file)
@@ -10,9 +10,7 @@
 
 // Test sized-ness checking in substitution in impls.
 
-use std::marker::MarkerTrait;
-
-trait T : MarkerTrait {}
+trait T {}
 
 // I would like these to fail eventually.
 // impl - bounded
index a5471e87f220403b242351530204b04e9557e7f9..8594c35f8dd1b1fbdb569c7e5f26ab8d174dd527 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15679
 
 fn foo<
     'β, //~ ERROR non-ascii idents are not fully supported
index 13dc0c6d12007e1f9dc5a8d8b0450783e69143b2..67975d02b19f06f1a037091612338475d11b47fd 100644 (file)
@@ -12,8 +12,6 @@
 
 // aux-build:issue13213aux.rs
 
-#![feature(old_io)]
-
 extern crate issue13213aux;
 
 // compile-flags:-g
index 4d40f86b97182d74313819abb93a72f5a705e643..09d32a71dea48f6d5e0f660da9d1cd94633ad516 100644 (file)
@@ -11,6 +11,8 @@
 // compile-flags: -Z parse-only
 
 fn main() {
-    box(1 + 1) //~ HELP perhaps you meant `box() (foo)` instead?
+    box (1 + 1)
+    //~^ HELP try using `box()` instead:
+    //~| SUGGESTION box() (1 + 1)
     ; //~ ERROR expected expression, found `;`
 }
index a5d82277d2f94aaa66de840350b9d03503b57efd..2dc7e8f952549dad342370cc4bc12997134000ea 100644 (file)
@@ -14,7 +14,6 @@
 // ignore-tidy-cr
 // ignore-tidy-tab
 // pp-exact:block-comment-wchar.pp
-// ignore-lexer-test FIXME #15679
 fn f() {
     fn nested() {
         /*
index eb6d2a4a0a17392851e3808808b65721053ac897..6f4a95e7c9b00443d6ae5148312cff9782e537a6 100644 (file)
@@ -14,7 +14,6 @@
 // ignore-tidy-cr
 // ignore-tidy-tab
 // pp-exact:block-comment-wchar.pp
-// ignore-lexer-test FIXME #15679
 fn f() {
     fn nested() {
         /*
index 509bee9def2731e2d65023c0fd98e1a4d35af415..a5246b9300c91ad2f1f4149e0d732ad6b19634c5 100644 (file)
@@ -8,13 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(optin_builtin_traits, core)]
+#![feature(optin_builtin_traits)]
 
 // pp-exact
 
-use std::marker::MarkerTrait;
-
-trait MyTrait: MarkerTrait { }
+trait MyTrait { }
 
 impl MyTrait for .. { }
 
diff --git a/src/test/run-make/archive-duplicate-names/Makefile b/src/test/run-make/archive-duplicate-names/Makefile
new file mode 100644 (file)
index 0000000..72c2d38
--- /dev/null
@@ -0,0 +1,11 @@
+-include ../tools.mk
+
+all:
+       mkdir $(TMPDIR)/a
+       mkdir $(TMPDIR)/b
+       $(CC) -c -o $(TMPDIR)/a/foo.o foo.c
+       $(CC) -c -o $(TMPDIR)/b/foo.o bar.c
+       ar crus $(TMPDIR)/libfoo.a $(TMPDIR)/a/foo.o $(TMPDIR)/b/foo.o
+       $(RUSTC) foo.rs
+       $(RUSTC) bar.rs
+       $(call RUN,bar)
diff --git a/src/test/run-make/archive-duplicate-names/bar.c b/src/test/run-make/archive-duplicate-names/bar.c
new file mode 100644 (file)
index 0000000..a25fa10
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+void bar() {}
diff --git a/src/test/run-make/archive-duplicate-names/bar.rs b/src/test/run-make/archive-duplicate-names/bar.rs
new file mode 100644 (file)
index 0000000..1200a6d
--- /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.
+
+extern crate foo;
+
+fn main() {
+    foo::baz();
+}
diff --git a/src/test/run-make/archive-duplicate-names/foo.c b/src/test/run-make/archive-duplicate-names/foo.c
new file mode 100644 (file)
index 0000000..61d5d15
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+void foo() {}
diff --git a/src/test/run-make/archive-duplicate-names/foo.rs b/src/test/run-make/archive-duplicate-names/foo.rs
new file mode 100644 (file)
index 0000000..24b4734
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "rlib"]
+
+#[link(name = "foo", kind = "static")]
+extern {
+    fn foo();
+    fn bar();
+}
+
+pub fn baz() {
+    unsafe {
+        foo();
+        bar();
+    }
+}
index 02af5244b8aabe93cf4e7f208e8d51957b2f506a..fd69d2786b8d0800adb74bc000a7b73b638e1c0f 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(old_io, old_path)]
-
 use std::env;
 use std::fs::File;
 use std::process::Command;
index b93bdbaa16f2abe5414dadb0bc2399b5acf2d5b9..244f32b8ee5fc323feaf63457562faf436f95bb2 100644 (file)
@@ -8,10 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(std_misc, old_path, os)]
+#![feature(std_misc)]
 
 use std::dynamic_lib::DynamicLibrary;
-use std::os;
 use std::path::Path;
 
 pub fn main() {
index fe0f32d97d6b102c07e0d49cd80293934503436c..4d75e58aad938a05cb65590936ea8f9636c78e7c 100644 (file)
@@ -25,8 +25,6 @@
 use sub::sub2;
 use sub::sub2::nested_struct as sub_struct;
 use std::num::One;
-use std::num::cast;
-use std::num::{from_int,from_i8,from_i32};
 
 use std::mem::size_of;
 
@@ -42,7 +40,6 @@ fn test_alias<I: Iterator>(i: Option<<I as Iterator>::Item>) {
 
     // import tests
     fn foo(x: &One) {}
-    let _: Option<u8> = from_i32(45);
 
     let x = 42;
 
index 68a6a5fbfe86425d49b1e9892427bce94c43b174..dc0fcec1980fd1f18ad85d728f7ef0dbcb998419 100644 (file)
@@ -27,7 +27,8 @@ define MK_TARGETS
 # on some platforms, but LLVM just prints a warning so that's fine for
 # now.
 $(1): simd.rs
-       $$(RUSTC) --target=$(1) --emit=llvm-ir,asm simd.rs -C target-feature='+neon,+sse2'
+       $$(RUSTC) --target=$(1) --emit=llvm-ir,asm simd.rs \
+                -C target-feature='+neon,+sse2' -C extra-filename=-$(1)
 endef
 
 $(foreach targetxxx,$(TARGETS),$(eval $(call MK_TARGETS,$(targetxxx))))
index 4bacde0aadf3fc67fed7a79fbef5e90361342828..1cf36dab395fd3f1091014239be44fa40264d3b5 100644 (file)
@@ -10,7 +10,7 @@
 
 // Test that the CompilerCalls interface to the compiler works.
 
-// ignore-android
+// ignore-cross-compile
 
 #![feature(rustc_private, path)]
 #![feature(core)]
index e4fb7c199094722d2987568c42f5fcbe08c8528e..e22736d77856a266fecb7e9b211214d3f4f3d1e5 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android
+// ignore-cross-compile
 
 #![feature(rustc_private)]
 
index 7e64bbdf703b7911dee91dc0173d2f995d1cfeb5..ea7e959a73ce82dc5605e58c76eaf09dd6d8e45d 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // no-prefer-dynamic
-// ignore-android
+// ignore-cross-compile
 
 #![feature(rustc_private)]
 
index 40947b2e25652fd3e494fe91309a0110bfdfb1c6..a439e2bb25b8c4df6b61dd223b6bb27c05f733da 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // ignore-pretty
-// ignore-android
+// ignore-cross-compile
 
 #![feature(quote, rustc_private)]
 
index e1ef32b64d7152c4f8baecfd545cb393ae46a94f..829fdb176bd3198ef38a3d9c3d76b131a068c1bd 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android
+// ignore-cross-compile
 // ignore-pretty: does not work well with `--test`
 
 #![feature(quote, rustc_private)]
index 7e11b9d9f278956289aca857a8ba66e4e0a7adbb..710b3b07549f9e11b6216ad2312dddc2a782e6c4 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-cross-compile
 // ignore-pretty
 // ignore-test
 
index 99e0333ee29856f52ce5af6651d1019fcb67e02c..64061eb09324794ec1bc7de892bf329eb2207820 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android
+// ignore-cross-compile
 // ignore-pretty: does not work well with `--test`
 
 #![feature(quote, rustc_private)]
index 928368fabdf3684dde673bca6478dce74e612d05..e9de95b95e5fd0cb1c47a519611fc94dd455d8c2 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android
+// ignore-cross-compile
 // ignore-pretty: does not work well with `--test`
 
 #![feature(quote, rustc_private)]
index a0644e513a6e9727c5e988b31f961f953a9b9074..2bec41f3ee040d7dfb8cb33d912d8292b30dc881 100644 (file)
@@ -11,7 +11,7 @@
 // This test can't be a unit test in std,
 // because it needs TempDir, which is in extra
 
-// ignore-android
+// ignore-cross-compile
 
 #![feature(rustc_private, path_ext)]
 
index 06521e0ec78e8164d3d37dbbb0f37cf31326ae09..2617a05fe24141e42a33e7aa438fff4e5a7807b1 100644 (file)
@@ -8,12 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-#![feature(core)]
-
-use std::marker::MarkerTrait;
-
-trait Foo : MarkerTrait {
+trait Foo {
     type T;
 }
 
index a601dc0739a467715a400448c1fd4945a0f9c7bd..c93a0b76a95600c31ec10a6a7be9089f6f5de019 100644 (file)
 
 // pretty-expanded FIXME #23616
 
-#![feature(core)]
-
-use std::marker::MarkerTrait;
-
 impl X for f64 { type Y = isize; }
-trait X : MarkerTrait { type Y; }
+trait X { type Y; }
 fn main() {}
index a26b428a4eacf2db945eb1b0654ff920bc31b996..83f0d360e6122cd7b6f5572ecb8af8c1267efa01 100644 (file)
 
 #![feature(core)]
 
-use std::marker::MarkerTrait;
 use std::slice;
 
-trait Bound : MarkerTrait {}
+trait Bound {}
 
 impl<'a> Bound for &'a i32 {}
 
index d95ad2e883471dacb595f5db819e22428758ff6f..7e2d1aa23149dea229d017bbac6c56951b5bc58a 100644 (file)
 
 // pretty-expanded FIXME #23616
 
-#![feature(core)]
 #![allow(dead_code)]
 
-use std::marker::MarkerTrait;
-
-pub trait Integral : MarkerTrait {
+pub trait Integral {
     type Opposite;
 }
 
index dfd468884a167ec2df94020703dfb1b3c615d3da..1830b41d0b50681ee7a986b259ae0ca1d7e4655a 100644 (file)
 // `Item` originates in a where-clause, not the declaration of
 // `T`. Issue #20300.
 
-
-#![feature(core)]
-
-use std::marker::{MarkerTrait, PhantomData};
+use std::marker::{PhantomData};
 use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
 use std::sync::atomic::Ordering::SeqCst;
 
 static COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
 
 // Preamble.
-trait Trait : MarkerTrait { type Item; }
+trait Trait { type Item; }
 struct Struct;
 impl Trait for Struct {
     type Item = u32;
index fbe2a65bc893719e4fec693f056314704ed1aec4..9f7b98a57fcec74d44ce0ad11879c3d6851af041 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15883
 
 
 static FOO: u8 = b'\xF0';
index 50f05c050b173cfee3f3d3a12a006eee5fd746a0..0fa67e873f89c4bb866383c6c44f759716066d29 100644 (file)
@@ -11,9 +11,7 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-#![feature(unboxed_closures, old_io)]
-
-use std::mem;
+#![feature(unboxed_closures)]
 
 fn call_it<F>(f: F)
     where F : FnOnce(String) -> String
index 4b32ee352311d1d50c3eefa7c585a2e1b4d32807..a29953bea887bbb0869515b499ac1347c673639c 100644 (file)
@@ -11,7 +11,6 @@
 
 macro_rules! assert_approx_eq {
     ($a:expr, $b:expr) => ({
-        use std::num::Float;
         let (a, b) = (&$a, &$b);
         assert!((*a - *b).abs() < 1.0e-6,
                 "{} is not approximately equal to {}", *a, *b);
index 3b1e04be78d48d220bb8186715e49b19f65f1b1d..0d45a5d52124d08694b21de408fff8083040b3e3 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15877
 
 
 // Tests that we can call a function bounded over a supertrait from
index fbc6c28fd4a580e6e43e208aa5cdbe385d3cd773..0234d7b0b6376e06fa6d4982a597ee0ee8d5fb5a 100644 (file)
@@ -31,7 +31,6 @@ enum Bar {
     Quux(u32),
 }
 
-#[derive(FromPrimitive)]
 enum Baz { A=0, B=5, }
 
 fn main() {
diff --git a/src/test/run-pass/deriving-primitive.rs b/src/test/run-pass/deriving-primitive.rs
deleted file mode 100644 (file)
index 4399d74..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(core)]
-
-use std::num::FromPrimitive;
-use std::isize;
-
-#[derive(PartialEq, FromPrimitive, Debug)]
-enum A {
-    Foo = isize::MAX,
-    Bar = 1,
-    Baz = 3,
-    Qux,
-}
-
-pub fn main() {
-    let x: Option<A> = FromPrimitive::from_int(isize::MAX);
-    assert_eq!(x, Some(A::Foo));
-
-    let x: Option<A> = FromPrimitive::from_int(1);
-    assert_eq!(x, Some(A::Bar));
-
-    let x: Option<A> = FromPrimitive::from_int(3);
-    assert_eq!(x, Some(A::Baz));
-
-    let x: Option<A> = FromPrimitive::from_int(4);
-    assert_eq!(x, Some(A::Qux));
-
-    let x: Option<A> = FromPrimitive::from_int(5);
-    assert_eq!(x, None);
-}
index 9dd458344cb5a3399e219f9ff74bb84fc76e5259..15f229dbca5d908869512b48cee4d9b62561c781 100644 (file)
@@ -9,11 +9,9 @@
 // except according to those terms.
 
 
-#![feature(str_words)]
-
 fn main() {
     let foo = "hello".to_string();
-    let foo: Vec<&str> = foo.words().collect();
+    let foo: Vec<&str> = foo.split_whitespace().collect();
     let invalid_string = &foo[0];
     assert_eq!(*invalid_string, "hello");
 }
index 7bd292e66f2585975499986084be4eb6fd63132d..0a490466ef73b3f109b38b62e50ed2e7c9402fdc 100644 (file)
@@ -10,8 +10,8 @@
 
 // pretty-expanded FIXME #23616
 
-use std::num::Int;
+use std::ops::Add;
 
-fn wsucc<T:Int>(n: T) -> T { n + { return n } }
+fn wsucc<T:Add<Output=T> + Copy>(n: T) -> T { n + { return n } }
 
 pub fn main() { }
diff --git a/src/test/run-pass/exponential-notation.rs b/src/test/run-pass/exponential-notation.rs
deleted file mode 100644 (file)
index 4d54bb4..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-#![feature(std_misc)]
-
-use std::num::strconv::ExponentFormat::{ExpBin, ExpDec};
-use std::num::strconv::SignificantDigits::DigMax;
-use std::num::strconv::SignFormat::{SignAll, SignNeg};
-use std::num::strconv::float_to_str_common as to_string;
-
-macro_rules! t {
-    ($a:expr, $b:expr) => { { let (r, _) = $a; assert_eq!(r, $b.to_string()); } }
-}
-
-pub fn main() {
-    // Basic usage
-    t!(to_string(1.2345678e-5f64, 10, true, SignNeg, DigMax(6), ExpDec, false),
-             "1.234568e-5");
-
-    // Hexadecimal output
-    t!(to_string(7.281738281250e+01f64, 16, true, SignAll, DigMax(6), ExpBin, false),
-              "+1.2345p+6");
-    t!(to_string(-1.777768135071e-02f64, 16, true, SignAll, DigMax(6), ExpBin, false),
-             "-1.2345p-6");
-
-    // Some denormals
-    t!(to_string(4.9406564584124654e-324f64, 10, true, SignNeg, DigMax(6), ExpBin, false),
-             "1p-1074");
-    t!(to_string(2.2250738585072009e-308f64, 10, true, SignNeg, DigMax(6), ExpBin, false),
-             "1p-1022");
-}
index 28a076113d1f093d257e1e86a1ab8014013fa45f..421b19f2864fe6050edbf81576e87640adba5567 100644 (file)
@@ -8,12 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-#![feature(core)]
-
-use std::marker::MarkerTrait;
-
-trait A : MarkerTrait {
+trait A {
     extern "fastcall" fn test1(i: i32);
     extern fn test2(i: i32);
 }
index 298f2a4719db9f4ebbb84331e3fc660b441ed5d7..856599431fd18149dfec2e84e1072f0c9076b45c 100644 (file)
@@ -8,17 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-#![feature(std_misc)]
-
-use std::num::Float;
+use std::f64;
 
 pub fn main() {
-  let nan: f64 = Float::nan();
+  let nan: f64 = f64::NAN;
   assert!((nan).is_nan());
 
-  let inf: f64 = Float::infinity();
-  let neg_inf: f64 = Float::neg_infinity();
+  let inf: f64 = f64::INFINITY;
+  let neg_inf: f64 = -f64::INFINITY;
   assert_eq!(-inf, neg_inf);
 
   assert!( nan !=  nan);
index 589d6e1581bde7914ec3662c514991f800bf48da..5b45f1e0d392896a8176dfa12ed08e7d905202cc 100644 (file)
 
 // ignore-pretty: pprust doesn't print hygiene output
 
+// Test that labels injected by macros do not break hygiene.  This
+// checks cases where the macros invocations are under the rhs of a
+// let statement.
+
+// Issue #24278: The label/lifetime shadowing checker from #24162
+// conservatively ignores hygiene, and thus issues warnings that are
+// both true- and false-positives for this test.
+
 macro_rules! loop_x {
     ($e: expr) => {
         // $e shouldn't be able to interact with this 'x
index df72a5410a2b2e505807eb306772790fbc837770..a5882f022920fb227a7528cf1fb6bc752b8cd825 100644 (file)
@@ -8,6 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Test that labels injected by macros do not break hygiene.
+
+// Issue #24278: The label/lifetime shadowing checker from #24162
+// conservatively ignores hygiene, and thus issues warnings that are
+// both true- and false-positives for this test.
 
 macro_rules! loop_x {
     ($e: expr) => {
index ea9db9b1e1f8d91aabb86d5628b4c727f9af657f..240b6286c8cfc64d43f03d3c9cad0b3b96dc0660 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // no-pretty-expanded unnecessary unsafe block generated
-// ignore-lexer-test FIXME #15679
 
 #![deny(warnings)]
 #![allow(unused_must_use)]
@@ -196,9 +195,11 @@ fn test_write() {
         write!(w, "{}", "hello");
         writeln!(w, "{}", "line");
         writeln!(w, "{foo}", foo="bar");
+        w.write_char('☃');
+        w.write_str("str");
     }
 
-    t!(buf, "34helloline\nbar\n");
+    t!(buf, "34helloline\nbar\n☃str");
 }
 
 // Just make sure that the macros are defined, there's not really a lot that we
index 8db29ebaa6d3e90eacb40e6af37a366e95409aed..37ceaae373b9468a0c6392493be126d533b372af 100644 (file)
@@ -13,7 +13,6 @@
 
 macro_rules! assert_approx_eq {
     ($a:expr, $b:expr) => ({
-        use std::num::Float;
         let (a, b) = (&$a, &$b);
         assert!((*a - *b).abs() < 1.0e-6,
                 "{} is not approximately equal to {}", *a, *b);
index 0d8f22254857db7ee9376dca003537fc9c92fb04..c81e16ebb7c60f3c62b4303112783fec5c03efc1 100644 (file)
@@ -12,8 +12,6 @@
 // Make sure that if a process doesn't have its stdio/stderr descriptors set up
 // that we don't die in a large ball of fire
 
-#![feature(old_io)]
-
 use std::env;
 use std::process::{Command, Stdio};
 
index fde04efc8bad9c63f204da244196403c0c719475..b4621a2d053b1de4dae9e8d12d889575b2b75115 100644 (file)
 
 #![feature(collections)]
 
-extern crate collections;
-
 use std::collections::BitVec;
-use std::num::Float;
 
 fn main() {
     // Generate sieve of Eratosthenes for n up to 1e6
index 483ae02d2dcbda8ac04946e39a27aced35282394..9da04f723553105d1f6226892e4f526afc3a7db1 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-#![feature(rustc_private, old_io)]
+#![feature(rustc_private)]
 
 extern crate rbml;
 extern crate serialize;
index 4009d17139ddacd128cc772c46b01a4dfe8b33e5..7bab2ddfed06bbc429c95063ed1ab68cb2d9eb8b 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15877
 
 pub fn main() {
     let x = 1;
index dadd480dc6a2cd644106fd5443aa9f5f3d63e24e..14987484711792ea44275d6236af8894a8a334a2 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15877
 
 // Tests that match expression handles overlapped literal and range
 // properly in the presence of guard function.
index 14de9e90306bc6b8adf31f455d1298c61fe272fd..ca68272d2d0f295f605d6df8b89f22a0f664ec49 100644 (file)
 
 // pretty-expanded FIXME #23616
 
-#![feature(core)]
-
-use std::marker::MarkerTrait;
-
-trait Foo : MarkerTrait {
+trait Foo {
     fn quux(u8) {}
 }
 
index b51afc1d02095cf728bfe6fa93029ef1d5708705..ba6815d5b7c6973e0a8588be3ffcb10177bb1c4b 100644 (file)
@@ -9,8 +9,6 @@
 // except according to those terms.
 
 
-#![feature(old_io, io)]
-
 use std::env;
 use std::process::Command;
 use std::io::{self, Write};
index d074095dbdedd796e2c1d781c31250415100ae43..7f0a341f147154499f9ac1b28a9608e072121a29 100644 (file)
@@ -11,7 +11,7 @@
 // compile-flags:--test
 // ignore-pretty turns out the pretty-printer doesn't handle gensym'd things...
 
-mod test {
+mod tests {
     use super::*;
 
     #[test]
index 75d064a00fa89ad2e54d9aaf2677eba47c4ebef0..e3340d9767d02c1e52d86c59a0926f928e049ee7 100644 (file)
 trait IntoIterator {
     type Iter: Iterator;
 
-    fn into_iter(self) -> Self::Iter;
+    fn into_iter2(self) -> Self::Iter;
 }
 
 impl<I> IntoIterator for I where I: Iterator {
     type Iter = I;
 
-    fn into_iter(self) -> I {
+    fn into_iter2(self) -> I {
         self
     }
 }
 
 fn desugared_for_loop_bad<T>(v: Vec<T>) {
-    match IntoIterator::into_iter(v.iter()) {
+    match IntoIterator::into_iter2(v.iter()) {
         mut iter => {
             loop {
                 match ::std::iter::Iterator::next(&mut iter) {
index 71d1439dd2bc8f3f14d197137c50853a27e506fe..0df89c72424b46ee484e3e0fb04772865fa12547 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15883
 
 #![feature(unsafe_destructor, std_misc)]
 
index 096eec803ffa1716aa51facbbb46d11ff6a82904..ed9b8066104f565ee7b9351520d0cebc0602bd80 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15877
 
 
 trait Foo {
index 3532a395b7a2d8aebc0a2f623f7b751b9320bcd0..a565460c42e28333fad057b931ed6d27ecc14fc0 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// pretty-expanded FIXME #23616
-
 trait U { fn f(self); }
 impl U for isize { fn f(self) {} }
 pub fn main() { 4.f(); }
index bd892465054693419c406a0e2d936d12d7a108b8..5e2e4df95b3261b0970eca1acb83baaac18bb876 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15877
 
 type FontTableTag = u32;
 
index d0bc396c368bdf4b1f8aa49896bd93490ef72e84..dd00fab50203b8e94c8483d1cc3e194f1577d1e0 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15877
 
 trait Fooable {
     fn yes(self);
index 2469dec9947273205e9ef4e0481ba379b5a38841..4ebc43163ede894d451b8a85d612a218ff334271 100644 (file)
@@ -8,35 +8,30 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(zero_one)]
 
-#![feature(core)]
-
-use std::num::Int;
+use std::num::Zero;
 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::spawn(move|| { min_val::<isize>() / -1; }).join().is_err());
-    assert!(thread::spawn(move|| { min_val::<i8>() / -1; }).join().is_err());
-    assert!(thread::spawn(move|| { min_val::<i16>() / -1; }).join().is_err());
-    assert!(thread::spawn(move|| { min_val::<i32>() / -1; }).join().is_err());
-    assert!(thread::spawn(move|| { min_val::<i64>() / -1; }).join().is_err());
-    assert!(thread::spawn(move|| { 1isize / zero::<isize>(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i8 / zero::<i8>(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i16 / zero::<i16>(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i32 / zero::<i32>(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i64 / zero::<i64>(); }).join().is_err());
-    assert!(thread::spawn(move|| { min_val::<isize>() % -1; }).join().is_err());
-    assert!(thread::spawn(move|| { min_val::<i8>() % -1; }).join().is_err());
-    assert!(thread::spawn(move|| { min_val::<i16>() % -1; }).join().is_err());
-    assert!(thread::spawn(move|| { min_val::<i32>() % -1; }).join().is_err());
-    assert!(thread::spawn(move|| { min_val::<i64>() % -1; }).join().is_err());
-    assert!(thread::spawn(move|| { 1isize % zero::<isize>(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i8 % zero::<i8>(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i16 % zero::<i16>(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i32 % zero::<i32>(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i64 % zero::<i64>(); }).join().is_err());
+    assert!(thread::spawn(move|| { isize::min_value() / -1; }).join().is_err());
+    assert!(thread::spawn(move|| { i8::min_value() / -1; }).join().is_err());
+    assert!(thread::spawn(move|| { i16::min_value() / -1; }).join().is_err());
+    assert!(thread::spawn(move|| { i32::min_value() / -1; }).join().is_err());
+    assert!(thread::spawn(move|| { i64::min_value() / -1; }).join().is_err());
+    assert!(thread::spawn(move|| { 1isize / isize::zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i8 / i8::zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i16 / i16::zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i32 / i32::zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i64 / i64::zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { isize::min_value() % -1; }).join().is_err());
+    assert!(thread::spawn(move|| { i8::min_value() % -1; }).join().is_err());
+    assert!(thread::spawn(move|| { i16::min_value() % -1; }).join().is_err());
+    assert!(thread::spawn(move|| { i32::min_value() % -1; }).join().is_err());
+    assert!(thread::spawn(move|| { i64::min_value() % -1; }).join().is_err());
+    assert!(thread::spawn(move|| { 1isize % isize::zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i8 % i8::zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i16 % i16::zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i32 % i32::zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i64 % i64::zero(); }).join().is_err());
 }
index 421ae8e94972e8c68d6a2c9643af31a694cb6d6f..5c8db524cc2edeec729b4efb9949333bace83422 100644 (file)
@@ -16,7 +16,6 @@
 // this directory should enforce it.\r
 \r
 // ignore-pretty\r
-// ignore-lexer-test FIXME #15882\r
 \r
 /// Doc comment that ends in CRLF\r
 pub fn foo() {}\r
index 945cf9370f4149c6df1214d1643e59cc743f785d..74da4273b6ab0fb9b773425793bed9e05ae5df70 100644 (file)
@@ -12,7 +12,7 @@
 // ignore-android: FIXME(#10379)
 // ignore-windows: std::dynamic_lib does not work on Windows well
 
-#![feature(std_misc, old_path)]
+#![feature(std_misc)]
 
 extern crate linkage_visibility as foo;
 
index 6ddaee9c8bd5c1a669f1889bd8955e4cbaf00b2f..6e65cb2afd4ff38c59063c1235c9276a4589690e 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15679
 
 
 #![forbid(non_camel_case_types)]
index 29cfe91eba5acce01f17ec2cea8e0ecdd1605b64..09759326afd911c69b942cddefb49a87c02332bc 100644 (file)
@@ -12,7 +12,7 @@
 // exec-env:RUST_LOG=debug
 // compile-flags:-C debug-assertions=y
 
-#![feature(old_io, rustc_private)]
+#![feature(rustc_private)]
 
 #[macro_use]
 extern crate log;
index 68719090cff521ae9ffb107efe9ad7fbd858314c..0b2e19d6c7930e0186119eae50540d328a26ae72 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15877
 
 pub fn main() {
     match 5_usize {
index 1611a2c07227a97a3d5db5f1ac9fd8fde36678a2..5eecf27db677bec2f0ec87f4add5a46ff439710e 100644 (file)
@@ -13,9 +13,8 @@
 // temporary. Issue #19147.
 
 
-#![feature(core, old_io)]
+#![feature(core)]
 
-use std::mem;
 use std::slice;
 
 pub type IoResult<T> = Result<T, ()>;
index 12162ba9022aec3b0a6a07c526e0322f6124aef0..b7de1b5f4cbb536efd0a3276093f0bae9f24b05b 100644 (file)
 
 // pretty-expanded FIXME #23616
 
-#![feature(core)]
-
-use std::marker::MarkerTrait;
-
-trait Serializer : MarkerTrait {
+trait Serializer {
 }
 
 trait Serializable {
index 77084836408aa199af670910c757d767d9d6156e..0475dd10fdef9ff6b8d8f6b75e265d795afebdf3 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15679
 
 // Test that multibyte characters don't crash the compiler
 pub fn main() {
index d5f64c1c7b1aa406023621a3691f7b5fc78eed92..b1d71abc78599c0bb908e08513fa12cedb0d6df9 100644 (file)
 // necessary. Testing the methods of the impls is done within the source
 // file for each numeric type.
 
-
-#![feature(core)]
-
 use std::ops::Add;
-use std::num::ToPrimitive;
 
 pub fn main() {
 // ints
@@ -37,9 +33,4 @@ pub fn main() {
     assert_eq!(15_u16.add(6u16), 21_u16);
     assert_eq!(15_u32.add(6u32), 21_u32);
     assert_eq!(15_u64.add(6u64), 21_u64);
-
-// floats
-    // num
-    assert_eq!(10_f32.to_i32().unwrap(), 10);
-    assert_eq!(10_f64.to_i32().unwrap(), 10);
 }
index ddd6ae4d0a090cf4fcce7c5973f50b677d3bf4a3..5e924d015b619ca712aa6101f2c89794d21199a5 100644 (file)
@@ -13,7 +13,6 @@
 
 use std::cell::RefCell;
 use std::rc::Rc;
-use std::num::ToPrimitive;
 
 #[derive(PartialEq, Debug)]
 struct Point {
@@ -23,9 +22,6 @@ struct Point {
 
 pub fn main() {
     let box_5: Box<_> = box 5_usize;
-    assert_eq!(Rc::new(5_usize).to_uint(), Some(5));
-    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
-    assert_eq!((Box::new(&Box::new(&Rc::new(Box::new(Box::new(&box_5)))))).to_uint(), Some(5));
     let point = Rc::new(Point {x: 2, y: 4});
     assert_eq!(point.x, 2);
     assert_eq!(point.y, 4);
index 32448d100fb9b0b4dfff27a9ae50685c0656edd8..a155ee396b614bc917d1923cad9fe95b2ced0c9d 100644 (file)
 // intact.
 
 // ignore-aarch64
-#![feature(path, fs, os, io, old_path)]
 
 use std::io::prelude::*;
 use std::io;
 use std::fs;
 use std::process::Command;
-use std::os;
 use std::env;
-use std::path::{Path, PathBuf};
+use std::path::Path;
 
 fn main() {
     let my_args = env::args().collect::<Vec<_>>();
index 298ac8f77eb11dd6f5a4a63ea68920e34a5e7d61..9ee824d4185851b4477dadb969fae7a857ff2bb8 100644 (file)
Binary files a/src/test/run-pass/raw-str.rs and b/src/test/run-pass/raw-str.rs differ
index 31d97305e0be49e7b6a37c2a89702b229c1e612d..db543116d17a5c3c040574a6c5a1a2937f2372d0 100644 (file)
@@ -8,16 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(start, os, std_misc, old_io)]
+#![feature(start, std_misc)]
 
 use std::ffi::CStr;
 use std::process::{Command, Output};
-use std::os;
 use std::rt::unwind::try;
-use std::rt;
 use std::str;
-use std::thread::Thread;
-use std::thunk::Thunk;
 
 #[start]
 fn start(argc: isize, argv: *const *const u8) -> isize {
index 87da814771b4597109b7b6d4bc337955d9a5bdbb..15ab21bbc8da7bcdbdbd14d70de513214f469294 100644 (file)
@@ -11,6 +11,5 @@
 
 // ignore-pretty: `expand` adds some preludes before shebang
 //
-// ignore-lexer-test FIXME #15878
 
 pub fn main() { println!("Hello World"); }
index 1ff13d4eaeacb1c2129beb4835fb40ed722f0dbe..109287a83b16a88e93ced69fd83047aac5ad4188 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15883
 
 #[derive(Copy, Clone)]
 pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
index ba8a3f77aacefe0b65d679f6403fe70de64372db..f69b857981d788f735983ad3ebf87e70d129c181 100644 (file)
 
 // pretty-expanded FIXME #23616
 
-#![feature(optin_builtin_traits, core)]
-
-use std::marker::{MarkerTrait, Send};
+#![feature(optin_builtin_traits)]
 
 struct TestType;
 
 impl TestType {}
 
-trait TestTrait : MarkerTrait {}
+trait TestTrait {}
 
 impl !Send for TestType {}
 
index 7bcde7b83cd1b6c7b5012c92d95b0a2c0c6f2e00..4a1bb5a5916f0dfaea28f83fafb7f8a55742f3ad 100644 (file)
@@ -8,10 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// pretty-expanded FIXME #23616
-
-#![allow(unknown_features)]
-#![feature(box_syntax, old_io, std_misc, io, set_panic, set_stdio)]
+#![feature(box_syntax, set_stdio)]
 
 use std::io::prelude::*;
 use std::io;
index 50c9c43ba2b8ba892fb5d9348e02811cc9ee4af9..558e69664ecf9c840f74cd2f09f483ef929b9e0e 100644 (file)
@@ -10,9 +10,7 @@
 
 // pretty-expanded FIXME #23616
 
-#![feature(core)]
-
-trait Foo : ::std::marker::MarkerTrait {
+trait Foo {
 }
 
 fn b(_x: Box<Foo+Send>) {
index 60c1816b1632c2df873681e958595f964f9f23ff..bb8ae8247fa99abe9d4b36e1d0cbabde496af10a 100644 (file)
 
 #![feature(core)]
 
-trait U : ::std::marker::MarkerTrait {}
+trait U {}
 trait T<X: U> { fn get(self) -> X; }
 
-trait S2<Y: U> : ::std::marker::MarkerTrait {
+trait S2<Y: U> {
     fn m(x: Box<T<Y>+'static>) {}
 }
 
index 250390f70b448b29d9f8cecca1fbe4a002f9540f..d984e9cdc990fb3cda395eb31f0d98b39af857a1 100644 (file)
 
 // pretty-expanded FIXME #23616
 
-#![feature(core)]
-
 trait I { fn i(&self) -> Self; }
 
-trait A<T:I> : ::std::marker::MarkerTrait {
+trait A<T:I> {
     fn id(x:T) -> T { x.i() }
 }
 
 trait J<T> { fn j(&self) -> T; }
 
-trait B<T:J<T>> : ::std::marker::MarkerTrait {
+trait B<T:J<T>> {
     fn id(x:T) -> T { x.j() }
 }
 
-trait C : ::std::marker::MarkerTrait {
+trait C {
     fn id<T:J<T>>(x:T) -> T { x.j() }
 }
 
index fa31d9891aaf7c9a1b14e9e2377ba69a6e94b3aa..d40d9c89f89dff05b683eecad1d7bd40621995c6 100644 (file)
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(unknown_features)]
-#![feature(box_syntax, old_io, io)]
+#![feature(box_syntax)]
 
 use std::io::{self, Write};
 
index 4af049fc0c3af92b3892ae1ff7e7816fc0680146..e5390ac8a6256c96d5c238f7a6299be828696823 100644 (file)
 
 // pretty-expanded FIXME #23616
 
-#![feature(core)]
-
-use std::cmp::{PartialEq, PartialOrd};
-use std::num::NumCast;
-
-pub trait NumExt: NumCast + PartialEq + PartialOrd {}
+pub trait NumExt: PartialEq + PartialOrd {}
 
 pub trait FloatExt: NumExt {}
 
-fn greater_than_one<T: NumExt>(n: &T) -> bool { *n > NumCast::from(1).unwrap() }
-fn greater_than_one_float<T: FloatExt>(n: &T) -> bool { *n > NumCast::from(1).unwrap() }
+fn greater_than_one<T: NumExt>(n: &T) -> bool { loop {} }
+fn greater_than_one_float<T: FloatExt>(n: &T) -> bool { loop {} }
 
 pub fn main() {}
index b7f9534935697b4f20afa7ff4ac60a92b078cee0..83c2a9ad33926281c369c1729ded5099dc684254 100644 (file)
 #![feature(core)]
 
 use std::cmp::PartialOrd;
-use std::num::NumCast;
+
+pub trait NumCast {
+    fn from(i: i32) -> Option<Self>;
+}
 
 pub trait Num {
     fn from_int(i: isize) -> Self;
index 02ebf6bfa5375afd029f202c5adca1e65f400002..14a6a9a0c664ce1fd1c5f61526db25c0ced5e6b3 100644 (file)
 
 // pretty-expanded FIXME #23616
 
-#![feature(core)]
-
-use std::cmp::PartialOrd;
-use std::num::NumCast;
+pub trait NumCast {
+    fn from(i: i32) -> Option<Self>;
+}
 
 pub trait NumExt: NumCast + PartialOrd { }
 
index 773fc387a2a34370bbff8732a942ad621c2d4755..5f8541a6da1e88c2a360eff74c0254a6389ee8d9 100644 (file)
 
 // A more complex example of numeric extensions
 
-#![feature(core)]
-
-use std::cmp::{PartialEq, PartialOrd};
-use std::num::NumCast;
-
-pub trait TypeExt : ::std::marker::MarkerTrait { }
+pub trait TypeExt {}
 
 impl TypeExt for u8 {}
 impl TypeExt for u16 {}
@@ -33,7 +28,7 @@ impl TypeExt for f32 {}
 impl TypeExt for f64 {}
 
 
-pub trait NumExt: TypeExt + PartialEq + PartialOrd + NumCast {}
+pub trait NumExt: TypeExt + PartialEq + PartialOrd {}
 
 impl NumExt for u8 {}
 impl NumExt for u16 {}
index b5cf25bc5a8f4cd6664824a9fa7c191b2f4d273d..abf8d2baf8732154115bbe5e674c73c4e22bf512 100644 (file)
@@ -8,14 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(core)]
-
-use std::cmp::{PartialEq, PartialOrd};
-use std::num::NumCast;
+pub trait NumCast {
+    fn from(i: i32) -> Option<Self>;
+}
 
 pub trait NumExt: PartialEq + PartialOrd + NumCast {}
 
 impl NumExt for f32 {}
+impl NumCast for f32 {
+    fn from(i: i32) -> Option<f32> { Some(i as f32) }
+}
 
 fn num_eq_one<T: NumExt>(n: T) {
     println!("{}", n == NumCast::from(1).unwrap())
index b2c3900bc0282886157664c1b0c5144a353d93ad..c6f8a5d4f1d99f98bda8a384088d0f6123528326 100644 (file)
 
 // pretty-expanded FIXME #23616
 
-#![feature(core)]
-
-use std::cmp::PartialEq;
-use std::num::NumCast;
+pub trait NumCast {
+    fn from(i: i32) -> Option<Self>;
+}
 
 pub trait NumExt: PartialEq + NumCast {}
 
 impl NumExt for f32 {}
 impl NumExt for isize {}
 
+impl NumCast for f32 {
+    fn from(i: i32) -> Option<f32> { Some(i as f32) }
+}
+impl NumCast for isize {
+    fn from(i: i32) -> Option<isize> { Some(i as isize) }
+}
+
 fn num_eq_one<T:NumExt>() -> T {
     NumCast::from(1).unwrap()
 }
index ac9485594eb3ede417355f26c172f7717cde0be9..c7e206cb474b86d81d0dbf3f66484972faf09b26 100644 (file)
@@ -10,9 +10,6 @@
 
 // Test for issue #4183: use of Self in supertraits.
 
-
-use std::num::Float as StdFloat;
-
 pub static FUZZY_EPSILON: f64 = 0.1;
 
 pub trait FuzzyEq<Eps> {
index 62feecf045b54bc6c974333538a588f1a602ad55..67bea3864a7720ffac467765398ee852071c3665 100644 (file)
@@ -8,12 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+pub trait MyEq {}
 
-#![feature(core)]
-
-pub trait MyEq : ::std::marker::MarkerTrait { }
-
-pub trait MyNum : ::std::marker::MarkerTrait {
+pub trait MyNum {
     fn from_int(isize) -> Self;
 }
 
index 3d84092c062e6b5117169b7a69b048f5fa54ae84..a29e0e932c07d329fe6969b303a0e37c389db35e 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15883
 
 
 trait to_str {
index 34a79c4cf31a05c547384312b15d8674bd75db25..cfd812400947e5e637b4986731c020aa81a64665 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15877
 
 pub trait Clone2 {
     /// Returns a copy of the value. The contents of owned pointers
index d9536108f4df3d77db84dc3178cf0c1fa5e7390e..36b0eb527b64251f5b8fb82bd6f95580691e3f9e 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15877
 
 
 trait Cat {
index 0e71fcab9d1476e461c21c0746994abe6cb5d3b2..a2e7f54bba65203bcbc97ce9be1498f67a4862df 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15877
 
 
 trait Cat {
index d408612f9b8569e2846a5b91b950b901f38dabdd..c4944548e17f02c1eedf7113eaa4a107f4f24580 100644 (file)
 
 // pretty-expanded FIXME #23616
 
-#![feature(unboxed_closures, core)]
+pub trait ToPrimitive {
+    fn to_int(&self) {}
+}
 
-use std::num::ToPrimitive;
+impl ToPrimitive for isize {}
+impl ToPrimitive for i32 {}
+impl ToPrimitive for usize {}
 
 fn doit<T,F>(val: T, f: &F)
     where F : Fn(T)
 {
-    f.call((val,))
+    f(val)
 }
 
 pub fn main() {
index c1e1ff3cd8e93738c5404c50c52f5b0ac65d72b4..9cad7d61e32c5e6d1977ee66be876b86190166bd 100644 (file)
 
 // pretty-expanded FIXME #23616
 
-#![feature(unboxed_closures, core)]
+pub trait ToPrimitive {
+    fn to_int(&self) {}
+}
 
-use std::num::ToPrimitive;
+impl ToPrimitive for isize {}
+impl ToPrimitive for i32 {}
+impl ToPrimitive for usize {}
 
-fn doit<T>(val: T, f: &Fn(T)) { f.call((val,)) }
+fn doit<T>(val: T, f: &Fn(T)) { f(val) }
 
 pub fn main() {
     doit(0, &|x /*: isize*/ | { x.to_int(); });
index 99e2149de966a3e759a19c2d31a75fcba12dc020..bdd1932182bdcbc19507fef7bbb25abacbe81854 100644 (file)
 
 // pretty-expanded FIXME #23616
 
-#![feature(unboxed_closures, core)]
+pub trait ToPrimitive {
+    fn to_int(&self) {}
+}
 
-use std::num::ToPrimitive;
+impl ToPrimitive for isize {}
+impl ToPrimitive for i32 {}
+impl ToPrimitive for usize {}
 
 fn doit<T,F>(val: T, f: &F)
     where F : Fn(&T)
 {
-    f.call((&val,))
+    f(&val)
 }
 
 pub fn main() {
index 449d6b37e9f894183d336845f66993600876a5c1..26f7b767988d240581d7bcb39cf838c352b06de7 100644 (file)
@@ -10,8 +10,6 @@
 
 // Test syntax checks for `?Sized` syntax.
 
-// pretty-expanded FIXME #23616
-
 use std::marker::PhantomData;
 
 trait T1  { }
index 965ce6bad1668bf006e17383eef554ae43ceff86..1cce98ae6b7258ed3efa814a353b6ff53125dd35 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// pretty-expanded FIXME #23616
-
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
index baa4e941ff097432389c287c30131ffee1533f2a..c3052a928d6d6764348cf56beb3d2d5f15b41a8f 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15679
 
 // This file has utf-8 BOM, it should be compiled normally without error.
 
index 07fd7b297b4247e29c0a82c36b2a36094df3b9a8..4782edf4e129aba11f829344b153207a8346a947 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15679
 // no-pretty-expanded FIXME #15189
 
 pub fn main() {
index 45a3f2327aaa6b559f4e2c71c438658497028c1a..36b64551ef28f679f1144c3bfd52d7dc54c52f8d 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15679
 
 #![feature(collections, core, str_char)]
 
index b11b7e83eb6713e979e948c88febf567fc41c765..579070a295adf90a0f4c40b668701eef3ff6147d 100644 (file)
@@ -8,12 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
-// ignore-lexer-test FIXME #15679
 
 #![feature(non_ascii_idents)]
 
-use std::num::Float;
-
 pub fn main() {
     let ε = 0.00001f64;
     let Π = 3.14f64;
index 92b243140021d26004cf22eda29972f79ec99cbd..6153a3966342c03aec62431869e2bb82343b379a 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:rustdoc-default-impl.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate rustdoc_default_impl as foo;
 
index 9178c1bcb9d76d56b65755ec191b8909669d5c41..10d2884ebae0771646f60cd5ef6605c71d89ee18 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:rustdoc-extern-default-method.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate rustdoc_extern_default_method as ext;
 
index 5e30e6c0c1c58a008651bd2414062f012ed5df17..c422871867d5d83ddf8eeb79909897bcd9a84ad7 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:rustdoc-extern-method.rs
-// ignore-android
+// ignore-cross-compile
 
 #![feature(unboxed_closures)]
 
index 717c64b3aa54667cf841c79af8c25310c24700cb..3997dcd81e153e75a20cb5a7fc2a5447e59ce788 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:rustdoc-ffi.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate rustdoc_ffi as lib;
 
index a613736ab4c500bed8e419a9253836fba51ca8d4..055af0160f54cdbd7def4aadd6d116d50bb5894b 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:inline-default-methods.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate inline_default_methods;
 
index 5c31c297724649f8cbb95b547e8635a62868c9e5..cf9b30a0fe9873a46f96eade6c92126fea358e79 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:issue-13698.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate issue_13698;
 
index 32898d652f8217fb112d6dce6b5acb4ae7b0e791..7999af46eebb6b5d88b85d80b828916edf3697ba 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:issue-15318.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate issue_15318;
 
index 3bcc8f45b0e88338009deb0e5e709a5e1628dd80..fd46b6e990962d37e81f6a53a012a03a2ee68f83 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:issue-15318.rs
-// ignore-android
+// ignore-cross-compile
 
 #![feature(no_std)]
 #![no_std]
index 8d31a1c288eb8d097d53eb9916ffefe4b2b5e816..dcd3f2a2ba5b8e5afc44139338a28a4333d2f8b6 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:issue-17476.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate issue_17476;
 
index c315ea26d264291f3ec4a8641c1dc3797d2afc04..eec5c0253773720b42574accfed97994efb26cde 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:issue-19190-3.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate issue_19190_3;
 
index 77abe35948c3de259726a6f80e855f957b9ad984..87c40d11579747af3090c46240593c38ac0523e1 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:issue-20646.rs
-// ignore-android
+// ignore-cross-compile
 
 #![feature(associated_types)]
 
index 03181bebdb05a187c08d43ee9290ae5deb59b2d6..1f29a9c97972c6986d24bc62781d1b1b6b863458 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:issue-20727.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate issue_20727;
 
index 9d05ce99c4d3034908cc52f71e576ff9a54b66d2..e4a9dd7e7f142b1c9217404374c7051bcc9b5ccb 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:issue-20727.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate issue_20727;
 
index 39db387f090003ebe6696b173b3d8a0d5d646264..9ebd1c448eeb0d4195479782b9e066531b043188 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:issue-20727.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate issue_20727;
 
index 3205f5bfa33715ff2d6bb5d6dbd8e67146c7d6cb..e38f06c4b317ac30d5bdc65d4d8f369c3dafc3ff 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:issue-20727.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate issue_20727;
 
index 38983aee93397de586152071a1ebba5c4799a768..745c6e2c6648da6822f4e6f6960e1b49e787cf69 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:issue-21092.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate issue_21092;
 
index a4392b84e5b12ab89e2a30b48a5f727000f2b729..4e2c77826b6c07d2fae90280d23f5139831753c2 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:issue-21801.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate issue_21801;
 
index d2eb4fb6ad845559e3f4b74c8ce497b4960d487d..c0e4e673f94d8d7178333714fc20d14cdc594ba7 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:issue-22025.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate issue_22025;
 
index 722046723be7c4e96d1461755cc5ffd31e402f39..4931d158ac3e4277a3b50b7fbc2f34ad25702032 100644 (file)
@@ -10,7 +10,7 @@
 
 // aux-build:issue-23207-1.rs
 // aux-build:issue-23207-2.rs
-// ignore-android
+// ignore-cross-compile
 
 extern crate issue_23207_2;