]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #40457 - frewsxcv:frewsxcv-macos, r=steveklabnik
authorCorey Farwell <coreyf@rwell.org>
Fri, 17 Mar 2017 12:48:52 +0000 (08:48 -0400)
committerGitHub <noreply@github.com>
Fri, 17 Mar 2017 12:48:52 +0000 (08:48 -0400)
Update usages of 'OSX' (and other old names) to 'macOS'.

As of last year with version 'Sierra', the Mac operating system is now
called 'macOS'.

109 files changed:
.travis.yml
appveyor.yml
configure
src/Cargo.lock
src/bootstrap/channel.rs
src/bootstrap/config.rs
src/bootstrap/config.toml.example
src/bootstrap/dist.rs
src/bootstrap/doc.rs
src/bootstrap/install.rs
src/bootstrap/lib.rs
src/bootstrap/native.rs
src/bootstrap/step.rs
src/ci/run.sh
src/doc/book/src/ffi.md
src/doc/book/src/guessing-game.md
src/doc/unstable-book/src/concat-idents.md
src/doc/unstable-book/src/conservative-impl-trait.md
src/doc/unstable-book/src/const-fn.md
src/doc/unstable-book/src/const-indexing.md
src/doc/unstable-book/src/i128-type.md
src/doc/unstable-book/src/non-ascii-idents.md
src/liballoc/rc.rs
src/libcollections/binary_heap.rs
src/libcollections/slice.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollections/vec.rs
src/libcollectionstest/lib.rs
src/libcollectionstest/str.rs
src/libcore/char.rs
src/libcore/clone.rs
src/libcore/convert.rs
src/libcore/hash/mod.rs
src/libcore/iter/iterator.rs
src/libcore/iter/mod.rs
src/libcore/iter/sources.rs
src/libcore/iter/traits.rs
src/libcore/macros.rs
src/libcore/marker.rs
src/libcore/mem.rs
src/libcore/num/mod.rs
src/libcore/ops.rs
src/libcore/ptr.rs
src/libcore/str/mod.rs
src/libproc_macro/lib.rs
src/librustc/hir/lowering.rs
src/librustc_driver/lib.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/librustc_trans/mir/block.rs
src/librustc_trans/mir/operand.rs
src/librustdoc/html/render.rs
src/libstd/collections/hash/map.rs
src/libstd/collections/hash/table.rs
src/libstd/ffi/c_str.rs
src/libstd/ffi/os_str.rs
src/libstd/fs.rs
src/libstd/io/error.rs
src/libstd/io/mod.rs
src/libstd/io/stdio.rs
src/libstd/io/util.rs
src/libstd/lib.rs
src/libstd/net/tcp.rs
src/libstd/net/udp.rs
src/libstd/panicking.rs
src/libstd/path.rs
src/libstd/prelude/mod.rs
src/libstd/primitive_docs.rs
src/libstd/sync/barrier.rs
src/libstd/sync/condvar.rs
src/libstd/sync/mpsc/mod.rs
src/libstd/sync/mutex.rs
src/libstd/sync/rwlock.rs
src/libstd/sys/redox/os_str.rs
src/libstd/sys/unix/ext/net.rs
src/libstd/sys/unix/os_str.rs
src/libstd/sys/windows/os_str.rs
src/libstd/sys_common/wtf8.rs
src/libstd/thread/mod.rs
src/libstd_unicode/char.rs
src/libsyntax/ast.rs
src/libsyntax/ext/build.rs
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pprust.rs
src/libsyntax/std_inject.rs
src/libsyntax/symbol.rs
src/libsyntax/test.rs
src/libsyntax/visit.rs
src/libsyntax_ext/concat_idents.rs
src/rustllvm/llvm-auto-clean-trigger [deleted file]
src/rustllvm/llvm-rebuild-trigger [new file with mode: 0644]
src/test/codegen/packed.rs
src/test/compile-fail/catch-in-match.rs [new file with mode: 0644]
src/test/compile-fail/catch-in-while.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-catch_expr.rs [new file with mode: 0644]
src/test/run-pass/catch-expr.rs [new file with mode: 0644]
src/test/ui/resolve/enums-are-namespaced-xc.stderr
src/test/ui/resolve/levenshtein.stderr
src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr
src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr
src/test/ui/span/issue-29595.rs [new file with mode: 0644]
src/test/ui/span/issue-29595.stderr [new file with mode: 0644]
src/tools/build-manifest/src/main.rs
src/tools/rustbook/Cargo.toml

index a9867cbc11e0e3127e3eaa1f70bfb7ee47f5d2ac..988ef66f8faddbbdcc97a48163549267cb122c67 100644 (file)
@@ -47,7 +47,7 @@ matrix:
         SRC=.
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
         SCCACHE_ERROR_LOG=/tmp/sccache.log
-        RUST_LOG=sccache
+        RUST_LOG=sccache=debug
       os: osx
       osx_image: xcode8.2
       install: &osx_install_sccache >
@@ -59,7 +59,7 @@ matrix:
         SRC=.
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
         SCCACHE_ERROR_LOG=/tmp/sccache.log
-        RUST_LOG=sccache
+        RUST_LOG=sccache=debug
       os: osx
       osx_image: xcode8.2
       install: *osx_install_sccache
@@ -71,7 +71,7 @@ matrix:
         DEPLOY=1
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
         SCCACHE_ERROR_LOG=/tmp/sccache.log
-        RUST_LOG=sccache
+        RUST_LOG=sccache=debug
       os: osx
       osx_image: xcode8.2
       install: >
@@ -84,7 +84,7 @@ matrix:
         DEPLOY=1
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
         SCCACHE_ERROR_LOG=/tmp/sccache.log
-        RUST_LOG=sccache
+        RUST_LOG=sccache=debug
       os: osx
       osx_image: xcode8.2
       install: *osx_install_sccache
@@ -101,7 +101,7 @@ matrix:
         DEPLOY_ALT=1
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
         SCCACHE_ERROR_LOG=/tmp/sccache.log
-        RUST_LOG=sccache
+        RUST_LOG=sccache=debug
       os: osx
       osx_image: xcode8.2
       install: *osx_install_sccache
index 46ff9a252a0f6af2c67acca0c4ac9c1f756ef7a5..94a5efb3a2ffbb98012917fe1001864c0abb2d81 100644 (file)
@@ -131,7 +131,7 @@ install:
   - handle.exe -accepteula -help
 
   # Attempt to debug sccache failures
-  - set RUST_LOG=sccache
+  - set RUST_LOG=sccache=debug
   - set SCCACHE_ERROR_LOG=%CD%/sccache.log
 
 test_script:
@@ -144,10 +144,10 @@ on_failure:
   - cat %CD%/sccache.log
 
 cache:
-  - "build/i686-pc-windows-msvc/llvm -> src/rustllvm/llvm-auto-clean-trigger"
-  - "build/x86_64-pc-windows-msvc/llvm -> src/rustllvm/llvm-auto-clean-trigger"
-  - "i686-pc-windows-msvc/llvm -> src/rustllvm/llvm-auto-clean-trigger"
-  - "x86_64-pc-windows-msvc/llvm -> src/rustllvm/llvm-auto-clean-trigger"
+  - "build/i686-pc-windows-msvc/llvm -> src/rustllvm/llvm-rebuild-trigger"
+  - "build/x86_64-pc-windows-msvc/llvm -> src/rustllvm/llvm-rebuild-trigger"
+  - "i686-pc-windows-msvc/llvm -> src/rustllvm/llvm-rebuild-trigger"
+  - "x86_64-pc-windows-msvc/llvm -> src/rustllvm/llvm-rebuild-trigger"
 
 branches:
   only:
index 9b34e214214a5e173ec7bbc9957e47695be8a5b4..d6dded6dc5f7bccfbeb0d57a48f394d7b326f1f7 100755 (executable)
--- a/configure
+++ b/configure
@@ -437,6 +437,7 @@ opt local-rust 0 "use an installed rustc rather than downloading a snapshot"
 opt local-rebuild 0 "assume local-rust matches the current version, for rebuilds; implies local-rust, and is implied if local-rust already matches the current version"
 opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM"
 opt llvm-link-shared 0 "prefer shared linking to LLVM (llvm-config --link-shared)"
+opt llvm-clean-rebuild 0 "delete LLVM build directory on rebuild"
 opt rpath 1 "build rpaths into rustc itself"
 opt stage0-landing-pads 1 "enable landing pads during bootstrap with stage0"
 # This is used by the automation to produce single-target nightlies
@@ -444,6 +445,7 @@ opt dist-host-only 0 "only install bins for the host architecture"
 opt inject-std-version 1 "inject the current compiler version of libstd into programs"
 opt llvm-version-check 1 "check if the LLVM version is supported, build anyway"
 opt codegen-tests 1 "run the src/test/codegen tests"
+opt save-analysis 0 "save API analysis data"
 opt option-checking 1 "complain about unrecognized options in this configure script"
 opt ninja 0 "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)"
 opt locked-deps 0 "force Cargo.lock to be up to date"
