]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #40841 - arielb1:immutable-blame, r=pnkfelix
authorCorey Farwell <coreyf@rwell.org>
Wed, 29 Mar 2017 12:57:06 +0000 (08:57 -0400)
committerGitHub <noreply@github.com>
Wed, 29 Mar 2017 12:57:06 +0000 (08:57 -0400)
borrowck: consolidate `mut` suggestions

This converts all of borrowck's `mut` suggestions to a new
`mc::ImmutabilityBlame` API instead of the current mix of various hacks.

Fixes #35937.
Fixes #40823.
Fixes #40859.

cc @estebank
r? @pnkfelix

325 files changed:
.gitmodules
.travis.yml
appveyor.yml
cargo
src/Cargo.lock
src/bootstrap/bin/rustdoc.rs
src/bootstrap/check.rs
src/ci/docker/armhf-gnu/Dockerfile
src/ci/docker/cross/Dockerfile
src/ci/docker/dist-android/Dockerfile
src/ci/docker/dist-arm-linux/Dockerfile
src/ci/docker/dist-armv7-aarch64-linux/Dockerfile
src/ci/docker/dist-freebsd/Dockerfile
src/ci/docker/dist-fuchsia/Dockerfile
src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile
src/ci/docker/dist-mips-linux/Dockerfile
src/ci/docker/dist-mips64-linux/Dockerfile
src/ci/docker/dist-powerpc-linux/Dockerfile
src/ci/docker/dist-powerpc64-linux/Dockerfile
src/ci/docker/dist-s390x-linux-netbsd/Dockerfile
src/ci/docker/dist-x86-linux/Dockerfile
src/ci/docker/dist-x86_64-musl/Dockerfile
src/ci/docker/emscripten/Dockerfile
src/ci/docker/emscripten/build-emscripten.sh
src/ci/docker/i686-gnu-nopt/Dockerfile
src/ci/docker/i686-gnu/Dockerfile
src/ci/docker/x86_64-gnu-aux/Dockerfile
src/ci/docker/x86_64-gnu-debug/Dockerfile
src/ci/docker/x86_64-gnu-distcheck/Dockerfile
src/ci/docker/x86_64-gnu-full-bootstrap/Dockerfile
src/ci/docker/x86_64-gnu-incremental/Dockerfile
src/ci/docker/x86_64-gnu-llvm-3.7/Dockerfile
src/ci/docker/x86_64-gnu-nopt/Dockerfile
src/ci/docker/x86_64-gnu/Dockerfile
src/doc/book
src/doc/nomicon
src/doc/reference
src/doc/unstable-book/src/SUMMARY.md
src/doc/unstable-book/src/alloc.md [new file with mode: 0644]
src/doc/unstable-book/src/as-unsafe-cell.md [new file with mode: 0644]
src/doc/unstable-book/src/ascii-ctype.md [new file with mode: 0644]
src/doc/unstable-book/src/binary-heap-extras.md [new file with mode: 0644]
src/doc/unstable-book/src/binary-heap-peek-mut-pop.md [new file with mode: 0644]
src/doc/unstable-book/src/borrow-state.md [new file with mode: 0644]
src/doc/unstable-book/src/box-heap.md [new file with mode: 0644]
src/doc/unstable-book/src/c-void-variant.md [new file with mode: 0644]
src/doc/unstable-book/src/catch-expr.md [new file with mode: 0644]
src/doc/unstable-book/src/char-escape-debug.md [new file with mode: 0644]
src/doc/unstable-book/src/closure-to-fn-coercion.md [new file with mode: 0644]
src/doc/unstable-book/src/coerce-unsized.md [new file with mode: 0644]
src/doc/unstable-book/src/collection-placement.md [new file with mode: 0644]
src/doc/unstable-book/src/collections-range.md [new file with mode: 0644]
src/doc/unstable-book/src/collections.md [new file with mode: 0644]
src/doc/unstable-book/src/command-envs.md [new file with mode: 0644]
src/doc/unstable-book/src/compiler-builtins-lib.md [new file with mode: 0644]
src/doc/unstable-book/src/concat-idents-macro.md [new file with mode: 0644]
src/doc/unstable-book/src/core-char-ext.md [new file with mode: 0644]
src/doc/unstable-book/src/core-float.md [new file with mode: 0644]
src/doc/unstable-book/src/core-intrinsics.md [new file with mode: 0644]
src/doc/unstable-book/src/core-panic.md [new file with mode: 0644]
src/doc/unstable-book/src/core-private-bignum.md [new file with mode: 0644]
src/doc/unstable-book/src/core-private-diy-float.md [new file with mode: 0644]
src/doc/unstable-book/src/core-slice-ext.md [new file with mode: 0644]
src/doc/unstable-book/src/core-str-ext.md [new file with mode: 0644]
src/doc/unstable-book/src/dec2flt.md [new file with mode: 0644]
src/doc/unstable-book/src/decode-utf8.md [new file with mode: 0644]
src/doc/unstable-book/src/derive-clone-copy.md [new file with mode: 0644]
src/doc/unstable-book/src/derive-eq.md [new file with mode: 0644]
src/doc/unstable-book/src/discriminant-value.md [new file with mode: 0644]
src/doc/unstable-book/src/enumset.md [new file with mode: 0644]
src/doc/unstable-book/src/error-type-id.md [new file with mode: 0644]
src/doc/unstable-book/src/exact-size-is-empty.md [new file with mode: 0644]
src/doc/unstable-book/src/fd-read.md [new file with mode: 0644]
src/doc/unstable-book/src/fd.md [new file with mode: 0644]
src/doc/unstable-book/src/field-init-shorthand.md [deleted file]
src/doc/unstable-book/src/fixed-size-array.md [new file with mode: 0644]
src/doc/unstable-book/src/float-extras.md [new file with mode: 0644]
src/doc/unstable-book/src/flt2dec.md [new file with mode: 0644]
src/doc/unstable-book/src/fmt-flags-align.md [new file with mode: 0644]
src/doc/unstable-book/src/fmt-internals.md [new file with mode: 0644]
src/doc/unstable-book/src/fn-traits.md [new file with mode: 0644]
src/doc/unstable-book/src/fnbox.md [new file with mode: 0644]
src/doc/unstable-book/src/fused.md [new file with mode: 0644]
src/doc/unstable-book/src/future-atomic-orderings.md [new file with mode: 0644]
src/doc/unstable-book/src/get-type-id.md [new file with mode: 0644]
src/doc/unstable-book/src/heap-api.md [new file with mode: 0644]
src/doc/unstable-book/src/i128.md [new file with mode: 0644]
src/doc/unstable-book/src/inclusive-range-syntax.md
src/doc/unstable-book/src/inclusive-range.md [new file with mode: 0644]
src/doc/unstable-book/src/int-error-internals.md [new file with mode: 0644]
src/doc/unstable-book/src/integer-atomics.md [new file with mode: 0644]
src/doc/unstable-book/src/into-boxed-c-str.md [new file with mode: 0644]
src/doc/unstable-book/src/into-boxed-os-str.md [new file with mode: 0644]
src/doc/unstable-book/src/into-boxed-path.md [new file with mode: 0644]
src/doc/unstable-book/src/io-error-internals.md [new file with mode: 0644]
src/doc/unstable-book/src/io.md [new file with mode: 0644]
src/doc/unstable-book/src/ip.md [new file with mode: 0644]
src/doc/unstable-book/src/is-unique.md [new file with mode: 0644]
src/doc/unstable-book/src/iter-rfind.md [new file with mode: 0644]
src/doc/unstable-book/src/libstd-io-internals.md [new file with mode: 0644]
src/doc/unstable-book/src/libstd-sys-internals.md [new file with mode: 0644]
src/doc/unstable-book/src/libstd-thread-internals.md [new file with mode: 0644]
src/doc/unstable-book/src/linked-list-extras.md [new file with mode: 0644]
src/doc/unstable-book/src/lookup-host.md [new file with mode: 0644]
src/doc/unstable-book/src/map-entry-recover-keys.md [new file with mode: 0644]
src/doc/unstable-book/src/mpsc-select.md [new file with mode: 0644]
src/doc/unstable-book/src/n16.md [new file with mode: 0644]
src/doc/unstable-book/src/never-type-impls.md [new file with mode: 0644]
src/doc/unstable-book/src/nonzero.md [new file with mode: 0644]
src/doc/unstable-book/src/once-poison.md [new file with mode: 0644]
src/doc/unstable-book/src/oom.md [new file with mode: 0644]
src/doc/unstable-book/src/option-entry.md [new file with mode: 0644]
src/doc/unstable-book/src/osstring-shrink-to-fit.md [new file with mode: 0644]
src/doc/unstable-book/src/panic-abort.md [new file with mode: 0644]
src/doc/unstable-book/src/panic-unwind.md [new file with mode: 0644]
src/doc/unstable-book/src/pattern.md [new file with mode: 0644]
src/doc/unstable-book/src/peek.md [new file with mode: 0644]
src/doc/unstable-book/src/placement-in.md [new file with mode: 0644]
src/doc/unstable-book/src/placement-new-protocol.md [new file with mode: 0644]
src/doc/unstable-book/src/print.md [new file with mode: 0644]
src/doc/unstable-book/src/proc-macro-internals.md [new file with mode: 0644]
src/doc/unstable-book/src/process-try-wait.md [new file with mode: 0644]
src/doc/unstable-book/src/pub-restricted.md [new file with mode: 0644]
src/doc/unstable-book/src/question-mark-carrier.md [new file with mode: 0644]
src/doc/unstable-book/src/rand.md [new file with mode: 0644]
src/doc/unstable-book/src/range-contains.md [new file with mode: 0644]
src/doc/unstable-book/src/raw.md [new file with mode: 0644]
src/doc/unstable-book/src/rc-would-unwrap.md [new file with mode: 0644]
src/doc/unstable-book/src/retain-hash-collection.md [new file with mode: 0644]
src/doc/unstable-book/src/rt.md [new file with mode: 0644]
src/doc/unstable-book/src/rustc-private.md [new file with mode: 0644]
src/doc/unstable-book/src/rustdoc.md [new file with mode: 0644]
src/doc/unstable-book/src/sanitizer-runtime-lib.md [new file with mode: 0644]
src/doc/unstable-book/src/set-stdio.md [new file with mode: 0644]
src/doc/unstable-book/src/shared.md [new file with mode: 0644]
src/doc/unstable-book/src/sip-hash-13.md [new file with mode: 0644]
src/doc/unstable-book/src/slice-concat-ext.md [new file with mode: 0644]
src/doc/unstable-book/src/slice-get-slice.md [new file with mode: 0644]
src/doc/unstable-book/src/sort-internals.md [new file with mode: 0644]
src/doc/unstable-book/src/static-recursion.md [deleted file]
src/doc/unstable-book/src/step-by.md [new file with mode: 0644]
src/doc/unstable-book/src/step-trait.md [new file with mode: 0644]
src/doc/unstable-book/src/str-escape.md [new file with mode: 0644]
src/doc/unstable-book/src/str-internals.md [new file with mode: 0644]
src/doc/unstable-book/src/thread-id.md [new file with mode: 0644]
src/doc/unstable-book/src/thread-local-internals.md [new file with mode: 0644]
src/doc/unstable-book/src/thread-local-state.md [new file with mode: 0644]
src/doc/unstable-book/src/trusted-len.md [new file with mode: 0644]
src/doc/unstable-book/src/try-from.md [new file with mode: 0644]
src/doc/unstable-book/src/unicode.md [new file with mode: 0644]
src/doc/unstable-book/src/unique.md [new file with mode: 0644]
src/doc/unstable-book/src/unsize.md [new file with mode: 0644]
src/doc/unstable-book/src/update-panic-count.md [new file with mode: 0644]
src/doc/unstable-book/src/utf8-error-error-len.md [new file with mode: 0644]
src/doc/unstable-book/src/vec-remove-item.md [new file with mode: 0644]
src/doc/unstable-book/src/windows-c.md [new file with mode: 0644]
src/doc/unstable-book/src/windows-handle.md [new file with mode: 0644]
src/doc/unstable-book/src/windows-net.md [new file with mode: 0644]
src/doc/unstable-book/src/windows-stdio.md [new file with mode: 0644]
src/doc/unstable-book/src/zero-one.md [new file with mode: 0644]
src/grammar/verify.rs
src/libcollections/linked_list.rs
src/libcollections/str.rs
src/libcollections/vec.rs
src/libcollectionstest/vec.rs
src/libcore/cmp.rs
src/libcore/num/dec2flt/algorithm.rs
src/libcore/ops.rs
src/libcore/result.rs
src/libcore/slice/sort.rs
src/libcore/str/mod.rs
src/libgraphviz/lib.rs
src/liblibc
src/liblog/Cargo.toml [deleted file]
src/liblog/directive.rs [deleted file]
src/liblog/lib.rs [deleted file]
src/liblog/macros.rs [deleted file]
src/librustc/Cargo.toml
src/librustc/dep_graph/dep_node.rs
src/librustc/dep_graph/dep_tracking_map.rs
src/librustc/dep_graph/edges.rs
src/librustc/dep_graph/shadow.rs
src/librustc/diagnostics.rs
src/librustc/hir/lowering.rs
src/librustc/hir/map/mod.rs
src/librustc/hir/mod.rs
src/librustc/ich/fingerprint.rs
src/librustc/infer/error_reporting/mod.rs
src/librustc/infer/higher_ranked/mod.rs
src/librustc/lint/context.rs
src/librustc/middle/cstore.rs
src/librustc/middle/dead.rs
src/librustc/middle/reachable.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/stability.rs
src/librustc/ty/adjustment.rs
src/librustc/ty/context.rs
src/librustc/ty/error.rs
src/librustc/ty/item_path.rs
src/librustc/ty/maps.rs
src/librustc/ty/mod.rs
src/librustc/ty/structural_impls.rs
src/librustc_back/Cargo.toml
src/librustc_borrowck/Cargo.toml
src/librustc_borrowck/borrowck/fragments.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_borrowck/graphviz.rs
src/librustc_const_eval/Cargo.toml
src/librustc_const_eval/_match.rs
src/librustc_const_eval/check_match.rs
src/librustc_data_structures/Cargo.toml
src/librustc_data_structures/accumulate_vec.rs
src/librustc_data_structures/base_n.rs
src/librustc_data_structures/blake2b.rs
src/librustc_data_structures/indexed_set.rs
src/librustc_driver/Cargo.toml
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_driver/pretty.rs
src/librustc_driver/test.rs
src/librustc_incremental/Cargo.toml
src/librustc_incremental/persist/file_format.rs
src/librustc_lint/Cargo.toml
src/librustc_lint/bad_style.rs
src/librustc_lint/builtin.rs
src/librustc_lint/unused.rs
src/librustc_llvm/build.rs
src/librustc_metadata/Cargo.toml
src/librustc_metadata/creader.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/locator.rs
src/librustc_metadata/schema.rs
src/librustc_mir/Cargo.toml
src/librustc_passes/Cargo.toml
src/librustc_plugin/load.rs
src/librustc_privacy/lib.rs
src/librustc_resolve/Cargo.toml
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/diagnostics.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/librustc_resolve/resolve_imports.rs
src/librustc_save_analysis/Cargo.toml
src/librustc_save_analysis/csv_dumper.rs
src/librustc_save_analysis/json_dumper.rs
src/librustc_save_analysis/lib.rs
src/librustc_trans/Cargo.toml
src/librustc_trans/abi.rs
src/librustc_trans/adt.rs
src/librustc_trans/asm.rs
src/librustc_trans/back/archive.rs
src/librustc_trans/back/link.rs
src/librustc_trans/back/lto.rs
src/librustc_trans/back/rpath.rs
src/librustc_trans/back/symbol_export.rs
src/librustc_trans/back/symbol_names.rs
src/librustc_trans/back/write.rs
src/librustc_trans/base.rs
src/librustc_trans/builder.rs
src/librustc_trans/context.rs
src/librustc_trans/monomorphize.rs
src/librustc_typeck/Cargo.toml
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/coherence/builtin.rs
src/librustc_typeck/coherence/inherent.rs [deleted file]
src/librustc_typeck/coherence/inherent_impls.rs [new file with mode: 0644]
src/librustc_typeck/coherence/inherent_impls_overlap.rs [new file with mode: 0644]
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/diagnostics.rs
src/librustdoc/Cargo.toml
src/librustdoc/build.rs [deleted file]
src/librustdoc/clean/inline.rs
src/librustdoc/core.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/render.rs
src/librustdoc/lib.rs
src/librustdoc/markdown.rs
src/librustdoc/visit_ast.rs
src/libstd/ascii.rs
src/libstd/io/cursor.rs
src/libstd/io/mod.rs
src/libstd/net/addr.rs
src/libstd/net/ip.rs
src/libstd/net/mod.rs
src/libstd/net/parser.rs
src/libstd/net/tcp.rs
src/libstd/net/udp.rs
src/libstd/os/raw.rs
src/libstd/sys/unix/ext/net.rs
src/libstd/sys/unix/process/process_common.rs
src/libstd/sys/unix/process/process_unix.rs
src/libstd/sys/windows/process.rs
src/libstd/sys/windows/stdio.rs
src/libstd/sys_common/net.rs
src/libstd_unicode/char.rs
src/libsyntax/Cargo.toml
src/libsyntax/ext/placeholders.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/feature_gate.rs
src/libsyntax/parse/parser.rs
src/libsyntax/symbol.rs
src/libsyntax/test.rs
src/libsyntax_ext/Cargo.toml
src/rt/hoedown [deleted submodule]
src/rustc/rustdoc.rs
src/test/compile-fail/imports/shadow_builtin_macros.rs [new file with mode: 0644]
src/test/compile-fail/issue-40000.rs [new file with mode: 0644]
src/test/compile-fail/issue-40749.rs [new file with mode: 0644]
src/test/compile-fail/issue-40845.rs [new file with mode: 0644]
src/test/compile-fail/static-lifetime-bound.rs [new file with mode: 0644]
src/test/run-pass-fulldeps/auxiliary/logging_right_crate.rs [deleted file]
src/test/run-pass-fulldeps/conditional-debug-macro-off.rs [deleted file]
src/test/run-pass-fulldeps/logging-enabled-debug.rs [deleted file]
src/test/run-pass-fulldeps/logging-enabled.rs [deleted file]
src/test/run-pass-fulldeps/logging-right-crate.rs [deleted file]
src/test/run-pass-fulldeps/logging-separate-lines.rs [deleted file]
src/test/run-pass-fulldeps/rust-log-filter.rs [deleted file]
src/test/run-pass-fulldeps/switch-stdout.rs [new file with mode: 0644]
src/test/run-pass/conditional-debug-macro-on.rs
src/test/run-pass/issue-40770.rs [new file with mode: 0644]
src/tools/compiletest/Cargo.toml
src/tools/compiletest/src/procsrv.rs
src/tools/error_index_generator/main.rs

index d2e1fb868a9990b1ed81bfdda3c23f3ce78b09f9..53d17874924093c298f0f111f1c4c4d680c68f55 100644 (file)
@@ -5,10 +5,6 @@
 [submodule "src/compiler-rt"]
        path = src/compiler-rt
        url = https://github.com/rust-lang/compiler-rt.git
-[submodule "src/rt/hoedown"]
-       path = src/rt/hoedown
-       url = https://github.com/rust-lang/hoedown.git
-       branch = rust-2015-09-21-do-not-delete
 [submodule "src/jemalloc"]
        path = src/jemalloc
        url = https://github.com/rust-lang/jemalloc.git
index 1faf860a3004f04108dd313aca616194ce6dfb14..148b59e8c64ebc5209ab68710d6f331001ca416a 100644 (file)
@@ -52,7 +52,7 @@ matrix:
       os: osx
       osx_image: xcode8.2
       install: &osx_install_sccache >
-        travis_retry curl -o /usr/local/bin/sccache https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-apple-darwin &&
+        travis_retry curl -o /usr/local/bin/sccache https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-apple-darwin &&
           chmod +x /usr/local/bin/sccache &&
         travis_retry curl -o /usr/local/bin/stamp https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-17-stamp-x86_64-apple-darwin &&
           chmod +x /usr/local/bin/stamp
index c33e07fb17e5f834aa9f7d5e441fd25f9a30ef99..68b2a239aff1babc31c622fd0631dd4abaac9c78 100644 (file)
@@ -46,13 +46,13 @@ environment:
     RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-ninja
     SCRIPT: python x.py test
     MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror
-    MINGW_ARCHIVE: i686-6.3.0-release-win32-dwarf-rt_v5-rev1.7z
+    MINGW_ARCHIVE: i686-6.2.0-release-win32-dwarf-rt_v5-rev1.7z
     MINGW_DIR: mingw32
   - MSYS_BITS: 64
     SCRIPT: python x.py test
     RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-ninja
     MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror
-    MINGW_ARCHIVE: x86_64-6.3.0-release-win32-seh-rt_v5-rev1.7z
+    MINGW_ARCHIVE: x86_64-6.2.0-release-win32-seh-rt_v5-rev1.7z
     MINGW_DIR: mingw64
 
   # 32/64 bit MSVC and GNU deployment
@@ -71,14 +71,14 @@ environment:
     RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-extended --enable-ninja
     SCRIPT: python x.py dist
     MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror
-    MINGW_ARCHIVE: i686-6.3.0-release-win32-dwarf-rt_v5-rev1.7z
+    MINGW_ARCHIVE: i686-6.2.0-release-win32-dwarf-rt_v5-rev1.7z
     MINGW_DIR: mingw32
     DEPLOY: 1
   - MSYS_BITS: 64
     SCRIPT: python x.py dist
     RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-extended --enable-ninja
     MINGW_URL: https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror
-    MINGW_ARCHIVE: x86_64-6.3.0-release-win32-seh-rt_v5-rev1.7z
+    MINGW_ARCHIVE: x86_64-6.2.0-release-win32-seh-rt_v5-rev1.7z
     MINGW_DIR: mingw64
     DEPLOY: 1
 
@@ -115,8 +115,8 @@ install:
   - set PATH=C:\Python27;%PATH%
 
   # Download and install sccache
-  - appveyor-retry appveyor DownloadFile https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-pc-windows-msvc
-  - mv 2017-03-22-sccache-x86_64-pc-windows-msvc sccache.exe
+  - appveyor-retry appveyor DownloadFile https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-pc-windows-msvc
+  - mv 2017-03-24-sccache-x86_64-pc-windows-msvc sccache.exe
   - set PATH=%PATH%;%CD%
 
   # Download and install ninja
diff --git a/cargo b/cargo
index c995e9eb5acf3976ae8674a0dc6d9e958053d9fd..4e95c6b41eca3388f54dd5f7787366ad2df637b5 160000 (submodule)
--- a/cargo
+++ b/cargo
@@ -1 +1 @@
-Subproject commit c995e9eb5acf3976ae8674a0dc6d9e958053d9fd
+Subproject commit 4e95c6b41eca3388f54dd5f7787366ad2df637b5
index 9ae894061a6762d0af21dde50427de153f6bfc6c..a9021dc34e207438edb537e673f3511c461aa7b9 100644 (file)
@@ -8,7 +8,7 @@ dependencies = [
 
 [[package]]
 name = "aho-corasick"
-version = "0.6.2"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -27,7 +27,7 @@ version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
  "core 0.0.0",
- "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.0.0",
 ]
 
@@ -65,7 +65,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "bitflags"
-version = "0.8.0"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -75,7 +75,7 @@ dependencies = [
  "build_helper 0.1.0",
  "cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -104,12 +104,12 @@ version = "0.1.0"
 
 [[package]]
 name = "clap"
-version = "2.21.1"
+version = "2.22.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "bitflags 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -122,7 +122,7 @@ name = "cmake"
 version = "0.1.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -140,14 +140,14 @@ version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
  "core 0.0.0",
- "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "compiletest"
 version = "0.0.0"
 dependencies = [
- "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -162,14 +162,6 @@ name = "dtoa"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "env_logger"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "env_logger"
 version = "0.4.2"
@@ -196,7 +188,7 @@ name = "flate"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -205,7 +197,7 @@ version = "0.0.0"
 
 [[package]]
 name = "gcc"
-version = "0.3.44"
+version = "0.3.45"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -223,10 +215,10 @@ version = "0.0.0"
 
 [[package]]
 name = "handlebars"
-version = "0.25.1"
+version = "0.25.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -251,7 +243,7 @@ dependencies = [
 
 [[package]]
 name = "lazy_static"
-version = "0.2.4"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -270,10 +262,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 name = "linkchecker"
 version = "0.1.0"
 
-[[package]]
-name = "log"
-version = "0.0.0"
-
 [[package]]
 name = "log"
 version = "0.3.7"
@@ -284,9 +272,9 @@ name = "mdbook"
 version = "0.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "clap 2.21.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.22.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "handlebars 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "handlebars 0.25.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -370,6 +358,14 @@ dependencies = [
  "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "pulldown-cmark"
+version = "0.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "qemu-test-client"
 version = "0.1.0"
@@ -395,7 +391,7 @@ name = "regex"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -428,7 +424,7 @@ dependencies = [
 name = "rustbook"
 version = "0.1.0"
 dependencies = [
- "clap 2.21.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.22.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "mdbook 0.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -439,7 +435,7 @@ dependencies = [
  "arena 0.0.0",
  "fmt_macros 0.0.0",
  "graphviz 0.0.0",
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_back 0.0.0",
  "rustc_bitflags 0.0.0",
  "rustc_const_math 0.0.0",
@@ -479,7 +475,7 @@ dependencies = [
 name = "rustc_back"
 version = "0.0.0"
 dependencies = [
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
  "syntax 0.0.0",
 ]
@@ -493,7 +489,7 @@ name = "rustc_borrowck"
 version = "0.0.0"
 dependencies = [
  "graphviz 0.0.0",
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
@@ -508,7 +504,7 @@ version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
  "graphviz 0.0.0",
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
  "rustc_const_math 0.0.0",
@@ -530,7 +526,7 @@ dependencies = [
 name = "rustc_data_structures"
 version = "0.0.0"
 dependencies = [
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
 ]
 
@@ -539,8 +535,9 @@ name = "rustc_driver"
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
+ "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc_macro_plugin 0.0.0",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
@@ -579,7 +576,7 @@ name = "rustc_incremental"
 version = "0.0.0"
 dependencies = [
  "graphviz 0.0.0",
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
  "serialize 0.0.0",
@@ -591,7 +588,7 @@ dependencies = [
 name = "rustc_lint"
 version = "0.0.0"
 dependencies = [
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
  "rustc_const_eval 0.0.0",
@@ -604,7 +601,7 @@ name = "rustc_llvm"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_bitflags 0.0.0",
 ]
 
@@ -623,7 +620,7 @@ name = "rustc_metadata"
 version = "0.0.0"
 dependencies = [
  "flate 0.0.0",
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc_macro 0.0.0",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
@@ -642,7 +639,7 @@ name = "rustc_mir"
 version = "0.0.0"
 dependencies = [
  "graphviz 0.0.0",
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_bitflags 0.0.0",
  "rustc_const_eval 0.0.0",
@@ -666,7 +663,7 @@ dependencies = [
 name = "rustc_passes"
 version = "0.0.0"
 dependencies = [
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_const_eval 0.0.0",
  "rustc_const_math 0.0.0",
@@ -705,7 +702,7 @@ name = "rustc_resolve"
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_errors 0.0.0",
  "syntax 0.0.0",
@@ -716,7 +713,7 @@ dependencies = [
 name = "rustc_save_analysis"
 version = "0.0.0"
 dependencies = [
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-data 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-span 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
@@ -730,7 +727,7 @@ name = "rustc_trans"
 version = "0.0.0"
 dependencies = [
  "flate 0.0.0",
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
  "rustc_bitflags 0.0.0",
@@ -762,7 +759,7 @@ version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
  "fmt_macros 0.0.0",
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
  "rustc_const_eval 0.0.0",
@@ -780,8 +777,10 @@ version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
  "build_helper 0.1.0",
- "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.0.0",
+ "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
  "rustc_const_eval 0.0.0",
@@ -828,7 +827,7 @@ dependencies = [
  "collections 0.0.0",
  "compiler_builtins 0.0.0",
  "core 0.0.0",
- "gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.0.0",
  "panic_abort 0.0.0",
  "panic_unwind 0.0.0",
@@ -857,7 +856,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 name = "syntax"
 version = "0.0.0"
 dependencies = [
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_bitflags 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
@@ -870,7 +869,7 @@ name = "syntax_ext"
 version = "0.0.0"
 dependencies = [
  "fmt_macros 0.0.0",
- "log 0.0.0",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc_macro 0.0.0",
  "rustc_errors 0.0.0",
  "syntax 0.0.0",
@@ -988,23 +987,22 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [metadata]
-"checksum aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0638fd549427caa90c499814196d1b9e3725eb4d15d7339d6de073a680ed0ca2"
+"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
 "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
 "checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
 "checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23"
-"checksum bitflags 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e1ab483fc81a8143faa7203c4a3c02888ebd1a782e37e41fa34753ba9a162"
-"checksum clap 2.21.1 (registry+https://github.com/rust-lang/crates.io-index)" = "74a80f603221c9cd9aa27a28f52af452850051598537bb6b359c38a7d61e5cda"
+"checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
+"checksum clap 2.22.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e17a4a72ffea176f77d6e2db609c6c919ef221f23862c9915e687fb54d833485"
 "checksum cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "d18d68987ed4c516dcc3e7913659bfa4076f5182eea4a7e0038bb060953e76ac"
 "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90"
-"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
 "checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83"
 "checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922"
-"checksum gcc 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)" = "a32cd40070d7611ab76343dcb3204b2bb28c8a9450989a83a3d590248142f439"
+"checksum gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)" = "40899336fb50db0c78710f53e87afc54d8c7266fb76262fecc78ca1a7f09deae"
 "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685"
-"checksum handlebars 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b2249f6f0dc5a3bb2b3b1a8f797dfccbc4b053344d773d654ad565e51427d335"
+"checksum handlebars 0.25.2 (registry+https://github.com/rust-lang/crates.io-index)" = "663e1728d8037fb0d4e13bcd1b1909fb5d913690a9929eb385922df157c2ff8f"
 "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
-"checksum lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7291b1dd97d331f752620b02dfdbc231df7fc01bf282a00769e1cdb963c460dc"
+"checksum lazy_static 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4732c563b9a21a406565c4747daa7b46742f082911ae4753f390dc9ec7ee1a97"
 "checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135"
 "checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad"
 "checksum mdbook 0.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "06a68e8738e42b38a02755d3ce5fa12d559e17acb238e4326cbc3cc056e65280"
@@ -1013,6 +1011,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "cee7e88156f3f9e19bdd598f8d6c9db7bf4078f99f8381f43a55b09648d1a6e3"
 "checksum open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3478ed1686bd1300c8a981a940abc92b06fac9cbef747f4c668d4e032ff7b842"
 "checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8"
+"checksum pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ab1e588ef8efd702c7ed9d2bd774db5e6f4d878bb5a1a9f371828fbdff6973"
 "checksum pulldown-cmark 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1058d7bb927ca067656537eec4e02c2b4b70eaaa129664c5b90c111e20326f41"
 "checksum quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0aad603e8d7fb67da22dbdf1f4b826ce8829e406124109e73cf1b2454b93a71c"
 "checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
index e9ca430f1582b4723529255bb17cfb7309fc4d36..3a1a9c3e40d66066b708f48e2de876d38d7fa702 100644 (file)
@@ -40,6 +40,14 @@ fn main() {
         .arg(sysroot)
         .env(bootstrap::util::dylib_path_var(),
              env::join_paths(&dylib_path).unwrap());
+
+    // Pass the `rustbuild` feature flag to crates which rustbuild is
+    // building. See the comment in bootstrap/lib.rs where this env var is
+    // set for more details.
+    if env::var_os("RUSTBUILD_UNSTABLE").is_some() {
+        cmd.arg("--cfg").arg("rustbuild");
+    }
+
     std::process::exit(match cmd.status() {
         Ok(s) => s.code().unwrap_or(1),
         Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e),
index 40cdb9242df15b2fec93cee92f272d31e4ec5849..f8f641060c442674f4d7b9a03b8d8bcde5008fec 100644 (file)
@@ -586,7 +586,7 @@ fn android_copy_libs(build: &Build, compiler: &Compiler, target: &str) {
                       .arg(ADB_TEST_DIR));
 
     let target_dir = format!("{}/{}", ADB_TEST_DIR, target);
-    build.run(Command::new("adb").args(&["shell", "mkdir", &target_dir[..]]));
+    build.run(Command::new("adb").args(&["shell", "mkdir", &target_dir]));
 
     for f in t!(build.sysroot_libdir(compiler, target).read_dir()) {
         let f = t!(f);
index a5126cb3c3f230ff54ace942bf755dcbfcad967d..933562c79e5821837b8fae00fa23bc908d750900 100644 (file)
@@ -74,7 +74,7 @@ RUN arm-linux-gnueabihf-gcc addentropy.c -o rootfs/addentropy -static
 RUN curl -O http://ftp.nl.debian.org/debian/dists/jessie/main/installer-armhf/current/images/device-tree/vexpress-v2p-ca15-tc1.dtb
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 9e7abb8b36e358110a03582de2f2e60ef991989f..8dc02ab522c21bf9604a500048734714fc33faa6 100644 (file)
@@ -22,7 +22,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 2785d2135f864d41a6f3199d1a34b1e95c840118..44d6863bf0bbdc8430f7cab91cd0c289f41e63a6 100644 (file)
@@ -32,7 +32,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV TARGETS=arm-linux-androideabi
index 6cdb5cfca74ba5d6e5181fdbbfbcfbee5b19114b..7facc52390ff4a294b1f5111a46cfe340dc7614b 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-toolchains.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/arm-unknown-linux-gnueabi/bin
index ed9b4a5929188ad0ea90fb1afed3de46d79fede8..369e5a7dffe2a8048c84023e861a322a280a0194 100644 (file)
@@ -63,7 +63,7 @@ RUN ./build-toolchains.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/aarch64-unknown-linux-gnueabi/bin
index 332a1fa73a4d5c60708a0d4be0ddc63b466c560d..633f58ea474b4eccc623af0cd2d03e29fa1b622d 100644 (file)
@@ -26,7 +26,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV \
index dcb9aa905f14ebcf70eac83379ad0dbb93bc2b35..ed37a9e842e227a9219599bf00b70e947a8c90d5 100644 (file)
@@ -29,7 +29,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV \
index 2051396988589da0332c7d978578471bc390c51c..d88ec7aab34643da663133c818c5bfadf58f7f1c 100644 (file)
@@ -26,7 +26,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV RUST_CONFIGURE_ARGS \
index 3123e69e7e1df22f97a4ca7be1b4c0832fcca3b5..938c53ae48837d057b653cced3a47d190b2b0b03 100644 (file)
@@ -18,7 +18,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 52db932dcdc38499aa97efbbf636cc5a4913e4c1..45de8100b4f27f9f3aed69d309e70a678e4840b3 100644 (file)
@@ -18,7 +18,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index fca931596853bf489731a767576bd3cf2a10ebd6..c1e5e863ae06c3b710900cdc6f03d81dbb9d4596 100644 (file)
@@ -63,7 +63,7 @@ RUN ./build-powerpc-toolchain.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/powerpc-unknown-linux-gnu/bin
index 17a4734aba7d1458eead69f76d9ccaf47e950aea..7413c327323e5072aca0e34050286b13a552eebd 100644 (file)
@@ -67,7 +67,7 @@ COPY build-powerpc64le-toolchain.sh /tmp/
 RUN ./build-powerpc64le-toolchain.sh
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/powerpc64-unknown-linux-gnu/bin
index c2877b081d5d7a7838fac16d96ae7fea6b85190c..4180006690fc902c76eb19eda0b3cf9c91d62edb 100644 (file)
@@ -66,7 +66,7 @@ RUN ./build-netbsd-toolchain.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/s390x-ibm-linux-gnu/bin:/x-tools/x86_64-unknown-netbsd/bin
index 100b6dcf9937eb7f6631406d5c8e32fa03b00ea5..18c7a4d2b3e7f54306fd5dba0f4e9056d6a927d7 100644 (file)
@@ -76,7 +76,7 @@ RUN curl -Lo /rustroot/dumb-init \
 ENTRYPOINT ["/rustroot/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV HOSTS=i686-unknown-linux-gnu
index 7ebd34ee904bcf3f2a03d2fa9e72384fb98673f5..085aa351659905c2af0da4113bd96c7d4a19207f 100644 (file)
@@ -26,7 +26,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV RUST_CONFIGURE_ARGS \
index 630b122c9359ab744d658404256defad42b299d5..77cf54a19a7fd9ee510066f3a9ed19a9aa0f4b16 100644 (file)
@@ -15,7 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   lib32stdc++6
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 88bf583007ce53f296b5a2405dac1174025d94a9..e39767357ad6301a56f463ec24d49a0ab7e97181 100755 (executable)
@@ -29,7 +29,24 @@ exit 1
 }
 
 curl https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz | \
-      tar xzf -
+    tar xzf -
+
+# Some versions of the EMSDK archive have their contents in .emsdk-portable
+# and others in emsdk_portable. Make sure the EMSDK ends up in a fixed path.
+if [ -d emsdk-portable ]; then
+    mv emsdk-portable emsdk_portable
+fi
+
+if [ ! -d emsdk_portable ]; then
+    echo "ERROR: Invalid emsdk archive. Dumping working directory." >&2
+    ls -l
+    exit 1
+fi
+
+# Some versions of the EMSDK set the permissions of the root directory to
+# 0700. Ensure the directory is readable by all users.
+chmod 755 emsdk_portable
+
 source emsdk_portable/emsdk_env.sh
 hide_output emsdk update
 hide_output emsdk install --build=Release sdk-tag-1.37.1-32bit
index b9f47731eee757190cd73f4fa5e355d0c0d07822..c84cf56e4e858bdaf788b30371b8fc00a672099b 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index e4a9c5b258fe6144e0c2a299b467aa4f940db38e..f4bb9083b85827ece5f152af18aaa1a4009761f7 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 104361830e1cd3031fe957b6acd06c10834f3b5c..68184c65cf17ffcf75ac8728c2d4de0a5889f279 100644 (file)
@@ -15,7 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 1575efdb4cb70763647635bb800a61d705dd30f2..6320a806fc301d3b7d9b7afd29d409ec46fcfc6e 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 94847712094d1aad97092e51d3e7273efc8023a5..180f53ec33f31f173ebd1dcd230ebf44272cda40 100644 (file)
@@ -16,7 +16,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 542b4f90b119f6120d0ec5746b2019b10cfda4d0..4500fc0f642deec293c20ca4c7e68e6514a1a9ca 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 4d9b218c7654cfadbb2d6c4fa56ee1d552f8d4bc..ad1227fa581f9ca745e74752d23333ab8b3b65eb 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 04358ff97484ab071d6393c73ecc0903eae08020..f1240201805718819fed02848b084ba7debbb263 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index dddeb82e6bfb2af8553002798548e4605522bc96..fa9707d1a7352c9f54d1b7bcd91acf4ba79639a0 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 393bcf023ea5bb1b913c0d4bda77874f894ccd3a..e5d89034dbe4268b6e46dcdf6dae3d914bbd591e 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-22-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 9bd223ca406b1170a24942d6474f9e8a56f4a420..a2c56870d4dc589237102cc5e0fe7b9ebd0d14a1 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 9bd223ca406b1170a24942d6474f9e8a56f4a420
+Subproject commit a2c56870d4dc589237102cc5e0fe7b9ebd0d14a1
index d08fe97d12b41c1ed8cc7701e545864132783941..616b98444ff4eb5260deee95ee3e090dfd98b947 160000 (submodule)
@@ -1 +1 @@
-Subproject commit d08fe97d12b41c1ed8cc7701e545864132783941
+Subproject commit 616b98444ff4eb5260deee95ee3e090dfd98b947
index 516549972d61c8946542d1a34afeae97167ff77b..acedc32cacae80cf2f4925753a4ce7f7ffd7c86a 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 516549972d61c8946542d1a34afeae97167ff77b
+Subproject commit acedc32cacae80cf2f4925753a4ce7f7ffd7c86a
index 456c76d43a6ece8d318d19adb2347806ddd80c42..fe491d7f9018ef5fff1d0c2cd78a5d55744be79f 100644 (file)
 - [abi_vectorcall](abi-vectorcall.md)
 - [abi_x86_interrupt](abi-x86-interrupt.md)
 - [advanced_slice_patterns](advanced-slice-patterns.md)
+- [alloc](alloc.md)
 - [alloc_jemalloc](alloc-jemalloc.md)
 - [alloc_system](alloc-system.md)
 - [allocator](allocator.md)
 - [allow_internal_unstable](allow-internal-unstable.md)
+- [as_unsafe_cell](as-unsafe-cell.md)
+- [ascii_ctype](ascii-ctype.md)
 - [asm](asm.md)
 - [associated_consts](associated-consts.md)
 - [associated_type_defaults](associated-type-defaults.md)
 - [attr_literals](attr-literals.md)
+- [binary_heap_extras](binary-heap-extras.md)
+- [binary_heap_peek_mut_pop](binary-heap-peek-mut-pop.md)
+- [borrow_state](borrow-state.md)
+- [box_heap](box-heap.md)
 - [box_patterns](box-patterns.md)
 - [box_syntax](box-syntax.md)
+- [c_void_variant](c-void-variant.md)
+- [catch_expr](catch-expr.md)
 - [cfg_target_feature](cfg-target-feature.md)
 - [cfg_target_has_atomic](cfg-target-has-atomic.md)
 - [cfg_target_thread_local](cfg-target-thread-local.md)
 - [cfg_target_vendor](cfg-target-vendor.md)
+- [char_escape_debug](char-escape-debug.md)
+- [closure_to_fn_coercion](closure-to-fn-coercion.md)
+- [coerce_unsized](coerce-unsized.md)
+- [collection_placement](collection-placement.md)
+- [collections](collections.md)
+- [collections_range](collections-range.md)
+- [command_envs](command-envs.md)
 - [compiler_builtins](compiler-builtins.md)
+- [compiler_builtins_lib](compiler-builtins-lib.md)
 - [concat_idents](concat-idents.md)
+- [concat_idents_macro](concat-idents-macro.md)
 - [conservative_impl_trait](conservative-impl-trait.md)
 - [const_fn](const-fn.md)
 - [const_indexing](const-indexing.md)
+- [core_char_ext](core-char-ext.md)
+- [core_float](core-float.md)
+- [core_intrinsics](core-intrinsics.md)
+- [core_panic](core-panic.md)
+- [core_private_bignum](core-private-bignum.md)
+- [core_private_diy_float](core-private-diy-float.md)
+- [core_slice_ext](core-slice-ext.md)
+- [core_str_ext](core-str-ext.md)
 - [custom_attribute](custom-attribute.md)
 - [custom_derive](custom-derive.md)
+- [dec2flt](dec2flt.md)
+- [decode_utf8](decode-utf8.md)
 - [default_type_parameter_fallback](default-type-parameter-fallback.md)
+- [derive_clone_copy](derive-clone-copy.md)
+- [derive_eq](derive-eq.md)
+- [discriminant_value](discriminant-value.md)
 - [drop_types_in_const](drop-types-in-const.md)
 - [dropck_eyepatch](dropck-eyepatch.md)
 - [dropck_parametricity](dropck-parametricity.md)
+- [enumset](enumset.md)
+- [error_type_id](error-type-id.md)
+- [exact_size_is_empty](exact-size-is-empty.md)
 - [exclusive_range_pattern](exclusive-range-pattern.md)
-- [field_init_shorthand](field-init-shorthand.md)
+- [fd](fd.md)
+- [fd_read](fd-read.md)
+- [fixed_size_array](fixed-size-array.md)
+- [float_extras](float-extras.md)
+- [flt2dec](flt2dec.md)
+- [fmt_flags_align](fmt-flags-align.md)
+- [fmt_internals](fmt-internals.md)
+- [fn_traits](fn-traits.md)
+- [fnbox](fnbox.md)
 - [fundamental](fundamental.md)
+- [fused](fused.md)
+- [future_atomic_orderings](future-atomic-orderings.md)
 - [generic_param_attrs](generic-param-attrs.md)
+- [get_type_id](get-type-id.md)
+- [heap_api](heap-api.md)
+- [i128](i128.md)
 - [i128_type](i128-type.md)
+- [inclusive_range](inclusive-range.md)
 - [inclusive_range_syntax](inclusive-range-syntax.md)
+- [int_error_internals](int-error-internals.md)
+- [integer_atomics](integer-atomics.md)
+- [into_boxed_c_str](into-boxed-c-str.md)
+- [into_boxed_os_str](into-boxed-os-str.md)
+- [into_boxed_path](into-boxed-path.md)
 - [intrinsics](intrinsics.md)
+- [io](io.md)
+- [io_error_internals](io-error-internals.md)
+- [ip](ip.md)
+- [is_unique](is-unique.md)
+- [iter_rfind](iter-rfind.md)
 - [lang_items](lang-items.md)
+- [libstd_io_internals](libstd-io-internals.md)
+- [libstd_sys_internals](libstd-sys-internals.md)
+- [libstd_thread_internals](libstd-thread-internals.md)
 - [link_args](link-args.md)
 - [link_cfg](link-cfg.md)
 - [link_llvm_intrinsics](link-llvm-intrinsics.md)
 - [linkage](linkage.md)
+- [linked_list_extras](linked-list-extras.md)
 - [log_syntax](log-syntax.md)
+- [lookup_host](lookup-host.md)
 - [loop_break_value](loop-break-value.md)
 - [macro_reexport](macro-reexport.md)
 - [main](main.md)
+- [map_entry_recover_keys](map-entry-recover-keys.md)
+- [mpsc_select](mpsc-select.md)
+- [n16](n16.md)
 - [naked_functions](naked-functions.md)
 - [needs_allocator](needs-allocator.md)
 - [needs_panic_runtime](needs-panic-runtime.md)
 - [never_type](never-type.md)
+- [never_type_impls](never-type-impls.md)
 - [no_core](no-core.md)
 - [no_debug](no-debug.md)
 - [non_ascii_idents](non-ascii-idents.md)
+- [nonzero](nonzero.md)
 - [omit_gdb_pretty_printer_section](omit-gdb-pretty-printer-section.md)
 - [on_unimplemented](on-unimplemented.md)
+- [once_poison](once-poison.md)
+- [oom](oom.md)
 - [optin_builtin_traits](optin-builtin-traits.md)
+- [option_entry](option-entry.md)
+- [osstring_shrink_to_fit](osstring-shrink-to-fit.md)
+- [panic_abort](panic-abort.md)
 - [panic_runtime](panic-runtime.md)
+- [panic_unwind](panic-unwind.md)
+- [pattern](pattern.md)
+- [peek](peek.md)
+- [placement_in](placement-in.md)
 - [placement_in_syntax](placement-in-syntax.md)
+- [placement_new_protocol](placement-new-protocol.md)
 - [platform_intrinsics](platform-intrinsics.md)
 - [plugin](plugin.md)
 - [plugin_registrar](plugin-registrar.md)
 - [prelude_import](prelude-import.md)
+- [print](print.md)
 - [proc_macro](proc-macro.md)
+- [proc_macro_internals](proc-macro-internals.md)
+- [process_try_wait](process-try-wait.md)
+- [pub_restricted](pub-restricted.md)
+- [question_mark_carrier](question-mark-carrier.md)
 - [quote](quote.md)
+- [rand](rand.md)
+- [range_contains](range-contains.md)
+- [raw](raw.md)
+- [rc_would_unwrap](rc-would-unwrap.md)
 - [relaxed_adts](relaxed-adts.md)
 - [repr_simd](repr-simd.md)
+- [retain_hash_collection](retain-hash-collection.md)
+- [rt](rt.md)
 - [rustc_attrs](rustc-attrs.md)
 - [rustc_diagnostic_macros](rustc-diagnostic-macros.md)
+- [rustc_private](rustc-private.md)
+- [rustdoc](rustdoc.md)
 - [rvalue_static_promotion](rvalue-static-promotion.md)
 - [sanitizer_runtime](sanitizer-runtime.md)
+- [sanitizer_runtime_lib](sanitizer-runtime-lib.md)
+- [set_stdio](set-stdio.md)
+- [shared](shared.md)
 - [simd](simd.md)
 - [simd_ffi](simd-ffi.md)
+- [sip_hash_13](sip-hash-13.md)
+- [slice_concat_ext](slice-concat-ext.md)
+- [slice_get_slice](slice-get-slice.md)
 - [slice_patterns](slice-patterns.md)
+- [sort_internals](sort-internals.md)
 - [sort_unstable](sort-unstable.md)
 - [specialization](specialization.md)
 - [staged_api](staged-api.md)
 - [start](start.md)
 - [static_nobundle](static-nobundle.md)
-- [static_recursion](static-recursion.md)
+- [step_by](step-by.md)
+- [step_trait](step-trait.md)
 - [stmt_expr_attributes](stmt-expr-attributes.md)
+- [str_escape](str-escape.md)
+- [str_internals](str-internals.md)
 - [struct_field_attributes](struct-field-attributes.md)
 - [structural_match](structural-match.md)
 - [target_feature](target-feature.md)
 - [test](test.md)
+- [thread_id](thread-id.md)
 - [thread_local](thread-local.md)
+- [thread_local_internals](thread-local-internals.md)
+- [thread_local_state](thread-local-state.md)
 - [trace_macros](trace-macros.md)
+- [trusted_len](trusted-len.md)
+- [try_from](try-from.md)
 - [type_ascription](type-ascription.md)
 - [unboxed_closures](unboxed-closures.md)
+- [unicode](unicode.md)
+- [unique](unique.md)
+- [unsize](unsize.md)
 - [untagged_unions](untagged-unions.md)
 - [unwind_attributes](unwind-attributes.md)
+- [update_panic_count](update-panic-count.md)
 - [use_extern_macros](use-extern-macros.md)
+- [utf8_error_error_len](utf8-error-error-len.md)
+- [vec_remove_item](vec-remove-item.md)
+- [windows_c](windows-c.md)
+- [windows_handle](windows-handle.md)
+- [windows_net](windows-net.md)
+- [windows_stdio](windows-stdio.md)
 - [windows_subsystem](windows-subsystem.md)
+- [zero_one](zero-one.md)
diff --git a/src/doc/unstable-book/src/alloc.md b/src/doc/unstable-book/src/alloc.md
new file mode 100644 (file)
index 0000000..47eeb08
--- /dev/null
@@ -0,0 +1,7 @@
+# `alloc`
+
+The tracking issue for this feature is: [#27783]
+
+[#27783]: https://github.com/rust-lang/rust/issues/27783
+
+------------------------
diff --git a/src/doc/unstable-book/src/as-unsafe-cell.md b/src/doc/unstable-book/src/as-unsafe-cell.md
new file mode 100644 (file)
index 0000000..79d7a7c
--- /dev/null
@@ -0,0 +1,7 @@
+# `as_unsafe_cell`
+
+The tracking issue for this feature is: [#27708]
+
+[#27708]: https://github.com/rust-lang/rust/issues/27708
+
+------------------------
diff --git a/src/doc/unstable-book/src/ascii-ctype.md b/src/doc/unstable-book/src/ascii-ctype.md
new file mode 100644 (file)
index 0000000..e253b4d
--- /dev/null
@@ -0,0 +1,5 @@
+# `ascii_ctype`
+
+The tracking issue for this feature is: [#39658]
+
+[#39658]: https://github.com/rust-lang/rust/issues/39658
diff --git a/src/doc/unstable-book/src/binary-heap-extras.md b/src/doc/unstable-book/src/binary-heap-extras.md
new file mode 100644 (file)
index 0000000..aa535f3
--- /dev/null
@@ -0,0 +1,7 @@
+# `binary_heap_extras`
+
+The tracking issue for this feature is: [#28147]
+
+[#28147]: https://github.com/rust-lang/rust/issues/28147
+
+------------------------
diff --git a/src/doc/unstable-book/src/binary-heap-peek-mut-pop.md b/src/doc/unstable-book/src/binary-heap-peek-mut-pop.md
new file mode 100644 (file)
index 0000000..f3863ab
--- /dev/null
@@ -0,0 +1,7 @@
+# `binary_heap_peek_mut_pop`
+
+The tracking issue for this feature is: [#38863]
+
+[#38863]: https://github.com/rust-lang/rust/issues/38863
+
+------------------------
diff --git a/src/doc/unstable-book/src/borrow-state.md b/src/doc/unstable-book/src/borrow-state.md
new file mode 100644 (file)
index 0000000..304b8df
--- /dev/null
@@ -0,0 +1,7 @@
+# `borrow_state`
+
+The tracking issue for this feature is: [#27733]
+
+[#27733]: https://github.com/rust-lang/rust/issues/27733
+
+------------------------
diff --git a/src/doc/unstable-book/src/box-heap.md b/src/doc/unstable-book/src/box-heap.md
new file mode 100644 (file)
index 0000000..0f3f01b
--- /dev/null
@@ -0,0 +1,7 @@
+# `box_heap`
+
+The tracking issue for this feature is: [#27779]
+
+[#27779]: https://github.com/rust-lang/rust/issues/27779
+
+------------------------
diff --git a/src/doc/unstable-book/src/c-void-variant.md b/src/doc/unstable-book/src/c-void-variant.md
new file mode 100644 (file)
index 0000000..a2fdc99
--- /dev/null
@@ -0,0 +1,5 @@
+# `c_void_variant`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/catch-expr.md b/src/doc/unstable-book/src/catch-expr.md
new file mode 100644 (file)
index 0000000..44eb2a6
--- /dev/null
@@ -0,0 +1,7 @@
+# `catch_expr`
+
+The tracking issue for this feature is: [#31436]
+
+[#31436]: https://github.com/rust-lang/rust/issues/31436
+
+------------------------
diff --git a/src/doc/unstable-book/src/char-escape-debug.md b/src/doc/unstable-book/src/char-escape-debug.md
new file mode 100644 (file)
index 0000000..21aa486
--- /dev/null
@@ -0,0 +1,7 @@
+# `char_escape_debug`
+
+The tracking issue for this feature is: [#35068]
+
+[#35068]: https://github.com/rust-lang/rust/issues/35068
+
+------------------------
diff --git a/src/doc/unstable-book/src/closure-to-fn-coercion.md b/src/doc/unstable-book/src/closure-to-fn-coercion.md
new file mode 100644 (file)
index 0000000..4e3b735
--- /dev/null
@@ -0,0 +1,7 @@
+# `closure_to_fn_coercion`
+
+The tracking issue for this feature is: [#39817]
+
+[#39817]: https://github.com/rust-lang/rust/issues/39817
+
+------------------------
diff --git a/src/doc/unstable-book/src/coerce-unsized.md b/src/doc/unstable-book/src/coerce-unsized.md
new file mode 100644 (file)
index 0000000..078d3fa
--- /dev/null
@@ -0,0 +1,7 @@
+# `coerce_unsized`
+
+The tracking issue for this feature is: [#27732]
+
+[#27732]: https://github.com/rust-lang/rust/issues/27732
+
+------------------------
diff --git a/src/doc/unstable-book/src/collection-placement.md b/src/doc/unstable-book/src/collection-placement.md
new file mode 100644 (file)
index 0000000..268ca6e
--- /dev/null
@@ -0,0 +1,7 @@
+# `collection_placement`
+
+The tracking issue for this feature is: [#30172]
+
+[#30172]: https://github.com/rust-lang/rust/issues/30172
+
+------------------------
diff --git a/src/doc/unstable-book/src/collections-range.md b/src/doc/unstable-book/src/collections-range.md
new file mode 100644 (file)
index 0000000..ea4f999
--- /dev/null
@@ -0,0 +1,7 @@
+# `collections_range`
+
+The tracking issue for this feature is: [#30877]
+
+[#30877]: https://github.com/rust-lang/rust/issues/30877
+
+------------------------
diff --git a/src/doc/unstable-book/src/collections.md b/src/doc/unstable-book/src/collections.md
new file mode 100644 (file)
index 0000000..5c93783
--- /dev/null
@@ -0,0 +1,5 @@
+# `collections`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/command-envs.md b/src/doc/unstable-book/src/command-envs.md
new file mode 100644 (file)
index 0000000..0ab89e2
--- /dev/null
@@ -0,0 +1,7 @@
+# `command_envs`
+
+The tracking issue for this feature is: [#38526]
+
+[#38526]: https://github.com/rust-lang/rust/issues/38526
+
+------------------------
diff --git a/src/doc/unstable-book/src/compiler-builtins-lib.md b/src/doc/unstable-book/src/compiler-builtins-lib.md
new file mode 100644 (file)
index 0000000..8986b96
--- /dev/null
@@ -0,0 +1,5 @@
+# `compiler_builtins_lib`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/concat-idents-macro.md b/src/doc/unstable-book/src/concat-idents-macro.md
new file mode 100644 (file)
index 0000000..ac2fdd4
--- /dev/null
@@ -0,0 +1,7 @@
+# `concat_idents_macro`
+
+The tracking issue for this feature is: [#29599]
+
+[#29599]: https://github.com/rust-lang/rust/issues/29599
+
+------------------------
diff --git a/src/doc/unstable-book/src/core-char-ext.md b/src/doc/unstable-book/src/core-char-ext.md
new file mode 100644 (file)
index 0000000..d37d6b5
--- /dev/null
@@ -0,0 +1,7 @@
+# `core_char_ext`
+
+The tracking issue for this feature is: [#32110]
+
+[#32110]: https://github.com/rust-lang/rust/issues/32110
+
+------------------------
diff --git a/src/doc/unstable-book/src/core-float.md b/src/doc/unstable-book/src/core-float.md
new file mode 100644 (file)
index 0000000..194b260
--- /dev/null
@@ -0,0 +1,7 @@
+# `core_float`
+
+The tracking issue for this feature is: [#32110]
+
+[#32110]: https://github.com/rust-lang/rust/issues/32110
+
+------------------------
diff --git a/src/doc/unstable-book/src/core-intrinsics.md b/src/doc/unstable-book/src/core-intrinsics.md
new file mode 100644 (file)
index 0000000..28ad352
--- /dev/null
@@ -0,0 +1,5 @@
+# `core_intrinsics`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/core-panic.md b/src/doc/unstable-book/src/core-panic.md
new file mode 100644 (file)
index 0000000..c197588
--- /dev/null
@@ -0,0 +1,5 @@
+# `core_panic`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/core-private-bignum.md b/src/doc/unstable-book/src/core-private-bignum.md
new file mode 100644 (file)
index 0000000..f85811c
--- /dev/null
@@ -0,0 +1,5 @@
+# `core_private_bignum`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/core-private-diy-float.md b/src/doc/unstable-book/src/core-private-diy-float.md
new file mode 100644 (file)
index 0000000..8465921
--- /dev/null
@@ -0,0 +1,5 @@
+# `core_private_diy_float`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/core-slice-ext.md b/src/doc/unstable-book/src/core-slice-ext.md
new file mode 100644 (file)
index 0000000..c50d44a
--- /dev/null
@@ -0,0 +1,7 @@
+# `core_slice_ext`
+
+The tracking issue for this feature is: [#32110]
+
+[#32110]: https://github.com/rust-lang/rust/issues/32110
+
+------------------------
diff --git a/src/doc/unstable-book/src/core-str-ext.md b/src/doc/unstable-book/src/core-str-ext.md
new file mode 100644 (file)
index 0000000..08c68f1
--- /dev/null
@@ -0,0 +1,7 @@
+# `core_str_ext`
+
+The tracking issue for this feature is: [#32110]
+
+[#32110]: https://github.com/rust-lang/rust/issues/32110
+
+------------------------
diff --git a/src/doc/unstable-book/src/dec2flt.md b/src/doc/unstable-book/src/dec2flt.md
new file mode 100644 (file)
index 0000000..311ab4a
--- /dev/null
@@ -0,0 +1,5 @@
+# `dec2flt`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/decode-utf8.md b/src/doc/unstable-book/src/decode-utf8.md
new file mode 100644 (file)
index 0000000..b96854e
--- /dev/null
@@ -0,0 +1,7 @@
+# `decode_utf8`
+
+The tracking issue for this feature is: [#27783]
+
+[#27783]: https://github.com/rust-lang/rust/issues/27783
+
+------------------------
diff --git a/src/doc/unstable-book/src/derive-clone-copy.md b/src/doc/unstable-book/src/derive-clone-copy.md
new file mode 100644 (file)
index 0000000..cc60391
--- /dev/null
@@ -0,0 +1,5 @@
+# `derive_clone_copy`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/derive-eq.md b/src/doc/unstable-book/src/derive-eq.md
new file mode 100644 (file)
index 0000000..68a275f
--- /dev/null
@@ -0,0 +1,5 @@
+# `derive_eq`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/discriminant-value.md b/src/doc/unstable-book/src/discriminant-value.md
new file mode 100644 (file)
index 0000000..2f99f5e
--- /dev/null
@@ -0,0 +1,7 @@
+# `discriminant_value`
+
+The tracking issue for this feature is: [#24263]
+
+[#24263]: https://github.com/rust-lang/rust/issues/24263
+
+------------------------
diff --git a/src/doc/unstable-book/src/enumset.md b/src/doc/unstable-book/src/enumset.md
new file mode 100644 (file)
index 0000000..24c8d8f
--- /dev/null
@@ -0,0 +1,7 @@
+# `enumset`
+
+The tracking issue for this feature is: [#37966]
+
+[#37966]: https://github.com/rust-lang/rust/issues/37966
+
+------------------------
diff --git a/src/doc/unstable-book/src/error-type-id.md b/src/doc/unstable-book/src/error-type-id.md
new file mode 100644 (file)
index 0000000..be7a3ff
--- /dev/null
@@ -0,0 +1,7 @@
+# `error_type_id`
+
+The tracking issue for this feature is: [#27745]
+
+[#27745]: https://github.com/rust-lang/rust/issues/27745
+
+------------------------
diff --git a/src/doc/unstable-book/src/exact-size-is-empty.md b/src/doc/unstable-book/src/exact-size-is-empty.md
new file mode 100644 (file)
index 0000000..200ec38
--- /dev/null
@@ -0,0 +1,7 @@
+# `exact_size_is_empty`
+
+The tracking issue for this feature is: [#35428]
+
+[#35428]: https://github.com/rust-lang/rust/issues/35428
+
+------------------------
diff --git a/src/doc/unstable-book/src/fd-read.md b/src/doc/unstable-book/src/fd-read.md
new file mode 100644 (file)
index 0000000..e78d433
--- /dev/null
@@ -0,0 +1,5 @@
+# `fd_read`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/fd.md b/src/doc/unstable-book/src/fd.md
new file mode 100644 (file)
index 0000000..0414244
--- /dev/null
@@ -0,0 +1,5 @@
+# `fd`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/field-init-shorthand.md b/src/doc/unstable-book/src/field-init-shorthand.md
deleted file mode 100644 (file)
index e737dba..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# `field_init_shorthand`
-
-The tracking issue for this feature is: [#37340]
-
-[#37340]: https://github.com/rust-lang/rust/issues/37340
-
-------------------------
-
-
-
diff --git a/src/doc/unstable-book/src/fixed-size-array.md b/src/doc/unstable-book/src/fixed-size-array.md
new file mode 100644 (file)
index 0000000..9e24e6a
--- /dev/null
@@ -0,0 +1,7 @@
+# `fixed_size_array`
+
+The tracking issue for this feature is: [#27778]
+
+[#27778]: https://github.com/rust-lang/rust/issues/27778
+
+------------------------
diff --git a/src/doc/unstable-book/src/float-extras.md b/src/doc/unstable-book/src/float-extras.md
new file mode 100644 (file)
index 0000000..ff2d20a
--- /dev/null
@@ -0,0 +1,7 @@
+# `float_extras`
+
+The tracking issue for this feature is: [#27752]
+
+[#27752]: https://github.com/rust-lang/rust/issues/27752
+
+------------------------
diff --git a/src/doc/unstable-book/src/flt2dec.md b/src/doc/unstable-book/src/flt2dec.md
new file mode 100644 (file)
index 0000000..15e62a3
--- /dev/null
@@ -0,0 +1,5 @@
+# `flt2dec`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/fmt-flags-align.md b/src/doc/unstable-book/src/fmt-flags-align.md
new file mode 100644 (file)
index 0000000..755263b
--- /dev/null
@@ -0,0 +1,7 @@
+# `fmt_flags_align`
+
+The tracking issue for this feature is: [#27726]
+
+[#27726]: https://github.com/rust-lang/rust/issues/27726
+
+------------------------
diff --git a/src/doc/unstable-book/src/fmt-internals.md b/src/doc/unstable-book/src/fmt-internals.md
new file mode 100644 (file)
index 0000000..7cbe3c8
--- /dev/null
@@ -0,0 +1,5 @@
+# `fmt_internals`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/fn-traits.md b/src/doc/unstable-book/src/fn-traits.md
new file mode 100644 (file)
index 0000000..3942cda
--- /dev/null
@@ -0,0 +1,7 @@
+# `fn_traits`
+
+The tracking issue for this feature is: [#29625]
+
+[#29625]: https://github.com/rust-lang/rust/issues/29625
+
+------------------------
diff --git a/src/doc/unstable-book/src/fnbox.md b/src/doc/unstable-book/src/fnbox.md
new file mode 100644 (file)
index 0000000..a9b74d4
--- /dev/null
@@ -0,0 +1,7 @@
+# `fnbox`
+
+The tracking issue for this feature is: [#28796]
+
+[#28796]: https://github.com/rust-lang/rust/issues/28796
+
+------------------------
diff --git a/src/doc/unstable-book/src/fused.md b/src/doc/unstable-book/src/fused.md
new file mode 100644 (file)
index 0000000..460555b
--- /dev/null
@@ -0,0 +1,7 @@
+# `fused`
+
+The tracking issue for this feature is: [#35602]
+
+[#35602]: https://github.com/rust-lang/rust/issues/35602
+
+------------------------
diff --git a/src/doc/unstable-book/src/future-atomic-orderings.md b/src/doc/unstable-book/src/future-atomic-orderings.md
new file mode 100644 (file)
index 0000000..40c2ef2
--- /dev/null
@@ -0,0 +1,5 @@
+# `future_atomic_orderings`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/get-type-id.md b/src/doc/unstable-book/src/get-type-id.md
new file mode 100644 (file)
index 0000000..afdb030
--- /dev/null
@@ -0,0 +1,7 @@
+# `get_type_id`
+
+The tracking issue for this feature is: [#27745]
+
+[#27745]: https://github.com/rust-lang/rust/issues/27745
+
+------------------------
diff --git a/src/doc/unstable-book/src/heap-api.md b/src/doc/unstable-book/src/heap-api.md
new file mode 100644 (file)
index 0000000..01404e4
--- /dev/null
@@ -0,0 +1,7 @@
+# `heap_api`
+
+The tracking issue for this feature is: [#27700]
+
+[#27700]: https://github.com/rust-lang/rust/issues/27700
+
+------------------------
diff --git a/src/doc/unstable-book/src/i128.md b/src/doc/unstable-book/src/i128.md
new file mode 100644 (file)
index 0000000..a1a7ce8
--- /dev/null
@@ -0,0 +1,7 @@
+# `i128`
+
+The tracking issue for this feature is: [#35118]
+
+[#35118]: https://github.com/rust-lang/rust/issues/35118
+
+------------------------
index 74d85536399d72f93096fce8091cb67d6167ddbe..255445c318dca7c830e4e325df5155715259ba44 100644 (file)
@@ -6,5 +6,15 @@ The tracking issue for this feature is: [#28237]
 
 ------------------------
 
+To get a range that goes from 0 to 10 and includes the value 10, you
+can write `0...10`:
 
+```rust
+#![feature(inclusive_range_syntax)]
 
+fn main() {
+    for i in 0...10 {
+        println!("{}", i);
+    }
+}
+```
diff --git a/src/doc/unstable-book/src/inclusive-range.md b/src/doc/unstable-book/src/inclusive-range.md
new file mode 100644 (file)
index 0000000..2e88e20
--- /dev/null
@@ -0,0 +1,7 @@
+# `inclusive_range`
+
+The tracking issue for this feature is: [#28237]
+
+[#28237]: https://github.com/rust-lang/rust/issues/28237
+
+------------------------
diff --git a/src/doc/unstable-book/src/int-error-internals.md b/src/doc/unstable-book/src/int-error-internals.md
new file mode 100644 (file)
index 0000000..402e4fa
--- /dev/null
@@ -0,0 +1,5 @@
+# `int_error_internals`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/integer-atomics.md b/src/doc/unstable-book/src/integer-atomics.md
new file mode 100644 (file)
index 0000000..50db9fd
--- /dev/null
@@ -0,0 +1,7 @@
+# `integer_atomics`
+
+The tracking issue for this feature is: [#32976]
+
+[#32976]: https://github.com/rust-lang/rust/issues/32976
+
+------------------------
diff --git a/src/doc/unstable-book/src/into-boxed-c-str.md b/src/doc/unstable-book/src/into-boxed-c-str.md
new file mode 100644 (file)
index 0000000..0d94b4f
--- /dev/null
@@ -0,0 +1,7 @@
+# `into_boxed_c_str`
+
+The tracking issue for this feature is: [#40380]
+
+[#40380]: https://github.com/rust-lang/rust/issues/40380
+
+------------------------
diff --git a/src/doc/unstable-book/src/into-boxed-os-str.md b/src/doc/unstable-book/src/into-boxed-os-str.md
new file mode 100644 (file)
index 0000000..7636e20
--- /dev/null
@@ -0,0 +1,7 @@
+# `into_boxed_os_str`
+
+The tracking issue for this feature is: [#into_boxed_os_str]
+
+[#into_boxed_os_str]: https://github.com/rust-lang/rust/issues/40380
+
+------------------------
diff --git a/src/doc/unstable-book/src/into-boxed-path.md b/src/doc/unstable-book/src/into-boxed-path.md
new file mode 100644 (file)
index 0000000..754c604
--- /dev/null
@@ -0,0 +1,7 @@
+# `into_boxed_path`
+
+The tracking issue for this feature is: [#40380]
+
+[#40380]: https://github.com/rust-lang/rust/issues/40380
+
+------------------------
diff --git a/src/doc/unstable-book/src/io-error-internals.md b/src/doc/unstable-book/src/io-error-internals.md
new file mode 100644 (file)
index 0000000..5bee18d
--- /dev/null
@@ -0,0 +1,5 @@
+# `io_error_internals`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/io.md b/src/doc/unstable-book/src/io.md
new file mode 100644 (file)
index 0000000..ed6cae2
--- /dev/null
@@ -0,0 +1,7 @@
+# `io`
+
+The tracking issue for this feature is: [#27802]
+
+[#27802]: https://github.com/rust-lang/rust/issues/27802
+
+------------------------
diff --git a/src/doc/unstable-book/src/ip.md b/src/doc/unstable-book/src/ip.md
new file mode 100644 (file)
index 0000000..7e7d52a
--- /dev/null
@@ -0,0 +1,7 @@
+# `ip`
+
+The tracking issue for this feature is: [#27709]
+
+[#27709]: https://github.com/rust-lang/rust/issues/27709
+
+------------------------
diff --git a/src/doc/unstable-book/src/is-unique.md b/src/doc/unstable-book/src/is-unique.md
new file mode 100644 (file)
index 0000000..6070006
--- /dev/null
@@ -0,0 +1,7 @@
+# `is_unique`
+
+The tracking issue for this feature is: [#28356]
+
+[#28356]: https://github.com/rust-lang/rust/issues/28356
+
+------------------------
diff --git a/src/doc/unstable-book/src/iter-rfind.md b/src/doc/unstable-book/src/iter-rfind.md
new file mode 100644 (file)
index 0000000..4447144
--- /dev/null
@@ -0,0 +1,7 @@
+# `iter_rfind`
+
+The tracking issue for this feature is: [#39480]
+
+[#39480]: https://github.com/rust-lang/rust/issues/39480
+
+------------------------
diff --git a/src/doc/unstable-book/src/libstd-io-internals.md b/src/doc/unstable-book/src/libstd-io-internals.md
new file mode 100644 (file)
index 0000000..8bcc276
--- /dev/null
@@ -0,0 +1,5 @@
+# `libstd_io_internals`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/libstd-sys-internals.md b/src/doc/unstable-book/src/libstd-sys-internals.md
new file mode 100644 (file)
index 0000000..1b53faa
--- /dev/null
@@ -0,0 +1,5 @@
+# `libstd_sys_internals`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/libstd-thread-internals.md b/src/doc/unstable-book/src/libstd-thread-internals.md
new file mode 100644 (file)
index 0000000..b682d12
--- /dev/null
@@ -0,0 +1,5 @@
+# `libstd_thread_internals`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/linked-list-extras.md b/src/doc/unstable-book/src/linked-list-extras.md
new file mode 100644 (file)
index 0000000..be3b96a
--- /dev/null
@@ -0,0 +1,7 @@
+# `linked_list_extras`
+
+The tracking issue for this feature is: [#27794]
+
+[#27794]: https://github.com/rust-lang/rust/issues/27794
+
+------------------------
diff --git a/src/doc/unstable-book/src/lookup-host.md b/src/doc/unstable-book/src/lookup-host.md
new file mode 100644 (file)
index 0000000..b60e7a0
--- /dev/null
@@ -0,0 +1,7 @@
+# `lookup_host`
+
+The tracking issue for this feature is: [#27705]
+
+[#27705]: https://github.com/rust-lang/rust/issues/27705
+
+------------------------
diff --git a/src/doc/unstable-book/src/map-entry-recover-keys.md b/src/doc/unstable-book/src/map-entry-recover-keys.md
new file mode 100644 (file)
index 0000000..2d15aa0
--- /dev/null
@@ -0,0 +1,5 @@
+# `map_entry_recover_keys`
+
+The tracking issue for this feature is: [#34285]
+
+[#34285]: https://github.com/rust-lang/rust/issues/34285
diff --git a/src/doc/unstable-book/src/mpsc-select.md b/src/doc/unstable-book/src/mpsc-select.md
new file mode 100644 (file)
index 0000000..1405b6c
--- /dev/null
@@ -0,0 +1,5 @@
+# `mpsc_select`
+
+The tracking issue for this feature is: [#27800]
+
+[#27800]: https://github.com/rust-lang/rust/issues/27800
diff --git a/src/doc/unstable-book/src/n16.md b/src/doc/unstable-book/src/n16.md
new file mode 100644 (file)
index 0000000..e556ada
--- /dev/null
@@ -0,0 +1,5 @@
+# `n16`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/never-type-impls.md b/src/doc/unstable-book/src/never-type-impls.md
new file mode 100644 (file)
index 0000000..4063cd0
--- /dev/null
@@ -0,0 +1,7 @@
+# `never_type_impls`
+
+The tracking issue for this feature is: [#35121]
+
+[#35121]: https://github.com/rust-lang/rust/issues/35121
+
+------------------------
diff --git a/src/doc/unstable-book/src/nonzero.md b/src/doc/unstable-book/src/nonzero.md
new file mode 100644 (file)
index 0000000..f200f8e
--- /dev/null
@@ -0,0 +1,7 @@
+# `nonzero`
+
+The tracking issue for this feature is: [#27730]
+
+[#27730]: https://github.com/rust-lang/rust/issues/27730
+
+------------------------
diff --git a/src/doc/unstable-book/src/once-poison.md b/src/doc/unstable-book/src/once-poison.md
new file mode 100644 (file)
index 0000000..3c16caf
--- /dev/null
@@ -0,0 +1,7 @@
+# `once_poison`
+
+The tracking issue for this feature is: [#33577]
+
+[#33577]: https://github.com/rust-lang/rust/issues/33577
+
+------------------------
diff --git a/src/doc/unstable-book/src/oom.md b/src/doc/unstable-book/src/oom.md
new file mode 100644 (file)
index 0000000..908caeb
--- /dev/null
@@ -0,0 +1,7 @@
+# `oom`
+
+The tracking issue for this feature is: [#27700]
+
+[#27700]: https://github.com/rust-lang/rust/issues/27700
+
+------------------------
diff --git a/src/doc/unstable-book/src/option-entry.md b/src/doc/unstable-book/src/option-entry.md
new file mode 100644 (file)
index 0000000..edb4efc
--- /dev/null
@@ -0,0 +1,7 @@
+# `option_entry`
+
+The tracking issue for this feature is: [#39288]
+
+[#39288]: https://github.com/rust-lang/rust/issues/39288
+
+------------------------
diff --git a/src/doc/unstable-book/src/osstring-shrink-to-fit.md b/src/doc/unstable-book/src/osstring-shrink-to-fit.md
new file mode 100644 (file)
index 0000000..21dc7d0
--- /dev/null
@@ -0,0 +1,7 @@
+# `osstring_shrink_to_fit`
+
+The tracking issue for this feature is: [#40421]
+
+[#40421]: https://github.com/rust-lang/rust/issues/40421
+
+------------------------
diff --git a/src/doc/unstable-book/src/panic-abort.md b/src/doc/unstable-book/src/panic-abort.md
new file mode 100644 (file)
index 0000000..07a9576
--- /dev/null
@@ -0,0 +1,7 @@
+# `panic_abort`
+
+The tracking issue for this feature is: [#32837]
+
+[#32837]: https://github.com/rust-lang/rust/issues/32837
+
+------------------------
diff --git a/src/doc/unstable-book/src/panic-unwind.md b/src/doc/unstable-book/src/panic-unwind.md
new file mode 100644 (file)
index 0000000..840e492
--- /dev/null
@@ -0,0 +1,7 @@
+# `panic_unwind`
+
+The tracking issue for this feature is: [#32837]
+
+[#32837]: https://github.com/rust-lang/rust/issues/32837
+
+------------------------
diff --git a/src/doc/unstable-book/src/pattern.md b/src/doc/unstable-book/src/pattern.md
new file mode 100644 (file)
index 0000000..e76ee6b
--- /dev/null
@@ -0,0 +1,7 @@
+# `pattern`
+
+The tracking issue for this feature is: [#27721]
+
+[#27721]: https://github.com/rust-lang/rust/issues/27721
+
+------------------------
diff --git a/src/doc/unstable-book/src/peek.md b/src/doc/unstable-book/src/peek.md
new file mode 100644 (file)
index 0000000..c42b4e9
--- /dev/null
@@ -0,0 +1,7 @@
+# `peek`
+
+The tracking issue for this feature is: [#38980]
+
+[#38980]: https://github.com/rust-lang/rust/issues/38980
+
+------------------------
diff --git a/src/doc/unstable-book/src/placement-in.md b/src/doc/unstable-book/src/placement-in.md
new file mode 100644 (file)
index 0000000..6ff010b
--- /dev/null
@@ -0,0 +1,7 @@
+# `placement_in`
+
+The tracking issue for this feature is: [#27779]
+
+[#27779]: https://github.com/rust-lang/rust/issues/27779
+
+------------------------
diff --git a/src/doc/unstable-book/src/placement-new-protocol.md b/src/doc/unstable-book/src/placement-new-protocol.md
new file mode 100644 (file)
index 0000000..d53225f
--- /dev/null
@@ -0,0 +1,7 @@
+# `placement_new_protocol`
+
+The tracking issue for this feature is: [#27779]
+
+[#27779]: https://github.com/rust-lang/rust/issues/27779
+
+------------------------
diff --git a/src/doc/unstable-book/src/print.md b/src/doc/unstable-book/src/print.md
new file mode 100644 (file)
index 0000000..dc25cb2
--- /dev/null
@@ -0,0 +1,5 @@
+# `print`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/proc-macro-internals.md b/src/doc/unstable-book/src/proc-macro-internals.md
new file mode 100644 (file)
index 0000000..ea087c0
--- /dev/null
@@ -0,0 +1,7 @@
+# `proc_macro_internals`
+
+The tracking issue for this feature is: [#27812]
+
+[#27812]: https://github.com/rust-lang/rust/issues/27812
+
+------------------------
diff --git a/src/doc/unstable-book/src/process-try-wait.md b/src/doc/unstable-book/src/process-try-wait.md
new file mode 100644 (file)
index 0000000..3593b64
--- /dev/null
@@ -0,0 +1,7 @@
+# `process_try_wait`
+
+The tracking issue for this feature is: [#38903]
+
+[#38903]: https://github.com/rust-lang/rust/issues/38903
+
+------------------------
diff --git a/src/doc/unstable-book/src/pub-restricted.md b/src/doc/unstable-book/src/pub-restricted.md
new file mode 100644 (file)
index 0000000..6b1e88b
--- /dev/null
@@ -0,0 +1,7 @@
+# `pub_restricted`
+
+The tracking issue for this feature is: [#32409]
+
+[#38356]: https://github.com/rust-lang/rust/issues/32409
+
+------------------------
diff --git a/src/doc/unstable-book/src/question-mark-carrier.md b/src/doc/unstable-book/src/question-mark-carrier.md
new file mode 100644 (file)
index 0000000..56154ac
--- /dev/null
@@ -0,0 +1,7 @@
+# `question_mark_carrier`
+
+The tracking issue for this feature is: [#31436]
+
+[#31436]: https://github.com/rust-lang/rust/issues/31436
+
+------------------------
diff --git a/src/doc/unstable-book/src/rand.md b/src/doc/unstable-book/src/rand.md
new file mode 100644 (file)
index 0000000..d0229d9
--- /dev/null
@@ -0,0 +1,5 @@
+# `rand`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/range-contains.md b/src/doc/unstable-book/src/range-contains.md
new file mode 100644 (file)
index 0000000..ac4581f
--- /dev/null
@@ -0,0 +1,7 @@
+# `range_contains`
+
+The tracking issue for this feature is: [#32311]
+
+[#32311]: https://github.com/rust-lang/rust/issues/32311
+
+------------------------
diff --git a/src/doc/unstable-book/src/raw.md b/src/doc/unstable-book/src/raw.md
new file mode 100644 (file)
index 0000000..d7caf22
--- /dev/null
@@ -0,0 +1,7 @@
+# `raw`
+
+The tracking issue for this feature is: [#27751]
+
+[#27751]: https://github.com/rust-lang/rust/issues/27751
+
+------------------------
diff --git a/src/doc/unstable-book/src/rc-would-unwrap.md b/src/doc/unstable-book/src/rc-would-unwrap.md
new file mode 100644 (file)
index 0000000..462387d
--- /dev/null
@@ -0,0 +1,5 @@
+# `rc_would_unwrap`
+
+The tracking issue for this feature is: [#28356]
+
+[#28356]: https://github.com/rust-lang/rust/issues/28356
diff --git a/src/doc/unstable-book/src/retain-hash-collection.md b/src/doc/unstable-book/src/retain-hash-collection.md
new file mode 100644 (file)
index 0000000..c9ba5ac
--- /dev/null
@@ -0,0 +1,7 @@
+# `retain_hash_collection`
+
+The tracking issue for this feature is: [#36648]
+
+[#36648]: https://github.com/rust-lang/rust/issues/36648
+
+------------------------
diff --git a/src/doc/unstable-book/src/rt.md b/src/doc/unstable-book/src/rt.md
new file mode 100644 (file)
index 0000000..007acc2
--- /dev/null
@@ -0,0 +1,5 @@
+# `rt`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/rustc-private.md b/src/doc/unstable-book/src/rustc-private.md
new file mode 100644 (file)
index 0000000..2453475
--- /dev/null
@@ -0,0 +1,7 @@
+# `rustc_private`
+
+The tracking issue for this feature is: [#27812]
+
+[#27812]: https://github.com/rust-lang/rust/issues/27812
+
+------------------------
diff --git a/src/doc/unstable-book/src/rustdoc.md b/src/doc/unstable-book/src/rustdoc.md
new file mode 100644 (file)
index 0000000..c7491ab
--- /dev/null
@@ -0,0 +1,7 @@
+# `rustdoc`
+
+The tracking issue for this feature is: [#27812]
+
+[#27812]: https://github.com/rust-lang/rust/issues/27812
+
+------------------------
diff --git a/src/doc/unstable-book/src/sanitizer-runtime-lib.md b/src/doc/unstable-book/src/sanitizer-runtime-lib.md
new file mode 100644 (file)
index 0000000..82ae67f
--- /dev/null
@@ -0,0 +1,5 @@
+# `sanitizer_runtime_lib`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/set-stdio.md b/src/doc/unstable-book/src/set-stdio.md
new file mode 100644 (file)
index 0000000..7dbdcda
--- /dev/null
@@ -0,0 +1,5 @@
+# `set_stdio`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/shared.md b/src/doc/unstable-book/src/shared.md
new file mode 100644 (file)
index 0000000..b79d121
--- /dev/null
@@ -0,0 +1,7 @@
+# `shared`
+
+The tracking issue for this feature is: [#27730]
+
+[#27730]: https://github.com/rust-lang/rust/issues/27730
+
+------------------------
diff --git a/src/doc/unstable-book/src/sip-hash-13.md b/src/doc/unstable-book/src/sip-hash-13.md
new file mode 100644 (file)
index 0000000..8f69c3a
--- /dev/null
@@ -0,0 +1,7 @@
+# `sip_hash_13`
+
+The tracking issue for this feature is: [#34767]
+
+[#34767]: https://github.com/rust-lang/rust/issues/34767
+
+------------------------
diff --git a/src/doc/unstable-book/src/slice-concat-ext.md b/src/doc/unstable-book/src/slice-concat-ext.md
new file mode 100644 (file)
index 0000000..9ba2de5
--- /dev/null
@@ -0,0 +1,7 @@
+# `slice_concat_ext`
+
+The tracking issue for this feature is: [#27747]
+
+[#27747]: https://github.com/rust-lang/rust/issues/27747
+
+------------------------
diff --git a/src/doc/unstable-book/src/slice-get-slice.md b/src/doc/unstable-book/src/slice-get-slice.md
new file mode 100644 (file)
index 0000000..57e2c14
--- /dev/null
@@ -0,0 +1,7 @@
+# `slice_get_slice`
+
+The tracking issue for this feature is: [#35729]
+
+[#35729]: https://github.com/rust-lang/rust/issues/35729
+
+------------------------
diff --git a/src/doc/unstable-book/src/sort-internals.md b/src/doc/unstable-book/src/sort-internals.md
new file mode 100644 (file)
index 0000000..6f2385e
--- /dev/null
@@ -0,0 +1,5 @@
+# `sort_internals`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/static-recursion.md b/src/doc/unstable-book/src/static-recursion.md
deleted file mode 100644 (file)
index d419ea4..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# `static_recursion`
-
-The tracking issue for this feature is: [#29719]
-
-[#29719]: https://github.com/rust-lang/rust/issues/29719
-
-------------------------
-
-
-
diff --git a/src/doc/unstable-book/src/step-by.md b/src/doc/unstable-book/src/step-by.md
new file mode 100644 (file)
index 0000000..b649496
--- /dev/null
@@ -0,0 +1,7 @@
+# `step_by`
+
+The tracking issue for this feature is: [#27741]
+
+[#27741]: https://github.com/rust-lang/rust/issues/27741
+
+------------------------
diff --git a/src/doc/unstable-book/src/step-trait.md b/src/doc/unstable-book/src/step-trait.md
new file mode 100644 (file)
index 0000000..e53ca13
--- /dev/null
@@ -0,0 +1,7 @@
+# `step_trait`
+
+The tracking issue for this feature is: [#27741]
+
+[#27741]: https://github.com/rust-lang/rust/issues/27741
+
+------------------------
diff --git a/src/doc/unstable-book/src/str-escape.md b/src/doc/unstable-book/src/str-escape.md
new file mode 100644 (file)
index 0000000..61e31c8
--- /dev/null
@@ -0,0 +1,7 @@
+# `str_escape`
+
+The tracking issue for this feature is: [#27791]
+
+[#27791]: https://github.com/rust-lang/rust/issues/27791
+
+------------------------
diff --git a/src/doc/unstable-book/src/str-internals.md b/src/doc/unstable-book/src/str-internals.md
new file mode 100644 (file)
index 0000000..af8ef05
--- /dev/null
@@ -0,0 +1,5 @@
+# `str_internals`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/thread-id.md b/src/doc/unstable-book/src/thread-id.md
new file mode 100644 (file)
index 0000000..af3ea99
--- /dev/null
@@ -0,0 +1,7 @@
+# `thread_id`
+
+The tracking issue for this feature is: [#21507]
+
+[#21507]: https://github.com/rust-lang/rust/issues/21507
+
+------------------------
diff --git a/src/doc/unstable-book/src/thread-local-internals.md b/src/doc/unstable-book/src/thread-local-internals.md
new file mode 100644 (file)
index 0000000..e1cdcc3
--- /dev/null
@@ -0,0 +1,5 @@
+# `thread_local_internals`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/thread-local-state.md b/src/doc/unstable-book/src/thread-local-state.md
new file mode 100644 (file)
index 0000000..113c1e9
--- /dev/null
@@ -0,0 +1,7 @@
+# `thread_local_state`
+
+The tracking issue for this feature is: [#27716]
+
+[#27716]: https://github.com/rust-lang/rust/issues/27716
+
+------------------------
diff --git a/src/doc/unstable-book/src/trusted-len.md b/src/doc/unstable-book/src/trusted-len.md
new file mode 100644 (file)
index 0000000..80213cf
--- /dev/null
@@ -0,0 +1,7 @@
+# `trusted_len`
+
+The tracking issue for this feature is: [#37572]
+
+[#37572]: https://github.com/rust-lang/rust/issues/37572
+
+------------------------
diff --git a/src/doc/unstable-book/src/try-from.md b/src/doc/unstable-book/src/try-from.md
new file mode 100644 (file)
index 0000000..d763caf
--- /dev/null
@@ -0,0 +1,7 @@
+# `try_from`
+
+The tracking issue for this feature is: [#33417]
+
+[#33417]: https://github.com/rust-lang/rust/issues/33417
+
+------------------------
diff --git a/src/doc/unstable-book/src/unicode.md b/src/doc/unstable-book/src/unicode.md
new file mode 100644 (file)
index 0000000..9fecec2
--- /dev/null
@@ -0,0 +1,7 @@
+# `unicode`
+
+The tracking issue for this feature is: [#27783]
+
+[#27783]: https://github.com/rust-lang/rust/issues/27783
+
+------------------------
diff --git a/src/doc/unstable-book/src/unique.md b/src/doc/unstable-book/src/unique.md
new file mode 100644 (file)
index 0000000..99a3490
--- /dev/null
@@ -0,0 +1,7 @@
+# `unique`
+
+The tracking issue for this feature is: [#27730]
+
+[#27730]: https://github.com/rust-lang/rust/issues/27730
+
+------------------------
diff --git a/src/doc/unstable-book/src/unsize.md b/src/doc/unstable-book/src/unsize.md
new file mode 100644 (file)
index 0000000..92807e2
--- /dev/null
@@ -0,0 +1,7 @@
+# `unsize`
+
+The tracking issue for this feature is: [#27732]
+
+[#27732]: https://github.com/rust-lang/rust/issues/27732
+
+------------------------
diff --git a/src/doc/unstable-book/src/update-panic-count.md b/src/doc/unstable-book/src/update-panic-count.md
new file mode 100644 (file)
index 0000000..d315647
--- /dev/null
@@ -0,0 +1,5 @@
+# `update_panic_count`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/utf8-error-error-len.md b/src/doc/unstable-book/src/utf8-error-error-len.md
new file mode 100644 (file)
index 0000000..1c14a5a
--- /dev/null
@@ -0,0 +1,7 @@
+# `utf8_error_error_len`
+
+The tracking issue for this feature is: [#40494]
+
+[#40494]: https://github.com/rust-lang/rust/issues/40494
+
+------------------------
diff --git a/src/doc/unstable-book/src/vec-remove-item.md b/src/doc/unstable-book/src/vec-remove-item.md
new file mode 100644 (file)
index 0000000..2b8c9f0
--- /dev/null
@@ -0,0 +1,7 @@
+# `vec_remove_item`
+
+The tracking issue for this feature is: [#40062]
+
+[#40062]: https://github.com/rust-lang/rust/issues/40062
+
+------------------------
diff --git a/src/doc/unstable-book/src/windows-c.md b/src/doc/unstable-book/src/windows-c.md
new file mode 100644 (file)
index 0000000..3f833eb
--- /dev/null
@@ -0,0 +1,5 @@
+# `windows_c`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/windows-handle.md b/src/doc/unstable-book/src/windows-handle.md
new file mode 100644 (file)
index 0000000..f47a842
--- /dev/null
@@ -0,0 +1,5 @@
+# `windows_handle`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/windows-net.md b/src/doc/unstable-book/src/windows-net.md
new file mode 100644 (file)
index 0000000..174960d
--- /dev/null
@@ -0,0 +1,5 @@
+# `windows_net`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/windows-stdio.md b/src/doc/unstable-book/src/windows-stdio.md
new file mode 100644 (file)
index 0000000..4d36144
--- /dev/null
@@ -0,0 +1,5 @@
+# `windows_stdio`
+
+This feature is internal to the Rust compiler and is not intended for general use.
+
+------------------------
diff --git a/src/doc/unstable-book/src/zero-one.md b/src/doc/unstable-book/src/zero-one.md
new file mode 100644 (file)
index 0000000..4d1cf38
--- /dev/null
@@ -0,0 +1,7 @@
+# `zero_one`
+
+The tracking issue for this feature is: [#27739]
+
+[#27739]: https://github.com/rust-lang/rust/issues/27739
+
+------------------------
index 919fc98e438c52a0ceb21bf41f38d2fecd48a274..bd28a63c5f4dfb947edce379ac569c3c1af43519 100644 (file)
@@ -196,7 +196,7 @@ fn parse_antlr_token(s: &str, tokens: &HashMap<String, token::Token>, surrogate_
     let toknum = &s[content_end + 3 .. toknum_end];
 
     let not_found = format!("didn't find token {:?} in the map", toknum);
-    let proto_tok = tokens.get(toknum).expect(&not_found[..]);
+    let proto_tok = tokens.get(toknum).expect(&not_found);
 
     let nm = Symbol::intern(content);
 
@@ -304,14 +304,14 @@ fn next(r: &mut lexer::StringReader) -> TokenAndSpan {
     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 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[..],
+                                                       &surrogate_pairs_pos,
                                                        has_bom));
 
     for antlr_tok in antlr_tokens {
index f58c87b801f552852d2f7c4392971eeaf2d18c3c..8f0488f69369e5d905c18c906e1cfa5c459e34f0 100644 (file)
@@ -1376,7 +1376,7 @@ fn test_send() {
         thread::spawn(move || {
                 check_links(&n);
                 let a: &[_] = &[&1, &2, &3];
-                assert_eq!(a, &n.iter().collect::<Vec<_>>()[..]);
+                assert_eq!(a, &*n.iter().collect::<Vec<_>>());
             })
             .join()
             .ok()
index 8abc9ca7e9fe87b19ee29c632480122bda4a7853..219e818f7d7385123e2eacdab699b19b655c8b6e 100644 (file)
 
 //! Unicode string slices.
 //!
+//! The `&str` type is one of the two main string types, the other being `String`.
+//! Unlike its `String` counterpart, its contents are borrowed.
+//!
+//! # Basic Usage
+//!
+//! A basic string declaration of `&str` type:
+//!
+//! ```
+//! let hello_world = "Hello, World!";
+//! ```
+//!
+//! Here we have declared a string literal, also known as a string slice.
+//! String literals have a static lifetime, which means the string `hello_world`
+//! is guaranteed to be valid for the duration of the entire program.
+//! We can explicitly specify `hello_world`'s lifetime as well:
+//!
+//! ```
+//! let hello_world: &'static str = "Hello, world!";
+//! ```
+//!
 //! *[See also the `str` primitive type](../../std/primitive.str.html).*
 
-
 #![stable(feature = "rust1", since = "1.0.0")]
 
 // Many of the usings in this module are only used in the test configuration.
index 7b408af13aa2f4b435ad64beed14b0871dd77b8e..56b60a3e00341b6b4eb6605b65d16d3350e0c2b5 100644 (file)
@@ -1563,7 +1563,7 @@ fn deref_mut(&mut self) -> &mut [T] {
 impl<T> FromIterator<T> for Vec<T> {
     #[inline]
     fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Vec<T> {
-        <Self as SpecExtend<_, _>>::from_iter(iter.into_iter())
+        <Self as SpecExtend<T, I::IntoIter>>::from_iter(iter.into_iter())
     }
 }
 
@@ -1631,7 +1631,7 @@ fn into_iter(mut self) -> slice::IterMut<'a, T> {
 impl<T> Extend<T> for Vec<T> {
     #[inline]
     fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
-        self.spec_extend(iter.into_iter())
+        <Self as SpecExtend<T, I::IntoIter>>::spec_extend(self, iter.into_iter())
     }
 }
 
@@ -1662,7 +1662,7 @@ impl<T, I> SpecExtend<T, I> for Vec<T>
                 vector
             }
         };
-        vector.spec_extend(iterator);
+        <Vec<T> as SpecExtend<T, I>>::spec_extend(&mut vector, iterator);
         vector
     }
 
@@ -1674,7 +1674,7 @@ impl<T, I> SpecExtend<T, I> for Vec<T>
 impl<T, I> SpecExtend<T, I> for Vec<T>
     where I: TrustedLen<Item=T>,
 {
-    fn from_iter(iterator: I) -> Self {
+    default fn from_iter(iterator: I) -> Self {
         let mut vector = Vec::new();
         vector.spec_extend(iterator);
         vector
@@ -1706,6 +1706,27 @@ fn spec_extend(&mut self, iterator: I) {
     }
 }
 
+impl<T> SpecExtend<T, IntoIter<T>> for Vec<T> {
+    fn from_iter(iterator: IntoIter<T>) -> Self {
+        // A common case is passing a vector into a function which immediately
+        // re-collects into a vector. We can short circuit this if the IntoIter
+        // has not been advanced at all.
+        if *iterator.buf == iterator.ptr as *mut T {
+            unsafe {
+                let vec = Vec::from_raw_parts(*iterator.buf as *mut T,
+                                              iterator.len(),
+                                              iterator.cap);
+                mem::forget(iterator);
+                vec
+            }
+        } else {
+            let mut vector = Vec::new();
+            vector.spec_extend(iterator);
+            vector
+        }
+    }
+}
+
 impl<'a, T: 'a, I> SpecExtend<&'a T, I> for Vec<T>
     where I: Iterator<Item=&'a T>,
           T: Clone,
index 06d70800d392560e8c99e44fd65edc878c95a114..63df0eb73050971b86dad86fe7e4814f53d23d32 100644 (file)
@@ -680,3 +680,19 @@ fn mkpanic() -> usize { panic!() }
     let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { vec.place_back() <- mkpanic(); }));
     assert_eq!(vec.len(), 3);
 }
+
+#[test]
+fn from_into_inner() {
+    let vec = vec![1, 2, 3];
+    let ptr = vec.as_ptr();
+    let vec = vec.into_iter().collect::<Vec<_>>();
+    assert_eq!(vec, [1, 2, 3]);
+    assert_eq!(vec.as_ptr(), ptr);
+
+    let ptr = &vec[1] as *const _;
+    let mut it = vec.into_iter();
+    it.next().unwrap();
+    let vec = it.collect::<Vec<_>>();
+    assert_eq!(vec, [2, 3]);
+    assert!(ptr != vec.as_ptr());
+}
index 7db35359a1f7d427433a69d9a100f8a5587bfc1b..dc2398b22acec67e6dbd98f1c94a9698a266c4ef 100644 (file)
@@ -322,6 +322,41 @@ pub fn then_with<F: FnOnce() -> Ordering>(self, f: F) -> Ordering {
     }
 }
 
+/// A helper struct for reverse ordering.
+///
+/// This struct is a helper to be used with functions like `Vec::sort_by_key` and
+/// can be used to reverse order a part of a key.
+///
+/// Example usage:
+///
+/// ```
+/// #![feature(reverse_cmp_key)]
+/// use std::cmp::Reverse;
+///
+/// let mut v = vec![1, 2, 3, 4, 5, 6];
+/// v.sort_by_key(|&num| (num > 3, Reverse(num)));
+/// assert_eq!(v, vec![3, 2, 1, 6, 5, 4]);
+/// ```
+#[derive(PartialEq, Eq, Debug)]
+#[unstable(feature = "reverse_cmp_key", issue = "40893")]
+pub struct Reverse<T>(pub T);
+
+#[unstable(feature = "reverse_cmp_key", issue = "40893")]
+impl<T: PartialOrd> PartialOrd for Reverse<T> {
+    #[inline]
+    fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> {
+        other.0.partial_cmp(&self.0)
+    }
+}
+
+#[unstable(feature = "reverse_cmp_key", issue = "40893")]
+impl<T: Ord> Ord for Reverse<T> {
+    #[inline]
+    fn cmp(&self, other: &Reverse<T>) -> Ordering {
+        other.0.cmp(&self.0)
+    }
+}
+
 /// Trait for types that form a [total order](https://en.wikipedia.org/wiki/Total_order).
 ///
 /// An order is a total order if it is (for all `a`, `b` and `c`):
index 604bc7c10dea0aedaa886e976f1c63e392314fce..60dab943a3acfa094b93b275162bacc294610b78 100644 (file)
@@ -141,7 +141,7 @@ pub fn fast_path<T: RawFloat>(integral: &[u8], fractional: &[u8], e: i64) -> Opt
 ///
 /// It rounds ``f`` to a float with 64 bit significand and multiplies it by the best approximation
 /// of `10^e` (in the same floating point format). This is often enough to get the correct result.
-/// However, when the result is close to halfway between two adjecent (ordinary) floats, the
+/// However, when the result is close to halfway between two adjacent (ordinary) floats, the
 /// compound rounding error from multiplying two approximation means the result may be off by a
 /// few bits. When this happens, the iterative Algorithm R fixes things up.
 ///
@@ -392,7 +392,7 @@ fn underflow<T: RawFloat>(x: Big, v: Big, rem: Big) -> T {
     //
     // Therefore, when the rounded-off bits are != 0.5 ULP, they decide the rounding
     // on their own. When they are equal and the remainder is non-zero, the value still
-    // needs to be rounded up. Only when the rounded off bits are 1/2 and the remainer
+    // needs to be rounded up. Only when the rounded off bits are 1/2 and the remainder
     // is zero, we have a half-to-even situation.
     let bits = x.bit_length();
     let lsb = bits - T::sig_bits() as usize;
index 686cc21eba1a0aafca8436250d940dc4ead374d6..d203b68c0dfd57fd1e8461968bf607a9089de01c 100644 (file)
@@ -196,7 +196,7 @@ pub trait Drop {
     fn drop(&mut self);
 }
 
-/// The `Add` trait is used to specify the functionality of `+`.
+/// The addition operator `+`.
 ///
 /// # Examples
 ///
@@ -269,7 +269,7 @@ fn add(self, other: $t) -> $t { self + other }
 
 add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `Sub` trait is used to specify the functionality of `-`.
+/// The subtraction operator `-`.
 ///
 /// # Examples
 ///
@@ -342,7 +342,7 @@ fn sub(self, other: $t) -> $t { self - other }
 
 sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `Mul` trait is used to specify the functionality of `*`.
+/// The multiplication operator `*`.
 ///
 /// # Examples
 ///
@@ -464,7 +464,7 @@ fn mul(self, other: $t) -> $t { self * other }
 
 mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `Div` trait is used to specify the functionality of `/`.
+/// The division operator `/`.
 ///
 /// # Examples
 ///
@@ -609,7 +609,7 @@ fn div(self, other: $t) -> $t { self / other }
 
 div_impl_float! { f32 f64 }
 
-/// The `Rem` trait is used to specify the functionality of `%`.
+/// The remainder operator `%`.
 ///
 /// # Examples
 ///
@@ -689,7 +689,7 @@ fn rem(self, other: $t) -> $t { self % other }
 
 rem_impl_float! { f32 f64 }
 
-/// The `Neg` trait is used to specify the functionality of unary `-`.
+/// The unary negation operator `-`.
 ///
 /// # Examples
 ///
@@ -768,7 +768,7 @@ macro_rules! neg_impl_unsigned {
 // neg_impl_unsigned! { usize u8 u16 u32 u64 }
 neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `Not` trait is used to specify the functionality of unary `!`.
+/// The unary logical negation operator `!`.
 ///
 /// # Examples
 ///
@@ -826,7 +826,7 @@ fn not(self) -> $t { !self }
 
 not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
-/// The `BitAnd` trait is used to specify the functionality of `&`.
+/// The bitwise AND operator `&`.
 ///
 /// # Examples
 ///
@@ -909,7 +909,7 @@ fn bitand(self, rhs: $t) -> $t { self & rhs }
 
 bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
-/// The `BitOr` trait is used to specify the functionality of `|`.
+/// The bitwise OR operator `|`.
 ///
 /// # Examples
 ///
@@ -992,7 +992,7 @@ fn bitor(self, rhs: $t) -> $t { self | rhs }
 
 bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
-/// The `BitXor` trait is used to specify the functionality of `^`.
+/// The bitwise XOR operator `^`.
 ///
 /// # Examples
 ///
@@ -1078,7 +1078,7 @@ fn bitxor(self, other: $t) -> $t { self ^ other }
 
 bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
-/// The `Shl` trait is used to specify the functionality of `<<`.
+/// The left shift operator `<<`.
 ///
 /// # Examples
 ///
@@ -1181,7 +1181,7 @@ macro_rules! shl_impl_all {
 
 shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 }
 
-/// The `Shr` trait is used to specify the functionality of `>>`.
+/// The right shift operator `>>`.
 ///
 /// # Examples
 ///
@@ -1284,7 +1284,7 @@ macro_rules! shr_impl_all {
 
 shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
 
-/// The `AddAssign` trait is used to specify the functionality of `+=`.
+/// The addition assignment operator `+=`.
 ///
 /// # Examples
 ///
@@ -1340,7 +1340,7 @@ fn add_assign(&mut self, other: $t) { *self += other }
 
 add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `SubAssign` trait is used to specify the functionality of `-=`.
+/// The subtraction assignment operator `-=`.
 ///
 /// # Examples
 ///
@@ -1396,7 +1396,7 @@ fn sub_assign(&mut self, other: $t) { *self -= other }
 
 sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `MulAssign` trait is used to specify the functionality of `*=`.
+/// The multiplication assignment operator `*=`.
 ///
 /// # Examples
 ///
@@ -1441,7 +1441,7 @@ fn mul_assign(&mut self, other: $t) { *self *= other }
 
 mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `DivAssign` trait is used to specify the functionality of `/=`.
+/// The division assignment operator `/=`.
 ///
 /// # Examples
 ///
@@ -1485,7 +1485,7 @@ fn div_assign(&mut self, other: $t) { *self /= other }
 
 div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `RemAssign` trait is used to specify the functionality of `%=`.
+/// The remainder assignment operator `%=`.
 ///
 /// # Examples
 ///
@@ -1529,7 +1529,7 @@ fn rem_assign(&mut self, other: $t) { *self %= other }
 
 rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `BitAndAssign` trait is used to specify the functionality of `&=`.
+/// The bitwise AND assignment operator `&=`.
 ///
 /// # Examples
 ///
@@ -1615,7 +1615,7 @@ fn bitand_assign(&mut self, other: $t) { *self &= other }
 
 bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
-/// The `BitOrAssign` trait is used to specify the functionality of `|=`.
+/// The bitwise OR assignment operator `|=`.
 ///
 /// # Examples
 ///
@@ -1659,7 +1659,7 @@ fn bitor_assign(&mut self, other: $t) { *self |= other }
 
 bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
-/// The `BitXorAssign` trait is used to specify the functionality of `^=`.
+/// The bitwise XOR assignment operator `^=`.
 ///
 /// # Examples
 ///
@@ -1703,7 +1703,7 @@ fn bitxor_assign(&mut self, other: $t) { *self ^= other }
 
 bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
-/// The `ShlAssign` trait is used to specify the functionality of `<<=`.
+/// The left shift assignment operator `<<=`.
 ///
 /// # Examples
 ///
@@ -1768,7 +1768,7 @@ macro_rules! shl_assign_impl_all {
 
 shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
 
-/// The `ShrAssign` trait is used to specify the functionality of `>>=`.
+/// The right shift assignment operator `>>=`.
 ///
 /// # Examples
 ///
index 6ec8a37dfa4330042e62996c4b956f1a3b75a770..c46b0c1324de6e1987df9afd69382ec53275ebda 100644 (file)
@@ -838,10 +838,10 @@ impl<T: Default, E> Result<T, E> {
     ///
     /// assert_eq!(1909, good_year);
     /// assert_eq!(0, bad_year);
+    /// ```
     ///
     /// [`parse`]: ../../std/primitive.str.html#method.parse
     /// [`FromStr`]: ../../std/str/trait.FromStr.html
-    /// ```
     #[inline]
     #[stable(feature = "result_unwrap_or_default", since = "1.16.0")]
     pub fn unwrap_or_default(self) -> T {
index d13d537d99301781dd6aa246c4008d529354e320..3612ee65bca0dba78c5ad3fd35e51bbba3b3340e 100644 (file)
@@ -152,8 +152,8 @@ fn partial_insertion_sort<T, F>(v: &mut [T], is_less: &mut F) -> bool
 fn insertion_sort<T, F>(v: &mut [T], is_less: &mut F)
     where F: FnMut(&T, &T) -> bool
 {
-    for i in 2..v.len()+1 {
-        shift_tail(&mut v[..i], is_less);
+    for i in 1..v.len() {
+        shift_tail(&mut v[..i+1], is_less);
     }
 }
 
@@ -498,32 +498,40 @@ fn partition_equal<T, F>(v: &mut [T], pivot: usize, is_less: &mut F) -> usize
 #[cold]
 fn break_patterns<T>(v: &mut [T]) {
     let len = v.len();
-
     if len >= 8 {
-        // A random number will be taken modulo this one. The modulus is a power of two so that we
-        // can simply take bitwise "and", thus avoiding costly CPU operations.
-        let modulus = (len / 4).next_power_of_two();
-        debug_assert!(modulus >= 1 && modulus <= len / 2);
-
-        // Pseudorandom number generation from the "Xorshift RNGs" paper by George Marsaglia.
-        let mut random = len;
-        random ^= random << 13;
-        random ^= random >> 17;
-        random ^= random << 5;
-        random &= modulus - 1;
-        debug_assert!(random < len / 2);
-
-        // The first index.
-        let a = len / 4 * 2;
-        debug_assert!(a >= 1 && a < len - 2);
-
-        // The second index.
-        let b = len / 4 + random;
-        debug_assert!(b >= 1 && b < len - 2);
-
-        // Swap neighbourhoods of `a` and `b`.
+        // Pseudorandom number generator from the "Xorshift RNGs" paper by George Marsaglia.
+        let mut random = len as u32;
+        let mut gen_u32 = || {
+            random ^= random << 13;
+            random ^= random >> 17;
+            random ^= random << 5;
+            random
+        };
+        let mut gen_usize = || {
+            if mem::size_of::<usize>() <= 4 {
+                gen_u32() as usize
+            } else {
+                (((gen_u32() as u64) << 32) | (gen_u32() as u64)) as usize
+            }
+        };
+
+        // Take random numbers modulo this number.
+        // The number fits into `usize` because `len` is not greater than `isize::MAX`.
+        let modulus = len.next_power_of_two();
+
+        // Some pivot candidates will be in the nearby of this index. Let's randomize them.
+        let pos = len / 4 * 2;
+
         for i in 0..3 {
-            v.swap(a - 1 + i, b - 1 + i);
+            // Generate a random number modulo `len`. However, in order to avoid costly operations
+            // we first take it modulo a power of two, and then decrease by `len` until it fits
+            // into the range `[0, len - 1]`.
+            let mut other = gen_usize() & (modulus - 1);
+            while other >= len {
+                other -= len;
+            }
+
+            v.swap(pos - 1 + i, other);
         }
     }
 }
index dfb6936da6bda4d1f381aa9ef28dc208a3940850..0d66d0e93aa85a5344706486479c1658d07fec3c 100644 (file)
 /// [`from_str`]: #tymethod.from_str
 /// [`str`]: ../../std/primitive.str.html
 /// [`parse`]: ../../std/primitive.str.html#method.parse
+///
+/// # Examples
+///
+/// Basic implementation of `FromStr` on an example `Point` type:
+///
+/// ```
+/// use std::str::FromStr;
+/// use std::num::ParseIntError;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct Point {
+///     x: i32,
+///     y: i32
+/// }
+///
+/// impl FromStr for Point {
+///     type Err = ParseIntError;
+///
+///     fn from_str(s: &str) -> Result<Self, Self::Err> {
+///         let coords: Vec<&str> = s.trim_matches(|p| p == '(' || p == ')' )
+///                                  .split(",")
+///                                  .collect();
+///
+///         let x_fromstr = coords[0].parse::<i32>()?;
+///         let y_fromstr = coords[1].parse::<i32>()?;
+///
+///         Ok(Point { x: x_fromstr, y: y_fromstr })
+///     }
+/// }
+///
+/// let p = Point::from_str("(1,2)");
+/// assert_eq!(p.unwrap(), Point{ x: 1, y: 2} )
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait FromStr: Sized {
     /// The associated error which can be returned from parsing.
@@ -101,7 +134,9 @@ fn from_str(s: &str) -> Result<bool, ParseBoolError> {
     }
 }
 
-/// An error returned when parsing a `bool` from a string fails.
+/// An error returned when parsing a `bool` using [`from_str`] fails
+///
+/// [`from_str`]: ../../std/primitive.bool.html#method.from_str
 #[derive(Debug, Clone, PartialEq, Eq)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct ParseBoolError { _priv: () }
index 8e587ad211de80c3c2e50b5d9672a1e527690794..1b2c7775185f78d9dbf9e318236f8d3e4e5c0426 100644 (file)
@@ -554,7 +554,7 @@ fn escape_str(s: &str) -> String {
     pub fn to_dot_string(&self) -> String {
         match self {
             &LabelStr(ref s) => format!("\"{}\"", s.escape_default()),
-            &EscStr(ref s) => format!("\"{}\"", LabelText::escape_str(&s[..])),
+            &EscStr(ref s) => format!("\"{}\"", LabelText::escape_str(&s)),
             &HtmlStr(ref s) => format!("<{}>", s),
         }
     }
@@ -587,7 +587,7 @@ pub fn suffix_line(self, suffix: LabelText) -> LabelText<'static> {
         let mut prefix = self.pre_escaped_content().into_owned();
         let suffix = suffix.pre_escaped_content();
         prefix.push_str(r"\n\n");
-        prefix.push_str(&suffix[..]);
+        prefix.push_str(&suffix);
         EscStr(prefix.into_cow())
     }
 }
@@ -878,7 +878,7 @@ impl<'a> Labeller<'a> for LabelledGraph {
         type Node = Node;
         type Edge = &'a Edge;
         fn graph_id(&'a self) -> Id<'a> {
-            Id::new(&self.name[..]).unwrap()
+            Id::new(self.name).unwrap()
         }
         fn node_id(&'a self, n: &Node) -> Id<'a> {
             id_name(n)
index 64d954c6a76e896fbf7ed5c17e77c40e388abe84..05a2d197356ef253dfd985166576619ac9b6947f 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 64d954c6a76e896fbf7ed5c17e77c40e388abe84
+Subproject commit 05a2d197356ef253dfd985166576619ac9b6947f
diff --git a/src/liblog/Cargo.toml b/src/liblog/Cargo.toml
deleted file mode 100644 (file)
index 31a8624..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "log"
-version = "0.0.0"
-
-[lib]
-name = "log"
-path = "lib.rs"
-crate-type = ["dylib", "rlib"]
diff --git a/src/liblog/directive.rs b/src/liblog/directive.rs
deleted file mode 100644 (file)
index eb50d6e..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::ascii::AsciiExt;
-use std::cmp;
-
-#[derive(Debug, Clone)]
-pub struct LogDirective {
-    pub name: Option<String>,
-    pub level: u32,
-}
-
-pub const LOG_LEVEL_NAMES: [&'static str; 5] = ["ERROR", "WARN", "INFO", "DEBUG", "TRACE"];
-
-/// Parse an individual log level that is either a number or a symbolic log level
-fn parse_log_level(level: &str) -> Option<u32> {
-    level.parse::<u32>()
-        .ok()
-        .or_else(|| {
-            let pos = LOG_LEVEL_NAMES.iter().position(|&name| name.eq_ignore_ascii_case(level));
-            pos.map(|p| p as u32 + 1)
-        })
-        .map(|p| cmp::min(p, ::MAX_LOG_LEVEL))
-}
-
-/// Parse a logging specification string (e.g: "crate1,crate2::mod3,crate3::x=1/foo")
-/// and return a vector with log directives.
-///
-/// Valid log levels are 0-255, with the most likely ones being 1-4 (defined in
-/// std::).  Also supports string log levels of error, warn, info, and debug
-pub fn parse_logging_spec(spec: &str) -> (Vec<LogDirective>, Option<String>) {
-    let mut dirs = Vec::new();
-
-    let mut parts = spec.split('/');
-    let mods = parts.next();
-    let filter = parts.next();
-    if parts.next().is_some() {
-        println!("warning: invalid logging spec '{}', ignoring it (too many '/'s)",
-                 spec);
-        return (dirs, None);
-    }
-    if let Some(m) = mods {
-        for s in m.split(',') {
-            if s.is_empty() {
-                continue;
-            }
-            let mut parts = s.split('=');
-            let (log_level, name) =
-                match (parts.next(), parts.next().map(|s| s.trim()), parts.next()) {
-                    (Some(part0), None, None) => {
-                        // if the single argument is a log-level string or number,
-                        // treat that as a global fallback
-                        match parse_log_level(part0) {
-                            Some(num) => (num, None),
-                            None => (::MAX_LOG_LEVEL, Some(part0)),
-                        }
-                    }
-                    (Some(part0), Some(""), None) => (::MAX_LOG_LEVEL, Some(part0)),
-                    (Some(part0), Some(part1), None) => {
-                        match parse_log_level(part1) {
-                            Some(num) => (num, Some(part0)),
-                            _ => {
-                                println!("warning: invalid logging spec '{}', ignoring it", part1);
-                                continue;
-                            }
-                        }
-                    }
-                    _ => {
-                        println!("warning: invalid logging spec '{}', ignoring it", s);
-                        continue;
-                    }
-                };
-            dirs.push(LogDirective {
-                name: name.map(str::to_owned),
-                level: log_level,
-            });
-        }
-    }
-
-    (dirs, filter.map(str::to_owned))
-}
-
-#[cfg(test)]
-mod tests {
-    use super::parse_logging_spec;
-
-    #[test]
-    fn parse_logging_spec_valid() {
-        let (dirs, filter) = parse_logging_spec("crate1::mod1=1,crate1::mod2,crate2=4");
-        assert_eq!(dirs.len(), 3);
-        assert_eq!(dirs[0].name, Some("crate1::mod1".to_owned()));
-        assert_eq!(dirs[0].level, 1);
-
-        assert_eq!(dirs[1].name, Some("crate1::mod2".to_owned()));
-        assert_eq!(dirs[1].level, ::MAX_LOG_LEVEL);
-
-        assert_eq!(dirs[2].name, Some("crate2".to_owned()));
-        assert_eq!(dirs[2].level, 4);
-        assert!(filter.is_none());
-    }
-
-    #[test]
-    fn parse_logging_spec_invalid_crate() {
-        // test parse_logging_spec with multiple = in specification
-        let (dirs, filter) = parse_logging_spec("crate1::mod1=1=2,crate2=4");
-        assert_eq!(dirs.len(), 1);
-        assert_eq!(dirs[0].name, Some("crate2".to_owned()));
-        assert_eq!(dirs[0].level, 4);
-        assert!(filter.is_none());
-    }
-
-    #[test]
-    fn parse_logging_spec_invalid_log_level() {
-        // test parse_logging_spec with 'noNumber' as log level
-        let (dirs, filter) = parse_logging_spec("crate1::mod1=noNumber,crate2=4");
-        assert_eq!(dirs.len(), 1);
-        assert_eq!(dirs[0].name, Some("crate2".to_owned()));
-        assert_eq!(dirs[0].level, 4);
-        assert!(filter.is_none());
-    }
-
-    #[test]
-    fn parse_logging_spec_string_log_level() {
-        // test parse_logging_spec with 'warn' as log level
-        let (dirs, filter) = parse_logging_spec("crate1::mod1=wrong,crate2=warn");
-        assert_eq!(dirs.len(), 1);
-        assert_eq!(dirs[0].name, Some("crate2".to_owned()));
-        assert_eq!(dirs[0].level, ::WARN);
-        assert!(filter.is_none());
-    }
-
-    #[test]
-    fn parse_logging_spec_empty_log_level() {
-        // test parse_logging_spec with '' as log level
-        let (dirs, filter) = parse_logging_spec("crate1::mod1=wrong,crate2=");
-        assert_eq!(dirs.len(), 1);
-        assert_eq!(dirs[0].name, Some("crate2".to_owned()));
-        assert_eq!(dirs[0].level, ::MAX_LOG_LEVEL);
-        assert!(filter.is_none());
-    }
-
-    #[test]
-    fn parse_logging_spec_global() {
-        // test parse_logging_spec with no crate
-        let (dirs, filter) = parse_logging_spec("warn,crate2=4");
-        assert_eq!(dirs.len(), 2);
-        assert_eq!(dirs[0].name, None);
-        assert_eq!(dirs[0].level, 2);
-        assert_eq!(dirs[1].name, Some("crate2".to_owned()));
-        assert_eq!(dirs[1].level, 4);
-        assert!(filter.is_none());
-    }
-
-    #[test]
-    fn parse_logging_spec_valid_filter() {
-        let (dirs, filter) = parse_logging_spec("crate1::mod1=1,crate1::mod2,crate2=4/abc");
-        assert_eq!(dirs.len(), 3);
-        assert_eq!(dirs[0].name, Some("crate1::mod1".to_owned()));
-        assert_eq!(dirs[0].level, 1);
-
-        assert_eq!(dirs[1].name, Some("crate1::mod2".to_owned()));
-        assert_eq!(dirs[1].level, ::MAX_LOG_LEVEL);
-
-        assert_eq!(dirs[2].name, Some("crate2".to_owned()));
-        assert_eq!(dirs[2].level, 4);
-        assert!(filter.is_some() && filter.unwrap().to_owned() == "abc");
-    }
-
-    #[test]
-    fn parse_logging_spec_invalid_crate_filter() {
-        let (dirs, filter) = parse_logging_spec("crate1::mod1=1=2,crate2=4/a.c");
-        assert_eq!(dirs.len(), 1);
-        assert_eq!(dirs[0].name, Some("crate2".to_owned()));
-        assert_eq!(dirs[0].level, 4);
-        assert!(filter.is_some() && filter.unwrap().to_owned() == "a.c");
-    }
-
-    #[test]
-    fn parse_logging_spec_empty_with_filter() {
-        let (dirs, filter) = parse_logging_spec("crate1/a*c");
-        assert_eq!(dirs.len(), 1);
-        assert_eq!(dirs[0].name, Some("crate1".to_owned()));
-        assert_eq!(dirs[0].level, ::MAX_LOG_LEVEL);
-        assert!(filter.is_some() && filter.unwrap().to_owned() == "a*c");
-    }
-}
diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs
deleted file mode 100644 (file)
index 057df64..0000000
+++ /dev/null
@@ -1,506 +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.
-
-//! Utilities for program-wide and customizable logging
-//!
-//! # Examples
-//!
-//! ```
-//! # #![feature(rustc_private)]
-//! #[macro_use] extern crate log;
-//!
-//! fn main() {
-//!     debug!("this is a debug {:?}", "message");
-//!     error!("this is printed by default");
-//!
-//!     if log_enabled!(log::INFO) {
-//!         let x = 3 * 4; // expensive computation
-//!         info!("the answer was: {:?}", x);
-//!     }
-//! }
-//! ```
-//!
-//! Assumes the binary is `main`:
-//!
-//! ```{.bash}
-//! $ RUST_LOG=error ./main
-//! ERROR:main: this is printed by default
-//! ```
-//!
-//! ```{.bash}
-//! $ RUST_LOG=info ./main
-//! ERROR:main: this is printed by default
-//! INFO:main: the answer was: 12
-//! ```
-//!
-//! ```{.bash}
-//! $ RUST_LOG=debug ./main
-//! DEBUG:main: this is a debug message
-//! ERROR:main: this is printed by default
-//! INFO:main: the answer was: 12
-//! ```
-//!
-//! You can also set the log level on a per module basis:
-//!
-//! ```{.bash}
-//! $ RUST_LOG=main=info ./main
-//! ERROR:main: this is printed by default
-//! INFO:main: the answer was: 12
-//! ```
-//!
-//! And enable all logging:
-//!
-//! ```{.bash}
-//! $ RUST_LOG=main ./main
-//! DEBUG:main: this is a debug message
-//! ERROR:main: this is printed by default
-//! INFO:main: the answer was: 12
-//! ```
-//!
-//! # Logging Macros
-//!
-//! There are five macros that the logging subsystem uses:
-//!
-//! * `log!(level, ...)` - the generic logging macro, takes a level as a u32 and any
-//!                        related `format!` arguments
-//! * `debug!(...)` - a macro hard-wired to the log level of `DEBUG`
-//! * `info!(...)` - a macro hard-wired to the log level of `INFO`
-//! * `warn!(...)` - a macro hard-wired to the log level of `WARN`
-//! * `error!(...)` - a macro hard-wired to the log level of `ERROR`
-//!
-//! All of these macros use the same style of syntax as the `format!` syntax
-//! extension. Details about the syntax can be found in the documentation of
-//! `std::fmt` along with the Rust tutorial/manual.
-//!
-//! If you want to check at runtime if a given logging level is enabled (e.g. if the
-//! information you would want to log is expensive to produce), you can use the
-//! following macro:
-//!
-//! * `log_enabled!(level)` - returns true if logging of the given level is enabled
-//!
-//! # Enabling logging
-//!
-//! Log levels are controlled on a per-module basis, and by default all logging is
-//! disabled except for `error!` (a log level of 1). Logging is controlled via the
-//! `RUST_LOG` environment variable. The value of this environment variable is a
-//! comma-separated list of logging directives. A logging directive is of the form:
-//!
-//! ```text
-//! path::to::module=log_level
-//! ```
-//!
-//! The path to the module is rooted in the name of the crate it was compiled for,
-//! so if your program is contained in a file `hello.rs`, for example, to turn on
-//! logging for this file you would use a value of `RUST_LOG=hello`.
-//! Furthermore, this path is a prefix-search, so all modules nested in the
-//! specified module will also have logging enabled.
-//!
-//! The actual `log_level` is optional to specify. If omitted, all logging will be
-//! enabled. If specified, the it must be either a numeric in the range of 1-255, or
-//! it must be one of the strings `debug`, `error`, `info`, or `warn`. If a numeric
-//! is specified, then all logging less than or equal to that numeral is enabled.
-//! For example, if logging level 3 is active, error, warn, and info logs will be
-//! printed, but debug will be omitted.
-//!
-//! As the log level for a module is optional, the module to enable logging for is
-//! also optional. If only a `log_level` is provided, then the global log level for
-//! all modules is set to this value.
-//!
-//! Some examples of valid values of `RUST_LOG` are:
-//!
-//! * `hello` turns on all logging for the 'hello' module
-//! * `info` turns on all info logging
-//! * `hello=debug` turns on debug logging for 'hello'
-//! * `hello=3` turns on info logging for 'hello'
-//! * `hello,std::option` turns on hello, and std's option logging
-//! * `error,hello=warn` turn on global error logging and also warn for hello
-//!
-//! # Filtering results
-//!
-//! A RUST_LOG directive may include a string filter. The syntax is to append
-//! `/` followed by a string. Each message is checked against the string and is
-//! only logged if it contains the string. Note that the matching is done after
-//! formatting the log string but before adding any logging meta-data. There is
-//! a single filter for all modules.
-//!
-//! Some examples:
-//!
-//! * `hello/foo` turns on all logging for the 'hello' module where the log message
-//! includes 'foo'.
-//! * `info/f.o` turns on all info logging where the log message includes 'foo',
-//! 'f1o', 'fao', etc.
-//! * `hello=debug/foo*foo` turns on debug logging for 'hello' where the log
-//! message includes 'foofoo' or 'fofoo' or 'fooooooofoo', etc.
-//! * `error,hello=warn/[0-9] scopes` turn on global error logging and also warn for
-//!  hello. In both cases the log message must include a single digit number
-//!  followed by 'scopes'
-//!
-//! # Performance and Side Effects
-//!
-//! Each of these macros will expand to code similar to:
-//!
-//! ```rust,ignore
-//! if log_level <= my_module_log_level() {
-//!     ::log::log(log_level, format!(...));
-//! }
-//! ```
-//!
-//! What this means is that each of these macros are very cheap at runtime if
-//! they're turned off (just a load and an integer comparison). This also means that
-//! if logging is disabled, none of the components of the log will be executed.
-
-#![crate_name = "log"]
-#![unstable(feature = "rustc_private",
-            reason = "use the crates.io `log` library instead",
-            issue = "27812")]
-#![crate_type = "rlib"]
-#![crate_type = "dylib"]
-#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
-       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
-       html_root_url = "https://doc.rust-lang.org/nightly/",
-       html_playground_url = "https://play.rust-lang.org/",
-       test(attr(deny(warnings))))]
-#![deny(missing_docs)]
-#![deny(warnings)]
-
-#![feature(staged_api)]
-
-use std::cell::RefCell;
-use std::fmt;
-use std::io::{self, Stderr};
-use std::io::prelude::*;
-use std::mem;
-use std::env;
-use std::slice;
-use std::sync::{Mutex, ONCE_INIT, Once};
-
-use directive::LOG_LEVEL_NAMES;
-
-#[macro_use]
-pub mod macros;
-
-mod directive;
-
-/// Maximum logging level of a module that can be specified. Common logging
-/// levels are found in the DEBUG/INFO/WARN/ERROR constants.
-pub const MAX_LOG_LEVEL: u32 = 255;
-
-/// The default logging level of a crate if no other is specified.
-const DEFAULT_LOG_LEVEL: u32 = 1;
-
-static mut LOCK: *mut Mutex<(Vec<directive::LogDirective>, Option<String>)> = 0 as *mut _;
-
-/// An unsafe constant that is the maximum logging level of any module
-/// specified. This is the first line of defense to determining whether a
-/// logging statement should be run.
-static mut LOG_LEVEL: u32 = MAX_LOG_LEVEL;
-
-/// Debug log level
-pub const DEBUG: u32 = 4;
-/// Info log level
-pub const INFO: u32 = 3;
-/// Warn log level
-pub const WARN: u32 = 2;
-/// Error log level
-pub const ERROR: u32 = 1;
-
-thread_local! {
-    static LOCAL_LOGGER: RefCell<Option<Box<Logger + Send>>> = {
-        RefCell::new(None)
-    }
-}
-
-/// A trait used to represent an interface to a thread-local logger. Each thread
-/// can have its own custom logger which can respond to logging messages
-/// however it likes.
-pub trait Logger {
-    /// Logs a single message described by the `record`.
-    fn log(&mut self, record: &LogRecord);
-}
-
-struct DefaultLogger {
-    handle: Stderr,
-}
-
-/// Wraps the log level with fmt implementations.
-#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
-pub struct LogLevel(pub u32);
-
-impl fmt::Display for LogLevel {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        let LogLevel(level) = *self;
-        match LOG_LEVEL_NAMES.get(level as usize - 1) {
-            Some(ref name) => fmt::Display::fmt(name, fmt),
-            None => fmt::Display::fmt(&level, fmt),
-        }
-    }
-}
-
-impl Logger for DefaultLogger {
-    fn log(&mut self, record: &LogRecord) {
-        match writeln!(&mut self.handle,
-                       "{}:{}: {}",
-                       record.level,
-                       record.module_path,
-                       record.args) {
-            Err(e) => panic!("failed to log: {:?}", e),
-            Ok(()) => {}
-        }
-    }
-}
-
-impl Drop for DefaultLogger {
-    fn drop(&mut self) {
-        // FIXME(#12628): is panicking the right thing to do?
-        match self.handle.flush() {
-            Err(e) => panic!("failed to flush a logger: {:?}", e),
-            Ok(()) => {}
-        }
-    }
-}
-
-/// This function is called directly by the compiler when using the logging
-/// macros. This function does not take into account whether the log level
-/// specified is active or not, it will always log something if this method is
-/// called.
-///
-/// It is not recommended to call this function directly, rather it should be
-/// invoked through the logging family of macros.
-#[doc(hidden)]
-pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) {
-    // Test the literal string from args against the current filter, if there
-    // is one.
-    unsafe {
-        let filter = (*LOCK).lock().unwrap();
-        if let Some(ref filter) = filter.1 {
-            if !args.to_string().contains(filter) {
-                return;
-            }
-        }
-    }
-
-    // Completely remove the local logger from TLS in case anyone attempts to
-    // frob the slot while we're doing the logging. This will destroy any logger
-    // set during logging.
-    let logger = LOCAL_LOGGER.with(|s| s.borrow_mut().take());
-    let mut logger = logger.unwrap_or_else(|| Box::new(DefaultLogger { handle: io::stderr() }));
-    logger.log(&LogRecord {
-        level: LogLevel(level),
-        args: args,
-        file: loc.file,
-        module_path: loc.module_path,
-        line: loc.line,
-    });
-    set_logger(logger);
-}
-
-/// Getter for the global log level. This is a function so that it can be called
-/// safely
-#[doc(hidden)]
-#[inline(always)]
-pub fn log_level() -> u32 {
-    unsafe { LOG_LEVEL }
-}
-
-/// Replaces the thread-local logger with the specified logger, returning the old
-/// logger.
-pub fn set_logger(logger: Box<Logger + Send>) -> Option<Box<Logger + Send>> {
-    LOCAL_LOGGER.with(|slot| mem::replace(&mut *slot.borrow_mut(), Some(logger)))
-}
-
-/// A LogRecord is created by the logging macros, and passed as the only
-/// argument to Loggers.
-#[derive(Debug)]
-pub struct LogRecord<'a> {
-    /// The module path of where the LogRecord originated.
-    pub module_path: &'a str,
-
-    /// The LogLevel of this record.
-    pub level: LogLevel,
-
-    /// The arguments from the log line.
-    pub args: fmt::Arguments<'a>,
-
-    /// The file of where the LogRecord originated.
-    pub file: &'a str,
-
-    /// The line number of where the LogRecord originated.
-    pub line: u32,
-}
-
-#[doc(hidden)]
-#[derive(Copy, Clone)]
-pub struct LogLocation {
-    pub module_path: &'static str,
-    pub file: &'static str,
-    pub line: u32,
-}
-
-/// Tests whether a given module's name is enabled for a particular level of
-/// logging. This is the second layer of defense about determining whether a
-/// module's log statement should be emitted or not.
-#[doc(hidden)]
-pub fn mod_enabled(level: u32, module: &str) -> bool {
-    static INIT: Once = ONCE_INIT;
-    INIT.call_once(init);
-
-    // It's possible for many threads are in this function, only one of them
-    // will perform the global initialization, but all of them will need to check
-    // again to whether they should really be here or not. Hence, despite this
-    // check being expanded manually in the logging macro, this function checks
-    // the log level again.
-    if level > unsafe { LOG_LEVEL } {
-        return false;
-    }
-
-    // This assertion should never get tripped unless we're in an at_exit
-    // handler after logging has been torn down and a logging attempt was made.
-
-    unsafe {
-        let directives = (*LOCK).lock().unwrap();
-        enabled(level, module, directives.0.iter())
-    }
-}
-
-fn enabled(level: u32, module: &str, iter: slice::Iter<directive::LogDirective>) -> bool {
-    // Search for the longest match, the vector is assumed to be pre-sorted.
-    for directive in iter.rev() {
-        match directive.name {
-            Some(ref name) if !module.starts_with(&name[..]) => {}
-            Some(..) | None => return level <= directive.level,
-        }
-    }
-    level <= DEFAULT_LOG_LEVEL
-}
-
-/// Initialize logging for the current process.
-///
-/// This is not threadsafe at all, so initialization is performed through a
-/// `Once` primitive (and this function is called from that primitive).
-fn init() {
-    let (mut directives, filter) = match env::var("RUST_LOG") {
-        Ok(spec) => directive::parse_logging_spec(&spec[..]),
-        Err(..) => (Vec::new(), None),
-    };
-
-    // Sort the provided directives by length of their name, this allows a
-    // little more efficient lookup at runtime.
-    directives.sort_by(|a, b| {
-        let alen = a.name.as_ref().map(|a| a.len()).unwrap_or(0);
-        let blen = b.name.as_ref().map(|b| b.len()).unwrap_or(0);
-        alen.cmp(&blen)
-    });
-
-    let max_level = {
-        let max = directives.iter().max_by_key(|d| d.level);
-        max.map(|d| d.level).unwrap_or(DEFAULT_LOG_LEVEL)
-    };
-
-    unsafe {
-        LOG_LEVEL = max_level;
-
-        assert!(LOCK.is_null());
-        LOCK = Box::into_raw(Box::new(Mutex::new((directives, filter))));
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::enabled;
-    use directive::LogDirective;
-
-    #[test]
-    fn match_full_path() {
-        let dirs = [LogDirective {
-                        name: Some("crate2".to_string()),
-                        level: 3,
-                    },
-                    LogDirective {
-                        name: Some("crate1::mod1".to_string()),
-                        level: 2,
-                    }];
-        assert!(enabled(2, "crate1::mod1", dirs.iter()));
-        assert!(!enabled(3, "crate1::mod1", dirs.iter()));
-        assert!(enabled(3, "crate2", dirs.iter()));
-        assert!(!enabled(4, "crate2", dirs.iter()));
-    }
-
-    #[test]
-    fn no_match() {
-        let dirs = [LogDirective {
-                        name: Some("crate2".to_string()),
-                        level: 3,
-                    },
-                    LogDirective {
-                        name: Some("crate1::mod1".to_string()),
-                        level: 2,
-                    }];
-        assert!(!enabled(2, "crate3", dirs.iter()));
-    }
-
-    #[test]
-    fn match_beginning() {
-        let dirs = [LogDirective {
-                        name: Some("crate2".to_string()),
-                        level: 3,
-                    },
-                    LogDirective {
-                        name: Some("crate1::mod1".to_string()),
-                        level: 2,
-                    }];
-        assert!(enabled(3, "crate2::mod1", dirs.iter()));
-    }
-
-    #[test]
-    fn match_beginning_longest_match() {
-        let dirs = [LogDirective {
-                        name: Some("crate2".to_string()),
-                        level: 3,
-                    },
-                    LogDirective {
-                        name: Some("crate2::mod".to_string()),
-                        level: 4,
-                    },
-                    LogDirective {
-                        name: Some("crate1::mod1".to_string()),
-                        level: 2,
-                    }];
-        assert!(enabled(4, "crate2::mod1", dirs.iter()));
-        assert!(!enabled(4, "crate2", dirs.iter()));
-    }
-
-    #[test]
-    fn match_default() {
-        let dirs = [LogDirective {
-                        name: None,
-                        level: 3,
-                    },
-                    LogDirective {
-                        name: Some("crate1::mod1".to_string()),
-                        level: 2,
-                    }];
-        assert!(enabled(2, "crate1::mod1", dirs.iter()));
-        assert!(enabled(3, "crate2::mod2", dirs.iter()));
-    }
-
-    #[test]
-    fn zero_level() {
-        let dirs = [LogDirective {
-                        name: None,
-                        level: 3,
-                    },
-                    LogDirective {
-                        name: Some("crate1::mod1".to_string()),
-                        level: 0,
-                    }];
-        assert!(!enabled(1, "crate1::mod1", dirs.iter()));
-        assert!(enabled(3, "crate2::mod2", dirs.iter()));
-    }
-}
diff --git a/src/liblog/macros.rs b/src/liblog/macros.rs
deleted file mode 100644 (file)
index 803a2df..0000000
+++ /dev/null
@@ -1,205 +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.
-
-//! Logging macros
-
-/// The standard logging macro
-///
-/// This macro will generically log over a provided level (of type u32) with a
-/// format!-based argument list. See documentation in `std::fmt` for details on
-/// how to use the syntax.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(rustc_private)]
-/// #[macro_use] extern crate log;
-///
-/// fn main() {
-///     log!(log::WARN, "this is a warning {}", "message");
-///     log!(log::DEBUG, "this is a debug message");
-///     log!(6, "this is a custom logging level: {level}", level=6);
-/// }
-/// ```
-///
-/// Assumes the binary is `main`:
-///
-/// ```{.bash}
-/// $ RUST_LOG=warn ./main
-/// WARN:main: this is a warning message
-/// ```
-///
-/// ```{.bash}
-/// $ RUST_LOG=debug ./main
-/// DEBUG:main: this is a debug message
-/// WARN:main: this is a warning message
-/// ```
-///
-/// ```{.bash}
-/// $ RUST_LOG=6 ./main
-/// DEBUG:main: this is a debug message
-/// WARN:main: this is a warning message
-/// 6:main: this is a custom logging level: 6
-/// ```
-#[macro_export]
-macro_rules! log {
-    ($lvl:expr, $($arg:tt)+) => ({
-        static LOC: ::log::LogLocation = ::log::LogLocation {
-            line: line!(),
-            file: file!(),
-            module_path: module_path!(),
-        };
-        let lvl = $lvl;
-        if log_enabled!(lvl) {
-            ::log::log(lvl, &LOC, format_args!($($arg)+))
-        }
-    })
-}
-
-/// A convenience macro for logging at the error log level.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(rustc_private)]
-/// #[macro_use] extern crate log;
-///
-/// fn main() {
-///     let error = 3;
-///     error!("the build has failed with error code: {}", error);
-/// }
-/// ```
-///
-/// Assumes the binary is `main`:
-///
-/// ```{.bash}
-/// $ RUST_LOG=error ./main
-/// ERROR:main: the build has failed with error code: 3
-/// ```
-///
-#[macro_export]
-macro_rules! error {
-    ($($arg:tt)*) => (log!(::log::ERROR, $($arg)*))
-}
-
-/// A convenience macro for logging at the warning log level.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(rustc_private)]
-/// #[macro_use] extern crate log;
-///
-/// fn main() {
-///     let code = 3;
-///     warn!("you may like to know that a process exited with: {}", code);
-/// }
-/// ```
-///
-/// Assumes the binary is `main`:
-///
-/// ```{.bash}
-/// $ RUST_LOG=warn ./main
-/// WARN:main: you may like to know that a process exited with: 3
-/// ```
-#[macro_export]
-macro_rules! warn {
-    ($($arg:tt)*) => (log!(::log::WARN, $($arg)*))
-}
-
-/// A convenience macro for logging at the info log level.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(rustc_private)]
-/// #[macro_use] extern crate log;
-///
-/// fn main() {
-///     let ret = 3;
-///     info!("this function is about to return: {}", ret);
-/// }
-/// ```
-///
-/// Assumes the binary is `main`:
-///
-/// ```{.bash}
-/// $ RUST_LOG=info ./main
-/// INFO:main: this function is about to return: 3
-/// ```
-#[macro_export]
-macro_rules! info {
-    ($($arg:tt)*) => (log!(::log::INFO, $($arg)*))
-}
-
-/// A convenience macro for logging at the debug log level. This macro will
-/// be omitted at compile time in an optimized build unless `-C debug-assertions`
-/// is passed to the compiler.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(rustc_private)]
-/// #[macro_use] extern crate log;
-///
-/// fn main() {
-///     debug!("x = {x}, y = {y}", x=10, y=20);
-/// }
-/// ```
-///
-/// Assumes the binary is `main`:
-///
-/// ```{.bash}
-/// $ RUST_LOG=debug ./main
-/// DEBUG:main: x = 10, y = 20
-/// ```
-#[macro_export]
-macro_rules! debug {
-    ($($arg:tt)*) => (if cfg!(debug_assertions) { log!(::log::DEBUG, $($arg)*) })
-}
-
-/// A macro to test whether a log level is enabled for the current module.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(rustc_private)]
-/// #[macro_use] extern crate log;
-///
-/// struct Point { x: i32, y: i32 }
-/// fn some_expensive_computation() -> Point { Point { x: 1, y: 2 } }
-///
-/// fn main() {
-///     if log_enabled!(log::DEBUG) {
-///         let x = some_expensive_computation();
-///         debug!("x.x = {}, x.y = {}", x.x, x.y);
-///     }
-/// }
-/// ```
-///
-/// Assumes the binary is `main`:
-///
-/// ```{.bash}
-/// $ RUST_LOG=error ./main
-/// ```
-///
-/// ```{.bash}
-/// $ RUST_LOG=debug ./main
-/// DEBUG:main: x.x = 1, x.y = 2
-/// ```
-#[macro_export]
-macro_rules! log_enabled {
-    ($lvl:expr) => ({
-        let lvl = $lvl;
-        (lvl != ::log::DEBUG || cfg!(debug_assertions)) &&
-        lvl <= ::log::log_level() &&
-        ::log::mod_enabled(lvl, module_path!())
-    })
-}
index 5d53c60ad7fdc1072620abf156c939ae5dce7619..fa217acd9f9bf5e4eed1ea2feaede465f4450cbd 100644 (file)
@@ -12,7 +12,7 @@ crate-type = ["dylib"]
 arena = { path = "../libarena" }
 fmt_macros = { path = "../libfmt_macros" }
 graphviz = { path = "../libgraphviz" }
-log = { path = "../liblog" }
+log = "0.3"
 rustc_back = { path = "../librustc_back" }
 rustc_bitflags = { path = "../librustc_bitflags" }
 rustc_const_math = { path = "../librustc_const_math" }
index 399af258e925167767be1ea6f3417141bfee6ae4..5aea2bcaa4f5c5fd5f4979df6ddb5183f4a9dcc5 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use hir::def_id::CrateNum;
 use std::fmt::Debug;
 use std::sync::Arc;
 
@@ -74,14 +75,13 @@ pub enum DepNode<D: Clone + Debug> {
     CoherenceCheckImpl(D),
     CoherenceOverlapCheck(D),
     CoherenceOverlapCheckSpecial(D),
-    CoherenceOverlapInherentCheck(D),
     CoherenceOrphanCheck(D),
     Variance,
     WfCheck(D),
     TypeckItemType(D),
     UnusedTraitCheck,
     CheckConst(D),
-    Privacy,
+    PrivacyAccessLevels(CrateNum),
     IntrinsicCheck(D),
     MatchCheck(D),
 
@@ -230,7 +230,7 @@ pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
             CheckEntryFn => Some(CheckEntryFn),
             Variance => Some(Variance),
             UnusedTraitCheck => Some(UnusedTraitCheck),
-            Privacy => Some(Privacy),
+            PrivacyAccessLevels(k) => Some(PrivacyAccessLevels(k)),
             Reachability => Some(Reachability),
             DeadCheck => Some(DeadCheck),
             LateLintCheck => Some(LateLintCheck),
@@ -251,7 +251,6 @@ pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
             CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl),
             CoherenceOverlapCheck(ref d) => op(d).map(CoherenceOverlapCheck),
             CoherenceOverlapCheckSpecial(ref d) => op(d).map(CoherenceOverlapCheckSpecial),
-            CoherenceOverlapInherentCheck(ref d) => op(d).map(CoherenceOverlapInherentCheck),
             CoherenceOrphanCheck(ref d) => op(d).map(CoherenceOrphanCheck),
             WfCheck(ref d) => op(d).map(WfCheck),
             TypeckItemType(ref d) => op(d).map(TypeckItemType),
index 0f3108df9a822589aa4bba9743d8eaf77309a8c8..b6a2360211cac92610410d081de314d4c45a2148 100644 (file)
@@ -81,21 +81,6 @@ pub fn contains_key(&self, k: &M::Key) -> bool {
     pub fn keys(&self) -> Vec<M::Key> {
         self.map.keys().cloned().collect()
     }
-
-    /// Append `elem` to the vector stored for `k`, creating a new vector if needed.
-    /// This is considered a write to `k`.
-    ///
-    /// NOTE: Caution is required when using this method. You should
-    /// be sure that nobody is **reading from the vector** while you
-    /// are writing to it. Eventually, it'd be nice to remove this.
-    pub fn push<E: Clone>(&mut self, k: M::Key, elem: E)
-        where M: DepTrackingMapConfig<Value=Vec<E>>
-    {
-        self.write(&k);
-        self.map.entry(k)
-                .or_insert(Vec::new())
-                .push(elem);
-    }
 }
 
 impl<M: DepTrackingMapConfig> MemoizationMap for RefCell<DepTrackingMap<M>> {
index 8657a3e5a587899f80ebb536847bcb8f8a9a9f0c..5dbabcc923048482f8f06884ac3ec25c1ae7e82c 100644 (file)
@@ -101,11 +101,15 @@ pub fn pop_task(&mut self, key: DepNode<D>) {
     }
 
     /// Indicates that the current task `C` reads `v` by adding an
-    /// edge from `v` to `C`. If there is no current task, panics. If
-    /// you want to suppress this edge, use `ignore`.
+    /// edge from `v` to `C`. If there is no current task, has no
+    /// effect. Note that *reading* from tracked state is harmless if
+    /// you are not in a task; what is bad is *writing* to tracked
+    /// state (and leaking data that you read into a tracked task).
     pub fn read(&mut self, v: DepNode<D>) {
-        let source = self.make_node(v);
-        self.add_edge_from_current_node(|current| (source, current))
+        if self.current_node().is_some() {
+            let source = self.make_node(v);
+            self.add_edge_from_current_node(|current| (source, current))
+        }
     }
 
     /// Indicates that the current task `C` writes `v` by adding an
index 5d4190a8ae1a35bd76d35bab0e7641897ba25e5b..bedb6ff2771f064e468b5789a0ffb0a04b33fc85 100644 (file)
@@ -80,7 +80,13 @@ pub fn enqueue(&self, message: &DepMessage) {
 
             let mut stack = self.stack.borrow_mut();
             match *message {
-                DepMessage::Read(ref n) => self.check_edge(Some(Some(n)), top(&stack)),
+                // It is ok to READ shared state outside of a
+                // task. That can't do any harm (at least, the only
+                // way it can do harm is by leaking that data into a
+                // query or task, which would be a problem
+                // anyway). What would be bad is WRITING to that
+                // state.
+                DepMessage::Read(_) => { }
                 DepMessage::Write(ref n) => self.check_edge(top(&stack), Some(Some(n))),
                 DepMessage::PushTask(ref n) => stack.push(Some(n.clone())),
                 DepMessage::PushIgnore => stack.push(None),
@@ -116,7 +122,7 @@ fn check_edge(&self,
             (None, None) => unreachable!(),
 
             // nothing on top of the stack
-            (None, Some(n)) | (Some(n), None) => bug!("read/write of {:?} but no current task", n),
+            (None, Some(n)) | (Some(n), None) => bug!("write of {:?} but no current task", n),
 
             // this corresponds to an Ignore being top of the stack
             (Some(None), _) | (_, Some(None)) => (),
index 85b4ddcdd719099a90bd1cd25abc93827b32b7a2..5a0fbf8efb70778cc07954fe2c60d8436b1d7e0b 100644 (file)
@@ -1336,7 +1336,7 @@ trait SecondTrait : FirstTrait {
 
 E0398: r##"
 In Rust 1.3, the default object lifetime bounds are expected to change, as
-described in RFC #1156 [1]. You are getting a warning because the compiler
+described in [RFC 1156]. You are getting a warning because the compiler
 thinks it is possible that this change will cause a compilation error in your
 code. It is possible, though unlikely, that this is a false alarm.
 
@@ -1365,7 +1365,7 @@ fn foo<'a>(arg: &Box<SomeTrait+'a>) { ... }
 This explicitly states that you expect the trait object `SomeTrait` to contain
 references (with a maximum lifetime of `'a`).
 
-[1]: https://github.com/rust-lang/rfcs/pull/1156
+[RFC 1156]: https://github.com/rust-lang/rfcs/blob/master/text/1156-adjust-default-object-bounds.md
 "##,
 
 E0452: r##"
@@ -1771,6 +1771,7 @@ extern "C" fn foo(userdata: Box<i32>) {
 **item** (`typeof(foo)`), which is zero-sized, and the target type (`fn()`)
 is a function pointer, which is not zero-sized.
 This pattern should be rewritten. There are a few possible ways to do this:
+
 - change the original fn declaration to match the expected signature,
   and do the cast in the fn body (the prefered option)
 - cast the fn item fo a fn pointer before calling transmute, as shown here:
index 726c305e903044442f583205ed80bde372d60507..f9b740235f49e46534af00fd689dfbf1299af9a3 100644 (file)
@@ -1907,57 +1907,45 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 hir::ExprIndex(P(self.lower_expr(el)), P(self.lower_expr(er)))
             }
             ExprKind::Range(ref e1, ref e2, lims) => {
-                fn make_struct(this: &mut LoweringContext,
-                               ast_expr: &Expr,
-                               path: &[&str],
-                               fields: &[(&str, &P<Expr>)]) -> hir::Expr {
-                    let struct_path = &iter::once(&"ops").chain(path).map(|s| *s)
-                                                         .collect::<Vec<_>>();
-                    let unstable_span = this.allow_internal_unstable("...", ast_expr.span);
-
-                    if fields.len() == 0 {
-                        this.expr_std_path(unstable_span, struct_path,
-                                           ast_expr.attrs.clone())
-                    } else {
-                        let fields = fields.into_iter().map(|&(s, e)| {
-                            let expr = P(this.lower_expr(&e));
-                            let unstable_span = this.allow_internal_unstable("...", e.span);
-                            this.field(Symbol::intern(s), expr, unstable_span)
-                        }).collect();
-                        let attrs = ast_expr.attrs.clone();
-
-                        this.expr_std_struct(unstable_span, struct_path, fields, None, attrs)
-                    }
-                }
-
                 use syntax::ast::RangeLimits::*;
 
-                return match (e1, e2, lims) {
-                    (&None,         &None,         HalfOpen) =>
-                        make_struct(self, e, &["RangeFull"], &[]),
-
-                    (&Some(ref e1), &None,         HalfOpen) =>
-                        make_struct(self, e, &["RangeFrom"],
-                                             &[("start", e1)]),
-
-                    (&None,         &Some(ref e2), HalfOpen) =>
-                        make_struct(self, e, &["RangeTo"],
-                                             &[("end", e2)]),
-
-                    (&Some(ref e1), &Some(ref e2), HalfOpen) =>
-                        make_struct(self, e, &["Range"],
-                                             &[("start", e1), ("end", e2)]),
-
-                    (&None,         &Some(ref e2), Closed)   =>
-                        make_struct(self, e, &["RangeToInclusive"],
-                                             &[("end", e2)]),
-
-                    (&Some(ref e1), &Some(ref e2), Closed)   =>
-                        make_struct(self, e, &["RangeInclusive", "NonEmpty"],
-                                             &[("start", e1), ("end", e2)]),
+                let (path, variant) = match (e1, e2, lims) {
+                    (&None, &None, HalfOpen) => ("RangeFull", None),
+                    (&Some(..), &None, HalfOpen) => ("RangeFrom", None),
+                    (&None, &Some(..), HalfOpen) => ("RangeTo", None),
+                    (&Some(..), &Some(..), HalfOpen) => ("Range", None),
+                    (&None, &Some(..), Closed) => ("RangeToInclusive", None),
+                    (&Some(..), &Some(..), Closed) => ("RangeInclusive", Some("NonEmpty")),
+                    (_, &None, Closed) =>
+                        panic!(self.diagnostic().span_fatal(
+                            e.span, "inclusive range with no end")),
+                };
 
-                    _ => panic!(self.diagnostic()
-                                    .span_fatal(e.span, "inclusive range with no end")),
+                let fields =
+                    e1.iter().map(|e| ("start", e)).chain(e2.iter().map(|e| ("end", e)))
+                    .map(|(s, e)| {
+                        let expr = P(self.lower_expr(&e));
+                        let unstable_span = self.allow_internal_unstable("...", e.span);
+                        self.field(Symbol::intern(s), expr, unstable_span)
+                    }).collect::<P<[hir::Field]>>();
+
+                let is_unit = fields.is_empty();
+                let unstable_span = self.allow_internal_unstable("...", e.span);
+                let struct_path =
+                    iter::once("ops").chain(iter::once(path)).chain(variant)
+                    .collect::<Vec<_>>();
+                let struct_path = self.std_path(unstable_span, &struct_path, is_unit);
+                let struct_path = hir::QPath::Resolved(None, P(struct_path));
+
+                return hir::Expr {
+                    id: self.lower_node_id(e.id),
+                    node: if is_unit {
+                        hir::ExprPath(struct_path)
+                    } else {
+                        hir::ExprStruct(struct_path, fields, None)
+                    },
+                    span: unstable_span,
+                    attrs: e.attrs.clone(),
                 };
             }
             ExprKind::Path(ref qself, ref path) => {
@@ -2620,17 +2608,6 @@ fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<hir::Expr>) -> P<hir::Expr
         P(self.expr(sp, hir::ExprTup(exprs), ThinVec::new()))
     }
 
-    fn expr_std_struct(&mut self,
-                       span: Span,
-                       components: &[&str],
-                       fields: hir::HirVec<hir::Field>,
-                       e: Option<P<hir::Expr>>,
-                       attrs: ThinVec<Attribute>) -> hir::Expr {
-        let path = self.std_path(span, components, false);
-        let qpath = hir::QPath::Resolved(None, P(path));
-        self.expr(span, hir::ExprStruct(qpath, fields, e), attrs)
-    }
-
     fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinVec<Attribute>) -> hir::Expr {
         hir::Expr {
             id: self.next_id(),
index 583b3b848f30d88a7e572cc713233555a265f594..d7aa36b24f94279ba345399f7276a1e6fe609fff 100644 (file)
@@ -948,7 +948,7 @@ pub fn map_crate<'hir>(forest: &'hir mut Forest,
     intravisit::walk_crate(&mut collector, &forest.krate);
     let map = collector.map;
 
-    if log_enabled!(::log::DEBUG) {
+    if log_enabled!(::log::LogLevel::Debug) {
         // This only makes sense for ordered stores; note the
         // enumerate to count the number of entries.
         let (entries_less_1, _) = map.iter().filter(|&x| {
index 43b7deb5b90e39fd9178520c1fc77b491a339f7c..27fa7487270885968948620ca571e64f7d849762 100644 (file)
@@ -159,6 +159,10 @@ impl Lifetime {
     pub fn is_elided(&self) -> bool {
         self.name == keywords::Invalid.name()
     }
+
+    pub fn is_static(&self) -> bool {
+        self.name == keywords::StaticLifetime.name()
+    }
 }
 
 /// A lifetime definition, eg `'a: 'b+'c+'d`
index d296d8293fb0674010bb00d12ec012fdfaca0588..e760f7efc93d912645454213f9b42b5707836261 100644 (file)
@@ -55,7 +55,7 @@ pub fn to_hex(&self) -> String {
 impl Encodable for Fingerprint {
     #[inline]
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        for &byte in &self.0[..] {
+        for &byte in &self.0 {
             s.emit_u8(byte)?;
         }
         Ok(())
@@ -66,7 +66,7 @@ impl Decodable for Fingerprint {
     #[inline]
     fn decode<D: Decoder>(d: &mut D) -> Result<Fingerprint, D::Error> {
         let mut result = Fingerprint([0u8; FINGERPRINT_LENGTH]);
-        for byte in &mut result.0[..] {
+        for byte in &mut result.0 {
             *byte = d.read_u8()?;
         }
         Ok(result)
index 21139c8dde2a4b34b96c22becfc1b483728c9dfb..9fa2bc8a2a7a96f5290c4be26adaaccdc78b3918 100644 (file)
@@ -426,30 +426,26 @@ pub fn note_issue_32330(&self,
     {
         debug!("note_issue_32330: terr={:?}", terr);
         match *terr {
-            TypeError::RegionsInsufficientlyPolymorphic(_, &Region::ReVar(vid)) |
-            TypeError::RegionsOverlyPolymorphic(_, &Region::ReVar(vid)) => {
-                match self.region_vars.var_origin(vid) {
-                    RegionVariableOrigin::EarlyBoundRegion(_, _, Some(Issue32330 {
-                        fn_def_id,
-                        region_name
-                    })) => {
-                        diag.note(
-                            &format!("lifetime parameter `{0}` declared on fn `{1}` \
-                                      appears only in the return type, \
-                                      but here is required to be higher-ranked, \
-                                      which means that `{0}` must appear in both \
-                                      argument and return types",
-                                     region_name,
-                                     self.tcx.item_path_str(fn_def_id)));
-                        diag.note(
-                            &format!("this error is the result of a recent bug fix; \
-                                      for more information, see issue #33685 \
-                                      <https://github.com/rust-lang/rust/issues/33685>"));
-                    }
-                    _ => { }
-                }
+            TypeError::RegionsInsufficientlyPolymorphic(_, _, Some(box Issue32330 {
+                fn_def_id, region_name
+            })) |
+            TypeError::RegionsOverlyPolymorphic(_, _, Some(box Issue32330 {
+                fn_def_id, region_name
+            })) => {
+                diag.note(
+                    &format!("lifetime parameter `{0}` declared on fn `{1}` \
+                              appears only in the return type, \
+                              but here is required to be higher-ranked, \
+                              which means that `{0}` must appear in both \
+                              argument and return types",
+                             region_name,
+                             self.tcx.item_path_str(fn_def_id)));
+                diag.note(
+                    &format!("this error is the result of a recent bug fix; \
+                              for more information, see issue #33685 \
+                              <https://github.com/rust-lang/rust/issues/33685>"));
             }
-            _ => { }
+            _ => {}
         }
     }
 
index e919f025409c510a717458b4ea4d073c5ea83e8e..e3ffc99c0e9677bc667494e388492c2201369aa3 100644 (file)
@@ -15,6 +15,7 @@
             InferCtxt,
             LateBoundRegion,
             HigherRankedType,
+            RegionVariableOrigin,
             SubregionOrigin,
             SkolemizationMap};
 use super::combine::CombineFields;
@@ -656,14 +657,27 @@ pub fn leak_check(&self,
                        skol_br,
                        tainted_region);
 
+                let issue_32330 = if let &ty::ReVar(vid) = tainted_region {
+                    match self.region_vars.var_origin(vid) {
+                        RegionVariableOrigin::EarlyBoundRegion(_, _, issue_32330) => {
+                            issue_32330.map(Box::new)
+                        }
+                        _ => None
+                    }
+                } else {
+                    None
+                };
+
                 if overly_polymorphic {
                     debug!("Overly polymorphic!");
                     return Err(TypeError::RegionsOverlyPolymorphic(skol_br,
-                                                                   tainted_region));
+                                                                   tainted_region,
+                                                                   issue_32330));
                 } else {
                     debug!("Not as polymorphic!");
                     return Err(TypeError::RegionsInsufficientlyPolymorphic(skol_br,
-                                                                           tainted_region));
+                                                                           tainted_region,
+                                                                           issue_32330));
                 }
             }
         }
index 843f3a53f33e5c9500b9244563a13d138c605a78..20bf241a99906e3afe1a5196fb29718bc88f9cc1 100644 (file)
 use std::default::Default as StdDefault;
 use std::mem;
 use std::fmt;
-use std::ops::Deref;
 use syntax::attr;
 use syntax::ast;
 use syntax::symbol::Symbol;
-use syntax_pos::{MultiSpan, Span};
+use syntax_pos::{DUMMY_SP, MultiSpan, Span};
 use errors::{self, Diagnostic, DiagnosticBuilder};
 use hir;
+use hir::def_id::LOCAL_CRATE;
 use hir::intravisit as hir_visit;
 use syntax::visit as ast_visit;
 
@@ -484,7 +484,7 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
                 Allow => bug!("earlier conditional return should handle Allow case")
             };
             let hyphen_case_lint_name = name.replace("_", "-");
-            if lint_flag_val.as_str().deref() == name {
+            if lint_flag_val.as_str() == name {
                 err.note(&format!("requested on the command line with `{} {}`",
                                   flag, hyphen_case_lint_name));
             } else {
@@ -495,7 +495,7 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
         },
         Node(lint_attr_name, src) => {
             def = Some(src);
-            if lint_attr_name.as_str().deref() != name {
+            if lint_attr_name.as_str() != name {
                 let level_str = level.as_str();
                 err.note(&format!("#[{}({})] implied by #[{}({})]",
                                   level_str, name, level_str, lint_attr_name));
@@ -1231,10 +1231,11 @@ fn check_lint_name_cmdline(sess: &Session, lint_cx: &LintStore,
 /// Perform lint checking on a crate.
 ///
 /// Consumes the `lint_store` field of the `Session`.
-pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                             access_levels: &AccessLevels) {
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let _task = tcx.dep_graph.in_task(DepNode::LateLintCheck);
 
+    let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
+
     let krate = tcx.hir.krate();
 
     // We want to own the lint store, so move it out of the session.
index 225d6fc9bb2b211100ff6bdf65a9fc7a8018d26c..8bc0cf2577b5db05761ebbbf9a4b966875383605 100644 (file)
@@ -176,7 +176,6 @@ pub trait CrateStore {
     fn item_generics_cloned(&self, def: DefId) -> ty::Generics;
     fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
     fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>;
-    fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>;
 
     // trait info
     fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>;
@@ -255,8 +254,8 @@ fn maybe_get_item_body<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
     fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>;
     fn used_crate_source(&self, cnum: CrateNum) -> CrateSource;
     fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
-    fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                 reexports: &def::ExportMap,
+    fn encode_metadata<'a, 'tcx>(&self,
+                                 tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                  link_meta: &LinkMeta,
                                  reachable: &NodeSet) -> Vec<u8>;
     fn metadata_encoding_version(&self) -> &[u8];
@@ -310,7 +309,6 @@ fn item_generics_cloned(&self, def: DefId) -> ty::Generics
         { bug!("item_generics_cloned") }
     fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
     fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name> { bug!("fn_arg_names") }
-    fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId> { vec![] }
 
     // trait info
     fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId> { vec![] }
@@ -412,10 +410,10 @@ fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
         { vec![] }
     fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") }
     fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> { None }
-    fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                           reexports: &def::ExportMap,
-                           link_meta: &LinkMeta,
-                           reachable: &NodeSet) -> Vec<u8> { vec![] }
+    fn encode_metadata<'a, 'tcx>(&self,
+                                 tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                 link_meta: &LinkMeta,
+                                 reachable: &NodeSet) -> Vec<u8> { vec![] }
     fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
 }
 
index cc6d6e88dee4ee068424be59d0d10ee853903fe1..8926ff5c1fbbb080dce5afbfe165418548395d66 100644 (file)
 use middle::privacy;
 use ty::{self, TyCtxt};
 use hir::def::Def;
-use hir::def_id::{DefId};
+use hir::def_id::{DefId, LOCAL_CRATE};
 use lint;
 use util::nodemap::FxHashSet;
 
 use syntax::{ast, codemap};
 use syntax::attr;
+use syntax::codemap::DUMMY_SP;
 use syntax_pos;
 
 // Any local node that may call something in its body block should be
@@ -592,9 +593,9 @@ fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
     }
 }
 
-pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                             access_levels: &privacy::AccessLevels) {
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let _task = tcx.dep_graph.in_task(DepNode::DeadCheck);
+    let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
     let krate = tcx.hir.krate();
     let live_symbols = find_live(tcx, access_levels, krate);
     let mut visitor = DeadVisitor { tcx: tcx, live_symbols: live_symbols };
index 4ec43e368a60dc9036e7ca96c9675ecbd3612c2e..b0e39442af98c9997f9885949d3b2e56e07d3178 100644 (file)
@@ -27,7 +27,9 @@
 use syntax::abi::Abi;
 use syntax::ast;
 use syntax::attr;
+use syntax::codemap::DUMMY_SP;
 use hir;
+use hir::def_id::LOCAL_CRATE;
 use hir::intravisit::{Visitor, NestedVisitorMap};
 use hir::itemlikevisit::ItemLikeVisitor;
 use hir::intravisit;
@@ -359,11 +361,11 @@ fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
     }
 }
 
-pub fn find_reachable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                access_levels: &privacy::AccessLevels)
-                                -> NodeSet {
+pub fn find_reachable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> NodeSet {
     let _task = tcx.dep_graph.in_task(DepNode::Reachability);
 
+    let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
+
     let any_library = tcx.sess.crate_types.borrow().iter().any(|ty| {
         *ty == config::CrateTypeRlib || *ty == config::CrateTypeDylib ||
         *ty == config::CrateTypeProcMacro
index 37749816eb153c725300a0eddba7f66cdc21b917..5094e28475b2640e9faea82e38e71fe28b91bba1 100644 (file)
@@ -29,7 +29,7 @@
 use syntax::attr;
 use syntax::ptr::P;
 use syntax::symbol::keywords;
-use syntax_pos::Span;
+use syntax_pos::{mk_sp, Span};
 use errors::DiagnosticBuilder;
 use util::nodemap::{NodeMap, NodeSet, FxHashSet, FxHashMap, DefIdMap};
 use rustc_back::slice;
@@ -434,7 +434,7 @@ fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
             self.resolve_elided_lifetimes(slice::ref_slice(lifetime_ref));
             return;
         }
-        if lifetime_ref.name == keywords::StaticLifetime.name() {
+        if lifetime_ref.is_static() {
             self.insert_lifetime(lifetime_ref, Region::Static);
             return;
         }
@@ -1434,7 +1434,7 @@ fn check_lifetime_defs(&mut self, old_scope: ScopeRef, lifetimes: &[hir::Lifetim
             let lifetime_i = &lifetimes[i];
 
             for lifetime in lifetimes {
-                if lifetime.lifetime.name == keywords::StaticLifetime.name() {
+                if lifetime.lifetime.is_static() {
                     let lifetime = lifetime.lifetime;
                     let mut err = struct_span_err!(self.sess, lifetime.span, E0262,
                                   "invalid lifetime parameter name: `{}`", lifetime.name);
@@ -1464,7 +1464,17 @@ fn check_lifetime_defs(&mut self, old_scope: ScopeRef, lifetimes: &[hir::Lifetim
             self.check_lifetime_def_for_shadowing(old_scope, &lifetime_i.lifetime);
 
             for bound in &lifetime_i.bounds {
-                self.resolve_lifetime_ref(bound);
+                if !bound.is_static() {
+                    self.resolve_lifetime_ref(bound);
+                } else {
+                    self.insert_lifetime(bound, Region::Static);
+                    let full_span = mk_sp(lifetime_i.lifetime.span.lo, bound.span.hi);
+                    self.sess.struct_span_warn(full_span,
+                        &format!("unnecessary lifetime parameter `{}`", lifetime_i.lifetime.name))
+                        .help(&format!("you can use the `'static` lifetime directly, in place \
+                                        of `{}`", lifetime_i.lifetime.name))
+                        .emit();
+                }
             }
         }
     }
index 1fb537140257465eae43371f32b7b78eead2c4bf..4354ed6817ae96376db2640305c638b9f9567b34 100644 (file)
@@ -536,7 +536,7 @@ pub fn check_stability(self, def_id: DefId, id: NodeId, span: Span) {
                 if !self.stability.borrow().active_features.contains(feature) {
                     let msg = match *reason {
                         Some(ref r) => format!("use of unstable library feature '{}': {}",
-                                               &feature.as_str(), &r),
+                                               feature.as_str(), &r),
                         None => format!("use of unstable library feature '{}'", &feature)
                     };
                     emit_feature_err(&self.sess.parse_sess, &feature.as_str(), span,
@@ -656,10 +656,11 @@ fn lookup_deprecation_uncached(self, id: DefId) -> Option<DeprecationEntry> {
 /// Given the list of enabled features that were not language features (i.e. that
 /// were expected to be library features), and the list of features used from
 /// libraries, identify activated features that don't exist and error about them.
-pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                                 access_levels: &AccessLevels) {
+pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let sess = &tcx.sess;
 
+    let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
+
     if tcx.stability.borrow().staged_api[&LOCAL_CRATE] && tcx.sess.features.borrow().staged_api {
         let _task = tcx.dep_graph.in_task(DepNode::StabilityIndex);
         let krate = tcx.hir.krate();
index 34977822bc69d8c8600105e7989ce5eed8e7c01f..d8ca30477205c53ccfcfd0e5bc61dab9c16828ae 100644 (file)
@@ -139,6 +139,21 @@ pub enum AutoBorrow<'tcx> {
     RawPtr(hir::Mutability),
 }
 
+/// Information for `CoerceUnsized` impls, storing information we
+/// have computed about the coercion.
+///
+/// This struct can be obtained via the `coerce_impl_info` query.
+/// Demanding this struct also has the side-effect of reporting errors
+/// for inappropriate impls.
+#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
+pub struct CoerceUnsizedInfo {
+    /// If this is a "custom coerce" impl, then what kind of custom
+    /// coercion is it? This applies to impls of `CoerceUnsized` for
+    /// structs, primarily, where we store a bit of info about which
+    /// fields need to be coerced.
+    pub custom_kind: Option<CustomCoerceUnsized>
+}
+
 #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
 pub enum CustomCoerceUnsized {
     /// Records the index of the field being coerced.
index 5543223105b444c37f5d8e512588661627c094a1..da56514ea82fbf9e485c3f1f761ff9253f9b54cc 100644 (file)
@@ -15,7 +15,7 @@
 use lint;
 use middle;
 use hir::TraitMap;
-use hir::def::Def;
+use hir::def::{Def, ExportMap};
 use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use hir::map as hir_map;
 use hir::map::DisambiguatedDefPathData;
@@ -416,6 +416,9 @@ pub struct GlobalCtxt<'tcx> {
     /// is relevant; generated by resolve.
     pub trait_map: TraitMap,
 
+    /// Export map produced by name resolution.
+    pub export_map: ExportMap,
+
     pub named_region_map: resolve_lifetime::NamedRegionMap,
 
     pub region_maps: RegionMaps,
@@ -698,6 +701,7 @@ pub fn create_and_enter<F, R>(s: &'tcx Session,
             region_maps: region_maps,
             variance_computed: Cell::new(false),
             trait_map: resolutions.trait_map,
+            export_map: resolutions.export_map,
             fulfilled_predicates: RefCell::new(fulfilled_predicates),
             hir: hir,
             maps: maps::Maps::new(dep_graph, providers),
index 5a696446b4bb6ea349abf18165ba1b0b269d557e..73d9c8b00ae472656765a3e2dd892df1b9720903 100644 (file)
@@ -39,8 +39,8 @@ pub enum TypeError<'tcx> {
     RegionsDoesNotOutlive(&'tcx Region, &'tcx Region),
     RegionsNotSame(&'tcx Region, &'tcx Region),
     RegionsNoOverlap(&'tcx Region, &'tcx Region),
-    RegionsInsufficientlyPolymorphic(BoundRegion, &'tcx Region),
-    RegionsOverlyPolymorphic(BoundRegion, &'tcx Region),
+    RegionsInsufficientlyPolymorphic(BoundRegion, &'tcx Region, Option<Box<ty::Issue32330>>),
+    RegionsOverlyPolymorphic(BoundRegion, &'tcx Region, Option<Box<ty::Issue32330>>),
     Sorts(ExpectedFound<Ty<'tcx>>),
     IntMismatch(ExpectedFound<ty::IntVarValue>),
     FloatMismatch(ExpectedFound<ast::FloatTy>),
@@ -116,11 +116,11 @@ fn report_maybe_different(f: &mut fmt::Formatter,
             RegionsNoOverlap(..) => {
                 write!(f, "lifetimes do not intersect")
             }
-            RegionsInsufficientlyPolymorphic(br, _) => {
+            RegionsInsufficientlyPolymorphic(br, _, _) => {
                 write!(f, "expected bound lifetime parameter {}, \
                            found concrete lifetime", br)
             }
-            RegionsOverlyPolymorphic(br, _) => {
+            RegionsOverlyPolymorphic(br, _, _) => {
                 write!(f, "expected concrete lifetime, \
                            found bound lifetime parameter {}", br)
             }
@@ -253,15 +253,15 @@ pub fn note_and_explain_type_err(self,
                 self.note_and_explain_region(db, "...does not overlap ",
                                            region2, "");
             }
-            RegionsInsufficientlyPolymorphic(_, conc_region) => {
+            RegionsInsufficientlyPolymorphic(_, conc_region, _) => {
                 self.note_and_explain_region(db, "concrete lifetime that was found is ",
                                            conc_region, "");
             }
-            RegionsOverlyPolymorphic(_, &ty::ReVar(_)) => {
+            RegionsOverlyPolymorphic(_, &ty::ReVar(_), _) => {
                 // don't bother to print out the message below for
                 // inference variables, it's not very illuminating.
             }
-            RegionsOverlyPolymorphic(_, conc_region) => {
+            RegionsOverlyPolymorphic(_, conc_region, _) => {
                 self.note_and_explain_region(db, "expected concrete lifetime is ",
                                            conc_region, "");
             }
index 874e032bc46445490ffd30dd05b2fdf78e99dd42..38699105290551e97d7a344ca5d1ff75db8cf532 100644 (file)
@@ -202,7 +202,8 @@ fn push_impl_path<T>(self,
         } else {
             // for local crates, check whether type info is
             // available; typeck might not have completed yet
-            self.maps.impl_trait_ref.borrow().contains_key(&impl_def_id)
+            self.maps.impl_trait_ref.borrow().contains_key(&impl_def_id) &&
+                self.maps.ty.borrow().contains_key(&impl_def_id)
         };
 
         if !use_types {
index ac8c38c7d585664d05d58efd4832d59e7a61e38e..5a57b0072107c666e6c504f2dc39ab37718513a7 100644 (file)
@@ -11,8 +11,9 @@
 use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
 use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use middle::const_val::ConstVal;
+use middle::privacy::AccessLevels;
 use mir;
-use ty::{self, Ty, TyCtxt};
+use ty::{self, CrateInherentImpls, Ty, TyCtxt};
 
 use rustc_data_structures::indexed_vec::IndexVec;
 use std::cell::{RefCell, RefMut};
@@ -176,9 +177,15 @@ fn describe(tcx: TyCtxt, (_, def_id): (CrateNum, DefId)) -> String {
     }
 }
 
-impl<'tcx> QueryDescription for queries::coherent_inherent_impls<'tcx> {
+impl<'tcx> QueryDescription for queries::crate_inherent_impls<'tcx> {
+    fn describe(_: TyCtxt, k: CrateNum) -> String {
+        format!("all inherent impls defined in crate `{:?}`", k)
+    }
+}
+
+impl<'tcx> QueryDescription for queries::crate_inherent_impls_overlap_check<'tcx> {
     fn describe(_: TyCtxt, _: CrateNum) -> String {
-        format!("coherence checking all inherent impls")
+        format!("check for overlap between inherent impls defined in this crate")
     }
 }
 
@@ -189,6 +196,12 @@ fn describe(tcx: TyCtxt, def: ty::InstanceDef<'tcx>) -> String {
     }
 }
 
+impl<'tcx> QueryDescription for queries::privacy_access_levels<'tcx> {
+    fn describe(_: TyCtxt, _: CrateNum) -> String {
+        format!("privacy access levels")
+    }
+}
+
 macro_rules! define_maps {
     (<$tcx:tt>
      $($(#[$attr:meta])*
@@ -368,7 +381,7 @@ fn default() -> Self {
     /// Maps a DefId of a type to a list of its inherent impls.
     /// Contains implementations of methods that are inherent to a type.
     /// Methods in these implementations don't need to be exported.
-    pub inherent_impls: InherentImpls(DefId) -> Vec<DefId>,
+    pub inherent_impls: InherentImpls(DefId) -> Rc<Vec<DefId>>,
 
     /// Maps from the def-id of a function/method or const/static
     /// to its MIR. Mutation is done at an item granularity to
@@ -393,19 +406,30 @@ fn default() -> Self {
     pub closure_type: ItemSignature(DefId) -> ty::PolyFnSig<'tcx>,
 
     /// Caches CoerceUnsized kinds for impls on custom types.
-    pub custom_coerce_unsized_kind: ItemSignature(DefId)
-        -> ty::adjustment::CustomCoerceUnsized,
+    pub coerce_unsized_info: ItemSignature(DefId)
+        -> ty::adjustment::CoerceUnsizedInfo,
 
     pub typeck_tables: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>,
 
     pub coherent_trait: coherent_trait_dep_node((CrateNum, DefId)) -> (),
 
-    pub coherent_inherent_impls: coherent_inherent_impls_dep_node(CrateNum) -> (),
+    /// Gets a complete map from all types to their inherent impls.
+    /// Not meant to be used directly outside of coherence.
+    /// (Defined only for LOCAL_CRATE)
+    pub crate_inherent_impls: crate_inherent_impls_dep_node(CrateNum) -> CrateInherentImpls,
+
+    /// Checks all types in the krate for overlap in their inherent impls. Reports errors.
+    /// Not meant to be used directly outside of coherence.
+    /// (Defined only for LOCAL_CRATE)
+    pub crate_inherent_impls_overlap_check: crate_inherent_impls_dep_node(CrateNum) -> (),
 
     /// Results of evaluating monomorphic constants embedded in
     /// other items, such as enum variant explicit discriminants.
     pub monomorphic_const_eval: MonomorphicConstEval(DefId) -> Result<ConstVal<'tcx>, ()>,
 
+    /// Performs the privacy check and computes "access levels".
+    pub privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Rc<AccessLevels>,
+
     pub mir_shims: mir_shim(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>
 }
 
@@ -413,7 +437,7 @@ fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
     DepNode::CoherenceCheckTrait(def_id)
 }
 
-fn coherent_inherent_impls_dep_node(_: CrateNum) -> DepNode<DefId> {
+fn crate_inherent_impls_dep_node(_: CrateNum) -> DepNode<DefId> {
     DepNode::Coherence
 }
 
index 36d1ae74e9114546b5a5f4fa6164bd8e9d417e78..6a4e7db21dd127d2d20bf57cb32a2517e4b1d0d1 100644 (file)
 
 use dep_graph::{self, DepNode};
 use hir::{map as hir_map, FreevarMap, TraitMap};
-use middle;
 use hir::def::{Def, CtorKind, ExportMap};
 use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
 use middle::const_val::ConstVal;
 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
+use middle::privacy::AccessLevels;
 use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
 use middle::resolve_lifetime::ObjectLifetimeDefault;
 use mir::Mir;
@@ -31,7 +31,7 @@
 use ty::util::IntTypeExt;
 use ty::walk::TypeWalker;
 use util::common::MemoizationMap;
-use util::nodemap::{NodeSet, FxHashMap};
+use util::nodemap::{NodeSet, DefIdMap, FxHashMap};
 
 use serialize::{self, Encodable, Encoder};
 use std::borrow::Cow;
 
 /// The complete set of all analyses described in this module. This is
 /// produced by the driver and fed to trans and later passes.
+///
+/// NB: These contents are being migrated into queries using the
+/// *on-demand* infrastructure.
 #[derive(Clone)]
 pub struct CrateAnalysis {
-    pub export_map: ExportMap,
-    pub access_levels: middle::privacy::AccessLevels,
+    pub access_levels: Rc<AccessLevels>,
     pub reachable: NodeSet,
     pub name: String,
     pub glob_map: Option<hir::GlobMap>,
@@ -122,6 +124,7 @@ pub struct Resolutions {
     pub freevars: FreevarMap,
     pub trait_map: TraitMap,
     pub maybe_unused_trait_imports: NodeSet,
+    pub export_map: ExportMap,
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
@@ -2054,8 +2057,8 @@ pub fn trait_relevant_for_never(self, did: DefId) -> bool {
         })
     }
 
-    pub fn custom_coerce_unsized_kind(self, did: DefId) -> adjustment::CustomCoerceUnsized {
-        queries::custom_coerce_unsized_kind::get(self, DUMMY_SP, did)
+    pub fn coerce_unsized_info(self, did: DefId) -> adjustment::CoerceUnsizedInfo {
+        queries::coerce_unsized_info::get(self, DUMMY_SP, did)
     }
 
     pub fn associated_item(self, def_id: DefId) -> AssociatedItem {
@@ -2345,34 +2348,6 @@ pub fn trait_has_default_impl(self, trait_def_id: DefId) -> bool {
         def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL)
     }
 
-    /// Populates the type context with all the inherent implementations for
-    /// the given type if necessary.
-    pub fn populate_inherent_implementations_for_type_if_necessary(self,
-                                                                   span: Span,
-                                                                   type_id: DefId) {
-        if type_id.is_local() {
-            // Make sure coherence of inherent impls ran already.
-            ty::queries::coherent_inherent_impls::force(self, span, LOCAL_CRATE);
-            return
-        }
-
-        // The type is not local, hence we are reading this out of
-        // metadata and don't need to track edges.
-        let _ignore = self.dep_graph.in_ignore();
-
-        if self.populated_external_types.borrow().contains(&type_id) {
-            return
-        }
-
-        debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}",
-               type_id);
-
-        let inherent_impls = self.sess.cstore.inherent_implementations_for_type(type_id);
-
-        self.maps.inherent_impls.borrow_mut().insert(type_id, inherent_impls);
-        self.populated_external_types.borrow_mut().insert(type_id);
-    }
-
     /// Populates the type context with all the implementations for the given
     /// trait if necessary.
     pub fn populate_implementations_for_trait_if_necessary(self, trait_id: DefId) {
@@ -2637,3 +2612,16 @@ pub fn provide(providers: &mut ty::maps::Providers) {
         ..*providers
     };
 }
+
+
+/// A map for the local crate mapping each type to a vector of its
+/// inherent impls. This is not meant to be used outside of coherence;
+/// rather, you should request the vector for a specific type via
+/// `ty::queries::inherent_impls::get(def_id)` so as to minimize your
+/// dependencies (constructing this map requires touching the entire
+/// crate).
+#[derive(Clone, Debug)]
+pub struct CrateInherentImpls {
+    pub inherent_impls: DefIdMap<Rc<Vec<DefId>>>,
+}
+
index 49824e8a738d7a74e5a5204d31cfa1a5cbc6ef70..9126600e3f65393d2eff900e06bcbd077535be8d 100644 (file)
@@ -293,11 +293,13 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
             RegionsNoOverlap(a, b) => {
                 return tcx.lift(&(a, b)).map(|(a, b)| RegionsNoOverlap(a, b))
             }
-            RegionsInsufficientlyPolymorphic(a, b) => {
-                return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b))
+            RegionsInsufficientlyPolymorphic(a, b, ref c) => {
+                let c = c.clone();
+                return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b, c))
             }
-            RegionsOverlyPolymorphic(a, b) => {
-                return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b))
+            RegionsOverlyPolymorphic(a, b, ref c) => {
+                let c = c.clone();
+                return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b, c))
             }
             IntMismatch(x) => IntMismatch(x),
             FloatMismatch(x) => FloatMismatch(x),
index 85e861b405a9f8620b9480902e0208ce33666abd..730abc54568e1364e12747db4329b8caea0acd1d 100644 (file)
@@ -11,7 +11,7 @@ crate-type = ["dylib"]
 [dependencies]
 syntax = { path = "../libsyntax" }
 serialize = { path = "../libserialize" }
-log = { path = "../liblog" }
+log = "0.3"
 
 [features]
 jemalloc = []
index d53318f1768480674f384b513b06e281fda7ff82..af99c0e938724d95023ff8c3831fdbb6e3d44670 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 test = false
 
 [dependencies]
-log = { path = "../liblog" }
+log = "0.3"
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 graphviz = { path = "../libgraphviz" }
index c0f681680a967b0350e27146d28486ae89a6c48b..b728d4d534516672e436312a336f40f627017943 100644 (file)
@@ -267,11 +267,11 @@ pub fn fixup_fragment_sets<'a, 'tcx>(this: &MoveData<'tcx>, tcx: TyCtxt<'a, 'tcx
     // First, filter out duplicates
     moved.sort();
     moved.dedup();
-    debug!("fragments 1 moved: {:?}", path_lps(&moved[..]));
+    debug!("fragments 1 moved: {:?}", path_lps(&moved));
 
     assigned.sort();
     assigned.dedup();
-    debug!("fragments 1 assigned: {:?}", path_lps(&assigned[..]));
+    debug!("fragments 1 assigned: {:?}", path_lps(&assigned));
 
     // Second, build parents from the moved and assigned.
     for m in &moved {
@@ -291,14 +291,14 @@ pub fn fixup_fragment_sets<'a, 'tcx>(this: &MoveData<'tcx>, tcx: TyCtxt<'a, 'tcx
 
     parents.sort();
     parents.dedup();
-    debug!("fragments 2 parents: {:?}", path_lps(&parents[..]));
+    debug!("fragments 2 parents: {:?}", path_lps(&parents));
 
     // Third, filter the moved and assigned fragments down to just the non-parents
-    moved.retain(|f| non_member(*f, &parents[..]));
-    debug!("fragments 3 moved: {:?}", path_lps(&moved[..]));
+    moved.retain(|f| non_member(*f, &parents));
+    debug!("fragments 3 moved: {:?}", path_lps(&moved));
 
-    assigned.retain(|f| non_member(*f, &parents[..]));
-    debug!("fragments 3 assigned: {:?}", path_lps(&assigned[..]));
+    assigned.retain(|f| non_member(*f, &parents));
+    debug!("fragments 3 assigned: {:?}", path_lps(&assigned));
 
     // Fourth, build the leftover from the moved, assigned, and parents.
     for m in &moved {
@@ -316,16 +316,16 @@ pub fn fixup_fragment_sets<'a, 'tcx>(this: &MoveData<'tcx>, tcx: TyCtxt<'a, 'tcx
 
     unmoved.sort();
     unmoved.dedup();
-    debug!("fragments 4 unmoved: {:?}", frag_lps(&unmoved[..]));
+    debug!("fragments 4 unmoved: {:?}", frag_lps(&unmoved));
 
     // Fifth, filter the leftover fragments down to its core.
     unmoved.retain(|f| match *f {
         AllButOneFrom(_) => true,
-        Just(mpi) => non_member(mpi, &parents[..]) &&
-            non_member(mpi, &moved[..]) &&
-            non_member(mpi, &assigned[..])
+        Just(mpi) => non_member(mpi, &parents) &&
+            non_member(mpi, &moved) &&
+            non_member(mpi, &assigned)
     });
-    debug!("fragments 5 unmoved: {:?}", frag_lps(&unmoved[..]));
+    debug!("fragments 5 unmoved: {:?}", frag_lps(&unmoved));
 
     // Swap contents back in.
     fragments.unmoved_fragments = unmoved;
index 558a835be188462070f8e145ed6444ecf9d4cbc6..0915c57b588eb1a7c2c33b091682fd4fce4790e7 100644 (file)
@@ -113,7 +113,7 @@ fn borrowck_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, body_id: hir::BodyId) {
                                                  &flowed_moves.move_data,
                                                  owner_id);
 
-    check_loans::check_loans(bccx, &loan_dfcx, &flowed_moves, &all_loans[..], body);
+    check_loans::check_loans(bccx, &loan_dfcx, &flowed_moves, &all_loans, body);
 }
 
 fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
index 0da9525efd8566e53520961e8b4addd8e9231a94..e3a2bfa392738586fe06cd374082d3222c6bf50d 100644 (file)
@@ -88,7 +88,7 @@ fn build_set<O:DataFlowOperator, F>(&self,
                 set.push_str(", ");
             }
             let loan_str = self.borrowck_ctxt.loan_path_to_string(&lp);
-            set.push_str(&loan_str[..]);
+            set.push_str(&loan_str);
             saw_some = true;
             true
         });
index 780b2c16a32ecefc5bd556d2a88b6409b9246554..907410f74dca4f268697e32d036a606894924996 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 
 [dependencies]
 arena = { path = "../libarena" }
-log = { path = "../liblog" }
+log = "0.3"
 rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
 rustc_const_math = { path = "../librustc_const_math" }
index 53a7e87292818d773a7af3dfcd859d0b8467adcd..c1dc5f5f7a2b8d10e0f5a99565480dfab83f9993 100644 (file)
@@ -680,10 +680,10 @@ fn is_useful_specialized<'p, 'a:'p, 'tcx: 'a>(
     }).collect();
     let wild_patterns: Vec<_> = wild_patterns_owned.iter().collect();
     let matrix = Matrix(m.iter().flat_map(|r| {
-        specialize(cx, &r[..], &ctor, &wild_patterns)
+        specialize(cx, &r, &ctor, &wild_patterns)
     }).collect());
     match specialize(cx, v, &ctor, &wild_patterns) {
-        Some(v) => match is_useful(cx, &matrix, &v[..], witness) {
+        Some(v) => match is_useful(cx, &matrix, &v, witness) {
             UsefulWithWitness(witnesses) => UsefulWithWitness(
                 witnesses.into_iter()
                     .map(|witness| witness.apply_constructor(cx, &ctor, lty))
index e2b9f174ff0c200a6e174347d0e85cf5c7239fff..9d55281d019d9ee579a4d755e47b6303d674ec04 100644 (file)
@@ -311,7 +311,7 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
         for &(pat, hir_pat) in pats {
             let v = vec![pat];
 
-            match is_useful(cx, &seen, &v[..], LeaveOutWitness) {
+            match is_useful(cx, &seen, &v, LeaveOutWitness) {
                 NotUseful => {
                     match source {
                         hir::MatchSource::IfLetDesugar { .. } => {
index e2e16059d98718c534335bf277927d4cb35c7853..343b1ed68b80431cb3e734dff8adc4764073cd87 100644 (file)
@@ -9,5 +9,5 @@ path = "lib.rs"
 crate-type = ["dylib"]
 
 [dependencies]
-log = { path = "../liblog" }
+log = "0.3"
 serialize = { path = "../libserialize" }
index d4bd9e707fdcb9780a618a6ba30151061b479109..c03c2890ba34c6cb4723c3eb00ed514a8bf2e5a5 100644 (file)
@@ -91,8 +91,8 @@ impl<A: Array> Deref for AccumulateVec<A> {
     type Target = [A::Element];
     fn deref(&self) -> &Self::Target {
         match *self {
-            AccumulateVec::Array(ref v) => &v[..],
-            AccumulateVec::Heap(ref v) => &v[..],
+            AccumulateVec::Array(ref v) => v,
+            AccumulateVec::Heap(ref v) => v,
         }
     }
 }
@@ -100,8 +100,8 @@ fn deref(&self) -> &Self::Target {
 impl<A: Array> DerefMut for AccumulateVec<A> {
     fn deref_mut(&mut self) -> &mut [A::Element] {
         match *self {
-            AccumulateVec::Array(ref mut v) => &mut v[..],
-            AccumulateVec::Heap(ref mut v) => &mut v[..],
+            AccumulateVec::Array(ref mut v) => v,
+            AccumulateVec::Heap(ref mut v) => v,
         }
     }
 }
index 4359581a897f57153df7e6179f8bb9f4ba553548..cf54229fa7f52e59130cbd39c43ee7656c90d1f4 100644 (file)
@@ -48,7 +48,7 @@ pub fn encode(n: u64, base: u64) -> String {
 #[test]
 fn test_encode() {
     fn test(n: u64, base: u64) {
-        assert_eq!(Ok(n), u64::from_str_radix(&encode(n, base)[..], base as u32));
+        assert_eq!(Ok(n), u64::from_str_radix(&encode(n, base), base as u32));
     }
 
     for base in 2..37 {
index 31492e2621945dd292d556f556fd61d4a3d36fb6..9d97a83f693c32f7cb528def5b49ff3ac47f1178 100644 (file)
@@ -35,7 +35,7 @@ pub struct Blake2bCtx {
 impl ::std::fmt::Debug for Blake2bCtx {
     fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
         try!(write!(fmt, "hash: "));
-        for v in &self.h[..] {
+        for v in &self.h {
             try!(write!(fmt, "{:x}", v));
         }
         Ok(())
index 2e9e054e97eafe7dd0172d5f116710d65f1c7669..572ce98d3ae8e30a0f19a8b9a69b887c9873eb3e 100644 (file)
@@ -91,13 +91,13 @@ unsafe fn from_slice_mut(s: &mut [Word]) -> &mut Self {
 impl<T: Idx> Deref for IdxSetBuf<T> {
     type Target = IdxSet<T>;
     fn deref(&self) -> &IdxSet<T> {
-        unsafe { IdxSet::from_slice(&self.bits[..]) }
+        unsafe { IdxSet::from_slice(&self.bits) }
     }
 }
 
 impl<T: Idx> DerefMut for IdxSetBuf<T> {
     fn deref_mut(&mut self) -> &mut IdxSet<T> {
-        unsafe { IdxSet::from_slice_mut(&mut self.bits[..]) }
+        unsafe { IdxSet::from_slice_mut(&mut self.bits) }
     }
 }
 
@@ -135,11 +135,11 @@ pub fn contains(&self, elem: &T) -> bool {
     }
 
     pub fn words(&self) -> &[Word] {
-        &self.bits[..]
+        &self.bits
     }
 
     pub fn words_mut(&mut self) -> &mut [Word] {
-        &mut self.bits[..]
+        &mut self.bits
     }
 
     pub fn clone_from(&mut self, other: &IdxSet<T>) {
index caa5c8b7e00581562638ea76af04f39571305455..5b5113caa8e8c0dd9d68e7e8078b71991efa107e 100644 (file)
@@ -11,7 +11,8 @@ crate-type = ["dylib"]
 [dependencies]
 arena = { path = "../libarena" }
 graphviz = { path = "../libgraphviz" }
-log = { path = "../liblog" }
+log = { version = "0.3", features = ["release_max_level_info"] }
+env_logger = { version = "0.4", default-features = false }
 proc_macro_plugin = { path = "../libproc_macro_plugin" }
 rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
index d37553d7d660ea8b3374df940bc229ea9b2137b7..4873b21c548740f98480346794ea5abc76309c64 100644 (file)
@@ -48,6 +48,7 @@
 use std::io::{self, Write};
 use std::iter;
 use std::path::{Path, PathBuf};
+use std::rc::Rc;
 use syntax::{ast, diagnostics, visit};
 use syntax::attr;
 use syntax::ext::base::ExtCtxt;
@@ -198,13 +199,13 @@ macro_rules! controller_entry_point {
 
             result?;
 
-            if log_enabled!(::log::INFO) {
+            if log_enabled!(::log::LogLevel::Info) {
                 println!("Pre-trans");
                 tcx.print_debug_stats();
             }
             let trans = phase_4_translate_to_llvm(tcx, analysis, &incremental_hashes_map);
 
-            if log_enabled!(::log::INFO) {
+            if log_enabled!(::log::LogLevel::Info) {
                 println!("Post-trans");
                 tcx.print_debug_stats();
             }
@@ -257,10 +258,7 @@ fn keep_hygiene_data(sess: &Session) -> bool {
 }
 
 fn keep_ast(sess: &Session) -> bool {
-    sess.opts.debugging_opts.keep_ast ||
-    sess.opts.debugging_opts.save_analysis ||
-    sess.opts.debugging_opts.save_analysis_csv ||
-    sess.opts.debugging_opts.save_analysis_api
+    sess.opts.debugging_opts.keep_ast || ::save_analysis(sess)
 }
 
 /// The name used for source code that doesn't originate in a file
@@ -807,18 +805,18 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
         expanded_crate: krate,
         defs: resolver.definitions,
         analysis: ty::CrateAnalysis {
-            export_map: resolver.export_map,
-            access_levels: AccessLevels::default(),
+            access_levels: Rc::new(AccessLevels::default()),
             reachable: NodeSet(),
             name: crate_name.to_string(),
             glob_map: if resolver.make_glob_map { Some(resolver.glob_map) } else { None },
         },
         resolutions: Resolutions {
             freevars: resolver.freevars,
+            export_map: resolver.export_map,
             trait_map: resolver.trait_map,
             maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
         },
-        hir_forest: hir_forest
+        hir_forest: hir_forest,
     })
 }
 
@@ -888,6 +886,7 @@ macro_rules! try_with_f {
 
     let mut local_providers = ty::maps::Providers::default();
     mir::provide(&mut local_providers);
+    rustc_privacy::provide(&mut local_providers);
     typeck::provide(&mut local_providers);
     ty::provide(&mut local_providers);
 
@@ -931,9 +930,7 @@ macro_rules! try_with_f {
              || consts::check_crate(tcx));
 
         analysis.access_levels =
-            time(time_passes, "privacy checking", || {
-                rustc_privacy::check_crate(tcx, &analysis.export_map)
-            });
+            time(time_passes, "privacy checking", || rustc_privacy::check_crate(tcx));
 
         time(time_passes,
              "intrinsic checking",
@@ -1000,19 +997,15 @@ macro_rules! try_with_f {
         analysis.reachable =
             time(time_passes,
                  "reachability checking",
-                 || reachable::find_reachable(tcx, &analysis.access_levels));
+                 || reachable::find_reachable(tcx));
 
-        time(time_passes, "death checking", || {
-            middle::dead::check_crate(tcx, &analysis.access_levels);
-        });
+        time(time_passes, "death checking", || middle::dead::check_crate(tcx));
 
         time(time_passes, "unused lib feature checking", || {
-            stability::check_unused_or_stable_features(tcx, &analysis.access_levels)
+            stability::check_unused_or_stable_features(tcx)
         });
 
-        time(time_passes,
-             "lint checking",
-             || lint::check_crate(tcx, &analysis.access_levels));
+        time(time_passes, "lint checking", || lint::check_crate(tcx));
 
         // The above three passes generate errors w/o aborting
         if sess.err_count() > 0 {
index 62d75126557284b806dcdf173c991fedf7c14bbb..c90dde3a5f6e0232694ae37dec7e11e70c91b446 100644 (file)
@@ -35,6 +35,7 @@
 extern crate arena;
 extern crate getopts;
 extern crate graphviz;
+extern crate env_logger;
 extern crate libc;
 extern crate rustc;
 extern crate rustc_back;
@@ -66,6 +67,7 @@
 
 use rustc_resolve as resolve;
 use rustc_save_analysis as save;
+use rustc_save_analysis::DumpHandler;
 use rustc_trans::back::link;
 use rustc_trans::back::write::{create_target_machine, RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS};
 use rustc::dep_graph::DepGraph;
@@ -232,7 +234,7 @@ fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<PathBuf>)
 // Extract input (string or file and optional path) from matches.
 fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>)> {
     if free_matches.len() == 1 {
-        let ifile = &free_matches[0][..];
+        let ifile = &free_matches[0];
         if ifile == "-" {
             let mut src = String::new();
             io::stdin().read_to_string(&mut src).unwrap();
@@ -506,8 +508,9 @@ fn build_controller(&mut self,
                                         state.expanded_crate.unwrap(),
                                         state.analysis.unwrap(),
                                         state.crate_name.unwrap(),
-                                        state.out_dir,
-                                        save_analysis_format(state.session))
+                                        DumpHandler::new(save_analysis_format(state.session),
+                                                         state.out_dir,
+                                                         state.crate_name.unwrap()))
                 });
             };
             control.after_analysis.run_callback_on_error = true;
@@ -799,7 +802,7 @@ fn sort_lint_groups(lints: Vec<(&'static str, Vec<lint::LintId>, bool)>)
         for lint in lints {
             let name = lint.name_lower().replace("_", "-");
             println!("    {}  {:7.7}  {}",
-                     padded(&name[..]),
+                     padded(&name),
                      lint.default_level.as_str(),
                      lint.desc);
         }
@@ -837,7 +840,7 @@ fn sort_lint_groups(lints: Vec<(&'static str, Vec<lint::LintId>, bool)>)
                          .map(|x| x.to_string().replace("_", "-"))
                          .collect::<Vec<String>>()
                          .join(", ");
-            println!("    {}  {}", padded(&name[..]), desc);
+            println!("    {}  {}", padded(&name), desc);
         }
         println!("\n");
     };
@@ -944,7 +947,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
                                                  .into_iter()
                                                  .map(|x| x.opt_group)
                                                  .collect();
-    let matches = match getopts::getopts(&args[..], &all_groups) {
+    let matches = match getopts::getopts(&args, &all_groups) {
         Ok(m) => m,
         Err(f) => early_error(ErrorOutputType::default(), &f.to_string()),
     };
@@ -1083,7 +1086,7 @@ fn flush(&mut self) -> io::Result<()> {
                       format!("we would appreciate a bug report: {}", BUG_REPORT_URL)];
             for note in &xs {
                 handler.emit(&MultiSpan::new(),
-                             &note[..],
+                             &note,
                              errors::Level::Note);
             }
             if match env::var_os("RUST_BACKTRACE") {
@@ -1127,6 +1130,7 @@ pub fn diagnostics_registry() -> errors::registry::Registry {
 }
 
 pub fn main() {
+    env_logger::init().unwrap();
     let result = run(|| run_compiler(&env::args().collect::<Vec<_>>(),
                                      &mut RustcDefaultCalls,
                                      None,
index 6cd97e9559885048ac4f6905ecc257b5bf45e545..18dc504ca8aa913568bbf5fd48fae2c8ff5728db 100644 (file)
@@ -589,7 +589,7 @@ fn all_matching_node_ids<'a, 'hir>(&'a self,
                                        -> NodesMatchingUII<'a, 'hir> {
         match *self {
             ItemViaNode(node_id) => NodesMatchingDirect(Some(node_id).into_iter()),
-            ItemViaPath(ref parts) => NodesMatchingSuffix(map.nodes_matching_suffix(&parts[..])),
+            ItemViaPath(ref parts) => NodesMatchingSuffix(map.nodes_matching_suffix(&parts)),
         }
     }
 
@@ -600,7 +600,7 @@ fn to_one_node_id(self, user_option: &str, sess: &Session, map: &hir_map::Map) -
                                   user_option,
                                   self.reconstructed_input(),
                                   is_wrong_because);
-            sess.fatal(&message[..])
+            sess.fatal(&message)
         };
 
         let mut saw_node = ast::DUMMY_NODE_ID;
@@ -771,7 +771,7 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
     fn expand_err_details(r: io::Result<()>) -> io::Result<()> {
         r.map_err(|ioerr| {
             io::Error::new(io::ErrorKind::Other,
-                           &format!("graphviz::render failed: {}", ioerr)[..])
+                           format!("graphviz::render failed: {}", ioerr))
         })
     }
 }
index 9568cc3d6de0e35c8cc00fce917dc91b73e344c0..af2416f787ea4669e693fa0162bca977c6ac7ece 100644 (file)
@@ -289,7 +289,7 @@ pub fn t_pair(&self, ty1: Ty<'tcx>, ty2: Ty<'tcx>) -> Ty<'tcx> {
 
     pub fn t_param(&self, index: u32) -> Ty<'tcx> {
         let name = format!("T{}", index);
-        self.infcx.tcx.mk_param(index, Symbol::intern(&name[..]))
+        self.infcx.tcx.mk_param(index, Symbol::intern(&name))
     }
 
     pub fn re_early_bound(&self, index: u32, name: &'static str) -> &'tcx ty::Region {
index e3ee7527545042211481ecf9d36f6e228c23f0bc..7bf2efa4b885f8eef332581957e4a84f795f75c8 100644 (file)
@@ -13,6 +13,6 @@ graphviz = { path = "../libgraphviz" }
 rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 serialize = { path = "../libserialize" }
-log = { path = "../liblog" }
+log = "0.3"
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
index b67caa6750a81b59de426b5923fb98199345a6e7..5c20f65274f54ffbcd86a5323b3bb704dbe328fb 100644 (file)
@@ -99,9 +99,9 @@ pub fn read_file(sess: &Session, path: &Path) -> io::Result<Option<Vec<u8>>> {
         let rustc_version_str_len = rustc_version_str_len[0] as usize;
         let mut buffer = Vec::with_capacity(rustc_version_str_len);
         buffer.resize(rustc_version_str_len, 0);
-        file.read_exact(&mut buffer[..])?;
+        file.read_exact(&mut buffer)?;
 
-        if &buffer[..] != rustc_version().as_bytes() {
+        if buffer != rustc_version().as_bytes() {
             report_format_mismatch(sess, path, "Different compiler version");
             return Ok(None);
         }
index 4d5c0d7ba0ae1130f253a8e05113c9078ed202e3..c3c5461ff7c506a612d45564e01aa6b8a8a41938 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 test = false
 
 [dependencies]
-log = { path = "../liblog" }
+log = "0.3"
 rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
 rustc_const_eval = { path = "../librustc_const_eval" }
index 353b86820c405e3811d9f438cc5a55cd797fdeea..c4220e9a0d3dc1420022e6a7b5b2a3c1ff9c8c98 100644 (file)
@@ -88,7 +88,7 @@ fn to_camel_case(s: &str) -> String {
             } else {
                 format!("{} `{}` should have a camel case name such as `{}`", sort, name, c)
             };
-            cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m[..]);
+            cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m);
         }
     }
 }
index f0276f90f274d6d99ffa2f37b88512c1481a2b37..0ee9d4a42c7f81a26c15efdb0a37ab3eb5af6b45 100644 (file)
@@ -334,7 +334,7 @@ fn enter_lint_attrs(&mut self, _: &LateContext, attrs: &[ast::Attribute]) {
             attr.check_name("doc") &&
             match attr.meta_item_list() {
                 None => false,
-                Some(l) => attr::list_contains_name(&l[..], "hidden"),
+                Some(l) => attr::list_contains_name(&l, "hidden"),
             }
         });
         self.doc_hidden_stack.push(doc_hidden);
index abba8afd9da8699f33f5a4691fd4ede7a5477619..86bf209ccf8c8d92c5c841f684f356f869293b20 100644 (file)
@@ -146,7 +146,7 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
             ty::TyBool => return,
             ty::TyAdt(def, _) => {
                 let attrs = cx.tcx.get_attrs(def.did);
-                check_must_use(cx, &attrs[..], s.span)
+                check_must_use(cx, &attrs, s.span)
             }
             _ => false,
         };
index 42717ec289c34d019bf2b6f1a462b214f39fab59..2b945e0a3afaff2f8e7d8ffe10335be2e719bbea 100644 (file)
@@ -140,7 +140,7 @@ fn main() {
         cfg.flag(flag);
     }
 
-    for component in &components[..] {
+    for component in &components {
         let mut flag = String::from("-DLLVM_COMPONENT_");
         flag.push_str(&component.to_uppercase());
         cfg.flag(&flag);
@@ -173,7 +173,7 @@ fn main() {
     if !is_crossed {
         cmd.arg("--system-libs");
     }
-    cmd.args(&components[..]);
+    cmd.args(&components);
 
     for lib in output(&mut cmd).split_whitespace() {
         let name = if lib.starts_with("-l") {
index 6f7f03ca216b9a3c83543c1448358e278f962285..e8b906092730e5cbee6f873daa302fd57eaf46a6 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 
 [dependencies]
 flate = { path = "../libflate" }
-log = { path = "../liblog" }
+log = "0.3"
 proc_macro = { path = "../libproc_macro" }
 rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
index fcdb968dc06152ceca6c81d41140876336ab79f8..04a8b88f8a594a694537722cfda51677330f75f6 100644 (file)
@@ -669,7 +669,7 @@ pub fn find_plugin_registrar(&mut self, span: Span, name: &str)
                                   name,
                                   config::host_triple(),
                                   self.sess.opts.target_triple);
-            span_fatal!(self.sess, span, E0456, "{}", &message[..]);
+            span_fatal!(self.sess, span, E0456, "{}", &message);
         }
 
         let root = ekrate.metadata.get_root();
@@ -1058,7 +1058,7 @@ fn postprocess(&mut self, krate: &ast::Crate) {
         self.inject_allocator_crate();
         self.inject_panic_runtime(krate);
 
-        if log_enabled!(log::INFO) {
+        if log_enabled!(log::LogLevel::Info) {
             dump_crates(&self.cstore);
         }
 
index 2a67b79eaa52e6022ef699ee90fcbad76e91380c..3e9b6a6226ab507d7f7087251b31f75fa6bdf9ea 100644 (file)
@@ -88,9 +88,9 @@ pub fn provide<$lt>(providers: &mut Providers<$lt>) {
     }
     associated_item => { cdata.get_associated_item(def_id.index) }
     impl_trait_ref => { cdata.get_impl_trait(def_id.index, tcx) }
-    custom_coerce_unsized_kind => {
-        cdata.get_custom_coerce_unsized_kind(def_id.index).unwrap_or_else(|| {
-            bug!("custom_coerce_unsized_kind: `{:?}` is missing its kind", def_id);
+    coerce_unsized_info => {
+        cdata.get_coerce_unsized_info(def_id.index).unwrap_or_else(|| {
+            bug!("coerce_unsized_info: `{:?}` is missing its info", def_id);
         })
     }
     mir => {
@@ -109,6 +109,7 @@ pub fn provide<$lt>(providers: &mut Providers<$lt>) {
     typeck_tables => { cdata.item_body_tables(def_id.index, tcx) }
     closure_kind => { cdata.closure_kind(def_id.index) }
     closure_type => { cdata.closure_ty(def_id.index, tcx) }
+    inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
 }
 
 impl CrateStore for cstore::CStore {
@@ -162,12 +163,6 @@ fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>
         self.get_crate_data(did.krate).get_fn_arg_names(did.index)
     }
 
-    fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>
-    {
-        self.dep_graph.read(DepNode::MetaData(def_id));
-        self.get_crate_data(def_id.krate).get_inherent_implementations_for_type(def_id.index)
-    }
-
     fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>
     {
         if let Some(def_id) = filter {
@@ -496,12 +491,12 @@ fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>
         self.do_extern_mod_stmt_cnum(emod_id)
     }
 
-    fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                 reexports: &def::ExportMap,
+    fn encode_metadata<'a, 'tcx>(&self,
+                                 tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                  link_meta: &LinkMeta,
                                  reachable: &NodeSet) -> Vec<u8>
     {
-        encoder::encode_metadata(tcx, self, reexports, link_meta, reachable)
+        encoder::encode_metadata(tcx, self, link_meta, reachable)
     }
 
     fn metadata_encoding_version(&self) -> &[u8]
index 6ccdf8092f210491c856774bb92ea632ccaf91bc..3de1e3442c69ddb6c0ecf63f8a31df8062bbad8d 100644 (file)
@@ -643,10 +643,10 @@ pub fn get_impl_polarity(&self, id: DefIndex) -> hir::ImplPolarity {
         self.get_impl_data(id).polarity
     }
 
-    pub fn get_custom_coerce_unsized_kind(&self,
-                                          id: DefIndex)
-                                          -> Option<ty::adjustment::CustomCoerceUnsized> {
-        self.get_impl_data(id).coerce_unsized_kind
+    pub fn get_coerce_unsized_info(&self,
+                                   id: DefIndex)
+                                   -> Option<ty::adjustment::CoerceUnsizedInfo> {
+        self.get_impl_data(id).coerce_unsized_info
     }
 
     pub fn get_impl_trait(&self,
index 044ed529ef74cfa50c96f36683172d5a04999174..38d774992a55111b8d901b75a5d192730f76ba38 100644 (file)
@@ -13,7 +13,6 @@
 use schema::*;
 
 use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary};
-use rustc::hir::def;
 use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId};
 use rustc::hir::map::definitions::DefPathTable;
 use rustc::middle::dependency_format::Linkage;
@@ -48,7 +47,6 @@
 pub struct EncodeContext<'a, 'tcx: 'a> {
     opaque: opaque::Encoder<'a>,
     pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    reexports: &'a def::ExportMap,
     link_meta: &'a LinkMeta,
     cstore: &'a cstore::CStore,
     exported_symbols: &'a NodeSet,
@@ -306,7 +304,7 @@ fn encode_info_for_mod(&mut self,
         let def_id = tcx.hir.local_def_id(id);
 
         let data = ModData {
-            reexports: match self.reexports.get(&id) {
+            reexports: match tcx.export_map.get(&id) {
                 Some(exports) if *vis == hir::Public => self.lazy_seq_ref(exports),
                 _ => LazySeq::empty(),
             },
@@ -695,7 +693,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
                 let data = ImplData {
                     polarity: hir::ImplPolarity::Positive,
                     parent_impl: None,
-                    coerce_unsized_kind: None,
+                    coerce_unsized_info: None,
                     trait_ref: tcx.impl_trait_ref(def_id).map(|trait_ref| self.lazy(&trait_ref)),
                 };
 
@@ -715,13 +713,21 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
                     None
                 };
 
+                // if this is an impl of `CoerceUnsized`, create its
+                // "unsized info", else just store None
+                let coerce_unsized_info =
+                    trait_ref.and_then(|t| {
+                        if Some(t.def_id) == tcx.lang_items.coerce_unsized_trait() {
+                            Some(ty::queries::coerce_unsized_info::get(tcx, item.span, def_id))
+                        } else {
+                            None
+                        }
+                    });
+
                 let data = ImplData {
                     polarity: polarity,
                     parent_impl: parent,
-                    coerce_unsized_kind: tcx.maps.custom_coerce_unsized_kind
-                        .borrow()
-                        .get(&def_id)
-                        .cloned(),
+                    coerce_unsized_info: coerce_unsized_info,
                     trait_ref: trait_ref.map(|trait_ref| self.lazy(&trait_ref)),
                 };
 
@@ -920,14 +926,14 @@ fn encode_addl_info_for_item(&mut self, item: &hir::Item) {
                 self.encode_fields(def_id);
             }
             hir::ItemImpl(..) => {
-                for &trait_item_def_id in &self.tcx.associated_item_def_ids(def_id)[..] {
+                for &trait_item_def_id in self.tcx.associated_item_def_ids(def_id).iter() {
                     self.record(trait_item_def_id,
                                 EncodeContext::encode_info_for_impl_item,
                                 trait_item_def_id);
                 }
             }
             hir::ItemTrait(..) => {
-                for &item_def_id in &self.tcx.associated_item_def_ids(def_id)[..] {
+                for &item_def_id in self.tcx.associated_item_def_ids(def_id).iter() {
                     self.record(item_def_id,
                                 EncodeContext::encode_info_for_trait_item,
                                 item_def_id);
@@ -1423,7 +1429,6 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
 
 pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                  cstore: &cstore::CStore,
-                                 reexports: &def::ExportMap,
                                  link_meta: &LinkMeta,
                                  exported_symbols: &NodeSet)
                                  -> Vec<u8> {
@@ -1437,7 +1442,6 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         let mut ecx = EncodeContext {
             opaque: opaque::Encoder::new(&mut cursor),
             tcx: tcx,
-            reexports: reexports,
             link_meta: link_meta,
             cstore: cstore,
             exported_symbols: exported_symbols,
index a6771083fc34eaf438313e920cbc78707a569ba2..e8bc8b01652a62a5c71161b6b8e489a21ea21a6f 100644 (file)
@@ -477,15 +477,15 @@ fn find_library_crate(&mut self) -> Option<Library> {
                 Some(file) => file,
             };
             let (hash, found_kind) =
-                if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") {
+                if file.starts_with(&rlib_prefix) && file.ends_with(".rlib") {
                     (&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], CrateFlavor::Rlib)
-                } else if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rmeta") {
+                } else if file.starts_with(&rlib_prefix) && file.ends_with(".rmeta") {
                     (&file[(rlib_prefix.len())..(file.len() - ".rmeta".len())], CrateFlavor::Rmeta)
                 } else if file.starts_with(&dylib_prefix) &&
                                              file.ends_with(&dypair.1) {
                     (&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], CrateFlavor::Dylib)
                 } else {
-                    if file.starts_with(&staticlib_prefix[..]) && file.ends_with(&staticpair.1) {
+                    if file.starts_with(&staticlib_prefix) && file.ends_with(&staticpair.1) {
                         staticlibs.push(CrateMismatch {
                             path: path.to_path_buf(),
                             got: "static".to_string(),
index 4a20913d0b3fd19e16cef779f1817c42880f1a81..abb482a50ebc2621487e53fb43c3af4c5e8f7b73 100644 (file)
@@ -285,7 +285,9 @@ pub struct TraitData<'tcx> {
 pub struct ImplData<'tcx> {
     pub polarity: hir::ImplPolarity,
     pub parent_impl: Option<DefId>,
-    pub coerce_unsized_kind: Option<ty::adjustment::CustomCoerceUnsized>,
+
+    /// This is `Some` only for impls of `CoerceUnsized`.
+    pub coerce_unsized_info: Option<ty::adjustment::CoerceUnsizedInfo>,
     pub trait_ref: Option<Lazy<ty::TraitRef<'tcx>>>,
 }
 
index 531be0b6ae9f5f620528982f7edf7f829b7f7bb0..6e42e02d5109b6c5e1fd1ea83ec8d55c244ea379 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 
 [dependencies]
 graphviz = { path = "../libgraphviz" }
-log = { path = "../liblog" }
+log = "0.3"
 rustc = { path = "../librustc" }
 rustc_const_eval = { path = "../librustc_const_eval" }
 rustc_const_math = { path = "../librustc_const_math" }
index cc710e0ac3563772aa88214d498e9d12488f992d..d2560c2f8203f0557957ea0bbb968fbaa127bba3 100644 (file)
@@ -9,10 +9,10 @@ path = "lib.rs"
 crate-type = ["dylib"]
 
 [dependencies]
-log = { path = "../liblog" }
+log = "0.3"
 rustc = { path = "../librustc" }
 rustc_const_eval = { path = "../librustc_const_eval" }
 rustc_const_math = { path = "../librustc_const_math" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
-rustc_errors = { path = "../librustc_errors" }
\ No newline at end of file
+rustc_errors = { path = "../librustc_errors" }
index 1bfc445fca98d72ca4f7c8f03a92b63dda875fc1..efe9963cecc7300a955394726544c1af4130cc4a 100644 (file)
@@ -126,19 +126,19 @@ fn dylink_registrar(&mut self,
             // inside this crate, so continue would spew "macro undefined"
             // errors
             Err(err) => {
-                self.sess.span_fatal(span, &err[..])
+                self.sess.span_fatal(span, &err)
             }
         };
 
         unsafe {
             let registrar =
-                match lib.symbol(&symbol[..]) {
+                match lib.symbol(&symbol) {
                     Ok(registrar) => {
                         mem::transmute::<*mut u8,PluginRegistrarFun>(registrar)
                     }
                     // again fatal if we can't register macros
                     Err(err) => {
-                        self.sess.span_fatal(span, &err[..])
+                        self.sess.span_fatal(span, &err)
                     }
                 };
 
index e32ec25a7e8f77857f40bf5242a5529ad17096e2..64821f5d44bf495d4126bc25516121db4720d933 100644 (file)
@@ -17,6 +17,7 @@
       html_root_url = "https://doc.rust-lang.org/nightly/")]
 #![deny(warnings)]
 
+#![cfg_attr(stage0, feature(field_init_shorthand))]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #[macro_use] extern crate syntax;
 extern crate syntax_pos;
 
-use rustc::dep_graph::DepNode;
 use rustc::hir::{self, PatKind};
-use rustc::hir::def::{self, Def};
-use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
+use rustc::hir::def::Def;
+use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId};
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::hir::itemlikevisit::DeepVisitor;
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
 use rustc::middle::privacy::{AccessLevel, AccessLevels};
 use rustc::ty::{self, TyCtxt, Ty, TypeFoldable};
 use rustc::ty::fold::TypeVisitor;
+use rustc::ty::maps::Providers;
 use rustc::util::nodemap::NodeSet;
 use syntax::ast;
-use syntax_pos::Span;
+use syntax_pos::{DUMMY_SP, Span};
 
 use std::cmp;
 use std::mem::replace;
+use std::rc::Rc;
 
 pub mod diagnostics;
 
@@ -71,7 +73,6 @@ fn visit_vis(&mut self, vis: &'tcx hir::Visibility) {
 
 struct EmbargoVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    export_map: &'a def::ExportMap,
 
     // Accessibility levels for reachable nodes
     access_levels: AccessLevels,
@@ -324,7 +325,7 @@ fn visit_mod(&mut self, m: &'tcx hir::Mod, _sp: Span, id: ast::NodeId) {
         // This code is here instead of in visit_item so that the
         // crate module gets processed as well.
         if self.prev_level.is_some() {
-            if let Some(exports) = self.export_map.get(&id) {
+            if let Some(exports) = self.tcx.export_map.get(&id) {
                 for export in exports {
                     if let Some(node_id) = self.tcx.hir.as_local_node_id(export.def.def_id()) {
                         self.update(node_id, Some(AccessLevel::Exported));
@@ -1204,10 +1205,23 @@ fn visit_expr(&mut self, _: &'tcx hir::Expr) {}
     fn visit_pat(&mut self, _: &'tcx hir::Pat) {}
 }
 
-pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                             export_map: &def::ExportMap)
-                             -> AccessLevels {
-    let _task = tcx.dep_graph.in_task(DepNode::Privacy);
+pub fn provide(providers: &mut Providers) {
+    *providers = Providers {
+        privacy_access_levels,
+        ..*providers
+    };
+}
+
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Rc<AccessLevels> {
+    tcx.dep_graph.with_ignore(|| { // FIXME
+        ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE)
+    })
+}
+
+fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                   krate: CrateNum)
+                                   -> Rc<AccessLevels> {
+    assert_eq!(krate, LOCAL_CRATE);
 
     let krate = tcx.hir.krate();
 
@@ -1226,7 +1240,6 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // items which are reachable from external crates based on visibility.
     let mut visitor = EmbargoVisitor {
         tcx: tcx,
-        export_map: export_map,
         access_levels: Default::default(),
         prev_level: Some(AccessLevel::Public),
         changed: false,
@@ -1270,7 +1283,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor));
     }
 
-    visitor.access_levels
+    Rc::new(visitor.access_levels)
 }
 
 __build_diagnostic_array! { librustc_privacy, DIAGNOSTICS }
index 5ce4c74e735fd6fb11015095554c5777730d2878..0968ea31b754f9e7b2d0e47f5ccd871156483204 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 test = false
 
 [dependencies]
-log = { path = "../liblog" }
+log = "0.3"
 syntax = { path = "../libsyntax" }
 rustc = { path = "../librustc" }
 arena = { path = "../libarena" }
index c33d5b9b6e16bb14bb4980039c00deac67c22c5c..86e0d0039d1a7c4a517308a66177409be5516995 100644 (file)
@@ -539,7 +539,7 @@ fn legacy_import_macro(&mut self,
                            binding: &'a NameBinding<'a>,
                            span: Span,
                            allow_shadowing: bool) {
-        if self.builtin_macros.insert(name, binding).is_some() && !allow_shadowing {
+        if self.global_macros.insert(name, binding).is_some() && !allow_shadowing {
             let msg = format!("`{}` is already in scope", name);
             let note =
                 "macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)";
index 8f6b1b8971e5b9ffb1967dbb72629227735966fe..2c2babf0a66535724b080ec1d8913c210f98eacd 100644 (file)
@@ -890,19 +890,23 @@ fn foo(f: i32, g: i32) {} // ok!
 E0422: r##"
 You are trying to use an identifier that is either undefined or not a struct.
 Erroneous code example:
-``` compile_fail,E0422
+
+```compile_fail,E0422
 fn main () {
     let x = Foo { x: 1, y: 2 };
 }
 ```
+
 In this case, `Foo` is undefined, so it inherently isn't anything, and
 definitely not a struct.
+
 ```compile_fail
 fn main () {
     let foo = 1;
     let x = foo { x: 1, y: 2 };
 }
 ```
+
 In this case, `foo` is defined, but is not a struct, so Rust can't use it as
 one.
 "##,
index f832e0f9a4811146e7f83cb2e57b1396b29b2de2..0466e76475da3d1f05069ec0b24edccf45500de3 100644 (file)
@@ -75,7 +75,7 @@
 use std::rc::Rc;
 
 use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver};
-use macros::{InvocationData, LegacyBinding, LegacyScope};
+use macros::{InvocationData, LegacyBinding, LegacyScope, MacroBinding};
 
 // NB: This module needs to be declared first so diagnostics are
 // registered before they are used.
@@ -922,6 +922,10 @@ fn is_trait(&self) -> bool {
     fn is_local(&self) -> bool {
         self.normal_ancestor_id.is_local()
     }
+
+    fn nearest_item_scope(&'a self) -> Module<'a> {
+        if self.is_trait() { self.parent.unwrap() } else { self }
+    }
 }
 
 impl<'a> fmt::Debug for ModuleData<'a> {
@@ -1174,7 +1178,7 @@ pub struct Resolver<'a> {
 
     crate_loader: &'a mut CrateLoader,
     macro_names: FxHashSet<Name>,
-    builtin_macros: FxHashMap<Name, &'a NameBinding<'a>>,
+    global_macros: FxHashMap<Name, &'a NameBinding<'a>>,
     lexical_macro_resolutions: Vec<(Name, &'a Cell<LegacyScope<'a>>)>,
     macro_map: FxHashMap<DefId, Rc<SyntaxExtension>>,
     macro_defs: FxHashMap<Mark, DefId>,
@@ -1372,7 +1376,7 @@ pub fn new(session: &'a Session,
 
             crate_loader: crate_loader,
             macro_names: FxHashSet(),
-            builtin_macros: FxHashMap(),
+            global_macros: FxHashMap(),
             lexical_macro_resolutions: Vec::new(),
             macro_map: FxHashMap(),
             macro_exports: Vec::new(),
@@ -2429,9 +2433,9 @@ fn resolve_qpath_anywhere(&mut self,
                 };
             }
         }
-        let is_builtin = self.builtin_macros.get(&path[0].name).cloned()
+        let is_global = self.global_macros.get(&path[0].name).cloned()
             .map(|binding| binding.get_macro(self).kind() == MacroKind::Bang).unwrap_or(false);
-        if primary_ns != MacroNS && (is_builtin || self.macro_names.contains(&path[0].name)) {
+        if primary_ns != MacroNS && (is_global || self.macro_names.contains(&path[0].name)) {
             // Return some dummy definition, it's enough for error reporting.
             return Some(
                 PathResolution::new(Def::Macro(DefId::local(CRATE_DEF_INDEX), MacroKind::Bang))
@@ -2566,6 +2570,7 @@ fn resolve_path(&mut self,
                 self.resolve_ident_in_module(module, ident, ns, false, record_used)
             } else if opt_ns == Some(MacroNS) {
                 self.resolve_lexical_macro_path_segment(ident, ns, record_used)
+                    .map(MacroBinding::binding)
             } else {
                 match self.resolve_ident_in_lexical_scope(ident, ns, record_used) {
                     Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
@@ -3223,7 +3228,7 @@ fn report_errors(&mut self) {
             };
             let msg1 = format!("`{}` could refer to the name {} here", name, participle(b1));
             let msg2 = format!("`{}` could also refer to the name {} here", name, participle(b2));
-            let note = if !lexical && b1.is_glob_import() {
+            let note = if b1.expansion == Mark::root() || !lexical && b1.is_glob_import() {
                 format!("consider adding an explicit import of `{}` to disambiguate", name)
             } else if let Def::Macro(..) = b1.def() {
                 format!("macro-expanded {} do not shadow",
@@ -3243,11 +3248,15 @@ fn report_errors(&mut self) {
                 let msg = format!("`{}` is ambiguous", name);
                 self.session.add_lint(lint::builtin::LEGACY_IMPORTS, id, span, msg);
             } else {
-                self.session.struct_span_err(span, &format!("`{}` is ambiguous", name))
-                    .span_note(b1.span, &msg1)
-                    .span_note(b2.span, &msg2)
-                    .note(&note)
-                    .emit();
+                let mut err =
+                    self.session.struct_span_err(span, &format!("`{}` is ambiguous", name));
+                err.span_note(b1.span, &msg1);
+                match b2.def() {
+                    Def::Macro(..) if b2.span == DUMMY_SP =>
+                        err.note(&format!("`{}` is also a builtin macro", name)),
+                    _ => err.span_note(b2.span, &msg2),
+                };
+                err.note(&note).emit();
             }
         }
 
@@ -3361,14 +3370,13 @@ fn check_proc_macro_attrs(&mut self, attrs: &[ast::Attribute]) {
         if self.proc_macro_enabled { return; }
 
         for attr in attrs {
-            let name = unwrap_or!(attr.name(), continue);
-            let maybe_binding = self.builtin_macros.get(&name).cloned().or_else(|| {
-                let ident = Ident::with_empty_ctxt(name);
-                self.resolve_lexical_macro_path_segment(ident, MacroNS, None).ok()
-            });
-
-            if let Some(binding) = maybe_binding {
-                if let SyntaxExtension::AttrProcMacro(..) = *binding.get_macro(self) {
+            if attr.path.segments.len() > 1 {
+                continue
+            }
+            let ident = attr.path.segments[0].identifier;
+            let result = self.resolve_lexical_macro_path_segment(ident, MacroNS, None);
+            if let Ok(binding) = result {
+                if let SyntaxExtension::AttrProcMacro(..) = *binding.binding().get_macro(self) {
                     attr::mark_known(attr);
 
                     let msg = "attribute procedural macros are experimental";
@@ -3376,7 +3384,7 @@ fn check_proc_macro_attrs(&mut self, attrs: &[ast::Attribute]) {
 
                     feature_err(&self.session.parse_sess, feature,
                                 attr.span, GateIssue::Language, msg)
-                        .span_note(binding.span, "procedural macro imported here")
+                        .span_note(binding.span(), "procedural macro imported here")
                         .emit();
                 }
             }
index 99fc1c142f6815fd2cc097699e3fd0be0e02cd2b..05f30f039c8f0649dd3eaf3bab6fc28c909219ee 100644 (file)
@@ -81,11 +81,29 @@ pub struct LegacyBinding<'a> {
     pub span: Span,
 }
 
+#[derive(Copy, Clone)]
 pub enum MacroBinding<'a> {
     Legacy(&'a LegacyBinding<'a>),
+    Global(&'a NameBinding<'a>),
     Modern(&'a NameBinding<'a>),
 }
 
+impl<'a> MacroBinding<'a> {
+    pub fn span(self) -> Span {
+        match self {
+            MacroBinding::Legacy(binding) => binding.span,
+            MacroBinding::Global(binding) | MacroBinding::Modern(binding) => binding.span,
+        }
+    }
+
+    pub fn binding(self) -> &'a NameBinding<'a> {
+        match self {
+            MacroBinding::Global(binding) | MacroBinding::Modern(binding) => binding,
+            MacroBinding::Legacy(_) => panic!("unexpected MacroBinding::Legacy"),
+        }
+    }
+}
+
 impl<'a> base::Resolver for Resolver<'a> {
     fn next_node_id(&mut self) -> ast::NodeId {
         self.session.next_node_id()
@@ -154,7 +172,6 @@ fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion, derives: &[Mark
             expansion: mark,
         };
         expansion.visit_with(&mut visitor);
-        self.current_module.unresolved_invocations.borrow_mut().remove(&mark);
         invocation.expansion.set(visitor.legacy_scope);
     }
 
@@ -171,7 +188,7 @@ fn add_builtin(&mut self, ident: ast::Ident, ext: Rc<SyntaxExtension>) {
             vis: ty::Visibility::Invisible,
             expansion: Mark::root(),
         });
-        self.builtin_macros.insert(ident.name, binding);
+        self.global_macros.insert(ident.name, binding);
     }
 
     fn resolve_imports(&mut self) {
@@ -189,7 +206,7 @@ fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>)
                 attr::mark_known(&attrs[i]);
             }
 
-            match self.builtin_macros.get(&name).cloned() {
+            match self.global_macros.get(&name).cloned() {
                 Some(binding) => match *binding.get_macro(self) {
                     MultiModifier(..) | MultiDecorator(..) | SyntaxExtension::AttrProcMacro(..) => {
                         return Some(attrs.remove(i))
@@ -221,7 +238,7 @@ fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>)
                     }
                     let trait_name = traits[j].segments[0].identifier.name;
                     let legacy_name = Symbol::intern(&format!("derive_{}", trait_name));
-                    if !self.builtin_macros.contains_key(&legacy_name) {
+                    if !self.global_macros.contains_key(&legacy_name) {
                         continue
                     }
                     let span = traits.remove(j).span;
@@ -372,27 +389,27 @@ fn resolve_macro_to_def(&mut self, scope: Mark, path: &ast::Path, kind: MacroKin
                     Err(Determinacy::Determined)
                 },
             };
-            self.current_module.macro_resolutions.borrow_mut()
+            self.current_module.nearest_item_scope().macro_resolutions.borrow_mut()
                 .push((path.into_boxed_slice(), span));
             return def;
         }
 
         let name = path[0].name;
-        let result = match self.resolve_legacy_scope(&invocation.legacy_scope, name, false) {
-            Some(MacroBinding::Legacy(binding)) => Ok(Def::Macro(binding.def_id, MacroKind::Bang)),
-            Some(MacroBinding::Modern(binding)) => Ok(binding.def_ignoring_ambiguity()),
-            None => match self.resolve_lexical_macro_path_segment(path[0], MacroNS, None) {
-                Ok(binding) => Ok(binding.def_ignoring_ambiguity()),
-                Err(Determinacy::Undetermined) if !force =>
-                    return Err(Determinacy::Undetermined),
+        let legacy_resolution = self.resolve_legacy_scope(&invocation.legacy_scope, name, false);
+        let result = if let Some(MacroBinding::Legacy(binding)) = legacy_resolution {
+            Ok(Def::Macro(binding.def_id, MacroKind::Bang))
+        } else {
+            match self.resolve_lexical_macro_path_segment(path[0], MacroNS, None) {
+                Ok(binding) => Ok(binding.binding().def_ignoring_ambiguity()),
+                Err(Determinacy::Undetermined) if !force => return Err(Determinacy::Undetermined),
                 Err(_) => {
                     self.found_unresolved_macro = true;
                     Err(Determinacy::Determined)
                 }
-            },
+            }
         };
 
-        self.current_module.legacy_macro_resolutions.borrow_mut()
+        self.current_module.nearest_item_scope().legacy_macro_resolutions.borrow_mut()
             .push((scope, path[0], span, kind));
 
         result
@@ -403,42 +420,56 @@ pub fn resolve_lexical_macro_path_segment(&mut self,
                                               ident: Ident,
                                               ns: Namespace,
                                               record_used: Option<Span>)
-                                              -> Result<&'a NameBinding<'a>, Determinacy> {
-        let mut module = self.current_module;
-        let mut potential_expanded_shadower: Option<&NameBinding> = None;
+                                              -> Result<MacroBinding<'a>, Determinacy> {
+        let mut module = Some(self.current_module);
+        let mut potential_illegal_shadower = Err(Determinacy::Determined);
+        let determinacy =
+            if record_used.is_some() { Determinacy::Determined } else { Determinacy::Undetermined };
         loop {
-            // Since expanded macros may not shadow the lexical scope (enforced below),
-            // we can ignore unresolved invocations (indicated by the penultimate argument).
-            match self.resolve_ident_in_module(module, ident, ns, true, record_used) {
+            let result = if let Some(module) = module {
+                // Since expanded macros may not shadow the lexical scope and
+                // globs may not shadow global macros (both enforced below),
+                // we resolve with restricted shadowing (indicated by the penultimate argument).
+                self.resolve_ident_in_module(module, ident, ns, true, record_used)
+                    .map(MacroBinding::Modern)
+            } else {
+                self.global_macros.get(&ident.name).cloned().ok_or(determinacy)
+                    .map(MacroBinding::Global)
+            };
+
+            match result.map(MacroBinding::binding) {
                 Ok(binding) => {
                     let span = match record_used {
                         Some(span) => span,
-                        None => return Ok(binding),
+                        None => return result,
                     };
-                    match potential_expanded_shadower {
-                        Some(shadower) if shadower.def() != binding.def() => {
+                    if let Ok(MacroBinding::Modern(shadower)) = potential_illegal_shadower {
+                        if shadower.def() != binding.def() {
                             let name = ident.name;
                             self.ambiguity_errors.push(AmbiguityError {
                                 span: span, name: name, b1: shadower, b2: binding, lexical: true,
                                 legacy: false,
                             });
-                            return Ok(shadower);
+                            return potential_illegal_shadower;
                         }
-                        _ if binding.expansion == Mark::root() => return Ok(binding),
-                        _ => potential_expanded_shadower = Some(binding),
+                    }
+                    if binding.expansion != Mark::root() ||
+                       (binding.is_glob_import() && module.unwrap().def().is_some()) {
+                        potential_illegal_shadower = result;
+                    } else {
+                        return result;
                     }
                 },
                 Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined),
                 Err(Determinacy::Determined) => {}
             }
 
-            match module.kind {
-                ModuleKind::Block(..) => module = module.parent.unwrap(),
-                ModuleKind::Def(..) => return match potential_expanded_shadower {
-                    Some(binding) => Ok(binding),
-                    None if record_used.is_some() => Err(Determinacy::Determined),
-                    None => Err(Determinacy::Undetermined),
+            module = match module {
+                Some(module) => match module.kind {
+                    ModuleKind::Block(..) => module.parent,
+                    ModuleKind::Def(..) => None,
                 },
+                None => return potential_illegal_shadower,
             }
         }
     }
@@ -488,11 +519,11 @@ pub fn resolve_legacy_scope(&mut self,
 
         let binding = if let Some(binding) = binding {
             MacroBinding::Legacy(binding)
-        } else if let Some(binding) = self.builtin_macros.get(&name).cloned() {
+        } else if let Some(binding) = self.global_macros.get(&name).cloned() {
             if !self.use_extern_macros {
                 self.record_use(Ident::with_empty_ctxt(name), MacroNS, binding, DUMMY_SP);
             }
-            MacroBinding::Modern(binding)
+            MacroBinding::Global(binding)
         } else {
             return None;
         };
@@ -524,21 +555,15 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
             let legacy_resolution = self.resolve_legacy_scope(legacy_scope, ident.name, true);
             let resolution = self.resolve_lexical_macro_path_segment(ident, MacroNS, Some(span));
             match (legacy_resolution, resolution) {
-                (Some(legacy_resolution), Ok(resolution)) => {
-                    let (legacy_span, participle) = match legacy_resolution {
-                        MacroBinding::Modern(binding)
-                            if binding.def() == resolution.def() => continue,
-                        MacroBinding::Modern(binding) => (binding.span, "imported"),
-                        MacroBinding::Legacy(binding) => (binding.span, "defined"),
-                    };
-                    let msg1 = format!("`{}` could refer to the macro {} here", ident, participle);
+                (Some(MacroBinding::Legacy(legacy_binding)), Ok(MacroBinding::Modern(binding))) => {
+                    let msg1 = format!("`{}` could refer to the macro defined here", ident);
                     let msg2 = format!("`{}` could also refer to the macro imported here", ident);
                     self.session.struct_span_err(span, &format!("`{}` is ambiguous", ident))
-                        .span_note(legacy_span, &msg1)
-                        .span_note(resolution.span, &msg2)
+                        .span_note(legacy_binding.span, &msg1)
+                        .span_note(binding.span, &msg2)
                         .emit();
                 },
-                (Some(MacroBinding::Modern(binding)), Err(_)) => {
+                (Some(MacroBinding::Global(binding)), Ok(MacroBinding::Global(_))) => {
                     self.record_use(ident, MacroNS, binding, span);
                     self.err_if_macro_use_proc_macro(ident.name, span, binding);
                 },
@@ -567,11 +592,11 @@ fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
             find_best_match_for_name(self.macro_names.iter(), name, None)
         } else {
             None
-        // Then check builtin macros.
+        // Then check global macros.
         }.or_else(|| {
             // FIXME: get_macro needs an &mut Resolver, can we do it without cloning?
-            let builtin_macros = self.builtin_macros.clone();
-            let names = builtin_macros.iter().filter_map(|(name, binding)| {
+            let global_macros = self.global_macros.clone();
+            let names = global_macros.iter().filter_map(|(name, binding)| {
                 if binding.get_macro(self).kind() == kind {
                     Some(name)
                 } else {
index 2f4ac12cd7363bf2604c8d738206947802300f27..43654c8ce6f6875b13aa5009fabec257024ae784 100644 (file)
@@ -145,7 +145,7 @@ pub fn resolve_ident_in_module(&mut self,
                                    module: Module<'a>,
                                    ident: Ident,
                                    ns: Namespace,
-                                   ignore_unresolved_invocations: bool,
+                                   restricted_shadowing: bool,
                                    record_used: Option<Span>)
                                    -> Result<&'a NameBinding<'a>, Determinacy> {
         self.populate_module_if_necessary(module);
@@ -158,9 +158,8 @@ pub fn resolve_ident_in_module(&mut self,
             if let Some(binding) = resolution.binding {
                 if let Some(shadowed_glob) = resolution.shadows_glob {
                     let name = ident.name;
-                    // If we ignore unresolved invocations, we must forbid
-                    // expanded shadowing to avoid time travel.
-                    if ignore_unresolved_invocations &&
+                    // Forbid expanded shadowing to avoid time travel.
+                    if restricted_shadowing &&
                        binding.expansion != Mark::root() &&
                        ns != MacroNS && // In MacroNS, `try_define` always forbids this shadowing
                        binding.def() != shadowed_glob.def() {
@@ -215,7 +214,7 @@ pub fn resolve_ident_in_module(&mut self,
         }
 
         let no_unresolved_invocations =
-            ignore_unresolved_invocations || module.unresolved_invocations.borrow().is_empty();
+            restricted_shadowing || module.unresolved_invocations.borrow().is_empty();
         match resolution.binding {
             // In `MacroNS`, expanded bindings do not shadow (enforced in `try_define`).
             Some(binding) if no_unresolved_invocations || ns == MacroNS =>
@@ -225,6 +224,9 @@ pub fn resolve_ident_in_module(&mut self,
         }
 
         // Check if the globs are determined
+        if restricted_shadowing && module.def().is_some() {
+            return Err(Determined);
+        }
         for directive in module.globs.borrow().iter() {
             if self.is_accessible(directive.vis.get()) {
                 if let Some(module) = directive.imported_module.get() {
index 06c5150fd13ade909458604075f3dcacd69a2b9c..07a5c266fc026798a23251015f1ed319788da744 100644 (file)
@@ -9,7 +9,7 @@ path = "lib.rs"
 crate-type = ["dylib"]
 
 [dependencies]
-log = { path = "../liblog" }
+log = "0.3"
 rustc = { path = "../librustc" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
index 59340ae87ee5da6e607b7e48ce976efd988b9228..4bab135ff12f70db54b2a65ef5007de61d07dcea 100644 (file)
@@ -423,7 +423,7 @@ fn make_values_str(pairs: &[(&'static str, &str)]) -> String {
 
     let strs = pairs.map(|(f, v)| format!(",{},\"{}\"", f, escape(String::from(v))));
     strs.fold(String::new(), |mut s, ss| {
-        s.push_str(&ss[..]);
+        s.push_str(&ss);
         s
     })
 }
index acc877d3947758fb20a222e51c2f6a896fe5c3e4..2d1e12bf0a10dfd379e4d90488a6f915a9059d9e 100644 (file)
 use data::{self, VariableKind};
 use dump::Dump;
 
-pub struct JsonDumper<'b, W: Write + 'b> {
-    output: &'b mut W,
+pub struct JsonDumper<O: DumpOutput> {
     result: Analysis,
+    output: O,
 }
 
-impl<'b, W: Write> JsonDumper<'b, W> {
-    pub fn new(writer: &'b mut W) -> JsonDumper<'b, W> {
-        JsonDumper { output: writer, result: Analysis::new() }
-    }
+pub trait DumpOutput {
+    fn dump(&mut self, result: &Analysis);
 }
 
-impl<'b, W: Write> Drop for JsonDumper<'b, W> {
-    fn drop(&mut self) {
-        if let Err(_) = write!(self.output, "{}", as_json(&self.result)) {
+pub struct WriteOutput<'b, W: Write + 'b> {
+    output: &'b mut W,
+}
+
+impl<'b, W: Write> DumpOutput for WriteOutput<'b, W> {
+    fn dump(&mut self, result: &Analysis) {
+        if let Err(_) = write!(self.output, "{}", as_json(&result)) {
             error!("Error writing output");
         }
     }
 }
 
+pub struct CallbackOutput<'b> {
+    callback: &'b mut FnMut(&Analysis),
+}
+
+impl<'b> DumpOutput for CallbackOutput<'b> {
+    fn dump(&mut self, result: &Analysis) {
+        (self.callback)(result)
+    }
+}
+
+impl<'b, W: Write> JsonDumper<WriteOutput<'b, W>> {
+    pub fn new(writer: &'b mut W) -> JsonDumper<WriteOutput<'b, W>> {
+        JsonDumper { output: WriteOutput { output: writer }, result: Analysis::new() }
+    }
+}
+
+impl<'b> JsonDumper<CallbackOutput<'b>> {
+    pub fn with_callback(callback: &'b mut FnMut(&Analysis)) -> JsonDumper<CallbackOutput<'b>> {
+        JsonDumper { output: CallbackOutput { callback: callback }, result: Analysis::new() }
+    }
+}
+
+impl<O: DumpOutput> Drop for JsonDumper<O> {
+    fn drop(&mut self) {
+        self.output.dump(&self.result);
+    }
+}
+
 macro_rules! impl_fn {
     ($fn_name: ident, $data_type: ident, $bucket: ident) => {
         fn $fn_name(&mut self, data: $data_type) {
@@ -49,7 +79,7 @@ fn $fn_name(&mut self, data: $data_type) {
     }
 }
 
-impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> {
+impl<'b, O: DumpOutput + 'b> Dump for JsonDumper<O> {
     fn crate_prelude(&mut self, data: CratePreludeData) {
         self.result.prelude = Some(data)
     }
index 5e2b1df9d34f89451f28737760f2f4648dc487bc..e5c04f6b61ec297643bb9cd1726fb33bcff8b115 100644 (file)
@@ -48,6 +48,7 @@
 use rustc::hir::map::Node;
 use rustc::hir::def_id::DefId;
 use rustc::session::config::CrateType::CrateTypeExecutable;
+use rustc::session::Session;
 use rustc::ty::{self, TyCtxt};
 
 use std::env;
@@ -866,55 +867,131 @@ fn extension(&self) -> &'static str {
     }
 }
 
-pub fn process_crate<'l, 'tcx>(tcx: TyCtxt<'l, 'tcx, 'tcx>,
-                               krate: &ast::Crate,
-                               analysis: &'l ty::CrateAnalysis,
-                               cratename: &str,
-                               odir: Option<&Path>,
-                               format: Format) {
-    let _ignore = tcx.dep_graph.in_ignore();
+/// Defines what to do with the results of saving the analysis.
+pub trait SaveHandler {
+    fn save<'l, 'tcx>(&mut self,
+                      save_ctxt: SaveContext<'l, 'tcx>,
+                      krate: &ast::Crate,
+                      cratename: &str);
+}
 
-    assert!(analysis.glob_map.is_some());
+/// Dump the save-analysis results to a file.
+pub struct DumpHandler<'a> {
+    format: Format,
+    odir: Option<&'a Path>,
+    cratename: String
+}
 
-    info!("Dumping crate {}", cratename);
+impl<'a> DumpHandler<'a> {
+    pub fn new(format: Format, odir: Option<&'a Path>, cratename: &str) -> DumpHandler<'a> {
+        DumpHandler {
+            format: format,
+            odir: odir,
+            cratename: cratename.to_owned()
+        }
+    }
 
-    // find a path to dump our data to
-    let mut root_path = match env::var_os("RUST_SAVE_ANALYSIS_FOLDER") {
-        Some(val) => PathBuf::from(val),
-        None => match odir {
-            Some(val) => val.join("save-analysis"),
-            None => PathBuf::from("save-analysis-temp"),
-        },
-    };
+    fn output_file(&self, sess: &Session) -> File {
+        let mut root_path = match env::var_os("RUST_SAVE_ANALYSIS_FOLDER") {
+            Some(val) => PathBuf::from(val),
+            None => match self.odir {
+                Some(val) => val.join("save-analysis"),
+                None => PathBuf::from("save-analysis-temp"),
+            },
+        };
 
-    if let Err(e) = std::fs::create_dir_all(&root_path) {
-        tcx.sess.err(&format!("Could not create directory {}: {}",
-                              root_path.display(),
-                              e));
+        if let Err(e) = std::fs::create_dir_all(&root_path) {
+            error!("Could not create directory {}: {}", root_path.display(), e);
+        }
+
+        {
+            let disp = root_path.display();
+            info!("Writing output to {}", disp);
+        }
+
+        let executable = sess.crate_types.borrow().iter().any(|ct| *ct == CrateTypeExecutable);
+        let mut out_name = if executable {
+            "".to_owned()
+        } else {
+            "lib".to_owned()
+        };
+        out_name.push_str(&self.cratename);
+        out_name.push_str(&sess.opts.cg.extra_filename);
+        out_name.push_str(self.format.extension());
+        root_path.push(&out_name);
+        let output_file = File::create(&root_path).unwrap_or_else(|e| {
+            let disp = root_path.display();
+            sess.fatal(&format!("Could not open {}: {}", disp, e));
+        });
+        root_path.pop();
+        output_file
     }
+}
+
+impl<'a> SaveHandler for DumpHandler<'a> {
+    fn save<'l, 'tcx>(&mut self,
+                      save_ctxt: SaveContext<'l, 'tcx>,
+                      krate: &ast::Crate,
+                      cratename: &str) {
+        macro_rules! dump {
+            ($new_dumper: expr) => {{
+                let mut dumper = $new_dumper;
+                let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper);
+
+                visitor.dump_crate_info(cratename, krate);
+                visit::walk_crate(&mut visitor, krate);
+            }}
+        }
+
+        let output = &mut self.output_file(&save_ctxt.tcx.sess);
 
-    {
-        let disp = root_path.display();
-        info!("Writing output to {}", disp);
+        match self.format {
+            Format::Csv => dump!(CsvDumper::new(output)),
+            Format::Json => dump!(JsonDumper::new(output)),
+            Format::JsonApi => dump!(JsonApiDumper::new(output)),
+        }
     }
+}
 
-    // Create output file.
-    let executable = tcx.sess.crate_types.borrow().iter().any(|ct| *ct == CrateTypeExecutable);
-    let mut out_name = if executable {
-        "".to_owned()
-    } else {
-        "lib".to_owned()
-    };
-    out_name.push_str(&cratename);
-    out_name.push_str(&tcx.sess.opts.cg.extra_filename);
-    out_name.push_str(format.extension());
-    root_path.push(&out_name);
-    let mut output_file = File::create(&root_path).unwrap_or_else(|e| {
-        let disp = root_path.display();
-        tcx.sess.fatal(&format!("Could not open {}: {}", disp, e));
-    });
-    root_path.pop();
-    let output = &mut output_file;
+/// Call a callback with the results of save-analysis.
+pub struct CallbackHandler<'b> {
+    pub callback: &'b mut FnMut(&rls_data::Analysis),
+}
+
+impl<'b> SaveHandler for CallbackHandler<'b> {
+    fn save<'l, 'tcx>(&mut self,
+                      save_ctxt: SaveContext<'l, 'tcx>,
+                      krate: &ast::Crate,
+                      cratename: &str) {
+        macro_rules! dump {
+            ($new_dumper: expr) => {{
+                let mut dumper = $new_dumper;
+                let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper);
+
+                visitor.dump_crate_info(cratename, krate);
+                visit::walk_crate(&mut visitor, krate);
+            }}
+        }
+
+        // We're using the JsonDumper here because it has the format of the
+        // save-analysis results that we will pass to the callback. IOW, we are
+        // using the JsonDumper to collect the save-analysis results, but not
+        // actually to dump them to a file. This is all a bit convoluted and
+        // there is certainly a simpler design here trying to get out (FIXME).
+        dump!(JsonDumper::with_callback(self.callback))
+    }
+}
+
+pub fn process_crate<'l, 'tcx, H: SaveHandler>(tcx: TyCtxt<'l, 'tcx, 'tcx>,
+                                               krate: &ast::Crate,
+                                               analysis: &'l ty::CrateAnalysis,
+                                               cratename: &str,
+                                               mut handler: H) {
+    let _ignore = tcx.dep_graph.in_ignore();
+
+    assert!(analysis.glob_map.is_some());
+
+    info!("Dumping crate {}", cratename);
 
     let save_ctxt = SaveContext {
         tcx: tcx,
@@ -923,21 +1000,7 @@ pub fn process_crate<'l, 'tcx>(tcx: TyCtxt<'l, 'tcx, 'tcx>,
         span_utils: SpanUtils::new(&tcx.sess),
     };
 
-    macro_rules! dump {
-        ($new_dumper: expr) => {{
-            let mut dumper = $new_dumper;
-            let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper);
-
-            visitor.dump_crate_info(cratename, krate);
-            visit::walk_crate(&mut visitor, krate);
-        }}
-    }
-
-    match format {
-        Format::Csv => dump!(CsvDumper::new(output)),
-        Format::Json => dump!(JsonDumper::new(output)),
-        Format::JsonApi => dump!(JsonApiDumper::new(output)),
-    }
+    handler.save(save_ctxt, krate, cratename)
 }
 
 // Utility functions for the module.
index b5c67ad998b69e4ea448eebe5cca0e99078b42f8..07dcb2fc29dc66d4f7db46140fdefd859a2238d6 100644 (file)
@@ -11,7 +11,7 @@ test = false
 
 [dependencies]
 flate = { path = "../libflate" }
-log = { path = "../liblog" }
+log = "0.3"
 rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
 rustc_bitflags = { path = "../librustc_bitflags" }
index 27a19d211c2908ef4f5910aa1f4915859d28cede..1530708b4b8882c6361608a1936496ae90769e93 100644 (file)
@@ -369,7 +369,7 @@ fn unadjusted<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             match sig.inputs().last().unwrap().sty {
                 ty::TyTuple(ref tupled_arguments, _) => {
                     inputs = &sig.inputs()[0..sig.inputs().len() - 1];
-                    &tupled_arguments[..]
+                    &tupled_arguments
                 }
                 _ => {
                     bug!("argument to function with \"rust-call\" ABI \
index 058f37f62dd82b70f87814f6ce567b2236d05c99..5c1ced573402e07d8314d0654ee458b6bbde3a18 100644 (file)
@@ -229,11 +229,11 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                  variant_fill].iter().cloned().collect();
             match name {
                 None => {
-                    Type::struct_(cx, &fields[..], false)
+                    Type::struct_(cx, &fields, false)
                 }
                 Some(name) => {
                     let mut llty = Type::named_struct(cx, name);
-                    llty.set_struct_body(&fields[..], false);
+                    llty.set_struct_body(&fields, false);
                     llty
                 }
             }
@@ -330,7 +330,7 @@ fn struct_wrapped_nullable_bitdiscr(
     alignment: Alignment,
 ) -> ValueRef {
     let llptrptr = bcx.gepi(scrutinee,
-        &discrfield.iter().map(|f| *f as usize).collect::<Vec<_>>()[..]);
+        &discrfield.iter().map(|f| *f as usize).collect::<Vec<_>>());
     let llptr = bcx.load(llptrptr, alignment.to_align());
     let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
     bcx.icmp(cmp, llptr, C_null(val_ty(llptr)))
@@ -402,7 +402,7 @@ pub fn trans_set_discr<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, val: Valu
                     base::call_memset(bcx, llptr, fill_byte, size, align, false);
                 } else {
                     let path = discrfield.iter().map(|&i| i as usize).collect::<Vec<_>>();
-                    let llptrptr = bcx.gepi(val, &path[..]);
+                    let llptrptr = bcx.gepi(val, &path);
                     let llptrty = val_ty(llptrptr).element_type();
                     bcx.store(C_null(llptrty), llptrptr, None);
                 }
index 12e4e57964f985e47c9ba31226693965c73b4dd7..b6195765b27c29711856314d9afc1524b0e012e2 100644 (file)
@@ -77,14 +77,14 @@ pub fn trans_inline_asm<'a, 'tcx>(
           .chain(arch_clobbers.iter().map(|s| s.to_string()))
           .collect::<Vec<String>>().join(",");
 
-    debug!("Asm Constraints: {}", &all_constraints[..]);
+    debug!("Asm Constraints: {}", &all_constraints);
 
     // Depending on how many outputs we have, the return type is different
     let num_outputs = output_types.len();
     let output_type = match num_outputs {
         0 => Type::void(bcx.ccx),
         1 => output_types[0],
-        _ => Type::struct_(bcx.ccx, &output_types[..], false)
+        _ => Type::struct_(bcx.ccx, &output_types, false)
     };
 
     let dialect = match ia.dialect {
index 11ab6dcaa87f99fa02a99fac8d9068d8c462d2c1..0f908b7d0698bc48e7bd1fd529d46212c5433a0f 100644 (file)
@@ -65,10 +65,10 @@ pub fn find_library(name: &str, search_paths: &[PathBuf], sess: &Session)
 
     for path in search_paths {
         debug!("looking for {} inside {:?}", name, path);
-        let test = path.join(&oslibname[..]);
+        let test = path.join(&oslibname);
         if test.exists() { return test }
         if oslibname != unixlibname {
-            let test = path.join(&unixlibname[..]);
+            let test = path.join(&unixlibname);
             if test.exists() { return test }
         }
     }
index cf1e10b317b1ed030a4acbdf60bc28131d477d61..6d17b2f0eeda3514c3b6079c2c0d92cc7ce315ff 100644 (file)
@@ -91,7 +91,7 @@ pub fn find_crate_name(sess: Option<&Session>,
                        attrs: &[ast::Attribute],
                        input: &Input) -> String {
     let validate = |s: String, span: Option<Span>| {
-        cstore::validate_crate_name(sess, &s[..], span);
+        cstore::validate_crate_name(sess, &s, span);
         s
     };
 
@@ -109,7 +109,7 @@ pub fn find_crate_name(sess: Option<&Session>,
                     let msg = format!("--crate-name and #[crate_name] are \
                                        required to match, but `{}` != `{}`",
                                       s, name);
-                    sess.span_err(attr.span, &msg[..]);
+                    sess.span_err(attr.span, &msg);
                 }
             }
             return validate(s.clone(), None);
@@ -417,7 +417,7 @@ fn object_filenames(trans: &CrateTranslation,
                     outputs: &OutputFilenames)
                     -> Vec<PathBuf> {
     trans.modules.iter().map(|module| {
-        outputs.temp_path(OutputType::Object, Some(&module.name[..]))
+        outputs.temp_path(OutputType::Object, Some(&module.name))
     }).collect()
 }
 
@@ -551,7 +551,7 @@ fn link_rlib<'a>(sess: &'a Session,
                                                  e))
                 }
 
-                let bc_data_deflated = flate::deflate_bytes(&bc_data[..]);
+                let bc_data_deflated = flate::deflate_bytes(&bc_data);
 
                 let mut bc_file_deflated = match fs::File::create(&bc_deflated_filename) {
                     Ok(file) => file,
@@ -819,12 +819,12 @@ fn escape_string(s: &[u8]) -> String {
                                          pname,
                                          prog.status))
                     .note(&format!("{:?}", &cmd))
-                    .note(&escape_string(&output[..]))
+                    .note(&escape_string(&output))
                     .emit();
                 sess.abort_if_errors();
             }
-            info!("linker stderr:\n{}", escape_string(&prog.stderr[..]));
-            info!("linker stdout:\n{}", escape_string(&prog.stdout[..]));
+            info!("linker stderr:\n{}", escape_string(&prog.stderr));
+            info!("linker stdout:\n{}", escape_string(&prog.stdout));
         },
         Err(e) => {
             sess.struct_err(&format!("could not exec the linker `{}`: {}", pname, e))
index 0ef3f351a2a4bffdb58292beb058e482a73416cc..e23ddd2542a808f8ae0b765c2c86a95ecafa3f45 100644 (file)
@@ -61,7 +61,7 @@ pub fn run(sess: &session::Session,
     }
 
     let export_threshold =
-        symbol_export::crates_export_threshold(&sess.crate_types.borrow()[..]);
+        symbol_export::crates_export_threshold(&sess.crate_types.borrow());
 
     let symbol_filter = &|&(ref name, level): &(String, _)| {
         if symbol_export::is_below_threshold(level, export_threshold) {
@@ -147,7 +147,7 @@ pub fn run(sess: &session::Session,
                                                         bc_decoded.len() as libc::size_t) {
                     write::llvm_err(sess.diagnostic(),
                                     format!("failed to load bc of `{}`",
-                                            &name[..]));
+                                            name));
                 }
             });
         }
index 9c982be3fa03ef7215009152e8ebd779bfe0c9dd..104e7bc6a52bde0cf04a013fe4ef0f4d47169a62 100644 (file)
@@ -37,8 +37,8 @@ pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
 
     let libs = config.used_crates.clone();
     let libs = libs.into_iter().filter_map(|(_, l)| l.option()).collect::<Vec<_>>();
-    let rpaths = get_rpaths(config, &libs[..]);
-    flags.extend_from_slice(&rpaths_to_flags(&rpaths[..]));
+    let rpaths = get_rpaths(config, &libs);
+    flags.extend_from_slice(&rpaths_to_flags(&rpaths));
 
     // Use DT_RUNPATH instead of DT_RPATH if available
     if config.linker_is_gnu {
@@ -84,14 +84,14 @@ fn log_rpaths(desc: &str, rpaths: &[String]) {
         }
     }
 
-    log_rpaths("relative", &rel_rpaths[..]);
-    log_rpaths("fallback", &fallback_rpaths[..]);
+    log_rpaths("relative", &rel_rpaths);
+    log_rpaths("fallback", &fallback_rpaths);
 
     let mut rpaths = rel_rpaths;
-    rpaths.extend_from_slice(&fallback_rpaths[..]);
+    rpaths.extend_from_slice(&fallback_rpaths);
 
     // Remove duplicates
-    let rpaths = minimize_rpaths(&rpaths[..]);
+    let rpaths = minimize_rpaths(&rpaths);
     return rpaths;
 }
 
@@ -177,7 +177,7 @@ fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
     let mut set = HashSet::new();
     let mut minimized = Vec::new();
     for rpath in rpaths {
-        if set.insert(&rpath[..]) {
+        if set.insert(rpath) {
             minimized.push(rpath.clone());
         }
     }
index 005fb3533ab0b793510bdec9fde95630c2a46744..23a67ef5046eebec0a527e24a0859eff3f359dce 100644 (file)
@@ -154,7 +154,7 @@ pub fn exported_symbols(&self,
                             cnum: CrateNum)
                             -> &[(String, SymbolExportLevel)] {
         match self.exports.get(&cnum) {
-            Some(exports) => &exports[..],
+            Some(exports) => exports,
             None => &[]
         }
     }
@@ -167,7 +167,7 @@ pub fn for_each_exported_symbol<F>(&self,
     {
         for &(ref name, export_level) in self.exported_symbols(cnum) {
             if is_below_threshold(export_level, export_threshold) {
-                f(&name[..], export_level)
+                f(&name, export_level)
             }
         }
     }
index 518995dfedcc282fac84b41ada9f0ebb288837be..3ad04e10cb027d20f4a555929eb43eff1a11dd62 100644 (file)
@@ -341,7 +341,7 @@ pub fn sanitize(s: &str) -> String {
     if !result.is_empty() &&
         result.as_bytes()[0] != '_' as u8 &&
         ! (result.as_bytes()[0] as char).is_xid_start() {
-        return format!("_{}", &result[..]);
+        return format!("_{}", result);
     }
 
     return result;
index 377ff34cb7e0db7a745dfc4e802b95137a302586..5a017e4fb8a9aa07e163887f28c443960278b1da 100644 (file)
@@ -105,7 +105,7 @@ fn dump(&mut self, handler: &Handler) {
                 Some(ref code) => {
                     handler.emit_with_code(&MultiSpan::new(),
                                            &diag.msg,
-                                           &code[..],
+                                           &code,
                                            diag.lvl);
                 },
                 None => {
@@ -189,8 +189,8 @@ pub fn create_target_machine(sess: &Session) -> TargetMachineRef {
     let fdata_sections = ffunction_sections;
 
     let code_model_arg = match sess.opts.cg.code_model {
-        Some(ref s) => &s[..],
-        None => &sess.target.target.options.code_model[..],
+        Some(ref s) => &s,
+        None => &sess.target.target.options.code_model,
     };
 
     let code_model = match CODE_GEN_MODEL_ARGS.iter().find(
@@ -397,7 +397,7 @@ struct HandlerFreeVars<'a> {
     let msg = llvm::build_string(|s| llvm::LLVMRustWriteSMDiagnosticToString(diag, s))
         .expect("non-UTF8 SMDiagnostic");
 
-    report_inline_asm(cgcx, &msg[..], cookie);
+    report_inline_asm(cgcx, &msg, cookie);
 }
 
 unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) {
@@ -823,7 +823,7 @@ pub fn run_passes(sess: &Session,
         if trans.modules.len() == 1 {
             // 1) Only one codegen unit.  In this case it's no difficulty
             //    to copy `foo.0.x` to `foo.x`.
-            let module_name = Some(&(trans.modules[0].name)[..]);
+            let module_name = Some(&trans.modules[0].name[..]);
             let path = crate_output.temp_path(output_type, module_name);
             copy_gracefully(&path,
                             &crate_output.path(output_type));
@@ -939,7 +939,7 @@ pub fn run_passes(sess: &Session,
 
         if metadata_config.emit_bc && !user_wants_bitcode {
             let path = crate_output.temp_path(OutputType::Bitcode,
-                                              Some(&trans.metadata_module.name[..]));
+                                              Some(&trans.metadata_module.name));
             remove(sess, &path);
         }
     }
index 80b563729f5ce3678a641d900e8559834d15037f..ec45c5593632ed3fddbc5bf18924ffdec73fc740 100644 (file)
@@ -514,7 +514,7 @@ pub fn call_memcpy<'a, 'tcx>(b: &Builder<'a, 'tcx>,
                                n_bytes: ValueRef,
                                align: u32) {
     let ccx = b.ccx;
-    let ptr_width = &ccx.sess().target.target.target_pointer_width[..];
+    let ptr_width = &ccx.sess().target.target.target_pointer_width;
     let key = format!("llvm.memcpy.p0i8.p0i8.i{}", ptr_width);
     let memcpy = ccx.get_intrinsic(&key);
     let src_ptr = b.pointercast(src, Type::i8p(ccx));
@@ -550,7 +550,7 @@ pub fn call_memset<'a, 'tcx>(b: &Builder<'a, 'tcx>,
                              size: ValueRef,
                              align: ValueRef,
                              volatile: bool) -> ValueRef {
-    let ptr_width = &b.ccx.sess().target.target.target_pointer_width[..];
+    let ptr_width = &b.ccx.sess().target.target.target_pointer_width;
     let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
     let llintrinsicfn = b.ccx.get_intrinsic(&intrinsic_key);
     let volatile = C_bool(b.ccx, volatile);
@@ -755,7 +755,6 @@ enum MetadataKind {
 
     let cstore = &cx.tcx().sess.cstore;
     let metadata = cstore.encode_metadata(cx.tcx(),
-                                          cx.export_map(),
                                           cx.link_meta(),
                                           exported_symbols);
     if kind == MetadataKind::Uncompressed {
@@ -766,7 +765,7 @@ enum MetadataKind {
     let mut compressed = cstore.metadata_encoding_version().to_vec();
     compressed.extend_from_slice(&flate::deflate_bytes(&metadata));
 
-    let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed[..]);
+    let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed);
     let llconst = C_struct_in_context(cx.metadata_llcx(), &[llmeta], false);
     let name = cx.metadata_symbol_name();
     let buf = CString::new(name).unwrap();
@@ -797,7 +796,7 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
                                  symbol_map: &SymbolMap<'tcx>,
                                  exported_symbols: &ExportedSymbols) {
     let export_threshold =
-        symbol_export::crates_export_threshold(&sess.crate_types.borrow()[..]);
+        symbol_export::crates_export_threshold(&sess.crate_types.borrow());
 
     let exported_symbols = exported_symbols
         .exported_symbols(LOCAL_CRATE)
@@ -1036,7 +1035,7 @@ pub fn find_exported_symbols(tcx: TyCtxt, reachable: NodeSet) -> NodeSet {
                 (generics.parent_types == 0 && generics.types.is_empty()) &&
                 // Functions marked with #[inline] are only ever translated
                 // with "internal" linkage and are never exported.
-                !attr::requests_inline(&attributes[..])
+                !attr::requests_inline(&attributes)
             }
 
             _ => false
@@ -1056,7 +1055,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // particular items that will be processed.
     let krate = tcx.hir.krate();
 
-    let ty::CrateAnalysis { export_map, reachable, name, .. } = analysis;
+    let ty::CrateAnalysis { reachable, name, .. } = analysis;
     let exported_symbols = find_exported_symbols(tcx, reachable);
 
     let check_overflow = tcx.sess.overflow_checks();
@@ -1064,7 +1063,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let link_meta = link::build_link_meta(incremental_hashes_map, &name);
 
     let shared_ccx = SharedCrateContext::new(tcx,
-                                             export_map,
                                              link_meta.clone(),
                                              exported_symbols,
                                              check_overflow);
@@ -1576,7 +1574,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
                 cgus.dedup();
                 for &(ref cgu_name, linkage) in cgus.iter() {
                     output.push_str(" ");
-                    output.push_str(&cgu_name[..]);
+                    output.push_str(&cgu_name);
 
                     let linkage_abbrev = match linkage {
                         llvm::Linkage::ExternalLinkage => "External",
index a62f07042a7035749ba970c1d685e2ca6957fed1..8b1010d89fd9fd1c03c5f0e657de371ae090529c 100644 (file)
@@ -627,7 +627,7 @@ pub fn gepi(&self, base: ValueRef, ixs: &[usize]) -> ValueRef {
         } else {
             let v = ixs.iter().map(|i| C_i32(self.ccx, *i as i32)).collect::<Vec<ValueRef>>();
             self.count_insn("gepi");
-            self.inbounds_gep(base, &v[..])
+            self.inbounds_gep(base, &v)
         }
     }
 
@@ -835,8 +835,8 @@ pub fn add_span_comment(&self, sp: Span, text: &str) {
             let s = format!("{} ({})",
                             text,
                             self.ccx.sess().codemap().span_to_string(sp));
-            debug!("{}", &s[..]);
-            self.add_comment(&s[..]);
+            debug!("{}", s);
+            self.add_comment(&s);
         }
     }
 
index 1c1395f1b7762604309616c59b07979824036bf8..73602dc420b3f9999be6534e41e5df674004cc91 100644 (file)
@@ -14,7 +14,6 @@
                        DepTrackingMapConfig, WorkProduct};
 use middle::cstore::LinkMeta;
 use rustc::hir;
-use rustc::hir::def::ExportMap;
 use rustc::hir::def_id::DefId;
 use rustc::traits;
 use debuginfo;
@@ -68,7 +67,6 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
     metadata_llmod: ModuleRef,
     metadata_llcx: ContextRef,
 
-    export_map: ExportMap,
     exported_symbols: NodeSet,
     link_meta: LinkMeta,
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -402,7 +400,6 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR
 
 impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
     pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
-               export_map: ExportMap,
                link_meta: LinkMeta,
                exported_symbols: NodeSet,
                check_overflow: bool)
@@ -459,7 +456,6 @@ pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
         SharedCrateContext {
             metadata_llmod: metadata_llmod,
             metadata_llcx: metadata_llcx,
-            export_map: export_map,
             exported_symbols: exported_symbols,
             link_meta: link_meta,
             empty_param_env: tcx.empty_parameter_environment(),
@@ -499,10 +495,6 @@ pub fn metadata_llcx(&self) -> ContextRef {
         self.metadata_llcx
     }
 
-    pub fn export_map<'a>(&'a self) -> &'a ExportMap {
-        &self.export_map
-    }
-
     pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet {
         &self.exported_symbols
     }
@@ -702,10 +694,6 @@ pub fn td(&self) -> llvm::TargetDataRef {
         unsafe { llvm::LLVMRustGetModuleDataLayout(self.llmod()) }
     }
 
-    pub fn export_map<'a>(&'a self) -> &'a ExportMap {
-        &self.shared.export_map
-    }
-
     pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet {
         &self.shared.exported_symbols
     }
index fcf6937d4b6d58670681f042e9bc6deedc71076b..382ca8ef01001ecfd31d922b869d143d5e3a04a0 100644 (file)
@@ -287,7 +287,7 @@ pub fn custom_coerce_unsize_info<'scx, 'tcx>(scx: &SharedCrateContext<'scx, 'tcx
 
     match fulfill_obligation(scx, DUMMY_SP, trait_ref) {
         traits::VtableImpl(traits::VtableImplData { impl_def_id, .. }) => {
-            scx.tcx().custom_coerce_unsized_kind(impl_def_id)
+            scx.tcx().coerce_unsized_info(impl_def_id).custom_kind.unwrap()
         }
         vtable => {
             bug!("invalid CoerceUnsized vtable: {:?}", vtable);
index f08d26373e50e979ef977f2c2346a77275eda918..07998aa4a30ea0aee8b6a633cd8ea96c529d2843 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 test = false
 
 [dependencies]
-log = { path = "../liblog" }
+log = "0.3"
 syntax = { path = "../libsyntax" }
 arena = { path = "../libarena" }
 fmt_macros = { path = "../libfmt_macros" }
index dfa7ababca0bbd8b97f143cbc9efcdca24d44ec6..5b0418921563a2dea56b4fa4bbf47897b57f3fc8 100644 (file)
@@ -479,14 +479,9 @@ fn assemble_inherent_impl_for_primitive(&mut self, lang_def_id: Option<DefId>) {
     }
 
     fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId) {
-        // Read the inherent implementation candidates for this type from the
-        // metadata if necessary.
-        self.tcx.populate_inherent_implementations_for_type_if_necessary(self.span, def_id);
-
-        if let Some(impl_infos) = self.tcx.maps.inherent_impls.borrow().get(&def_id) {
-            for &impl_def_id in impl_infos.iter() {
-                self.assemble_inherent_impl_probe(impl_def_id);
-            }
+        let impl_def_ids = ty::queries::inherent_impls::get(self.tcx, self.span, def_id);
+        for &impl_def_id in impl_def_ids.iter() {
+            self.assemble_inherent_impl_probe(impl_def_id);
         }
     }
 
index 3cdf9fc93ae600617a4c84aa935dfdb1adcaec07..47b41a75cf5316a9f041d1200ce362f260a45aea 100644 (file)
@@ -18,6 +18,7 @@
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::ParameterEnvironment;
 use rustc::ty::TypeFoldable;
+use rustc::ty::adjustment::CoerceUnsizedInfo;
 use rustc::ty::subst::Subst;
 use rustc::ty::util::CopyImplementationError;
 use rustc::infer;
@@ -159,11 +160,26 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                                    coerce_unsized_trait: DefId,
+                                                    _: DefId,
                                                     impl_did: DefId) {
     debug!("visit_implementation_of_coerce_unsized: impl_did={:?}",
            impl_did);
 
+    // Just compute this for the side-effects, in particular reporting
+    // errors; other parts of the code may demand it for the info of
+    // course.
+    if impl_did.is_local() {
+        let span = tcx.def_span(impl_did);
+        ty::queries::coerce_unsized_info::get(tcx, span, impl_did);
+    }
+}
+
+pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                     impl_did: DefId)
+                                     -> CoerceUnsizedInfo {
+    debug!("compute_coerce_unsized_info(impl_did={:?})", impl_did);
+    let coerce_unsized_trait = tcx.lang_items.coerce_unsized_trait().unwrap();
+
     let unsize_trait = match tcx.lang_items.require(UnsizeTraitLangItem) {
         Ok(id) => id,
         Err(err) => {
@@ -171,16 +187,14 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
     };
 
-    let impl_node_id = if let Some(n) = tcx.hir.as_local_node_id(impl_did) {
-        n
-    } else {
-        debug!("visit_implementation_of_coerce_unsized(): impl not \
-                in this crate");
-        return;
-    };
+    // this provider should only get invoked for local def-ids
+    let impl_node_id = tcx.hir.as_local_node_id(impl_did).unwrap_or_else(|| {
+        bug!("coerce_unsized_info: invoked for non-local def-id {:?}", impl_did)
+    });
 
     let source = tcx.item_type(impl_did);
     let trait_ref = tcx.impl_trait_ref(impl_did).unwrap();
+    assert_eq!(trait_ref.def_id, coerce_unsized_trait);
     let target = trait_ref.substs.type_at(1);
     debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (bound)",
            source,
@@ -192,6 +206,8 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let target = target.subst(tcx, &param_env.free_substs);
     assert!(!source.has_escaping_regions());
 
+    let err_info = CoerceUnsizedInfo { custom_kind: None };
+
     debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (free)",
            source,
            target);
@@ -234,7 +250,7 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                definition; expected {}, found {}",
                               source_path,
                               target_path);
-                    return;
+                    return err_info;
                 }
 
                 let fields = &def_a.struct_variant().fields;
@@ -268,7 +284,7 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                               "the trait `CoerceUnsized` may only be implemented \
                                for a coercion between structures with one field \
                                being coerced, none found");
-                    return;
+                    return err_info;
                 } else if diff_fields.len() > 1 {
                     let item = tcx.hir.expect_item(impl_node_id);
                     let span = if let ItemImpl(.., Some(ref t), _, _) = item.node {
@@ -295,7 +311,7 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                           .join(", ")));
                     err.span_label(span, &format!("requires multiple coercions"));
                     err.emit();
-                    return;
+                    return err_info;
                 }
 
                 let (i, a, b) = diff_fields[0];
@@ -309,7 +325,7 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                           E0376,
                           "the trait `CoerceUnsized` may only be implemented \
                            for a coercion between structures");
-                return;
+                return err_info;
             }
         };
 
@@ -331,8 +347,8 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             .caller_bounds);
         infcx.resolve_regions_and_report_errors(&free_regions, impl_node_id);
 
-        if let Some(kind) = kind {
-            tcx.maps.custom_coerce_unsized_kind.borrow_mut().insert(impl_did, kind);
+        CoerceUnsizedInfo {
+            custom_kind: kind
         }
-    });
+    })
 }
diff --git a/src/librustc_typeck/coherence/inherent.rs b/src/librustc_typeck/coherence/inherent.rs
deleted file mode 100644 (file)
index e3b4ba9..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-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 rustc::dep_graph::DepNode;
-use rustc::hir::def_id::DefId;
-use rustc::hir;
-use rustc::hir::itemlikevisit::ItemLikeVisitor;
-use rustc::lint;
-use rustc::traits::{self, Reveal};
-use rustc::ty::{self, TyCtxt};
-
-use syntax::ast;
-use syntax_pos::Span;
-
-struct InherentCollect<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'a, 'tcx, 'tcx>
-}
-
-impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
-    fn visit_item(&mut self, item: &hir::Item) {
-        let (unsafety, ty) = match item.node {
-            hir::ItemImpl(unsafety, .., None, ref ty, _) => (unsafety, ty),
-            _ => return
-        };
-
-        match unsafety {
-            hir::Unsafety::Normal => {
-                // OK
-            }
-            hir::Unsafety::Unsafe => {
-                span_err!(self.tcx.sess,
-                          item.span,
-                          E0197,
-                          "inherent impls cannot be declared as unsafe");
-            }
-        }
-
-        let def_id = self.tcx.hir.local_def_id(item.id);
-        let self_ty = self.tcx.item_type(def_id);
-        match self_ty.sty {
-            ty::TyAdt(def, _) => {
-                self.check_def_id(item, def.did);
-            }
-            ty::TyDynamic(ref data, ..) if data.principal().is_some() => {
-                self.check_def_id(item, data.principal().unwrap().def_id());
-            }
-            ty::TyChar => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.char_impl(),
-                                          "char",
-                                          "char",
-                                          item.span);
-            }
-            ty::TyStr => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.str_impl(),
-                                          "str",
-                                          "str",
-                                          item.span);
-            }
-            ty::TySlice(_) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.slice_impl(),
-                                          "slice",
-                                          "[T]",
-                                          item.span);
-            }
-            ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.const_ptr_impl(),
-                                          "const_ptr",
-                                          "*const T",
-                                          item.span);
-            }
-            ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.mut_ptr_impl(),
-                                          "mut_ptr",
-                                          "*mut T",
-                                          item.span);
-            }
-            ty::TyInt(ast::IntTy::I8) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.i8_impl(),
-                                          "i8",
-                                          "i8",
-                                          item.span);
-            }
-            ty::TyInt(ast::IntTy::I16) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.i16_impl(),
-                                          "i16",
-                                          "i16",
-                                          item.span);
-            }
-            ty::TyInt(ast::IntTy::I32) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.i32_impl(),
-                                          "i32",
-                                          "i32",
-                                          item.span);
-            }
-            ty::TyInt(ast::IntTy::I64) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.i64_impl(),
-                                          "i64",
-                                          "i64",
-                                          item.span);
-            }
-            ty::TyInt(ast::IntTy::I128) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.i128_impl(),
-                                          "i128",
-                                          "i128",
-                                          item.span);
-            }
-            ty::TyInt(ast::IntTy::Is) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.isize_impl(),
-                                          "isize",
-                                          "isize",
-                                          item.span);
-            }
-            ty::TyUint(ast::UintTy::U8) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.u8_impl(),
-                                          "u8",
-                                          "u8",
-                                          item.span);
-            }
-            ty::TyUint(ast::UintTy::U16) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.u16_impl(),
-                                          "u16",
-                                          "u16",
-                                          item.span);
-            }
-            ty::TyUint(ast::UintTy::U32) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.u32_impl(),
-                                          "u32",
-                                          "u32",
-                                          item.span);
-            }
-            ty::TyUint(ast::UintTy::U64) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.u64_impl(),
-                                          "u64",
-                                          "u64",
-                                          item.span);
-            }
-            ty::TyUint(ast::UintTy::U128) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.u128_impl(),
-                                          "u128",
-                                          "u128",
-                                          item.span);
-            }
-            ty::TyUint(ast::UintTy::Us) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.usize_impl(),
-                                          "usize",
-                                          "usize",
-                                          item.span);
-            }
-            ty::TyFloat(ast::FloatTy::F32) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.f32_impl(),
-                                          "f32",
-                                          "f32",
-                                          item.span);
-            }
-            ty::TyFloat(ast::FloatTy::F64) => {
-                self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.f64_impl(),
-                                          "f64",
-                                          "f64",
-                                          item.span);
-            }
-            ty::TyError => {
-                return;
-            }
-            _ => {
-                struct_span_err!(self.tcx.sess,
-                                 ty.span,
-                                 E0118,
-                                 "no base type found for inherent implementation")
-                    .span_label(ty.span, &format!("impl requires a base type"))
-                    .note(&format!("either implement a trait on it or create a newtype \
-                                    to wrap it instead"))
-                    .emit();
-                return;
-            }
-        }
-    }
-
-    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
-    }
-
-    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
-    }
-}
-
-impl<'a, 'tcx> InherentCollect<'a, 'tcx> {
-    fn check_def_id(&self, item: &hir::Item, def_id: DefId) {
-        if def_id.is_local() {
-            // Add the implementation to the mapping from implementation to base
-            // type def ID, if there is a base type for this implementation and
-            // the implementation does not have any associated traits.
-            let impl_def_id = self.tcx.hir.local_def_id(item.id);
-
-            // Subtle: it'd be better to collect these into a local map
-            // and then write the vector only once all items are known,
-            // but that leads to degenerate dep-graphs. The problem is
-            // that the write of that big vector winds up having reads
-            // from *all* impls in the krate, since we've lost the
-            // precision basically.  This would be ok in the firewall
-            // model so once we've made progess towards that we can modify
-            // the strategy here. In the meantime, using `push` is ok
-            // because we are doing this as a pre-pass before anyone
-            // actually reads from `inherent_impls` -- and we know this is
-            // true beacuse we hold the refcell lock.
-            self.tcx.maps.inherent_impls.borrow_mut().push(def_id, impl_def_id);
-        } else {
-            struct_span_err!(self.tcx.sess,
-                             item.span,
-                             E0116,
-                             "cannot define inherent `impl` for a type outside of the crate \
-                              where the type is defined")
-                .span_label(item.span,
-                            &format!("impl for type defined outside of crate."))
-                .note("define and implement a trait or new type instead")
-                .emit();
-        }
-    }
-
-    fn check_primitive_impl(&self,
-                            impl_def_id: DefId,
-                            lang_def_id: Option<DefId>,
-                            lang: &str,
-                            ty: &str,
-                            span: Span) {
-        match lang_def_id {
-            Some(lang_def_id) if lang_def_id == impl_def_id => {
-                // OK
-            }
-            _ => {
-                struct_span_err!(self.tcx.sess,
-                                 span,
-                                 E0390,
-                                 "only a single inherent implementation marked with `#[lang = \
-                                  \"{}\"]` is allowed for the `{}` primitive",
-                                 lang,
-                                 ty)
-                    .span_help(span, "consider using a trait to implement these methods")
-                    .emit();
-            }
-        }
-    }
-}
-
-struct InherentOverlapChecker<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'a, 'tcx, 'tcx>
-}
-
-impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
-    fn check_for_common_items_in_impls(&self, impl1: DefId, impl2: DefId) {
-        #[derive(Copy, Clone, PartialEq)]
-        enum Namespace {
-            Type,
-            Value,
-        }
-
-        let name_and_namespace = |def_id| {
-            let item = self.tcx.associated_item(def_id);
-            (item.name, match item.kind {
-                ty::AssociatedKind::Type => Namespace::Type,
-                ty::AssociatedKind::Const |
-                ty::AssociatedKind::Method => Namespace::Value,
-            })
-        };
-
-        let impl_items1 = self.tcx.associated_item_def_ids(impl1);
-        let impl_items2 = self.tcx.associated_item_def_ids(impl2);
-
-        for &item1 in &impl_items1[..] {
-            let (name, namespace) = name_and_namespace(item1);
-
-            for &item2 in &impl_items2[..] {
-                if (name, namespace) == name_and_namespace(item2) {
-                    let msg = format!("duplicate definitions with name `{}`", name);
-                    let node_id = self.tcx.hir.as_local_node_id(item1).unwrap();
-                    self.tcx.sess.add_lint(lint::builtin::OVERLAPPING_INHERENT_IMPLS,
-                                           node_id,
-                                           self.tcx.span_of_impl(item1).unwrap(),
-                                           msg);
-                }
-            }
-        }
-    }
-
-    fn check_for_overlapping_inherent_impls(&self, ty_def_id: DefId) {
-        let _task = self.tcx.dep_graph.in_task(DepNode::CoherenceOverlapInherentCheck(ty_def_id));
-
-        let inherent_impls = self.tcx.maps.inherent_impls.borrow();
-        let impls = match inherent_impls.get(&ty_def_id) {
-            Some(impls) => impls,
-            None => return,
-        };
-
-        for (i, &impl1_def_id) in impls.iter().enumerate() {
-            for &impl2_def_id in &impls[(i + 1)..] {
-                self.tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
-                    if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id).is_some() {
-                        self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id)
-                    }
-                });
-            }
-        }
-    }
-}
-
-impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentOverlapChecker<'a, 'tcx> {
-    fn visit_item(&mut self, item: &'v hir::Item) {
-        match item.node {
-            hir::ItemEnum(..) |
-            hir::ItemStruct(..) |
-            hir::ItemTrait(..) |
-            hir::ItemUnion(..) => {
-                let type_def_id = self.tcx.hir.local_def_id(item.id);
-                self.check_for_overlapping_inherent_impls(type_def_id);
-            }
-            _ => {}
-        }
-    }
-
-    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
-    }
-
-    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
-    }
-}
-
-pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    tcx.visit_all_item_likes_in_krate(DepNode::CoherenceCheckImpl,
-                                      &mut InherentCollect { tcx });
-    tcx.visit_all_item_likes_in_krate(DepNode::CoherenceOverlapCheckSpecial,
-                                      &mut InherentOverlapChecker { tcx });
-}
diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs
new file mode 100644 (file)
index 0000000..3a39df5
--- /dev/null
@@ -0,0 +1,325 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The code in this module gathers up all of the inherent impls in
+//! the current crate and organizes them in a map. It winds up
+//! touching the whole crate and thus must be recomputed completely
+//! for any change, but it is very cheap to compute. In practice, most
+//! code in the compiler never *directly* requests this map. Instead,
+//! it requests the inherent impls specific to some type (via
+//! `ty::queries::inherent_impls::get(def_id)`). That value, however,
+//! is computed by selecting an idea from this table.
+
+use rustc::dep_graph::DepNode;
+use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use rustc::hir;
+use rustc::hir::itemlikevisit::ItemLikeVisitor;
+use rustc::ty::{self, CrateInherentImpls, TyCtxt};
+use rustc::util::nodemap::DefIdMap;
+
+use std::rc::Rc;
+use syntax::ast;
+use syntax_pos::{DUMMY_SP, Span};
+
+/// On-demand query: yields a map containing all types mapped to their inherent impls.
+pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                      crate_num: CrateNum)
+                                      -> CrateInherentImpls {
+    assert_eq!(crate_num, LOCAL_CRATE);
+
+    let krate = tcx.hir.krate();
+    let mut collect = InherentCollect {
+        tcx,
+        impls_map: CrateInherentImpls {
+            inherent_impls: DefIdMap()
+        }
+    };
+    krate.visit_all_item_likes(&mut collect);
+    collect.impls_map
+}
+
+/// On-demand query: yields a vector of the inherent impls for a specific type.
+pub fn inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                ty_def_id: DefId)
+                                -> Rc<Vec<DefId>> {
+    assert!(ty_def_id.is_local());
+
+    // NB. Until we adopt the red-green dep-tracking algorithm (see
+    // [the plan] for details on that), we do some hackery here to get
+    // the dependencies correct.  Basically, we use a `with_ignore` to
+    // read the result we want. If we didn't have the `with_ignore`,
+    // we would wind up with a dependency on the entire crate, which
+    // we don't want. Then we go and add dependencies on all the impls
+    // in the result (which is what we wanted).
+    //
+    // The result is a graph with an edge from `Hir(I)` for every impl
+    // `I` defined on some type `T` to `CoherentInherentImpls(T)`,
+    // thus ensuring that if any of those impls change, the set of
+    // inherent impls is considered dirty.
+    //
+    // [the plan]: https://github.com/rust-lang/rust-roadmap/issues/4
+
+    let result = tcx.dep_graph.with_ignore(|| {
+        let crate_map = ty::queries::crate_inherent_impls::get(tcx, DUMMY_SP, ty_def_id.krate);
+        match crate_map.inherent_impls.get(&ty_def_id) {
+            Some(v) => v.clone(),
+            None => Rc::new(vec![]),
+        }
+    });
+
+    for &impl_def_id in &result[..] {
+        tcx.dep_graph.read(DepNode::Hir(impl_def_id));
+    }
+
+    result
+}
+
+struct InherentCollect<'a, 'tcx: 'a> {
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    impls_map: CrateInherentImpls,
+}
+
+impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
+    fn visit_item(&mut self, item: &hir::Item) {
+        let (unsafety, ty) = match item.node {
+            hir::ItemImpl(unsafety, .., None, ref ty, _) => (unsafety, ty),
+            _ => return
+        };
+
+        match unsafety {
+            hir::Unsafety::Normal => {
+                // OK
+            }
+            hir::Unsafety::Unsafe => {
+                span_err!(self.tcx.sess,
+                          item.span,
+                          E0197,
+                          "inherent impls cannot be declared as unsafe");
+            }
+        }
+
+        let def_id = self.tcx.hir.local_def_id(item.id);
+        let self_ty = self.tcx.item_type(def_id);
+        match self_ty.sty {
+            ty::TyAdt(def, _) => {
+                self.check_def_id(item, def.did);
+            }
+            ty::TyDynamic(ref data, ..) if data.principal().is_some() => {
+                self.check_def_id(item, data.principal().unwrap().def_id());
+            }
+            ty::TyChar => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.char_impl(),
+                                          "char",
+                                          "char",
+                                          item.span);
+            }
+            ty::TyStr => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.str_impl(),
+                                          "str",
+                                          "str",
+                                          item.span);
+            }
+            ty::TySlice(_) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.slice_impl(),
+                                          "slice",
+                                          "[T]",
+                                          item.span);
+            }
+            ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.const_ptr_impl(),
+                                          "const_ptr",
+                                          "*const T",
+                                          item.span);
+            }
+            ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.mut_ptr_impl(),
+                                          "mut_ptr",
+                                          "*mut T",
+                                          item.span);
+            }
+            ty::TyInt(ast::IntTy::I8) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.i8_impl(),
+                                          "i8",
+                                          "i8",
+                                          item.span);
+            }
+            ty::TyInt(ast::IntTy::I16) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.i16_impl(),
+                                          "i16",
+                                          "i16",
+                                          item.span);
+            }
+            ty::TyInt(ast::IntTy::I32) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.i32_impl(),
+                                          "i32",
+                                          "i32",
+                                          item.span);
+            }
+            ty::TyInt(ast::IntTy::I64) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.i64_impl(),
+                                          "i64",
+                                          "i64",
+                                          item.span);
+            }
+            ty::TyInt(ast::IntTy::I128) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.i128_impl(),
+                                          "i128",
+                                          "i128",
+                                          item.span);
+            }
+            ty::TyInt(ast::IntTy::Is) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.isize_impl(),
+                                          "isize",
+                                          "isize",
+                                          item.span);
+            }
+            ty::TyUint(ast::UintTy::U8) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.u8_impl(),
+                                          "u8",
+                                          "u8",
+                                          item.span);
+            }
+            ty::TyUint(ast::UintTy::U16) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.u16_impl(),
+                                          "u16",
+                                          "u16",
+                                          item.span);
+            }
+            ty::TyUint(ast::UintTy::U32) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.u32_impl(),
+                                          "u32",
+                                          "u32",
+                                          item.span);
+            }
+            ty::TyUint(ast::UintTy::U64) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.u64_impl(),
+                                          "u64",
+                                          "u64",
+                                          item.span);
+            }
+            ty::TyUint(ast::UintTy::U128) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.u128_impl(),
+                                          "u128",
+                                          "u128",
+                                          item.span);
+            }
+            ty::TyUint(ast::UintTy::Us) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.usize_impl(),
+                                          "usize",
+                                          "usize",
+                                          item.span);
+            }
+            ty::TyFloat(ast::FloatTy::F32) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.f32_impl(),
+                                          "f32",
+                                          "f32",
+                                          item.span);
+            }
+            ty::TyFloat(ast::FloatTy::F64) => {
+                self.check_primitive_impl(def_id,
+                                          self.tcx.lang_items.f64_impl(),
+                                          "f64",
+                                          "f64",
+                                          item.span);
+            }
+            ty::TyError => {
+                return;
+            }
+            _ => {
+                struct_span_err!(self.tcx.sess,
+                                 ty.span,
+                                 E0118,
+                                 "no base type found for inherent implementation")
+                    .span_label(ty.span, &format!("impl requires a base type"))
+                    .note(&format!("either implement a trait on it or create a newtype \
+                                    to wrap it instead"))
+                    .emit();
+                return;
+            }
+        }
+    }
+
+    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
+    }
+
+    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
+    }
+}
+
+impl<'a, 'tcx> InherentCollect<'a, 'tcx> {
+    fn check_def_id(&mut self, item: &hir::Item, def_id: DefId) {
+        if def_id.is_local() {
+            // Add the implementation to the mapping from implementation to base
+            // type def ID, if there is a base type for this implementation and
+            // the implementation does not have any associated traits.
+            let impl_def_id = self.tcx.hir.local_def_id(item.id);
+            let mut rc_vec = self.impls_map.inherent_impls
+                                           .entry(def_id)
+                                           .or_insert_with(|| Rc::new(vec![]));
+
+            // At this point, there should not be any clones of the
+            // `Rc`, so we can still safely push into it in place:
+            Rc::get_mut(&mut rc_vec).unwrap().push(impl_def_id);
+        } else {
+            struct_span_err!(self.tcx.sess,
+                             item.span,
+                             E0116,
+                             "cannot define inherent `impl` for a type outside of the crate \
+                              where the type is defined")
+                .span_label(item.span,
+                            &format!("impl for type defined outside of crate."))
+                .note("define and implement a trait or new type instead")
+                .emit();
+        }
+    }
+
+    fn check_primitive_impl(&self,
+                            impl_def_id: DefId,
+                            lang_def_id: Option<DefId>,
+                            lang: &str,
+                            ty: &str,
+                            span: Span) {
+        match lang_def_id {
+            Some(lang_def_id) if lang_def_id == impl_def_id => {
+                // OK
+            }
+            _ => {
+                struct_span_err!(self.tcx.sess,
+                                 span,
+                                 E0390,
+                                 "only a single inherent implementation marked with `#[lang = \
+                                  \"{}\"]` is allowed for the `{}` primitive",
+                                 lang,
+                                 ty)
+                    .span_help(span, "consider using a trait to implement these methods")
+                    .emit();
+            }
+        }
+    }
+}
+
diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs
new file mode 100644 (file)
index 0000000..4b36072
--- /dev/null
@@ -0,0 +1,102 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-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 rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use rustc::hir;
+use rustc::hir::itemlikevisit::ItemLikeVisitor;
+use rustc::lint;
+use rustc::traits::{self, Reveal};
+use rustc::ty::{self, TyCtxt};
+
+use syntax_pos::DUMMY_SP;
+
+pub fn crate_inherent_impls_overlap_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                                    crate_num: CrateNum) {
+    assert_eq!(crate_num, LOCAL_CRATE);
+    let krate = tcx.hir.krate();
+    krate.visit_all_item_likes(&mut InherentOverlapChecker { tcx });
+}
+
+struct InherentOverlapChecker<'a, 'tcx: 'a> {
+    tcx: TyCtxt<'a, 'tcx, 'tcx>
+}
+
+impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
+    fn check_for_common_items_in_impls(&self, impl1: DefId, impl2: DefId) {
+        #[derive(Copy, Clone, PartialEq)]
+        enum Namespace {
+            Type,
+            Value,
+        }
+
+        let name_and_namespace = |def_id| {
+            let item = self.tcx.associated_item(def_id);
+            (item.name, match item.kind {
+                ty::AssociatedKind::Type => Namespace::Type,
+                ty::AssociatedKind::Const |
+                ty::AssociatedKind::Method => Namespace::Value,
+            })
+        };
+
+        let impl_items1 = self.tcx.associated_item_def_ids(impl1);
+        let impl_items2 = self.tcx.associated_item_def_ids(impl2);
+
+        for &item1 in &impl_items1[..] {
+            let (name, namespace) = name_and_namespace(item1);
+
+            for &item2 in &impl_items2[..] {
+                if (name, namespace) == name_and_namespace(item2) {
+                    let msg = format!("duplicate definitions with name `{}`", name);
+                    let node_id = self.tcx.hir.as_local_node_id(item1).unwrap();
+                    self.tcx.sess.add_lint(lint::builtin::OVERLAPPING_INHERENT_IMPLS,
+                                           node_id,
+                                           self.tcx.span_of_impl(item1).unwrap(),
+                                           msg);
+                }
+            }
+        }
+    }
+
+    fn check_for_overlapping_inherent_impls(&self, ty_def_id: DefId) {
+        let impls = ty::queries::inherent_impls::get(self.tcx, DUMMY_SP, ty_def_id);
+
+        for (i, &impl1_def_id) in impls.iter().enumerate() {
+            for &impl2_def_id in &impls[(i + 1)..] {
+                self.tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
+                    if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id).is_some() {
+                        self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id)
+                    }
+                });
+            }
+        }
+    }
+}
+
+impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentOverlapChecker<'a, 'tcx> {
+    fn visit_item(&mut self, item: &'v hir::Item) {
+        match item.node {
+            hir::ItemEnum(..) |
+            hir::ItemStruct(..) |
+            hir::ItemTrait(..) |
+            hir::ItemUnion(..) => {
+                let type_def_id = self.tcx.hir.local_def_id(item.id);
+                self.check_for_overlapping_inherent_impls(type_def_id);
+            }
+            _ => {}
+        }
+    }
+
+    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
+    }
+
+    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
+    }
+}
+
index 9ecf42daeaae52021fd7f60f0a4dfd91de90f3d7..b3a7b612dd5b8532af75ac7aee58742cbfb29953 100644 (file)
@@ -24,7 +24,8 @@
 use syntax_pos::DUMMY_SP;
 
 mod builtin;
-mod inherent;
+mod inherent_impls;
+mod inherent_impls_overlap;
 mod orphan;
 mod overlap;
 mod unsafety;
@@ -102,9 +103,16 @@ fn enforce_trait_manually_implementable(tcx: TyCtxt, impl_def_id: DefId, trait_d
 }
 
 pub fn provide(providers: &mut Providers) {
+    use self::builtin::coerce_unsized_info;
+    use self::inherent_impls::{crate_inherent_impls, inherent_impls};
+    use self::inherent_impls_overlap::crate_inherent_impls_overlap_check;
+
     *providers = Providers {
         coherent_trait,
-        coherent_inherent_impls,
+        crate_inherent_impls,
+        inherent_impls,
+        crate_inherent_impls_overlap_check,
+        coerce_unsized_info,
         ..*providers
     };
 }
@@ -123,10 +131,6 @@ fn coherent_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     builtin::check_trait(tcx, def_id);
 }
 
-fn coherent_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, _: CrateNum) {
-    inherent::check(tcx);
-}
-
 pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let _task = tcx.dep_graph.in_task(DepNode::Coherence);
     for &trait_def_id in tcx.hir.krate().trait_impls.keys() {
@@ -137,5 +141,7 @@ pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     orphan::check(tcx);
     overlap::check_default_impls(tcx);
 
-    ty::queries::coherent_inherent_impls::get(tcx, DUMMY_SP, LOCAL_CRATE);
+    // these queries are executed for side-effects (error reporting):
+    ty::queries::crate_inherent_impls::get(tcx, DUMMY_SP, LOCAL_CRATE);
+    ty::queries::crate_inherent_impls_overlap_check::get(tcx, DUMMY_SP, LOCAL_CRATE);
 }
index 0136faef28d8cc1413517a7243b146ba7e45d4d7..bd6129eb5bee3c80befdfa76500988837d72f91e 100644 (file)
@@ -790,7 +790,7 @@ fn main() {
 and [RFC 809] for more details.
 
 [RFC 470]: https://github.com/rust-lang/rfcs/pull/470
-[RFC 809]: https://github.com/rust-lang/rfcs/pull/809
+[RFC 809]: https://github.com/rust-lang/rfcs/blob/master/text/0809-box-and-in-for-stdlib.md
 "##,
 
 E0067: r##"
@@ -1428,7 +1428,7 @@ struct Baz<'a> {
 ```
 
 Note that type parameters for enum-variant constructors go after the variant,
-not after the enum (Option::None::<u32>, not Option::<u32>::None).
+not after the enum (`Option::None::<u32>`, not `Option::<u32>::None`).
 "##,
 
 E0110: r##"
@@ -1521,7 +1521,7 @@ fn get(&self) -> usize { 0 }
 
 For information on the design of the orphan rules, see [RFC 1023].
 
-[RFC 1023]: https://github.com/rust-lang/rfcs/pull/1023
+[RFC 1023]: https://github.com/rust-lang/rfcs/blob/master/text/1023-rebalancing-coherence.md
 "##,
 
 E0118: r##"
@@ -1911,8 +1911,9 @@ trait Trait {
 
 E0192: r##"
 Negative impls are only allowed for traits with default impls. For more
-information see the [opt-in builtin traits RFC](https://github.com/rust-lang/
-rfcs/blob/master/text/0019-opt-in-builtin-traits.md).
+information see the [opt-in builtin traits RFC][RFC 19].
+
+[RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md
 "##,
 
 E0193: r##"
@@ -2147,7 +2148,7 @@ fn bar(&self) -> bool { self.0 }
 Inherent associated types were part of [RFC 195] but are not yet implemented.
 See [the tracking issue][iss8995] for the status of this implementation.
 
-[RFC 195]: https://github.com/rust-lang/rfcs/pull/195
+[RFC 195]: https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md
 [iss8995]: https://github.com/rust-lang/rust/issues/8995
 "##,
 
@@ -2424,7 +2425,7 @@ impl<P1, ..., Pm> ForeignTrait<T1, ..., Tn> for T0 { ... }
 
 For information on the design of the orphan rules, see [RFC 1023].
 
-[RFC 1023]: https://github.com/rust-lang/rfcs/pull/1023
+[RFC 1023]: https://github.com/rust-lang/rfcs/blob/master/text/1023-rebalancing-coherence.md
 "##,
 
 /*
@@ -2799,8 +2800,9 @@ fn drop(&mut self) { }
 
 E0318: r##"
 Default impls for a trait must be located in the same crate where the trait was
-defined. For more information see the [opt-in builtin traits RFC](https://github
-.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md).
+defined. For more information see the [opt-in builtin traits RFC][RFC 19].
+
+[RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md
 "##,
 
 E0321: r##"
@@ -3018,10 +3020,8 @@ impl<T> Unsize<T> for MyType {}
 ```
 
 If you are defining your own smart pointer type and would like to enable
-conversion from a sized to an unsized type with the [DST coercion system]
-(https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md), use
-[`CoerceUnsized`](https://doc.rust-lang.org/std/ops/trait.CoerceUnsized.html)
-instead.
+conversion from a sized to an unsized type with the
+[DST coercion system][RFC 982], use [`CoerceUnsized`] instead.
 
 ```
 #![feature(coerce_unsized)]
@@ -3035,6 +3035,9 @@ pub struct MyType<T: ?Sized> {
 impl<T, U> CoerceUnsized<MyType<U>> for MyType<T>
     where T: CoerceUnsized<U> {}
 ```
+
+[RFC 982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
+[`CoerceUnsized`]: https://doc.rust-lang.org/std/ops/trait.CoerceUnsized.html
 "##,
 
 E0329: r##"
@@ -3438,8 +3441,9 @@ impl<T, U> CoerceUnsized<Foo<U>> for Foo<T> where T: CoerceUnsized<U> {}
 
 E0380: r##"
 Default impls are only allowed for traits with no methods or associated items.
-For more information see the [opt-in builtin traits RFC](https://github.com/rust
--lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md).
+For more information see the [opt-in builtin traits RFC][RFC 19].
+
+[RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md
 "##,
 
 E0390: r##"
index 93c0bd6d6d836fb646f64c781d02d05949126e29..52f5d99838dc7c342047ed4bd0e19e74844e2b2f 100644 (file)
@@ -2,7 +2,6 @@
 authors = ["The Rust Project Developers"]
 name = "rustdoc"
 version = "0.0.0"
-build = "build.rs"
 
 [lib]
 name = "rustdoc"
@@ -11,11 +10,13 @@ crate-type = ["dylib"]
 
 [dependencies]
 arena = { path = "../libarena" }
+env_logger = { version = "0.4", default-features = false }
+log = "0.3"
 rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
 rustc_const_eval = { path = "../librustc_const_eval" }
-rustc_driver = { path = "../librustc_driver" }
 rustc_data_structures = { path = "../librustc_data_structures" }
+rustc_driver = { path = "../librustc_driver" }
 rustc_errors = { path = "../librustc_errors" }
 rustc_lint = { path = "../librustc_lint" }
 rustc_metadata = { path = "../librustc_metadata" }
@@ -24,7 +25,7 @@ rustc_trans = { path = "../librustc_trans" }
 serialize = { path = "../libserialize" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
-log = { path = "../liblog" }
+pulldown-cmark = { version = "0.0.14", default-features = false }
 
 [build-dependencies]
 build_helper = { path = "../build_helper" }
diff --git a/src/librustdoc/build.rs b/src/librustdoc/build.rs
deleted file mode 100644 (file)
index 9fa6406..0000000
+++ /dev/null
@@ -1,29 +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.
-
-extern crate build_helper;
-extern crate gcc;
-
-fn main() {
-    let src_dir = std::path::Path::new("../rt/hoedown/src");
-    build_helper::rerun_if_changed_anything_in_dir(src_dir);
-    let mut cfg = gcc::Config::new();
-    cfg.file("../rt/hoedown/src/autolink.c")
-       .file("../rt/hoedown/src/buffer.c")
-       .file("../rt/hoedown/src/document.c")
-       .file("../rt/hoedown/src/escape.c")
-       .file("../rt/hoedown/src/html.c")
-       .file("../rt/hoedown/src/html_blocks.c")
-       .file("../rt/hoedown/src/html_smartypants.c")
-       .file("../rt/hoedown/src/stack.c")
-       .file("../rt/hoedown/src/version.c")
-       .include(src_dir)
-       .compile("libhoedown.a");
-}
index c4476483186c7a35ed1de6bb20e9de0e52ff179f..cc30fdf56fc346c08b411d8b027a6400cfbb33f1 100644 (file)
@@ -232,14 +232,12 @@ fn build_type_alias(cx: &DocContext, did: DefId) -> clean::Typedef {
 
 pub fn build_impls(cx: &DocContext, did: DefId) -> Vec<clean::Item> {
     let tcx = cx.tcx;
-    tcx.populate_inherent_implementations_for_type_if_necessary(DUMMY_SP, did);
     let mut impls = Vec::new();
 
-    if let Some(i) = tcx.maps.inherent_impls.borrow().get(&did) {
-        for &did in i.iter() {
-            build_impl(cx, did, &mut impls);
-        }
+    for &did in ty::queries::inherent_impls::get(tcx, DUMMY_SP, did).iter() {
+        build_impl(cx, did, &mut impls);
     }
+
     // If this is the first time we've inlined something from another crate, then
     // we inline *all* impls from all the crates into this crate. Note that there's
     // currently no way for us to filter this based on type, and we likely need
index 0a9db2c26464ce6370b4c4c573742e469bf55959..a47d5f9937a02c337745038043e5d09735b9c2b2 100644 (file)
@@ -13,7 +13,7 @@
 use rustc::dep_graph::DepGraph;
 use rustc::session::{self, config};
 use rustc::hir::def_id::DefId;
-use rustc::hir::def::{Def, ExportMap};
+use rustc::hir::def::Def;
 use rustc::middle::privacy::AccessLevels;
 use rustc::ty::{self, TyCtxt, GlobalArenas};
 use rustc::hir::map as hir_map;
@@ -64,7 +64,6 @@ pub struct DocContext<'a, 'tcx: 'a> {
     pub ty_substs: RefCell<FxHashMap<Def, clean::Type>>,
     /// Table node id of lifetime parameter definition -> substituted lifetime
     pub lt_substs: RefCell<FxHashMap<ast::NodeId, clean::Lifetime>>,
-    pub export_map: ExportMap,
 }
 
 impl<'a, 'tcx> DocContext<'a, 'tcx> {
@@ -180,13 +179,13 @@ pub fn run_core(search_paths: SearchPaths,
             sess.fatal("Compilation failed, aborting rustdoc");
         }
 
-        let ty::CrateAnalysis { access_levels, export_map, .. } = analysis;
+        let ty::CrateAnalysis { access_levels, .. } = analysis;
 
         // Convert from a NodeId set to a DefId set since we don't always have easy access
         // to the map from defid -> nodeid
         let access_levels = AccessLevels {
-            map: access_levels.map.into_iter()
-                                  .map(|(k, v)| (tcx.hir.local_def_id(k), v))
+            map: access_levels.map.iter()
+                                  .map(|(&k, &v)| (tcx.hir.local_def_id(k), v))
                                   .collect()
         };
 
@@ -198,7 +197,6 @@ pub fn run_core(search_paths: SearchPaths,
             renderinfo: Default::default(),
             ty_substs: Default::default(),
             lt_substs: Default::default(),
-            export_map: export_map,
         };
         debug!("crate: {:?}", tcx.hir.krate());
 
index c7c5aabab97ae8002ce57b674d6623068c5090dd..117cfbabb52f7211379bdfa040aa9258967802a9 100644 (file)
 
 //! Markdown formatting for rustdoc
 //!
-//! This module implements markdown formatting through the hoedown C-library
-//! (bundled into the rust runtime). This module self-contains the C bindings
-//! and necessary legwork to render markdown, and exposes all of the
+//! This module implements markdown formatting through the pulldown-cmark
+//! rust-library. This module exposes all of the
 //! functionality through a unit-struct, `Markdown`, which has an implementation
 //! of `fmt::Display`. Example usage:
 //!
 //! ```rust,ignore
-//! use rustdoc::html::markdown::Markdown;
+//! use rustdoc::html::markdown::{Markdown, MarkdownOutputStyle};
 //!
 //! let s = "My *markdown* _text_";
-//! let html = format!("{}", Markdown(s));
+//! let html = format!("{}", Markdown(s, MarkdownOutputStyle::Fancy));
 //! // ... something using html
 //! ```
 
 #![allow(non_camel_case_types)]
 
-use libc;
 use std::ascii::AsciiExt;
 use std::cell::RefCell;
 use std::default::Default;
-use std::ffi::CString;
 use std::fmt::{self, Write};
-use std::slice;
 use std::str;
 use syntax::feature_gate::UnstableFeatures;
 use syntax::codemap::Span;
 use html::escape::Escape;
 use test;
 
+use pulldown_cmark::{self, Event, Parser, Tag};
+
+#[derive(Copy, Clone)]
+pub enum MarkdownOutputStyle {
+    Compact,
+    Fancy,
+}
+
+impl MarkdownOutputStyle {
+    pub fn is_compact(&self) -> bool {
+        match *self {
+            MarkdownOutputStyle::Compact => true,
+            _ => false,
+        }
+    }
+
+    pub fn is_fancy(&self) -> bool {
+        match *self {
+            MarkdownOutputStyle::Fancy => true,
+            _ => false,
+        }
+    }
+}
+
 /// A unit struct which has the `fmt::Display` trait implemented. When
 /// formatted, this struct will emit the HTML corresponding to the rendered
 /// version of the contained markdown string.
-pub struct Markdown<'a>(pub &'a str);
+// The second parameter is whether we need a shorter version or not.
+pub struct Markdown<'a>(pub &'a str, pub MarkdownOutputStyle);
 /// A unit struct like `Markdown`, that renders the markdown with a
 /// table of contents.
 pub struct MarkdownWithToc<'a>(pub &'a str);
 /// A unit struct like `Markdown`, that renders the markdown escaping HTML tags.
 pub struct MarkdownHtml<'a>(pub &'a str);
 
-const DEF_OUNIT: libc::size_t = 64;
-const HOEDOWN_EXT_NO_INTRA_EMPHASIS: libc::c_uint = 1 << 11;
-const HOEDOWN_EXT_TABLES: libc::c_uint = 1 << 0;
-const HOEDOWN_EXT_FENCED_CODE: libc::c_uint = 1 << 1;
-const HOEDOWN_EXT_AUTOLINK: libc::c_uint = 1 << 3;
-const HOEDOWN_EXT_STRIKETHROUGH: libc::c_uint = 1 << 4;
-const HOEDOWN_EXT_SUPERSCRIPT: libc::c_uint = 1 << 8;
-const HOEDOWN_EXT_FOOTNOTES: libc::c_uint = 1 << 2;
-const HOEDOWN_HTML_ESCAPE: libc::c_uint = 1 << 1;
-
-const HOEDOWN_EXTENSIONS: libc::c_uint =
-    HOEDOWN_EXT_NO_INTRA_EMPHASIS | HOEDOWN_EXT_TABLES |
-    HOEDOWN_EXT_FENCED_CODE | HOEDOWN_EXT_AUTOLINK |
-    HOEDOWN_EXT_STRIKETHROUGH | HOEDOWN_EXT_SUPERSCRIPT |
-    HOEDOWN_EXT_FOOTNOTES;
-
-enum hoedown_document {}
-
-type blockcodefn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
-                                 *const hoedown_buffer, *const hoedown_renderer_data,
-                                 libc::size_t);
-
-type blockquotefn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
-                                  *const hoedown_renderer_data, libc::size_t);
-
-type headerfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
-                              libc::c_int, *const hoedown_renderer_data,
-                              libc::size_t);
-
-type blockhtmlfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
-                                 *const hoedown_renderer_data, libc::size_t);
-
-type codespanfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
-                                *const hoedown_renderer_data, libc::size_t) -> libc::c_int;
-
-type linkfn = extern "C" fn (*mut hoedown_buffer, *const hoedown_buffer,
-                             *const hoedown_buffer, *const hoedown_buffer,
-                             *const hoedown_renderer_data, libc::size_t) -> libc::c_int;
-
-type entityfn = extern "C" fn (*mut hoedown_buffer, *const hoedown_buffer,
-                               *const hoedown_renderer_data, libc::size_t);
-
-type normaltextfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
-                                  *const hoedown_renderer_data, libc::size_t);
-
-#[repr(C)]
-struct hoedown_renderer_data {
-    opaque: *mut libc::c_void,
-}
-
-#[repr(C)]
-struct hoedown_renderer {
-    opaque: *mut libc::c_void,
-
-    blockcode: Option<blockcodefn>,
-    blockquote: Option<blockquotefn>,
-    header: Option<headerfn>,
-
-    other_block_level_callbacks: [libc::size_t; 11],
-
-    blockhtml: Option<blockhtmlfn>,
-
-    /* span level callbacks - NULL or return 0 prints the span verbatim */
-    autolink: libc::size_t, // unused
-    codespan: Option<codespanfn>,
-    other_span_level_callbacks_1: [libc::size_t; 7],
-    link: Option<linkfn>,
-    other_span_level_callbacks_2: [libc::size_t; 6],
-
-    /* low level callbacks - NULL copies input directly into the output */
-    entity: Option<entityfn>,
-    normal_text: Option<normaltextfn>,
-
-    /* header and footer */
-    other_callbacks: [libc::size_t; 2],
-}
-
-#[repr(C)]
-struct hoedown_html_renderer_state {
-    opaque: *mut libc::c_void,
-    toc_data: html_toc_data,
-    flags: libc::c_uint,
-    link_attributes: Option<extern "C" fn(*mut hoedown_buffer,
-                                          *const hoedown_buffer,
-                                          *const hoedown_renderer_data)>,
-}
-
-#[repr(C)]
-struct html_toc_data {
-    header_count: libc::c_int,
-    current_level: libc::c_int,
-    level_offset: libc::c_int,
-    nesting_level: libc::c_int,
-}
-
-struct MyOpaque {
-    dfltblk: extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
-                           *const hoedown_buffer, *const hoedown_renderer_data,
-                           libc::size_t),
-    toc_builder: Option<TocBuilder>,
-}
-
-#[repr(C)]
-struct hoedown_buffer {
-    data: *const u8,
-    size: libc::size_t,
-    asize: libc::size_t,
-    unit: libc::size_t,
-}
-
-extern {
-    fn hoedown_html_renderer_new(render_flags: libc::c_uint,
-                                 nesting_level: libc::c_int)
-        -> *mut hoedown_renderer;
-    fn hoedown_html_renderer_free(renderer: *mut hoedown_renderer);
-
-    fn hoedown_document_new(rndr: *const hoedown_renderer,
-                            extensions: libc::c_uint,
-                            max_nesting: libc::size_t) -> *mut hoedown_document;
-    fn hoedown_document_render(doc: *mut hoedown_document,
-                               ob: *mut hoedown_buffer,
-                               document: *const u8,
-                               doc_size: libc::size_t);
-    fn hoedown_document_free(md: *mut hoedown_document);
-
-    fn hoedown_buffer_new(unit: libc::size_t) -> *mut hoedown_buffer;
-    fn hoedown_buffer_put(b: *mut hoedown_buffer, c: *const libc::c_char,
-                          n: libc::size_t);
-    fn hoedown_buffer_puts(b: *mut hoedown_buffer, c: *const libc::c_char);
-    fn hoedown_buffer_free(b: *mut hoedown_buffer);
-
-}
-
-// hoedown_buffer helpers
-impl hoedown_buffer {
-    fn as_bytes(&self) -> &[u8] {
-        unsafe { slice::from_raw_parts(self.data, self.size as usize) }
-    }
-}
-
 /// Returns Some(code) if `s` is a line that should be stripped from
 /// documentation but used in example code. `code` is the portion of
 /// `s` that should be used in tests. (None for lines that should be
@@ -222,123 +103,126 @@ fn collapse_whitespace(s: &str) -> String {
     RefCell::new(None)
 });
 
+macro_rules! event_loop_break {
+    ($parser:expr, $toc_builder:expr, $shorter:expr, $buf:expr, $escape:expr, $id:expr,
+     $($end_event:pat)|*) => {{
+        fn inner(id: &mut Option<&mut String>, s: &str) {
+            if let Some(ref mut id) = *id {
+                id.push_str(s);
+            }
+        }
+        while let Some(event) = $parser.next() {
+            match event {
+                $($end_event)|* => break,
+                Event::Text(ref s) => {
+                    inner($id, s);
+                    if $escape {
+                        $buf.push_str(&format!("{}", Escape(s)));
+                    } else {
+                        $buf.push_str(s);
+                    }
+                }
+                Event::SoftBreak | Event::HardBreak if !$buf.is_empty() => {
+                    $buf.push(' ');
+                }
+                x => {
+                    looper($parser, &mut $buf, Some(x), $toc_builder, $shorter, $id);
+                }
+            }
+        }
+    }}
+}
 
 pub fn render(w: &mut fmt::Formatter,
               s: &str,
               print_toc: bool,
-              html_flags: libc::c_uint) -> fmt::Result {
-    extern fn block(ob: *mut hoedown_buffer, orig_text: *const hoedown_buffer,
-                    lang: *const hoedown_buffer, data: *const hoedown_renderer_data,
-                    line: libc::size_t) {
-        unsafe {
-            if orig_text.is_null() { return }
-
-            let opaque = (*data).opaque as *mut hoedown_html_renderer_state;
-            let my_opaque: &MyOpaque = &*((*opaque).opaque as *const MyOpaque);
-            let text = (*orig_text).as_bytes();
-            let origtext = str::from_utf8(text).unwrap();
-            let origtext = origtext.trim_left();
-            debug!("docblock: ==============\n{:?}\n=======", text);
-            let rendered = if lang.is_null() || origtext.is_empty() {
-                false
-            } else {
-                let rlang = (*lang).as_bytes();
-                let rlang = str::from_utf8(rlang).unwrap();
-                if !LangString::parse(rlang).rust {
-                    (my_opaque.dfltblk)(ob, orig_text, lang,
-                                        opaque as *const hoedown_renderer_data,
-                                        line);
-                    true
-                } else {
-                    false
+              shorter: MarkdownOutputStyle) -> fmt::Result {
+    fn code_block(parser: &mut Parser, buffer: &mut String, lang: &str) {
+        let mut origtext = String::new();
+        while let Some(event) = parser.next() {
+            match event {
+                Event::End(Tag::CodeBlock(_)) => break,
+                Event::Text(ref s) => {
+                    origtext.push_str(s);
                 }
-            };
+                _ => {}
+            }
+        }
+        let origtext = origtext.trim_left();
+        debug!("docblock: ==============\n{:?}\n=======", origtext);
 
-            let lines = origtext.lines().filter(|l| {
-                stripped_filtered_line(*l).is_none()
-            });
-            let text = lines.collect::<Vec<&str>>().join("\n");
-            if rendered { return }
-            PLAYGROUND.with(|play| {
-                // insert newline to clearly separate it from the
-                // previous block so we can shorten the html output
-                let mut s = String::from("\n");
-                let playground_button = play.borrow().as_ref().and_then(|&(ref krate, ref url)| {
-                    if url.is_empty() {
-                        return None;
-                    }
-                    let test = origtext.lines().map(|l| {
-                        stripped_filtered_line(l).unwrap_or(l)
-                    }).collect::<Vec<&str>>().join("\n");
-                    let krate = krate.as_ref().map(|s| &**s);
-                    let test = test::maketest(&test, krate, false,
-                                              &Default::default());
-                    let channel = if test.contains("#![feature(") {
-                        "&amp;version=nightly"
+        let lines = origtext.lines().filter(|l| {
+            stripped_filtered_line(*l).is_none()
+        });
+        let text = lines.collect::<Vec<&str>>().join("\n");
+        let block_info = if lang.is_empty() {
+            LangString::all_false()
+        } else {
+            LangString::parse(lang)
+        };
+        if !block_info.rust {
+            buffer.push_str(&format!("<pre><code class=\"language-{}\">{}</code></pre>",
+                            lang, text));
+            return
+        }
+        PLAYGROUND.with(|play| {
+            // insert newline to clearly separate it from the
+            // previous block so we can shorten the html output
+            buffer.push('\n');
+            let playground_button = play.borrow().as_ref().and_then(|&(ref krate, ref url)| {
+                if url.is_empty() {
+                    return None;
+                }
+                let test = origtext.lines().map(|l| {
+                    stripped_filtered_line(l).unwrap_or(l)
+                }).collect::<Vec<&str>>().join("\n");
+                let krate = krate.as_ref().map(|s| &**s);
+                let test = test::maketest(&test, krate, false,
+                                          &Default::default());
+                let channel = if test.contains("#![feature(") {
+                    "&amp;version=nightly"
+                } else {
+                    ""
+                };
+                // These characters don't need to be escaped in a URI.
+                // FIXME: use a library function for percent encoding.
+                fn dont_escape(c: u8) -> bool {
+                    (b'a' <= c && c <= b'z') ||
+                    (b'A' <= c && c <= b'Z') ||
+                    (b'0' <= c && c <= b'9') ||
+                    c == b'-' || c == b'_' || c == b'.' ||
+                    c == b'~' || c == b'!' || c == b'\'' ||
+                    c == b'(' || c == b')' || c == b'*'
+                }
+                let mut test_escaped = String::new();
+                for b in test.bytes() {
+                    if dont_escape(b) {
+                        test_escaped.push(char::from(b));
                     } else {
-                        ""
-                    };
-                    // These characters don't need to be escaped in a URI.
-                    // FIXME: use a library function for percent encoding.
-                    fn dont_escape(c: u8) -> bool {
-                        (b'a' <= c && c <= b'z') ||
-                        (b'A' <= c && c <= b'Z') ||
-                        (b'0' <= c && c <= b'9') ||
-                        c == b'-' || c == b'_' || c == b'.' ||
-                        c == b'~' || c == b'!' || c == b'\'' ||
-                        c == b'(' || c == b')' || c == b'*'
+                        write!(test_escaped, "%{:02X}", b).unwrap();
                     }
-                    let mut test_escaped = String::new();
-                    for b in test.bytes() {
-                        if dont_escape(b) {
-                            test_escaped.push(char::from(b));
-                        } else {
-                            write!(test_escaped, "%{:02X}", b).unwrap();
-                        }
-                    }
-                    Some(format!(
-                        r#"<a class="test-arrow" target="_blank" href="{}?code={}{}">Run</a>"#,
-                        url, test_escaped, channel
-                    ))
-                });
-                s.push_str(&highlight::render_with_highlighting(
-                               &text,
-                               Some("rust-example-rendered"),
-                               None,
-                               playground_button.as_ref().map(String::as_str)));
-                let output = CString::new(s).unwrap();
-                hoedown_buffer_puts(ob, output.as_ptr());
-            })
-        }
+                }
+                Some(format!(
+                    r#"<a class="test-arrow" target="_blank" href="{}?code={}{}">Run</a>"#,
+                    url, test_escaped, channel
+                ))
+            });
+            buffer.push_str(&highlight::render_with_highlighting(
+                            &text,
+                            Some("rust-example-rendered"),
+                            None,
+                            playground_button.as_ref().map(String::as_str)));
+        });
     }
 
-    extern fn header(ob: *mut hoedown_buffer, text: *const hoedown_buffer,
-                     level: libc::c_int, data: *const hoedown_renderer_data,
-                     _: libc::size_t) {
-        // hoedown does this, we may as well too
-        unsafe { hoedown_buffer_puts(ob, "\n\0".as_ptr() as *const _); }
+    fn heading(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
+               shorter: MarkdownOutputStyle, level: i32) {
+        let mut ret = String::new();
+        let mut id = String::new();
+        event_loop_break!(parser, toc_builder, shorter, ret, true, &mut Some(&mut id),
+                          Event::End(Tag::Header(_)));
+        ret = ret.trim_right().to_owned();
 
-        // Extract the text provided
-        let s = if text.is_null() {
-            "".to_owned()
-        } else {
-            let s = unsafe { (*text).as_bytes() };
-            str::from_utf8(&s).unwrap().to_owned()
-        };
-
-        // Discard '<em>', '<code>' tags and some escaped characters,
-        // transform the contents of the header into a hyphenated string
-        // without non-alphanumeric characters other than '-' and '_'.
-        //
-        // This is a terrible hack working around how hoedown gives us rendered
-        // html for text rather than the raw text.
-        let mut id = s.clone();
-        let repl_sub = vec!["<em>", "</em>", "<code>", "</code>",
-                            "<strong>", "</strong>",
-                            "&lt;", "&gt;", "&amp;", "&#39;", "&quot;"];
-        for sub in repl_sub {
-            id = id.replace(sub, "");
-        }
         let id = id.chars().filter_map(|c| {
             if c.is_alphanumeric() || c == '-' || c == '_' {
                 if c.is_ascii() {
@@ -353,145 +237,309 @@ fn dont_escape(c: u8) -> bool {
             }
         }).collect::<String>();
 
-        let opaque = unsafe { (*data).opaque as *mut hoedown_html_renderer_state };
-        let opaque = unsafe { &mut *((*opaque).opaque as *mut MyOpaque) };
-
         let id = derive_id(id);
 
-        let sec = opaque.toc_builder.as_mut().map_or("".to_owned(), |builder| {
-            format!("{} ", builder.push(level as u32, s.clone(), id.clone()))
+        let sec = toc_builder.as_mut().map_or("".to_owned(), |builder| {
+            format!("{} ", builder.push(level as u32, ret.clone(), id.clone()))
         });
 
         // Render the HTML
-        let text = format!("<h{lvl} id='{id}' class='section-header'>\
-                           <a href='#{id}'>{sec}{}</a></h{lvl}>",
-                           s, lvl = level, id = id, sec = sec);
-
-        let text = CString::new(text).unwrap();
-        unsafe { hoedown_buffer_puts(ob, text.as_ptr()) }
-    }
-
-    extern fn codespan(
-        ob: *mut hoedown_buffer,
-        text: *const hoedown_buffer,
-        _: *const hoedown_renderer_data,
-        _: libc::size_t
-    ) -> libc::c_int {
-        let content = if text.is_null() {
-            "".to_owned()
-        } else {
-            let bytes = unsafe { (*text).as_bytes() };
-            let s = str::from_utf8(bytes).unwrap();
-            collapse_whitespace(s)
-        };
+        buffer.push_str(&format!("<h{lvl} id=\"{id}\" class=\"section-header\">\
+                                  <a href=\"#{id}\">{sec}{}</a></h{lvl}>",
+                                 ret, lvl = level, id = id, sec = sec));
+    }
 
-        let content = format!("<code>{}</code>", Escape(&content));
-        let element = CString::new(content).unwrap();
-        unsafe { hoedown_buffer_puts(ob, element.as_ptr()); }
-        // Return anything except 0, which would mean "also print the code span verbatim".
-        1
+    fn inline_code(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
+                   shorter: MarkdownOutputStyle, id: &mut Option<&mut String>) {
+        let mut content = String::new();
+        event_loop_break!(parser, toc_builder, shorter, content, false, id, Event::End(Tag::Code));
+        buffer.push_str(&format!("<code>{}</code>",
+                                 Escape(&collapse_whitespace(content.trim_right()))));
     }
 
-    unsafe {
-        let ob = hoedown_buffer_new(DEF_OUNIT);
-        let renderer = hoedown_html_renderer_new(html_flags, 0);
-        let mut opaque = MyOpaque {
-            dfltblk: (*renderer).blockcode.unwrap(),
-            toc_builder: if print_toc {Some(TocBuilder::new())} else {None}
-        };
-        (*((*renderer).opaque as *mut hoedown_html_renderer_state)).opaque
-                = &mut opaque as *mut _ as *mut libc::c_void;
-        (*renderer).blockcode = Some(block);
-        (*renderer).header = Some(header);
-        (*renderer).codespan = Some(codespan);
+    fn link(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
+            shorter: MarkdownOutputStyle, url: &str, mut title: String,
+            id: &mut Option<&mut String>) {
+        event_loop_break!(parser, toc_builder, shorter, title, true, id,
+                          Event::End(Tag::Link(_, _)));
+        buffer.push_str(&format!("<a href=\"{}\">{}</a>", url, title));
+    }
 
-        let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16);
-        hoedown_document_render(document, ob, s.as_ptr(),
-                                s.len() as libc::size_t);
-        hoedown_document_free(document);
+    fn paragraph(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
+                 shorter: MarkdownOutputStyle, id: &mut Option<&mut String>) {
+        let mut content = String::new();
+        event_loop_break!(parser, toc_builder, shorter, content, true, id,
+                          Event::End(Tag::Paragraph));
+        buffer.push_str(&format!("<p>{}</p>", content.trim_right()));
+    }
 
-        hoedown_html_renderer_free(renderer);
+    fn table_cell(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
+                  shorter: MarkdownOutputStyle) {
+        let mut content = String::new();
+        event_loop_break!(parser, toc_builder, shorter, content, true, &mut None,
+                          Event::End(Tag::TableHead) |
+                              Event::End(Tag::Table(_)) |
+                              Event::End(Tag::TableRow) |
+                              Event::End(Tag::TableCell));
+        buffer.push_str(&format!("<td>{}</td>", content.trim()));
+    }
 
-        let mut ret = opaque.toc_builder.map_or(Ok(()), |builder| {
-            write!(w, "<nav id=\"TOC\">{}</nav>", builder.into_toc())
-        });
+    fn table_row(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
+                 shorter: MarkdownOutputStyle) {
+        let mut content = String::new();
+        while let Some(event) = parser.next() {
+            match event {
+                Event::End(Tag::TableHead) |
+                    Event::End(Tag::Table(_)) |
+                    Event::End(Tag::TableRow) => break,
+                Event::Start(Tag::TableCell) => {
+                    table_cell(parser, &mut content, toc_builder, shorter);
+                }
+                x => {
+                    looper(parser, &mut content, Some(x), toc_builder, shorter, &mut None);
+                }
+            }
+        }
+        buffer.push_str(&format!("<tr>{}</tr>", content));
+    }
 
-        if ret.is_ok() {
-            let buf = (*ob).as_bytes();
-            ret = w.write_str(str::from_utf8(buf).unwrap());
+    fn table_head(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
+                  shorter: MarkdownOutputStyle) {
+        let mut content = String::new();
+        while let Some(event) = parser.next() {
+            match event {
+                Event::End(Tag::TableHead) | Event::End(Tag::Table(_)) => break,
+                Event::Start(Tag::TableCell) => {
+                    table_cell(parser, &mut content, toc_builder, shorter);
+                }
+                x => {
+                    looper(parser, &mut content, Some(x), toc_builder, shorter, &mut None);
+                }
+            }
+        }
+        if !content.is_empty() {
+            buffer.push_str(&format!("<thead><tr>{}</tr></thead>", content.replace("td>", "th>")));
         }
-        hoedown_buffer_free(ob);
-        ret
     }
-}
 
-pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span) {
-    extern fn block(_ob: *mut hoedown_buffer,
-                    text: *const hoedown_buffer,
-                    lang: *const hoedown_buffer,
-                    data: *const hoedown_renderer_data,
-                    line: libc::size_t) {
-        unsafe {
-            if text.is_null() { return }
-            let block_info = if lang.is_null() {
-                LangString::all_false()
-            } else {
-                let lang = (*lang).as_bytes();
-                let s = str::from_utf8(lang).unwrap();
-                LangString::parse(s)
-            };
-            if !block_info.rust { return }
-            let text = (*text).as_bytes();
-            let opaque = (*data).opaque as *mut hoedown_html_renderer_state;
-            let tests = &mut *((*opaque).opaque as *mut ::test::Collector);
-            let text = str::from_utf8(text).unwrap();
-            let lines = text.lines().map(|l| {
-                stripped_filtered_line(l).unwrap_or(l)
-            });
-            let text = lines.collect::<Vec<&str>>().join("\n");
-            let line = tests.get_line() + line;
-            let filename = tests.get_filename();
-            tests.add_test(text.to_owned(),
-                           block_info.should_panic, block_info.no_run,
-                           block_info.ignore, block_info.test_harness,
-                           block_info.compile_fail, block_info.error_codes,
-                           line, filename);
+    fn table(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
+             shorter: MarkdownOutputStyle) {
+        let mut content = String::new();
+        let mut rows = String::new();
+        while let Some(event) = parser.next() {
+            match event {
+                Event::End(Tag::Table(_)) => break,
+                Event::Start(Tag::TableHead) => {
+                    table_head(parser, &mut content, toc_builder, shorter);
+                }
+                Event::Start(Tag::TableRow) => {
+                    table_row(parser, &mut rows, toc_builder, shorter);
+                }
+                _ => {}
+            }
         }
+        buffer.push_str(&format!("<table>{}{}</table>",
+                                 content,
+                                 if shorter.is_compact() || rows.is_empty() {
+                                     String::new()
+                                 } else {
+                                     format!("<tbody>{}</tbody>", rows)
+                                 }));
     }
 
-    extern fn header(_ob: *mut hoedown_buffer,
-                     text: *const hoedown_buffer,
-                     level: libc::c_int, data: *const hoedown_renderer_data,
-                     _: libc::size_t) {
-        unsafe {
-            let opaque = (*data).opaque as *mut hoedown_html_renderer_state;
-            let tests = &mut *((*opaque).opaque as *mut ::test::Collector);
-            if text.is_null() {
-                tests.register_header("", level as u32);
-            } else {
-                let text = (*text).as_bytes();
-                let text = str::from_utf8(text).unwrap();
-                tests.register_header(text, level as u32);
+    fn blockquote(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
+                  shorter: MarkdownOutputStyle) {
+        let mut content = String::new();
+        event_loop_break!(parser, toc_builder, shorter, content, true, &mut None,
+                          Event::End(Tag::BlockQuote));
+        buffer.push_str(&format!("<blockquote>{}</blockquote>", content.trim_right()));
+    }
+
+    fn list_item(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
+                 shorter: MarkdownOutputStyle) {
+        let mut content = String::new();
+        while let Some(event) = parser.next() {
+            match event {
+                Event::End(Tag::Item) => break,
+                Event::Text(ref s) => {
+                    content.push_str(&format!("{}", Escape(s)));
+                }
+                x => {
+                    looper(parser, &mut content, Some(x), toc_builder, shorter, &mut None);
+                }
+            }
+        }
+        buffer.push_str(&format!("<li>{}</li>", content));
+    }
+
+    fn list(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
+            shorter: MarkdownOutputStyle) {
+        let mut content = String::new();
+        while let Some(event) = parser.next() {
+            match event {
+                Event::End(Tag::List(_)) => break,
+                Event::Start(Tag::Item) => {
+                    list_item(parser, &mut content, toc_builder, shorter);
+                }
+                x => {
+                    looper(parser, &mut content, Some(x), toc_builder, shorter, &mut None);
+                }
+            }
+        }
+        buffer.push_str(&format!("<ul>{}</ul>", content));
+    }
+
+    fn emphasis(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
+                shorter: MarkdownOutputStyle, id: &mut Option<&mut String>) {
+        let mut content = String::new();
+        event_loop_break!(parser, toc_builder, shorter, content, false, id,
+                          Event::End(Tag::Emphasis));
+        buffer.push_str(&format!("<em>{}</em>", content));
+    }
+
+    fn strong(parser: &mut Parser, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
+              shorter: MarkdownOutputStyle, id: &mut Option<&mut String>) {
+        let mut content = String::new();
+        event_loop_break!(parser, toc_builder, shorter, content, false, id,
+                          Event::End(Tag::Strong));
+        buffer.push_str(&format!("<strong>{}</strong>", content));
+    }
+
+    fn looper<'a>(parser: &'a mut Parser, buffer: &mut String, next_event: Option<Event<'a>>,
+                  toc_builder: &mut Option<TocBuilder>, shorter: MarkdownOutputStyle,
+                  id: &mut Option<&mut String>) -> bool {
+        if let Some(event) = next_event {
+            match event {
+                Event::Start(Tag::CodeBlock(lang)) => {
+                    code_block(parser, buffer, &*lang);
+                }
+                Event::Start(Tag::Header(level)) => {
+                    heading(parser, buffer, toc_builder, shorter, level);
+                }
+                Event::Start(Tag::Code) => {
+                    inline_code(parser, buffer, toc_builder, shorter, id);
+                }
+                Event::Start(Tag::Paragraph) => {
+                    paragraph(parser, buffer, toc_builder, shorter, id);
+                }
+                Event::Start(Tag::Link(ref url, ref t)) => {
+                    link(parser, buffer, toc_builder, shorter, url, t.as_ref().to_owned(), id);
+                }
+                Event::Start(Tag::Table(_)) => {
+                    table(parser, buffer, toc_builder, shorter);
+                }
+                Event::Start(Tag::BlockQuote) => {
+                    blockquote(parser, buffer, toc_builder, shorter);
+                }
+                Event::Start(Tag::List(_)) => {
+                    list(parser, buffer, toc_builder, shorter);
+                }
+                Event::Start(Tag::Emphasis) => {
+                    emphasis(parser, buffer, toc_builder, shorter, id);
+                }
+                Event::Start(Tag::Strong) => {
+                    strong(parser, buffer, toc_builder, shorter, id);
+                }
+                Event::Html(h) | Event::InlineHtml(h) => {
+                    buffer.push_str(&*h);
+                }
+                _ => {}
             }
+            shorter.is_fancy()
+        } else {
+            false
+        }
+    }
+
+    let mut toc_builder = if print_toc {
+        Some(TocBuilder::new())
+    } else {
+        None
+    };
+    let mut buffer = String::new();
+    let mut parser = Parser::new_ext(s, pulldown_cmark::OPTION_ENABLE_TABLES);
+    loop {
+        let next_event = parser.next();
+        if !looper(&mut parser, &mut buffer, next_event, &mut toc_builder, shorter, &mut None) {
+            break
         }
     }
+    let mut ret = toc_builder.map_or(Ok(()), |builder| {
+        write!(w, "<nav id=\"TOC\">{}</nav>", builder.into_toc())
+    });
+
+    if ret.is_ok() {
+        ret = w.write_str(&buffer);
+    }
+    ret
+}
 
+pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span) {
     tests.set_position(position);
-    unsafe {
-        let ob = hoedown_buffer_new(DEF_OUNIT);
-        let renderer = hoedown_html_renderer_new(0, 0);
-        (*renderer).blockcode = Some(block);
-        (*renderer).header = Some(header);
-        (*((*renderer).opaque as *mut hoedown_html_renderer_state)).opaque
-                = tests as *mut _ as *mut libc::c_void;
-
-        let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16);
-        hoedown_document_render(document, ob, doc.as_ptr(),
-                                doc.len() as libc::size_t);
-        hoedown_document_free(document);
-
-        hoedown_html_renderer_free(renderer);
-        hoedown_buffer_free(ob);
+
+    let mut parser = Parser::new(doc);
+    let mut prev_offset = 0;
+    let mut nb_lines = 0;
+    let mut register_header = None;
+    'main: while let Some(event) = parser.next() {
+        match event {
+            Event::Start(Tag::CodeBlock(s)) => {
+                let block_info = if s.is_empty() {
+                    LangString::all_false()
+                } else {
+                    LangString::parse(&*s)
+                };
+                if !block_info.rust {
+                    continue
+                }
+                let mut test_s = String::new();
+                let mut offset = None;
+                loop {
+                    let event = parser.next();
+                    if let Some(event) = event {
+                        match event {
+                            Event::End(Tag::CodeBlock(_)) => break,
+                            Event::Text(ref s) => {
+                                test_s.push_str(s);
+                                if offset.is_none() {
+                                    offset = Some(parser.get_offset());
+                                }
+                            }
+                            _ => {}
+                        }
+                    } else {
+                        break 'main;
+                    }
+                }
+                let offset = offset.unwrap_or(0);
+                let lines = test_s.lines().map(|l| {
+                    stripped_filtered_line(l).unwrap_or(l)
+                });
+                let text = lines.collect::<Vec<&str>>().join("\n");
+                nb_lines += doc[prev_offset..offset].lines().count();
+                let line = tests.get_line() + (nb_lines - 1);
+                let filename = tests.get_filename();
+                tests.add_test(text.to_owned(),
+                               block_info.should_panic, block_info.no_run,
+                               block_info.ignore, block_info.test_harness,
+                               block_info.compile_fail, block_info.error_codes,
+                               line, filename);
+                prev_offset = offset;
+            }
+            Event::Start(Tag::Header(level)) => {
+                register_header = Some(level as u32);
+            }
+            Event::Text(ref s) if register_header.is_some() => {
+                let level = register_header.unwrap();
+                if s.is_empty() {
+                    tests.register_header("", level);
+                } else {
+                    tests.register_header(s, level);
+                }
+                register_header = None;
+            }
+            _ => {}
+        }
     }
 }
 
@@ -570,17 +618,17 @@ fn parse(string: &str) -> LangString {
 
 impl<'a> fmt::Display for Markdown<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        let Markdown(md) = *self;
+        let Markdown(md, shorter) = *self;
         // This is actually common enough to special-case
         if md.is_empty() { return Ok(()) }
-        render(fmt, md, false, 0)
+        render(fmt, md, false, shorter)
     }
 }
 
 impl<'a> fmt::Display for MarkdownWithToc<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let MarkdownWithToc(md) = *self;
-        render(fmt, md, true, 0)
+        render(fmt, md, true, MarkdownOutputStyle::Fancy)
     }
 }
 
@@ -589,62 +637,67 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let MarkdownHtml(md) = *self;
         // This is actually common enough to special-case
         if md.is_empty() { return Ok(()) }
-        render(fmt, md, false, HOEDOWN_HTML_ESCAPE)
+        render(fmt, md, false, MarkdownOutputStyle::Fancy)
     }
 }
 
 pub fn plain_summary_line(md: &str) -> String {
-    extern fn link(_ob: *mut hoedown_buffer,
-                       _link: *const hoedown_buffer,
-                       _title: *const hoedown_buffer,
-                       content: *const hoedown_buffer,
-                       data: *const hoedown_renderer_data,
-                       _: libc::size_t) -> libc::c_int
-    {
-        unsafe {
-            if !content.is_null() && (*content).size > 0 {
-                let ob = (*data).opaque as *mut hoedown_buffer;
-                hoedown_buffer_put(ob, (*content).data as *const libc::c_char,
-                                   (*content).size);
-            }
-        }
-        1
-    }
-
-    extern fn normal_text(_ob: *mut hoedown_buffer,
-                          text: *const hoedown_buffer,
-                          data: *const hoedown_renderer_data,
-                          _: libc::size_t)
-    {
-        unsafe {
-            let ob = (*data).opaque as *mut hoedown_buffer;
-            hoedown_buffer_put(ob, (*text).data as *const libc::c_char,
-                               (*text).size);
-        }
+    struct ParserWrapper<'a> {
+        inner: Parser<'a>,
+        is_in: isize,
+        is_first: bool,
     }
 
-    unsafe {
-        let ob = hoedown_buffer_new(DEF_OUNIT);
-        let mut plain_renderer: hoedown_renderer = ::std::mem::zeroed();
-        let renderer: *mut hoedown_renderer = &mut plain_renderer;
-        (*renderer).opaque = ob as *mut libc::c_void;
-        (*renderer).link = Some(link);
-        (*renderer).normal_text = Some(normal_text);
+    impl<'a> Iterator for ParserWrapper<'a> {
+        type Item = String;
 
-        let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16);
-        hoedown_document_render(document, ob, md.as_ptr(),
-                                md.len() as libc::size_t);
-        hoedown_document_free(document);
-        let plain_slice = (*ob).as_bytes();
-        let plain = str::from_utf8(plain_slice).unwrap_or("").to_owned();
-        hoedown_buffer_free(ob);
-        plain
+        fn next(&mut self) -> Option<String> {
+            let next_event = self.inner.next();
+            if next_event.is_none() {
+                return None
+            }
+            let next_event = next_event.unwrap();
+            let (ret, is_in) = match next_event {
+                Event::Start(Tag::Paragraph) => (None, 1),
+                Event::Start(Tag::Link(_, ref t)) if !self.is_first => {
+                    (Some(t.as_ref().to_owned()), 1)
+                }
+                Event::Start(Tag::Code) => (Some("`".to_owned()), 1),
+                Event::End(Tag::Code) => (Some("`".to_owned()), -1),
+                Event::Start(Tag::Header(_)) => (None, 1),
+                Event::Text(ref s) if self.is_in > 0 => (Some(s.as_ref().to_owned()), 0),
+                Event::End(Tag::Link(_, ref t)) => (Some(t.as_ref().to_owned()), -1),
+                Event::End(Tag::Paragraph) | Event::End(Tag::Header(_)) => (None, -1),
+                _ => (None, 0),
+            };
+            if is_in > 0 || (is_in < 0 && self.is_in > 0) {
+                self.is_in += is_in;
+            }
+            if ret.is_some() {
+                self.is_first = false;
+                ret
+            } else {
+                Some(String::new())
+            }
+        }
+    }
+    let mut s = String::with_capacity(md.len() * 3 / 2);
+    let mut p = ParserWrapper {
+        inner: Parser::new(md),
+        is_in: 0,
+        is_first: true,
+    };
+    while let Some(t) = p.next() {
+        if !t.is_empty() {
+            s.push_str(&t);
+        }
     }
+    s
 }
 
 #[cfg(test)]
 mod tests {
-    use super::{LangString, Markdown, MarkdownHtml};
+    use super::{LangString, Markdown, MarkdownHtml, MarkdownOutputStyle};
     use super::plain_summary_line;
     use html::render::reset_ids;
 
@@ -684,52 +737,52 @@ fn t(s: &str,
     #[test]
     fn issue_17736() {
         let markdown = "# title";
-        format!("{}", Markdown(markdown));
+        format!("{}", Markdown(markdown, MarkdownOutputStyle::Fancy));
         reset_ids(true);
     }
 
     #[test]
     fn test_header() {
         fn t(input: &str, expect: &str) {
-            let output = format!("{}", Markdown(input));
-            assert_eq!(output, expect);
+            let output = format!("{}", Markdown(input, MarkdownOutputStyle::Fancy));
+            assert_eq!(output, expect, "original: {}", input);
             reset_ids(true);
         }
 
-        t("# Foo bar", "\n<h1 id='foo-bar' class='section-header'>\
-          <a href='#foo-bar'>Foo bar</a></h1>");
-        t("## Foo-bar_baz qux", "\n<h2 id='foo-bar_baz-qux' class=\'section-\
-          header'><a href='#foo-bar_baz-qux'>Foo-bar_baz qux</a></h2>");
+        t("# Foo bar", "<h1 id=\"foo-bar\" class=\"section-header\">\
+          <a href=\"#foo-bar\">Foo bar</a></h1>");
+        t("## Foo-bar_baz qux", "<h2 id=\"foo-bar_baz-qux\" class=\"section-\
+          header\"><a href=\"#foo-bar_baz-qux\">Foo-bar_baz qux</a></h2>");
         t("### **Foo** *bar* baz!?!& -_qux_-%",
-          "\n<h3 id='foo-bar-baz--_qux_-' class='section-header'>\
-          <a href='#foo-bar-baz--_qux_-'><strong>Foo</strong> \
-          <em>bar</em> baz!?!&amp; -_qux_-%</a></h3>");
-        t("####**Foo?** & \\*bar?!*  _`baz`_ ❤ #qux",
-          "\n<h4 id='foo--bar--baz--qux' class='section-header'>\
-          <a href='#foo--bar--baz--qux'><strong>Foo?</strong> &amp; *bar?!*  \
+          "<h3 id=\"foo-bar-baz--qux-\" class=\"section-header\">\
+          <a href=\"#foo-bar-baz--qux-\"><strong>Foo</strong> \
+          <em>bar</em> baz!?!&amp; -<em>qux</em>-%</a></h3>");
+        t("#### **Foo?** & \\*bar?!*  _`baz`_ ❤ #qux",
+          "<h4 id=\"foo--bar--baz--qux\" class=\"section-header\">\
+          <a href=\"#foo--bar--baz--qux\"><strong>Foo?</strong> &amp; *bar?!*  \
           <em><code>baz</code></em> ❤ #qux</a></h4>");
     }
 
     #[test]
     fn test_header_ids_multiple_blocks() {
         fn t(input: &str, expect: &str) {
-            let output = format!("{}", Markdown(input));
-            assert_eq!(output, expect);
+            let output = format!("{}", Markdown(input, MarkdownOutputStyle::Fancy));
+            assert_eq!(output, expect, "original: {}", input);
         }
 
         let test = || {
-            t("# Example", "\n<h1 id='example' class='section-header'>\
-              <a href='#example'>Example</a></h1>");
-            t("# Panics", "\n<h1 id='panics' class='section-header'>\
-              <a href='#panics'>Panics</a></h1>");
-            t("# Example", "\n<h1 id='example-1' class='section-header'>\
-              <a href='#example-1'>Example</a></h1>");
-            t("# Main", "\n<h1 id='main-1' class='section-header'>\
-              <a href='#main-1'>Main</a></h1>");
-            t("# Example", "\n<h1 id='example-2' class='section-header'>\
-              <a href='#example-2'>Example</a></h1>");
-            t("# Panics", "\n<h1 id='panics-1' class='section-header'>\
-              <a href='#panics-1'>Panics</a></h1>");
+            t("# Example", "<h1 id=\"example\" class=\"section-header\">\
+              <a href=\"#example\">Example</a></h1>");
+            t("# Panics", "<h1 id=\"panics\" class=\"section-header\">\
+              <a href=\"#panics\">Panics</a></h1>");
+            t("# Example", "<h1 id=\"example-1\" class=\"section-header\">\
+              <a href=\"#example-1\">Example</a></h1>");
+            t("# Main", "<h1 id=\"main-1\" class=\"section-header\">\
+              <a href=\"#main-1\">Main</a></h1>");
+            t("# Example", "<h1 id=\"example-2\" class=\"section-header\">\
+              <a href=\"#example-2\">Example</a></h1>");
+            t("# Panics", "<h1 id=\"panics-1\" class=\"section-header\">\
+              <a href=\"#panics-1\">Panics</a></h1>");
         };
         test();
         reset_ids(true);
@@ -740,7 +793,7 @@ fn t(input: &str, expect: &str) {
     fn test_plain_summary_line() {
         fn t(input: &str, expect: &str) {
             let output = plain_summary_line(input);
-            assert_eq!(output, expect);
+            assert_eq!(output, expect, "original: {}", input);
         }
 
         t("hello [Rust](https://www.rust-lang.org) :)", "hello Rust :)");
@@ -754,10 +807,10 @@ fn t(input: &str, expect: &str) {
     fn test_markdown_html_escape() {
         fn t(input: &str, expect: &str) {
             let output = format!("{}", MarkdownHtml(input));
-            assert_eq!(output, expect);
+            assert_eq!(output, expect, "original: {}", input);
         }
 
-        t("`Struct<'a, T>`", "<p><code>Struct&lt;&#39;a, T&gt;</code></p>\n");
-        t("Struct<'a, T>", "<p>Struct&lt;&#39;a, T&gt;</p>\n");
+        t("`Struct<'a, T>`", "<p><code>Struct&lt;&#39;a, T&gt;</code></p>");
+        t("Struct<'a, T>", "<p>Struct&lt;&#39;a, T&gt;</p>");
     }
 }
index 5c94032c6b9cf74df6fd754e13e4bd4b4079892a..f0b624105e3475de90a56d967e2a23b1013d8093 100644 (file)
@@ -72,7 +72,7 @@
 use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace};
 use html::format::fmt_impl_for_trait_page;
 use html::item_type::ItemType;
-use html::markdown::{self, Markdown, MarkdownHtml};
+use html::markdown::{self, Markdown, MarkdownHtml, MarkdownOutputStyle};
 use html::{highlight, layout};
 
 /// A pair of name and its optional document.
@@ -1650,7 +1650,8 @@ fn document_short(w: &mut fmt::Formatter, item: &clean::Item, link: AssocItemLin
         } else {
             format!("{}", &plain_summary_line(Some(s)))
         };
-        write!(w, "<div class='docblock'>{}</div>", Markdown(&markdown))?;
+        write!(w, "<div class='docblock'>{}</div>",
+               Markdown(&markdown, MarkdownOutputStyle::Fancy))?;
     }
     Ok(())
 }
@@ -1683,7 +1684,8 @@ fn get_doc_value(item: &clean::Item) -> Option<&str> {
 fn document_full(w: &mut fmt::Formatter, item: &clean::Item) -> fmt::Result {
     if let Some(s) = get_doc_value(item) {
         write!(w, "<div class='docblock'>{}</div>",
-               Markdown(&format!("{}{}", md_render_assoc_item(item), s)))?;
+               Markdown(&format!("{}{}", md_render_assoc_item(item), s),
+                                 MarkdownOutputStyle::Fancy))?;
     }
     Ok(())
 }
@@ -1871,7 +1873,8 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: usize, idx2: usize) -> Ordering
                        </tr>",
                        name = *myitem.name.as_ref().unwrap(),
                        stab_docs = stab_docs,
-                       docs = shorter(Some(&Markdown(doc_value).to_string())),
+                       docs = shorter(Some(&Markdown(doc_value,
+                                                     MarkdownOutputStyle::Compact).to_string())),
                        class = myitem.type_(),
                        stab = myitem.stability_class().unwrap_or("".to_string()),
                        unsafety_flag = unsafety_flag,
@@ -2611,7 +2614,7 @@ fn render_attribute(attr: &ast::MetaItem) -> Option<String> {
     if attr.is_word() {
         Some(format!("{}", name))
     } else if let Some(v) = attr.value_str() {
-        Some(format!("{} = {:?}", name, &v.as_str()[..]))
+        Some(format!("{} = {:?}", name, v.as_str()))
     } else if let Some(values) = attr.meta_item_list() {
         let display: Vec<_> = values.iter().filter_map(|attr| {
             attr.meta_item().and_then(|mi| render_attribute(mi))
@@ -2642,7 +2645,7 @@ fn render_attributes(w: &mut fmt::Formatter, it: &clean::Item) -> fmt::Result {
 
     for attr in &it.attrs.other_attrs {
         let name = attr.name().unwrap();
-        if !ATTRIBUTE_WHITELIST.contains(&&name.as_str()[..]) {
+        if !ATTRIBUTE_WHITELIST.contains(&&*name.as_str()) {
             continue;
         }
         if let Some(s) = render_attribute(&attr.meta().unwrap()) {
@@ -2901,7 +2904,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
         write!(w, "</span>")?;
         write!(w, "</h3>\n")?;
         if let Some(ref dox) = i.impl_item.doc_value() {
-            write!(w, "<div class='docblock'>{}</div>", Markdown(dox))?;
+            write!(w, "<div class='docblock'>{}</div>", Markdown(dox, MarkdownOutputStyle::Fancy))?;
         }
     }
 
index 84f69cd35045c91fd833f4dce04235ecd14048d6..447d60018d91291f4e5fe469c7f26f253e8dfa44 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![crate_name = "rustdoc"]
-#![unstable(feature = "rustdoc", issue = "27812")]
+#![unstable(feature = "rustc_private", issue = "27812")]
 #![crate_type = "dylib"]
 #![crate_type = "rlib"]
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
@@ -30,6 +30,7 @@
 
 extern crate arena;
 extern crate getopts;
+extern crate env_logger;
 extern crate libc;
 extern crate rustc;
 extern crate rustc_const_eval;
@@ -47,6 +48,7 @@
 extern crate std_unicode;
 #[macro_use] extern crate log;
 extern crate rustc_errors as errors;
+extern crate pulldown_cmark;
 
 extern crate serialize as rustc_serialize; // used by deriving
 
@@ -99,6 +101,7 @@ struct Output {
 
 pub fn main() {
     const STACK_SIZE: usize = 32_000_000; // 32MB
+    env_logger::init().unwrap();
     let res = std::thread::Builder::new().stack_size(STACK_SIZE).spawn(move || {
         let s = env::args().collect::<Vec<_>>();
         main_args(&s)
index c67e2fdc2b0276a7ecf45938b19cfb66f94cdef5..5cc0f03e1f629f4ff3021684d766a13640ebe15a 100644 (file)
 use html::render::reset_ids;
 use html::escape::Escape;
 use html::markdown;
-use html::markdown::{Markdown, MarkdownWithToc, find_testable_code};
+use html::markdown::{Markdown, MarkdownWithToc, MarkdownOutputStyle, find_testable_code};
 use test::{TestOptions, Collector};
 
-/// Separate any lines at the start of the file that begin with `%`.
+/// Separate any lines at the start of the file that begin with `# ` or `%`.
 fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) {
     let mut metadata = Vec::new();
     let mut count = 0;
+
     for line in s.lines() {
-        if line.starts_with("%") {
-            // remove %<whitespace>
+        if line.starts_with("# ") || line.starts_with("%") {
+            // trim the whitespace after the symbol
             metadata.push(line[1..].trim_left());
             count += line.len() + 1;
         } else {
             return (metadata, &s[count..]);
         }
     }
-    // if we're here, then all lines were metadata % lines.
+
+    // if we're here, then all lines were metadata `# ` or `%` lines.
     (metadata, "")
 }
 
@@ -83,7 +85,7 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches,
     if metadata.is_empty() {
         let _ = writeln!(
             &mut io::stderr(),
-            "rustdoc: invalid markdown file: expecting initial line with `% ...TITLE...`"
+            "rustdoc: invalid markdown file: no initial lines starting with `# ` or `%`"
         );
         return 5;
     }
@@ -94,7 +96,7 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches,
     let rendered = if include_toc {
         format!("{}", MarkdownWithToc(text))
     } else {
-        format!("{}", Markdown(text))
+        format!("{}", Markdown(text, MarkdownOutputStyle::Fancy))
     };
 
     let err = write!(
index 4a909f8e2a9728c8117919d6cedc84104246e737..2793307697852b8aa1b36a0e971e2bc115f549e4 100644 (file)
@@ -198,7 +198,7 @@ pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec<ast::Attribu
             self.visit_item(item, None, &mut om);
         }
         self.inside_public_path = orig_inside_public_path;
-        if let Some(exports) = self.cx.export_map.get(&id) {
+        if let Some(exports) = self.cx.tcx.export_map.get(&id) {
             for export in exports {
                 if let Def::Macro(def_id, ..) = export.def {
                     if def_id.krate == LOCAL_CRATE {
index af21d6d906eb5d2569964202e91f1510f0fc9408..1cac11f668d95ebc90366af15145066816921d16 100644 (file)
@@ -17,7 +17,7 @@
 use ops::Range;
 use iter::FusedIterator;
 
-/// Extension methods for ASCII-subset only operations on string slices.
+/// Extension methods for ASCII-subset only operations.
 ///
 /// Be aware that operations on seemingly non-ASCII characters can sometimes
 /// have unexpected results. Consider this example:
@@ -54,19 +54,21 @@ pub trait AsciiExt {
     ///
     /// let ascii = 'a';
     /// let utf8 = '❤';
+    /// let int_ascii = 97;
     ///
     /// assert!(ascii.is_ascii());
     /// assert!(!utf8.is_ascii());
+    /// assert!(int_ascii.is_ascii());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn is_ascii(&self) -> bool;
 
-    /// Makes a copy of the string in ASCII upper case.
+    /// Makes a copy of the value in its ASCII upper case equivalent.
     ///
     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
     /// but non-ASCII letters are unchanged.
     ///
-    /// To uppercase the string in-place, use [`make_ascii_uppercase`].
+    /// To uppercase the value in-place, use [`make_ascii_uppercase`].
     ///
     /// To uppercase ASCII characters in addition to non-ASCII characters, use
     /// [`str::to_uppercase`].
@@ -78,9 +80,11 @@ pub trait AsciiExt {
     ///
     /// let ascii = 'a';
     /// let utf8 = '❤';
+    /// let int_ascii = 97;
     ///
     /// assert_eq!('A', ascii.to_ascii_uppercase());
     /// assert_eq!('❤', utf8.to_ascii_uppercase());
+    /// assert_eq!(65, int_ascii.to_ascii_uppercase());
     /// ```
     ///
     /// [`make_ascii_uppercase`]: #tymethod.make_ascii_uppercase
@@ -88,12 +92,12 @@ pub trait AsciiExt {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn to_ascii_uppercase(&self) -> Self::Owned;
 
-    /// Makes a copy of the string in ASCII lower case.
+    /// Makes a copy of the value in its ASCII lower case equivalent.
     ///
     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
     /// but non-ASCII letters are unchanged.
     ///
-    /// To lowercase the string in-place, use [`make_ascii_lowercase`].
+    /// To lowercase the value in-place, use [`make_ascii_lowercase`].
     ///
     /// To lowercase ASCII characters in addition to non-ASCII characters, use
     /// [`str::to_lowercase`].
@@ -105,9 +109,11 @@ pub trait AsciiExt {
     ///
     /// let ascii = 'A';
     /// let utf8 = '❤';
+    /// let int_ascii = 65;
     ///
     /// assert_eq!('a', ascii.to_ascii_lowercase());
     /// assert_eq!('❤', utf8.to_ascii_lowercase());
+    /// assert_eq!(97, int_ascii.to_ascii_lowercase());
     /// ```
     ///
     /// [`make_ascii_lowercase`]: #tymethod.make_ascii_lowercase
@@ -115,10 +121,10 @@ pub trait AsciiExt {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn to_ascii_lowercase(&self) -> Self::Owned;
 
-    /// Checks that two strings are an ASCII case-insensitive match.
+    /// Checks that two values are an ASCII case-insensitive match.
     ///
     /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
-    /// but without allocating and copying temporary strings.
+    /// but without allocating and copying temporaries.
     ///
     /// # Examples
     ///
@@ -142,7 +148,7 @@ pub trait AsciiExt {
     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
     /// but non-ASCII letters are unchanged.
     ///
-    /// To return a new uppercased string without modifying the existing one, use
+    /// To return a new uppercased value without modifying the existing one, use
     /// [`to_ascii_uppercase`].
     ///
     /// # Examples
@@ -166,7 +172,7 @@ pub trait AsciiExt {
     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
     /// but non-ASCII letters are unchanged.
     ///
-    /// To return a new lowercased string without modifying the existing one, use
+    /// To return a new lowercased value without modifying the existing one, use
     /// [`to_ascii_lowercase`].
     ///
     /// # Examples
index 60767ea4786618551f9720c2318db53ef7e3543c..53347eb14db0dec614cc5c9ee3dc2573496c7f06 100644 (file)
@@ -89,6 +89,10 @@ pub struct Cursor<T> {
 impl<T> Cursor<T> {
     /// Creates a new cursor wrapping the provided underlying I/O object.
     ///
+    /// Cursor initial position is `0` even if underlying object (e.
+    /// g. `Vec`) is not empty. So writing to cursor starts with
+    /// overwriting `Vec` content, not with appending to it.
+    ///
     /// # Examples
     ///
     /// ```
index 850885a8c0f3aaf76799ab398ce79bf132f8e00f..5b628d51d1513986eb31cbc17d2ff19756553849 100644 (file)
@@ -1290,28 +1290,42 @@ pub trait BufRead: Read {
     /// If an I/O error is encountered then all bytes read so far will be
     /// present in `buf` and its length will have been adjusted appropriately.
     ///
-    /// # Examples
-    ///
-    /// A locked standard input implements `BufRead`. In this example, we'll
-    /// read from standard input until we see an `a` byte.
-    ///
     /// [`fill_buf`]: #tymethod.fill_buf
     /// [`ErrorKind::Interrupted`]: enum.ErrorKind.html#variant.Interrupted
     ///
-    /// ```
-    /// use std::io;
-    /// use std::io::prelude::*;
+    /// # Examples
     ///
-    /// fn foo() -> io::Result<()> {
-    /// let stdin = io::stdin();
-    /// let mut stdin = stdin.lock();
-    /// let mut buffer = Vec::new();
+    /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In
+    /// this example, we use [`Cursor`] to read all the bytes in a byte slice
+    /// in hyphen delimited segments:
     ///
-    /// stdin.read_until(b'a', &mut buffer)?;
+    /// [`Cursor`]: struct.Cursor.html
     ///
-    /// println!("{:?}", buffer);
-    /// # Ok(())
-    /// # }
+    /// ```
+    /// use std::io::{self, BufRead};
+    ///
+    /// let mut cursor = io::Cursor::new(b"lorem-ipsum");
+    /// let mut buf = vec![];
+    ///
+    /// // cursor is at 'l'
+    /// let num_bytes = cursor.read_until(b'-', &mut buf)
+    ///     .expect("reading from cursor won't fail");
+    /// assert_eq!(num_bytes, 6);
+    /// assert_eq!(buf, b"lorem-");
+    /// buf.clear();
+    ///
+    /// // cursor is at 'i'
+    /// let num_bytes = cursor.read_until(b'-', &mut buf)
+    ///     .expect("reading from cursor won't fail");
+    /// assert_eq!(num_bytes, 5);
+    /// assert_eq!(buf, b"ipsum");
+    /// buf.clear();
+    ///
+    /// // cursor is at EOF
+    /// let num_bytes = cursor.read_until(b'-', &mut buf)
+    ///     .expect("reading from cursor won't fail");
+    /// assert_eq!(num_bytes, 0);
+    /// assert_eq!(buf, b"");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
@@ -1337,28 +1351,36 @@ fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
     ///
     /// # Examples
     ///
-    /// A locked standard input implements `BufRead`. In this example, we'll
-    /// read all of the lines from standard input. If we were to do this in
-    /// an actual project, the [`lines`] method would be easier, of
-    /// course.
+    /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In
+    /// this example, we use [`Cursor`] to read all the lines in a byte slice:
     ///
-    /// [`lines`]: #method.lines
-    /// [`read_until`]: #method.read_until
+    /// [`Cursor`]: struct.Cursor.html
     ///
     /// ```
-    /// use std::io;
-    /// use std::io::prelude::*;
-    ///
-    /// let stdin = io::stdin();
-    /// let mut stdin = stdin.lock();
-    /// let mut buffer = String::new();
-    ///
-    /// while stdin.read_line(&mut buffer).unwrap() > 0 {
-    ///     // work with buffer
-    ///     println!("{:?}", buffer);
-    ///
-    ///     buffer.clear();
-    /// }
+    /// use std::io::{self, BufRead};
+    ///
+    /// let mut cursor = io::Cursor::new(b"foo\nbar");
+    /// let mut buf = String::new();
+    ///
+    /// // cursor is at 'f'
+    /// let num_bytes = cursor.read_line(&mut buf)
+    ///     .expect("reading from cursor won't fail");
+    /// assert_eq!(num_bytes, 4);
+    /// assert_eq!(buf, "foo\n");
+    /// buf.clear();
+    ///
+    /// // cursor is at 'b'
+    /// let num_bytes = cursor.read_line(&mut buf)
+    ///     .expect("reading from cursor won't fail");
+    /// assert_eq!(num_bytes, 3);
+    /// assert_eq!(buf, "bar");
+    /// buf.clear();
+    ///
+    /// // cursor is at EOF
+    /// let num_bytes = cursor.read_line(&mut buf)
+    ///     .expect("reading from cursor won't fail");
+    /// assert_eq!(num_bytes, 0);
+    /// assert_eq!(buf, "");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn read_line(&mut self, buf: &mut String) -> Result<usize> {
@@ -1378,24 +1400,28 @@ fn read_line(&mut self, buf: &mut String) -> Result<usize> {
     /// This function will yield errors whenever [`read_until`] would have
     /// also yielded an error.
     ///
-    /// # Examples
-    ///
-    /// A locked standard input implements `BufRead`. In this example, we'll
-    /// read some input from standard input, splitting on commas.
-    ///
     /// [`io::Result`]: type.Result.html
     /// [`Vec<u8>`]: ../vec/struct.Vec.html
     /// [`read_until`]: #method.read_until
     ///
+    /// # Examples
+    ///
+    /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In
+    /// this example, we use [`Cursor`] to iterate over all hyphen delimited
+    /// segments in a byte slice
+    ///
+    /// [`Cursor`]: struct.Cursor.html
+    ///
     /// ```
-    /// use std::io;
-    /// use std::io::prelude::*;
+    /// use std::io::{self, BufRead};
     ///
-    /// let stdin = io::stdin();
+    /// let cursor = io::Cursor::new(b"lorem-ipsum-dolor");
     ///
-    /// for content in stdin.lock().split(b',') {
-    ///     println!("{:?}", content.unwrap());
-    /// }
+    /// let mut split_iter = cursor.split(b'-').map(|l| l.unwrap());
+    /// assert_eq!(split_iter.next(), Some(b"lorem".to_vec()));
+    /// assert_eq!(split_iter.next(), Some(b"ipsum".to_vec()));
+    /// assert_eq!(split_iter.next(), Some(b"dolor".to_vec()));
+    /// assert_eq!(split_iter.next(), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn split(self, byte: u8) -> Split<Self> where Self: Sized {
@@ -1413,17 +1439,22 @@ fn split(self, byte: u8) -> Split<Self> where Self: Sized {
     ///
     /// # Examples
     ///
-    /// A locked standard input implements `BufRead`:
+    /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In
+    /// this example, we use [`Cursor`] to iterate over all the lines in a byte
+    /// slice.
+    ///
+    /// [`Cursor`]: struct.Cursor.html
     ///
     /// ```
-    /// use std::io;
-    /// use std::io::prelude::*;
+    /// use std::io::{self, BufRead};
     ///
-    /// let stdin = io::stdin();
+    /// let cursor = io::Cursor::new(b"lorem\nipsum\r\ndolor");
     ///
-    /// for line in stdin.lock().lines() {
-    ///     println!("{}", line.unwrap());
-    /// }
+    /// let mut lines_iter = cursor.lines().map(|l| l.unwrap());
+    /// assert_eq!(lines_iter.next(), Some(String::from("lorem")));
+    /// assert_eq!(lines_iter.next(), Some(String::from("ipsum")));
+    /// assert_eq!(lines_iter.next(), Some(String::from("dolor")));
+    /// assert_eq!(lines_iter.next(), None);
     /// ```
     ///
     /// # Errors
index 84c4acb8d9247c4365ca33db13653297f405a914..36c06dc0b58d057d8a0f6df048b48e8837ebfafd 100644 (file)
 use iter;
 use slice;
 
-/// Representation of a socket address for networking applications.
+/// An internet socket address, either IPv4 or IPv6.
 ///
-/// A socket address can either represent the IPv4 or IPv6 protocol and is
-/// paired with at least a port number as well. Each protocol may have more
-/// specific information about the address available to it as well.
+/// Internet socket addresses consist of an [IP address], a 16-bit port number, as well
+/// as possibly some version-dependent additional information. See [`SocketAddrV4`]'s and
+/// [`SocketAddrV6`]'s respective documentation for more details.
+///
+/// [IP address]: ../../std/net/enum.IpAddr.html
+/// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
+/// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
+///
+/// # Examples
+///
+/// ```
+/// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
+///
+/// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
+///
+/// assert_eq!("127.0.0.1:8080".parse(), Ok(socket));
+/// assert_eq!(socket.port(), 8080);
+/// assert_eq!(socket.is_ipv4(), true);
+/// ```
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum SocketAddr {
-    /// An IPv4 socket address which is a (ip, port) combination.
+    /// An IPv4 socket address.
     #[stable(feature = "rust1", since = "1.0.0")]
     V4(#[stable(feature = "rust1", since = "1.0.0")] SocketAddrV4),
     /// An IPv6 socket address.
@@ -36,18 +52,63 @@ pub enum SocketAddr {
     V6(#[stable(feature = "rust1", since = "1.0.0")] SocketAddrV6),
 }
 
-/// An IPv4 socket address which is a (ip, port) combination.
+/// An IPv4 socket address.
+///
+/// IPv4 socket addresses consist of an [IPv4 address] and a 16-bit port number, as
+/// stated in [IETF RFC 793].
+///
+/// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
+///
+/// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
+/// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html
+/// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
+///
+/// # Examples
+///
+/// ```
+/// use std::net::{Ipv4Addr, SocketAddrV4};
+///
+/// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
+///
+/// assert_eq!("127.0.0.1:8080".parse(), Ok(socket));
+/// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
+/// assert_eq!(socket.port(), 8080);
+/// ```
 #[derive(Copy)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct SocketAddrV4 { inner: c::sockaddr_in }
 
 /// An IPv6 socket address.
+///
+/// IPv6 socket addresses consist of an [Ipv6 address], a 16-bit port number, as well
+/// as fields containing the traffic class, the flow label, and a scope identifier
+/// (see [IETF RFC 2553, Section 3.3] for more details).
+///
+/// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
+///
+/// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
+/// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html
+/// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
+///
+/// # Examples
+///
+/// ```
+/// use std::net::{Ipv6Addr, SocketAddrV6};
+///
+/// let socket = SocketAddrV6::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
+///
+/// assert_eq!("[2001:db8::1]:8080".parse(), Ok(socket));
+/// assert_eq!(socket.ip(), &Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1));
+/// assert_eq!(socket.port(), 8080);
+/// ```
 #[derive(Copy)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct SocketAddrV6 { inner: c::sockaddr_in6 }
 
 impl SocketAddr {
-    /// Creates a new socket address from the (ip, port) pair.
+    /// Creates a new socket address from an [IP address] and a port number.
+    ///
+    /// [IP address]: ../../std/net/enum.IpAddr.html
     ///
     /// # Examples
     ///
@@ -84,7 +145,7 @@ pub fn ip(&self) -> IpAddr {
         }
     }
 
-    /// Change the IP address associated with this socket address.
+    /// Changes the IP address associated with this socket address.
     ///
     /// # Examples
     ///
@@ -123,7 +184,7 @@ pub fn port(&self) -> u16 {
         }
     }
 
-    /// Change the port number associated with this socket address.
+    /// Changes the port number associated with this socket address.
     ///
     /// # Examples
     ///
@@ -142,8 +203,13 @@ pub fn set_port(&mut self, new_port: u16) {
         }
     }
 
-    /// Returns true if the IP in this `SocketAddr` is a valid IPv4 address,
-    /// false if it's a valid IPv6 address.
+    /// Returns [`true`] if the [IP address] in this `SocketAddr` is an
+    /// [IPv4 address], and [`false`] otherwise.
+    ///
+    /// [`true`]: ../../std/primitive.bool.html
+    /// [`false`]: ../../std/primitive.bool.html
+    /// [IP address]: ../../std/net/enum.IpAddr.html
+    /// [IPv4 address]: ../../std/net/enum.IpAddr.html#variant.V4
     ///
     /// # Examples
     ///
@@ -164,8 +230,13 @@ pub fn is_ipv4(&self) -> bool {
         }
     }
 
-    /// Returns true if the IP in this `SocketAddr` is a valid IPv6 address,
-    /// false if it's a valid IPv4 address.
+    /// Returns [`true`] if the [IP address] in this `SocketAddr` is an
+    /// [IPv6 address], and [`false`] otherwise.
+    ///
+    /// [`true`]: ../../std/primitive.bool.html
+    /// [`false`]: ../../std/primitive.bool.html
+    /// [IP address]: ../../std/net/enum.IpAddr.html
+    /// [IPv6 address]: ../../std/net/enum.IpAddr.html#variant.V6
     ///
     /// # Examples
     ///
@@ -189,7 +260,9 @@ pub fn is_ipv6(&self) -> bool {
 }
 
 impl SocketAddrV4 {
-    /// Creates a new socket address from the (ip, port) pair.
+    /// Creates a new socket address from an [IPv4 address] and a port number.
+    ///
+    /// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html
     ///
     /// # Examples
     ///
@@ -227,7 +300,7 @@ pub fn ip(&self) -> &Ipv4Addr {
         }
     }
 
-    /// Change the IP address associated with this socket address.
+    /// Changes the IP address associated with this socket address.
     ///
     /// # Examples
     ///
@@ -258,7 +331,7 @@ pub fn port(&self) -> u16 {
         ntoh(self.inner.sin_port)
     }
 
-    /// Change the port number associated with this socket address.
+    /// Changes the port number associated with this socket address.
     ///
     /// # Examples
     ///
@@ -276,8 +349,14 @@ pub fn set_port(&mut self, new_port: u16) {
 }
 
 impl SocketAddrV6 {
-    /// Creates a new socket address from the ip/port/flowinfo/scope_id
-    /// components.
+    /// Creates a new socket address from an [IPv6 address], a 16-bit port number,
+    /// and the `flowinfo` and `scope_id` fields.
+    ///
+    /// For more information on the meaning and layout of the `flowinfo` and `scope_id`
+    /// parameters, see [IETF RFC 2553, Section 3.3].
+    ///
+    /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
+    /// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html
     ///
     /// # Examples
     ///
@@ -318,7 +397,7 @@ pub fn ip(&self) -> &Ipv6Addr {
         }
     }
 
-    /// Change the IP address associated with this socket address.
+    /// Changes the IP address associated with this socket address.
     ///
     /// # Examples
     ///
@@ -349,7 +428,7 @@ pub fn port(&self) -> u16 {
         ntoh(self.inner.sin6_port)
     }
 
-    /// Change the port number associated with this socket address.
+    /// Changes the port number associated with this socket address.
     ///
     /// # Examples
     ///
@@ -365,8 +444,17 @@ pub fn set_port(&mut self, new_port: u16) {
         self.inner.sin6_port = hton(new_port);
     }
 
-    /// Returns the flow information associated with this address,
-    /// corresponding to the `sin6_flowinfo` field in C.
+    /// Returns the flow information associated with this address.
+    ///
+    /// This information corresponds to the `sin6_flowinfo` field in C's `netinet/in.h`,
+    /// as specified in [IETF RFC 2553, Section 3.3].
+    /// It combines information about the flow label and the traffic class as specified
+    /// in [IETF RFC 2460], respectively [Section 6] and [Section 7].
+    ///
+    /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
+    /// [IETF RFC 2460]: https://tools.ietf.org/html/rfc2460
+    /// [Section 6]: https://tools.ietf.org/html/rfc2460#section-6
+    /// [Section 7]: https://tools.ietf.org/html/rfc2460#section-7
     ///
     /// # Examples
     ///
@@ -381,7 +469,11 @@ pub fn flowinfo(&self) -> u32 {
         self.inner.sin6_flowinfo
     }
 
-    /// Change the flow information associated with this socket address.
+    /// Changes the flow information associated with this socket address.
+    ///
+    /// See the [`flowinfo`] method's documentation for more details.
+    ///
+    /// [`flowinfo`]: #method.flowinfo
     ///
     /// # Examples
     ///
@@ -397,8 +489,12 @@ pub fn set_flowinfo(&mut self, new_flowinfo: u32) {
         self.inner.sin6_flowinfo = new_flowinfo;
     }
 
-    /// Returns the scope ID associated with this address,
-    /// corresponding to the `sin6_scope_id` field in C.
+    /// Returns the scope ID associated with this address.
+    ///
+    /// This information corresponds to the `sin6_scope_id` field in C's `netinet/in.h`,
+    /// as specified in [IETF RFC 2553, Section 3.3].
+    ///
+    /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
     ///
     /// # Examples
     ///
@@ -415,6 +511,10 @@ pub fn scope_id(&self) -> u32 {
 
     /// Change the scope ID associated with this socket address.
     ///
+    /// See the [`scope_id`] method's documentation for more details.
+    ///
+    /// [`scope_id`]: #method.scope_id
+    ///
     /// # Examples
     ///
     /// ```
@@ -559,37 +659,51 @@ fn hash<H: hash::Hasher>(&self, s: &mut H) {
 }
 
 /// A trait for objects which can be converted or resolved to one or more
-/// `SocketAddr` values.
+/// [`SocketAddr`] values.
 ///
 /// This trait is used for generic address resolution when constructing network
 /// objects.  By default it is implemented for the following types:
 ///
-///  * `SocketAddr`, `SocketAddrV4`, `SocketAddrV6` - `to_socket_addrs` is
-///    identity function.
+///  * [`SocketAddr`]: [`to_socket_addrs`] is the identity function.
 ///
-///  * `(IpvNAddr, u16)` - `to_socket_addrs` constructs `SocketAddr` trivially.
+///  * [`SocketAddrV4`], [`SocketAddrV6`], `(`[`IpAddr`]`, `[`u16`]`)`,
+///    `(`[`Ipv4Addr`]`, `[`u16`]`)`, `(`[`Ipv6Addr`]`, `[`u16`]`)`:
+///    [`to_socket_addrs`] constructs a [`SocketAddr`] trivially.
 ///
-///  * `(&str, u16)` - the string should be either a string representation of an
-///    IP address expected by `FromStr` implementation for `IpvNAddr` or a host
+///  * `(`[`&str`]`, `[`u16`]`)`: the string should be either a string representation
+///    of an [`IpAddr`] address as expected by [`FromStr`] implementation or a host
 ///    name.
 ///
-///  * `&str` - the string should be either a string representation of a
-///    `SocketAddr` as expected by its `FromStr` implementation or a string like
-///    `<host_name>:<port>` pair where `<port>` is a `u16` value.
+///  * [`&str`]: the string should be either a string representation of a
+///    [`SocketAddr`] as expected by its [`FromStr`] implementation or a string like
+///    `<host_name>:<port>` pair where `<port>` is a [`u16`] value.
 ///
-/// This trait allows constructing network objects like `TcpStream` or
-/// `UdpSocket` easily with values of various types for the bind/connection
+/// This trait allows constructing network objects like [`TcpStream`] or
+/// [`UdpSocket`] easily with values of various types for the bind/connection
 /// address. It is needed because sometimes one type is more appropriate than
 /// the other: for simple uses a string like `"localhost:12345"` is much nicer
-/// than manual construction of the corresponding `SocketAddr`, but sometimes
-/// `SocketAddr` value is *the* main source of the address, and converting it to
+/// than manual construction of the corresponding [`SocketAddr`], but sometimes
+/// [`SocketAddr`] value is *the* main source of the address, and converting it to
 /// some other type (e.g. a string) just for it to be converted back to
-/// `SocketAddr` in constructor methods is pointless.
+/// [`SocketAddr`] in constructor methods is pointless.
 ///
 /// Addresses returned by the operating system that are not IP addresses are
 /// silently ignored.
 ///
-/// Some examples:
+/// [`FromStr`]: ../../std/str/trait.FromStr.html
+/// [`IpAddr`]: ../../std/net/enum.IpAddr.html
+/// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
+/// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
+/// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
+/// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
+/// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
+/// [`&str`]: ../../std/primitive.str.html
+/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
+/// [`to_socket_addrs`]: #tymethod.to_socket_addrs
+/// [`UdpSocket`]: ../../std/net/struct.UdpSocket.html
+/// [`u16`]: ../../std/primitive.u16.html
+///
+/// # Examples
 ///
 /// ```no_run
 /// use std::net::{SocketAddrV4, TcpStream, UdpSocket, TcpListener, Ipv4Addr};
@@ -629,10 +743,6 @@ pub trait ToSocketAddrs {
     ///
     /// Note that this function may block the current thread while resolution is
     /// performed.
-    ///
-    /// # Errors
-    ///
-    /// Any errors encountered during resolution will be returned as an `Err`.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn to_socket_addrs(&self) -> io::Result<Self::Iter>;
 }
index 24e0e6f3fa659f3ec98204ecdec3ffe60588188e..c46fe4a58c7e246f919c74ec28afb9b679f63948 100644 (file)
 use sys::net::netc as c;
 use sys_common::{AsInner, FromInner};
 
-/// An IP address, either an IPv4 or IPv6 address.
+/// An IP address, either IPv4 or IPv6.
 ///
-/// # Examples
+/// This enum can contain either an [`Ipv4Addr`] or an [`Ipv6Addr`], see their
+/// respective documentation for more details.
 ///
-/// Constructing an IPv4 address:
+/// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
+/// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
 ///
-/// ```
-/// use std::net::{IpAddr, Ipv4Addr};
+/// # Examples
 ///
-/// IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
 /// ```
+/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
 ///
-/// Constructing an IPv6 address:
+/// let localhost_v4 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
+/// let localhost_v6 = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
 ///
-/// ```
-/// use std::net::{IpAddr, Ipv6Addr};
+/// assert_eq!("127.0.0.1".parse(), Ok(localhost_v4));
+/// assert_eq!("::1".parse(), Ok(localhost_v6));
 ///
-/// IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
+/// assert_eq!(localhost_v4.is_ipv6(), false);
+/// assert_eq!(localhost_v4.is_ipv4(), true);
 /// ```
 #[stable(feature = "ip_addr", since = "1.7.0")]
 #[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
 pub enum IpAddr {
-    /// Representation of an IPv4 address.
+    /// An IPv4 address.
     #[stable(feature = "ip_addr", since = "1.7.0")]
     V4(#[stable(feature = "ip_addr", since = "1.7.0")] Ipv4Addr),
-    /// Representation of an IPv6 address.
+    /// An IPv6 address.
     #[stable(feature = "ip_addr", since = "1.7.0")]
     V6(#[stable(feature = "ip_addr", since = "1.7.0")] Ipv6Addr),
 }
 
-/// Representation of an IPv4 address.
+/// An IPv4 address.
+///
+/// IPv4 addresses are defined as 32-bit integers in [IETF RFC 791].
+/// They are usually represented as four octets.
+///
+/// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses.
+///
+/// [IETF RFC 791]: https://tools.ietf.org/html/rfc791
+/// [`IpAddr`]: ../../std/net/enum.IpAddr.html
+///
+/// # Textual representation
+///
+/// `Ipv4Addr` provides a [`FromStr`] implementation. The four octets are in decimal
+/// notation, divided by `.` (this is called "dot-decimal notation").
+///
+/// [`FromStr`]: ../../std/str/trait.FromStr.html
+///
+/// # Examples
+///
+/// ```
+/// use std::net::Ipv4Addr;
+///
+/// let localhost = Ipv4Addr::new(127, 0, 0, 1);
+/// assert_eq!("127.0.0.1".parse(), Ok(localhost));
+/// assert_eq!(localhost.is_loopback(), true);
+/// ```
 #[derive(Copy)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Ipv4Addr {
     inner: c::in_addr,
 }
 
-/// Representation of an IPv6 address.
+/// An IPv6 address.
+///
+/// IPv6 addresses are defined as 128-bit integers in [IETF RFC 4291].
+/// They are usually represented as eight 16-bit segments.
+///
+/// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses.
+///
+/// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
+/// [`IpAddr`]: ../../std/net/enum.IpAddr.html
+///
+/// # Textual representation
+///
+/// `Ipv6Addr` provides a [`FromStr`] implementation. There are many ways to represent
+/// an IPv6 address in text, but in general, each segments is written in hexadecimal
+/// notation, and segments are separated by `:`. For more information, see
+/// [IETF RFC 5952].
+///
+/// [`FromStr`]: ../../std/str/trait.FromStr.html
+/// [IETF RFC 5952]: https://tools.ietf.org/html/rfc5952
+///
+/// # Examples
+///
+/// ```
+/// use std::net::Ipv6Addr;
+///
+/// let localhost = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
+/// assert_eq!("::1".parse(), Ok(localhost));
+/// assert_eq!(localhost.is_loopback(), true);
+/// ```
 #[derive(Copy)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Ipv6Addr {
@@ -78,10 +134,14 @@ pub enum Ipv6MulticastScope {
 }
 
 impl IpAddr {
-    /// Returns true for the special 'unspecified' address ([IPv4], [IPv6]).
+    /// Returns [`true`] for the special 'unspecified' address.
+    ///
+    /// See the documentation for [`Ipv4Addr::is_unspecified`][IPv4] and
+    /// [`Ipv6Addr::is_unspecified`][IPv6] for more details.
     ///
     /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_unspecified
     /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_unspecified
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -99,10 +159,14 @@ pub fn is_unspecified(&self) -> bool {
         }
     }
 
-    /// Returns true if this is a loopback address ([IPv4], [IPv6]).
+    /// Returns [`true`] if this is a loopback address.
+    ///
+    /// See the documentation for [`Ipv4Addr::is_loopback`][IPv4] and
+    /// [`Ipv6Addr::is_loopback`][IPv6] for more details.
     ///
     /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_loopback
     /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_loopback
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -120,10 +184,14 @@ pub fn is_loopback(&self) -> bool {
         }
     }
 
-    /// Returns true if the address appears to be globally routable ([IPv4], [IPv6]).
+    /// Returns [`true`] if the address appears to be globally routable.
+    ///
+    /// See the documentation for [`Ipv4Addr::is_global`][IPv4] and
+    /// [`Ipv6Addr::is_global`][IPv6] for more details.
     ///
     /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_global
     /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_global
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -145,10 +213,14 @@ pub fn is_global(&self) -> bool {
         }
     }
 
-    /// Returns true if this is a multicast address ([IPv4], [IPv6]).
+    /// Returns [`true`] if this is a multicast address.
+    ///
+    /// See the documentation for [`Ipv4Addr::is_multicast`][IPv4] and
+    /// [`Ipv6Addr::is_multicast`][IPv6] for more details.
     ///
     /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_multicast
     /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_multicast
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -166,10 +238,14 @@ pub fn is_multicast(&self) -> bool {
         }
     }
 
-    /// Returns true if this address is in a range designated for documentation ([IPv4], [IPv6]).
+    /// Returns [`true`] if this address is in a range designated for documentation.
+    ///
+    /// See the documentation for [`Ipv4Addr::is_documentation`][IPv4] and
+    /// [`Ipv6Addr::is_documentation`][IPv6] for more details.
     ///
     /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_documentation
     /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_documentation
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -191,7 +267,11 @@ pub fn is_documentation(&self) -> bool {
         }
     }
 
-    /// Returns true if this address is a valid IPv4 address, false if it's a valid IPv6 address.
+    /// Returns [`true`] if this address is an [IPv4 address], and [`false`] otherwise.
+    ///
+    /// [`true`]: ../../std/primitive.bool.html
+    /// [`false`]: ../../std/primitive.bool.html
+    /// [IPv4 address]: #variant.V4
     ///
     /// # Examples
     ///
@@ -212,7 +292,11 @@ pub fn is_ipv4(&self) -> bool {
         }
     }
 
-    /// Returns true if this address is a valid IPv6 address, false if it's a valid IPv4 address.
+    /// Returns [`true`] if this address is an [IPv6 address], and [`false`] otherwise.
+    ///
+    /// [`true`]: ../../std/primitive.bool.html
+    /// [`false`]: ../../std/primitive.bool.html
+    /// [IPv6 address]: #variant.V6
     ///
     /// # Examples
     ///
@@ -274,12 +358,13 @@ pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
         [(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8]
     }
 
-    /// Returns true for the special 'unspecified' address (0.0.0.0).
+    /// Returns [`true`] for the special 'unspecified' address (0.0.0.0).
     ///
     /// This property is defined in _UNIX Network Programming, Second Edition_,
     /// W. Richard Stevens, p. 891; see also [ip7].
     ///
     /// [ip7]: http://man7.org/linux/man-pages/man7/ip.7.html
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -294,11 +379,12 @@ pub fn is_unspecified(&self) -> bool {
         self.inner.s_addr == 0
     }
 
-    /// Returns true if this is a loopback address (127.0.0.0/8).
+    /// Returns [`true`] if this is a loopback address (127.0.0.0/8).
     ///
-    /// This property is defined by [RFC 1122].
+    /// This property is defined by [IETF RFC 1122].
     ///
-    /// [RFC 1122]: https://tools.ietf.org/html/rfc1122
+    /// [IETF RFC 1122]: https://tools.ietf.org/html/rfc1122
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -313,15 +399,16 @@ pub fn is_loopback(&self) -> bool {
         self.octets()[0] == 127
     }
 
-    /// Returns true if this is a private address.
+    /// Returns [`true`] if this is a private address.
     ///
-    /// The private address ranges are defined in [RFC 1918] and include:
+    /// The private address ranges are defined in [IETF RFC 1918] and include:
     ///
     ///  - 10.0.0.0/8
     ///  - 172.16.0.0/12
     ///  - 192.168.0.0/16
     ///
-    /// [RFC 1918]: https://tools.ietf.org/html/rfc1918
+    /// [IETF RFC 1918]: https://tools.ietf.org/html/rfc1918
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -346,11 +433,12 @@ pub fn is_private(&self) -> bool {
         }
     }
 
-    /// Returns true if the address is link-local (169.254.0.0/16).
+    /// Returns [`true`] if the address is link-local (169.254.0.0/16).
     ///
-    /// This property is defined by [RFC 3927].
+    /// This property is defined by [IETF RFC 3927].
     ///
-    /// [RFC 3927]: https://tools.ietf.org/html/rfc3927
+    /// [IETF RFC 3927]: https://tools.ietf.org/html/rfc3927
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -366,7 +454,7 @@ pub fn is_link_local(&self) -> bool {
         self.octets()[0] == 169 && self.octets()[1] == 254
     }
 
-    /// Returns true if the address appears to be globally routable.
+    /// Returns [`true`] if the address appears to be globally routable.
     /// See [iana-ipv4-special-registry][ipv4-sr].
     ///
     /// The following return false:
@@ -379,6 +467,7 @@ pub fn is_link_local(&self) -> bool {
     /// - the unspecified address (0.0.0.0)
     ///
     /// [ipv4-sr]: http://goo.gl/RaZ7lg
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -400,12 +489,13 @@ pub fn is_global(&self) -> bool {
         !self.is_broadcast() && !self.is_documentation() && !self.is_unspecified()
     }
 
-    /// Returns true if this is a multicast address (224.0.0.0/4).
+    /// Returns [`true`] if this is a multicast address (224.0.0.0/4).
     ///
     /// Multicast addresses have a most significant octet between 224 and 239,
-    /// and is defined by [RFC 5771].
+    /// and is defined by [IETF RFC 5771].
     ///
-    /// [RFC 5771]: https://tools.ietf.org/html/rfc5771
+    /// [IETF RFC 5771]: https://tools.ietf.org/html/rfc5771
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -421,11 +511,12 @@ pub fn is_multicast(&self) -> bool {
         self.octets()[0] >= 224 && self.octets()[0] <= 239
     }
 
-    /// Returns true if this is a broadcast address (255.255.255.255).
+    /// Returns [`true`] if this is a broadcast address (255.255.255.255).
     ///
-    /// A broadcast address has all octets set to 255 as defined in [RFC 919].
+    /// A broadcast address has all octets set to 255 as defined in [IETF RFC 919].
     ///
-    /// [RFC 919]: https://tools.ietf.org/html/rfc919
+    /// [IETF RFC 919]: https://tools.ietf.org/html/rfc919
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -441,15 +532,16 @@ pub fn is_broadcast(&self) -> bool {
         self.octets()[2] == 255 && self.octets()[3] == 255
     }
 
-    /// Returns true if this address is in a range designated for documentation.
+    /// Returns [`true`] if this address is in a range designated for documentation.
     ///
-    /// This is defined in [RFC 5737]:
+    /// This is defined in [IETF RFC 5737]:
     ///
     /// - 192.0.2.0/24 (TEST-NET-1)
     /// - 198.51.100.0/24 (TEST-NET-2)
     /// - 203.0.113.0/24 (TEST-NET-3)
     ///
-    /// [RFC 5737]: https://tools.ietf.org/html/rfc5737
+    /// [IETF RFC 5737]: https://tools.ietf.org/html/rfc5737
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -471,10 +563,12 @@ pub fn is_documentation(&self) -> bool {
         }
     }
 
-    /// Converts this address to an IPv4-compatible IPv6 address.
+    /// Converts this address to an IPv4-compatible [IPv6 address].
     ///
     /// a.b.c.d becomes ::a.b.c.d
     ///
+    /// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -490,10 +584,12 @@ pub fn to_ipv6_compatible(&self) -> Ipv6Addr {
                       ((self.octets()[2] as u16) << 8) | self.octets()[3] as u16)
     }
 
-    /// Converts this address to an IPv4-mapped IPv6 address.
+    /// Converts this address to an IPv4-mapped [IPv6 address].
     ///
     /// a.b.c.d becomes ::ffff:a.b.c.d
     ///
+    /// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -717,11 +813,12 @@ pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16,
         ]
     }
 
-    /// Returns true for the special 'unspecified' address (::).
+    /// Returns [`true`] for the special 'unspecified' address (::).
     ///
-    /// This property is defined in [RFC 4291].
+    /// This property is defined in [IETF RFC 4291].
     ///
-    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -736,11 +833,12 @@ pub fn is_unspecified(&self) -> bool {
         self.segments() == [0, 0, 0, 0, 0, 0, 0, 0]
     }
 
-    /// Returns true if this is a loopback address (::1).
+    /// Returns [`true`] if this is a loopback address (::1).
     ///
-    /// This property is defined in [RFC 4291].
+    /// This property is defined in [IETF RFC 4291].
     ///
-    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -755,14 +853,17 @@ pub fn is_loopback(&self) -> bool {
         self.segments() == [0, 0, 0, 0, 0, 0, 0, 1]
     }
 
-    /// Returns true if the address appears to be globally routable.
+    /// Returns [`true`] if the address appears to be globally routable.
     ///
-    /// The following return false:
+    /// The following return [`false`]:
     ///
     /// - the loopback address
     /// - link-local, site-local, and unique local unicast addresses
     /// - interface-, link-, realm-, admin- and site-local multicast addresses
     ///
+    /// [`true`]: ../../std/primitive.bool.html
+    /// [`false`]: ../../std/primitive.bool.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -784,11 +885,12 @@ pub fn is_global(&self) -> bool {
         }
     }
 
-    /// Returns true if this is a unique local address (fc00::/7).
+    /// Returns [`true`] if this is a unique local address (fc00::/7).
     ///
-    /// This property is defined in [RFC 4193].
+    /// This property is defined in [IETF RFC 4193].
     ///
-    /// [RFC 4193]: https://tools.ietf.org/html/rfc4193
+    /// [IETF RFC 4193]: https://tools.ietf.org/html/rfc4193
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -807,11 +909,12 @@ pub fn is_unique_local(&self) -> bool {
         (self.segments()[0] & 0xfe00) == 0xfc00
     }
 
-    /// Returns true if the address is unicast and link-local (fe80::/10).
+    /// Returns [`true`] if the address is unicast and link-local (fe80::/10).
     ///
-    /// This property is defined in [RFC 4291].
+    /// This property is defined in [IETF RFC 4291].
     ///
-    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -830,9 +933,11 @@ pub fn is_unicast_link_local(&self) -> bool {
         (self.segments()[0] & 0xffc0) == 0xfe80
     }
 
-    /// Returns true if this is a deprecated unicast site-local address
+    /// Returns [`true`] if this is a deprecated unicast site-local address
     /// (fec0::/10).
     ///
+    /// [`true`]: ../../std/primitive.bool.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -850,12 +955,13 @@ pub fn is_unicast_site_local(&self) -> bool {
         (self.segments()[0] & 0xffc0) == 0xfec0
     }
 
-    /// Returns true if this is an address reserved for documentation
+    /// Returns [`true`] if this is an address reserved for documentation
     /// (2001:db8::/32).
     ///
-    /// This property is defined in [RFC 3849].
+    /// This property is defined in [IETF RFC 3849].
     ///
-    /// [RFC 3849]: https://tools.ietf.org/html/rfc3849
+    /// [IETF RFC 3849]: https://tools.ietf.org/html/rfc3849
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -874,7 +980,7 @@ pub fn is_documentation(&self) -> bool {
         (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
     }
 
-    /// Returns true if the address is a globally routable unicast address.
+    /// Returns [`true`] if the address is a globally routable unicast address.
     ///
     /// The following return false:
     ///
@@ -885,6 +991,8 @@ pub fn is_documentation(&self) -> bool {
     /// - the unspecified address
     /// - the address range reserved for documentation
     ///
+    /// [`true`]: ../../std/primitive.bool.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -937,11 +1045,13 @@ pub fn multicast_scope(&self) -> Option<Ipv6MulticastScope> {
         }
     }
 
-    /// Returns true if this is a multicast address (ff00::/8).
+    /// Returns [`true`] if this is a multicast address (ff00::/8).
+    ///
+    /// This property is defined by [IETF RFC 4291].
     ///
-    /// This property is defined by [RFC 4291].
+    /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [`true`]: ../../std/primitive.bool.html
     ///
-    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
     /// # Examples
     ///
     /// ```
@@ -955,11 +1065,16 @@ pub fn is_multicast(&self) -> bool {
         (self.segments()[0] & 0xff00) == 0xff00
     }
 
-    /// Converts this address to an IPv4 address. Returns None if this address is
+    /// Converts this address to an [IPv4 address]. Returns [`None`] if this address is
     /// neither IPv4-compatible or IPv4-mapped.
     ///
     /// ::a.b.c.d and ::ffff:a.b.c.d become a.b.c.d
     ///
+    /// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html
+    /// [`None`]: ../../std/option/enum.Option.html#variant.None
+    ///
+    /// # Examples
+    ///
     /// ```
     /// use std::net::{Ipv4Addr, Ipv6Addr};
     ///
index b0d2e3e4687b44c24e4fee5cf64a14b9109261c0..9fcb93e2032b3ce40489f2cb6d4be9cd103cdb24 100644 (file)
@@ -9,6 +9,32 @@
 // except according to those terms.
 
 //! Networking primitives for TCP/UDP communication.
+//!
+//! This module provides networking functionality for the Transmission Control and User
+//! Datagram Protocols, as well as types for IP and socket addresses.
+//!
+//! # Organization
+//!
+//! * [`TcpListener`] and [`TcpStream`] provide functionality for communication over TCP
+//! * [`UdpSocket`] provides functionality for communication over UDP
+//! * [`IpAddr`] represents IP addresses of either IPv4 or IPv6; [`Ipv4Addr`] and
+//!   [`Ipv6Addr`] are respectively IPv4 and IPv6 addresses
+//! * [`SocketAddr`] represents socket addresses of either IPv4 or IPv6; [`SocketAddrV4`]
+//!   and [`SocketAddrV6`] are respectively IPv4 and IPv6 socket addresses
+//! * [`ToSocketAddrs`] is a trait that used for generic address resolution when interacting
+//!   with networking objects like [`TcpListener`], [`TcpStream`] or [`UdpSocket`]
+//! * Other types are return or parameter types for various methods in this module
+//!
+//! [`IpAddr`]: ../../std/net/enum.IpAddr.html
+//! [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
+//! [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
+//! [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
+//! [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
+//! [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
+//! [`TcpListener`]: ../../std/net/struct.TcpListener.html
+//! [`TcpStream`]: ../../std/net/struct.TcpStream.html
+//! [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
+//! [`UdpSocket`]: ../../std/net/struct.UdpSocket.html
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Shutdown {
-    /// Indicates that the reading portion of this stream/socket should be shut
-    /// down. All currently blocked and future reads will return `Ok(0)`.
+    /// The reading portion of the [`TcpStream`] should be shut down.
+    ///
+    /// All currently blocked and future [reads] will return [`Ok(0)`].
+    ///
+    /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
+    /// [reads]: ../../std/io/trait.Read.html
+    /// [`Ok(0)`]: ../../std/result/enum.Result.html#variant.Ok
     #[stable(feature = "rust1", since = "1.0.0")]
     Read,
-    /// Indicates that the writing portion of this stream/socket should be shut
-    /// down. All currently blocked and future writes will return an error.
+    /// The writing portion of the [`TcpStream`] should be shut down.
+    ///
+    /// All currently blocked and future [writes] will return an error.
+    ///
+    /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
+    /// [writes]: ../../std/io/trait.Write.html
     #[stable(feature = "rust1", since = "1.0.0")]
     Write,
-    /// Shut down both the reading and writing portions of this stream.
+    /// Both the reading and the writing portions of the [`TcpStream`] should be shut down.
+    ///
+    /// See [`Shutdown::Read`] and [`Shutdown::Write`] for more information.
     ///
-    /// See `Shutdown::Read` and `Shutdown::Write` for more information.
+    /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
+    /// [`Shutdown::Read`]: #variant.Read
+    /// [`Shutdown::Write`]: #variant.Write
     #[stable(feature = "rust1", since = "1.0.0")]
     Both,
 }
index d86711c10ac7965c9dfcb17ab474ce8e771c3875..7d7c67ff3f9f767fcc80801af177543767797851 100644 (file)
@@ -368,7 +368,19 @@ fn from_str(s: &str) -> Result<SocketAddr, AddrParseError> {
     }
 }
 
-/// An error returned when parsing an IP address or a socket address.
+/// An error which can be returned when parsing an IP address or a socket address.
+///
+/// This error is used as the error type for the [`FromStr`] implementation for
+/// [`IpAddr`], [`Ipv4Addr`], [`Ipv6Addr`], [`SocketAddr`], [`SocketAddrV4`], and
+/// [`SocketAddrV6`].
+///
+/// [`FromStr`]: ../../std/str/trait.FromStr.html
+/// [`IpAddr`]: ../../std/net/enum.IpAddr.html
+/// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
+/// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
+/// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
+/// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
+/// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct AddrParseError(());
index a07972468e68a3afdfeff1d871d15ea413791fbb..cf119720e5a17cc1d3f9ae62cfb772d5c6d49287 100644 (file)
 use sys_common::{AsInner, FromInner, IntoInner};
 use time::Duration;
 
-/// A structure which represents a TCP stream between a local socket and a
-/// remote socket.
+/// A TCP stream between a local and a remote socket.
 ///
-/// The socket will be closed when the value is dropped.
+/// After creating a `TcpStream` by either [`connect`]ing to a remote host or
+/// [`accept`]ing a connection on a [`TcpListener`], data can be transmitted
+/// by [reading] and [writing] to it.
+///
+/// The connection will be closed when the value is dropped. The reading and writing
+/// portions of the connection can also be shut down individually with the [`shutdown`]
+/// method.
+///
+/// The Transmission Control Protocol is specified in [IETF RFC 793].
+///
+/// [`accept`]: ../../std/net/struct.TcpListener.html#method.accept
+/// [`connect`]: #method.connect
+/// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
+/// [reading]: ../../std/io/trait.Read.html
+/// [`shutdown`]: #method.shutdown
+/// [`TcpListener`]: ../../std/net/struct.TcpListener.html
+/// [writing]: ../../std/io/trait.Write.html
 ///
 /// # Examples
 ///
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct TcpStream(net_imp::TcpStream);
 
-/// A structure representing a socket server.
+/// A TCP socket server, listening for connections.
+///
+/// After creating a `TcpListener` by [`bind`]ing it to a socket address, it listens
+/// for incoming TCP connections. These can be accepted by calling [`accept`] or by
+/// iterating over the [`Incoming`] iterator returned by [`incoming`].
+///
+/// The socket will be closed when the value is dropped.
+///
+/// The Transmission Control Protocol is specified in [IETF RFC 793].
+///
+/// [`accept`]: #method.accept
+/// [`bind`]: #method.bind
+/// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
+/// [`Incoming`]: ../../std/net/struct.Incoming.html
+/// [`incoming`]: #method.incoming
 ///
 /// # Examples
 ///
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct TcpListener(net_imp::TcpListener);
 
-/// An infinite iterator over the connections from a `TcpListener`.
-///
-/// This iterator will infinitely yield [`Some`] of the accepted connections. It
-/// is equivalent to calling `accept` in a loop.
+/// An iterator that infinitely [`accept`]s connections on a [`TcpListener`].
 ///
 /// This `struct` is created by the [`incoming`] method on [`TcpListener`].
+/// See its documentation for more.
 ///
-/// [`Some`]: ../../std/option/enum.Option.html#variant.Some
-/// [`incoming`]: struct.TcpListener.html#method.incoming
-/// [`TcpListener`]: struct.TcpListener.html
+/// [`accept`]: ../../std/net/struct.TcpListener.html#method.accept
+/// [`incoming`]: ../../std/net/struct.TcpListener.html#method.incoming
+/// [`TcpListener`]: ../../std/net/struct.TcpListener.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 pub struct Incoming<'a> { listener: &'a TcpListener }
@@ -83,11 +110,15 @@ impl TcpStream {
     /// Opens a TCP connection to a remote host.
     ///
     /// `addr` is an address of the remote host. Anything which implements
-    /// `ToSocketAddrs` trait can be supplied for the address; see this trait
+    /// [`ToSocketAddrs`] trait can be supplied for the address; see this trait
     /// documentation for concrete examples.
-    /// In case `ToSocketAddrs::to_socket_addrs()` returns more than one entry,
+    /// In case [`ToSocketAddrs::to_socket_addrs()`] returns more than one entry,
     /// then the first valid and reachable address is used.
     ///
+    /// [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
+    /// [`ToSocketAddrs::to_socket_addrs()`]:
+    /// ../../std/net/trait.ToSocketAddrs.html#tymethod.to_socket_addrs
+    ///
     /// # Examples
     ///
     /// ```no_run
@@ -494,11 +525,14 @@ impl TcpListener {
     ///
     /// Binding with a port number of 0 will request that the OS assigns a port
     /// to this listener. The port allocated can be queried via the
-    /// `local_addr` method.
+    /// [`local_addr`] method.
     ///
-    /// The address type can be any implementor of `ToSocketAddrs` trait. See
+    /// The address type can be any implementor of [`ToSocketAddrs`] trait. See
     /// its documentation for concrete examples.
     ///
+    /// [`local_addr`]: #method.local_addr
+    /// [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
+    ///
     /// # Examples
     ///
     /// ```no_run
@@ -529,10 +563,12 @@ pub fn local_addr(&self) -> io::Result<SocketAddr> {
 
     /// Creates a new independently owned handle to the underlying socket.
     ///
-    /// The returned `TcpListener` is a reference to the same socket that this
+    /// The returned [`TcpListener`] is a reference to the same socket that this
     /// object references. Both handles can be used to accept incoming
     /// connections and options set on one listener will affect the other.
     ///
+    /// [`TcpListener`]: ../../std/net/struct.TcpListener.html
+    ///
     /// # Examples
     ///
     /// ```no_run
@@ -549,9 +585,11 @@ pub fn try_clone(&self) -> io::Result<TcpListener> {
     /// Accept a new incoming connection from this listener.
     ///
     /// This function will block the calling thread until a new TCP connection
-    /// is established. When established, the corresponding `TcpStream` and the
+    /// is established. When established, the corresponding [`TcpStream`] and the
     /// remote peer's address will be returned.
     ///
+    /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
+    ///
     /// # Examples
     ///
     /// ```no_run
@@ -572,10 +610,12 @@ pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
     /// listener.
     ///
     /// The returned iterator will never return [`None`] and will also not yield
-    /// the peer's [`SocketAddr`] structure.
+    /// the peer's [`SocketAddr`] structure. Iterating over it is equivalent to
+    /// calling [`accept`] in a loop.
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
     /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
+    /// [`accept`]: #method.accept
     ///
     /// # Examples
     ///
index 1ebce939348401d5087250e7cd365a092b717614..cdf04f7f1a484bb02f5f257000060fe82d98b7b8 100644 (file)
 use sys_common::{AsInner, FromInner, IntoInner};
 use time::Duration;
 
-/// A User Datagram Protocol socket.
+/// A UDP socket.
 ///
-/// This is an implementation of a bound UDP socket. This supports both IPv4 and
-/// IPv6 addresses, and there is no corresponding notion of a server because UDP
-/// is a datagram protocol.
+/// After creating a `UdpSocket` by [`bind`]ing it to a socket address, data can be
+/// [sent to] and [received from] any other socket address.
+///
+/// Although UDP is a connectionless protocol, this implementation provides an interface
+/// to set an address where data should be sent and received from. After setting a remote
+/// address with [`connect`], data can be sent to and received from that address with
+/// [`send`] and [`recv`].
+///
+/// As stated in the User Datagram Protocol's specification in [IETF RFC 768], UDP is
+/// an unordered, unreliable protocol; refer to [`TcpListener`] and [`TcpStream`] for TCP
+/// primitives.
+///
+/// [`bind`]: #method.bind
+/// [`connect`]: #method.connect
+/// [IETF RFC 768]: https://tools.ietf.org/html/rfc768
+/// [`recv`]: #method.recv
+/// [received from]: #method.recv_from
+/// [`send`]: #method.send
+/// [sent to]: #method.send_to
+/// [`TcpListener`]: ../../std/net/struct.TcpListener.html
+/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
 ///
 /// # Examples
 ///
@@ -582,9 +600,11 @@ pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
     /// Receives data on the socket from the remote address to which it is
     /// connected.
     ///
-    /// The `connect` method will connect this socket to a remote address. This
+    /// The [`connect`] method will connect this socket to a remote address. This
     /// method will fail if the socket is not connected.
     ///
+    /// [`connect`]: #method.connect
+    ///
     /// # Examples
     ///
     /// ```no_run
index 68d4ca900195c5ed8c3161eaa5d9853942fb5500..c34491941d69010a25f60a5ec6aa3ac947c36f98 100644 (file)
 
 use fmt;
 
-#[cfg(any(target_os = "android",
-          target_os = "emscripten",
+#[cfg(any(target_os = "emscripten",
           all(target_os = "linux", any(target_arch = "aarch64",
                                        target_arch = "arm",
                                        target_arch = "powerpc",
                                        target_arch = "powerpc64",
                                        target_arch = "s390x")),
+          all(target_os = "android", any(target_arch = "aarch64",
+                                         target_arch = "arm")),
           all(target_os = "fuchsia", target_arch = "aarch64")))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8;
-#[cfg(not(any(target_os = "android",
-              target_os = "emscripten",
+#[cfg(not(any(target_os = "emscripten",
               all(target_os = "linux", any(target_arch = "aarch64",
                                            target_arch = "arm",
                                            target_arch = "powerpc",
                                            target_arch = "powerpc64",
                                            target_arch = "s390x")),
+              all(target_os = "android", any(target_arch = "aarch64",
+                                             target_arch = "arm")),
               all(target_os = "fuchsia", target_arch = "aarch64"))))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8;
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8;
index 55118829eee9f950ef900cb1a5ca62c068c63eb9..d688f2fa504517cb3fe450b15f68cc8ea7005f6e 100644 (file)
@@ -641,7 +641,7 @@ fn inner(path: &Path) -> io::Result<UnixListener> {
                 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
                 let (addr, len) = sockaddr_un(path)?;
 
-                cvt(libc::bind(*inner.as_inner(), &addr as *const _ as *const _, len))?;
+                cvt(libc::bind(*inner.as_inner(), &addr as *const _ as *const _, len as _))?;
                 cvt(libc::listen(*inner.as_inner(), 128))?;
 
                 Ok(UnixListener(inner))
@@ -920,7 +920,7 @@ fn inner(path: &Path) -> io::Result<UnixDatagram> {
                 let socket = UnixDatagram::unbound()?;
                 let (addr, len) = sockaddr_un(path)?;
 
-                cvt(libc::bind(*socket.0.as_inner(), &addr as *const _ as *const _, len))?;
+                cvt(libc::bind(*socket.0.as_inner(), &addr as *const _ as *const _, len as _))?;
 
                 Ok(socket)
             }
index 5f1a6c2f7465150a9132072807c3f9259d617651..e9f41009064ca43ea267861b2bfe76cc8fd64718 100644 (file)
@@ -417,12 +417,26 @@ macro_rules! t {
         }
     }
 
+    // Android with api less than 21 define sig* functions inline, so it is not
+    // available for dynamic link. Implementing sigemptyset and sigaddset allow us
+    // to support older Android version (independent of libc version).
+    // The following implementations are based on https://git.io/vSkNf
+
     #[cfg(not(target_os = "android"))]
     extern {
+        #[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")]
+        fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int;
+
         #[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")]
         fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int;
     }
 
+    #[cfg(target_os = "android")]
+    unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
+        libc::memset(set as *mut _, 0, mem::size_of::<libc::sigset_t>());
+        return 0;
+    }
+
     #[cfg(target_os = "android")]
     unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
         use slice;
@@ -450,7 +464,7 @@ fn test_process_mask() {
 
             let mut set: libc::sigset_t = mem::uninitialized();
             let mut old_set: libc::sigset_t = mem::uninitialized();
-            t!(cvt(libc::sigemptyset(&mut set)));
+            t!(cvt(sigemptyset(&mut set)));
             t!(cvt(sigaddset(&mut set, libc::SIGINT)));
             t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, &mut old_set)));
 
index a213273aac8fd55f174a91b145b2e27b139546ee..edd322ca6fa0708b1e4a928f7ecdb3ff66e5480c 100644 (file)
@@ -193,7 +193,16 @@ macro_rules! t {
             // need to clean things up now to avoid confusing the program
             // we're about to run.
             let mut set: libc::sigset_t = mem::uninitialized();
-            t!(cvt(libc::sigemptyset(&mut set)));
+            if cfg!(target_os = "android") {
+                // Implementing sigemptyset allow us to support older Android
+                // versions. See the comment about Android and sig* functions in
+                // process_common.rs
+                libc::memset(&mut set as *mut _ as *mut _,
+                             0,
+                             mem::size_of::<libc::sigset_t>());
+            } else {
+                t!(cvt(libc::sigemptyset(&mut set)));
+            }
             t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set,
                                          ptr::null_mut())));
             let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL);
index 1afb3728c9d72e7d00d20a153631a312b72302e6..dfbc1b581ee55f39b4bb22366beb1240e3c4c79a 100644 (file)
@@ -257,8 +257,13 @@ fn to_handle(&self, stdio_id: c::DWORD, pipe: &mut Option<AnonPipe>)
             // INVALID_HANDLE_VALUE.
             Stdio::Inherit => {
                 match stdio::get(stdio_id) {
-                    Ok(io) => io.handle().duplicate(0, true,
-                                                    c::DUPLICATE_SAME_ACCESS),
+                    Ok(io) => {
+                        let io = Handle::new(io.handle());
+                        let ret = io.duplicate(0, true,
+                                               c::DUPLICATE_SAME_ACCESS);
+                        io.into_raw();
+                        return ret
+                    }
                     Err(..) => Ok(Handle::new(c::INVALID_HANDLE_VALUE)),
                 }
             }
index b1a57c349fbb909e942fc854571ed57967e708ee..d72e4b4438b7bc8d367638bcb55ec96a6bf77474 100644 (file)
 use sys::handle::Handle;
 use sys_common::io::read_to_end_uninitialized;
 
-pub struct NoClose(Option<Handle>);
-
 pub enum Output {
-    Console(NoClose),
-    Pipe(NoClose),
+    Console(c::HANDLE),
+    Pipe(c::HANDLE),
 }
 
 pub struct Stdin {
-    handle: Output,
     utf8: Mutex<io::Cursor<Vec<u8>>>,
 }
-pub struct Stdout(Output);
-pub struct Stderr(Output);
+pub struct Stdout;
+pub struct Stderr;
 
 pub fn get(handle: c::DWORD) -> io::Result<Output> {
     let handle = unsafe { c::GetStdHandle(handle) };
     if handle == c::INVALID_HANDLE_VALUE {
         Err(io::Error::last_os_error())
     } else if handle.is_null() {
-        Err(io::Error::new(io::ErrorKind::Other,
-                           "no stdio handle available for this process"))
+        Err(io::Error::from_raw_os_error(c::ERROR_INVALID_HANDLE as i32))
     } else {
-        let ret = NoClose::new(handle);
         let mut out = 0;
         match unsafe { c::GetConsoleMode(handle, &mut out) } {
-            0 => Ok(Output::Pipe(ret)),
-            _ => Ok(Output::Console(ret)),
+            0 => Ok(Output::Pipe(handle)),
+            _ => Ok(Output::Console(handle)),
         }
     }
 }
 
-fn write(out: &Output, data: &[u8]) -> io::Result<usize> {
-    let handle = match *out {
-        Output::Console(ref c) => c.get().raw(),
-        Output::Pipe(ref p) => return p.get().write(data),
+fn write(handle: c::DWORD, data: &[u8]) -> io::Result<usize> {
+    let handle = match try!(get(handle)) {
+        Output::Console(c) => c,
+        Output::Pipe(p) => {
+            let handle = Handle::new(p);
+            let ret = handle.write(data);
+            handle.into_raw();
+            return ret
+        }
     };
+
     // As with stdin on windows, stdout often can't handle writes of large
     // sizes. For an example, see #14940. For this reason, don't try to
     // write the entire output buffer on windows.
@@ -93,18 +94,20 @@ fn write(out: &Output, data: &[u8]) -> io::Result<usize> {
 
 impl Stdin {
     pub fn new() -> io::Result<Stdin> {
-        get(c::STD_INPUT_HANDLE).map(|handle| {
-            Stdin {
-                handle: handle,
-                utf8: Mutex::new(Cursor::new(Vec::new())),
-            }
+        Ok(Stdin {
+            utf8: Mutex::new(Cursor::new(Vec::new())),
         })
     }
 
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
-        let handle = match self.handle {
-            Output::Console(ref c) => c.get().raw(),
-            Output::Pipe(ref p) => return p.get().read(buf),
+        let handle = match try!(get(c::STD_INPUT_HANDLE)) {
+            Output::Console(c) => c,
+            Output::Pipe(p) => {
+                let handle = Handle::new(p);
+                let ret = handle.read(buf);
+                handle.into_raw();
+                return ret
+            }
         };
         let mut utf8 = self.utf8.lock().unwrap();
         // Read more if the buffer is empty
@@ -125,11 +128,9 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
                 Ok(utf8) => utf8.into_bytes(),
                 Err(..) => return Err(invalid_encoding()),
             };
-            if let Output::Console(_) = self.handle {
-                if let Some(&last_byte) = data.last() {
-                    if last_byte == CTRL_Z {
-                        data.pop();
-                    }
+            if let Some(&last_byte) = data.last() {
+                if last_byte == CTRL_Z {
+                    data.pop();
                 }
             }
             *utf8 = Cursor::new(data);
@@ -158,11 +159,11 @@ fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
 
 impl Stdout {
     pub fn new() -> io::Result<Stdout> {
-        get(c::STD_OUTPUT_HANDLE).map(Stdout)
+        Ok(Stdout)
     }
 
     pub fn write(&self, data: &[u8]) -> io::Result<usize> {
-        write(&self.0, data)
+        write(c::STD_OUTPUT_HANDLE, data)
     }
 
     pub fn flush(&self) -> io::Result<()> {
@@ -172,11 +173,11 @@ pub fn flush(&self) -> io::Result<()> {
 
 impl Stderr {
     pub fn new() -> io::Result<Stderr> {
-        get(c::STD_ERROR_HANDLE).map(Stderr)
+        Ok(Stderr)
     }
 
     pub fn write(&self, data: &[u8]) -> io::Result<usize> {
-        write(&self.0, data)
+        write(c::STD_ERROR_HANDLE, data)
     }
 
     pub fn flush(&self) -> io::Result<()> {
@@ -197,27 +198,12 @@ fn flush(&mut self) -> io::Result<()> {
     }
 }
 
-impl NoClose {
-    fn new(handle: c::HANDLE) -> NoClose {
-        NoClose(Some(Handle::new(handle)))
-    }
-
-    fn get(&self) -> &Handle { self.0.as_ref().unwrap() }
-}
-
-impl Drop for NoClose {
-    fn drop(&mut self) {
-        self.0.take().unwrap().into_raw();
-    }
-}
-
 impl Output {
-    pub fn handle(&self) -> &Handle {
-        let nc = match *self {
-            Output::Console(ref c) => c,
-            Output::Pipe(ref c) => c,
-        };
-        nc.0.as_ref().unwrap()
+    pub fn handle(&self) -> c::HANDLE {
+        match *self {
+            Output::Console(c) => c,
+            Output::Pipe(c) => c,
+        }
     }
 }
 
index 3cdeb511945756d7d8c451ad4ff89ff6aac8f164..9239c18e59717a2bf088859ff05a8dbbccfbe81a 100644 (file)
@@ -339,7 +339,7 @@ pub fn bind(addr: &SocketAddr) -> io::Result<TcpListener> {
 
         // Bind our new socket
         let (addrp, len) = addr.into_inner();
-        cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) })?;
+        cvt(unsafe { c::bind(*sock.as_inner(), addrp, len as _) })?;
 
         // Start listening
         cvt(unsafe { c::listen(*sock.as_inner(), 128) })?;
@@ -430,7 +430,7 @@ pub fn bind(addr: &SocketAddr) -> io::Result<UdpSocket> {
 
         let sock = Socket::new(addr, c::SOCK_DGRAM)?;
         let (addrp, len) = addr.into_inner();
-        cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) })?;
+        cvt(unsafe { c::bind(*sock.as_inner(), addrp, len as _) })?;
         Ok(UdpSocket { inner: sock })
     }
 
index b980300126e4b8a2b8b05d9323ecdf3b6dfc063e..92e5369758b4e5914dff87ebfedbf2862ae02a42 100644 (file)
@@ -842,11 +842,11 @@ pub fn to_lowercase(self) -> ToLowercase {
     /// Returns an iterator that yields the uppercase equivalent of a `char`
     /// as one or more `char`s.
     ///
-    /// If a character does not have a uppercase equivalent, the same character
+    /// If a character does not have an uppercase equivalent, the same character
     /// will be returned back by the iterator.
     ///
     /// This performs complex unconditional mappings with no tailoring: it maps
-    /// one Unicode character to its lowercase equivalent according to the
+    /// one Unicode character to its uppercase equivalent according to the
     /// [Unicode database] and the additional complex mappings
     /// [`SpecialCasing.txt`]. Conditional mappings (based on context or
     /// language) are not considered here.
index 0b38f5450b63faf09251971ad20926318130c2ff..97d37266130af750a304561f1eb0ec33ae06f5e7 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 
 [dependencies]
 serialize = { path = "../libserialize" }
-log = { path = "../liblog" }
+log = "0.3"
 rustc_bitflags = { path = "../librustc_bitflags" }
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_errors = { path = "../librustc_errors" }
index f0e328a551d5f37003d53bf6f93a40617708ea83..2d0994a7b78fb1b798f00cd04366b20fab589d7c 100644 (file)
@@ -106,8 +106,8 @@ fn remove(&mut self, id: ast::NodeId) -> Expansion {
 impl<'a, 'b> Folder for PlaceholderExpander<'a, 'b> {
     fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
         match item.node {
-            ast::ItemKind::Mac(ref mac) if !mac.node.path.segments.is_empty() => {}
             ast::ItemKind::Mac(_) => return self.remove(item.id).make_items(),
+            ast::ItemKind::MacroDef(_) => return SmallVector::one(item),
             _ => {}
         }
 
index 021c5398a4200459218a8f94d78df25ed77b6502..66f5520b8826371991822087a551cfc35277a80e 100644 (file)
@@ -119,7 +119,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                 };
                 let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), false);
                 p.root_module_name = cx.current_expansion.module.mod_path.last()
-                    .map(|id| (*id.name.as_str()).to_owned());
+                    .map(|id| id.name.as_str().to_string());
 
                 p.check_unknown_macro_variable();
                 // Let the context choose how to interpret the result.
index 7af432176cf6ea44d0160cb0387ee577f3ea9013..9d280a413e666c5403015bcbdc9ccec310febd68 100644 (file)
@@ -818,7 +818,7 @@ pub struct GatedCfg {
 
 impl GatedCfg {
     pub fn gate(cfg: &ast::MetaItem) -> Option<GatedCfg> {
-        let name = &*cfg.name().as_str();
+        let name = cfg.name().as_str();
         GATED_CFGS.iter()
                   .position(|info| info.0 == name)
                   .map(|idx| {
@@ -865,8 +865,7 @@ macro_rules! gate_feature {
 impl<'a> Context<'a> {
     fn check_attribute(&self, attr: &ast::Attribute, is_macro: bool) {
         debug!("check_attribute(attr = {:?})", attr);
-        let name = unwrap_or!(attr.name(), return);
-
+        let name = unwrap_or!(attr.name(), return).as_str();
         for &(n, ty, ref gateage) in BUILTIN_ATTRIBUTES {
             if name == n {
                 if let &Gated(_, ref name, ref desc, ref has_feature) = gateage {
@@ -885,12 +884,12 @@ fn check_attribute(&self, attr: &ast::Attribute, is_macro: bool) {
                 return;
             }
         }
-        if name.as_str().starts_with("rustc_") {
+        if name.starts_with("rustc_") {
             gate_feature!(self, rustc_attrs, attr.span,
                           "unless otherwise specified, attributes \
                            with the prefix `rustc_` \
                            are reserved for internal compiler diagnostics");
-        } else if name.as_str().starts_with("derive_") {
+        } else if name.starts_with("derive_") {
             gate_feature!(self, custom_derive, attr.span, EXPLAIN_DERIVE_UNDERSCORE);
         } else if !attr::is_known(attr) {
             // Only run the custom attribute lint during regular
index 649e90599345bf93aa5ee6bc0f7e4e8e3dad75ec..43a9d8c5f787c77bcc993e6f5a701c668e97b95f 100644 (file)
@@ -5151,15 +5151,15 @@ fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo>
 
     fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
         if let Some(path) = attr::first_attr_value_str_by_name(attrs, "path") {
-            self.directory.path.push(&*path.as_str());
+            self.directory.path.push(&path.as_str());
             self.directory.ownership = DirectoryOwnership::Owned;
         } else {
-            self.directory.path.push(&*id.name.as_str());
+            self.directory.path.push(&id.name.as_str());
         }
     }
 
     pub fn submod_path_from_attr(attrs: &[ast::Attribute], dir_path: &Path) -> Option<PathBuf> {
-        attr::first_attr_value_str_by_name(attrs, "path").map(|d| dir_path.join(&*d.as_str()))
+        attr::first_attr_value_str_by_name(attrs, "path").map(|d| dir_path.join(&d.as_str()))
     }
 
     /// Returns either a path to a module, or .
index 6642c60d256b3c4e40e0cc437ddb60993544e1f6..2acbeee426beead4b72b286e16bfffacf89957ad 100644 (file)
@@ -72,9 +72,9 @@ fn decode<D: Decoder>(d: &mut D) -> Result<Symbol, D::Error> {
     }
 }
 
-impl<'a> PartialEq<&'a str> for Symbol {
-    fn eq(&self, other: &&str) -> bool {
-        *self.as_str() == **other
+impl<T: ::std::ops::Deref<Target=str>> PartialEq<T> for Symbol {
+    fn eq(&self, other: &T) -> bool {
+        self.as_str() == other.deref()
     }
 }
 
@@ -244,11 +244,47 @@ fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
 /// destroyed. In particular, they must not access string contents. This can
 /// be fixed in the future by just leaking all strings until thread death
 /// somehow.
-#[derive(Clone, PartialEq, Hash, PartialOrd, Eq, Ord)]
+#[derive(Clone, Hash, PartialOrd, Eq, Ord)]
 pub struct InternedString {
     string: &'static str,
 }
 
+impl<U: ?Sized> ::std::convert::AsRef<U> for InternedString where str: ::std::convert::AsRef<U> {
+    fn as_ref(&self) -> &U {
+        self.string.as_ref()
+    }
+}
+
+impl<T: ::std::ops::Deref<Target = str>> ::std::cmp::PartialEq<T> for InternedString {
+    fn eq(&self, other: &T) -> bool {
+        self.string == other.deref()
+    }
+}
+
+impl ::std::cmp::PartialEq<InternedString> for str {
+    fn eq(&self, other: &InternedString) -> bool {
+        self == other.string
+    }
+}
+
+impl<'a> ::std::cmp::PartialEq<InternedString> for &'a str {
+    fn eq(&self, other: &InternedString) -> bool {
+        *self == other.string
+    }
+}
+
+impl ::std::cmp::PartialEq<InternedString> for String {
+    fn eq(&self, other: &InternedString) -> bool {
+        self == other.string
+    }
+}
+
+impl<'a> ::std::cmp::PartialEq<InternedString> for &'a String {
+    fn eq(&self, other: &InternedString) -> bool {
+        *self == other.string
+    }
+}
+
 impl !Send for InternedString { }
 
 impl ::std::ops::Deref for InternedString {
index e052d2cda3a42469b000be576f82b416a08bb20c..6fb6db9ca0282fd09cac855a9f6f3838714694ea 100644 (file)
@@ -616,7 +616,7 @@ fn mk_tests(cx: &TestCtxt) -> P<ast::Item> {
 
 fn is_test_crate(krate: &ast::Crate) -> bool {
     match attr::find_crate_name(&krate.attrs) {
-        Some(s) if "test" == &*s.as_str() => true,
+        Some(s) if "test" == s.as_str() => true,
         _ => false
     }
 }
index 960db792a623e4c2a1ab38cb60b12ba37481ff41..bdcec26cb838b211ba5980542da2ca62bb386b99 100644 (file)
@@ -10,7 +10,7 @@ crate-type = ["dylib"]
 
 [dependencies]
 fmt_macros = { path = "../libfmt_macros" }
-log = { path = "../liblog" }
+log = "0.3"
 proc_macro = { path = "../libproc_macro" }
 rustc_errors = { path = "../librustc_errors" }
 syntax = { path = "../libsyntax" }
diff --git a/src/rt/hoedown b/src/rt/hoedown
deleted file mode 160000 (submodule)
index da282f1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit da282f1bb7277b4d30fa1599ee29ad8eb4dd2a92
index 6fecd3a27a8a459f2d3237fe67d3bc4be2ca5502..a4f43c42623d33be11e547c4b6f9f1694f841e6b 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(rustdoc)]
+#![feature(rustc_private)]
 
 extern crate rustdoc;
 
diff --git a/src/test/compile-fail/imports/shadow_builtin_macros.rs b/src/test/compile-fail/imports/shadow_builtin_macros.rs
new file mode 100644 (file)
index 0000000..2b3ba1b
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:two_macros.rs
+
+#![feature(use_extern_macros)]
+
+mod foo {
+    extern crate two_macros;
+    pub use self::two_macros::m as panic;
+}
+
+mod m1 {
+    use foo::panic; // ok
+    fn f() { panic!(); }
+}
+
+mod m2 {
+    use foo::*; //~ NOTE `panic` could refer to the name imported here
+    fn f() { panic!(); } //~ ERROR ambiguous
+    //~| NOTE `panic` is also a builtin macro
+    //~| NOTE consider adding an explicit import of `panic` to disambiguate
+}
+
+mod m3 {
+    ::two_macros::m!(use foo::panic;); //~ NOTE `panic` could refer to the name imported here
+    //~| NOTE in this expansion
+    fn f() { panic!(); } //~ ERROR ambiguous
+    //~| NOTE `panic` is also a builtin macro
+    //~| NOTE macro-expanded macro imports do not shadow
+}
+
+mod m4 {
+    macro_rules! panic { () => {} } // ok
+    panic!();
+}
+
+mod m5 {
+    macro_rules! m { () => {
+        macro_rules! panic { () => {} } //~ ERROR `panic` is already in scope
+        //~| NOTE macro-expanded `macro_rules!`s may not shadow existing macros
+    } }
+    m!(); //~ NOTE in this expansion
+    //~| NOTE in this expansion
+    panic!();
+}
+
+#[macro_use(n)] //~ NOTE `n` could also refer to the name imported here
+extern crate two_macros;
+mod bar {
+    pub use two_macros::m as n;
+}
+
+mod m6 {
+    use bar::n; // ok
+    n!();
+}
+
+mod m7 {
+    use bar::*; //~ NOTE `n` could refer to the name imported here
+    n!(); //~ ERROR ambiguous
+    //~| NOTE consider adding an explicit import of `n` to disambiguate
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-40000.rs b/src/test/compile-fail/issue-40000.rs
new file mode 100644 (file)
index 0000000..9be114e
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-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(closure_to_fn_coercion)]
+
+fn main() {
+    let bar: fn(&mut u32) = |_| {}; //~ ERROR mismatched types
+    //~| expected concrete lifetime, found bound lifetime parameter
+
+    fn foo(x: Box<Fn(&i32)>) {}
+    let bar = Box::new(|x: &i32| {}) as Box<Fn(_)>;
+    foo(bar); //~ ERROR mismatched types
+    //~| expected concrete lifetime, found bound lifetime parameter
+}
diff --git a/src/test/compile-fail/issue-40749.rs b/src/test/compile-fail/issue-40749.rs
new file mode 100644 (file)
index 0000000..261ed49
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-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() {
+    [0; ..10];
+    //~^ ERROR mismatched types
+    //~| expected type `usize`
+    //~| found type `std::ops::RangeTo<{integer}>`
+}
diff --git a/src/test/compile-fail/issue-40845.rs b/src/test/compile-fail/issue-40845.rs
new file mode 100644 (file)
index 0000000..c5604a0
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait T { m!(); } //~ ERROR cannot find macro `m!` in this scope
+
+struct S;
+impl S { m!(); } //~ ERROR cannot find macro `m!` in this scope
+
+fn main() {}
diff --git a/src/test/compile-fail/static-lifetime-bound.rs b/src/test/compile-fail/static-lifetime-bound.rs
new file mode 100644 (file)
index 0000000..38534ab
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn f<'a: 'static>(_: &'a i32) {} //~WARN unnecessary lifetime parameter `'a`
+
+fn main() {
+    let x = 0;
+    f(&x); //~ERROR does not live long enough
+}
diff --git a/src/test/run-pass-fulldeps/auxiliary/logging_right_crate.rs b/src/test/run-pass-fulldeps/auxiliary/logging_right_crate.rs
deleted file mode 100644 (file)
index db26b10..0000000
+++ /dev/null
@@ -1,18 +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(rustc_private)]
-
-#[macro_use] extern crate log;
-
-pub fn foo<T>() {
-    fn death() -> isize { panic!() }
-    debug!("{}", (||{ death() })());
-}
diff --git a/src/test/run-pass-fulldeps/conditional-debug-macro-off.rs b/src/test/run-pass-fulldeps/conditional-debug-macro-off.rs
deleted file mode 100644 (file)
index c6beb5b..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags: -C debug-assertions=no
-// exec-env:RUST_LOG=conditional-debug-macro-off=4
-
-
-#![feature(rustc_private)]
-
-#[macro_use]
-extern crate log;
-
-pub fn main() {
-    // only panics if println! evaluates its argument.
-    debug!("{:?}", { if true { panic!() } });
-}
diff --git a/src/test/run-pass-fulldeps/logging-enabled-debug.rs b/src/test/run-pass-fulldeps/logging-enabled-debug.rs
deleted file mode 100644 (file)
index 3ae4884..0000000
+++ /dev/null
@@ -1,24 +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.
-
-// compile-flags:-C debug-assertions=no
-// exec-env:RUST_LOG=logging-enabled-debug=debug
-
-
-#![feature(rustc_private)]
-
-#[macro_use]
-extern crate log;
-
-pub fn main() {
-    if log_enabled!(log::DEBUG) {
-        panic!("what?! debugging?");
-    }
-}
diff --git a/src/test/run-pass-fulldeps/logging-enabled.rs b/src/test/run-pass-fulldeps/logging-enabled.rs
deleted file mode 100644 (file)
index 2626134..0000000
+++ /dev/null
@@ -1,27 +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.
-
-// exec-env:RUST_LOG=logging_enabled=info
-// ignore-emscripten: FIXME(#31622)
-
-
-#![feature(rustc_private)]
-
-#[macro_use]
-extern crate log;
-
-pub fn main() {
-    if log_enabled!(log::DEBUG) {
-        panic!("what?! debugging?");
-    }
-    if !log_enabled!(log::INFO) {
-        panic!("what?! no info?");
-    }
-}
diff --git a/src/test/run-pass-fulldeps/logging-right-crate.rs b/src/test/run-pass-fulldeps/logging-right-crate.rs
deleted file mode 100644 (file)
index 7caeeb4..0000000
+++ /dev/null
@@ -1,31 +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.
-
-// aux-build:logging_right_crate.rs
-// exec-env:RUST_LOG=logging-right-crate=debug
-
-// This is a test for issue #3046 to make sure that when we monomorphize a
-// function from one crate to another the right top-level logging name is
-// preserved.
-//
-// It used to be the case that if logging were turned on for this crate, all
-// monomorphized functions from other crates had logging turned on (their
-// logging module names were all incorrect). This test ensures that this no
-// longer happens by enabling logging for *this* crate and then invoking a
-// function in an external crate which will panic when logging is enabled.
-
-// pretty-expanded FIXME #23616
-
-extern crate logging_right_crate;
-
-pub fn main() {
-    // this function panicks if logging is turned on
-    logging_right_crate::foo::<isize>();
-}
diff --git a/src/test/run-pass-fulldeps/logging-separate-lines.rs b/src/test/run-pass-fulldeps/logging-separate-lines.rs
deleted file mode 100644 (file)
index 183a522..0000000
+++ /dev/null
@@ -1,40 +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-windows
-// exec-env:RUST_LOG=debug
-// compile-flags:-C debug-assertions=y
-// ignore-emscripten: FIXME(#31622)
-
-#![feature(rustc_private)]
-
-#[macro_use]
-extern crate log;
-
-use std::process::Command;
-use std::env;
-use std::str;
-
-fn main() {
-    let args: Vec<String> = env::args().collect();
-    if args.len() > 1 && args[1] == "child" {
-        debug!("foo");
-        debug!("bar");
-        return
-    }
-
-    let p = Command::new(&args[0])
-                    .arg("child")
-                    .output().unwrap();
-    assert!(p.status.success());
-    let mut lines = str::from_utf8(&p.stderr).unwrap().lines();
-    assert!(lines.next().unwrap().contains("foo"));
-    assert!(lines.next().unwrap().contains("bar"));
-}
diff --git a/src/test/run-pass-fulldeps/rust-log-filter.rs b/src/test/run-pass-fulldeps/rust-log-filter.rs
deleted file mode 100644 (file)
index 306d24e..0000000
+++ /dev/null
@@ -1,58 +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.
-
-// exec-env:RUST_LOG=rust_log_filter/foo
-// ignore-emscripten no threads support
-
-#![allow(unknown_features)]
-#![feature(box_syntax, std_misc, rustc_private)]
-
-#[macro_use]
-extern crate log;
-
-use std::sync::mpsc::{channel, Sender, Receiver};
-use std::thread;
-
-pub struct ChannelLogger {
-    tx: Sender<String>
-}
-
-impl ChannelLogger {
-    pub fn new() -> (Box<ChannelLogger>, Receiver<String>) {
-        let (tx, rx) = channel();
-        (box ChannelLogger { tx: tx }, rx)
-    }
-}
-
-impl log::Logger for ChannelLogger {
-    fn log(&mut self, record: &log::LogRecord) {
-        self.tx.send(format!("{}", record.args)).unwrap();
-    }
-}
-
-pub fn main() {
-    let (logger, rx) = ChannelLogger::new();
-
-    let t = thread::spawn(move|| {
-        log::set_logger(logger);
-
-        info!("foo");
-        info!("bar");
-        info!("foo bar");
-        info!("bar foo");
-    });
-
-    assert_eq!(rx.recv().unwrap(), "foo");
-    assert_eq!(rx.recv().unwrap(), "foo bar");
-    assert_eq!(rx.recv().unwrap(), "bar foo");
-    assert!(rx.recv().is_err());
-
-    t.join();
-}
diff --git a/src/test/run-pass-fulldeps/switch-stdout.rs b/src/test/run-pass-fulldeps/switch-stdout.rs
new file mode 100644 (file)
index 0000000..4542e27
--- /dev/null
@@ -0,0 +1,64 @@
+// 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.
+
+#![feature(rustc_private)]
+
+extern crate rustc_back;
+
+use std::fs::File;
+use std::io::{Read, Write};
+
+use rustc_back::tempdir::TempDir;
+
+#[cfg(unix)]
+fn switch_stdout_to(file: File) {
+    use std::os::unix::prelude::*;
+
+    extern {
+        fn dup2(old: i32, new: i32) -> i32;
+    }
+
+    unsafe {
+        assert_eq!(dup2(file.as_raw_fd(), 1), 1);
+    }
+}
+
+#[cfg(windows)]
+fn switch_stdout_to(file: File) {
+    use std::os::windows::prelude::*;
+
+    extern "system" {
+        fn SetStdHandle(nStdHandle: u32, handle: *mut u8) -> i32;
+    }
+
+    const STD_OUTPUT_HANDLE: u32 = (-11i32) as u32;
+
+    unsafe {
+        let rc = SetStdHandle(STD_OUTPUT_HANDLE,
+                              file.into_raw_handle() as *mut _);
+        assert!(rc != 0);
+    }
+}
+
+fn main() {
+    let td = TempDir::new("foo").unwrap();
+    let path = td.path().join("bar");
+    let f = File::create(&path).unwrap();
+
+    println!("foo");
+    std::io::stdout().flush().unwrap();
+    switch_stdout_to(f);
+    println!("bar");
+    std::io::stdout().flush().unwrap();
+
+    let mut contents = String::new();
+    File::open(&path).unwrap().read_to_string(&mut contents).unwrap();
+    assert_eq!(contents, "bar\n");
+}
index b335e20f91d932df7a127b37a6eca2e56c4b73f8..7da33be7a57daf19faa1a47bcad1fc9f4be345a4 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// exec-env:RUST_LOG=conditional-debug-macro-on=4
-
 pub fn main() {
     // exits early if println! evaluates its arguments, otherwise it
     // will hit the panic.
diff --git a/src/test/run-pass/issue-40770.rs b/src/test/run-pass/issue-40770.rs
new file mode 100644 (file)
index 0000000..599d0b2
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-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! m {
+    ($e:expr) => {
+        macro_rules! n { () => { $e } }
+    }
+}
+
+fn main() {
+    m!(foo!());
+}
index 1fc98a78a7c473c73148174942d0e62f82bb9fda..7530b65a9b7c4fc383dc24fe94a6426e81593d66 100644 (file)
@@ -5,6 +5,6 @@ version = "0.0.0"
 
 [dependencies]
 log = "0.3"
-env_logger = { version = "0.3.5", default-features = false }
+env_logger = { version = "0.4", default-features = false }
 rustc-serialize = "0.3"
 filetime = "0.1"
index f55667f93c031939c534cd8d79ced66704d71e91..3d8f2296236a2014c6c60df5657c7ab5fd522b26 100644 (file)
@@ -58,24 +58,8 @@ pub fn run(lib_path: &str,
     let mut cmd = Command::new(prog);
     cmd.args(args)
         .stdout(Stdio::piped())
-        .stderr(Stdio::piped());
-
-    // Why oh why do we sometimes make a pipe and sometimes inherit the stdin
-    // stream, well that's an excellent question! In theory it should suffice to
-    // always create a pipe here and be done with it. Unfortunately though
-    // there's apparently something odd with the gdb that comes with gcc 6.3.0
-    // on MinGW. Tracked at rust-lang/rust#40184 when stdin is piped here
-    // (unconditionally) then all gdb tests will fail on MinGW when using gcc
-    // 6.3.0. WHen using an inherited stdin though they happen to all work!
-    //
-    // As to why this fixes the issue, well, I have no idea. If you can remove
-    // this branch and unconditionally use `piped` and it gets past @bors please
-    // feel free to send a PR!
-    if input.is_some() || !cfg!(windows) {
-        cmd.stdin(Stdio::piped());
-    } else {
-        cmd.stdin(Stdio::inherit());
-    }
+        .stderr(Stdio::piped())
+        .stdin(Stdio::piped());
 
     add_target_env(&mut cmd, lib_path, aux_path);
     for (key, val) in env {
index e33df0dfbc8dec5cf344341d76546138dc15e39a..1d4f2c60d544f6ea05366167e93ba0aed74bc959 100644 (file)
@@ -24,7 +24,7 @@
 
 use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata};
 
-use rustdoc::html::markdown::{Markdown, PLAYGROUND};
+use rustdoc::html::markdown::{Markdown, MarkdownOutputStyle, PLAYGROUND};
 use rustc_serialize::json;
 
 enum OutputFormat {
@@ -100,7 +100,7 @@ fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
 
         // Description rendered as markdown.
         match info.description {
-            Some(ref desc) => write!(output, "{}", Markdown(desc))?,
+            Some(ref desc) => write!(output, "{}", Markdown(desc, MarkdownOutputStyle::Fancy))?,
             None => write!(output, "<p>No description.</p>\n")?,
         }