index 6dc71e8b602db46269af3a242531e8db205d8e05..b34007db8ac7af314b10f246cd54147df60fef6b 100644 (file)
@@ -67,7 +67,7 @@ dependencies = [
  "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "gcc 0.3.43 (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.20 (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)",
  "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -99,7 +99,7 @@ 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)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.21 (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)",
@@ -139,7 +139,7 @@ version = "0.0.0"
 dependencies = [
  "env_logger 0.3.5 (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.6 (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.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -157,15 +157,15 @@ name = "env_logger"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "env_logger"
-version = "0.4.0"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -178,7 +178,7 @@ name = "filetime"
 version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -216,13 +216,13 @@ name = "handlebars"
 version = "0.25.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.2.4 (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)",
  "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -241,7 +241,7 @@ dependencies = [
 
 [[package]]
 name = "lazy_static"
-version = "0.2.2"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -253,7 +253,7 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.20"
+version = "0.2.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -266,24 +266,24 @@ version = "0.0.0"
 
 [[package]]
 name = "log"
-version = "0.3.6"
+version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "mdbook"
-version = "0.0.17"
+version = "0.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "env_logger 0.4.0 (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)",
- "log 0.3.6 (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)",
  "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -291,12 +291,12 @@ name = "memchr"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "num-traits"
-version = "0.1.36"
+version = "0.1.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -304,7 +304,7 @@ name = "num_cpus"
 version = "0.2.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -402,7 +402,7 @@ name = "rustbook"
 version = "0.1.0"
 dependencies = [
  "clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "mdbook 0.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mdbook 0.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -770,18 +770,18 @@ dependencies = [
 
 [[package]]
 name = "serde"
-version = "0.9.7"
+version = "0.9.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde_json"
-version = "0.9.7"
+version = "0.9.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -865,7 +865,7 @@ version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -883,7 +883,7 @@ version = "3.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -909,10 +909,10 @@ dependencies = [
 
 [[package]]
 name = "toml"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -967,19 +967,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum cmake 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "e1acc68a3f714627af38f9f5d09706a28584ba60dfe2cca68f40bf779f941b25"
 "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.0 (registry+https://github.com/rust-lang/crates.io-index)" = "99971fb1b635fe7a0ee3c4d065845bb93cca80a23b5613b5613391ece5de4144"
+"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.43 (registry+https://github.com/rust-lang/crates.io-index)" = "c07c758b972368e703a562686adb39125707cc1ef3399da8c019fc6c2498a75d"
 "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 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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6abe0ee2e758cd6bc8a2cd56726359007748fbf4128da998b65d0b70f881e19b"
-"checksum libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "684f330624d8c3784fb9558ca46c4ce488073a8d22450415c5eb4f4cfb0d11b5"
-"checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054"
-"checksum mdbook 0.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "dbba458ca886cb082d026afd704eeeeb0531f7e4ffd6c619f72dc309c1c18fe4"
+"checksum lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7291b1dd97d331f752620b02dfdbc231df7fc01bf282a00769e1cdb963c460dc"
+"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"
 "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
-"checksum num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "a16a42856a256b39c6d3484f097f6713e14feacd9bfb02290917904fae46c81c"
+"checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
 "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"
@@ -988,14 +988,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
 "checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457"
 "checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b"
-"checksum serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1e0ed773960f90a78567fcfbe935284adf50c5d7cf119aa2cf43bb0b4afa69bb"
-"checksum serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb96d30e4e6f9fc52e08f51176d078b6f79b981dc3ed4134f7b850be9f446a8"
+"checksum serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a702319c807c016e51f672e5c77d6f0b46afddd744b5e437d6b8436b888b458f"
+"checksum serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc45439552eb8fb86907a2c41c1fd0ef97458efb87ff7f878db466eb581824e"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "07b6c1ac5b3fffd75073276bca1ceed01f67a28537097a2a9539e116e50fb21a"
 "checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a"
 "checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7"
 "checksum toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796"
-"checksum toml 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08272367dd2e766db3fa38f068067d17aa6a9dfd7259af24b3927db92f1e0c2f"
+"checksum toml 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3474f3c6eaf32eedb4f4a66a26214f020f828a6d96c37e38a35e3a379bbcfd11"
 "checksum unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18127285758f0e2c6cf325bb3f3d138a12fee27de4f23e146cd6a179f26c2cf3"
 "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
 "checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
index c126c076a3d4eccf862197263a520d6b04d5007c..2607ce412f1081bd83e470c4dd81ffa1a2396443 100644 (file)
@@ -42,9 +42,22 @@ struct Info {
 
 impl GitInfo {
     pub fn new(dir: &Path) -> GitInfo {
-        if !dir.join(".git").is_dir() {
+        // See if this even begins to look like a git dir
+        if !dir.join(".git").exists() {
             return GitInfo { inner: None }
         }
+
+        // Make sure git commands work
+        let out = Command::new("git")
+                          .arg("rev-parse")
+                          .current_dir(dir)
+                          .output()
+                          .expect("failed to spawn git");
+        if !out.status.success() {
+            return GitInfo { inner: None }
+        }
+
+        // Ok, let's scrape some info
         let ver_date = output(Command::new("git").current_dir(dir)
                                       .arg("log").arg("-1")
                                       .arg("--date=short")
index 431d4a333d3375f07ef942dc92017b672ff77801..b1d1d79b9eaa3c58d4e8b4f5575f45c054a275aa 100644 (file)
@@ -60,6 +60,7 @@ pub struct Config {
     pub llvm_link_shared: bool,
     pub llvm_targets: Option<String>,
     pub llvm_link_jobs: Option<u32>,
+    pub llvm_clean_rebuild: bool,
 
     // rust codegen options
     pub rust_optimize: bool,
@@ -73,6 +74,7 @@ pub struct Config {
     pub rustc_default_ar: Option<String>,
     pub rust_optimize_tests: bool,
     pub rust_debuginfo_tests: bool,
+    pub rust_save_analysis: bool,
     pub rust_dist_src: bool,
 
     pub build: String,
@@ -181,6 +183,7 @@ struct Llvm {
     static_libstdcpp: Option<bool>,
     targets: Option<String>,
     link_jobs: Option<u32>,
+    clean_rebuild: Option<bool>,
 }
 
 #[derive(RustcDecodable, Default, Clone)]
@@ -223,6 +226,7 @@ struct Rust {
     optimize_tests: Option<bool>,
     debuginfo_tests: Option<bool>,
     codegen_tests: Option<bool>,
+    save_analysis: Option<bool>,
 }
 
 /// TOML representation of how each build target is configured.
@@ -334,6 +338,7 @@ pub fn parse(build: &str, file: Option<PathBuf>) -> Config {
             set(&mut config.llvm_release_debuginfo, llvm.release_debuginfo);
             set(&mut config.llvm_version_check, llvm.version_check);
             set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp);
+            set(&mut config.llvm_clean_rebuild, llvm.clean_rebuild);
             config.llvm_targets = llvm.targets.clone();
             config.llvm_link_jobs = llvm.link_jobs;
         }
@@ -347,6 +352,7 @@ pub fn parse(build: &str, file: Option<PathBuf>) -> Config {
             set(&mut config.rust_optimize_tests, rust.optimize_tests);
             set(&mut config.rust_debuginfo_tests, rust.debuginfo_tests);
             set(&mut config.codegen_tests, rust.codegen_tests);
+            set(&mut config.rust_save_analysis, rust.save_analysis);
             set(&mut config.rust_rpath, rust.rpath);
             set(&mut config.debug_jemalloc, rust.debug_jemalloc);
             set(&mut config.use_jemalloc, rust.use_jemalloc);
@@ -439,6 +445,7 @@ macro_rules! check {
                 ("LLVM_VERSION_CHECK", self.llvm_version_check),
                 ("LLVM_STATIC_STDCPP", self.llvm_static_stdcpp),
                 ("LLVM_LINK_SHARED", self.llvm_link_shared),
+                ("LLVM_CLEAN_REBUILD", self.llvm_clean_rebuild),
                 ("OPTIMIZE", self.rust_optimize),
                 ("DEBUG_ASSERTIONS", self.rust_debug_assertions),
                 ("DEBUGINFO", self.rust_debuginfo),
@@ -453,6 +460,7 @@ macro_rules! check {
                 ("LOCAL_REBUILD", self.local_rebuild),
                 ("NINJA", self.ninja),
                 ("CODEGEN_TESTS", self.codegen_tests),
+                ("SAVE_ANALYSIS", self.rust_save_analysis),
                 ("LOCKED_DEPS", self.locked_deps),
                 ("VENDOR", self.vendor),
                 ("FULL_BOOTSTRAP", self.full_bootstrap),
index 776bd729119e24458de1038d90252139159420a4..76fedae0f03ebb6189b0ab2695b0db1c7a948f16 100644 (file)
 # controlled by rustbuild's -j parameter.
 #link-jobs = 0
 
+# Delete LLVM build directory on LLVM rebuild.
+# This option defaults to `false` for local development, but CI may want to
+# always perform clean full builds (possibly accelerated by (s)ccache).
+#clean-rebuild = false
+
 # =============================================================================
 # General build configuration options
 # =============================================================================
 # saying that the FileCheck executable is missing, you may want to disable this.
 #codegen-tests = true
 
+# Flag indicating whether the API analysis data should be saved.
+#save-analysis = false
+
 # =============================================================================
 # Options for specific targets
 #
index 7c463bec5ff7c3829aba8318630fd5c0b6f7293a..289c1e1c3a99c5053883ee4eb42c900a7f511858 100644 (file)
@@ -311,18 +311,14 @@ pub fn rust_src_location(build: &Build) -> PathBuf {
 
 /// Creates a tarball of save-analysis metadata, if available.
 pub fn analysis(build: &Build, compiler: &Compiler, target: &str) {
+    if !build.config.rust_save_analysis {
+        return
+    }
+
     println!("Dist analysis");
 
-    if build.config.channel != "nightly" {
-        println!("\tskipping - not on nightly channel");
-        return;
-    }
     if compiler.host != build.config.build {
-        println!("\tskipping - not a build host");
-        return
-    }
-    if compiler.stage != 2 {
-        println!("\tskipping - not stage2");
+        println!("\tskipping, not a build host");
         return
     }
 
index 5a5cfe0c682d40ad585c26b727869b52912f19f1..db8ed579cecdb26f028739d30ca2404b0b220771 100644 (file)
@@ -168,9 +168,7 @@ pub fn std(build: &Build, stage: u32, target: &str) {
     // We don't want to build docs for internal std dependencies unless
     // in compiler-docs mode. When not in that mode, we whitelist the crates
     // for which docs must be built.
-    if build.config.compiler_docs {
-        cargo.arg("-p").arg("std");
-    } else {
+    if !build.config.compiler_docs {
         cargo.arg("--no-deps");
         for krate in &["alloc", "collections", "core", "std", "std_unicode"] {
             cargo.arg("-p").arg(krate);
@@ -244,9 +242,15 @@ pub fn rustc(build: &Build, stage: u32, target: &str) {
          .arg(build.src.join("src/rustc/Cargo.toml"))
          .arg("--features").arg(build.rustc_features());
 
-    // Like with libstd above if compiler docs aren't enabled then we're not
-    // documenting internal dependencies, so we have a whitelist.
-    if !build.config.compiler_docs {
+    if build.config.compiler_docs {
+        // src/rustc/Cargo.toml contains bin crates called rustc and rustdoc
+        // which would otherwise overwrite the docs for the real rustc and
+        // rustdoc lib crates.
+        cargo.arg("-p").arg("rustc_driver")
+             .arg("-p").arg("rustdoc");
+    } else {
+        // Like with libstd above if compiler docs aren't enabled then we're not
+        // documenting internal dependencies, so we have a whitelist.
         cargo.arg("--no-deps");
         for krate in &["proc_macro"] {
             cargo.arg("-p").arg(krate);
index ba8442ebd8c37bfe1571a76d841ba5b4824e6718..249f241a151bbd446dc3fc5c92661b954ceba9e2 100644 (file)
@@ -49,6 +49,10 @@ pub fn install(build: &Build, stage: u32, host: &str) {
         install_sh(&build, "docs", "rust-docs", stage, host, &prefix,
                    &docdir, &libdir, &mandir, &empty_dir);
     }
+    if build.config.rust_save_analysis {
+        install_sh(&build, "analysis", "rust-analysis", stage, host, &prefix,
+                   &docdir, &libdir, &mandir, &empty_dir);
+    }
     install_sh(&build, "std", "rust-std", stage, host, &prefix,
                &docdir, &libdir, &mandir, &empty_dir);
     install_sh(&build, "rustc", "rustc", stage, host, &prefix,
index 75a8b780248464df066cd93c0c5ea06d38473842..270cb8490d9a78cc8b825191b25923e90ae925b4 100644 (file)
@@ -232,7 +232,7 @@ pub fn new(flags: Flags, config: Config) -> Build {
             None => false,
         };
         let rust_info = channel::GitInfo::new(&src);
-        let cargo_info = channel::GitInfo::new(&src.join("src/tools/cargo"));
+        let cargo_info = channel::GitInfo::new(&src.join("cargo"));
 
         Build {
             flags: flags,
@@ -524,7 +524,7 @@ fn cargo(&self,
                  .env(format!("CFLAGS_{}", target), self.cflags(target).join(" "));
         }
 
-        if self.config.channel == "nightly" && compiler.is_final_stage(self) {
+        if self.config.rust_save_analysis && compiler.is_final_stage(self) {
             cargo.env("RUSTC_SAVE_ANALYSIS", "api".to_string());
         }
 
index c13235b9c76804cb9bbb572091307b894c7e4f24..6cc1ca8d02ed04e33eaa9baa12dc82d7bbd290e8 100644 (file)
@@ -41,9 +41,9 @@ pub fn llvm(build: &Build, target: &str) {
         }
     }
 
-    let clean_trigger = build.src.join("src/rustllvm/llvm-auto-clean-trigger");
-    let mut clean_trigger_contents = String::new();
-    t!(t!(File::open(&clean_trigger)).read_to_string(&mut clean_trigger_contents));
+    let rebuild_trigger = build.src.join("src/rustllvm/llvm-rebuild-trigger");
+    let mut rebuild_trigger_contents = String::new();
+    t!(t!(File::open(&rebuild_trigger)).read_to_string(&mut rebuild_trigger_contents));
 
     let out_dir = build.llvm_out(target);
     let done_stamp = out_dir.join("llvm-finished-building");
@@ -51,18 +51,15 @@ pub fn llvm(build: &Build, target: &str) {
         let mut done_contents = String::new();
         t!(t!(File::open(&done_stamp)).read_to_string(&mut done_contents));
 
-        // LLVM was already built previously.
-        // We don't track changes in LLVM sources, so we need to choose between reusing
-        // what was built previously, or cleaning the directory and doing a fresh build.
-        // The choice depends on contents of the clean-trigger file.
-        // If the contents are the same as during the previous build, then no action is required.
-        // If the contents differ from the previous build, then cleaning is triggered.
-        if done_contents == clean_trigger_contents {
+        // If LLVM was already built previously and contents of the rebuild-trigger file
+        // didn't change from the previous build, then no action is required.
+        if done_contents == rebuild_trigger_contents {
             return
-        } else {
-            t!(fs::remove_dir_all(&out_dir));
         }
     }
+    if build.config.llvm_clean_rebuild {
+        drop(fs::remove_dir_all(&out_dir));
+    }
 
     println!("Building LLVM for {}", target);
     let _time = util::timeit();
@@ -154,7 +151,7 @@ pub fn llvm(build: &Build, target: &str) {
     //        tools and libs on all platforms.
     cfg.build();
 
-    t!(t!(File::create(&done_stamp)).write_all(clean_trigger_contents.as_bytes()));
+    t!(t!(File::create(&done_stamp)).write_all(rebuild_trigger_contents.as_bytes()));
 }
 
 fn check_llvm_version(build: &Build, llvm_config: &Path) {
index 39f07459d4267914de8c8314e72ec42d042f14b7..6b047c62d99bef2984a8836c7feacb3e918e69a0 100644 (file)
@@ -633,12 +633,16 @@ fn crate_rule<'a, 'b>(build: &'a Build,
     for (krate, path, default) in krates("test") {
         rules.doc(&krate.doc_step, path)
              .dep(|s| s.name("libtest-link"))
+             // Needed so rustdoc generates relative links to std.
+             .dep(|s| s.name("doc-crate-std"))
              .default(default && build.config.compiler_docs)
              .run(move |s| doc::test(build, s.stage, s.target));
     }
     for (krate, path, default) in krates("rustc-main") {
         rules.doc(&krate.doc_step, path)
              .dep(|s| s.name("librustc-link"))
+             // Needed so rustdoc generates relative links to std.
+             .dep(|s| s.name("doc-crate-std"))
              .host(true)
              .default(default && build.config.docs)
              .run(move |s| doc::rustc(build, s.stage, s.target));
@@ -1213,20 +1217,20 @@ fn build(args: &[&str],
             name: "std".to_string(),
             deps: Vec::new(),
             path: cwd.join("src/std"),
-            doc_step: "doc-std".to_string(),
+            doc_step: "doc-crate-std".to_string(),
             build_step: "build-crate-std".to_string(),
-            test_step: "test-std".to_string(),
-            bench_step: "bench-std".to_string(),
+            test_step: "test-crate-std".to_string(),
+            bench_step: "bench-crate-std".to_string(),
             version: String::new(),
         });
         build.crates.insert("test".to_string(), ::Crate {
             name: "test".to_string(),
             deps: Vec::new(),
             path: cwd.join("src/test"),
-            doc_step: "doc-test".to_string(),
+            doc_step: "doc-crate-test".to_string(),
             build_step: "build-crate-test".to_string(),
-            test_step: "test-test".to_string(),
-            bench_step: "bench-test".to_string(),
+            test_step: "test-crate-test".to_string(),
+            bench_step: "bench-crate-test".to_string(),
             version: String::new(),
         });
         build.crates.insert("rustc-main".to_string(), ::Crate {
@@ -1234,10 +1238,10 @@ fn build(args: &[&str],
             deps: Vec::new(),
             version: String::new(),
             path: cwd.join("src/rustc-main"),
-            doc_step: "doc-rustc-main".to_string(),
+            doc_step: "doc-crate-rustc-main".to_string(),
             build_step: "build-crate-rustc-main".to_string(),
-            test_step: "test-rustc-main".to_string(),
-            bench_step: "bench-rustc-main".to_string(),
+            test_step: "test-crate-rustc-main".to_string(),
+            bench_step: "bench-crate-rustc-main".to_string(),
         });
         return build
     }
index 4c4836d7ca2301f9ded0d7766af01ee05056dd72..d8b317a46c31e7f8653fbff7108a18ba5ec53529 100755 (executable)
@@ -28,6 +28,7 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-quiet-tests"
 RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-manage-submodules"
 RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-locked-deps"
 RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-cargo-openssl-static"
+RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-clean-rebuild"
 
 if [ "$DIST_SRC" = "" ]; then
   RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-dist-src"
@@ -42,6 +43,7 @@ fi
 if [ "$DEPLOY$DEPLOY_ALT" != "" ]; then
   RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=nightly"
   RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp"
+  RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-save-analysis"
 
   if [ "$NO_LLVM_ASSERTIONS" = "1" ]; then
     RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions"
index e9e2dab73eff3f74d553c651e28f8acdd8aac21a..3dd9aa3885bc0f84c710f924fd7bc0ffc5dc1c30 100644 (file)
@@ -687,7 +687,7 @@ attribute turns off Rust's name mangling, so that it is easier to link to.
 
 It’s important to be mindful of `panic!`s when working with FFI. A `panic!`
 across an FFI boundary is undefined behavior. If you’re writing code that may
-panic, you should run it in a closure with [`catch_unwind()`]:
+panic, you should run it in a closure with [`catch_unwind`]:
 
 ```rust
 use std::panic::catch_unwind;
@@ -706,11 +706,11 @@ pub extern fn oh_no() -> i32 {
 fn main() {}
 ```
 
-Please note that [`catch_unwind()`] will only catch unwinding panics, not
-those who abort the process. See the documentation of [`catch_unwind()`]
+Please note that [`catch_unwind`] will only catch unwinding panics, not
+those who abort the process. See the documentation of [`catch_unwind`]
 for more information.
 
-[`catch_unwind()`]: ../std/panic/fn.catch_unwind.html
+[`catch_unwind`]: ../std/panic/fn.catch_unwind.html
 
 # Representing opaque structs
 
index 4d81438b11deadfe9cfb3c7a8c587df46fd09747..bbb43b4a9ef4bac098bf9917fe59db3e091048d8 100644 (file)
@@ -217,7 +217,7 @@ The next part will use this handle to get input from the user:
 .read_line(&mut guess)
 ```
 
-Here, we call the [`read_line()`][read_line] method on our handle.
+Here, we call the [`read_line`][read_line] method on our handle.
 [Methods][method] are like associated functions, but are only available on a
 particular instance of a type, rather than the type itself. We’re also passing
 one argument to `read_line()`: `&mut guess`.
index c9a48293dba684c2105ae6e83a77b047df5810b8..ecfd34a22e5ccbd39794a260879eb88317088e09 100644 (file)
@@ -6,5 +6,17 @@ The tracking issue for this feature is: [#29599]
 
 ------------------------
 
+The `concat_idents` feature adds a macro for concatenating multiple identifiers
+into one identifier.
 
+## Examples
 
+```rust
+#![feature(concat_idents)]
+
+fn main() {
+    fn foobar() -> u32 { 23 }
+    let f = concat_idents!(foo, bar);
+    assert_eq!(f(), 23);
+}
+```
\ No newline at end of file
index 7d8bda439bd347219eafa33e3c70c62302e05d8a..62a7f8c16a0a71d5c09b64883d6191fe42e1bf15 100644 (file)
@@ -6,5 +6,61 @@ The tracking issue for this feature is: [#34511]
 
 ------------------------
 
+The `conservative_impl_trait` feature allows a conservative form of abstract
+return types.
 
+Abstract return types allow a function to hide a concrete return type behind a
+trait interface similar to trait objects, while still generating the same
+statically dispatched code as with concrete types.
 
+## Examples
+
+```rust
+#![feature(conservative_impl_trait)]
+
+fn even_iter() -> impl Iterator<Item=u32> {
+    (0..).map(|n| n * 2)
+}
+
+fn main() {
+    let first_four_even_numbers = even_iter().take(4).collect::<Vec<_>>();
+    assert_eq!(first_four_even_numbers, vec![0, 2, 4, 6]);
+}
+```
+
+## Background
+
+In today's Rust, you can write function signatures like:
+
+````rust,ignore
+fn consume_iter_static<I: Iterator<u8>>(iter: I) { }
+
+fn consume_iter_dynamic(iter: Box<Iterator<u8>>) { }
+````
+
+In both cases, the function does not depend on the exact type of the argument.
+The type held is "abstract", and is assumed only to satisfy a trait bound.
+
+* In the `_static` version using generics, each use of the function is
+  specialized to a concrete, statically-known type, giving static dispatch,
+  inline layout, and other performance wins.
+* In the `_dynamic` version using trait objects, the concrete argument type is
+  only known at runtime using a vtable.
+
+On the other hand, while you can write:
+
+````rust,ignore
+fn produce_iter_dynamic() -> Box<Iterator<u8>> { }
+````
+
+...but you _cannot_ write something like:
+
+````rust,ignore
+fn produce_iter_static() -> Iterator<u8> { }
+````
+
+That is, in today's Rust, abstract return types can only be written using trait
+objects, which can be a significant performance penalty. This RFC proposes
+"unboxed abstract types" as a way of achieving signatures like
+`produce_iter_static`. Like generics, unboxed abstract types guarantee static
+dispatch and inline data layout.
index 9b7942c408a2483fdb871c77653fe0c80bac699d..d5a22436838623d7729d6dbf976ae28bcf2527ed 100644 (file)
@@ -6,5 +6,24 @@ The tracking issue for this feature is: [#24111]
 
 ------------------------
 
+The `const_fn` feature allows marking free functions and inherent methods as
+`const`, enabling them to be called in constants contexts, with constant
+arguments.
 
+## Examples
 
+```rust
+#![feature(const_fn)]
+
+const fn double(x: i32) -> i32 {
+    x * 2
+}
+
+const FIVE: i32 = 5;
+const TEN: i32 = double(FIVE);
+
+fn main() {
+    assert_eq!(5, FIVE);
+    assert_eq!(10, TEN);
+}
+```
index bd92b0b1b478fdc3422f261f4aaa6162d6634d1b..42d46ce15f676e552025619097bd9c90c17730e3 100644 (file)
@@ -6,5 +6,14 @@ The tracking issue for this feature is: [#29947]
 
 ------------------------
 
+The `const_indexing` feature allows the constant evaluation of index operations
+on constant arrays and repeat expressions.
 
+## Examples
 
+```rust
+#![feature(const_indexing)]
+
+const ARR: [usize; 5] = [1, 2, 3, 4, 5];
+const ARR2: [usize; ARR[1]] = [42, 99];
+```
\ No newline at end of file
index ffcf45feb2ad7ef5d1b570f887cbd6d21bdc3611..a850b7644c3a76fee296606cf1ea858640251c41 100644 (file)
@@ -6,5 +6,20 @@ The tracking issue for this feature is: [#35118]
 
 ------------------------
 
+The `i128_type` feature adds support for 128 bit signed and unsigned integer
+types.
 
+```rust
+#![feature(i128_type)]
+
+fn main() {
+    assert_eq!(1u128 + 1u128, 2u128);
+    assert_eq!(u128::min_value(), 0);
+    assert_eq!(u128::max_value(), 340282366920938463463374607431768211455);
+
+    assert_eq!(1i128 - 2i128, -1i128);
+    assert_eq!(i128::min_value(), -170141183460469231731687303715884105728);
+    assert_eq!(i128::max_value(), 170141183460469231731687303715884105727);
+}
+```
 
index f426022ab3a5161cc05a24b30912ad84605b7270..d5600c58fd9a657fff7c7e8c4c992335a2b4f666 100644 (file)
@@ -6,5 +6,13 @@ The tracking issue for this feature is: [#28979]
 
 ------------------------
 
+The `non_ascii_idents` feature adds support for non-ASCII identifiers.
 
+## Examples
 
+```rust
+#![feature(non_ascii_idents)]
+
+const ε: f64 = 0.00001f64;
+const Π: f64 = 3.14f64;
+```
\ No newline at end of file
index 6108a06634bb88cfaefafda0e88a76f80aa12e2d..eb449b266067985ce09f91215e52eed8b162f28a 100644 (file)
@@ -13,7 +13,7 @@
 //! Single-threaded reference-counting pointers.
 //!
 //! The type [`Rc<T>`][`Rc`] provides shared ownership of a value of type `T`,
-//! allocated in the heap. Invoking [`clone()`][clone] on [`Rc`] produces a new
+//! allocated in the heap. Invoking [`clone`][clone] on [`Rc`] produces a new
 //! pointer to the same value in the heap. When the last [`Rc`] pointer to a
 //! given value is destroyed, the pointed-to value is also destroyed.
 //!
@@ -30,7 +30,7 @@
 //! threads. If you need multi-threaded, atomic reference counting, use
 //! [`sync::Arc`][arc].
 //!
-//! The [`downgrade()`][downgrade] method can be used to create a non-owning
+//! The [`downgrade`][downgrade] method can be used to create a non-owning
 //! [`Weak`] pointer. A [`Weak`] pointer can be [`upgrade`][upgrade]d
 //! to an [`Rc`], but this will return [`None`] if the value has
 //! already been dropped.
index a5a2f70492dc97daaa05e5ef2ee1a770f32173dc..519117ff9e5196ec1a686f5c4e2513c49d9d8707 100644 (file)
@@ -218,10 +218,10 @@ pub struct BinaryHeap<T> {
     data: Vec<T>,
 }
 
-/// A container object that represents the result of the [`peek_mut()`] method
+/// A container object that represents the result of the [`peek_mut`] method
 /// on `BinaryHeap`. See its documentation for details.
 ///
-/// [`peek_mut()`]: struct.BinaryHeap.html#method.peek_mut
+/// [`peek_mut`]: struct.BinaryHeap.html#method.peek_mut
 #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
 pub struct PeekMut<'a, T: 'a + Ord> {
     heap: &'a mut BinaryHeap<T>,
index 2ea953df8735729b6d02dbecf7453d1a07615d9d..11fc1d553f28e7a60bda0b2eee9989fd6a0838cd 100644 (file)
 //! the element type of the slice is `i32`, the element type of the iterator is
 //! `&mut i32`.
 //!
-//! * [`.iter()`] and [`.iter_mut()`] are the explicit methods to return the default
+//! * [`.iter`] and [`.iter_mut`] are the explicit methods to return the default
 //!   iterators.
-//! * Further methods that return iterators are [`.split()`], [`.splitn()`],
-//!   [`.chunks()`], [`.windows()`] and more.
+//! * Further methods that return iterators are [`.split`], [`.splitn`],
+//!   [`.chunks`], [`.windows`] and more.
 //!
 //! *[See also the slice primitive type](../../std/primitive.slice.html).*
 //!
 //! [`Ord`]: ../../std/cmp/trait.Ord.html
 //! [`Iter`]: struct.Iter.html
 //! [`Hash`]: ../../std/hash/trait.Hash.html
-//! [`.iter()`]: ../../std/primitive.slice.html#method.iter
-//! [`.iter_mut()`]: ../../std/primitive.slice.html#method.iter_mut
-//! [`.split()`]: ../../std/primitive.slice.html#method.split
-//! [`.splitn()`]: ../../std/primitive.slice.html#method.splitn
-//! [`.chunks()`]: ../../std/primitive.slice.html#method.chunks
-//! [`.windows()`]: ../../std/primitive.slice.html#method.windows
+//! [`.iter`]: ../../std/primitive.slice.html#method.iter
+//! [`.iter_mut`]: ../../std/primitive.slice.html#method.iter_mut
+//! [`.split`]: ../../std/primitive.slice.html#method.split
+//! [`.splitn`]: ../../std/primitive.slice.html#method.splitn
+//! [`.chunks`]: ../../std/primitive.slice.html#method.chunks
+//! [`.windows`]: ../../std/primitive.slice.html#method.windows
 #![stable(feature = "rust1", since = "1.0.0")]
 
 // Many of the usings in this module are only used in the test configuration.
@@ -368,9 +368,9 @@ pub fn get<I>(&self, index: I) -> Option<&I::Output>
     }
 
     /// Returns a mutable reference to an element or subslice depending on the
-    /// type of index (see [`get()`]) or `None` if the index is out of bounds.
+    /// type of index (see [`get`]) or `None` if the index is out of bounds.
     ///
-    /// [`get()`]: #method.get
+    /// [`get`]: #method.get
     ///
     /// # Examples
     ///
index e27c45773441a7a7e114eba1460fdf50fefafd0f..90e54a383d623730a0612d802f79473110e740a0 100644 (file)
@@ -298,9 +298,9 @@ pub fn as_ptr(&self) -> *const u8 {
     /// excluding `end`.
     ///
     /// To get a mutable string slice instead, see the
-    /// [`slice_mut_unchecked()`] method.
+    /// [`slice_mut_unchecked`] method.
     ///
-    /// [`slice_mut_unchecked()`]: #method.slice_mut_unchecked
+    /// [`slice_mut_unchecked`]: #method.slice_mut_unchecked
     ///
     /// # Safety
     ///
@@ -341,9 +341,9 @@ pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
     /// excluding `end`.
     ///
     /// To get an immutable string slice instead, see the
-    /// [`slice_unchecked()`] method.
+    /// [`slice_unchecked`] method.
     ///
-    /// [`slice_unchecked()`]: #method.slice_unchecked
+    /// [`slice_unchecked`]: #method.slice_unchecked
     ///
     /// # Safety
     ///
@@ -367,10 +367,10 @@ pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut s
     /// The two slices returned go from the start of the string slice to `mid`,
     /// and from `mid` to the end of the string slice.
     ///
-    /// To get mutable string slices instead, see the [`split_at_mut()`]
+    /// To get mutable string slices instead, see the [`split_at_mut`]
     /// method.
     ///
-    /// [`split_at_mut()`]: #method.split_at_mut
+    /// [`split_at_mut`]: #method.split_at_mut
     ///
     /// # Panics
     ///
@@ -403,9 +403,9 @@ pub fn split_at(&self, mid: usize) -> (&str, &str) {
     /// The two slices returned go from the start of the string slice to `mid`,
     /// and from `mid` to the end of the string slice.
     ///
-    /// To get immutable string slices instead, see the [`split_at()`] method.
+    /// To get immutable string slices instead, see the [`split_at`] method.
     ///
-    /// [`split_at()`]: #method.split_at
+    /// [`split_at`]: #method.split_at
     ///
     /// # Panics
     ///
@@ -824,10 +824,10 @@ pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
     /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
     ///
     /// If the pattern allows a reverse search but its results might differ
-    /// from a forward search, the [`rsplit()`] method can be used.
+    /// from a forward search, the [`rsplit`] method can be used.
     ///
     /// [`char`]: primitive.char.html
-    /// [`rsplit()`]: #method.rsplit
+    /// [`rsplit`]: #method.rsplit
     ///
     /// # Examples
     ///
@@ -912,9 +912,9 @@ pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
     /// assert_eq!(d, &["a", "b", "c"]);
     /// ```
     ///
-    /// Use [`split_whitespace()`] for this behavior.
+    /// Use [`split_whitespace`] for this behavior.
     ///
-    /// [`split_whitespace()`]: #method.split_whitespace
+    /// [`split_whitespace`]: #method.split_whitespace
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
         core_str::StrExt::split(self, pat)
@@ -936,9 +936,9 @@ pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
     ///
     /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
     ///
-    /// For iterating from the front, the [`split()`] method can be used.
+    /// For iterating from the front, the [`split`] method can be used.
     ///
-    /// [`split()`]: #method.split
+    /// [`split`]: #method.split
     ///
     /// # Examples
     ///
@@ -977,10 +977,10 @@ pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
     /// The pattern can be a `&str`, [`char`], or a closure that determines the
     /// split.
     ///
-    /// Equivalent to [`split()`], except that the trailing substring
+    /// Equivalent to [`split`], except that the trailing substring
     /// is skipped if empty.
     ///
-    /// [`split()`]: #method.split
+    /// [`split`]: #method.split
     ///
     /// This method can be used for string data that is _terminated_,
     /// rather than _separated_ by a pattern.
@@ -995,9 +995,9 @@ pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
     /// [`char`]: primitive.char.html
     ///
     /// If the pattern allows a reverse search but its results might differ
-    /// from a forward search, the [`rsplit_terminator()`] method can be used.
+    /// from a forward search, the [`rsplit_terminator`] method can be used.
     ///
-    /// [`rsplit_terminator()`]: #method.rsplit_terminator
+    /// [`rsplit_terminator`]: #method.rsplit_terminator
     ///
     /// # Examples
     ///
@@ -1025,10 +1025,10 @@ pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator
     ///
     /// [`char`]: primitive.char.html
     ///
-    /// Equivalent to [`split()`], except that the trailing substring is
+    /// Equivalent to [`split`], except that the trailing substring is
     /// skipped if empty.
     ///
-    /// [`split()`]: #method.split
+    /// [`split`]: #method.split
     ///
     /// This method can be used for string data that is _terminated_,
     /// rather than _separated_ by a pattern.
@@ -1039,10 +1039,10 @@ pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator
     /// reverse search, and it will be double ended if a forward/reverse
     /// search yields the same elements.
     ///
-    /// For iterating from the front, the [`split_terminator()`] method can be
+    /// For iterating from the front, the [`split_terminator`] method can be
     /// used.
     ///
-    /// [`split_terminator()`]: #method.split_terminator
+    /// [`split_terminator`]: #method.split_terminator
     ///
     /// # Examples
     ///
@@ -1076,10 +1076,10 @@ pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminat
     /// The returned iterator will not be double ended, because it is
     /// not efficient to support.
     ///
-    /// If the pattern allows a reverse search, the [`rsplitn()`] method can be
+    /// If the pattern allows a reverse search, the [`rsplitn`] method can be
     /// used.
     ///
-    /// [`rsplitn()`]: #method.rsplitn
+    /// [`rsplitn`]: #method.rsplitn
     ///
     /// # Examples
     ///
@@ -1127,9 +1127,9 @@ pub fn splitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> SplitN<'a, P> {
     /// The returned iterator will not be double ended, because it is not
     /// efficient to support.
     ///
-    /// For splitting from the front, the [`splitn()`] method can be used.
+    /// For splitting from the front, the [`splitn`] method can be used.
     ///
-    /// [`splitn()`]: #method.splitn
+    /// [`splitn`]: #method.splitn
     ///
     /// # Examples
     ///
@@ -1177,9 +1177,9 @@ pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
     /// [`char`]: primitive.char.html
     ///
     /// If the pattern allows a reverse search but its results might differ
-    /// from a forward search, the [`rmatches()`] method can be used.
+    /// from a forward search, the [`rmatches`] method can be used.
     ///
-    /// [`rmatches()`]: #method.rmatches
+    /// [`rmatches`]: #method.rmatches
     ///
     /// # Examples
     ///
@@ -1213,9 +1213,9 @@ pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
     ///
     /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
     ///
-    /// For iterating from the front, the [`matches()`] method can be used.
+    /// For iterating from the front, the [`matches`] method can be used.
     ///
-    /// [`matches()`]: #method.matches
+    /// [`matches`]: #method.matches
     ///
     /// # Examples
     ///
@@ -1255,9 +1255,9 @@ pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
     /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
     ///
     /// If the pattern allows a reverse search but its results might differ
-    /// from a forward search, the [`rmatch_indices()`] method can be used.
+    /// from a forward search, the [`rmatch_indices`] method can be used.
     ///
-    /// [`rmatch_indices()`]: #method.rmatch_indices
+    /// [`rmatch_indices`]: #method.rmatch_indices
     ///
     /// # Examples
     ///
@@ -1297,9 +1297,9 @@ pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P
     ///
     /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
     ///
-    /// For iterating from the front, the [`match_indices()`] method can be used.
+    /// For iterating from the front, the [`match_indices`] method can be used.
     ///
-    /// [`match_indices()`]: #method.match_indices
+    /// [`match_indices`]: #method.match_indices
     ///
     /// # Examples
     ///
index 43323676ab459b4f39a1233218f6dcc3c63f58dd..0ee4c8b8e95a60bec3e8d06cea73460f03bcb274 100644 (file)
@@ -89,8 +89,8 @@
 /// let hello = String::from("Hello, world!");
 /// ```
 ///
-/// You can append a [`char`] to a `String` with the [`push()`] method, and
-/// append a [`&str`] with the [`push_str()`] method:
+/// You can append a [`char`] to a `String` with the [`push`] method, and
+/// append a [`&str`] with the [`push_str`] method:
 ///
 /// ```
 /// let mut hello = String::from("Hello, ");
 /// ```
 ///
 /// [`char`]: ../../std/primitive.char.html
-/// [`push()`]: #method.push
-/// [`push_str()`]: #method.push_str
+/// [`push`]: #method.push
+/// [`push_str`]: #method.push_str
 ///
 /// If you have a vector of UTF-8 bytes, you can create a `String` from it with
-/// the [`from_utf8()`] method:
+/// the [`from_utf8`] method:
 ///
 /// ```
 /// // some bytes, in a vector
 /// assert_eq!("💖", sparkle_heart);
 /// ```
 ///
-/// [`from_utf8()`]: #method.from_utf8
+/// [`from_utf8`]: #method.from_utf8
 ///
 /// # UTF-8
 ///
 /// Indexing is intended to be a constant-time operation, but UTF-8 encoding
 /// does not allow us to do this. Furthermore, it's not clear what sort of
 /// thing the index should return: a byte, a codepoint, or a grapheme cluster.
-/// The [`bytes()`] and [`chars()`] methods return iterators over the first
+/// The [`bytes`] and [`chars`] methods return iterators over the first
 /// two, respectively.
 ///
-/// [`bytes()`]: #method.bytes
-/// [`chars()`]: #method.chars
+/// [`bytes`]: #method.bytes
+/// [`chars`]: #method.chars
 ///
 /// # Deref
 ///
 ///
 /// This buffer is always stored on the heap.
 ///
-/// You can look at these with the [`as_ptr()`], [`len()`], and [`capacity()`]
+/// You can look at these with the [`as_ptr`], [`len`], and [`capacity`]
 /// methods:
 ///
 /// ```
 /// assert_eq!(String::from("Once upon a time..."), s);
 /// ```
 ///
-/// [`as_ptr()`]: #method.as_ptr
-/// [`len()`]: #method.len
-/// [`capacity()`]: #method.capacity
+/// [`as_ptr`]: #method.as_ptr
+/// [`len`]: #method.len
+/// [`capacity`]: #method.capacity
 ///
 /// If a `String` has enough capacity, adding elements to it will not
 /// re-allocate. For example, consider this program:
 ///
 /// At first, we have no memory allocated at all, but as we append to the
 /// string, it increases its capacity appropriately. If we instead use the
-/// [`with_capacity()`] method to allocate the correct capacity initially:
+/// [`with_capacity`] method to allocate the correct capacity initially:
 ///
 /// ```
 /// let mut s = String::with_capacity(25);
 /// }
 /// ```
 ///
-/// [`with_capacity()`]: #method.with_capacity
+/// [`with_capacity`]: #method.with_capacity
 ///
 /// We end up with a different output:
 ///
@@ -266,25 +266,25 @@ pub struct String {
 
 /// A possible error value when converting a `String` from a UTF-8 byte vector.
 ///
-/// This type is the error type for the [`from_utf8()`] method on [`String`]. It
+/// This type is the error type for the [`from_utf8`] method on [`String`]. It
 /// is designed in such a way to carefully avoid reallocations: the
-/// [`into_bytes()`] method will give back the byte vector that was used in the
+/// [`into_bytes`] method will give back the byte vector that was used in the
 /// conversion attempt.
 ///
-/// [`from_utf8()`]: struct.String.html#method.from_utf8
+/// [`from_utf8`]: struct.String.html#method.from_utf8
 /// [`String`]: struct.String.html
-/// [`into_bytes()`]: struct.FromUtf8Error.html#method.into_bytes
+/// [`into_bytes`]: struct.FromUtf8Error.html#method.into_bytes
 ///
 /// The [`Utf8Error`] type provided by [`std::str`] represents an error that may
 /// occur when converting a slice of [`u8`]s to a [`&str`]. In this sense, it's
 /// an analogue to `FromUtf8Error`, and you can get one from a `FromUtf8Error`
-/// through the [`utf8_error()`] method.
+/// through the [`utf8_error`] method.
 ///
 /// [`Utf8Error`]: ../../std/str/struct.Utf8Error.html
 /// [`std::str`]: ../../std/str/index.html
 /// [`u8`]: ../../std/primitive.u8.html
 /// [`&str`]: ../../std/primitive.str.html
-/// [`utf8_error()`]: #method.utf8_error
+/// [`utf8_error`]: #method.utf8_error
 ///
 /// # Examples
 ///
@@ -308,9 +308,9 @@ pub struct FromUtf8Error {
 
 /// A possible error value when converting a `String` from a UTF-16 byte slice.
 ///
-/// This type is the error type for the [`from_utf16()`] method on [`String`].
+/// This type is the error type for the [`from_utf16`] method on [`String`].
 ///
-/// [`from_utf16()`]: struct.String.html#method.from_utf16
+/// [`from_utf16`]: struct.String.html#method.from_utf16
 /// [`String`]: struct.String.html
 ///
 /// # Examples
@@ -335,10 +335,10 @@ impl String {
     /// buffer. While that means that this initial operation is very
     /// inexpensive, but may cause excessive allocation later, when you add
     /// data. If you have an idea of how much data the `String` will hold,
-    /// consider the [`with_capacity()`] method to prevent excessive
+    /// consider the [`with_capacity`] method to prevent excessive
     /// re-allocation.
     ///
-    /// [`with_capacity()`]: #method.with_capacity
+    /// [`with_capacity`]: #method.with_capacity
     ///
     /// # Examples
     ///
@@ -356,18 +356,18 @@ pub fn new() -> String {
     /// Creates a new empty `String` with a particular capacity.
     ///
     /// `String`s have an internal buffer to hold their data. The capacity is
-    /// the length of that buffer, and can be queried with the [`capacity()`]
+    /// the length of that buffer, and can be queried with the [`capacity`]
     /// method. This method creates an empty `String`, but one with an initial
     /// buffer that can hold `capacity` bytes. This is useful when you may be
     /// appending a bunch of data to the `String`, reducing the number of
     /// reallocations it needs to do.
     ///
-    /// [`capacity()`]: #method.capacity
+    /// [`capacity`]: #method.capacity
     ///
     /// If the given capacity is `0`, no allocation will occur, and this method
-    /// is identical to the [`new()`] method.
+    /// is identical to the [`new`] method.
     ///
-    /// [`new()`]: #method.new
+    /// [`new`]: #method.new
     ///
     /// # Examples
     ///
@@ -420,18 +420,18 @@ pub fn from_str(_: &str) -> String {
     ///
     /// If you are sure that the byte slice is valid UTF-8, and you don't want
     /// to incur the overhead of the validity check, there is an unsafe version
-    /// of this function, [`from_utf8_unchecked()`], which has the same behavior
+    /// of this function, [`from_utf8_unchecked`], which has the same behavior
     /// but skips the check.
     ///
-    /// [`from_utf8_unchecked()`]: struct.String.html#method.from_utf8_unchecked
+    /// [`from_utf8_unchecked`]: struct.String.html#method.from_utf8_unchecked
     ///
     /// This method will take care to not copy the vector, for efficiency's
     /// sake.
     ///
     /// If you need a `&str` instead of a `String`, consider
-    /// [`str::from_utf8()`].
+    /// [`str::from_utf8`].
     ///
-    /// [`str::from_utf8()`]: ../../std/str/fn.from_utf8.html
+    /// [`str::from_utf8`]: ../../std/str/fn.from_utf8.html
     ///
     /// The inverse of this method is [`as_bytes`].
     ///
@@ -497,10 +497,10 @@ pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
     ///
     /// If you are sure that the byte slice is valid UTF-8, and you don't want
     /// to incur the overhead of the conversion, there is an unsafe version
-    /// of this function, [`from_utf8_unchecked()`], which has the same behavior
+    /// of this function, [`from_utf8_unchecked`], which has the same behavior
     /// but skips the checks.
     ///
-    /// [`from_utf8_unchecked()`]: struct.String.html#method.from_utf8_unchecked
+    /// [`from_utf8_unchecked`]: struct.String.html#method.from_utf8_unchecked
     ///
     /// This function returns a [`Cow<'a, str>`]. If our byte slice is invalid
     /// UTF-8, then we need to insert the replacement characters, which will
@@ -738,9 +738,9 @@ pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> St
     /// Converts a vector of bytes to a `String` without checking that the
     /// string contains valid UTF-8.
     ///
-    /// See the safe version, [`from_utf8()`], for more details.
+    /// See the safe version, [`from_utf8`], for more details.
     ///
-    /// [`from_utf8()`]: struct.String.html#method.from_utf8
+    /// [`from_utf8`]: struct.String.html#method.from_utf8
     ///
     /// # Safety
     ///
@@ -845,10 +845,10 @@ pub fn capacity(&self) -> usize {
     /// The capacity may be increased by more than `additional` bytes if it
     /// chooses, to prevent frequent reallocations.
     ///
-    /// If you do not want this "at least" behavior, see the [`reserve_exact()`]
+    /// If you do not want this "at least" behavior, see the [`reserve_exact`]
     /// method.
     ///
-    /// [`reserve_exact()`]: #method.reserve_exact
+    /// [`reserve_exact`]: #method.reserve_exact
     ///
     /// # Panics
     ///
@@ -892,10 +892,10 @@ pub fn reserve(&mut self, additional: usize) {
     /// Ensures that this `String`'s capacity is `additional` bytes
     /// larger than its length.
     ///
-    /// Consider using the [`reserve()`] method unless you absolutely know
+    /// Consider using the [`reserve`] method unless you absolutely know
     /// better than the allocator.
     ///
-    /// [`reserve()`]: #method.reserve
+    /// [`reserve`]: #method.reserve
     ///
     /// # Panics
     ///
@@ -1699,9 +1699,9 @@ fn add(mut self, other: &str) -> String {
 
 /// Implements the `+=` operator for appending to a `String`.
 ///
-/// This has the same behavior as the [`push_str()`] method.
+/// This has the same behavior as the [`push_str`] method.
 ///
-/// [`push_str()`]: struct.String.html#method.push_str
+/// [`push_str`]: struct.String.html#method.push_str
 #[stable(feature = "stringaddassign", since = "1.12.0")]
 impl<'a> AddAssign<&'a str> for String {
     #[inline]
@@ -1830,14 +1830,14 @@ fn deref_mut(&mut self) -> &mut str {
 ///
 /// This `enum` is slightly awkward: it will never actually exist. This error is
 /// part of the type signature of the implementation of [`FromStr`] on
-/// [`String`]. The return type of [`from_str()`], requires that an error be
+/// [`String`]. The return type of [`from_str`], requires that an error be
 /// defined, but, given that a [`String`] can always be made into a new
 /// [`String`] without error, this type will never actually be returned. As
 /// such, it is only here to satisfy said signature, and is useless otherwise.
 ///
 /// [`FromStr`]: ../../std/str/trait.FromStr.html
 /// [`String`]: struct.String.html
-/// [`from_str()`]: ../../std/str/trait.FromStr.html#tymethod.from_str
+/// [`from_str`]: ../../std/str/trait.FromStr.html#tymethod.from_str
 #[stable(feature = "str_parse_error", since = "1.5.0")]
 #[derive(Copy)]
 pub enum ParseError {}
@@ -1974,6 +1974,22 @@ fn from(s: &'a str) -> String {
     }
 }
 
+// note: test pulls in libstd, which causes errors here
+#[cfg(not(test))]
+#[stable(feature = "string_from_box", since = "1.17.0")]
+impl From<Box<str>> for String {
+    fn from(s: Box<str>) -> String {
+        s.into_string()
+    }
+}
+
+#[stable(feature = "box_from_str", since = "1.17.0")]
+impl Into<Box<str>> for String {
+    fn into(self) -> Box<str> {
+        self.into_boxed_str()
+    }
+}
+
 #[stable(feature = "string_from_cow_str", since = "1.14.0")]
 impl<'a> From<Cow<'a, str>> for String {
     fn from(s: Cow<'a, str>) -> String {
@@ -2042,10 +2058,10 @@ fn write_char(&mut self, c: char) -> fmt::Result {
 
 /// A draining iterator for `String`.
 ///
-/// This struct is created by the [`drain()`] method on [`String`]. See its
+/// This struct is created by the [`drain`] method on [`String`]. See its
 /// documentation for more.
 ///
-/// [`drain()`]: struct.String.html#method.drain
+/// [`drain`]: struct.String.html#method.drain
 /// [`String`]: struct.String.html
 #[stable(feature = "drain", since = "1.6.0")]
 pub struct Drain<'a> {
index d38c9f6e1cf805f3a82b250e6afeb23e5e4f1f27..f3cd5eee5c1c815a30a459a042804c0e2e76eac7 100644 (file)
@@ -16,7 +16,7 @@
 //!
 //! # Examples
 //!
-//! You can explicitly create a [`Vec<T>`] with [`new()`]:
+//! You can explicitly create a [`Vec<T>`] with [`new`]:
 //!
 //! ```
 //! let v: Vec<i32> = Vec::new();
@@ -58,7 +58,7 @@
 //! ```
 //!
 //! [`Vec<T>`]: ../../std/vec/struct.Vec.html
-//! [`new()`]: ../../std/vec/struct.Vec.html#method.new
+//! [`new`]: ../../std/vec/struct.Vec.html#method.new
 //! [`push`]: ../../std/vec/struct.Vec.html#method.push
 //! [`Index`]: ../../std/ops/trait.Index.html
 //! [`IndexMut`]: ../../std/ops/trait.IndexMut.html
 /// The pointer will never be null, so this type is null-pointer-optimized.
 ///
 /// However, the pointer may not actually point to allocated memory. In particular,
-/// if you construct a `Vec` with capacity 0 via [`Vec::new()`], [`vec![]`][`vec!`],
-/// [`Vec::with_capacity(0)`][`Vec::with_capacity`], or by calling [`shrink_to_fit()`]
+/// if you construct a `Vec` with capacity 0 via [`Vec::new`], [`vec![]`][`vec!`],
+/// [`Vec::with_capacity(0)`][`Vec::with_capacity`], or by calling [`shrink_to_fit`]
 /// on an empty Vec, it will not allocate memory. Similarly, if you store zero-sized
 /// types inside a `Vec`, it will not allocate space for them. *Note that in this case
-/// the `Vec` may not report a [`capacity()`] of 0*. `Vec` will allocate if and only
-/// if [`mem::size_of::<T>()`]` * capacity() > 0`. In general, `Vec`'s allocation
+/// the `Vec` may not report a [`capacity`] of 0*. `Vec` will allocate if and only
+/// if [`mem::size_of::<T>`]` * capacity() > 0`. In general, `Vec`'s allocation
 /// details are subtle enough that it is strongly recommended that you only
 /// free memory allocated by a `Vec` by creating a new `Vec` and dropping it.
 ///
 /// If a `Vec` *has* allocated memory, then the memory it points to is on the heap
 /// (as defined by the allocator Rust is configured to use by default), and its
-/// pointer points to [`len()`] initialized elements in order (what you would see
-/// if you coerced it to a slice), followed by [`capacity()`]` - `[`len()`]
+/// pointer points to [`len`] initialized elements in order (what you would see
+/// if you coerced it to a slice), followed by [`capacity`]` - `[`len`]
 /// logically uninitialized elements.
 ///
 /// `Vec` will never perform a "small optimization" where elements are actually
 ///
 /// `Vec` will never automatically shrink itself, even if completely empty. This
 /// ensures no unnecessary allocations or deallocations occur. Emptying a `Vec`
-/// and then filling it back up to the same [`len()`] should incur no calls to
+/// and then filling it back up to the same [`len`] should incur no calls to
 /// the allocator. If you wish to free up unused memory, use
-/// [`shrink_to_fit`][`shrink_to_fit()`].
+/// [`shrink_to_fit`][`shrink_to_fit`].
 ///
 /// [`push`] and [`insert`] will never (re)allocate if the reported capacity is
 /// sufficient. [`push`] and [`insert`] *will* (re)allocate if
-/// [`len()`]` == `[`capacity()`]. That is, the reported capacity is completely
+/// [`len`]` == `[`capacity`]. That is, the reported capacity is completely
 /// accurate, and can be relied on. It can even be used to manually free the memory
 /// allocated by a `Vec` if desired. Bulk insertion methods *may* reallocate, even
 /// when not necessary.
 ///
 /// `vec![x; n]`, `vec![a, b, c, d]`, and
 /// [`Vec::with_capacity(n)`][`Vec::with_capacity`], will all produce a `Vec`
-/// with exactly the requested capacity. If [`len()`]` == `[`capacity()`],
+/// with exactly the requested capacity. If [`len`]` == `[`capacity`],
 /// (as is the case for the [`vec!`] macro), then a `Vec<T>` can be converted to
 /// and from a [`Box<[T]>`][owned slice] without reallocating or moving the elements.
 ///
 /// [`String`]: ../../std/string/struct.String.html
 /// [`&str`]: ../../std/primitive.str.html
 /// [`Vec::with_capacity`]: ../../std/vec/struct.Vec.html#method.with_capacity
-/// [`Vec::new()`]: ../../std/vec/struct.Vec.html#method.new
-/// [`shrink_to_fit()`]: ../../std/vec/struct.Vec.html#method.shrink_to_fit
-/// [`capacity()`]: ../../std/vec/struct.Vec.html#method.capacity
-/// [`mem::size_of::<T>()`]: ../../std/mem/fn.size_of.html
-/// [`len()`]: ../../std/vec/struct.Vec.html#method.len
+/// [`Vec::new`]: ../../std/vec/struct.Vec.html#method.new
+/// [`shrink_to_fit`]: ../../std/vec/struct.Vec.html#method.shrink_to_fit
+/// [`capacity`]: ../../std/vec/struct.Vec.html#method.capacity
+/// [`mem::size_of::<T>`]: ../../std/mem/fn.size_of.html
+/// [`len`]: ../../std/vec/struct.Vec.html#method.len
 /// [`push`]: ../../std/vec/struct.Vec.html#method.push
 /// [`insert`]: ../../std/vec/struct.Vec.html#method.insert
 /// [`reserve`]: ../../std/vec/struct.Vec.html#method.reserve
@@ -504,12 +504,12 @@ pub fn shrink_to_fit(&mut self) {
     /// Converts the vector into [`Box<[T]>`][owned slice].
     ///
     /// Note that this will drop any excess capacity. Calling this and
-    /// converting back to a vector with [`into_vec()`] is equivalent to calling
-    /// [`shrink_to_fit()`].
+    /// converting back to a vector with [`into_vec`] is equivalent to calling
+    /// [`shrink_to_fit`].
     ///
     /// [owned slice]: ../../std/boxed/struct.Box.html
-    /// [`into_vec()`]: ../../std/primitive.slice.html#method.into_vec
-    /// [`shrink_to_fit()`]: #method.shrink_to_fit
+    /// [`into_vec`]: ../../std/primitive.slice.html#method.into_vec
+    /// [`shrink_to_fit`]: #method.shrink_to_fit
     ///
     /// # Examples
     ///
@@ -1897,6 +1897,22 @@ fn from(s: Cow<'a, [T]>) -> Vec<T> {
     }
 }
 
+// note: test pulls in libstd, which causes errors here
+#[cfg(not(test))]
+#[stable(feature = "vec_from_box", since = "1.17.0")]
+impl<T> From<Box<[T]>> for Vec<T> {
+    fn from(s: Box<[T]>) -> Vec<T> {
+        s.into_vec()
+    }
+}
+
+#[stable(feature = "box_from_vec", since = "1.17.0")]
+impl<T> Into<Box<[T]>> for Vec<T> {
+    fn into(self) -> Box<[T]> {
+        self.into_boxed_slice()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> From<&'a str> for Vec<u8> {
     fn from(s: &'a str) -> Vec<u8> {
index d97d9b8ab83f67935fcec4a60e48c83f0e924a4c..98d0b1c8e156594ab4a72570f7ac4cc033ebf56b 100644 (file)
@@ -28,6 +28,7 @@
 #![feature(test)]
 #![feature(unboxed_closures)]
 #![feature(unicode)]
+#![feature(utf8_error_error_len)]
 
 extern crate collections;
 extern crate test;
index 8071c7e8c20d58688534d4e94e571034c9c28b45..c9b7104fec4f0072d2256f2b0de70153fd4648a9 100644 (file)
@@ -540,6 +540,36 @@ fn from_utf8_mostly_ascii() {
     }
 }
 
+#[test]
+fn from_utf8_error() {
+    macro_rules! test {
+        ($input: expr, $expected_valid_up_to: expr, $expected_error_len: expr) => {
+            let error = from_utf8($input).unwrap_err();
+            assert_eq!(error.valid_up_to(), $expected_valid_up_to);
+            assert_eq!(error.error_len(), $expected_error_len);
+        }
+    }
+    test!(b"A\xC3\xA9 \xFF ", 4, Some(1));
+    test!(b"A\xC3\xA9 \x80 ", 4, Some(1));
+    test!(b"A\xC3\xA9 \xC1 ", 4, Some(1));
+    test!(b"A\xC3\xA9 \xC1", 4, Some(1));
+    test!(b"A\xC3\xA9 \xC2", 4, None);
+    test!(b"A\xC3\xA9 \xC2 ", 4, Some(1));
+    test!(b"A\xC3\xA9 \xC2\xC0", 4, Some(1));
+    test!(b"A\xC3\xA9 \xE0", 4, None);
+    test!(b"A\xC3\xA9 \xE0\x9F", 4, Some(1));
+    test!(b"A\xC3\xA9 \xE0\xA0", 4, None);
+    test!(b"A\xC3\xA9 \xE0\xA0\xC0", 4, Some(2));
+    test!(b"A\xC3\xA9 \xE0\xA0 ", 4, Some(2));
+    test!(b"A\xC3\xA9 \xED\xA0\x80 ", 4, Some(1));
+    test!(b"A\xC3\xA9 \xF1", 4, None);
+    test!(b"A\xC3\xA9 \xF1\x80", 4, None);
+    test!(b"A\xC3\xA9 \xF1\x80\x80", 4, None);
+    test!(b"A\xC3\xA9 \xF1 ", 4, Some(1));
+    test!(b"A\xC3\xA9 \xF1\x80 ", 4, Some(2));
+    test!(b"A\xC3\xA9 \xF1\x80\x80 ", 4, Some(3));
+}
+
 #[test]
 fn test_as_bytes() {
     // no null
index 78764091cf03275a3569dc30bae907ff275292d7..a9282b5b02fea6164095138e48ff770ca5cf0ae2 100644 (file)
@@ -97,9 +97,9 @@
 /// [`as`]: ../../book/casting-between-types.html#as
 ///
 /// For an unsafe version of this function which ignores these checks, see
-/// [`from_u32_unchecked()`].
+/// [`from_u32_unchecked`].
 ///
-/// [`from_u32_unchecked()`]: fn.from_u32_unchecked.html
+/// [`from_u32_unchecked`]: fn.from_u32_unchecked.html
 ///
 /// # Examples
 ///
@@ -152,9 +152,9 @@ pub fn from_u32(i: u32) -> Option<char> {
 ///
 /// This function is unsafe, as it may construct invalid `char` values.
 ///
-/// For a safe version of this function, see the [`from_u32()`] function.
+/// For a safe version of this function, see the [`from_u32`] function.
 ///
-/// [`from_u32()`]: fn.from_u32.html
+/// [`from_u32`]: fn.from_u32.html
 ///
 /// # Examples
 ///
@@ -479,10 +479,10 @@ fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] {
 /// Returns an iterator that yields the hexadecimal Unicode escape of a
 /// character, as `char`s.
 ///
-/// This `struct` is created by the [`escape_unicode()`] method on [`char`]. See
+/// This `struct` is created by the [`escape_unicode`] method on [`char`]. See
 /// its documentation for more.
 ///
-/// [`escape_unicode()`]: ../../std/primitive.char.html#method.escape_unicode
+/// [`escape_unicode`]: ../../std/primitive.char.html#method.escape_unicode
 /// [`char`]: ../../std/primitive.char.html
 #[derive(Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -600,10 +600,10 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 /// An iterator that yields the literal escape code of a `char`.
 ///
-/// This `struct` is created by the [`escape_default()`] method on [`char`]. See
+/// This `struct` is created by the [`escape_default`] method on [`char`]. See
 /// its documentation for more.
 ///
-/// [`escape_default()`]: ../../std/primitive.char.html#method.escape_default
+/// [`escape_default`]: ../../std/primitive.char.html#method.escape_default
 /// [`char`]: ../../std/primitive.char.html
 #[derive(Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -713,10 +713,10 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 /// An iterator that yields the literal escape code of a `char`.
 ///
-/// This `struct` is created by the [`escape_debug()`] method on [`char`]. See its
+/// This `struct` is created by the [`escape_debug`] method on [`char`]. See its
 /// documentation for more.
 ///
-/// [`escape_debug()`]: ../../std/primitive.char.html#method.escape_debug
+/// [`escape_debug`]: ../../std/primitive.char.html#method.escape_debug
 /// [`char`]: ../../std/primitive.char.html
 #[unstable(feature = "char_escape_debug", issue = "35068")]
 #[derive(Clone, Debug)]
index 8dbbc5928f45ab9f56e3e3905b2e9e5d6606a35b..97b9525da6715ddc66f544a5b73faf0ce96a9f07 100644 (file)
@@ -61,7 +61,7 @@
 /// ## Derivable
 ///
 /// This trait can be used with `#[derive]` if all fields are `Clone`. The `derive`d
-/// implementation of [`clone()`] calls [`clone()`] on each field.
+/// implementation of [`clone`] calls [`clone`] on each field.
 ///
 /// ## How can I implement `Clone`?
 ///
@@ -75,7 +75,7 @@
 /// `Clone` cannot be `derive`d, but can be implemented as:
 ///
 /// [`Copy`]: ../../std/marker/trait.Copy.html
-/// [`clone()`]: trait.Clone.html#tymethod.clone
+/// [`clone`]: trait.Clone.html#tymethod.clone
 ///
 /// ```
 /// #[derive(Copy)]
index 4e170794c1d6e411d57443a56c91e2ff7339f93b..70e285f202e52f74eb257cd310c43f03a90e02c4 100644 (file)
@@ -154,14 +154,14 @@ pub trait AsMut<T: ?Sized> {
 /// # Generic Impls
 ///
 /// - [`From<T>`][From]` for U` implies `Into<U> for T`
-/// - [`into()`] is reflexive, which means that `Into<T> for T` is implemented
+/// - [`into`] is reflexive, which means that `Into<T> for T` is implemented
 ///
 /// [`TryInto`]: trait.TryInto.html
 /// [`Option<T>`]: ../../std/option/enum.Option.html
 /// [`Result<T, E>`]: ../../std/result/enum.Result.html
 /// [`String`]: ../../std/string/struct.String.html
 /// [From]: trait.From.html
-/// [`into()`]: trait.Into.html#tymethod.into
+/// [`into`]: trait.Into.html#tymethod.into
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Into<T>: Sized {
     /// Performs the conversion.
@@ -187,14 +187,14 @@ pub trait Into<T>: Sized {
 /// # Generic impls
 ///
 /// - `From<T> for U` implies [`Into<U>`]` for T`
-/// - [`from()`] is reflexive, which means that `From<T> for T` is implemented
+/// - [`from`] is reflexive, which means that `From<T> for T` is implemented
 ///
 /// [`TryFrom`]: trait.TryFrom.html
 /// [`Option<T>`]: ../../std/option/enum.Option.html
 /// [`Result<T, E>`]: ../../std/result/enum.Result.html
 /// [`String`]: ../../std/string/struct.String.html
 /// [`Into<U>`]: trait.Into.html
-/// [`from()`]: trait.From.html#tymethod.from
+/// [`from`]: trait.From.html#tymethod.from
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait From<T>: Sized {
     /// Performs the conversion.
index f0d8d1a321917a23a6d69bf21d659421f5a3bc8e..aadeaac83d5c85d7d622e8dac1e8e68ab9bdb9e2 100644 (file)
 ///
 /// This trait can be used with `#[derive]` if all fields implement `Hash`.
 /// When `derive`d, the resulting hash will be the combination of the values
-/// from calling [`.hash()`] on each field.
+/// from calling [`.hash`] on each field.
 ///
 /// ## How can I implement `Hash`?
 ///
 /// [`Eq`]: ../../std/cmp/trait.Eq.html
 /// [`HashMap`]: ../../std/collections/struct.HashMap.html
 /// [`HashSet`]: ../../std/collections/struct.HashSet.html
-/// [`.hash()`]: #tymethod.hash
+/// [`.hash`]: #tymethod.hash
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Hash {
     /// Feeds this value into the state given, updating the hasher as necessary.
index 0f47378aebb7ca03d3e41465b05bb525478e588b..1301c311c14caa361f22bb6471cb9b492cc76dc1 100644 (file)
@@ -140,11 +140,11 @@ fn size_hint(&self) -> (usize, Option<usize>) { (0, None) }
 
     /// Consumes the iterator, counting the number of iterations and returning it.
     ///
-    /// This method will evaluate the iterator until its [`next()`] returns
+    /// This method will evaluate the iterator until its [`next`] returns
     /// [`None`]. Once [`None`] is encountered, `count()` returns the number of
-    /// times it called [`next()`].
+    /// times it called [`next`].
     ///
-    /// [`next()`]: #tymethod.next
+    /// [`next`]: #tymethod.next
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
     ///
     /// # Overflow Behavior
@@ -323,7 +323,7 @@ fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter> where
     ///
     /// In other words, it zips two iterators together, into a single one.
     ///
-    /// When either iterator returns [`None`], all further calls to [`next()`]
+    /// When either iterator returns [`None`], all further calls to [`next`]
     /// will return [`None`].
     ///
     /// # Examples
@@ -364,7 +364,7 @@ fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter> where
     ///
     /// `zip()` is often used to zip an infinite iterator to a finite one.
     /// This works because the finite iterator will eventually return [`None`],
-    /// ending the zipper. Zipping with `(0..)` can look a lot like [`enumerate()`]:
+    /// ending the zipper. Zipping with `(0..)` can look a lot like [`enumerate`]:
     ///
     /// ```
     /// let enumerate: Vec<_> = "foo".chars().enumerate().collect();
@@ -381,8 +381,8 @@ fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter> where
     /// assert_eq!((2, 'o'), zipper[2]);
     /// ```
     ///
-    /// [`enumerate()`]: trait.Iterator.html#method.enumerate
-    /// [`next()`]: ../../std/iter/trait.Iterator.html#tymethod.next
+    /// [`enumerate`]: trait.Iterator.html#method.enumerate
+    /// [`next`]: ../../std/iter/trait.Iterator.html#tymethod.next
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -524,11 +524,11 @@ fn filter<P>(self, predicate: P) -> Filter<Self, P> where
     /// closure returns [`None`], it will try again, and call the closure on the
     /// next element, seeing if it will return [`Some`].
     ///
-    /// Why `filter_map()` and not just [`filter()`].[`map()`]? The key is in this
+    /// Why `filter_map()` and not just [`filter()`].[`map`]? The key is in this
     /// part:
     ///
-    /// [`filter()`]: #method.filter
-    /// [`map()`]: #method.map
+    /// [`filter`]: #method.filter
+    /// [`map`]: #method.map
     ///
     /// > If the closure returns [`Some(element)`][`Some`], then that element is returned.
     ///
@@ -550,7 +550,7 @@ fn filter<P>(self, predicate: P) -> Filter<Self, P> where
     /// assert_eq!(iter.next(), None);
     /// ```
     ///
-    /// Here's the same example, but with [`filter()`] and [`map()`]:
+    /// Here's the same example, but with [`filter`] and [`map`]:
     ///
     /// ```
     /// let a = ["1", "2", "lol"];
@@ -585,7 +585,7 @@ fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
     /// iterator.
     ///
     /// `enumerate()` keeps its count as a [`usize`]. If you want to count by a
-    /// different sized integer, the [`zip()`] function provides similar
+    /// different sized integer, the [`zip`] function provides similar
     /// functionality.
     ///
     /// # Overflow Behavior
@@ -601,7 +601,7 @@ fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
     ///
     /// [`usize::MAX`]: ../../std/usize/constant.MAX.html
     /// [`usize`]: ../../std/primitive.usize.html
-    /// [`zip()`]: #method.zip
+    /// [`zip`]: #method.zip
     ///
     /// # Examples
     ///
@@ -624,16 +624,16 @@ fn enumerate(self) -> Enumerate<Self> where Self: Sized {
     /// Creates an iterator which can use `peek` to look at the next element of
     /// the iterator without consuming it.
     ///
-    /// Adds a [`peek()`] method to an iterator. See its documentation for
+    /// Adds a [`peek`] method to an iterator. See its documentation for
     /// more information.
     ///
-    /// Note that the underlying iterator is still advanced when [`peek()`] is
+    /// Note that the underlying iterator is still advanced when [`peek`] is
     /// called for the first time: In order to retrieve the next element,
-    /// [`next()`] is called on the underlying iterator, hence any side effects of
-    /// the [`next()`] method will occur.
+    /// [`next`] is called on the underlying iterator, hence any side effects of
+    /// the [`next`] method will occur.
     ///
-    /// [`peek()`]: struct.Peekable.html#method.peek
-    /// [`next()`]: ../../std/iter/trait.Iterator.html#tymethod.next
+    /// [`peek`]: struct.Peekable.html#method.peek
+    /// [`next`]: ../../std/iter/trait.Iterator.html#tymethod.next
     ///
     /// # Examples
     ///
@@ -666,9 +666,9 @@ fn peekable(self) -> Peekable<Self> where Self: Sized {
         Peekable{iter: self, peeked: None}
     }
 
-    /// Creates an iterator that [`skip()`]s elements based on a predicate.
+    /// Creates an iterator that [`skip`]s elements based on a predicate.
     ///
-    /// [`skip()`]: #method.skip
+    /// [`skip`]: #method.skip
     ///
     /// `skip_while()` takes a closure as an argument. It will call this
     /// closure on each element of the iterator, and ignore elements
@@ -863,10 +863,10 @@ fn take(self, n: usize) -> Take<Self> where Self: Sized, {
         Take{iter: self, n: n}
     }
 
-    /// An iterator adaptor similar to [`fold()`] that holds internal state and
+    /// An iterator adaptor similar to [`fold`] that holds internal state and
     /// produces a new iterator.
     ///
-    /// [`fold()`]: #method.fold
+    /// [`fold`]: #method.fold
     ///
     /// `scan()` takes two arguments: an initial value which seeds the internal
     /// state, and a closure with two arguments, the first being a mutable
@@ -910,16 +910,16 @@ fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
 
     /// Creates an iterator that works like map, but flattens nested structure.
     ///
-    /// The [`map()`] adapter is very useful, but only when the closure
+    /// The [`map`] adapter is very useful, but only when the closure
     /// argument produces values. If it produces an iterator instead, there's
     /// an extra layer of indirection. `flat_map()` will remove this extra layer
     /// on its own.
     ///
-    /// Another way of thinking about `flat_map()`: [`map()`]'s closure returns
+    /// Another way of thinking about `flat_map()`: [`map`]'s closure returns
     /// one item for each element, and `flat_map()`'s closure returns an
     /// iterator for each element.
     ///
-    /// [`map()`]: #method.map
+    /// [`map`]: #method.map
     ///
     /// # Examples
     ///
@@ -1106,7 +1106,7 @@ fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
     /// library, used in a variety of contexts.
     ///
     /// The most basic pattern in which `collect()` is used is to turn one
-    /// collection into another. You take a collection, call [`iter()`] on it,
+    /// collection into another. You take a collection, call [`iter`] on it,
     /// do a bunch of transformations, and then `collect()` at the end.
     ///
     /// One of the keys to `collect()`'s power is that many things you might
@@ -1211,7 +1211,7 @@ fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
     /// assert_eq!(Ok(vec![1, 3]), result);
     /// ```
     ///
-    /// [`iter()`]: ../../std/iter/trait.Iterator.html#tymethod.next
+    /// [`iter`]: ../../std/iter/trait.Iterator.html#tymethod.next
     /// [`String`]: ../../std/string/struct.String.html
     /// [`char`]: ../../std/primitive.char.html
     /// [`Result`]: ../../std/result/enum.Result.html
@@ -1816,9 +1816,9 @@ fn rev(self) -> Rev<Self> where Self: Sized + DoubleEndedIterator {
     /// collections: one from the left elements of the pairs, and one
     /// from the right elements.
     ///
-    /// This function is, in some sense, the opposite of [`zip()`].
+    /// This function is, in some sense, the opposite of [`zip`].
     ///
-    /// [`zip()`]: #method.zip
+    /// [`zip`]: #method.zip
     ///
     /// # Examples
     ///
@@ -1849,12 +1849,12 @@ fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
         (ts, us)
     }
 
-    /// Creates an iterator which [`clone()`]s all of its elements.
+    /// Creates an iterator which [`clone`]s all of its elements.
     ///
     /// This is useful when you have an iterator over `&T`, but you need an
     /// iterator over `T`.
     ///
-    /// [`clone()`]: ../../std/clone/trait.Clone.html#tymethod.clone
+    /// [`clone`]: ../../std/clone/trait.Clone.html#tymethod.clone
     ///
     /// # Examples
     ///
index d9b8c5ea589fd57aa74a840b889ae5aad9deb4de..04394e0a3a876c811ab3ce7d3af3543b2713b3af 100644 (file)
 //! }
 //! ```
 //!
-//! An iterator has a method, [`next()`], which when called, returns an
-//! [`Option`]`<Item>`. [`next()`] will return `Some(Item)` as long as there
+//! An iterator has a method, [`next`], which when called, returns an
+//! [`Option`]`<Item>`. [`next`] will return `Some(Item)` as long as there
 //! are elements, and once they've all been exhausted, will return `None` to
 //! indicate that iteration is finished. Individual iterators may choose to
-//! resume iteration, and so calling [`next()`] again may or may not eventually
+//! resume iteration, and so calling [`next`] again may or may not eventually
 //! start returning `Some(Item)` again at some point.
 //!
 //! [`Iterator`]'s full definition includes a number of other methods as well,
-//! but they are default methods, built on top of [`next()`], and so you get
+//! but they are default methods, built on top of [`next`], and so you get
 //! them for free.
 //!
 //! Iterators are also composable, and it's common to chain them together to do
@@ -64,7 +64,7 @@
 //! below for more details.
 //!
 //! [`Iterator`]: trait.Iterator.html
-//! [`next()`]: trait.Iterator.html#tymethod.next
+//! [`next`]: trait.Iterator.html#tymethod.next
 //! [`Option`]: ../../std/option/enum.Option.html
 //!
 //! # The three forms of iteration
 //! produce an iterator. What gives?
 //!
 //! There's a trait in the standard library for converting something into an
-//! iterator: [`IntoIterator`]. This trait has one method, [`into_iter()`],
+//! iterator: [`IntoIterator`]. This trait has one method, [`into_iter`],
 //! which converts the thing implementing [`IntoIterator`] into an iterator.
 //! Let's take a look at that `for` loop again, and what the compiler converts
 //! it into:
 //!
 //! [`IntoIterator`]: trait.IntoIterator.html
-//! [`into_iter()`]: trait.IntoIterator.html#tymethod.into_iter
+//! [`into_iter`]: trait.IntoIterator.html#tymethod.into_iter
 //!
 //! ```
 //! let values = vec![1, 2, 3, 4, 5];
 //! ```
 //!
 //! First, we call `into_iter()` on the value. Then, we match on the iterator
-//! that returns, calling [`next()`] over and over until we see a `None`. At
+//! that returns, calling [`next`] over and over until we see a `None`. At
 //! that point, we `break` out of the loop, and we're done iterating.
 //!
 //! There's one more subtle bit here: the standard library contains an
 //! often called 'iterator adapters', as they're a form of the 'adapter
 //! pattern'.
 //!
-//! Common iterator adapters include [`map()`], [`take()`], and [`filter()`].
+//! Common iterator adapters include [`map`], [`take`], and [`filter`].
 //! For more, see their documentation.
 //!
-//! [`map()`]: trait.Iterator.html#method.map
-//! [`take()`]: trait.Iterator.html#method.take
-//! [`filter()`]: trait.Iterator.html#method.filter
+//! [`map`]: trait.Iterator.html#method.map
+//! [`take`]: trait.Iterator.html#method.take
+//! [`filter`]: trait.Iterator.html#method.filter
 //!
 //! # Laziness
 //!
 //! Iterators (and iterator [adapters](#adapters)) are *lazy*. This means that
 //! just creating an iterator doesn't _do_ a whole lot. Nothing really happens
-//! until you call [`next()`]. This is sometimes a source of confusion when
-//! creating an iterator solely for its side effects. For example, the [`map()`]
+//! until you call [`next`]. This is sometimes a source of confusion when
+//! creating an iterator solely for its side effects. For example, the [`map`]
 //! method calls a closure on each element it iterates over:
 //!
 //! ```
 //! do nothing unless consumed
 //! ```
 //!
-//! The idiomatic way to write a [`map()`] for its side effects is to use a
+//! The idiomatic way to write a [`map`] for its side effects is to use a
 //! `for` loop instead:
 //!
 //! ```
 //! }
 //! ```
 //!
-//! [`map()`]: trait.Iterator.html#method.map
+//! [`map`]: trait.Iterator.html#method.map
 //!
 //! The two most common ways to evaluate an iterator are to use a `for` loop
-//! like this, or using the [`collect()`] method to produce a new collection.
+//! like this, or using the [`collect`] method to produce a new collection.
 //!
-//! [`collect()`]: trait.Iterator.html#method.collect
+//! [`collect`]: trait.Iterator.html#method.collect
 //!
 //! # Infinity
 //!
 //! let numbers = 0..;
 //! ```
 //!
-//! It is common to use the [`take()`] iterator adapter to turn an infinite
+//! It is common to use the [`take`] iterator adapter to turn an infinite
 //! iterator into a finite one:
 //!
 //! ```
 //!
 //! This will print the numbers `0` through `4`, each on their own line.
 //!
-//! [`take()`]: trait.Iterator.html#method.take
+//! [`take`]: trait.Iterator.html#method.take
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
 mod sources;
 mod traits;
 
-/// An double-ended iterator with the direction inverted.
+/// A double-ended iterator with the direction inverted.
 ///
-/// This `struct` is created by the [`rev()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`rev`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`rev()`]: trait.Iterator.html#method.rev
+/// [`rev`]: trait.Iterator.html#method.rev
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
@@ -389,10 +389,10 @@ unsafe impl<I> TrustedLen for Rev<I>
 
 /// An iterator that clones the elements of an underlying iterator.
 ///
-/// This `struct` is created by the [`cloned()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`cloned`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`cloned()`]: trait.Iterator.html#method.cloned
+/// [`cloned`]: trait.Iterator.html#method.cloned
 /// [`Iterator`]: trait.Iterator.html
 #[stable(feature = "iter_cloned", since = "1.1.0")]
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
@@ -469,10 +469,10 @@ unsafe impl<'a, I, T: 'a> TrustedLen for Cloned<I>
 
 /// An iterator that repeats endlessly.
 ///
-/// This `struct` is created by the [`cycle()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`cycle`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`cycle()`]: trait.Iterator.html#method.cycle
+/// [`cycle`]: trait.Iterator.html#method.cycle
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
@@ -510,10 +510,10 @@ impl<I> FusedIterator for Cycle<I> where I: Clone + Iterator {}
 
 /// An iterator that strings two iterators together.
 ///
-/// This `struct` is created by the [`chain()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`chain`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`chain()`]: trait.Iterator.html#method.chain
+/// [`chain`]: trait.Iterator.html#method.chain
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
@@ -703,10 +703,10 @@ unsafe impl<A, B> TrustedLen for Chain<A, B>
 
 /// An iterator that iterates two other iterators simultaneously.
 ///
-/// This `struct` is created by the [`zip()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`zip`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`zip()`]: trait.Iterator.html#method.zip
+/// [`zip`]: trait.Iterator.html#method.zip
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
@@ -925,16 +925,16 @@ unsafe impl<A, B> TrustedLen for Zip<A, B>
 
 /// An iterator that maps the values of `iter` with `f`.
 ///
-/// This `struct` is created by the [`map()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`map`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`map()`]: trait.Iterator.html#method.map
+/// [`map`]: trait.Iterator.html#method.map
 /// [`Iterator`]: trait.Iterator.html
 ///
 /// # Notes about side effects
 ///
-/// The [`map()`] iterator implements [`DoubleEndedIterator`], meaning that
-/// you can also [`map()`] backwards:
+/// The [`map`] iterator implements [`DoubleEndedIterator`], meaning that
+/// you can also [`map`] backwards:
 ///
 /// ```rust
 /// let v: Vec<i32> = vec![1, 2, 3].into_iter().map(|x| x + 1).rev().collect();
@@ -1058,10 +1058,10 @@ fn may_have_side_effect() -> bool { true }
 
 /// An iterator that filters the elements of `iter` with `predicate`.
 ///
-/// This `struct` is created by the [`filter()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`filter`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`filter()`]: trait.Iterator.html#method.filter
+/// [`filter`]: trait.Iterator.html#method.filter
 /// [`Iterator`]: trait.Iterator.html
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1142,10 +1142,10 @@ impl<I: FusedIterator, P> FusedIterator for Filter<I, P>
 
 /// An iterator that uses `f` to both filter and map elements from `iter`.
 ///
-/// This `struct` is created by the [`filter_map()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`filter_map`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`filter_map()`]: trait.Iterator.html#method.filter_map
+/// [`filter_map`]: trait.Iterator.html#method.filter_map
 /// [`Iterator`]: trait.Iterator.html
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1208,10 +1208,10 @@ impl<B, I: FusedIterator, F> FusedIterator for FilterMap<I, F>
 
 /// An iterator that yields the current count and the element during iteration.
 ///
-/// This `struct` is created by the [`enumerate()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`enumerate()`]: trait.Iterator.html#method.enumerate
+/// [`enumerate`]: trait.Iterator.html#method.enumerate
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
@@ -1317,10 +1317,10 @@ unsafe impl<I> TrustedLen for Enumerate<I>
 /// An iterator with a `peek()` that returns an optional reference to the next
 /// element.
 ///
-/// This `struct` is created by the [`peekable()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`peekable`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`peekable()`]: trait.Iterator.html#method.peekable
+/// [`peekable`]: trait.Iterator.html#method.peekable
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
@@ -1401,10 +1401,10 @@ impl<I: FusedIterator> FusedIterator for Peekable<I> {}
 impl<I: Iterator> Peekable<I> {
     /// Returns a reference to the next() value without advancing the iterator.
     ///
-    /// Like [`next()`], if there is a value, it is wrapped in a `Some(T)`.
+    /// Like [`next`], if there is a value, it is wrapped in a `Some(T)`.
     /// But if the iteration is over, `None` is returned.
     ///
-    /// [`next()`]: trait.Iterator.html#tymethod.next
+    /// [`next`]: trait.Iterator.html#tymethod.next
     ///
     /// Because `peek()` returns a reference, and many iterators iterate over
     /// references, there can be a possibly confusing situation where the
@@ -1452,10 +1452,10 @@ pub fn peek(&mut self) -> Option<&I::Item> {
 
 /// An iterator that rejects elements while `predicate` is true.
 ///
-/// This `struct` is created by the [`skip_while()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`skip_while()`]: trait.Iterator.html#method.skip_while
+/// [`skip_while`]: trait.Iterator.html#method.skip_while
 /// [`Iterator`]: trait.Iterator.html
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1506,10 +1506,10 @@ impl<I, P> FusedIterator for SkipWhile<I, P>
 
 /// An iterator that only accepts elements while `predicate` is true.
 ///
-/// This `struct` is created by the [`take_while()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`take_while()`]: trait.Iterator.html#method.take_while
+/// [`take_while`]: trait.Iterator.html#method.take_while
 /// [`Iterator`]: trait.Iterator.html
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1565,10 +1565,10 @@ impl<I, P> FusedIterator for TakeWhile<I, P>
 
 /// An iterator that skips over `n` elements of `iter`.
 ///
-/// This `struct` is created by the [`skip()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`skip`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`skip()`]: trait.Iterator.html#method.skip
+/// [`skip`]: trait.Iterator.html#method.skip
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
@@ -1659,10 +1659,10 @@ impl<I> FusedIterator for Skip<I> where I: FusedIterator {}
 
 /// An iterator that only iterates over the first `n` iterations of `iter`.
 ///
-/// This `struct` is created by the [`take()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`take`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`take()`]: trait.Iterator.html#method.take
+/// [`take`]: trait.Iterator.html#method.take
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
@@ -1723,10 +1723,10 @@ impl<I> FusedIterator for Take<I> where I: FusedIterator {}
 
 /// An iterator to maintain state while iterating another iterator.
 ///
-/// This `struct` is created by the [`scan()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`scan`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`scan()`]: trait.Iterator.html#method.scan
+/// [`scan`]: trait.Iterator.html#method.scan
 /// [`Iterator`]: trait.Iterator.html
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1773,10 +1773,10 @@ impl<B, I, St, F> FusedIterator for Scan<I, St, F>
 /// An iterator that maps each element to an iterator, and yields the elements
 /// of the produced iterators.
 ///
-/// This `struct` is created by the [`flat_map()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`flat_map`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`flat_map()`]: trait.Iterator.html#method.flat_map
+/// [`flat_map`]: trait.Iterator.html#method.flat_map
 /// [`Iterator`]: trait.Iterator.html
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1863,10 +1863,10 @@ impl<I, U, F> FusedIterator for FlatMap<I, U, F>
 /// An iterator that yields `None` forever after the underlying iterator
 /// yields `None` once.
 ///
-/// This `struct` is created by the [`fuse()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`fuse`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`fuse()`]: trait.Iterator.html#method.fuse
+/// [`fuse`]: trait.Iterator.html#method.fuse
 /// [`Iterator`]: trait.Iterator.html
 #[derive(Clone, Debug)]
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
@@ -2012,10 +2012,10 @@ fn is_empty(&self) -> bool {
 /// An iterator that calls a function with a reference to each element before
 /// yielding it.
 ///
-/// This `struct` is created by the [`inspect()`] method on [`Iterator`]. See its
+/// This `struct` is created by the [`inspect`] method on [`Iterator`]. See its
 /// documentation for more.
 ///
-/// [`inspect()`]: trait.Iterator.html#method.inspect
+/// [`inspect`]: trait.Iterator.html#method.inspect
 /// [`Iterator`]: trait.Iterator.html
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
index b988ce73bdefc66ba9f174f4a9c43405d079c2c4..b405f35d5e4dbac5316db6491d50d87c3dc16403 100644 (file)
@@ -16,9 +16,9 @@
 
 /// An iterator that repeats an element endlessly.
 ///
-/// This `struct` is created by the [`repeat()`] function. See its documentation for more.
+/// This `struct` is created by the [`repeat`] function. See its documentation for more.
 ///
-/// [`repeat()`]: fn.repeat.html
+/// [`repeat`]: fn.repeat.html
 #[derive(Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Repeat<A> {
@@ -50,9 +50,9 @@ impl<A: Clone> FusedIterator for Repeat<A> {}
 /// over and over and 🔁.
 ///
 /// Infinite iterators like `repeat()` are often used with adapters like
-/// [`take()`], in order to make them finite.
+/// [`take`], in order to make them finite.
 ///
-/// [`take()`]: trait.Iterator.html#method.take
+/// [`take`]: trait.Iterator.html#method.take
 ///
 /// # Examples
 ///
@@ -74,7 +74,7 @@ impl<A: Clone> FusedIterator for Repeat<A> {}
 /// assert_eq!(Some(4), fours.next());
 /// ```
 ///
-/// Going finite with [`take()`]:
+/// Going finite with [`take`]:
 ///
 /// ```
 /// use std::iter;
@@ -98,9 +98,9 @@ pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
 
 /// An iterator that yields nothing.
 ///
-/// This `struct` is created by the [`empty()`] function. See its documentation for more.
+/// This `struct` is created by the [`empty`] function. See its documentation for more.
 ///
-/// [`empty()`]: fn.empty.html
+/// [`empty`]: fn.empty.html
 #[stable(feature = "iter_empty", since = "1.2.0")]
 pub struct Empty<T>(marker::PhantomData<T>);
 
@@ -183,9 +183,9 @@ pub fn empty<T>() -> Empty<T> {
 
 /// An iterator that yields an element exactly once.
 ///
-/// This `struct` is created by the [`once()`] function. See its documentation for more.
+/// This `struct` is created by the [`once`] function. See its documentation for more.
 ///
-/// [`once()`]: fn.once.html
+/// [`once`]: fn.once.html
 #[derive(Clone, Debug)]
 #[stable(feature = "iter_once", since = "1.2.0")]
 pub struct Once<T> {
@@ -227,12 +227,12 @@ impl<T> FusedIterator for Once<T> {}
 
 /// Creates an iterator that yields an element exactly once.
 ///
-/// This is commonly used to adapt a single value into a [`chain()`] of other
+/// This is commonly used to adapt a single value into a [`chain`] of other
 /// kinds of iteration. Maybe you have an iterator that covers almost
 /// everything, but you need an extra special case. Maybe you have a function
 /// which works on iterators, but you only need to process one value.
 ///
-/// [`chain()`]: trait.Iterator.html#method.chain
+/// [`chain`]: trait.Iterator.html#method.chain
 ///
 /// # Examples
 ///
index cb180110d3cc0116159b137a1201c744ba677264..3415b0eea9bd01519090bdd9c20567e906eb2819 100644 (file)
 /// created from an iterator. This is common for types which describe a
 /// collection of some kind.
 ///
-/// `FromIterator`'s [`from_iter()`] is rarely called explicitly, and is instead
-/// used through [`Iterator`]'s [`collect()`] method. See [`collect()`]'s
+/// `FromIterator`'s [`from_iter`] is rarely called explicitly, and is instead
+/// used through [`Iterator`]'s [`collect`] method. See [`collect`]'s
 /// documentation for more examples.
 ///
-/// [`from_iter()`]: #tymethod.from_iter
+/// [`from_iter`]: #tymethod.from_iter
 /// [`Iterator`]: trait.Iterator.html
-/// [`collect()`]: trait.Iterator.html#method.collect
+/// [`collect`]: trait.Iterator.html#method.collect
 ///
 /// See also: [`IntoIterator`].
 ///
@@ -42,7 +42,7 @@
 /// assert_eq!(v, vec![5, 5, 5, 5, 5]);
 /// ```
 ///
-/// Using [`collect()`] to implicitly use `FromIterator`:
+/// Using [`collect`] to implicitly use `FromIterator`:
 ///
 /// ```
 /// let five_fives = std::iter::repeat(5).take(5);
@@ -487,17 +487,17 @@ fn next_back(&mut self) -> Option<I::Item> { (**self).next_back() }
 /// backwards, a good start is to know where the end is.
 ///
 /// When implementing an `ExactSizeIterator`, You must also implement
-/// [`Iterator`]. When doing so, the implementation of [`size_hint()`] *must*
+/// [`Iterator`]. When doing so, the implementation of [`size_hint`] *must*
 /// return the exact size of the iterator.
 ///
 /// [`Iterator`]: trait.Iterator.html
-/// [`size_hint()`]: trait.Iterator.html#method.size_hint
+/// [`size_hint`]: trait.Iterator.html#method.size_hint
 ///
-/// The [`len()`] method has a default implementation, so you usually shouldn't
+/// The [`len`] method has a default implementation, so you usually shouldn't
 /// implement it. However, you may be able to provide a more performant
 /// implementation than the default, so overriding it in this case makes sense.
 ///
-/// [`len()`]: #method.len
+/// [`len`]: #method.len
 ///
 /// # Examples
 ///
@@ -557,11 +557,11 @@ pub trait ExactSizeIterator: Iterator {
     /// implementation, you can do so. See the [trait-level] docs for an
     /// example.
     ///
-    /// This function has the same safety guarantees as the [`size_hint()`]
+    /// This function has the same safety guarantees as the [`size_hint`]
     /// function.
     ///
     /// [trait-level]: trait.ExactSizeIterator.html
-    /// [`size_hint()`]: trait.Iterator.html#method.size_hint
+    /// [`size_hint`]: trait.Iterator.html#method.size_hint
     ///
     /// # Examples
     ///
@@ -624,14 +624,14 @@ fn is_empty(&self) -> bool {
 
 /// Trait to represent types that can be created by summing up an iterator.
 ///
-/// This trait is used to implement the [`sum()`] method on iterators. Types which
-/// implement the trait can be generated by the [`sum()`] method. Like
+/// This trait is used to implement the [`sum`] method on iterators. Types which
+/// implement the trait can be generated by the [`sum`] method. Like
 /// [`FromIterator`] this trait should rarely be called directly and instead
-/// interacted with through [`Iterator::sum()`].
+/// interacted with through [`Iterator::sum`].
 ///
-/// [`sum()`]: ../../std/iter/trait.Sum.html#tymethod.sum
+/// [`sum`]: ../../std/iter/trait.Sum.html#tymethod.sum
 /// [`FromIterator`]: ../../std/iter/trait.FromIterator.html
-/// [`Iterator::sum()`]: ../../std/iter/trait.Iterator.html#method.sum
+/// [`Iterator::sum`]: ../../std/iter/trait.Iterator.html#method.sum
 #[stable(feature = "iter_arith_traits", since = "1.12.0")]
 pub trait Sum<A = Self>: Sized {
     /// Method which takes an iterator and generates `Self` from the elements by
@@ -643,14 +643,14 @@ pub trait Sum<A = Self>: Sized {
 /// Trait to represent types that can be created by multiplying elements of an
 /// iterator.
 ///
-/// This trait is used to implement the [`product()`] method on iterators. Types
-/// which implement the trait can be generated by the [`product()`] method. Like
+/// This trait is used to implement the [`product`] method on iterators. Types
+/// which implement the trait can be generated by the [`product`] method. Like
 /// [`FromIterator`] this trait should rarely be called directly and instead
-/// interacted with through [`Iterator::product()`].
+/// interacted with through [`Iterator::product`].
 ///
-/// [`product()`]: ../../std/iter/trait.Product.html#tymethod.product
+/// [`product`]: ../../std/iter/trait.Product.html#tymethod.product
 /// [`FromIterator`]: ../../std/iter/trait.FromIterator.html
-/// [`Iterator::product()`]: ../../std/iter/trait.Iterator.html#method.product
+/// [`Iterator::product`]: ../../std/iter/trait.Iterator.html#method.product
 #[stable(feature = "iter_arith_traits", since = "1.12.0")]
 pub trait Product<A = Self>: Sized {
     /// Method which takes an iterator and generates `Self` from the elements by
@@ -823,12 +823,12 @@ fn product<I>(iter: I) -> Result<T, E>
 /// that behave this way because it allows for some significant optimizations.
 ///
 /// Note: In general, you should not use `FusedIterator` in generic bounds if
-/// you need a fused iterator. Instead, you should just call [`Iterator::fuse()`]
+/// you need a fused iterator. Instead, you should just call [`Iterator::fuse`]
 /// on the iterator. If the iterator is already fused, the additional [`Fuse`]
 /// wrapper will be a no-op with no performance penalty.
 ///
 /// [`None`]: ../../std/option/enum.Option.html#variant.None
-/// [`Iterator::fuse()`]: ../../std/iter/trait.Iterator.html#method.fuse
+/// [`Iterator::fuse`]: ../../std/iter/trait.Iterator.html#method.fuse
 /// [`Fuse`]: ../../std/iter/struct.Fuse.html
 #[unstable(feature = "fused", issue = "35602")]
 pub trait FusedIterator: Iterator {}
@@ -848,11 +848,11 @@ impl<'a, I: FusedIterator + ?Sized> FusedIterator for &'a mut I {}
 /// # Safety
 ///
 /// This trait must only be implemented when the contract is upheld.
-/// Consumers of this trait must inspect [`.size_hint()`]’s upper bound.
+/// Consumers of this trait must inspect [`.size_hint`]’s upper bound.
 ///
 /// [`None`]: ../../std/option/enum.Option.html#variant.None
 /// [`usize::MAX`]: ../../std/usize/constant.MAX.html
-/// [`.size_hint()`]: ../../std/iter/trait.Iterator.html#method.size_hint
+/// [`.size_hint`]: ../../std/iter/trait.Iterator.html#method.size_hint
 #[unstable(feature = "trusted_len", issue = "37572")]
 pub unsafe trait TrustedLen : Iterator {}
 
index b22f7fa17077b7890940b0ac82ba331d685d3e7f..021079f85f6be2292001ad9fb70a0ecc8c83d81e 100644 (file)
@@ -90,10 +90,10 @@ macro_rules! assert {
 /// On panic, this macro will print the values of the expressions with their
 /// debug representations.
 ///
-/// Like [`assert!()`], this macro has a second version, where a custom
+/// Like [`assert!`], this macro has a second version, where a custom
 /// panic message can be provided.
 ///
-/// [`assert!()`]: macro.assert.html
+/// [`assert!`]: macro.assert.html
 ///
 /// # Examples
 ///
index 1e9eaaf5f3223761f172536c2b50ad4eb347b1f8..393c01b0105c5c63d427e042d27bc46592509607 100644 (file)
@@ -245,7 +245,7 @@ pub trait Unsize<T: ?Sized> {
 /// [`String`]'s buffer, leading to a double free.
 ///
 /// Generalizing the latter case, any type implementing [`Drop`] can't be `Copy`, because it's
-/// managing some resource besides its own [`size_of::<T>()`] bytes.
+/// managing some resource besides its own [`size_of::<T>`] bytes.
 ///
 /// If you try to implement `Copy` on a struct or enum containing non-`Copy` data, you will get
 /// the error [E0204].
@@ -262,7 +262,7 @@ pub trait Unsize<T: ?Sized> {
 /// [`Vec<T>`]: ../../std/vec/struct.Vec.html
 /// [`String`]: ../../std/string/struct.String.html
 /// [`Drop`]: ../../std/ops/trait.Drop.html
-/// [`size_of::<T>()`]: ../../std/mem/fn.size_of.html
+/// [`size_of::<T>`]: ../../std/mem/fn.size_of.html
 /// [`Clone`]: ../clone/trait.Clone.html
 /// [`String`]: ../../std/string/struct.String.html
 /// [`i32`]: ../../std/primitive.i32.html
index f4ce4697d7cf4108f8973119fc3b635bdfd904e5..ba65e4494a8bbed54cb47b242d3b3161265b4c36 100644 (file)
@@ -617,7 +617,7 @@ pub fn drop<T>(_x: T) { }
 /// the contained value.
 ///
 /// This function will unsafely assume the pointer `src` is valid for
-/// [`size_of::<U>()`][size_of] bytes by transmuting `&T` to `&U` and then reading
+/// [`size_of::<U>`][size_of] bytes by transmuting `&T` to `&U` and then reading
 /// the `&U`. It will also unsafely create a copy of the contained value instead of
 /// moving out of `src`.
 ///
index 97ea6bb347b54adcecb766ba32169583baccf75e..81c80ba51152d72cd14d49db6309e9f1f9ca13e3 100644 (file)
@@ -2390,11 +2390,11 @@ impl usize {
 
 /// A classification of floating point numbers.
 ///
-/// This `enum` is used as the return type for [`f32::classify()`] and [`f64::classify()`]. See
+/// This `enum` is used as the return type for [`f32::classify`] and [`f64::classify`]. See
 /// their documentation for more.
 ///
-/// [`f32::classify()`]: ../../std/primitive.f32.html#method.classify
-/// [`f64::classify()`]: ../../std/primitive.f64.html#method.classify
+/// [`f32::classify`]: ../../std/primitive.f32.html#method.classify
+/// [`f64::classify`]: ../../std/primitive.f64.html#method.classify
 ///
 /// # Examples
 ///
@@ -2756,9 +2756,9 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) -> Result<T, Par
 /// An error which can be returned when parsing an integer.
 ///
 /// This error is used as the error type for the `from_str_radix()` functions
-/// on the primitive integer types, such as [`i8::from_str_radix()`].
+/// on the primitive integer types, such as [`i8::from_str_radix`].
 ///
-/// [`i8::from_str_radix()`]: ../../std/primitive.i8.html#method.from_str_radix
+/// [`i8::from_str_radix`]: ../../std/primitive.i8.html#method.from_str_radix
 #[derive(Debug, Clone, PartialEq, Eq)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct ParseIntError {
index 59bcb340ec99a07accf078d53eb04d628ee5a275..686cc21eba1a0aafca8436250d940dc4ead374d6 100644 (file)
@@ -30,7 +30,7 @@
 //! contexts involving built-in types, this is usually not a problem.
 //! However, using these operators in generic code, requires some
 //! attention if values have to be reused as opposed to letting the operators
-//! consume them. One option is to occasionally use [`clone()`].
+//! consume them. One option is to occasionally use [`clone`].
 //! Another option is to rely on the types involved providing additional
 //! operator implementations for references. For example, for a user-defined
 //! type `T` which is supposed to support addition, it is probably a good
 //! [`FnOnce`]: trait.FnOnce.html
 //! [`Add`]: trait.Add.html
 //! [`Sub`]: trait.Sub.html
-//! [`clone()`]: ../clone/trait.Clone.html#tymethod.clone
+//! [`clone`]: ../clone/trait.Clone.html#tymethod.clone
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -2027,7 +2027,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 /// A (half-open) range which is bounded at both ends: { x | start <= x < end }.
 /// Use `start..end` (two dots) for its shorthand.
 ///
-/// See the [`contains()`](#method.contains) method for its characterization.
+/// See the [`contains`](#method.contains) method for its characterization.
 ///
 /// # Examples
 ///
@@ -2085,7 +2085,7 @@ pub fn contains(&self, item: Idx) -> bool {
 /// A range which is only bounded below: { x | start <= x }.
 /// Use `start..` for its shorthand.
 ///
-/// See the [`contains()`](#method.contains) method for its characterization.
+/// See the [`contains`](#method.contains) method for its characterization.
 ///
 /// Note: Currently, no overflow checking is done for the iterator
 /// implementation; if you use an integer range and the integer overflows, it
@@ -2141,7 +2141,7 @@ pub fn contains(&self, item: Idx) -> bool {
 /// A range which is only bounded above: { x | x < end }.
 /// Use `..end` (two dots) for its shorthand.
 ///
-/// See the [`contains()`](#method.contains) method for its characterization.
+/// See the [`contains`](#method.contains) method for its characterization.
 ///
 /// It cannot serve as an iterator because it doesn't have a starting point.
 ///
@@ -2207,7 +2207,7 @@ pub fn contains(&self, item: Idx) -> bool {
 /// An inclusive range which is bounded at both ends: { x | start <= x <= end }.
 /// Use `start...end` (three dots) for its shorthand.
 ///
-/// See the [`contains()`](#method.contains) method for its characterization.
+/// See the [`contains`](#method.contains) method for its characterization.
 ///
 /// # Examples
 ///
@@ -2293,7 +2293,7 @@ pub fn contains(&self, item: Idx) -> bool {
 /// An inclusive range which is only bounded above: { x | x <= end }.
 /// Use `...end` (three dots) for its shorthand.
 ///
-/// See the [`contains()`](#method.contains) method for its characterization.
+/// See the [`contains`](#method.contains) method for its characterization.
 ///
 /// It cannot serve as an iterator because it doesn't have a starting point.
 ///
index 260fdab9d58fb5205faa1d1f6aa226c7f5c629cf..0b7aa4fa9117c27b860d67dd5dcf4be67daef2c9 100644 (file)
@@ -191,9 +191,8 @@ pub unsafe fn read_unaligned<T>(src: *const T) -> T {
 /// allocations or resources, so care must be taken not to overwrite an object
 /// that should be dropped.
 ///
-/// It does not immediately drop the contents of `src` either; it is rather
-/// *moved* into the memory location `dst` and will be dropped whenever that
-/// location goes out of scope.
+/// Additionally, it does not drop `src`. Semantically, `src` is moved into the
+/// location pointed to by `dst`.
 ///
 /// This is appropriate for initializing uninitialized memory, or overwriting
 /// memory that has previously been `read` from.
@@ -233,6 +232,9 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
 /// allocations or resources, so care must be taken not to overwrite an object
 /// that should be dropped.
 ///
+/// Additionally, it does not drop `src`. Semantically, `src` is moved into the
+/// location pointed to by `dst`.
+///
 /// This is appropriate for initializing uninitialized memory, or overwriting
 /// memory that has previously been `read` from.
 ///
index 52e330163105222ca1a8caec998eaec384789ccb..0775142651006469185cbcbd22809efec25c0f56 100644 (file)
 /// A trait to abstract the idea of creating a new instance of a type from a
 /// string.
 ///
-/// `FromStr`'s [`from_str()`] method is often used implicitly, through
-/// [`str`]'s [`parse()`] method. See [`parse()`]'s documentation for examples.
+/// `FromStr`'s [`from_str`] method is often used implicitly, through
+/// [`str`]'s [`parse`] method. See [`parse`]'s documentation for examples.
 ///
-/// [`from_str()`]: #tymethod.from_str
+/// [`from_str`]: #tymethod.from_str
 /// [`str`]: ../../std/primitive.str.html
-/// [`parse()`]: ../../std/primitive.str.html#method.parse
+/// [`parse`]: ../../std/primitive.str.html#method.parse
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait FromStr: Sized {
     /// The associated error which can be returned from parsing.
@@ -125,13 +125,14 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Utf8Error {
     valid_up_to: usize,
+    error_len: Option<u8>,
 }
 
 impl Utf8Error {
     /// Returns the index in the given string up to which valid UTF-8 was
     /// verified.
     ///
-    /// It is the maximum index such that `from_utf8(input[..index])`
+    /// It is the maximum index such that `from_utf8(&input[..index])`
     /// would return `Ok(_)`.
     ///
     /// # Examples
@@ -152,6 +153,23 @@ impl Utf8Error {
     /// ```
     #[stable(feature = "utf8_error", since = "1.5.0")]
     pub fn valid_up_to(&self) -> usize { self.valid_up_to }
+
+    /// Provide more information about the failure:
+    ///
+    /// * `None`: the end of the input was reached unexpectedly.
+    ///   `self.valid_up_to()` is 1 to 3 bytes from the end of the input.
+    ///   If a byte stream (such as a file or a network socket) is being decoded incrementally,
+    ///   this could be a valid `char` whose UTF-8 byte sequence is spanning multiple chunks.
+    ///
+    /// * `Some(len)`: an unexpected byte was encountered.
+    ///   The length provided is that of the invalid byte sequence
+    ///   that starts at the index given by `valid_up_to()`.
+    ///   Decoding should resume after that sequence
+    ///   (after inserting a U+FFFD REPLACEMENT CHARACTER) in case of lossy decoding.
+    #[unstable(feature = "utf8_error_error_len", reason ="new", issue = "40494")]
+    pub fn error_len(&self) -> Option<usize> {
+        self.error_len.map(|len| len as usize)
+    }
 }
 
 /// Converts a slice of bytes to a string slice.
@@ -164,13 +182,13 @@ pub fn valid_up_to(&self) -> usize { self.valid_up_to }
 ///
 /// If you are sure that the byte slice is valid UTF-8, and you don't want to
 /// incur the overhead of the validity check, there is an unsafe version of
-/// this function, [`from_utf8_unchecked()`][fromutf8u], which has the same
+/// this function, [`from_utf8_unchecked`][fromutf8u], which has the same
 /// behavior but skips the check.
 ///
 /// [fromutf8u]: fn.from_utf8_unchecked.html
 ///
 /// If you need a `String` instead of a `&str`, consider
-/// [`String::from_utf8()`][string].
+/// [`String::from_utf8`][string].
 ///
 /// [string]: ../../std/string/struct.String.html#method.from_utf8
 ///
@@ -265,7 +283,7 @@ unsafe fn from_raw_parts_mut<'a>(p: *mut u8, len: usize) -> &'a mut str {
 /// Converts a slice of bytes to a string slice without checking
 /// that the string contains valid UTF-8.
 ///
-/// See the safe version, [`from_utf8()`][fromutf8], for more information.
+/// See the safe version, [`from_utf8`][fromutf8], for more information.
 ///
 /// [fromutf8]: fn.from_utf8.html
 ///
@@ -300,7 +318,12 @@ pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for Utf8Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "invalid utf-8: invalid byte near index {}", self.valid_up_to)
+        if let Some(error_len) = self.error_len {
+            write!(f, "invalid utf-8 sequence of {} bytes from index {}",
+                   error_len, self.valid_up_to)
+        } else {
+            write!(f, "incomplete utf-8 byte sequence from index {}", self.valid_up_to)
+        }
     }
 }
 
@@ -310,9 +333,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 /// Iterator for the char (representing *Unicode Scalar Values*) of a string
 ///
-/// Created with the method [`chars()`].
+/// Created with the method [`chars`].
 ///
-/// [`chars()`]: ../../std/primitive.str.html#method.chars
+/// [`chars`]: ../../std/primitive.str.html#method.chars
 #[derive(Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Chars<'a> {
@@ -567,9 +590,9 @@ pub fn as_str(&self) -> &'a str {
 /// External iterator for a string's bytes.
 /// Use with the `std::iter` module.
 ///
-/// Created with the method [`bytes()`].
+/// Created with the method [`bytes`].
 ///
-/// [`bytes()`]: ../../std/primitive.str.html#method.bytes
+/// [`bytes`]: ../../std/primitive.str.html#method.bytes
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone, Debug)]
 pub struct Bytes<'a>(Cloned<slice::Iter<'a, u8>>);
@@ -902,14 +925,14 @@ fn next_back(&mut self) -> Option<&'a str>
 
 generate_pattern_iterators! {
     forward:
-        /// Created with the method [`split()`].
+        /// Created with the method [`split`].
         ///
-        /// [`split()`]: ../../std/primitive.str.html#method.split
+        /// [`split`]: ../../std/primitive.str.html#method.split
         struct Split;
     reverse:
-        /// Created with the method [`rsplit()`].
+        /// Created with the method [`rsplit`].
         ///
-        /// [`rsplit()`]: ../../std/primitive.str.html#method.rsplit
+        /// [`rsplit`]: ../../std/primitive.str.html#method.rsplit
         struct RSplit;
     stability:
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -920,14 +943,14 @@ fn next_back(&mut self) -> Option<&'a str>
 
 generate_pattern_iterators! {
     forward:
-        /// Created with the method [`split_terminator()`].
+        /// Created with the method [`split_terminator`].
         ///
-        /// [`split_terminator()`]: ../../std/primitive.str.html#method.split_terminator
+        /// [`split_terminator`]: ../../std/primitive.str.html#method.split_terminator
         struct SplitTerminator;
     reverse:
-        /// Created with the method [`rsplit_terminator()`].
+        /// Created with the method [`rsplit_terminator`].
         ///
-        /// [`rsplit_terminator()`]: ../../std/primitive.str.html#method.rsplit_terminator
+        /// [`rsplit_terminator`]: ../../std/primitive.str.html#method.rsplit_terminator
         struct RSplitTerminator;
     stability:
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -980,14 +1003,14 @@ fn next_back(&mut self) -> Option<&'a str>
 
 generate_pattern_iterators! {
     forward:
-        /// Created with the method [`splitn()`].
+        /// Created with the method [`splitn`].
         ///
-        /// [`splitn()`]: ../../std/primitive.str.html#method.splitn
+        /// [`splitn`]: ../../std/primitive.str.html#method.splitn
         struct SplitN;
     reverse:
-        /// Created with the method [`rsplitn()`].
+        /// Created with the method [`rsplitn`].
         ///
-        /// [`rsplitn()`]: ../../std/primitive.str.html#method.rsplitn
+        /// [`rsplitn`]: ../../std/primitive.str.html#method.rsplitn
         struct RSplitN;
     stability:
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -1031,14 +1054,14 @@ fn next_back(&mut self) -> Option<(usize, &'a str)>
 
 generate_pattern_iterators! {
     forward:
-        /// Created with the method [`match_indices()`].
+        /// Created with the method [`match_indices`].
         ///
-        /// [`match_indices()`]: ../../std/primitive.str.html#method.match_indices
+        /// [`match_indices`]: ../../std/primitive.str.html#method.match_indices
         struct MatchIndices;
     reverse:
-        /// Created with the method [`rmatch_indices()`].
+        /// Created with the method [`rmatch_indices`].
         ///
-        /// [`rmatch_indices()`]: ../../std/primitive.str.html#method.rmatch_indices
+        /// [`rmatch_indices`]: ../../std/primitive.str.html#method.rmatch_indices
         struct RMatchIndices;
     stability:
         #[stable(feature = "str_match_indices", since = "1.5.0")]
@@ -1084,14 +1107,14 @@ fn next_back(&mut self) -> Option<&'a str>
 
 generate_pattern_iterators! {
     forward:
-        /// Created with the method [`matches()`].
+        /// Created with the method [`matches`].
         ///
-        /// [`matches()`]: ../../std/primitive.str.html#method.matches
+        /// [`matches`]: ../../std/primitive.str.html#method.matches
         struct Matches;
     reverse:
-        /// Created with the method [`rmatches()`].
+        /// Created with the method [`rmatches`].
         ///
-        /// [`rmatches()`]: ../../std/primitive.str.html#method.rmatches
+        /// [`rmatches`]: ../../std/primitive.str.html#method.rmatches
         struct RMatches;
     stability:
         #[stable(feature = "str_matches", since = "1.2.0")]
@@ -1100,9 +1123,9 @@ fn next_back(&mut self) -> Option<&'a str>
     delegate double ended;
 }
 
-/// Created with the method [`lines()`].
+/// Created with the method [`lines`].
 ///
-/// [`lines()`]: ../../std/primitive.str.html#method.lines
+/// [`lines`]: ../../std/primitive.str.html#method.lines
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone, Debug)]
 pub struct Lines<'a>(Map<SplitTerminator<'a, char>, LinesAnyMap>);
@@ -1133,9 +1156,9 @@ fn next_back(&mut self) -> Option<&'a str> {
 #[unstable(feature = "fused", issue = "35602")]
 impl<'a> FusedIterator for Lines<'a> {}
 
-/// Created with the method [`lines_any()`].
+/// Created with the method [`lines_any`].
 ///
-/// [`lines_any()`]: ../../std/primitive.str.html#method.lines_any
+/// [`lines_any`]: ../../std/primitive.str.html#method.lines_any
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_deprecated(since = "1.4.0", reason = "use lines()/Lines instead now")]
 #[derive(Clone, Debug)]
@@ -1241,17 +1264,20 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
 
     while index < len {
         let old_offset = index;
-        macro_rules! err { () => {{
-            return Err(Utf8Error {
-                valid_up_to: old_offset
-            })
-        }}}
+        macro_rules! err {
+            ($error_len: expr) => {
+                return Err(Utf8Error {
+                    valid_up_to: old_offset,
+                    error_len: $error_len,
+                })
+            }
+        }
 
         macro_rules! next { () => {{
             index += 1;
             // we needed data, but there was none: error!
             if index >= len {
-                err!()
+                err!(None)
             }
             v[index]
         }}}
@@ -1259,7 +1285,6 @@ macro_rules! next { () => {{
         let first = v[index];
         if first >= 128 {
             let w = UTF8_CHAR_WIDTH[first as usize];
-            let second = next!();
             // 2-byte encoding is for codepoints  \u{0080} to  \u{07ff}
             //        first  C2 80        last DF BF
             // 3-byte encoding is for codepoints  \u{0800} to  \u{ffff}
@@ -1279,25 +1304,36 @@ macro_rules! next { () => {{
             // UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
             //               %xF4 %x80-8F 2( UTF8-tail )
             match w {
-                2 => if second & !CONT_MASK != TAG_CONT_U8 {err!()},
+                2 => if next!() & !CONT_MASK != TAG_CONT_U8 {
+                    err!(Some(1))
+                },
                 3 => {
-                    match (first, second, next!() & !CONT_MASK) {
-                        (0xE0         , 0xA0 ... 0xBF, TAG_CONT_U8) |
-                        (0xE1 ... 0xEC, 0x80 ... 0xBF, TAG_CONT_U8) |
-                        (0xED         , 0x80 ... 0x9F, TAG_CONT_U8) |
-                        (0xEE ... 0xEF, 0x80 ... 0xBF, TAG_CONT_U8) => {}
-                        _ => err!()
+                    match (first, next!()) {
+                        (0xE0         , 0xA0 ... 0xBF) |
+                        (0xE1 ... 0xEC, 0x80 ... 0xBF) |
+                        (0xED         , 0x80 ... 0x9F) |
+                        (0xEE ... 0xEF, 0x80 ... 0xBF) => {}
+                        _ => err!(Some(1))
+                    }
+                    if next!() & !CONT_MASK != TAG_CONT_U8 {
+                        err!(Some(2))
                     }
                 }
                 4 => {
-                    match (first, second, next!() & !CONT_MASK, next!() & !CONT_MASK) {
-                        (0xF0         , 0x90 ... 0xBF, TAG_CONT_U8, TAG_CONT_U8) |
-                        (0xF1 ... 0xF3, 0x80 ... 0xBF, TAG_CONT_U8, TAG_CONT_U8) |
-                        (0xF4         , 0x80 ... 0x8F, TAG_CONT_U8, TAG_CONT_U8) => {}
-                        _ => err!()
+                    match (first, next!()) {
+                        (0xF0         , 0x90 ... 0xBF) |
+                        (0xF1 ... 0xF3, 0x80 ... 0xBF) |
+                        (0xF4         , 0x80 ... 0x8F) => {}
+                        _ => err!(Some(1))
+                    }
+                    if next!() & !CONT_MASK != TAG_CONT_U8 {
+                        err!(Some(2))
+                    }
+                    if next!() & !CONT_MASK != TAG_CONT_U8 {
+                        err!(Some(3))
                     }
                 }
-                _ => err!()
+                _ => err!(Some(1))
             }
             index += 1;
         } else {
index 0d2a467b577027aa79cac6b420bfcd41f9036992..0ab0550469bad07248a69d92acb6328bdbc0eae6 100644 (file)
 #![crate_type = "dylib"]
 #![deny(warnings)]
 #![deny(missing_docs)]
+#![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/",
+       issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
+       test(no_crate_inject, attr(deny(warnings))),
+       test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]
 
 #![feature(rustc_private)]
 #![feature(staged_api)]
index aa6614b0af4f7b492dd84a49635fa0614a12c428..d92eaee6f0c8ec9e72902fa48a3b5c54aac5b969 100644 (file)
@@ -84,6 +84,7 @@ pub struct LoweringContext<'a> {
     trait_impls: BTreeMap<DefId, Vec<NodeId>>,
     trait_default_impl: BTreeMap<DefId, NodeId>,
 
+    catch_scopes: Vec<NodeId>,
     loop_scopes: Vec<NodeId>,
     is_in_loop_condition: bool,
 
@@ -123,6 +124,7 @@ pub fn lower_crate(sess: &Session,
         trait_impls: BTreeMap::new(),
         trait_default_impl: BTreeMap::new(),
         exported_macros: Vec::new(),
+        catch_scopes: Vec::new(),
         loop_scopes: Vec::new(),
         is_in_loop_condition: false,
         type_def_lifetime_params: DefIdMap(),
@@ -261,6 +263,21 @@ fn allow_internal_unstable(&self, reason: &'static str, mut span: Span) -> Span
         span
     }
 
+    fn with_catch_scope<T, F>(&mut self, catch_id: NodeId, f: F) -> T
+        where F: FnOnce(&mut LoweringContext) -> T
+    {
+        let len = self.catch_scopes.len();
+        self.catch_scopes.push(catch_id);
+
+        let result = f(self);
+        assert_eq!(len + 1, self.catch_scopes.len(),
+            "catch scopes should be added and removed in stack order");
+
+        self.catch_scopes.pop().unwrap();
+
+        result
+    }
+
     fn with_loop_scope<T, F>(&mut self, loop_id: NodeId, f: F) -> T
         where F: FnOnce(&mut LoweringContext) -> T
     {
@@ -295,15 +312,17 @@ fn with_loop_condition_scope<T, F>(&mut self, f: F) -> T
         result
     }
 
-    fn with_new_loop_scopes<T, F>(&mut self, f: F) -> T
+    fn with_new_scopes<T, F>(&mut self, f: F) -> T
         where F: FnOnce(&mut LoweringContext) -> T
     {
         let was_in_loop_condition = self.is_in_loop_condition;
         self.is_in_loop_condition = false;
 
+        let catch_scopes = mem::replace(&mut self.catch_scopes, Vec::new());
         let loop_scopes = mem::replace(&mut self.loop_scopes, Vec::new());
         let result = f(self);
-        mem::replace(&mut self.loop_scopes, loop_scopes);
+        self.catch_scopes = catch_scopes;
+        self.loop_scopes = loop_scopes;
 
         self.is_in_loop_condition = was_in_loop_condition;
 
@@ -1065,7 +1084,7 @@ fn lower_item_kind(&mut self,
                                self.record_body(value, None))
             }
             ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
-                self.with_new_loop_scopes(|this| {
+                self.with_new_scopes(|this| {
                     let body = this.lower_block(body);
                     let body = this.expr_block(body, ThinVec::new());
                     let body_id = this.record_body(body, Some(decl));
@@ -1665,13 +1684,17 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                                       this.lower_opt_sp_ident(opt_ident),
                                       hir::LoopSource::Loop))
                 }
+                ExprKind::Catch(ref body) => {
+                    // FIXME(cramertj): Add catch to HIR
+                    self.with_catch_scope(e.id, |this| hir::ExprBlock(this.lower_block(body)))
+                }
                 ExprKind::Match(ref expr, ref arms) => {
                     hir::ExprMatch(P(self.lower_expr(expr)),
                                    arms.iter().map(|x| self.lower_arm(x)).collect(),
                                    hir::MatchSource::Normal)
                 }
                 ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => {
-                    self.with_new_loop_scopes(|this| {
+                    self.with_new_scopes(|this| {
                         this.with_parent_def(e.id, |this| {
                             let expr = this.lower_expr(body);
                             hir::ExprClosure(this.lower_capture_clause(capture_clause),
@@ -2069,6 +2092,12 @@ fn make_struct(this: &mut LoweringContext,
                     //     Err(err) => #[allow(unreachable_code)]
                     //                 return Carrier::from_error(From::from(err)),
                     // }
+
+                    // FIXME(cramertj): implement breaking to catch
+                    if !self.catch_scopes.is_empty() {
+                        bug!("`?` in catch scopes is unimplemented")
+                    }
+
                     let unstable_span = self.allow_internal_unstable("?", e.span);
 
                     // Carrier::translate(<expr>)
index 9810f121ef2c125570c4df911f625e6b7ae2510a..62d75126557284b806dcdf173c991fedf7c14bbb 100644 (file)
@@ -738,7 +738,7 @@ fn describe_lints(lint_store: &lint::LintStore, loaded_plugins: bool) {
               Allow <foo>
     -D <foo>           Deny <foo>
     -F <foo>           Forbid <foo> \
-              (deny, and deny all overrides)
+              (deny <foo> and all attempts to override)
 
 ");
 
index 0958748ed092fc88ffd76c61b5d2076a39cf29d7..104cc78597a4a501f89286355d633d99fc06fbfa 100644 (file)
@@ -407,7 +407,7 @@ enum PathSource<'a> {
     // Trait paths in bounds or impls.
     Trait,
     // Expression paths `path`, with optional parent context.
-    Expr(Option<&'a ExprKind>),
+    Expr(Option<&'a Expr>),
     // Paths in path patterns `Path`.
     Pat,
     // Paths in struct expressions and patterns `Path { .. }`.
@@ -464,7 +464,7 @@ fn descr_expected(self) -> &'static str {
                 ValueNS => "method or associated constant",
                 MacroNS => bug!("associated macro"),
             },
-            PathSource::Expr(parent) => match parent {
+            PathSource::Expr(parent) => match parent.map(|p| &p.node) {
                 // "function" here means "anything callable" rather than `Def::Fn`,
                 // this is not precise but usually more helpful than just "value".
                 Some(&ExprKind::Call(..)) => "function",
@@ -2200,7 +2200,8 @@ fn smart_resolve_path(&mut self,
                           source: PathSource)
                           -> PathResolution {
         let segments = &path.segments.iter().map(|seg| seg.identifier).collect::<Vec<_>>();
-        self.smart_resolve_path_fragment(id, qself, segments, path.span, source)
+        let ident_span = path.segments.last().map_or(path.span, |seg| seg.span);
+        self.smart_resolve_path_fragment(id, qself, segments, path.span, ident_span, source)
     }
 
     fn smart_resolve_path_fragment(&mut self,
@@ -2208,6 +2209,7 @@ fn smart_resolve_path_fragment(&mut self,
                                    qself: Option<&QSelf>,
                                    path: &[Ident],
                                    span: Span,
+                                   ident_span: Span,
                                    source: PathSource)
                                    -> PathResolution {
         let ns = source.namespace();
@@ -2219,9 +2221,9 @@ fn smart_resolve_path_fragment(&mut self,
             let expected = source.descr_expected();
             let path_str = names_to_string(path);
             let code = source.error_code(def.is_some());
-            let (base_msg, fallback_label) = if let Some(def) = def {
+            let (base_msg, fallback_label, base_span) = if let Some(def) = def {
                 (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str),
-                 format!("not a {}", expected))
+                 format!("not a {}", expected), span)
             } else {
                 let item_str = path[path.len() - 1];
                 let (mod_prefix, mod_str) = if path.len() == 1 {
@@ -2237,9 +2239,9 @@ fn smart_resolve_path_fragment(&mut self,
                     (mod_prefix, format!("`{}`", names_to_string(mod_path)))
                 };
                 (format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str),
-                 format!("not found in {}", mod_str))
+                 format!("not found in {}", mod_str), ident_span)
             };
-            let mut err = this.session.struct_span_err_with_code(span, &base_msg, code);
+            let mut err = this.session.struct_span_err_with_code(base_span, &base_msg, code);
 
             // Emit special messages for unresolved `Self` and `self`.
             if is_self_type(path, ns) {
@@ -2297,15 +2299,15 @@ fn smart_resolve_path_fragment(&mut self,
                         err.span_label(span, &format!("type aliases cannot be used for traits"));
                         return err;
                     }
-                    (Def::Mod(..), PathSource::Expr(Some(parent))) => match *parent {
+                    (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node {
                         ExprKind::Field(_, ident) => {
-                            err.span_label(span, &format!("did you mean `{}::{}`?",
-                                                           path_str, ident.node));
+                            err.span_label(parent.span, &format!("did you mean `{}::{}`?",
+                                                                 path_str, ident.node));
                             return err;
                         }
                         ExprKind::MethodCall(ident, ..) => {
-                            err.span_label(span, &format!("did you mean `{}::{}(...)`?",
-                                                           path_str, ident.node));
+                            err.span_label(parent.span, &format!("did you mean `{}::{}(...)`?",
+                                                                 path_str, ident.node));
                             return err;
                         }
                         _ => {}
@@ -2330,12 +2332,12 @@ fn smart_resolve_path_fragment(&mut self,
 
             // Try Levenshtein if nothing else worked.
             if let Some(candidate) = this.lookup_typo_candidate(path, ns, is_expected) {
-                err.span_label(span, &format!("did you mean `{}`?", candidate));
+                err.span_label(ident_span, &format!("did you mean `{}`?", candidate));
                 return err;
             }
 
             // Fallback label.
-            err.span_label(span, &fallback_label);
+            err.span_label(base_span, &fallback_label);
             err
         };
         let report_errors = |this: &mut Self, def: Option<Def>| {
@@ -2455,7 +2457,7 @@ fn resolve_qpath(&mut self,
             // Make sure `A::B` in `<T as A>::B::C` is a trait item.
             let ns = if qself.position + 1 == path.len() { ns } else { TypeNS };
             let res = self.smart_resolve_path_fragment(id, None, &path[..qself.position + 1],
-                                                       span, PathSource::TraitItem(ns));
+                                                       span, span, PathSource::TraitItem(ns));
             return Some(PathResolution::with_unresolved_segments(
                 res.base_def(), res.unresolved_segments() + path.len() - qself.position - 1
             ));
@@ -2813,7 +2815,7 @@ fn lookup_typo_candidate<FilterFn>(&mut self,
                                        path: &[Ident],
                                        ns: Namespace,
                                        filter_fn: FilterFn)
-                                       -> Option<String>
+                                       -> Option<Symbol>
         where FilterFn: Fn(Def) -> bool
     {
         let add_module_candidates = |module: Module, names: &mut Vec<Name>| {
@@ -2827,7 +2829,7 @@ fn lookup_typo_candidate<FilterFn>(&mut self,
         };
 
         let mut names = Vec::new();
-        let prefix_str = if path.len() == 1 {
+        if path.len() == 1 {
             // Search in lexical scope.
             // Walk backwards up the ribs in scope and collect candidates.
             for rib in self.ribs[ns].iter().rev() {
@@ -2861,21 +2863,19 @@ fn lookup_typo_candidate<FilterFn>(&mut self,
                     names.push(*name);
                 }
             }
-            String::new()
         } else {
             // Search in module.
             let mod_path = &path[..path.len() - 1];
             if let PathResult::Module(module) = self.resolve_path(mod_path, Some(TypeNS), None) {
                 add_module_candidates(module, &mut names);
             }
-            names_to_string(mod_path) + "::"
-        };
+        }
 
         let name = path[path.len() - 1].name;
         // Make sure error reporting is deterministic.
         names.sort_by_key(|name| name.as_str());
         match find_best_match_for_name(names.iter(), &name.as_str(), None) {
-            Some(found) if found != name => Some(format!("{}{}", prefix_str, found)),
+            Some(found) if found != name => Some(found),
             _ => None,
         }
     }
@@ -2898,7 +2898,7 @@ fn resolve_labeled_block(&mut self, label: Option<SpannedIdent>, id: NodeId, blo
         self.with_resolved_label(label, id, |this| this.visit_block(block));
     }
 
-    fn resolve_expr(&mut self, expr: &Expr, parent: Option<&ExprKind>) {
+    fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
         // First, record candidate traits for this expression if it could
         // result in the invocation of a method call.
 
@@ -2979,11 +2979,11 @@ fn resolve_expr(&mut self, expr: &Expr, parent: Option<&ExprKind>) {
 
             // Equivalent to `visit::walk_expr` + passing some context to children.
             ExprKind::Field(ref subexpression, _) => {
-                self.resolve_expr(subexpression, Some(&expr.node));
+                self.resolve_expr(subexpression, Some(expr));
             }
             ExprKind::MethodCall(_, ref types, ref arguments) => {
                 let mut arguments = arguments.iter();
-                self.resolve_expr(arguments.next().unwrap(), Some(&expr.node));
+                self.resolve_expr(arguments.next().unwrap(), Some(expr));
                 for argument in arguments {
                     self.resolve_expr(argument, None);
                 }
@@ -2999,7 +2999,7 @@ fn resolve_expr(&mut self, expr: &Expr, parent: Option<&ExprKind>) {
                 });
             }
             ExprKind::Call(ref callee, ref arguments) => {
-                self.resolve_expr(callee, Some(&expr.node));
+                self.resolve_expr(callee, Some(expr));
                 for argument in arguments {
                     self.resolve_expr(argument, None);
                 }
@@ -3130,11 +3130,10 @@ fn lookup_import_candidates<FilterFn>(&mut self,
                 if ident.name == lookup_name && ns == namespace {
                     if filter_fn(name_binding.def()) {
                         // create the path
-                        let span = name_binding.span;
                         let mut segms = path_segments.clone();
-                        segms.push(ident.into());
+                        segms.push(ast::PathSegment::from_ident(ident, name_binding.span));
                         let path = Path {
-                            span: span,
+                            span: name_binding.span,
                             segments: segms,
                         };
                         // the entity is accessible in the following cases:
@@ -3154,7 +3153,7 @@ fn lookup_import_candidates<FilterFn>(&mut self,
                 if let Some(module) = name_binding.module() {
                     // form the path
                     let mut path_segments = path_segments.clone();
-                    path_segments.push(ident.into());
+                    path_segments.push(ast::PathSegment::from_ident(ident, name_binding.span));
 
                     if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
                         // add the module to the lookup
index 7ad122d1c31d8d13373dfc90eff69071702beb7e..dbdf3a0b21e691119a593de08a0e566ba1c0cd55 100644 (file)
@@ -111,8 +111,11 @@ fn fold_path(&mut self, mut path: ast::Path) -> ast::Path {
                     path.segments[0].identifier.name = keywords::CrateRoot.name();
                     let module = self.0.resolve_crate_var(ident.ctxt);
                     if !module.is_local() {
+                        let span = path.segments[0].span;
                         path.segments.insert(1, match module.kind {
-                            ModuleKind::Def(_, name) => ast::Ident::with_empty_ctxt(name).into(),
+                            ModuleKind::Def(_, name) => ast::PathSegment::from_ident(
+                                ast::Ident::with_empty_ctxt(name), span
+                            ),
                             _ => unreachable!(),
                         })
                     }
@@ -569,7 +572,6 @@ fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
             };
             let ident = Ident::from_str(name);
             self.lookup_typo_candidate(&vec![ident], MacroNS, is_macro)
-                .as_ref().map(|s| Symbol::intern(s))
         });
 
         if let Some(suggestion) = suggestion {
index 34d8c6500b9263d325bb3251cff8202a9904caf4..9d40419d338b8a50b2a2f5322b897dd61314885b 100644 (file)
@@ -833,8 +833,21 @@ fn make_return_dest(&mut self, bcx: &Builder<'a, 'tcx>,
             self.trans_lvalue(bcx, dest)
         };
         if fn_ret_ty.is_indirect() {
-            llargs.push(dest.llval);
-            ReturnDest::Nothing
+            match dest.alignment {
+                Alignment::AbiAligned => {
+                    llargs.push(dest.llval);
+                    ReturnDest::Nothing
+                },
+                Alignment::Packed => {
+                    // Currently, MIR code generation does not create calls
+                    // that store directly to fields of packed structs (in
+                    // fact, the calls it creates write only to temps),
+                    //
+                    // If someone changes that, please update this code path
+                    // to create a temporary.
+                    span_bug!(self.mir.span, "can't directly store to unaligned value");
+                }
+            }
         } else {
             ReturnDest::Store(dest.llval)
         }
index cb77fcbbff85dbea7f015394b73f77cc494d202f..3f29545ecf45a16c2bf8c59607503ce69a903322 100644 (file)
@@ -268,10 +268,17 @@ pub fn store_operand(&mut self,
                 bcx.store(base::from_immediate(bcx, s), lldest, align);
             }
             OperandValue::Pair(a, b) => {
+                let f_align = match *bcx.ccx.layout_of(operand.ty) {
+                    Layout::Univariant { ref variant, .. } if variant.packed => {
+                        Some(1)
+                    }
+                    _ => align
+                };
+
                 let a = base::from_immediate(bcx, a);
                 let b = base::from_immediate(bcx, b);
-                bcx.store(a, bcx.struct_gep(lldest, 0), align);
-                bcx.store(b, bcx.struct_gep(lldest, 1), align);
+                bcx.store(a, bcx.struct_gep(lldest, 0), f_align);
+                bcx.store(b, bcx.struct_gep(lldest, 1), f_align);
             }
         }
     }
index 44f71d8952985b0098e482d561dad83d960969da..c571bcb08e4b7fc3c0c3e2d9758c2998c73029fa 100644 (file)
@@ -763,7 +763,7 @@ fn collect(path: &Path, krate: &str,
             // going on). If they're in different crates then the crate defining
             // the trait will be interested in our implementation.
             if imp.def_id.krate == did.krate { continue }
-            write!(implementors, r#""{}","#, imp.impl_).unwrap();
+            write!(implementors, "{},", as_json(&imp.impl_.to_string())).unwrap();
         }
         implementors.push_str("];");
 
index f9b0ec479d70115768328111f24537acbb979453..3ca8b41347a268c3ac3f65529ee09bf00506dd6c 100644 (file)
@@ -19,8 +19,9 @@
 use hash::{Hash, Hasher, BuildHasher, SipHasher13};
 use iter::{FromIterator, FusedIterator};
 use mem::{self, replace};
-use ops::{Deref, Index};
+use ops::{Deref, Index, InPlace, Place, Placer};
 use rand::{self, Rng};
+use ptr;
 
 use super::table::{self, Bucket, EmptyBucket, FullBucket, FullBucketMut, RawTable, SafeHash};
 use super::table::BucketState::{Empty, Full};
@@ -483,7 +484,7 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
                                 mut hash: SafeHash,
                                 mut key: K,
                                 mut val: V)
-                                -> &'a mut V {
+                                -> FullBucketMut<'a, K, V> {
     let start_index = bucket.index();
     let size = bucket.table().size();
     // Save the *starting point*.
@@ -515,7 +516,7 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
                     // bucket, which is a FullBucket on top of a
                     // FullBucketMut, into just one FullBucketMut. The "table"
                     // refers to the inner FullBucketMut in this context.
-                    return bucket.into_table().into_mut_refs().1;
+                    return bucket.into_table();
                 }
                 Full(bucket) => bucket,
             };
@@ -1818,6 +1819,80 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+/// A place for insertion to a `Entry`.
+///
+/// See [`HashMap::entry`](struct.HashMap.html#method.entry) for details.
+#[must_use = "places do nothing unless written to with `<-` syntax"]
+#[unstable(feature = "collection_placement",
+           reason = "struct name and placement protocol is subject to change",
+           issue = "30172")]
+pub struct EntryPlace<'a, K: 'a, V: 'a> {
+    bucket: FullBucketMut<'a, K, V>,
+}
+
+#[unstable(feature = "collection_placement",
+           reason = "struct name and placement protocol is subject to change",
+           issue = "30172")]
+impl<'a, K: 'a + Debug, V: 'a + Debug> Debug for EntryPlace<'a, K, V> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("EntryPlace")
+            .field("key", self.bucket.read().0)
+            .field("value", self.bucket.read().1)
+            .finish()
+    }
+}
+
+#[unstable(feature = "collection_placement",
+           reason = "struct name and placement protocol is subject to change",
+           issue = "30172")]
+impl<'a, K, V> Drop for EntryPlace<'a, K, V> {
+    fn drop(&mut self) {
+        // Inplacement insertion failed. Only key need to drop.
+        // The value is failed to insert into map.
+        unsafe { self.bucket.remove_key() };
+    }
+}
+
+#[unstable(feature = "collection_placement",
+           reason = "placement protocol is subject to change",
+           issue = "30172")]
+impl<'a, K, V> Placer<V> for Entry<'a, K, V> {
+    type Place = EntryPlace<'a, K, V>;
+
+    fn make_place(self) -> EntryPlace<'a, K, V> {
+        let b = match self {
+            Occupied(mut o) => {
+                unsafe { ptr::drop_in_place(o.elem.read_mut().1); }
+                o.elem
+            }
+            Vacant(v) => {
+                unsafe { v.insert_key() }
+            }
+        };
+        EntryPlace { bucket: b }
+    }
+}
+
+#[unstable(feature = "collection_placement",
+           reason = "placement protocol is subject to change",
+           issue = "30172")]
+impl<'a, K, V> Place<V> for EntryPlace<'a, K, V> {
+    fn pointer(&mut self) -> *mut V {
+        self.bucket.read_mut().1
+    }
+}
+
+#[unstable(feature = "collection_placement",
+           reason = "placement protocol is subject to change",
+           issue = "30172")]
+impl<'a, K, V> InPlace<V> for EntryPlace<'a, K, V> {
+    type Owner = ();
+
+    unsafe fn finalize(self) {
+        mem::forget(self);
+    }
+}
+
 impl<'a, K, V> Entry<'a, K, V> {
     #[stable(feature = "rust1", since = "1.0.0")]
     /// Ensures a value is in the entry by inserting the default if empty, and returns
@@ -2108,7 +2183,7 @@ pub fn into_key(self) -> K {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn insert(self, value: V) -> &'a mut V {
-        match self.elem {
+        let b = match self.elem {
             NeqElem(mut bucket, disp) => {
                 if disp >= DISPLACEMENT_THRESHOLD {
                     bucket.table_mut().set_tag(true);
@@ -2119,7 +2194,28 @@ pub fn insert(self, value: V) -> &'a mut V {
                 if disp >= DISPLACEMENT_THRESHOLD {
                     bucket.table_mut().set_tag(true);
                 }
-                bucket.put(self.hash, self.key, value).into_mut_refs().1
+                bucket.put(self.hash, self.key, value)
+            },
+        };
+        b.into_mut_refs().1
+    }
+
+    // Only used for InPlacement insert. Avoid unnecessary value copy.
+    // The value remains uninitialized.
+    unsafe fn insert_key(self) -> FullBucketMut<'a, K, V> {
+        match self.elem {
+            NeqElem(mut bucket, disp) => {
+                if disp >= DISPLACEMENT_THRESHOLD {
+                    bucket.table_mut().set_tag(true);
+                }
+                let uninit = mem::uninitialized();
+                robin_hood(bucket, disp, self.hash, self.key, uninit)
+            },
+            NoElem(mut bucket, disp) => {
+                if disp >= DISPLACEMENT_THRESHOLD {
+                    bucket.table_mut().set_tag(true);
+                }
+                bucket.put_key(self.hash, self.key)
             },
         }
     }
@@ -2392,6 +2488,7 @@ mod test_map {
     use super::RandomState;
     use cell::RefCell;
     use rand::{thread_rng, Rng};
+    use panic;
 
     #[test]
     fn test_zero_capacities() {
@@ -3265,4 +3362,57 @@ fn test_adaptive() {
         }
         panic!("Adaptive early resize failed");
     }
+
+    #[test]
+    fn test_placement_in() {
+        let mut map = HashMap::new();
+        map.extend((0..10).map(|i| (i, i)));
+
+        map.entry(100) <- 100;
+        assert_eq!(map[&100], 100);
+
+        map.entry(0) <- 10;
+        assert_eq!(map[&0], 10);
+
+        assert_eq!(map.len(), 11);
+    }
+
+    #[test]
+    fn test_placement_panic() {
+        let mut map = HashMap::new();
+        map.extend((0..10).map(|i| (i, i)));
+
+        fn mkpanic() -> usize { panic!() }
+
+        // modify existing key
+        // when panic happens, previous key is removed.
+        let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { map.entry(0) <- mkpanic(); }));
+        assert_eq!(map.len(), 9);
+        assert!(!map.contains_key(&0));
+
+        // add new key
+        let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { map.entry(100) <- mkpanic(); }));
+        assert_eq!(map.len(), 9);
+        assert!(!map.contains_key(&100));
+    }
+
+    #[test]
+    fn test_placement_drop() {
+        // correctly drop
+        struct TestV<'a>(&'a mut bool);
+        impl<'a> Drop for TestV<'a> {
+            fn drop(&mut self) {
+                if !*self.0 { panic!("value double drop!"); } // no double drop
+                *self.0 = false;
+            }
+        }
+
+        fn makepanic<'a>() -> TestV<'a> { panic!() }
+
+        let mut can_drop = true;
+        let mut hm = HashMap::new();
+        hm.insert(0, TestV(&mut can_drop));
+        let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { hm.entry(0) <- makepanic(); }));
+        assert_eq!(hm.len(), 0);
+    }
 }
index 0e225b2964f63752246b7a30d6fc26096b425e98..2c8bb433e8aef1ba1fd65a5d3948802be26293e8 100644 (file)
@@ -506,6 +506,22 @@ pub fn put(mut self, hash: SafeHash, key: K, value: V) -> FullBucket<K, V, M> {
             table: self.table,
         }
     }
+
+    /// Puts given key, remain value uninitialized.
+    /// It is only used for inplacement insertion.
+    pub unsafe fn put_key(mut self, hash: SafeHash, key: K) -> FullBucket<K, V, M> {
+        *self.raw.hash = hash.inspect();
+        let pair_mut = self.raw.pair as *mut (K, V);
+        ptr::write(&mut (*pair_mut).0, key);
+
+        self.table.borrow_table_mut().size += 1;
+
+        FullBucket {
+            raw: self.raw,
+            idx: self.idx,
+            table: self.table,
+        }
+    }
 }
 
 impl<K, V, M: Deref<Target = RawTable<K, V>>> FullBucket<K, V, M> {
@@ -581,6 +597,17 @@ pub fn take(mut self) -> (EmptyBucket<K, V, &'t mut RawTable<K, V>>, K, V) {
             v)
         }
     }
+
+    /// Remove this bucket's `key` from the hashtable.
+    /// Only used for inplacement insertion.
+    /// NOTE: `Value` is uninitialized when this function is called, don't try to drop the `Value`.
+    pub unsafe fn remove_key(&mut self) {
+        self.table.size -= 1;
+
+        *self.raw.hash = EMPTY_BUCKET;
+        let pair_mut = self.raw.pair as *mut (K, V);
+        ptr::drop_in_place(&mut (*pair_mut).0); // only drop key
+    }
 }
 
 // This use of `Put` is misleading and restrictive, but safe and sufficient for our use cases
index bfb0aa6e1a122410e6fe6acfd1e9b612e2c76710..2d14bb66bf4f976e6016832f1ff17050d008fe9c 100644 (file)
@@ -325,7 +325,7 @@ pub fn as_bytes_with_nul(&self) -> &[u8] {
     }
 
     /// Converts this `CString` into a boxed `CStr`.
-    #[unstable(feature = "into_boxed_c_str", issue = "0")]
+    #[unstable(feature = "into_boxed_c_str", issue = "40380")]
     pub fn into_boxed_c_str(self) -> Box<CStr> {
         unsafe { mem::transmute(self.into_inner()) }
     }
@@ -415,6 +415,20 @@ fn from(s: &'a CStr) -> Box<CStr> {
     }
 }
 
+#[stable(feature = "c_string_from_box", since = "1.17.0")]
+impl From<Box<CStr>> for CString {
+    fn from(s: Box<CStr>) -> CString {
+        s.into_c_string()
+    }
+}
+
+#[stable(feature = "box_from_c_string", since = "1.17.0")]
+impl Into<Box<CStr>> for CString {
+    fn into(self) -> Box<CStr> {
+        self.into_boxed_c_str()
+    }
+}
+
 #[stable(feature = "default_box_extra", since = "1.17.0")]
 impl Default for Box<CStr> {
     fn default() -> Box<CStr> {
@@ -728,6 +742,12 @@ pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
     pub fn to_string_lossy(&self) -> Cow<str> {
         String::from_utf8_lossy(self.to_bytes())
     }
+
+    /// Converts a `Box<CStr>` into a `CString` without copying or allocating.
+    #[unstable(feature = "into_boxed_c_str", issue = "40380")]
+    pub fn into_c_string(self: Box<CStr>) -> CString {
+        unsafe { mem::transmute(self) }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -922,12 +942,11 @@ fn from_bytes_with_nul_interior() {
     fn into_boxed() {
         let orig: &[u8] = b"Hello, world!\0";
         let cstr = CStr::from_bytes_with_nul(orig).unwrap();
-        let cstring = cstr.to_owned();
-        let box1: Box<CStr> = Box::from(cstr);
-        let box2 = cstring.into_boxed_c_str();
-        assert_eq!(cstr, &*box1);
-        assert_eq!(box1, box2);
-        assert_eq!(&*box2, cstr);
+        let boxed: Box<CStr> = Box::from(cstr);
+        let cstring = cstr.to_owned().into_boxed_c_str().into_c_string();
+        assert_eq!(cstr, &*boxed);
+        assert_eq!(&*boxed, &*cstring);
+        assert_eq!(&*cstring, cstr);
     }
 
     #[test]
index 41bdd9c51d458e1c9d85f34cfdd1f0cc1ec6386a..2765fd83ed554027cb213cb07f484540ca91f085 100644 (file)
@@ -212,7 +212,7 @@ pub fn shrink_to_fit(&mut self) {
     }
 
     /// Converts this `OsString` into a boxed `OsStr`.
-    #[unstable(feature = "into_boxed_os_str", issue = "0")]
+    #[unstable(feature = "into_boxed_os_str", issue = "40380")]
     pub fn into_boxed_os_str(self) -> Box<OsStr> {
         unsafe { mem::transmute(self.inner.into_box()) }
     }
@@ -448,6 +448,13 @@ pub fn len(&self) -> usize {
         self.inner.inner.len()
     }
 
+    /// Converts a `Box<OsStr>` into an `OsString` without copying or allocating.
+    #[unstable(feature = "into_boxed_os_str", issue = "40380")]
+    pub fn into_os_string(self: Box<OsStr>) -> OsString {
+        let inner: Box<Slice> = unsafe { mem::transmute(self) };
+        OsString { inner: Buf::from_box(inner) }
+    }
+
     /// Gets the underlying byte representation.
     ///
     /// Note: it is *crucial* that this API is private, to avoid
@@ -464,6 +471,20 @@ fn from(s: &'a OsStr) -> Box<OsStr> {
     }
 }
 
+#[stable(feature = "os_string_from_box", since = "1.17.0")]
+impl<'a> From<Box<OsStr>> for OsString {
+    fn from(boxed: Box<OsStr>) -> OsString {
+        boxed.into_os_string()
+    }
+}
+
+#[stable(feature = "box_from_c_string", since = "1.17.0")]
+impl Into<Box<OsStr>> for OsString {
+    fn into(self) -> Box<OsStr> {
+        self.into_boxed_os_str()
+    }
+}
+
 #[stable(feature = "box_default_extra", since = "1.17.0")]
 impl Default for Box<OsStr> {
     fn default() -> Box<OsStr> {
@@ -772,12 +793,11 @@ fn test_os_str_default() {
     fn into_boxed() {
         let orig = "Hello, world!";
         let os_str = OsStr::new(orig);
-        let os_string = os_str.to_owned();
-        let box1: Box<OsStr> = Box::from(os_str);
-        let box2 = os_string.into_boxed_os_str();
-        assert_eq!(os_str, &*box1);
-        assert_eq!(box1, box2);
-        assert_eq!(&*box2, os_str);
+        let boxed: Box<OsStr> = Box::from(os_str);
+        let os_string = os_str.to_owned().into_boxed_os_str().into_os_string();
+        assert_eq!(os_str, &*boxed);
+        assert_eq!(&*boxed, &*os_string);
+        assert_eq!(&*os_string, os_str);
     }
 
     #[test]
index e5562d05f10ae92472aebb2a3fbe2c114f82f372..b074e8b86b9a329f6068d84ce55cf07b6fd35a17 100644 (file)
@@ -142,14 +142,14 @@ pub struct File {
 /// [`File::open`]: struct.File.html#method.open
 /// [`File::create`]: struct.File.html#method.create
 ///
-/// Generally speaking, when using `OpenOptions`, you'll first call [`new()`],
-/// then chain calls to methods to set each option, then call [`open()`],
+/// Generally speaking, when using `OpenOptions`, you'll first call [`new`],
+/// then chain calls to methods to set each option, then call [`open`],
 /// passing the path of the file you're trying to open. This will give you a
 /// [`io::Result`][result] with a [`File`][file] inside that you can further
 /// operate on.
 ///
-/// [`new()`]: struct.OpenOptions.html#method.new
-/// [`open()`]: struct.OpenOptions.html#method.open
+/// [`new`]: struct.OpenOptions.html#method.new
+/// [`open`]: struct.OpenOptions.html#method.open
 /// [result]: ../io/type.Result.html
 /// [file]: struct.File.html
 ///
index 6d4da2e6a88cff93ae7c7ee390a370aac5ccf54c..fb67eaf3c63a903f4c2b4eb9b994539c04c688f7 100644 (file)
@@ -140,13 +140,13 @@ pub enum ErrorKind {
     #[stable(feature = "rust1", since = "1.0.0")]
     TimedOut,
     /// An error returned when an operation could not be completed because a
-    /// call to [`write()`] returned [`Ok(0)`].
+    /// call to [`write`] returned [`Ok(0)`].
     ///
     /// This typically means that an operation could only succeed if it wrote a
     /// particular number of bytes but only a smaller number of bytes could be
     /// written.
     ///
-    /// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
+    /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
     /// [`Ok(0)`]: ../../std/io/type.Result.html
     #[stable(feature = "rust1", since = "1.0.0")]
     WriteZero,
index 58788cdcd4c7c4eb9d521789e7b2beacb506fdc9..850885a8c0f3aaf76799ab398ce79bf132f8e00f 100644 (file)
@@ -21,7 +21,7 @@
 //! of other types, and you can implement them for your types too. As such,
 //! you'll see a few different types of I/O throughout the documentation in
 //! this module: [`File`]s, [`TcpStream`]s, and sometimes even [`Vec<T>`]s. For
-//! example, [`Read`] adds a [`read()`] method, which we can use on `File`s:
+//! example, [`Read`] adds a [`read`] method, which we can use on `File`s:
 //!
 //! ```
 //! use std::io;
 //! ```
 //!
 //! [`BufWriter`] doesn't add any new ways of writing; it just buffers every call
-//! to [`write()`]:
+//! to [`write`]:
 //!
 //! ```
 //! use std::io;
 //! # }
 //! ```
 //!
-//! Of course, using [`io::stdout()`] directly is less common than something like
+//! Of course, using [`io::stdout`] directly is less common than something like
 //! [`println!`].
 //!
 //! ## Iterator types
 //! [`Vec<T>`]: ../vec/struct.Vec.html
 //! [`BufReader`]: struct.BufReader.html
 //! [`BufWriter`]: struct.BufWriter.html
-//! [`write()`]: trait.Write.html#tymethod.write
-//! [`io::stdout()`]: fn.stdout.html
+//! [`write`]: trait.Write.html#tymethod.write
+//! [`io::stdout`]: fn.stdout.html
 //! [`println!`]: ../macro.println.html
 //! [`Lines`]: struct.Lines.html
 //! [`io::Result`]: type.Result.html
 //! [`?` operator]: ../../book/syntax-index.html
-//! [`read()`]: trait.Read.html#tymethod.read
+//! [`read`]: trait.Read.html#tymethod.read
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -530,7 +530,7 @@ fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
     /// If the data in this stream is *not* valid UTF-8 then an error is
     /// returned and `buf` is unchanged.
     ///
-    /// See [`read_to_end()`][readtoend] for other error semantics.
+    /// See [`read_to_end`][readtoend] for other error semantics.
     ///
     /// [readtoend]: #method.read_to_end
     ///
@@ -815,12 +815,12 @@ fn take(self, limit: u64) -> Take<Self> where Self: Sized {
 ///
 /// Implementors of the `Write` trait are sometimes called 'writers'.
 ///
-/// Writers are defined by two required methods, [`write()`] and [`flush()`]:
+/// Writers are defined by two required methods, [`write`] and [`flush`]:
 ///
-/// * The [`write()`] method will attempt to write some data into the object,
+/// * The [`write`] method will attempt to write some data into the object,
 ///   returning how many bytes were successfully written.
 ///
-/// * The [`flush()`] method is useful for adaptors and explicit buffers
+/// * The [`flush`] method is useful for adaptors and explicit buffers
 ///   themselves for ensuring that all buffered data has been pushed out to the
 ///   'true sink'.
 ///
@@ -828,8 +828,8 @@ fn take(self, limit: u64) -> Take<Self> where Self: Sized {
 /// throughout [`std::io`] take and provide types which implement the `Write`
 /// trait.
 ///
-/// [`write()`]: #tymethod.write
-/// [`flush()`]: #tymethod.flush
+/// [`write`]: #tymethod.write
+/// [`flush`]: #tymethod.flush
 /// [`std::io`]: index.html
 ///
 /// # Examples
@@ -1159,7 +1159,7 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
 ///
 /// For example, reading line-by-line is inefficient without using a buffer, so
 /// if you want to read by line, you'll need `BufRead`, which includes a
-/// [`read_line()`] method as well as a [`lines()`] iterator.
+/// [`read_line`] method as well as a [`lines`] iterator.
 ///
 /// # Examples
 ///
@@ -1183,8 +1183,8 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
 ///
 /// [`BufReader`]: struct.BufReader.html
 /// [`File`]: ../fs/struct.File.html
-/// [`read_line()`]: #method.read_line
-/// [`lines()`]: #method.lines
+/// [`read_line`]: #method.read_line
+/// [`lines`]: #method.lines
 /// [`Read`]: trait.Read.html
 ///
 /// ```
@@ -1209,13 +1209,13 @@ pub trait BufRead: Read {
     /// Fills the internal buffer of this object, returning the buffer contents.
     ///
     /// This function is a lower-level call. It needs to be paired with the
-    /// [`consume()`] method to function properly. When calling this
+    /// [`consume`] method to function properly. When calling this
     /// method, none of the contents will be "read" in the sense that later
-    /// calling `read` may return the same contents. As such, [`consume()`] must
+    /// calling `read` may return the same contents. As such, [`consume`] must
     /// be called with the number of bytes that are consumed from this buffer to
     /// ensure that the bytes are never returned twice.
     ///
-    /// [`consume()`]: #tymethod.consume
+    /// [`consume`]: #tymethod.consume
     ///
     /// An empty buffer returned indicates that the stream has reached EOF.
     ///
@@ -1256,21 +1256,21 @@ pub trait BufRead: Read {
     /// so they should no longer be returned in calls to `read`.
     ///
     /// This function is a lower-level call. It needs to be paired with the
-    /// [`fill_buf()`] method to function properly. This function does
+    /// [`fill_buf`] method to function properly. This function does
     /// not perform any I/O, it simply informs this object that some amount of
-    /// its buffer, returned from [`fill_buf()`], has been consumed and should
+    /// its buffer, returned from [`fill_buf`], has been consumed and should
     /// no longer be returned. As such, this function may do odd things if
-    /// [`fill_buf()`] isn't called before calling it.
+    /// [`fill_buf`] isn't called before calling it.
     ///
     /// The `amt` must be `<=` the number of bytes in the buffer returned by
-    /// [`fill_buf()`].
+    /// [`fill_buf`].
     ///
     /// # Examples
     ///
-    /// Since `consume()` is meant to be used with [`fill_buf()`],
+    /// Since `consume()` is meant to be used with [`fill_buf`],
     /// that method's example includes an example of `consume()`.
     ///
-    /// [`fill_buf()`]: #tymethod.fill_buf
+    /// [`fill_buf`]: #tymethod.fill_buf
     #[stable(feature = "rust1", since = "1.0.0")]
     fn consume(&mut self, amt: usize);
 
@@ -1285,7 +1285,7 @@ pub trait BufRead: Read {
     /// # Errors
     ///
     /// This function will ignore all instances of [`ErrorKind::Interrupted`] and
-    /// will otherwise return any errors returned by [`fill_buf()`].
+    /// will otherwise return any errors returned by [`fill_buf`].
     ///
     /// 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.
@@ -1295,7 +1295,7 @@ pub trait BufRead: Read {
     /// 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
+    /// [`fill_buf`]: #tymethod.fill_buf
     /// [`ErrorKind::Interrupted`]: enum.ErrorKind.html#variant.Interrupted
     ///
     /// ```
@@ -1330,7 +1330,7 @@ fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
     ///
     /// # Errors
     ///
-    /// This function has the same error semantics as [`read_until()`] and will
+    /// This function has the same error semantics as [`read_until`] and will
     /// also return an error if the read bytes are not valid UTF-8. If an I/O
     /// error is encountered then `buf` may contain some bytes already read in
     /// the event that all data read so far was valid UTF-8.
@@ -1339,11 +1339,11 @@ fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
     ///
     /// 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
+    /// an actual project, the [`lines`] method would be easier, of
     /// course.
     ///
-    /// [`lines()`]: #method.lines
-    /// [`read_until()`]: #method.read_until
+    /// [`lines`]: #method.lines
+    /// [`read_until`]: #method.read_until
     ///
     /// ```
     /// use std::io;
@@ -1375,7 +1375,7 @@ fn read_line(&mut self, buf: &mut String) -> Result<usize> {
     /// [`io::Result`]`<`[`Vec<u8>`]`>`. Each vector returned will *not* have
     /// the delimiter byte at the end.
     ///
-    /// This function will yield errors whenever [`read_until()`] would have
+    /// This function will yield errors whenever [`read_until`] would have
     /// also yielded an error.
     ///
     /// # Examples
@@ -1385,7 +1385,7 @@ fn read_line(&mut self, buf: &mut String) -> Result<usize> {
     ///
     /// [`io::Result`]: type.Result.html
     /// [`Vec<u8>`]: ../vec/struct.Vec.html
-    /// [`read_until()`]: #method.read_until
+    /// [`read_until`]: #method.read_until
     ///
     /// ```
     /// use std::io;
@@ -1428,9 +1428,9 @@ fn split(self, byte: u8) -> Split<Self> where Self: Sized {
     ///
     /// # Errors
     ///
-    /// Each line of the iterator has the same error semantics as [`BufRead::read_line()`].
+    /// Each line of the iterator has the same error semantics as [`BufRead::read_line`].
     ///
-    /// [`BufRead::read_line()`]: trait.BufRead.html#method.read_line
+    /// [`BufRead::read_line`]: trait.BufRead.html#method.read_line
     #[stable(feature = "rust1", since = "1.0.0")]
     fn lines(self) -> Lines<Self> where Self: Sized {
         Lines { buf: self }
@@ -1439,10 +1439,10 @@ fn lines(self) -> Lines<Self> where Self: Sized {
 
 /// Adaptor to chain together two readers.
 ///
-/// This struct is generally created by calling [`chain()`] on a reader.
-/// Please see the documentation of [`chain()`] for more details.
+/// This struct is generally created by calling [`chain`] on a reader.
+/// Please see the documentation of [`chain`] for more details.
 ///
-/// [`chain()`]: trait.Read.html#method.chain
+/// [`chain`]: trait.Read.html#method.chain
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Chain<T, U> {
     first: T,
@@ -1496,10 +1496,10 @@ fn consume(&mut self, amt: usize) {
 
 /// Reader adaptor which limits the bytes read from an underlying reader.
 ///
-/// This struct is generally created by calling [`take()`] on a reader.
-/// Please see the documentation of [`take()`] for more details.
+/// This struct is generally created by calling [`take`] on a reader.
+/// Please see the documentation of [`take`] for more details.
 ///
-/// [`take()`]: trait.Read.html#method.take
+/// [`take`]: trait.Read.html#method.take
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 pub struct Take<T> {
@@ -1614,10 +1614,10 @@ fn read_one_byte(reader: &mut Read) -> Option<Result<u8>> {
 
 /// An iterator over `u8` values of a reader.
 ///
-/// This struct is generally created by calling [`bytes()`] on a reader.
-/// Please see the documentation of [`bytes()`] for more details.
+/// This struct is generally created by calling [`bytes`] on a reader.
+/// Please see the documentation of [`bytes`] for more details.
 ///
-/// [`bytes()`]: trait.Read.html#method.bytes
+/// [`bytes`]: trait.Read.html#method.bytes
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 pub struct Bytes<R> {
@@ -1635,7 +1635,7 @@ fn next(&mut self) -> Option<Result<u8>> {
 
 /// An iterator over the `char`s of a reader.
 ///
-/// This struct is generally created by calling [`chars()`][chars] on a reader.
+/// This struct is generally created by calling [`chars`][chars] on a reader.
 /// Please see the documentation of `chars()` for more details.
 ///
 /// [chars]: trait.Read.html#method.chars
@@ -1726,7 +1726,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// An iterator over the contents of an instance of `BufRead` split on a
 /// particular byte.
 ///
-/// This struct is generally created by calling [`split()`][split] on a
+/// This struct is generally created by calling [`split`][split] on a
 /// `BufRead`. Please see the documentation of `split()` for more details.
 ///
 /// [split]: trait.BufRead.html#method.split
@@ -1758,7 +1758,7 @@ fn next(&mut self) -> Option<Result<Vec<u8>>> {
 
 /// An iterator over the lines of an instance of `BufRead`.
 ///
-/// This struct is generally created by calling [`lines()`][lines] on a
+/// This struct is generally created by calling [`lines`][lines] on a
 /// `BufRead`. Please see the documentation of `lines()` for more details.
 ///
 /// [lines]: trait.BufRead.html#method.lines
index e16e8019b5f735fb6e2af5192363d2941bf6b869..38ad23e14b3ebc01a174787c05a06a1b94687094 100644 (file)
@@ -332,11 +332,11 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 ///
 /// Each handle shares a global buffer of data to be written to the standard
 /// output stream. Access is also synchronized via a lock and explicit control
-/// over locking is available via the [`lock()`] method.
+/// over locking is available via the [`lock`] method.
 ///
 /// Created by the [`io::stdout`] method.
 ///
-/// [`lock()`]: #method.lock
+/// [`lock`]: #method.lock
 /// [`io::stdout`]: fn.stdout.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stdout {
index 4163187488e6544d378808bde18689977623edf3..078f1ad3f6cfe5b0410e027aa5b8649127c55deb 100644 (file)
@@ -63,7 +63,7 @@ pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<
 
 /// A reader which is always at EOF.
 ///
-/// This struct is generally created by calling [`empty()`][empty]. Please see
+/// This struct is generally created by calling [`empty`][empty]. Please see
 /// the documentation of `empty()` for more details.
 ///
 /// [empty]: fn.empty.html
@@ -107,7 +107,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 /// A reader which yields one byte over and over and over and over and over and...
 ///
-/// This struct is generally created by calling [`repeat()`][repeat]. Please
+/// This struct is generally created by calling [`repeat`][repeat]. Please
 /// see the documentation of `repeat()` for more details.
 ///
 /// [repeat]: fn.repeat.html
@@ -150,7 +150,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 /// A writer which will move data into the void.
 ///
-/// This struct is generally created by calling [`sink()`][sink]. Please
+/// This struct is generally created by calling [`sink`][sink]. Please
 /// see the documentation of `sink()` for more details.
 ///
 /// [sink]: fn.sink.html
index 070690773b6c4792a05dc525ce790c9d1cdc72ce..2c83518d38880f093d2869eb6be37f4595c62c1f 100644 (file)
@@ -21,7 +21,7 @@
 //! contained an `extern crate std;` import at the [crate root]. Therefore the
 //! standard library can be accessed in [`use`] statements through the path
 //! `std`, as in [`use std::env`], or in expressions through the absolute path
-//! `::std`, as in [`::std::env::args()`].
+//! `::std`, as in [`::std::env::args`].
 //!
 //! # How to read this documentation
 //!
 //! [TCP]: net/struct.TcpStream.html
 //! [The Rust Prelude]: prelude/index.html
 //! [UDP]: net/struct.UdpSocket.html
-//! [`::std::env::args()`]: env/fn.args.html
+//! [`::std::env::args`]: env/fn.args.html
 //! [`Arc`]: sync/struct.Arc.html
 //! [owned slice]: boxed/index.html
 //! [`Cell`]: cell/struct.Cell.html
 #![feature(panic_unwind)]
 #![feature(peek)]
 #![feature(placement_in_syntax)]
+#![feature(placement_new_protocol)]
 #![feature(prelude_import)]
 #![feature(pub_restricted)]
 #![feature(rand)]
index 9bead22ef7f5e0516267712a326b3c465671e159..a07972468e68a3afdfeff1d871d15ea413791fbb 100644 (file)
@@ -183,7 +183,7 @@ pub fn try_clone(&self) -> io::Result<TcpStream> {
 
     /// Sets the read timeout to the timeout specified.
     ///
-    /// If the value specified is [`None`], then [`read()`] calls will block
+    /// If the value specified is [`None`], then [`read`] calls will block
     /// indefinitely. It is an error to pass the zero `Duration` to this
     /// method.
     ///
@@ -194,7 +194,7 @@ pub fn try_clone(&self) -> io::Result<TcpStream> {
     /// error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`read()`]: ../../std/io/trait.Read.html#tymethod.read
+    /// [`read`]: ../../std/io/trait.Read.html#tymethod.read
     /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
     /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
     ///
@@ -214,7 +214,7 @@ pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
 
     /// Sets the write timeout to the timeout specified.
     ///
-    /// If the value specified is [`None`], then [`write()`] calls will block
+    /// If the value specified is [`None`], then [`write`] calls will block
     /// indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
     ///
@@ -225,7 +225,7 @@ pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
     /// an error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
+    /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
     /// [`Duration`]: ../../std/time/struct.Duration.html
     /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
     /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
@@ -246,14 +246,14 @@ pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
 
     /// Returns the read timeout of this socket.
     ///
-    /// If the timeout is [`None`], then [`read()`] calls will block indefinitely.
+    /// If the timeout is [`None`], then [`read`] calls will block indefinitely.
     ///
     /// # Note
     ///
     /// Some platforms do not provide access to the current timeout.
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`read()`]: ../../std/io/trait.Read.html#tymethod.read
+    /// [`read`]: ../../std/io/trait.Read.html#tymethod.read
     ///
     /// # Examples
     ///
@@ -272,14 +272,14 @@ pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
 
     /// Returns the write timeout of this socket.
     ///
-    /// If the timeout is [`None`], then [`write()`] calls will block indefinitely.
+    /// If the timeout is [`None`], then [`write`] calls will block indefinitely.
     ///
     /// # Note
     ///
     /// Some platforms do not provide access to the current timeout.
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
+    /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
     ///
     /// # Examples
     ///
@@ -618,7 +618,7 @@ pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
 
     /// Gets the value of the `IP_TTL` option for this socket.
     ///
-    /// For more information about this option, see [`set_ttl()`][link].
+    /// For more information about this option, see [`set_ttl`][link].
     ///
     /// [link]: #method.set_ttl
     ///
index f452c75d389664ed90bf0da30aa2066ec12a7086..1ebce939348401d5087250e7cd365a092b717614 100644 (file)
@@ -175,7 +175,7 @@ pub fn try_clone(&self) -> io::Result<UdpSocket> {
 
     /// Sets the read timeout to the timeout specified.
     ///
-    /// If the value specified is [`None`], then [`read()`] calls will block
+    /// If the value specified is [`None`], then [`read`] calls will block
     /// indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
     ///
@@ -186,7 +186,7 @@ pub fn try_clone(&self) -> io::Result<UdpSocket> {
     /// error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`read()`]: ../../std/io/trait.Read.html#tymethod.read
+    /// [`read`]: ../../std/io/trait.Read.html#tymethod.read
     /// [`Duration`]: ../../std/time/struct.Duration.html
     /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
     /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
@@ -206,7 +206,7 @@ pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
 
     /// Sets the write timeout to the timeout specified.
     ///
-    /// If the value specified is [`None`], then [`write()`] calls will block
+    /// If the value specified is [`None`], then [`write`] calls will block
     /// indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
     ///
@@ -217,7 +217,7 @@ pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
     /// an error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
+    /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
     /// [`Duration`]: ../../std/time/struct.Duration.html
     /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
     /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
@@ -237,10 +237,10 @@ pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
 
     /// Returns the read timeout of this socket.
     ///
-    /// If the timeout is [`None`], then [`read()`] calls will block indefinitely.
+    /// If the timeout is [`None`], then [`read`] calls will block indefinitely.
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`read()`]: ../../std/io/trait.Read.html#tymethod.read
+    /// [`read`]: ../../std/io/trait.Read.html#tymethod.read
     ///
     /// # Examples
     ///
@@ -258,10 +258,10 @@ pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
 
     /// Returns the write timeout of this socket.
     ///
-    /// If the timeout is [`None`], then [`write()`] calls will block indefinitely.
+    /// If the timeout is [`None`], then [`write`] calls will block indefinitely.
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
+    /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
     ///
     /// # Examples
     ///
@@ -560,10 +560,10 @@ pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
 
     /// Sends data on the socket to 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
+    /// [`connect`]: #method.connect
     ///
     /// # Examples
     ///
index 3b5a1cffc7a2203dd7b7c8b9a52c720652396166..6f46a73698f35c49d5f4ef43f6bd939c8ef9422f 100644 (file)
@@ -160,10 +160,10 @@ pub fn take_hook() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
 
 /// A struct providing information about a panic.
 ///
-/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook()`]
+/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`]
 /// function.
 ///
-/// [`set_hook()`]: ../../std/panic/fn.set_hook.html
+/// [`set_hook`]: ../../std/panic/fn.set_hook.html
 ///
 /// # Examples
 ///
@@ -237,9 +237,9 @@ pub fn location(&self) -> Option<&Location> {
 
 /// A struct containing information about the location of a panic.
 ///
-/// This structure is created by the [`location()`] method of [`PanicInfo`].
+/// This structure is created by the [`location`] method of [`PanicInfo`].
 ///
-/// [`location()`]: ../../std/panic/struct.PanicInfo.html#method.location
+/// [`location`]: ../../std/panic/struct.PanicInfo.html#method.location
 /// [`PanicInfo`]: ../../std/panic/struct.PanicInfo.html
 ///
 /// # Examples
index 245a6d945b5a320c330adbc6391f8a5cb4f54ba3..8f1c2ae0c8daa187e8e91fa98efba5e9d4d1c3c6 100644 (file)
@@ -1065,13 +1065,13 @@ fn _push(&mut self, path: &Path) {
         self.inner.push(path);
     }
 
-    /// Truncate `self` to [`self.parent()`].
+    /// Truncate `self` to [`self.parent`].
     ///
-    /// Returns false and does nothing if [`self.file_name()`] is `None`.
+    /// Returns false and does nothing if [`self.file_name`] is `None`.
     /// Otherwise, returns `true`.
     ///
-    /// [`self.parent()`]: struct.PathBuf.html#method.parent
-    /// [`self.file_name()`]: struct.PathBuf.html#method.file_name
+    /// [`self.parent`]: struct.PathBuf.html#method.parent
+    /// [`self.file_name`]: struct.PathBuf.html#method.file_name
     ///
     /// # Examples
     ///
@@ -1096,12 +1096,12 @@ pub fn pop(&mut self) -> bool {
         }
     }
 
-    /// Updates [`self.file_name()`] to `file_name`.
+    /// Updates [`self.file_name`] to `file_name`.
     ///
-    /// If [`self.file_name()`] was [`None`], this is equivalent to pushing
+    /// If [`self.file_name`] was [`None`], this is equivalent to pushing
     /// `file_name`.
     ///
-    /// [`self.file_name()`]: struct.PathBuf.html#method.file_name
+    /// [`self.file_name`]: struct.PathBuf.html#method.file_name
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
     ///
     /// # Examples
@@ -1130,15 +1130,15 @@ fn _set_file_name(&mut self, file_name: &OsStr) {
         self.push(file_name);
     }
 
-    /// Updates [`self.extension()`] to `extension`.
+    /// Updates [`self.extension`] to `extension`.
     ///
-    /// If [`self.file_name()`] is `None`, does nothing and returns `false`.
+    /// If [`self.file_name`] is `None`, does nothing and returns `false`.
     ///
-    /// Otherwise, returns `true`; if [`self.extension()`] is [`None`], the
+    /// Otherwise, returns `true`; if [`self.extension`] is [`None`], the
     /// extension is added; otherwise it is replaced.
     ///
-    /// [`self.file_name()`]: struct.PathBuf.html#method.file_name
-    /// [`self.extension()`]: struct.PathBuf.html#method.extension
+    /// [`self.file_name`]: struct.PathBuf.html#method.file_name
+    /// [`self.extension`]: struct.PathBuf.html#method.extension
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
     ///
     /// # Examples
@@ -1196,7 +1196,7 @@ pub fn into_os_string(self) -> OsString {
     }
 
     /// Converts this `PathBuf` into a boxed `Path`.
-    #[unstable(feature = "into_boxed_path", issue = "0")]
+    #[unstable(feature = "into_boxed_path", issue = "40380")]
     pub fn into_boxed_path(self) -> Box<Path> {
         unsafe { mem::transmute(self.inner.into_boxed_os_str()) }
     }
@@ -1210,6 +1210,20 @@ fn from(path: &'a Path) -> Box<Path> {
     }
 }
 
+#[stable(feature = "path_buf_from_box", since = "1.17.0")]
+impl<'a> From<Box<Path>> for PathBuf {
+    fn from(boxed: Box<Path>) -> PathBuf {
+        boxed.into_path_buf()
+    }
+}
+
+#[stable(feature = "box_from_path_buf", since = "1.17.0")]
+impl Into<Box<Path>> for PathBuf {
+    fn into(self) -> Box<Path> {
+        self.into_boxed_path()
+    }
+}
+
 #[stable(feature = "box_default_extra", since = "1.17.0")]
 impl Default for Box<Path> {
     fn default() -> Box<Path> {
@@ -1733,9 +1747,9 @@ fn _ends_with(&self, child: &Path) -> bool {
         iter_after(self.components().rev(), child.components().rev()).is_some()
     }
 
-    /// Extracts the stem (non-extension) portion of [`self.file_name()`].
+    /// Extracts the stem (non-extension) portion of [`self.file_name`].
     ///
-    /// [`self.file_name()`]: struct.Path.html#method.file_name
+    /// [`self.file_name`]: struct.Path.html#method.file_name
     ///
     /// The stem is:
     ///
@@ -1760,7 +1774,7 @@ pub fn file_stem(&self) -> Option<&OsStr> {
         self.file_name().map(split_file_at_dot).and_then(|(before, after)| before.or(after))
     }
 
-    /// Extracts the extension of [`self.file_name()`], if possible.
+    /// Extracts the extension of [`self.file_name`], if possible.
     ///
     /// The extension is:
     ///
@@ -1769,7 +1783,7 @@ pub fn file_stem(&self) -> Option<&OsStr> {
     /// * [`None`], if the file name begins with `.` and has no other `.`s within;
     /// * Otherwise, the portion of the file name after the final `.`
     ///
-    /// [`self.file_name()`]: struct.Path.html#method.file_name
+    /// [`self.file_name`]: struct.Path.html#method.file_name
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
     ///
     /// # Examples
@@ -2089,6 +2103,13 @@ pub fn is_file(&self) -> bool {
     pub fn is_dir(&self) -> bool {
         fs::metadata(self).map(|m| m.is_dir()).unwrap_or(false)
     }
+
+    /// Converts a `Box<Path>` into a `PathBuf` without copying or allocating.
+    #[unstable(feature = "into_boxed_path", issue = "40380")]
+    pub fn into_path_buf(self: Box<Path>) -> PathBuf {
+        let inner: Box<OsStr> = unsafe { mem::transmute(self) };
+        PathBuf { inner: OsString::from(inner) }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -3703,12 +3724,11 @@ fn test_iter_debug() {
     fn into_boxed() {
         let orig: &str = "some/sort/of/path";
         let path = Path::new(orig);
-        let path_buf = path.to_owned();
-        let box1: Box<Path> = Box::from(path);
-        let box2 = path_buf.into_boxed_path();
-        assert_eq!(path, &*box1);
-        assert_eq!(box1, box2);
-        assert_eq!(&*box2, path);
+        let boxed: Box<Path> = Box::from(path);
+        let path_buf = path.to_owned().into_boxed_path().into_path_buf();
+        assert_eq!(path, &*boxed);
+        assert_eq!(&*boxed, &*path_buf);
+        assert_eq!(&*path_buf, path);
     }
 
     #[test]
index f4cd319f06454a128b5ec701f3de83f56f3d1a36..c71e0b2a7035af1415270d94e4ac23fee64d57bf 100644 (file)
@@ -60,9 +60,9 @@
 //!   value.
 //! * [`std::boxed`]::[`Box`], a way to allocate values on the heap.
 //! * [`std::borrow`]::[`ToOwned`], The conversion trait that defines
-//!   [`to_owned()`], the generic method for creating an owned type from a
+//!   [`to_owned`], the generic method for creating an owned type from a
 //!   borrowed type.
-//! * [`std::clone`]::[`Clone`], the ubiquitous trait that defines [`clone()`],
+//! * [`std::clone`]::[`Clone`], the ubiquitous trait that defines [`clone`],
 //!   the method for producing a copy of a value.
 //! * [`std::cmp`]::{[`PartialEq`], [`PartialOrd`], [`Eq`], [`Ord`] }. The
 //!   comparison traits, which implement the comparison operators and are often
 //! [`ToOwned`]: ../borrow/trait.ToOwned.html
 //! [`ToString`]: ../string/trait.ToString.html
 //! [`Vec`]: ../vec/struct.Vec.html
-//! [`clone()`]: ../clone/trait.Clone.html#tymethod.clone
+//! [`clone`]: ../clone/trait.Clone.html#tymethod.clone
 //! [`drop`]: ../mem/fn.drop.html
 //! [`std::borrow`]: ../borrow/index.html
 //! [`std::boxed`]: ../boxed/index.html
 //! [`std::slice`]: ../slice/index.html
 //! [`std::string`]: ../string/index.html
 //! [`std::vec`]: ../vec/index.html
-//! [`to_owned()`]: ../borrow/trait.ToOwned.html#tymethod.to_owned
+//! [`to_owned`]: ../borrow/trait.ToOwned.html#tymethod.to_owned
 //! [book-closures]: ../../book/closures.html
 //! [book-dtor]: ../../book/drop.html
 //! [book-enums]: ../../book/enums.html
index 11197db98a39680b098af9d929f637f5954a9d7c..7d6d16f4748452c70d9924d2c0a5c66f99f8d582 100644 (file)
@@ -420,7 +420,7 @@ mod prim_slice { }
 /// # Representation
 ///
 /// A `&str` is made up of two components: a pointer to some bytes, and a
-/// length. You can look at these with the [`.as_ptr()`] and [`len()`] methods:
+/// length. You can look at these with the [`.as_ptr`] and [`len`] methods:
 ///
 /// ```
 /// use std::slice;
@@ -447,8 +447,8 @@ mod prim_slice { }
 /// assert_eq!(s, Ok(story));
 /// ```
 ///
-/// [`.as_ptr()`]: #method.as_ptr
-/// [`len()`]: #method.len
+/// [`.as_ptr`]: #method.as_ptr
+/// [`len`]: #method.len
 ///
 /// Note: This example shows the internals of `&str`. `unsafe` should not be
 /// used to get a string slice under normal circumstances. Use `.as_slice()`
index f15e7ff891684ceee5c212d101666874614de53a..295a49d6a8e8916050ad20267b666b06bce6c07f 100644 (file)
@@ -52,10 +52,10 @@ struct BarrierState {
 
 /// A result returned from wait.
 ///
-/// Currently this opaque structure only has one method, [`.is_leader()`]. Only
+/// Currently this opaque structure only has one method, [`.is_leader`]. Only
 /// one thread will receive a result that will return `true` from this function.
 ///
-/// [`.is_leader()`]: #method.is_leader
+/// [`.is_leader`]: #method.is_leader
 ///
 /// # Examples
 ///
index 68c7e88f67fc56218f5f8fd557fc2a088ce1fe46..7ad9d9ee37ce60e83dc8a4a6b74407d3aafc1def 100644 (file)
@@ -150,7 +150,7 @@ pub fn new() -> Condvar {
     ///
     /// This function will atomically unlock the mutex specified (represented by
     /// `guard`) and block the current thread. This means that any calls
-    /// to [`notify_one()`] or [`notify_all()`] which happen logically after the
+    /// to [`notify_one`] or [`notify_all`] which happen logically after the
     /// mutex is unlocked are candidates to wake this thread up. When this
     /// function call returns, the lock specified will have been re-acquired.
     ///
@@ -167,16 +167,16 @@ pub fn new() -> Condvar {
     ///
     /// # Panics
     ///
-    /// This function will [`panic!()`] if it is used with more than one mutex
+    /// This function will [`panic!`] if it is used with more than one mutex
     /// over time. Each condition variable is dynamically bound to exactly one
     /// mutex to ensure defined behavior across platforms. If this functionality
     /// is not desired, then unsafe primitives in `sys` are provided.
     ///
-    /// [`notify_one()`]: #method.notify_one
-    /// [`notify_all()`]: #method.notify_all
+    /// [`notify_one`]: #method.notify_one
+    /// [`notify_all`]: #method.notify_all
     /// [poisoning]: ../sync/struct.Mutex.html#poisoning
     /// [`Mutex`]: ../sync/struct.Mutex.html
-    /// [`panic!()`]: ../../std/macro.panic.html
+    /// [`panic!`]: ../../std/macro.panic.html
     ///
     /// # Examples
     ///
@@ -359,11 +359,11 @@ pub fn wait_timeout<'a, T>(&self, guard: MutexGuard<'a, T>,
     /// be woken up from its call to [`wait`] or [`wait_timeout`]. Calls to
     /// `notify_one` are not buffered in any way.
     ///
-    /// To wake up all threads, see [`notify_all()`].
+    /// To wake up all threads, see [`notify_all`].
     ///
     /// [`wait`]: #method.wait
     /// [`wait_timeout`]: #method.wait_timeout
-    /// [`notify_all()`]: #method.notify_all
+    /// [`notify_all`]: #method.notify_all
     ///
     /// # Examples
     ///
@@ -401,9 +401,9 @@ pub fn notify_one(&self) {
     /// variable are awoken. Calls to `notify_all()` are not buffered in any
     /// way.
     ///
-    /// To wake up only one thread, see [`notify_one()`].
+    /// To wake up only one thread, see [`notify_one`].
     ///
-    /// [`notify_one()`]: #method.notify_one
+    /// [`notify_one`]: #method.notify_one
     ///
     /// # Examples
     ///
index aeeab170deafe9cfdd92324197a2bf14c74ffacd..71dd94161c03df8625c719e73a2e595fccbdea72 100644 (file)
@@ -460,10 +460,10 @@ fn inner_unsafe(&self) -> &UnsafeCell<Flavor<T>> {
 /// All data sent on the sender will become available on the receiver, and no
 /// send will block the calling thread (this channel has an "infinite buffer").
 ///
-/// If the [`Receiver`] is disconnected while trying to [`send()`] with the
-/// [`Sender`], the [`send()`] method will return an error.
+/// If the [`Receiver`] is disconnected while trying to [`send`] with the
+/// [`Sender`], the [`send`] method will return an error.
 ///
-/// [`send()`]: ../../../std/sync/mpsc/struct.Sender.html#method.send
+/// [`send`]: ../../../std/sync/mpsc/struct.Sender.html#method.send
 /// [`Sender`]: ../../../std/sync/mpsc/struct.Sender.html
 /// [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html
 ///
@@ -504,13 +504,13 @@ pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
 /// `bound` specifies the buffer size. When the internal buffer becomes full,
 /// future sends will *block* waiting for the buffer to open up. Note that a
 /// buffer size of 0 is valid, in which case this becomes "rendezvous channel"
-/// where each [`send()`] will not return until a recv is paired with it.
+/// where each [`send`] will not return until a recv is paired with it.
 ///
 /// Like asynchronous channels, if the [`Receiver`] is disconnected while
-/// trying to [`send()`] with the [`SyncSender`], the [`send()`] method will
+/// trying to [`send`] with the [`SyncSender`], the [`send`] method will
 /// return an error.
 ///
-/// [`send()`]: ../../../std/sync/mpsc/struct.SyncSender.html#method.send
+/// [`send`]: ../../../std/sync/mpsc/struct.SyncSender.html#method.send
 /// [`SyncSender`]: ../../../std/sync/mpsc/struct.SyncSender.html
 /// [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html
 ///
index 97b84d59218ac290de902b451f7ccfbfb9ffea58..48d8d34dbe090377bc232b433acafbb88c7b4206 100644 (file)
@@ -135,13 +135,13 @@ unsafe impl<T: ?Sized + Send> Sync for Mutex<T> { }
 /// The data protected by the mutex can be access through this guard via its
 /// [`Deref`] and [`DerefMut`] implementations.
 ///
-/// This structure is created by the [`lock()`] and [`try_lock()`] methods on
+/// This structure is created by the [`lock`] and [`try_lock`] methods on
 /// [`Mutex`].
 ///
 /// [`Deref`]: ../../std/ops/trait.Deref.html
 /// [`DerefMut`]: ../../std/ops/trait.DerefMut.html
-/// [`lock()`]: struct.Mutex.html#method.lock
-/// [`try_lock()`]: struct.Mutex.html#method.try_lock
+/// [`lock`]: struct.Mutex.html#method.lock
+/// [`try_lock`]: struct.Mutex.html#method.try_lock
 /// [`Mutex`]: struct.Mutex.html
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
index a3db0adeda00dc6042c2c8f26dc77d6c3b65162c..d26f2f7bb7e3c7222ec6694254860ddaa9be2d01 100644 (file)
@@ -78,11 +78,11 @@ unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
 /// RAII structure used to release the shared read access of a lock when
 /// dropped.
 ///
-/// This structure is created by the [`read()`] and [`try_read()`] methods on
+/// This structure is created by the [`read`] and [`try_read`] methods on
 /// [`RwLock`].
 ///
-/// [`read()`]: struct.RwLock.html#method.read
-/// [`try_read()`]: struct.RwLock.html#method.try_read
+/// [`read`]: struct.RwLock.html#method.read
+/// [`try_read`]: struct.RwLock.html#method.try_read
 /// [`RwLock`]: struct.RwLock.html
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -96,11 +96,11 @@ impl<'a, T: ?Sized> !marker::Send for RwLockReadGuard<'a, T> {}
 /// RAII structure used to release the exclusive write access of a lock when
 /// dropped.
 ///
-/// This structure is created by the [`write()`] and [`try_write()`] methods
+/// This structure is created by the [`write`] and [`try_write`] methods
 /// on [`RwLock`].
 ///
-/// [`write()`]: struct.RwLock.html#method.write
-/// [`try_write()`]: struct.RwLock.html#method.try_write
+/// [`write`]: struct.RwLock.html#method.write
+/// [`try_write`]: struct.RwLock.html#method.try_write
 /// [`RwLock`]: struct.RwLock.html
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
index 474d59eed83d1daa3bf3b8b00b6e73edec840688..c2bba07f68ce0be0e346aa0763759cd97da51198 100644 (file)
@@ -104,6 +104,12 @@ pub fn push_slice(&mut self, s: &Slice) {
     pub fn into_box(self) -> Box<Slice> {
         unsafe { mem::transmute(self.inner.into_boxed_slice()) }
     }
+
+    #[inline]
+    pub fn from_box(boxed: Box<Slice>) -> Buf {
+        let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
+        Buf { inner: inner.into_vec() }
+    }
 }
 
 impl Slice {
index 8a15f7ec68232b72dd5ad19c3c05206610464202..55118829eee9f950ef900cb1a5ca62c068c63eb9 100644 (file)
@@ -375,12 +375,12 @@ pub fn peer_addr(&self) -> io::Result<SocketAddr> {
 
     /// Sets the read timeout for the socket.
     ///
-    /// If the provided value is [`None`], then [`read()`] calls will block
+    /// If the provided value is [`None`], then [`read`] calls will block
     /// indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
     ///
     /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
-    /// [`read()`]: ../../../../std/io/trait.Read.html#tymethod.read
+    /// [`read`]: ../../../../std/io/trait.Read.html#tymethod.read
     /// [`Duration`]: ../../../../std/time/struct.Duration.html
     ///
     /// # Examples
@@ -399,12 +399,12 @@ pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
 
     /// Sets the write timeout for the socket.
     ///
-    /// If the provided value is [`None`], then [`write()`] calls will block
+    /// If the provided value is [`None`], then [`write`] calls will block
     /// indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
     ///
     /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
-    /// [`read()`]: ../../../../std/io/trait.Write.html#tymethod.write
+    /// [`read`]: ../../../../std/io/trait.Write.html#tymethod.write
     /// [`Duration`]: ../../../../std/time/struct.Duration.html
     ///
     /// # Examples
@@ -974,12 +974,12 @@ pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
 
     /// Connects the socket to the specified address.
     ///
-    /// The [`send()`] method may be used to send data to the specified address.
-    /// [`recv()`] and [`recv_from()`] will only receive data from that address.
+    /// The [`send`] method may be used to send data to the specified address.
+    /// [`recv`] and [`recv_from`] will only receive data from that address.
     ///
-    /// [`send()`]: #method.send
-    /// [`recv()`]: #method.recv
-    /// [`recv_from()`]: #method.recv_from
+    /// [`send`]: #method.send
+    /// [`recv`]: #method.recv
+    /// [`recv_from`]: #method.recv_from
     ///
     /// # Examples
     ///
@@ -1047,9 +1047,9 @@ pub fn local_addr(&self) -> io::Result<SocketAddr> {
 
     /// Returns the address of this socket's peer.
     ///
-    /// The [`connect()`] method will connect the socket to a peer.
+    /// The [`connect`] method will connect the socket to a peer.
     ///
-    /// [`connect()`]: #method.connect
+    /// [`connect`]: #method.connect
     ///
     /// # Examples
     ///
@@ -1178,13 +1178,13 @@ pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
 
     /// Sets the read timeout for the socket.
     ///
-    /// If the provided value is [`None`], then [`recv()`] and [`recv_from()`] calls will
+    /// If the provided value is [`None`], then [`recv`] and [`recv_from`] calls will
     /// block indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
     ///
     /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
-    /// [`recv()`]: #method.recv
-    /// [`recv_from()`]: #method.recv_from
+    /// [`recv`]: #method.recv
+    /// [`recv_from`]: #method.recv_from
     /// [`Duration`]: ../../../../std/time/struct.Duration.html
     ///
     /// # Examples
@@ -1203,13 +1203,13 @@ pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
 
     /// Sets the write timeout for the socket.
     ///
-    /// If the provided value is [`None`], then [`send()`] and [`send_to()`] calls will
+    /// If the provided value is [`None`], then [`send`] and [`send_to`] calls will
     /// block indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
     ///
     /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
-    /// [`send()`]: #method.send
-    /// [`send_to()`]: #method.send_to
+    /// [`send`]: #method.send
+    /// [`send_to`]: #method.send_to
     /// [`Duration`]: ../../../../std/time/struct.Duration.html
     ///
     /// # Examples
index c27599ec0206f8ae46b581c658e80fa215b7ebe2..f5b942d3343dc23e5ba221a9b498855e2c71448d 100644 (file)
@@ -104,6 +104,12 @@ pub fn push_slice(&mut self, s: &Slice) {
     pub fn into_box(self) -> Box<Slice> {
         unsafe { mem::transmute(self.inner.into_boxed_slice()) }
     }
+
+    #[inline]
+    pub fn from_box(boxed: Box<Slice>) -> Buf {
+        let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
+        Buf { inner: inner.into_vec() }
+    }
 }
 
 impl Slice {
index b02b06e1ef2e1510aed1b7885a9efaf70655f9ac..f401e7b35c8d8d6c78c360733f8e6d99f724d8f1 100644 (file)
@@ -97,6 +97,12 @@ pub fn shrink_to_fit(&mut self) {
     pub fn into_box(self) -> Box<Slice> {
         unsafe { mem::transmute(self.inner.into_box()) }
     }
+
+    #[inline]
+    pub fn from_box(boxed: Box<Slice>) -> Buf {
+        let inner: Box<Wtf8> = unsafe { mem::transmute(boxed) };
+        Buf { inner: Wtf8Buf::from_box(inner) }
+    }
 }
 
 impl Slice {
index b486d4ffda3fd61c239b94d61f9a03e9b758e52e..79aaf34ce2e0f5d68d18ea134f7cefa4275b20f2 100644 (file)
@@ -351,6 +351,12 @@ pub fn into_string_lossy(mut self) -> String {
     pub fn into_box(self) -> Box<Wtf8> {
         unsafe { mem::transmute(self.bytes.into_boxed_slice()) }
     }
+
+    /// Converts a `Box<Wtf8>` into a `Wtf8Buf`.
+    pub fn from_box(boxed: Box<Wtf8>) -> Wtf8Buf {
+        let bytes: Box<[u8]> = unsafe { mem::transmute(boxed) };
+        Wtf8Buf { bytes: bytes.into_vec() }
+    }
 }
 
 /// Create a new WTF-8 string from an iterator of code points.
index 2bc066d3fea55c3c203525a08317a3e1cd609aa5..64c2be25222a0c8336c286bd1dd973a54397341b 100644 (file)
 //! two ways:
 //!
 //! * By spawning a new thread, e.g. using the [`thread::spawn`][`spawn`]
-//!   function, and calling [`thread()`] on the [`JoinHandle`].
-//! * By requesting the current thread, using the [`thread::current()`] function.
+//!   function, and calling [`thread`] on the [`JoinHandle`].
+//! * By requesting the current thread, using the [`thread::current`] function.
 //!
-//! The [`thread::current()`] function is available even for threads not spawned
+//! The [`thread::current`] function is available even for threads not spawned
 //! by the APIs of this module.
 //!
 //! ## Blocking support: park and unpark
 //!
 //! Every thread is equipped with some basic low-level blocking support, via the
-//! [`thread::park()`][`park()`] function and [`thread::Thread::unpark()`][`unpark()`]
-//! method. [`park()`] blocks the current thread, which can then be resumed from
-//! another thread by calling the [`unpark()`] method on the blocked thread's handle.
+//! [`thread::park`][`park`] function and [`thread::Thread::unpark()`][`unpark`]
+//! method. [`park`] blocks the current thread, which can then be resumed from
+//! another thread by calling the [`unpark`] method on the blocked thread's handle.
 //!
 //! Conceptually, each [`Thread`] handle has an associated token, which is
 //! initially not present:
 //!
-//! * The [`thread::park()`][`park()`] function blocks the current thread unless or until
+//! * The [`thread::park`][`park`] function blocks the current thread unless or until
 //!   the token is available for its thread handle, at which point it atomically
 //!   consumes the token. It may also return *spuriously*, without consuming the
-//!   token. [`thread::park_timeout()`] does the same, but allows specifying a
+//!   token. [`thread::park_timeout`] does the same, but allows specifying a
 //!   maximum time to block the thread for.
 //!
-//! * The [`unpark()`] method on a [`Thread`] atomically makes the token available
+//! * The [`unpark`] method on a [`Thread`] atomically makes the token available
 //!   if it wasn't already.
 //!
 //! In other words, each [`Thread`] acts a bit like a semaphore with initial count
 //! The API is typically used by acquiring a handle to the current thread,
 //! placing that handle in a shared data structure so that other threads can
 //! find it, and then `park`ing. When some desired condition is met, another
-//! thread calls [`unpark()`] on the handle.
+//! thread calls [`unpark`] on the handle.
 //!
 //! The motivation for this design is twofold:
 //!
 //! [`Arc`]: ../../std/sync/struct.Arc.html
 //! [`spawn`]: ../../std/thread/fn.spawn.html
 //! [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
-//! [`thread()`]: ../../std/thread/struct.JoinHandle.html#method.thread
+//! [`thread`]: ../../std/thread/struct.JoinHandle.html#method.thread
 //! [`join`]: ../../std/thread/struct.JoinHandle.html#method.join
 //! [`Result`]: ../../std/result/enum.Result.html
 //! [`Ok`]: ../../std/result/enum.Result.html#variant.Ok
 //! [`Err`]: ../../std/result/enum.Result.html#variant.Err
 //! [`panic!`]: ../../std/macro.panic.html
 //! [`Builder`]: ../../std/thread/struct.Builder.html
-//! [`thread::current()`]: ../../std/thread/fn.spawn.html
+//! [`thread::current`]: ../../std/thread/fn.spawn.html
 //! [`Thread`]: ../../std/thread/struct.Thread.html
-//! [`park()`]: ../../std/thread/fn.park.html
-//! [`unpark()`]: ../../std/thread/struct.Thread.html#method.unpark
-//! [`thread::park_timeout()`]: ../../std/thread/fn.park_timeout.html
+//! [`park`]: ../../std/thread/fn.park.html
+//! [`unpark`]: ../../std/thread/struct.Thread.html#method.unpark
+//! [`thread::park_timeout`]: ../../std/thread/fn.park_timeout.html
 //! [`Cell`]: ../cell/struct.Cell.html
 //! [`RefCell`]: ../cell/struct.RefCell.html
 //! [`thread_local!`]: ../macro.thread_local.html
@@ -547,7 +547,7 @@ pub fn sleep(dur: Duration) {
 /// Blocks unless or until the current thread's token is made available.
 ///
 /// Every thread is equipped with some basic low-level blocking support, via
-/// the `park()` function and the [`unpark()`][unpark] method. These can be
+/// the `park()` function and the [`unpark`][unpark] method. These can be
 /// used as a more CPU-efficient implementation of a spinlock.
 ///
 /// [unpark]: struct.Thread.html#method.unpark
index 4269ce8534bd032e056a76dabec6fd88359e1669..682eec490bc652ccbd15020834454150e8fbd2ac 100644 (file)
 
 /// Returns an iterator that yields the lowercase equivalent of a `char`.
 ///
-/// This `struct` is created by the [`to_lowercase()`] method on [`char`]. See
+/// This `struct` is created by the [`to_lowercase`] method on [`char`]. See
 /// its documentation for more.
 ///
-/// [`to_lowercase()`]: ../../std/primitive.char.html#method.to_lowercase
+/// [`to_lowercase`]: ../../std/primitive.char.html#method.to_lowercase
 /// [`char`]: ../../std/primitive.char.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct ToLowercase(CaseMappingIter);
@@ -70,10 +70,10 @@ impl FusedIterator for ToLowercase {}
 
 /// Returns an iterator that yields the uppercase equivalent of a `char`.
 ///
-/// This `struct` is created by the [`to_uppercase()`] method on [`char`]. See
+/// This `struct` is created by the [`to_uppercase`] method on [`char`]. See
 /// its documentation for more.
 ///
-/// [`to_uppercase()`]: ../../std/primitive.char.html#method.to_uppercase
+/// [`to_uppercase`]: ../../std/primitive.char.html#method.to_uppercase
 /// [`char`]: ../../std/primitive.char.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct ToUppercase(CaseMappingIter);
@@ -183,7 +183,7 @@ impl char {
     /// * `a-z`
     /// * `A-Z`
     ///
-    /// For a more comprehensive understanding of 'digit', see [`is_numeric()`][is_numeric].
+    /// For a more comprehensive understanding of 'digit', see [`is_numeric`][is_numeric].
     ///
     /// [is_numeric]: #method.is_numeric
     ///
@@ -465,10 +465,10 @@ pub fn len_utf8(self) -> usize {
     /// Returns the number of 16-bit code units this `char` would need if
     /// encoded in UTF-16.
     ///
-    /// See the documentation for [`len_utf8()`] for more explanation of this
+    /// See the documentation for [`len_utf8`] for more explanation of this
     /// concept. This function is a mirror, but for UTF-16 instead of UTF-8.
     ///
-    /// [`len_utf8()`]: #method.len_utf8
+    /// [`len_utf8`]: #method.len_utf8
     ///
     /// # Examples
     ///
index 981667337d59a9d02b839ab772411276d6344436..a456fa512254c788050c584b0e8c67ebe9b4056d 100644 (file)
@@ -134,7 +134,7 @@ impl Path {
     pub fn from_ident(s: Span, identifier: Ident) -> Path {
         Path {
             span: s,
-            segments: vec![identifier.into()],
+            segments: vec![PathSegment::from_ident(identifier, s)],
         }
     }
 
@@ -159,6 +159,8 @@ pub fn is_global(&self) -> bool {
 pub struct PathSegment {
     /// The identifier portion of this path segment.
     pub identifier: Ident,
+    /// Span of the segment identifier.
+    pub span: Span,
 
     /// Type/lifetime parameters attached to this path. They come in
     /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
@@ -170,16 +172,14 @@ pub struct PathSegment {
     pub parameters: Option<P<PathParameters>>,
 }
 
-impl From<Ident> for PathSegment {
-    fn from(id: Ident) -> Self {
-        PathSegment { identifier: id, parameters: None }
-    }
-}
-
 impl PathSegment {
+    pub fn from_ident(ident: Ident, span: Span) -> Self {
+        PathSegment { identifier: ident, span: span, parameters: None }
+    }
     pub fn crate_root() -> Self {
         PathSegment {
             identifier: keywords::CrateRoot.ident(),
+            span: DUMMY_SP,
             parameters: None,
         }
     }
@@ -935,6 +935,8 @@ pub enum ExprKind {
     Closure(CaptureBy, P<FnDecl>, P<Expr>, Span),
     /// A block (`{ ... }`)
     Block(P<Block>),
+    /// A catch block (`catch { ... }`)
+    Catch(P<Block>),
 
     /// An assignment (`a = foo()`)
     Assign(P<Expr>, P<Expr>),
index f8d4eff80b2d19f7eeb95fb62bdcc8be080688ee..e0fb46ff5eb095a01c659ab0a6e124c30f82c577 100644 (file)
@@ -38,11 +38,11 @@ fn path_all(&self, sp: Span,
 
     fn qpath(&self, self_type: P<ast::Ty>,
              trait_path: ast::Path,
-             ident: ast::Ident)
+             ident: ast::SpannedIdent)
              -> (ast::QSelf, ast::Path);
     fn qpath_all(&self, self_type: P<ast::Ty>,
                 trait_path: ast::Path,
-                ident: ast::Ident,
+                ident: ast::SpannedIdent,
                 lifetimes: Vec<ast::Lifetime>,
                 types: Vec<P<ast::Ty>>,
                 bindings: Vec<ast::TypeBinding>)
@@ -323,7 +323,7 @@ fn path_all(&self,
             segments.push(ast::PathSegment::crate_root());
         }
 
-        segments.extend(idents.into_iter().map(Into::into));
+        segments.extend(idents.into_iter().map(|i| ast::PathSegment::from_ident(i, sp)));
         let parameters = if lifetimes.is_empty() && types.is_empty() && bindings.is_empty() {
             None
         } else {
@@ -333,7 +333,11 @@ fn path_all(&self,
                 bindings: bindings,
             })))
         };
-        segments.push(ast::PathSegment { identifier: last_identifier, parameters: parameters });
+        segments.push(ast::PathSegment {
+            identifier: last_identifier,
+            span: sp,
+            parameters: parameters
+        });
         ast::Path {
             span: sp,
             segments: segments,
@@ -346,7 +350,7 @@ fn path_all(&self,
     fn qpath(&self,
              self_type: P<ast::Ty>,
              trait_path: ast::Path,
-             ident: ast::Ident)
+             ident: ast::SpannedIdent)
              -> (ast::QSelf, ast::Path) {
         self.qpath_all(self_type, trait_path, ident, vec![], vec![], vec![])
     }
@@ -357,7 +361,7 @@ fn qpath(&self,
     fn qpath_all(&self,
                  self_type: P<ast::Ty>,
                  trait_path: ast::Path,
-                 ident: ast::Ident,
+                 ident: ast::SpannedIdent,
                  lifetimes: Vec<ast::Lifetime>,
                  types: Vec<P<ast::Ty>>,
                  bindings: Vec<ast::TypeBinding>)
@@ -369,7 +373,8 @@ fn qpath_all(&self,
             bindings: bindings,
         };
         path.segments.push(ast::PathSegment {
-            identifier: ident,
+            identifier: ident.node,
+            span: ident.span,
             parameters: Some(P(ast::PathParameters::AngleBracketed(parameters))),
         });
 
index e7bf16eae9ee660bd6bbf06f70bccb096a683116..15913d56d162f0cba362d22881b496c066a6fcd0 100644 (file)
@@ -339,6 +339,9 @@ pub fn new() -> Features {
 
     // `extern "x86-interrupt" fn()`
     (active, abi_x86_interrupt, "1.17.0", Some(40180)),
+
+    // Allows the `catch {...}` expression
+    (active, catch_expr, "1.17.0", Some(31436)),
 );
 
 declare_features! (
@@ -1287,6 +1290,9 @@ fn visit_expr(&mut self, e: &'a ast::Expr) {
                     }
                 }
             }
+            ast::ExprKind::Catch(_) => {
+                gate_feature_post!(&self, catch_expr, e.span, "`catch` expression is experimental");
+            }
             _ => {}
         }
         visit::walk_expr(self, e);
index fb4eb19be2b15d8f1a1f56fb019d3fa32cdbf80c..9f11d0173d6d5168c6602b8d85dc58f5642325f0 100644 (file)
@@ -434,8 +434,9 @@ pub fn noop_fold_usize<T: Folder>(i: usize, _: &mut T) -> usize {
 
 pub fn noop_fold_path<T: Folder>(Path { segments, span }: Path, fld: &mut T) -> Path {
     Path {
-        segments: segments.move_map(|PathSegment {identifier, parameters}| PathSegment {
+        segments: segments.move_map(|PathSegment {identifier, span, parameters}| PathSegment {
             identifier: fld.fold_ident(identifier),
+            span: fld.new_span(span),
             parameters: parameters.map(|ps| ps.map(|ps| fld.fold_path_parameters(ps))),
         }),
         span: fld.new_span(span)
@@ -1268,6 +1269,7 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
                 };
             }
             ExprKind::Try(ex) => ExprKind::Try(folder.fold_expr(ex)),
+            ExprKind::Catch(body) => ExprKind::Catch(folder.fold_block(body)),
         },
         id: folder.new_id(id),
         span: folder.new_span(span),
index c00d2952b3b425bcc87e6ac78be0bf9719c53a2c..88535f91379f72330ed449f407519d05b9edeb8a 100644 (file)
@@ -617,13 +617,17 @@ fn sp(a: u32, b: u32) -> Span {
         Span {lo: BytePos(a), hi: BytePos(b), expn_id: NO_EXPANSION}
     }
 
+    fn str2seg(s: &str, lo: u32, hi: u32) -> ast::PathSegment {
+        ast::PathSegment::from_ident(Ident::from_str(s), sp(lo, hi))
+    }
+
     #[test] fn path_exprs_1() {
         assert!(string_to_expr("a".to_string()) ==
                    P(ast::Expr{
                     id: ast::DUMMY_NODE_ID,
                     node: ast::ExprKind::Path(None, ast::Path {
                         span: sp(0, 1),
-                        segments: vec![Ident::from_str("a").into()],
+                        segments: vec![str2seg("a", 0, 1)],
                     }),
                     span: sp(0, 1),
                     attrs: ThinVec::new(),
@@ -637,8 +641,8 @@ fn sp(a: u32, b: u32) -> Span {
                     node: ast::ExprKind::Path(None, ast::Path {
                         span: sp(0, 6),
                         segments: vec![ast::PathSegment::crate_root(),
-                                       Ident::from_str("a").into(),
-                                       Ident::from_str("b").into()]
+                                       str2seg("a", 2, 3),
+                                       str2seg("b", 5, 6)]
                     }),
                     span: sp(0, 6),
                     attrs: ThinVec::new(),
@@ -744,7 +748,7 @@ fn string_to_tts_1() {
                         id: ast::DUMMY_NODE_ID,
                         node:ast::ExprKind::Path(None, ast::Path{
                             span: sp(7, 8),
-                            segments: vec![Ident::from_str("d").into()],
+                            segments: vec![str2seg("d", 7, 8)],
                         }),
                         span:sp(7,8),
                         attrs: ThinVec::new(),
@@ -761,7 +765,7 @@ fn string_to_tts_1() {
                            id: ast::DUMMY_NODE_ID,
                            node: ast::ExprKind::Path(None, ast::Path {
                                span:sp(0,1),
-                               segments: vec![Ident::from_str("b").into()],
+                               segments: vec![str2seg("b", 0, 1)],
                             }),
                            span: sp(0,1),
                            attrs: ThinVec::new()})),
@@ -802,7 +806,7 @@ fn parser_done(p: Parser){
                                     ty: P(ast::Ty{id: ast::DUMMY_NODE_ID,
                                                   node: ast::TyKind::Path(None, ast::Path{
                                         span:sp(10,13),
-                                        segments: vec![Ident::from_str("i32").into()],
+                                        segments: vec![str2seg("i32", 10, 13)],
                                         }),
                                         span:sp(10,13)
                                     }),
@@ -844,7 +848,7 @@ fn parser_done(p: Parser){
                                                 node: ast::ExprKind::Path(None,
                                                       ast::Path{
                                                         span:sp(17,18),
-                                                        segments: vec![Ident::from_str("b").into()],
+                                                        segments: vec![str2seg("b", 17, 18)],
                                                       }),
                                                 span: sp(17,18),
                                                 attrs: ThinVec::new()})),
index 4164932e90e57e1869a355caa282639d5422cf80..8f66c1a2b8cf630eada9a2627ac6360b1d2dd72b 100644 (file)
@@ -27,7 +27,7 @@
 use ast::MacStmtStyle;
 use ast::Mac_;
 use ast::{MutTy, Mutability};
-use ast::{Pat, PatKind};
+use ast::{Pat, PatKind, PathSegment};
 use ast::{PolyTraitRef, QSelf};
 use ast::{Stmt, StmtKind};
 use ast::{VariantData, StructField};
@@ -1811,7 +1811,7 @@ pub fn parse_path(&mut self, mode: PathStyle) -> PResult<'a, ast::Path> {
         };
 
         if is_global {
-            segments.insert(0, ast::PathSegment::crate_root());
+            segments.insert(0, PathSegment::crate_root());
         }
 
         // Assemble the span.
@@ -1829,11 +1829,12 @@ pub fn parse_path(&mut self, mode: PathStyle) -> PResult<'a, ast::Path> {
     /// - `a::b<T,U>::c<V,W>`
     /// - `a::b<T,U>::c(V) -> W`
     /// - `a::b<T,U>::c(V)`
-    pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<ast::PathSegment>> {
+    pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<PathSegment>> {
         let mut segments = Vec::new();
         loop {
             // First, parse an identifier.
             let identifier = self.parse_path_segment_ident()?;
+            let ident_span = self.prev_span;
 
             if self.check(&token::ModSep) && self.look_ahead(1, |t| *t == token::Lt) {
                 self.bump();
@@ -1881,7 +1882,11 @@ pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<ast::Pat
             };
 
             // Assemble and push the result.
-            segments.push(ast::PathSegment { identifier: identifier, parameters: parameters });
+            segments.push(PathSegment {
+                identifier: identifier,
+                span: ident_span,
+                parameters: parameters
+            });
 
             // Continue only if we see a `::`
             if !self.eat(&token::ModSep) {
@@ -1892,15 +1897,16 @@ pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<ast::Pat
 
     /// Examples:
     /// - `a::b::<T,U>::c`
-    pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSegment>> {
+    pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<PathSegment>> {
         let mut segments = Vec::new();
         loop {
             // First, parse an identifier.
             let identifier = self.parse_path_segment_ident()?;
+            let ident_span = self.prev_span;
 
             // If we do not see a `::`, stop.
             if !self.eat(&token::ModSep) {
-                segments.push(identifier.into());
+                segments.push(PathSegment::from_ident(identifier, ident_span));
                 return Ok(segments);
             }
 
@@ -1909,8 +1915,9 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSe
                 // Consumed `a::b::<`, go look for types
                 let (lifetimes, types, bindings) = self.parse_generic_args()?;
                 self.expect_gt()?;
-                segments.push(ast::PathSegment {
+                segments.push(PathSegment {
                     identifier: identifier,
+                    span: ident_span,
                     parameters: ast::AngleBracketedParameterData {
                         lifetimes: lifetimes,
                         types: types,
@@ -1924,7 +1931,7 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSe
                 }
             } else {
                 // Consumed `a::`, go look for `b`
-                segments.push(identifier.into());
+                segments.push(PathSegment::from_ident(identifier, ident_span));
             }
         }
     }
@@ -1932,14 +1939,14 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSe
     /// Examples:
     /// - `a::b::c`
     pub fn parse_path_segments_without_types(&mut self)
-                                             -> PResult<'a, Vec<ast::PathSegment>> {
+                                             -> PResult<'a, Vec<PathSegment>> {
         let mut segments = Vec::new();
         loop {
             // First, parse an identifier.
             let identifier = self.parse_path_segment_ident()?;
 
             // Assemble and push the result.
-            segments.push(identifier.into());
+            segments.push(PathSegment::from_ident(identifier, self.prev_span));
 
             // If we do not see a `::` or see `::{`/`::*`, stop.
             if !self.check(&token::ModSep) || self.is_import_coupler() {
@@ -2273,6 +2280,12 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
                         BlockCheckMode::Unsafe(ast::UserProvided),
                         attrs);
                 }
+                if self.is_catch_expr() {
+                    assert!(self.eat_keyword(keywords::Do));
+                    assert!(self.eat_keyword(keywords::Catch));
+                    let lo = self.prev_span.lo;
+                    return self.parse_catch_expr(lo, attrs);
+                }
                 if self.eat_keyword(keywords::Return) {
                     if self.token.can_begin_expr() {
                         let e = self.parse_expr()?;
@@ -3092,6 +3105,16 @@ pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::SpannedIdent>,
         Ok(self.mk_expr(span_lo, hi, ExprKind::Loop(body, opt_ident), attrs))
     }
 
+    /// Parse a `do catch {...}` expression (`do catch` token already eaten)
+    pub fn parse_catch_expr(&mut self, span_lo: BytePos, mut attrs: ThinVec<Attribute>)
+        -> PResult<'a, P<Expr>>
+    {
+        let (iattrs, body) = self.parse_inner_attrs_and_block()?;
+        attrs.extend(iattrs);
+        let hi = body.span.hi;
+        Ok(self.mk_expr(span_lo, hi, ExprKind::Catch(body), attrs))
+    }
+
     // `match` token already eaten
     fn parse_match_expr(&mut self, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
         let match_span = self.prev_span;
@@ -3699,6 +3722,15 @@ fn parse_stmt_(&mut self, macro_legacy_warnings: bool) -> Option<Stmt> {
         })
     }
 
+    fn is_catch_expr(&mut self) -> bool {
+        self.token.is_keyword(keywords::Do) &&
+        self.look_ahead(1, |t| t.is_keyword(keywords::Catch)) &&
+        self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace)) &&
+
+        // prevent `while catch {} {}`, `if catch {} {} else {}`, etc.
+        !self.restrictions.contains(Restrictions::RESTRICTION_NO_STRUCT_LITERAL)
+    }
+
     fn is_union_item(&self) -> bool {
         self.token.is_keyword(keywords::Union) &&
         self.look_ahead(1, |t| t.is_ident() && !t.is_any_keyword())
@@ -4875,6 +4907,7 @@ fn parse_poly_trait_ref(&mut self) -> PResult<'a, PolyTraitRef> {
     /// Parse struct Foo { ... }
     fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> {
         let class_name = self.parse_ident()?;
+
         let mut generics = self.parse_generics()?;
 
         // There is a special case worth noting here, as reported in issue #17904.
@@ -4924,6 +4957,7 @@ fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> {
     /// Parse union Foo { ... }
     fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> {
         let class_name = self.parse_ident()?;
+
         let mut generics = self.parse_generics()?;
 
         let vdata = if self.token.is_keyword(keywords::Where) {
@@ -5950,7 +5984,7 @@ fn parse_view_path(&mut self) -> PResult<'a, P<ViewPath>> {
             // `{foo, bar}`, `::{foo, bar}`, `*`, or `::*`.
             self.eat(&token::ModSep);
             let prefix = ast::Path {
-                segments: vec![ast::PathSegment::crate_root()],
+                segments: vec![PathSegment::crate_root()],
                 span: mk_sp(lo, self.span.hi),
             };
             let view_path_kind = if self.eat(&token::BinOp(token::Star)) {
index 5b65aac92b81c2d28ad6efe19d6ba38e1d0c59bc..25601f2420e8a7d680d4f21c2861200f3e55ce3e 100644 (file)
@@ -86,6 +86,7 @@ fn ident_can_begin_expr(ident: ast::Ident) -> bool {
     !ident_token.is_any_keyword() ||
     ident_token.is_path_segment_keyword() ||
     [
+        keywords::Do.name(),
         keywords::Box.name(),
         keywords::Break.name(),
         keywords::Continue.name(),
index 3efadbd00d1e080924cd28dd33a46a6a9613b183..83753f398a3765cd7e3df0424a89cf97c7fae479 100644 (file)
@@ -2279,6 +2279,11 @@ fn print_expr_outer_attr_style(&mut self,
                 self.print_expr(e)?;
                 word(&mut self.s, "?")?
             }
+            ast::ExprKind::Catch(ref blk) => {
+                self.head("do catch")?;
+                space(&mut self.s)?;
+                self.print_block_with_attrs(&blk, attrs)?
+            }
         }
         self.ann.post(self, NodeExpr(expr))?;
         self.end()
index 4a2dfaf61247cb1648e5ea6ce0a3ffb049556421..2192d203cdc23cce08e67e73d352d4e35640d5b4 100644 (file)
@@ -82,7 +82,7 @@ pub fn maybe_inject_crates_ref(sess: &ParseSess,
         vis: ast::Visibility::Inherited,
         node: ast::ItemKind::Use(P(codemap::dummy_spanned(ast::ViewPathGlob(ast::Path {
             segments: ["{{root}}", name, "prelude", "v1"].into_iter().map(|name| {
-                ast::Ident::from_str(name).into()
+                ast::PathSegment::from_ident(ast::Ident::from_str(name), DUMMY_SP)
             }).collect(),
             span: span,
         })))),
index c278171aa109a81120433777fafd9a4504dedb53..6642c60d256b3c4e40e0cc437ddb60993544e1f6 100644 (file)
@@ -221,9 +221,10 @@ fn fresh() -> Self {
     (53, Default,        "default")
     (54, StaticLifetime, "'static")
     (55, Union,          "union")
+    (56, Catch,          "catch")
 
     // A virtual keyword that resolves to the crate root when used in a lexical scope.
-    (56, CrateRoot, "{{root}}")
+    (57, CrateRoot, "{{root}}")
 }
 
 // If an interner exists in TLS, return it. Otherwise, prepare a fresh one.
index dd2756cd2b22c95aa42b715c59a095488ab4bf41..e052d2cda3a42469b000be576f82b416a08bb20c 100644 (file)
@@ -580,7 +580,7 @@ fn nospan<T>(t: T) -> codemap::Spanned<T> {
 fn path_node(ids: Vec<Ident>) -> ast::Path {
     ast::Path {
         span: DUMMY_SP,
-        segments: ids.into_iter().map(Into::into).collect(),
+        segments: ids.into_iter().map(|id| ast::PathSegment::from_ident(id, DUMMY_SP)).collect(),
     }
 }
 
index ee7dd18247b213d4b6b6a7c153b8db3c74ca3d60..a5333f3bb6a6e46c1f3af1c8e1d30194c194d897 100644 (file)
@@ -779,6 +779,9 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
         ExprKind::Try(ref subexpression) => {
             visitor.visit_expr(subexpression)
         }
+        ExprKind::Catch(ref body) => {
+            visitor.visit_block(body)
+        }
     }
 
     visitor.visit_expr_post(expression)
index 1fc1bdff593c2766fa16ab94bad998451f82e0ee..dc4b8eb24cd0a570ce18531a84024bd2e90ebff9 100644 (file)
@@ -61,7 +61,7 @@ impl Result {
         fn path(&self) -> ast::Path {
             ast::Path {
                 span: self.span,
-                segments: vec![self.ident.into()],
+                segments: vec![ast::PathSegment::from_ident(self.ident, self.span)],
             }
         }
     }
diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger
deleted file mode 100644 (file)
index e30ad63..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
-# The actual contents of this file do not matter, but to trigger a change on the
-# build bots then the contents should be changed so git updates the mtime.
-2017-03-04
diff --git a/src/rustllvm/llvm-rebuild-trigger b/src/rustllvm/llvm-rebuild-trigger
new file mode 100644 (file)
index 0000000..aeabf4a
--- /dev/null
@@ -0,0 +1,4 @@
+# If this file is modified, then llvm will be (optionally) cleaned and then rebuilt.
+# The actual contents of this file do not matter, but to trigger a change on the
+# build bots then the contents should be changed so git updates the mtime.
+2017-03-04
index db2cd3b41656d3026d310bb08051d4073209475a..99e6e38a3bf0bd97654846d3f5c6e151d1d2b822 100644 (file)
@@ -27,3 +27,36 @@ pub fn write_pkd(pkd: &mut Packed) -> u32 {
     pkd.data = 42;
     result
 }
+
+pub struct Array([i32; 8]);
+#[repr(packed)]
+pub struct BigPacked {
+    dealign: u8,
+    data: Array
+}
+
+// CHECK-LABEL: @call_pkd
+#[no_mangle]
+pub fn call_pkd(f: fn() -> Array) -> BigPacked {
+// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
+// CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]])
+// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 32, i32 1, i1 false)
+    // check that calls whose destination is a field of a packed struct
+    // go through an alloca rather than calling the function with an
+    // unaligned destination.
+    BigPacked { dealign: 0, data: f() }
+}
+
+#[repr(packed)]
+#[derive(Copy, Clone)]
+pub struct PackedPair(u8, u32);
+
+// CHECK-LABEL: @pkd_pair
+#[no_mangle]
+pub fn pkd_pair(pair1: &mut PackedPair, pair2: &mut PackedPair) {
+    // CHECK: [[V1:%[a-z0-9]+]] = load i8, i8* %{{.*}}, align 1
+    // CHECK: [[V2:%[a-z0-9]+]] = load i32, i32* %{{.*}}, align 1
+    // CHECK: store i8 [[V1]], i8* {{.*}}, align 1
+    // CHECK: store i32 [[V2]], i32* {{.*}}, align 1
+    *pair2 = *pair1;
+}
diff --git a/src/test/compile-fail/catch-in-match.rs b/src/test/compile-fail/catch-in-match.rs
new file mode 100644 (file)
index 0000000..9f9968e
--- /dev/null
@@ -0,0 +1,15 @@
+// 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(catch_expr)]
+
+fn main() {
+    match do catch { false } { _ => {} } //~ ERROR expected expression, found reserved keyword `do`
+}
diff --git a/src/test/compile-fail/catch-in-while.rs b/src/test/compile-fail/catch-in-while.rs
new file mode 100644 (file)
index 0000000..cb8613e
--- /dev/null
@@ -0,0 +1,15 @@
+// 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(catch_expr)]
+
+fn main() {
+    while do catch { false } {} //~ ERROR expected expression, found reserved keyword `do`
+}
diff --git a/src/test/compile-fail/feature-gate-catch_expr.rs b/src/test/compile-fail/feature-gate-catch_expr.rs
new file mode 100644 (file)
index 0000000..5568a5c
--- /dev/null
@@ -0,0 +1,17 @@
+// 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.
+
+pub fn main() {
+    let catch_result = do catch { //~ ERROR `catch` expression is experimental
+        let x = 5;
+        x
+    };
+    assert_eq!(catch_result, 5);
+}
diff --git a/src/test/run-pass/catch-expr.rs b/src/test/run-pass/catch-expr.rs
new file mode 100644 (file)
index 0000000..a9b28a5
--- /dev/null
@@ -0,0 +1,32 @@
+// 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(catch_expr)]
+
+struct catch {}
+
+pub fn main() {
+    let catch_result = do catch {
+        let x = 5;
+        x
+    };
+    assert_eq!(catch_result, 5);
+
+    let mut catch = true;
+    while catch { catch = false; }
+    assert_eq!(catch, false);
+
+    catch = if catch { false } else { true };
+    assert_eq!(catch, true);
+
+    match catch {
+        _ => {}
+    };
+}
index d541aa599a48b2bdbbf24c1b8336c707c52ab246..dd04c5ce356c626224f5eda92cbc93e69edc4d5c 100644 (file)
@@ -1,26 +1,26 @@
 error[E0425]: cannot find value `A` in module `namespaced_enums`
-  --> $DIR/enums-are-namespaced-xc.rs:15:13
+  --> $DIR/enums-are-namespaced-xc.rs:15:31
    |
 15 |     let _ = namespaced_enums::A;
-   |             ^^^^^^^^^^^^^^^^^^^ not found in `namespaced_enums`
+   |                               ^ not found in `namespaced_enums`
    |
    = help: possible candidate is found in another module, you can import it into scope:
              `use namespaced_enums::Foo::A;`
 
 error[E0425]: cannot find function `B` in module `namespaced_enums`
-  --> $DIR/enums-are-namespaced-xc.rs:18:13
+  --> $DIR/enums-are-namespaced-xc.rs:18:31
    |
 18 |     let _ = namespaced_enums::B(10);
-   |             ^^^^^^^^^^^^^^^^^^^ not found in `namespaced_enums`
+   |                               ^ not found in `namespaced_enums`
    |
    = help: possible candidate is found in another module, you can import it into scope:
              `use namespaced_enums::Foo::B;`
 
 error[E0422]: cannot find struct, variant or union type `C` in module `namespaced_enums`
-  --> $DIR/enums-are-namespaced-xc.rs:21:13
+  --> $DIR/enums-are-namespaced-xc.rs:21:31
    |
 21 |     let _ = namespaced_enums::C { a: 10 };
-   |             ^^^^^^^^^^^^^^^^^^^ not found in `namespaced_enums`
+   |                               ^ not found in `namespaced_enums`
    |
    = help: possible candidate is found in another module, you can import it into scope:
              `use namespaced_enums::Foo::C;`
index c7c42bcf239405088ebea527aaae1baa55e460cb..4dff2620319e4607dcee7cf5fe92c79bd922a8ab 100644 (file)
@@ -14,7 +14,7 @@ error[E0412]: cannot find type `Opiton` in this scope
   --> $DIR/levenshtein.rs:20:10
    |
 20 | type B = Opiton<u8>; // Misspelled type name from the prelude.
-   |          ^^^^^^^^^^ did you mean `Option`?
+   |          ^^^^^^ did you mean `Option`?
 
 error[E0412]: cannot find type `Baz` in this scope
   --> $DIR/levenshtein.rs:23:14
@@ -35,16 +35,16 @@ error[E0425]: cannot find function `foobar` in this scope
    |     ^^^^^^ did you mean `foo_bar`?
 
 error[E0412]: cannot find type `first` in module `m`
-  --> $DIR/levenshtein.rs:32:12
+  --> $DIR/levenshtein.rs:32:15
    |
 32 |     let b: m::first = m::second; // Misspelled item in module.
-   |            ^^^^^^^^ did you mean `m::First`?
+   |               ^^^^^ did you mean `First`?
 
 error[E0425]: cannot find value `second` in module `m`
-  --> $DIR/levenshtein.rs:32:23
+  --> $DIR/levenshtein.rs:32:26
    |
 32 |     let b: m::first = m::second; // Misspelled item in module.
-   |                       ^^^^^^^^^ did you mean `m::Second`?
+   |                          ^^^^^^ did you mean `Second`?
 
 error: aborting due to 8 previous errors
 
index 57c0ecc813505d39b31a9ffc956a1a970ef44274..85fb1777dea233abf7e71dd53e577a29a7ba84b5 100644 (file)
@@ -2,55 +2,73 @@ error[E0423]: expected value, found module `a`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:27:5
    |
 27 |     a.I
-   |     ^ did you mean `a::I`?
+   |     ^--
+   |     |
+   |     did you mean `a::I`?
 
 error[E0423]: expected value, found module `a`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:33:5
    |
 33 |     a.g()
-   |     ^ did you mean `a::g(...)`?
+   |     ^----
+   |     |
+   |     did you mean `a::g(...)`?
 
 error[E0423]: expected value, found module `a`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:39:5
    |
 39 |     a.b.J
-   |     ^ did you mean `a::b`?
+   |     ^--
+   |     |
+   |     did you mean `a::b`?
 
 error[E0423]: expected value, found module `a::b`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:45:5
    |
 45 |     a::b.J
-   |     ^^^^ did you mean `a::b::J`?
+   |     ^^^^--
+   |     |
+   |     did you mean `a::b::J`?
 
 error[E0423]: expected value, found module `a`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:51:5
    |
 51 |     a.b.f();
-   |     ^ did you mean `a::b`?
+   |     ^--
+   |     |
+   |     did you mean `a::b`?
 
 error[E0423]: expected value, found module `a::b`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:55:12
    |
 55 |     v.push(a::b);
-   |            ^^^^ did you mean `a::I`?
+   |            ^^^-
+   |               |
+   |               did you mean `I`?
 
 error[E0423]: expected value, found module `a::b`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:61:5
    |
 61 |     a::b.f()
-   |     ^^^^ did you mean `a::b::f(...)`?
+   |     ^^^^----
+   |     |
+   |     did you mean `a::b::f(...)`?
 
 error[E0423]: expected value, found module `a::b`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:67:5
    |
 67 |     a::b
-   |     ^^^^ did you mean `a::I`?
+   |     ^^^-
+   |        |
+   |        did you mean `I`?
 
 error[E0423]: expected function, found module `a::b`
   --> $DIR/suggest-path-instead-of-mod-dot-item.rs:73:5
    |
 73 |     a::b()
-   |     ^^^^ did you mean `a::I`?
+   |     ^^^-
+   |        |
+   |        did you mean `I`?
 
 error: main function not found
 
index f0d363f7335f72c19d650efcfbdc3b38b1d78a7c..015dbfc3dc775fe509d4ac8e7bef1b8748332212 100644 (file)
@@ -2,7 +2,7 @@ error[E0405]: cannot find trait `Nonexist` in this scope
   --> $DIR/unboxed-closure-sugar-nonexistent-trait.rs:11:8
    |
 11 | fn f<F:Nonexist(isize) -> isize>(x: F) {}
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
+   |        ^^^^^^^^ not found in this scope
 
 error[E0404]: expected trait, found type alias `Typedef`
   --> $DIR/unboxed-closure-sugar-nonexistent-trait.rs:17:8
diff --git a/src/test/ui/span/issue-29595.rs b/src/test/ui/span/issue-29595.rs
new file mode 100644 (file)
index 0000000..7970461
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(associated_consts)]
+
+trait Tr {
+    const C: Self;
+}
+
+fn main() {
+    let a: u8 = Tr::C; //~ ERROR the trait bound `u8: Tr` is not satisfied
+}
diff --git a/src/test/ui/span/issue-29595.stderr b/src/test/ui/span/issue-29595.stderr
new file mode 100644 (file)
index 0000000..abbac24
--- /dev/null
@@ -0,0 +1,10 @@
+error[E0277]: the trait bound `u8: Tr` is not satisfied
+  --> $DIR/issue-29595.rs:18:17
+   |
+18 |     let a: u8 = Tr::C; //~ ERROR the trait bound `u8: Tr` is not satisfied
+   |                 ^^^^^ the trait `Tr` is not implemented for `u8`
+   |
+   = note: required by `Tr::C`
+
+error: aborting due to previous error
+
index c2ec42195fcb7e16a76601780e46a10334e1ac60..adddd7b7e89b047030eeb63a0b32cb2aa18c017d 100644 (file)
@@ -250,12 +250,13 @@ fn build_manifest(&mut self) -> Manifest {
             let mut components = Vec::new();
             let mut extensions = Vec::new();
 
-            // rustc/rust-std/cargo are all required, and so is rust-mingw if it's
-            // available for the target.
+            // rustc/rust-std/cargo/docs are all required, and so is rust-mingw
+            // if it's available for the target.
             components.extend(vec![
                 Component { pkg: "rustc".to_string(), target: host.to_string() },
                 Component { pkg: "rust-std".to_string(), target: host.to_string() },
                 Component { pkg: "cargo".to_string(), target: host.to_string() },
+                Component { pkg: "rust-docs".to_string(), target: host.to_string() },
             ]);
             if host.contains("pc-windows-gnu") {
                 components.push(Component {
@@ -264,12 +265,6 @@ fn build_manifest(&mut self) -> Manifest {
                 });
             }
 
-            // Docs, other standard libraries, and the source package are all
-            // optional.
-            extensions.push(Component {
-                pkg: "rust-docs".to_string(),
-                target: host.to_string(),
-            });
             for target in TARGETS {
                 if target != host {
                     extensions.push(Component {
index 40318141e04fa57716c45c673ab798eb33357789..d5b95c08306b27afc372d866f5bda97b814e7368 100644 (file)
@@ -8,5 +8,5 @@ license = "MIT/Apache-2.0"
 clap = "2.19.3"
 
 [dependencies.mdbook]
-version = "0.0.17"
+version = "0.0.18"
 default-features = false