New upstream version 1.32.0+dfsg1

This commit is contained in:
Ximin Luo 2019-01-27 21:51:14 -08:00
parent a1dfa0c682
commit 69743fb678
288 changed files with 4337 additions and 3485 deletions

96
Cargo.lock generated
View File

@ -69,7 +69,7 @@ name = "atty"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -81,7 +81,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -92,7 +92,7 @@ version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -128,7 +128,7 @@ dependencies = [
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -205,7 +205,7 @@ dependencies = [
"jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"libgit2-sys 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -223,7 +223,7 @@ dependencies = [
"serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -392,7 +392,7 @@ name = "commoncrypto-sys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -412,7 +412,7 @@ dependencies = [
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -431,7 +431,7 @@ dependencies = [
"diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -455,7 +455,7 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -567,7 +567,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)",
"schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
@ -581,7 +581,7 @@ version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"libnghttp2-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)",
@ -631,7 +631,7 @@ name = "directories"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -756,7 +756,7 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -770,7 +770,7 @@ name = "flate2"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -802,7 +802,7 @@ name = "fs2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -867,7 +867,7 @@ version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"libgit2-sys 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1007,7 +1007,7 @@ dependencies = [
"flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"xz2 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1038,7 +1038,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1046,7 +1046,7 @@ name = "jobserver"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1120,7 +1120,7 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.43"
version = "0.2.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -1130,7 +1130,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1151,7 +1151,7 @@ version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1164,7 +1164,7 @@ version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1213,7 +1213,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1285,7 +1285,7 @@ name = "memchr"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1293,7 +1293,7 @@ name = "memmap"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1316,7 +1316,7 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1384,7 +1384,7 @@ name = "num_cpus"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1411,7 +1411,7 @@ dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1434,7 +1434,7 @@ version = "0.9.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-src 111.0.1+1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1500,7 +1500,7 @@ name = "parking_lot_core"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1511,7 +1511,7 @@ name = "parking_lot_core"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1737,7 +1737,7 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1748,7 +1748,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1774,7 +1774,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2127,7 +2127,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2213,7 +2213,7 @@ dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2754,7 +2754,7 @@ version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2939,11 +2939,11 @@ dependencies = [
[[package]]
name = "tar"
version = "0.4.19"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2953,7 +2953,7 @@ name = "tempfile"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2996,7 +2996,7 @@ name = "termion"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -3040,7 +3040,7 @@ name = "time"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -3197,7 +3197,7 @@ name = "wait-timeout"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -3261,7 +3261,7 @@ name = "xattr"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -3377,7 +3377,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7"
"checksum lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddba4c30a78328befecec92fc94970e53b3ae385827d28620f0f5bb2493081e0"
"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
"checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74"
"checksum libgit2-sys 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4916b5addc78ec36cc309acfcdf0b9f9d97ab7b84083118b248709c5b7029356"
"checksum libnghttp2-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ffbfb81475cc9f625e44f3a8f8b9cf7173815ae1c7cc2fa91853ec009e38198"
"checksum libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "126a1f4078368b163bfdee65fbab072af08a1b374a5551b21e87ade27b1fbf9d"
@ -3506,7 +3506,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)" = "816b7af21405b011a23554ea2dc3f6576dc86ca557047c34098c1d741f10f823"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7"
"checksum tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "69e16840a1e0a1f1a880b739ef1cc6a4b85496c99b8aa786ccffce6e0c15624c"
"checksum tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "a303ba60a099fcd2aaa646b14d2724591a96a75283e4b7ed3d1a1658909d9ae2"
"checksum tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c4b103c6d08d323b92ff42c8ce62abcd83ca8efa7fd5bf7927efefec75f58c76"
"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561"

View File

@ -1,3 +1,312 @@
Version 1.32.0 (2019-01-17)
==========================
Language
--------
#### 2018 edition
- [You can now use the `?` operator in macro definitions.][56245] The `?`
operator allows you to specify zero or one repetitions similar to the `*` and
`+` operators.
- [Module paths with no leading keyword like `super`, `self`, or `crate`, will
now always resolve to the item (`enum`, `struct`, etc.) available in the
module if present, before resolving to a external crate or an item the prelude.][56759]
E.g.
```rust
enum Color { Red, Green, Blue }
use Color::*;
```
#### All editions
- [You can now match against `PhantomData<T>` types.][55837]
- [You can now match against literals in macros with the `literal`
specifier.][56072] This will match against a literal of any type.
E.g. `1`, `'A'`, `"Hello World"`
- [Self can now be used as a constructor and pattern for unit and tuple structs.][56365] E.g.
```rust
struct Point(i32, i32);
impl Point {
pub fn new(x: i32, y: i32) -> Self {
Self(x, y)
}
pub fn is_origin(&self) -> bool {
match self {
Self(0, 0) => true,
_ => false,
}
}
}
```
- [Self can also now be used in type definitions.][56366] E.g.
```rust
enum List<T>
where
Self: PartialOrd<Self> // can write `Self` instead of `List<T>`
{
Nil,
Cons(T, Box<Self>) // likewise here
}
```
- [You can now mark traits with `#[must_use]`.][55663] This provides a warning if
a `impl Trait` or `dyn Trait` is returned and unused in the program.
Compiler
--------
- [The default allocator has changed from jemalloc to the default allocator on
your system.][55238] The compiler itself on Linux & macOS will still use
jemalloc, but programs compiled with it will use the system allocator.
- [Added the `aarch64-pc-windows-msvc` target.][55702]
Libraries
---------
- [`PathBuf` now implements `FromStr`.][55148]
- [`Box<[T]>` now implements `FromIterator<T>`.][55843]
- [The `dbg!` macro has been stabilized.][56395] This macro enables you to
easily debug expressions in your rust program. E.g.
```rust
let a = 2;
let b = dbg!(a * 2) + 1;
// ^-- prints: [src/main.rs:4] a * 2 = 4
assert_eq!(b, 5);
```
The following APIs are now `const` functions and can be used in a
`const` context.
- [`Cell::as_ptr`]
- [`UnsafeCell::get`]
- [`char::is_ascii`]
- [`iter::empty`]
- [`ManuallyDrop::new`]
- [`ManuallyDrop::into_inner`]
- [`RangeInclusive::start`]
- [`RangeInclusive::end`]
- [`NonNull::as_ptr`]
- [`slice::as_ptr`]
- [`str::as_ptr`]
- [`Duration::as_secs`]
- [`Duration::subsec_millis`]
- [`Duration::subsec_micros`]
- [`Duration::subsec_nanos`]
- [`CStr::as_ptr`]
- [`Ipv4Addr::is_unspecified`]
- [`Ipv6Addr::new`]
- [`Ipv6Addr::octets`]
Stabilized APIs
---------------
- [`i8::to_be_bytes`]
- [`i8::to_le_bytes`]
- [`i8::to_ne_bytes`]
- [`i8::from_be_bytes`]
- [`i8::from_le_bytes`]
- [`i8::from_ne_bytes`]
- [`i16::to_be_bytes`]
- [`i16::to_le_bytes`]
- [`i16::to_ne_bytes`]
- [`i16::from_be_bytes`]
- [`i16::from_le_bytes`]
- [`i16::from_ne_bytes`]
- [`i32::to_be_bytes`]
- [`i32::to_le_bytes`]
- [`i32::to_ne_bytes`]
- [`i32::from_be_bytes`]
- [`i32::from_le_bytes`]
- [`i32::from_ne_bytes`]
- [`i64::to_be_bytes`]
- [`i64::to_le_bytes`]
- [`i64::to_ne_bytes`]
- [`i64::from_be_bytes`]
- [`i64::from_le_bytes`]
- [`i64::from_ne_bytes`]
- [`i128::to_be_bytes`]
- [`i128::to_le_bytes`]
- [`i128::to_ne_bytes`]
- [`i128::from_be_bytes`]
- [`i128::from_le_bytes`]
- [`i128::from_ne_bytes`]
- [`isize::to_be_bytes`]
- [`isize::to_le_bytes`]
- [`isize::to_ne_bytes`]
- [`isize::from_be_bytes`]
- [`isize::from_le_bytes`]
- [`isize::from_ne_bytes`]
- [`u8::to_be_bytes`]
- [`u8::to_le_bytes`]
- [`u8::to_ne_bytes`]
- [`u8::from_be_bytes`]
- [`u8::from_le_bytes`]
- [`u8::from_ne_bytes`]
- [`u16::to_be_bytes`]
- [`u16::to_le_bytes`]
- [`u16::to_ne_bytes`]
- [`u16::from_be_bytes`]
- [`u16::from_le_bytes`]
- [`u16::from_ne_bytes`]
- [`u32::to_be_bytes`]
- [`u32::to_le_bytes`]
- [`u32::to_ne_bytes`]
- [`u32::from_be_bytes`]
- [`u32::from_le_bytes`]
- [`u32::from_ne_bytes`]
- [`u64::to_be_bytes`]
- [`u64::to_le_bytes`]
- [`u64::to_ne_bytes`]
- [`u64::from_be_bytes`]
- [`u64::from_le_bytes`]
- [`u64::from_ne_bytes`]
- [`u128::to_be_bytes`]
- [`u128::to_le_bytes`]
- [`u128::to_ne_bytes`]
- [`u128::from_be_bytes`]
- [`u128::from_le_bytes`]
- [`u128::from_ne_bytes`]
- [`usize::to_be_bytes`]
- [`usize::to_le_bytes`]
- [`usize::to_ne_bytes`]
- [`usize::from_be_bytes`]
- [`usize::from_le_bytes`]
- [`usize::from_ne_bytes`]
Cargo
-----
- [You can now run `cargo c` as an alias for `cargo check`.][cargo/6218]
- [Usernames are now allowed in alt registry URLs.][cargo/6242]
Misc
----
- [`libproc_macro` has been added to the `rust-src` distribution.][55280]
Compatibility Notes
-------------------
- [The argument types for AVX's
`_mm256_stream_si256`, `_mm256_stream_pd`, `_mm256_stream_ps`][55610] have
been changed from `*const` to `*mut` as the previous implementation
was unsound.
[55148]: https://github.com/rust-lang/rust/pull/55148/
[55238]: https://github.com/rust-lang/rust/pull/55238/
[55280]: https://github.com/rust-lang/rust/pull/55280/
[55610]: https://github.com/rust-lang/rust/pull/55610/
[55663]: https://github.com/rust-lang/rust/pull/55663/
[55702]: https://github.com/rust-lang/rust/pull/55702/
[55837]: https://github.com/rust-lang/rust/pull/55837/
[55843]: https://github.com/rust-lang/rust/pull/55843/
[56072]: https://github.com/rust-lang/rust/pull/56072/
[56245]: https://github.com/rust-lang/rust/pull/56245/
[56365]: https://github.com/rust-lang/rust/pull/56365/
[56366]: https://github.com/rust-lang/rust/pull/56366/
[56395]: https://github.com/rust-lang/rust/pull/56395/
[56759]: https://github.com/rust-lang/rust/pull/56759/
[cargo/6218]: https://github.com/rust-lang/cargo/pull/6218/
[cargo/6242]: https://github.com/rust-lang/cargo/pull/6242/
[`CStr::as_ptr`]: https://doc.rust-lang.org/std/ffi/struct.CStr.html#method.as_ptr
[`Cell::as_ptr`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.as_ptr
[`Duration::as_secs`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs
[`Duration::subsec_micros`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.subsec_micros
[`Duration::subsec_millis`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.subsec_millis
[`Duration::subsec_nanos`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.subsec_nanos
[`Ipv4Addr::is_unspecified`]: https://doc.rust-lang.org/std/net/struct.Ipv4Addr.html#method.is_unspecified
[`Ipv6Addr::new`]: https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html#method.new
[`Ipv6Addr::octets`]: https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html#method.octets
[`ManuallyDrop::into_inner`]: https://doc.rust-lang.org/std/mem/struct.ManuallyDrop.html#method.into_inner
[`ManuallyDrop::new`]: https://doc.rust-lang.org/std/mem/struct.ManuallyDrop.html#method.new
[`NonNull::as_ptr`]: https://doc.rust-lang.org/std/ptr/struct.NonNull.html#method.as_ptr
[`RangeInclusive::end`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html#method.end
[`RangeInclusive::start`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html#method.start
[`UnsafeCell::get`]: https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html#method.get
[`slice::as_ptr`]: https://doc.rust-lang.org/std/primitive.slice.html#method.as_ptr
[`char::is_ascii`]: https://doc.rust-lang.org/std/primitive.char.html#method.is_ascii
[`i128::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.from_be_bytes
[`i128::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.from_le_bytes
[`i128::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.from_ne_bytes
[`i128::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.to_be_bytes
[`i128::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.to_le_bytes
[`i128::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.to_ne_bytes
[`i16::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.from_be_bytes
[`i16::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.from_le_bytes
[`i16::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.from_ne_bytes
[`i16::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.to_be_bytes
[`i16::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.to_le_bytes
[`i16::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.to_ne_bytes
[`i32::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.from_be_bytes
[`i32::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.from_le_bytes
[`i32::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.from_ne_bytes
[`i32::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.to_be_bytes
[`i32::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.to_le_bytes
[`i32::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.to_ne_bytes
[`i64::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.from_be_bytes
[`i64::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.from_le_bytes
[`i64::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.from_ne_bytes
[`i64::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.to_be_bytes
[`i64::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.to_le_bytes
[`i64::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.to_ne_bytes
[`i8::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.from_be_bytes
[`i8::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.from_le_bytes
[`i8::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.from_ne_bytes
[`i8::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.to_be_bytes
[`i8::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.to_le_bytes
[`i8::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.to_ne_bytes
[`isize::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.from_be_bytes
[`isize::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.from_le_bytes
[`isize::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.from_ne_bytes
[`isize::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.to_be_bytes
[`isize::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.to_le_bytes
[`isize::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.to_ne_bytes
[`iter::empty`]: https://doc.rust-lang.org/std/iter/fn.empty.html
[`str::as_ptr`]: https://doc.rust-lang.org/std/primitive.str.html#method.as_ptr
[`u128::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.from_be_bytes
[`u128::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.from_le_bytes
[`u128::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.from_ne_bytes
[`u128::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.to_be_bytes
[`u128::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.to_le_bytes
[`u128::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.to_ne_bytes
[`u16::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.from_be_bytes
[`u16::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.from_le_bytes
[`u16::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.from_ne_bytes
[`u16::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.to_be_bytes
[`u16::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.to_le_bytes
[`u16::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.to_ne_bytes
[`u32::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.from_be_bytes
[`u32::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.from_le_bytes
[`u32::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.from_ne_bytes
[`u32::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.to_be_bytes
[`u32::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.to_le_bytes
[`u32::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.to_ne_bytes
[`u64::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.from_be_bytes
[`u64::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.from_le_bytes
[`u64::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.from_ne_bytes
[`u64::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.to_be_bytes
[`u64::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.to_le_bytes
[`u64::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.to_ne_bytes
[`u8::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.from_be_bytes
[`u8::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.from_le_bytes
[`u8::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.from_ne_bytes
[`u8::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_be_bytes
[`u8::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_le_bytes
[`u8::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_ne_bytes
[`usize::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.from_be_bytes
[`usize::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.from_le_bytes
[`usize::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.from_ne_bytes
[`usize::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.to_be_bytes
[`usize::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.to_le_bytes
[`usize::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.to_ne_bytes
Version 1.31.1 (2018-12-20)
===========================
- [Fix Rust failing to build on `powerpc-unknown-netbsd`][56562]
- [Fix broken go-to-definition in RLS][rls/1171]
- [Fix infinite loop on hover in RLS][rls/1170]
[56562]: https://github.com/rust-lang/rust/pull/56562
[rls/1171]: https://github.com/rust-lang/rls/issues/1171
[rls/1170]: https://github.com/rust-lang/rls/pull/1170
Version 1.31.0 (2018-12-06)
==========================

View File

@ -1 +1 @@
a01e4761a1507939430d4044a5f0a35fdb2b146c
9fda7c2237db910e41d6a712e9a2139b352e558b

View File

@ -67,7 +67,7 @@ RUN ./build-gcc.sh
COPY dist-x86_64-linux/build-python.sh /tmp/
RUN ./build-python.sh
# Now build LLVM+Clang 7, afterwards configuring further compilations to use the
# Now build LLVM+Clang 6, afterwards configuring further compilations to use the
# clang/clang++ compilers.
COPY dist-x86_64-linux/build-clang.sh /tmp/
RUN ./build-clang.sh

View File

@ -67,7 +67,7 @@ RUN ./build-gcc.sh
COPY dist-x86_64-linux/build-python.sh /tmp/
RUN ./build-python.sh
# Now build LLVM+Clang 7, afterwards configuring further compilations to use the
# Now build LLVM+Clang 6, afterwards configuring further compilations to use the
# clang/clang++ compilers.
COPY dist-x86_64-linux/build-clang.sh /tmp/
RUN ./build-clang.sh

View File

@ -13,7 +13,7 @@ set -ex
source shared.sh
LLVM=7.0.0
LLVM=6.0.0
mkdir clang
cd clang

View File

@ -20,4 +20,5 @@ COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
ENV SCRIPT python2.7 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu
ENV SCRIPT python2.7 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
python2.7 ../x.py build --stage 0 src/tools/build-manifest

View File

@ -51,7 +51,7 @@ hide_output make clean
cd ..
LLVM=70
LLVM=60
# may have been downloaded in a previous run
if [ ! -d libunwind-release_$LLVM ]; then

View File

@ -52,7 +52,7 @@ fi
#
# FIXME: need a scheme for changing this `nightly` value to `beta` and `stable`
# either automatically or manually.
export RUST_RELEASE_CHANNEL=beta
export RUST_RELEASE_CHANNEL=stable
if [ "$DEPLOY$DEPLOY_ALT" != "" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL"
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp"

View File

@ -20,5 +20,5 @@ Here are the relevant sections in the new and old books:
* <small>[In the first edition: Ch 3.27 — Attributes][1]</small>
[1]: first-edition/attributes.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/attributes.html
[2]: ../reference/attributes.html

View File

@ -9,6 +9,6 @@ You might be interested in a similar page in [the Rust Reference][3].
* <small>[In the first edition: Section 7 — Bibliography][1]</small>
[1]: first-edition/bibliography.html
[2]: second-edition/index.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/bibliography.html
[2]: index.html
[3]: ../reference/influences.html

View File

@ -20,6 +20,6 @@ The best place to learn more about this is [the Rust documentation][3].
* <small>[In the first edition: Ch 4.10 — Borrow and AsRef][1]</small>
[1]: first-edition/borrow-and-asref.html
[2]: second-edition/index.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/borrow-and-asref.html
[2]: index.html
[3]: ../std/convert/trait.AsRef.html

View File

@ -20,13 +20,13 @@ fn average(values: &[f64]) -> f64 {
Here are the relevant sections in the new and old books:
* **[In the second edition: Appendix A — Keywords][2]**
* **[in the current edition: Appendix A — Keywords][2]**
* [In the Rust Reference: Type Cast Expressions][3]
* [In the Rust documentation: `mem::transmute`][4]
* <small>[In the first edition: Ch 3.29 — Casting between types][1]</small>
[1]: first-edition/casting-between-types.html
[2]: second-edition/appendix-01-keywords.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/casting-between-types.html
[2]: appendix-01-keywords.html
[3]: ../reference/expressions/operator-expr.html#type-cast-expressions
[4]: ../std/mem/fn.transmute.html

View File

@ -14,9 +14,9 @@ println!("b = {}", b);
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 15.00 — Smart Pointers][2]**
* **[In the current edition: Ch 15.00 — Smart Pointers][2]**
* <small>[In the first edition: Ch 4.8 — Choosing your Guarantees][1]</small>
[1]: first-edition/choosing-your-guarantees.html
[2]: second-edition/ch15-00-smart-pointers.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/choosing-your-guarantees.html
[2]: ch15-00-smart-pointers.html

View File

@ -20,9 +20,9 @@ let expensive_closure = |num| {
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 13.01 — Closures][2]**
* **[in the current edition: Ch 13.01 — Closures][2]**
* <small>[In the first edition: Ch 3.23 — Closures][1]</small>
[1]: first-edition/closures.html
[2]: second-edition/ch13-01-closures.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/closures.html
[2]: ch13-01-closures.html

View File

@ -15,9 +15,9 @@
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 3.04 — Comments][2]**
* **[in the current edition: Ch 3.04 — Comments][2]**
* <small>[In the first edition: Ch 3.4 — Comments][1]</small>
[1]: first-edition/comments.html
[2]: second-edition/ch03-04-comments.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/comments.html
[2]: ch03-04-comments.html

View File

@ -9,9 +9,9 @@
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 16.00 — Fearless Concurrency][2]**
* **[in the current edition: Ch 16.00 — Fearless Concurrency][2]**
* <small>[In the first edition: Ch 4.6 — Concurrency][1]</small>
[1]: first-edition/concurrency.html
[2]: second-edition/ch16-00-concurrency.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/concurrency.html
[2]: ch16-00-concurrency.html

View File

@ -23,6 +23,6 @@ The best place to learn about it is [the Rust Reference][3].
* <small>[In the first edition: Ch 4.3 — Conditional Compilation][1]</small>
[1]: first-edition/conditional-compilation.html
[2]: second-edition/index.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/conditional-compilation.html
[2]: index.html
[3]: ../reference/attributes.html#conditional-compilation

View File

@ -18,11 +18,11 @@ mod network {
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 7.01 — `mod` and the Filesystem][2]**
* [In the second edition: Ch 14.02 — Publishing a Crate to Crates.io][3]
* **[in the current edition: Ch 7.01 — `mod` and the Filesystem][2]**
* [in the current edition: Ch 14.02 — Publishing a Crate to Crates.io][3]
* <small>[In the first edition: Ch 3.25 — Crates and Modules][1]</small>
[1]: first-edition/crates-and-modules.html
[2]: second-edition/ch07-01-mod-and-the-filesystem.html
[3]: second-edition/ch14-02-publishing-to-crates-io.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/crates-and-modules.html
[2]: ch07-00-packages-crates-and-modules.html
[3]: ch14-02-publishing-to-crates-io.html

View File

@ -22,9 +22,9 @@ impl<T> Deref for MyBox<T> {
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 15.02 — Treating Smart Pointers like Regular References with the `Deref` Trait][2]**
* **[in the current edition: Ch 15.02 — Treating Smart Pointers like Regular References with the `Deref` Trait][2]**
* <small>[In the first edition: Ch 3.33 — Deref coercions][1]</small>
[1]: first-edition/deref-coercions.html
[2]: second-edition/ch15-02-deref.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/deref-coercions.html
[2]: ch15-02-deref.html

View File

@ -26,9 +26,9 @@ fn main() {
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 15.03 — The `Drop` Trait Runs Code on Cleanup][2]**
* **[in the current edition: Ch 15.03 — The `Drop` Trait Runs Code on Cleanup][2]**
* <small>[In the first edition: Ch 3.20 — Drop][1]</small>
[1]: first-edition/drop.html
[2]: second-edition/ch15-03-drop.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/drop.html
[2]: ch15-03-drop.html

View File

@ -10,5 +10,5 @@ It is recommended to start there.
* <small>[In the first edition: Ch 4 — Effective Rust][1]</small>
[1]: first-edition/effective-rust.html
[2]: second-edition/index.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/effective-rust.html
[2]: index.html

View File

@ -15,9 +15,9 @@ enum IpAddrKind {
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 6.01 — Defining an Enum][2]**
* **[in the current edition: Ch 6.01 — Defining an Enum][2]**
* <small>[In the first edition: Ch 3.13 — Enums][1]</small>
[1]: first-edition/enums.html
[2]: second-edition/ch06-01-defining-an-enum.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/enums.html
[2]: ch06-01-defining-an-enum.html

View File

@ -8,9 +8,9 @@
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 9.00 — Error Handling][2]**
* **[in the current edition: Ch 9.00 — Error Handling][2]**
* <small>[In the first edition: Ch 4.7 — Error Handling][1]</small>
[1]: first-edition/error-handling.html
[2]: second-edition/ch09-00-error-handling.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/error-handling.html
[2]: ch09-00-error-handling.html

View File

@ -23,8 +23,8 @@ fn another_function() {
Here are the relevant sections in the new and old books:
* **[In the first edition: Ch 3.2 — Functions][1]**
* <small>[In the second edition: Ch 3.03 — Functions][2]</small>
* <small>[in the current edition: Ch 3.03 — Functions][2]</small>
[1]: first-edition/functions.html
[2]: second-edition/ch03-03-how-functions-work.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/functions.html
[2]: ch03-03-how-functions-work.html

View File

@ -21,10 +21,10 @@ fn main() {
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 10.00 — Generic Types, Traits, and Lifetimes][2]**
* **[in the current edition: Ch 10.00 — Generic Types, Traits, and Lifetimes][2]**
* <small>[In the first edition: Ch 3.18 — Generics][1]</small>
[1]: first-edition/generics.html
[2]: second-edition/ch10-00-generics.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/generics.html
[2]: ch10-00-generics.html

View File

@ -5,9 +5,9 @@
You can [continue to the exact older page][1].
If you're trying to learn Rust, checking out [the second edition][2] might be a better choice.
* **[In the second edition: Getting Started][2]**
* **[in the current edition: Getting Started][2]**
* <small>[In the first edition: Getting Started][1]</small>
[1]: first-edition/getting-started.html
[2]: second-edition/ch01-00-getting-started.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/getting-started.html
[2]: ch01-00-getting-started.html

View File

@ -10,5 +10,5 @@ It is recommended to start there.
* <small>[In the first edition: Glossary][1]</small>
[1]: first-edition/glossary.html
[2]: second-edition/index.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/glossary.html
[2]: index.html

View File

@ -5,8 +5,8 @@
If you're trying to learn Rust, checking out [the second edition][2] might be a better choice.
* **[In the first edition: Tutorial — Guessing Game][1]**
* <small>[In the second edition: Ch 2.00 — Guessing Game tutorial][2]</small>
* <small>[in the current edition: Ch 2.00 — Guessing Game tutorial][2]</small>
[1]: first-edition/guessing-game.html
[2]: second-edition/ch02-00-guessing-game-tutorial.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/guessing-game.html
[2]: ch02-00-guessing-game-tutorial.html

View File

@ -15,9 +15,8 @@ if let Some(3) = some_u8_value {
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 6.03 — Concise Control Flow with `if let`][2]**
* [In the current edition: Ch 6.03 — Concise Control Flow with `if let`][2]
* <small>[In the first edition: Ch 3.21 — if let][1]</small>
[1]: first-edition/if-let.html
[2]: second-edition/ch06-03-if-let.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/if-let.html
[2]: ch06-03-if-let.html

View File

@ -19,9 +19,9 @@ for val in v1_iter {
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 13.02 — Iterators][2]**
* **[in the current edition: Ch 13.02 — Iterators][2]**
* <small>[In the first edition: Ch 4.5 — Iterators][1]</small>
[1]: first-edition/iterators.html
[2]: second-edition/ch13-02-iterators.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/iterators.html
[2]: ch13-02-iterators.html

View File

@ -20,11 +20,11 @@
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 10.03 — Lifetimes][2]**
* [In the second edition: Ch 19.02 — Advanced Lifetimes][3]
* **[in the current edition: Ch 10.03 — Lifetimes][2]**
* [in the current edition: Ch 19.02 — Advanced Lifetimes][3]
* <small>[In the first edition: Ch 3.10 — Lifetimes][1]</small>
[1]: first-edition/lifetimes.html
[2]: second-edition/ch10-03-lifetime-syntax.html
[3]: second-edition/ch19-02-advanced-lifetimes.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/lifetimes.html
[2]: ch10-03-lifetime-syntax.html
[3]: ch19-02-advanced-lifetimes.html

View File

@ -18,13 +18,13 @@ fn main() {
Here are the relevant sections in the new and old books:
* **[In the second edition: Appendix D — Macros][2]**
* **[In the current edition: Ch 19.06 Macros][2]**
* [Rust By Example: Macros][3]
* [In the Rust Reference: Ch 3.1 — Macros by Example][4]
* <small>[In the first edition: Ch 3.34 — Macros][1]</small>
[1]: first-edition/macros.html
[2]: second-edition/appendix-04-macros.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/macros.html
[2]: ch19-06-macros.html
[3]: https://rustbyexample.com/macros.html
[4]: ../reference/macros-by-example.html

View File

@ -27,12 +27,12 @@ fn value_in_cents(coin: Coin) -> u32 {
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 6.02 — The `match` Control Flow Operator][2]**
* [In the second edition: Ch 18.00 — Patterns][3]
* **[in the current edition: Ch 6.02 — The `match` Control Flow Operator][2]**
* [in the current edition: Ch 18.00 — Patterns][3]
* <small>[In the first edition: Ch 3.14 — Match][1]</small>
[1]: first-edition/match.html
[2]: second-edition/ch06-02-match.html
[3]: second-edition/ch18-00-patterns.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/match.html
[2]: ch06-02-match.html
[3]: ch18-00-patterns.html

View File

@ -21,9 +21,9 @@ impl Rectangle {
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 5.03 — Method Syntax][2]**
* **[in the current edition: Ch 5.03 — Method Syntax][2]**
* <small>[In the first edition: Ch 3.16 — Method Syntax][1]</small>
[1]: first-edition/method-syntax.html
[2]: second-edition/ch05-03-method-syntax.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/method-syntax.html
[2]: ch05-03-method-syntax.html

View File

@ -15,9 +15,9 @@ println!("The value of x is: {}", x);
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 3.01 — Variables and Mutability][2]**
* **[in the current edition: Ch 3.01 — Variables and Mutability][2]**
* <small>[In the first edition: Ch 3.11 — Mutability][1]</small>
[1]: first-edition/mutability.html
[2]: second-edition/ch03-01-variables-and-mutability.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/mutability.html
[2]: ch03-01-variables-and-mutability.html

View File

@ -12,9 +12,9 @@
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 4.00 — Understanding Ownership][2]**
* **[in the current edition: Ch 4.00 — Understanding Ownership][2]**
* <small>[In the first edition: Ch 3.8 — Ownership][1]</small>
[1]: first-edition/ownership.html
[2]: second-edition/ch04-00-understanding-ownership.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/ownership.html
[2]: ch04-00-understanding-ownership.html

View File

@ -16,9 +16,9 @@ let y: f32 = 3.0; // f32
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 3.02 — Data Types][2]**
* **[in the current edition: Ch 3.02 — Data Types][2]**
* <small>[In the first edition: Ch 3.3 — Primitive Types][1]</small>
[1]: first-edition/primitive-types.html
[2]: second-edition/ch03-02-data-types.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/primitive-types.html
[2]: ch03-02-data-types.html

View File

@ -9,13 +9,13 @@
This chapter does not exist yet in [the second edition][2].
You can check out other resources that describe macros.
* **[In the Rust Reference: Ch 3.2 — Procedural Macros][4]**
* **[In the current edition: Ch 19.06 Macros][2]**
* [In the Rust Reference: Ch 3.2 — Procedural Macros][4]
* [The `proc_macro` crate documentation][3]
* [In the second edition: (future) Appendix D — Macros][2]
* <small>[In the first edition: Ch 4.13 — Procedural Macros (and custom Derive)][1]</small>
[1]: first-edition/procedural-macros.html
[2]: second-edition/appendix-04-macros.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/procedural-macros.html
[2]: ch19-06-macros.html
[3]: ../proc_macro/index.html
[4]: ../reference/procedural-macros.html
[4]: ../reference/procedural-macros.html

View File

@ -16,9 +16,9 @@ fn calculate_length(s: &String) -> usize { // s is a reference to a String
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 4.02 — References and Borrowing][2]**
* **[in the current edition: Ch 4.02 — References and Borrowing][2]**
* <small>[In the first edition: Ch 3.9 — References and Borrowing][1]</small>
[1]: first-edition/references-and-borrowing.html
[2]: second-edition/ch04-02-references-and-borrowing.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/references-and-borrowing.html
[2]: ch04-02-references-and-borrowing.html

View File

@ -16,12 +16,12 @@ You can check out other resources that describe release channels.
* **[In the Rustup documentation: Keeping Rust Up-to-date][4]**
* [On the website: Install Rust][5]
* [In the Rust RFCs: RFC 507 — Release Channels][3]
* [In the second edition: How Rust is Made and “Nightly Rust”][2]
* [in the current edition: How Rust is Made and “Nightly Rust”][2]
* <small>[In the first edition: Ch 4.11 — Release Channels][1]</small>
[1]: first-edition/release-channels.html
[2]: second-edition/appendix-07-nightly-rust.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/release-channels.html
[2]: appendix-07-nightly-rust.html
[3]: https://github.com/rust-lang/rfcs/blob/master/text/0507-release-channels.md
[4]: https://github.com/rust-lang-nursery/rustup.rs/blob/master/README.md#keeping-rust-up-to-date
[5]: https://www.rust-lang.org/en-US/install.html

View File

@ -21,5 +21,5 @@ Here are the relevant sections in the new and old books:
* <small>[In the first edition: Ch 3.12 — Structs][1]</small>
[1]: first-edition/structs.html
[2]: second-edition/ch05-00-structs.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/structs.html
[2]: ch05-00-structs.html

View File

@ -5,14 +5,14 @@
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 3.00 — Common Programming Concepts][2]**
* [In the second edition: Appendix A — Keywords][3]
* [In the second edition: Appendix B — Operators][4]
* **[in the current edition: Ch 3.00 — Common Programming Concepts][2]**
* [in the current edition: Appendix A — Keywords][3]
* [in the current edition: Appendix B — Operators][4]
* <small>[In the first edition: Ch 3 — Syntax and Semantics][1]</small>
[1]: first-edition/syntax-and-semantics.html
[2]: second-edition/ch03-00-common-programming-concepts.html
[3]: second-edition/appendix-01-keywords.html
[4]: second-edition/appendix-02-operators.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/syntax-and-semantics.html
[2]: ch03-00-common-programming-concepts.html
[3]: appendix-01-keywords.html
[4]: appendix-02-operators.html

View File

@ -4,11 +4,10 @@
Here are the relevant sections in the new and old books:
* **[In the second edition: Appendix A — Keywords][2]**
* **[In the second edition: Appendix B — Operators][3]**
* **[In the current edition: Appendix A — Keywords][2]**
* **[In the current edition: Appendix B — Operators][3]**
* <small>[In the first edition: Ch 6 — Syntax Index][1]</small>
[1]: first-edition/syntax-index.html
[2]: second-edition/appendix-01-keywords.html
[3]: second-edition/appendix-02-operators.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/syntax-index.html
[2]: appendix-01-keywords.html
[3]: appendix-02-operators.html

View File

@ -17,9 +17,9 @@ mod tests {
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 11.00 — Testing][2]**
* **[in the current edition: Ch 11.00 — Testing][2]**
* <small>[In the first edition: Ch 4.2 — Testing][1]</small>
[1]: first-edition/testing.html
[2]: second-edition/ch11-00-testing.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/testing.html
[2]: ch11-00-testing.html

View File

@ -60,9 +60,9 @@ fn main() {
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 17.02 — Trait Objects][2]**
* **[in the current edition: Ch 17.02 — Trait Objects][2]**
* <small>[In the first edition: Ch 3.22 — Trait Objects][1]</small>
[1]: first-edition/trait-objects.html
[2]: second-edition/ch17-02-trait-objects.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/trait-objects.html
[2]: ch17-02-trait-objects.html

View File

@ -14,11 +14,11 @@ pub trait Summarizable {
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 10.02 — Traits][2]**
* [In the second edition: Ch 19.03 — Advanced Traits][3]
* **[in the current edition: Ch 10.02 — Traits][2]**
* [in the current edition: Ch 19.03 — Advanced Traits][3]
* <small>[In the first edition: Ch 3.19 — Traits][1]</small>
[1]: first-edition/traits.html
[2]: second-edition/ch10-02-traits.html
[3]: second-edition/ch19-03-advanced-traits.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/traits.html
[2]: ch10-02-traits.html
[3]: ch19-03-advanced-traits.html

View File

@ -8,11 +8,11 @@
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 19.01 — Unsafe Rust][2]**
* **[in the current edition: Ch 19.01 — Unsafe Rust][2]**
* [The Rustonomicon, The Dark Arts of Advanced and Unsafe Rust Programming][3]
* <small>[In the first edition: Ch 3.36 — `unsafe`][1]</small>
[1]: first-edition/unsafe.html
[2]: second-edition/ch19-01-unsafe-rust.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/unsafe.html
[2]: ch19-01-unsafe-rust.html
[3]: ../nomicon/index.html

View File

@ -13,5 +13,5 @@ This particular chapter has moved to [the Unstable Book][2].
* <small>[In the first edition: Ch 4.12 — Using Rust without the Standard Library][1]</small>
[1]: first-edition/using-rust-without-the-standard-library.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/using-rust-without-the-standard-library.html
[2]: ../unstable-book/language-features/lang-items.html#writing-an-executable-without-stdlib

View File

@ -14,10 +14,10 @@ let numbers = vec![1, 2, 3];
Here are the relevant sections in the new and old books:
* **[In the second edition: Ch 8.01 — Vectors][2]**
* **[in the current edition: Ch 8.01 — Vectors][2]**
* <small>[In the first edition: Ch 3.7 — Vectors][1]</small>
[1]: first-edition/vectors.html
[2]: second-edition/ch08-01-vectors.html
[1]: https://doc.rust-lang.org/1.30.0/book/first-edition/vectors.html
[2]: ch08-01-vectors.html

View File

@ -15,7 +15,7 @@ library that you can use with `derive`. Each section covers:
* Examples of operations that require the trait
If you want different behavior than that provided by the `derive` attribute,
consult the [standard library documentation](../std/index.html)
consult the [standard library documentation](../std/index.html)<!-- ignore -->
for each trait for details of how to manually implement them.
The rest of the traits defined in the standard library cant be implemented on

View File

@ -188,4 +188,4 @@ doesnt compile.
The source files from which this book is generated can be found on
[GitHub][book].
[book]: https://github.com/rust-lang/book/tree/master/2018-edition/src
[book]: https://github.com/rust-lang/book/tree/master/src

View File

@ -35,6 +35,7 @@ Look at the generated *Cargo.toml* file:
name = "guessing_game"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
edition = "2018"
[dependencies]
```
@ -169,12 +170,12 @@ let mut bar = 5; // mutable
> line. Rust ignores everything in comments, which are discussed in more detail
> in Chapter 3.
Now you know that `let mut guess` will introduce a mutable variable named
`guess`. On the other side of the equal sign (`=`) is the value that `guess` is
bound to, which is the result of calling `String::new`, a function that returns
a new instance of a `String`. [`String`][string]<!-- ignore --> is a string
type provided by the standard library that is a growable, UTF-8 encoded bit of
text.
Let's return to the guessing game program. You now know that `let mut guess`
will introduce a mutable variable named `guess`. On the other side of the equal
sign (`=`) is the value that `guess` is bound to, which is the result of
calling `String::new`, a function that returns a new instance of a `String`.
[`String`][string]<!-- ignore --> is a string type provided by the standard
library that is a growable, UTF-8 encoded bit of text.
[string]: ../std/string/struct.String.html
@ -271,14 +272,14 @@ The `Err` variant means the operation failed, and `Err` contains information
about how or why the operation failed.
The purpose of these `Result` types is to encode error-handling information.
Values of the `Result` type, like any type, have methods defined on them. An
instance of `io::Result` has an [`expect` method][expect]<!-- ignore --> that
you can call. If this instance of `io::Result` is an `Err` value, `expect` will
cause the program to crash and display the message that you passed as an
argument to `expect`. If the `read_line` method returns an `Err`, it would
likely be the result of an error coming from the underlying operating system.
If this instance of `io::Result` is an `Ok` value, `expect` will take the
return value that `Ok` is holding and return just that value to you so you
Values of the `Result` type, like values of any type, have methods defined on
them. An instance of `io::Result` has an [`expect` method][expect]<!-- ignore
--> that you can call. If this instance of `io::Result` is an `Err` value,
`expect` will cause the program to crash and display the message that you
passed as an argument to `expect`. If the `read_line` method returns an `Err`,
it would likely be the result of an error coming from the underlying operating
system. If this instance of `io::Result` is an `Ok` value, `expect` will take
the return value that `Ok` is holding and return just that value to you so you
can use it. In this case, that value is the number of bytes in what the user
entered into standard input.
@ -302,7 +303,7 @@ Rust warns that you havent used the `Result` value returned from `read_line`,
indicating that the program hasnt handled a possible error.
The right way to suppress the warning is to actually write error handling, but
since you just want to crash this program when a problem occurs, you can use
because you just want to crash this program when a problem occurs, you can use
`expect`. Youll learn about recovering from errors in Chapter 9.
### Printing Values with `println!` Placeholders
@ -392,7 +393,7 @@ version 0.3.14.”
[semver]: http://semver.org
Now, without changing any of the code, lets build the project, as shown in
Listing 2-2:
Listing 2-2.
```text
$ cargo build
@ -450,7 +451,7 @@ your part of the code.
Cargo has a mechanism that ensures you can rebuild the same artifact every time
you or anyone else builds your code: Cargo will use only the versions of the
dependencies you specified until you indicate otherwise. For example, what
happens if next week version `v0.3.15` of the `rand` crate comes out and
happens if next week version 0.3.15 of the `rand` crate comes out and
contains an important bug fix but also contains a regression that will break
your code?
@ -510,7 +511,7 @@ from a number of packages.
### Generating a Random Number
Now that youve added the `rand` crate to *Cargo.toml*, lets start using
`rand`. The next step is to update *src/main.rs*, as shown in Listing 2-3:
`rand`. The next step is to update *src/main.rs*, as shown in Listing 2-3.
<span class="filename">Filename: src/main.rs</span>
@ -608,6 +609,7 @@ use std::cmp::Ordering;
use rand::Rng;
fn main() {
// ---snip---
println!("You guessed: {}", guess);
@ -629,9 +631,8 @@ The first new bit here is another `use` statement, bringing a type called
`Greater`, and `Equal`. These are the three outcomes that are possible when you
compare two values.
Then we add five new lines at the bottom that use the `Ordering` type.
The `cmp` method compares two values and can be called on anything that can be
Then we add five new lines at the bottom that use the `Ordering` type. The
`cmp` method compares two values and can be called on anything that can be
compared. It takes a reference to whatever you want to compare with: here its
comparing the `guess` to the `secret_number`. Then it returns a variant of the
`Ordering` enum we brought into scope with the `use` statement. We use a
@ -729,7 +730,7 @@ a variable named `guess`? It does, but Rust allows us to *shadow* the previous
value of `guess` with a new one. This feature is often used in situations in
which you want to convert a value from one type to another type. Shadowing lets
us reuse the `guess` variable name rather than forcing us to create two unique
variables, like `guess_str` and `guess` for example. (Chapter 3 covers
variables, such as `guess_str` and `guess` for example. (Chapter 3 covers
shadowing in more detail.)
We bind `guess` to the expression `guess.trim().parse()`. The `guess` in the
@ -774,7 +775,7 @@ Lets run the program now!
$ cargo run
Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
Finished dev [unoptimized + debuginfo] target(s) in 0.43 secs
Running `target/guessing_game`
Running `target/debug/guessing_game`
Guess the number!
The secret number is: 58
Please input your guess.
@ -834,7 +835,7 @@ shown here:
$ cargo run
Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
Finished dev [unoptimized + debuginfo] target(s) in 1.50 secs
Running `target/guessing_game`
Running `target/debug/guessing_game`
Guess the number!
The secret number is: 59
Please input your guess.
@ -890,15 +891,29 @@ exiting the program, because the loop is the last part of `main`.
To further refine the games behavior, rather than crashing the program when
the user inputs a non-number, lets make the game ignore a non-number so the
user can continue guessing. We can do that by altering the line where `guess`
is converted from a `String` to a `u32`:
is converted from a `String` to a `u32`, as shown in Listing 2-5.
<span class="filename">Filename: src/main.rs</span>
```rust,ignore
// --snip--
io::stdin().read_line(&mut guess)
.expect("Failed to read line");
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
println!("You guessed: {}", guess);
// --snip--
```
<span class="caption">Listing 2-5: Ignoring a non-number guess and asking for
another guess instead of crashing the program</span>
Switching from an `expect` call to a `match` expression is how you generally
move from crashing on an error to handling the error. Remember that `parse`
returns a `Result` type and `Result` is an enum that has the variants `Ok` or
@ -917,16 +932,16 @@ does not match the `Ok(num)` pattern in the first `match` arm, but it does
match the `Err(_)` pattern in the second arm. The underscore, `_`, is a
catchall value; in this example, were saying we want to match all `Err`
values, no matter what information they have inside them. So the program will
execute the second arms code, `continue`, which means to go to the next
iteration of the `loop` and ask for another guess. So effectively, the program
ignores all errors that `parse` might encounter!
execute the second arms code, `continue`, which tells the program to go to the
next iteration of the `loop` and ask for another guess. So effectively, the
program ignores all errors that `parse` might encounter!
Now everything in the program should work as expected. Lets try it:
```text
$ cargo run
Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
Running `target/guessing_game`
Running `target/debug/guessing_game`
Guess the number!
The secret number is: 61
Please input your guess.
@ -948,7 +963,7 @@ You win!
Awesome! With one tiny final tweak, we will finish the guessing game. Recall
that the program is still printing the secret number. That worked well for
testing, but it ruins the game. Lets delete the `println!` that outputs the
secret number. Listing 2-5 shows the final code:
secret number. Listing 2-6 shows the final code.
<span class="filename">Filename: src/main.rs</span>
@ -989,11 +1004,11 @@ fn main() {
}
```
<span class="caption">Listing 2-5: Complete guessing game code</span>
<span class="caption">Listing 2-6: Complete guessing game code</span>
## Summary
At this point, youve successfully built the guessing game! Congratulations!
At this point, youve successfully built the guessing game. Congratulations!
This project was a hands-on way to introduce you to many new Rust concepts:
`let`, `match`, methods, associated functions, the use of external crates, and

View File

@ -44,9 +44,9 @@ Even though compiler errors can be frustrating, they only mean your program
isnt safely doing what you want it to do yet; they do *not* mean that youre
not a good programmer! Experienced Rustaceans still get compiler errors.
The error indicates that the cause of the error is that you `cannot assign twice
to immutable variable x`, because you tried to assign a second value to the
immutable `x` variable.
The error message indicates that the cause of the error is that you `cannot
assign twice to immutable variable x`, because you tried to assign a second
value to the immutable `x` variable.
Its important that we get compile-time errors when we attempt to change a
value that we previously designated as immutable because this very situation
@ -126,9 +126,9 @@ not the result of a function call or any other value that could only be
computed at runtime.
Heres an example of a constant declaration where the constants name is
`MAX_POINTS` and its value is set to 100,000. (Rusts constant naming
convention is to use all uppercase with underscores between words,
and underscores can be inserted in numeric literals to improve readability):
`MAX_POINTS` and its value is set to 100,000. (Rusts naming convention for
constants is to use all uppercase with underscores between words, and
underscores can be inserted in numeric literals to improve readability):
```rust
const MAX_POINTS: u32 = 100_000;
@ -147,13 +147,13 @@ hardcoded value needed to be updated in the future.
### Shadowing
As you saw in the “Comparing the Guess to the Secret Number” section in Chapter
2, you can declare a new variable with the same name as a previous variable,
and the new variable shadows the previous variable. Rustaceans say that the
first variable is *shadowed* by the second, which means that the second
variables value is what appears when the variable is used. We can shadow a
variable by using the same variables name and repeating the use of the `let`
keyword as follows:
As you saw in the guessing game tutorial in the “Comparing the Guess to the
Secret Number” section in Chapter 2, you can declare a new variable with the
same name as a previous variable, and the new variable shadows the previous
variable. Rustaceans say that the first variable is *shadowed* by the second,
which means that the second variables value is what appears when the variable
is used. We can shadow a variable by using the same variables name and
repeating the use of the `let` keyword as follows:
<span class="filename">Filename: src/main.rs</span>

View File

@ -184,7 +184,7 @@ fn main() {
}
```
The main way to consume Boolean values is through conditionals, such as an `if`
The main way to use Boolean values is through conditionals, such as an `if`
expression. Well cover how `if` expressions work in Rust in the “Control Flow”
section.
@ -302,7 +302,7 @@ fn main() {
```
Arrays are useful when you want your data allocated on the stack rather than
the heap (we will discuss the stack and the heap more in Chapter 4), or when
the heap (we will discuss the stack and the heap more in Chapter 4) or when
you want to ensure you always have a fixed number of elements. An array isnt
as flexible as the vector type, though. A vector is a similar collection type
provided by the standard library that *is* allowed to grow or shrink in size.

View File

@ -133,24 +133,22 @@ The value of y is: 6
Because we called the function with `5` as the value for `x` and `6` is passed
as the value for `y`, the two strings are printed with these values.
### Function Bodies
### Function Bodies Contain Statements and Expressions
Function bodies are made up of a series of statements optionally ending in an
expression. So far, weve only covered functions without an ending expression,
but you have seen an expression as part of statements. Because Rust is an
but you have seen an expression as part of a statement. Because Rust is an
expression-based language, this is an important distinction to understand.
Other languages dont have the same distinctions, so lets look at what
statements and expressions are and how their differences affect the bodies of
functions.
### Statements and Expressions
Weve actually already used statements and expressions. *Statements* are
instructions that perform some action and do not return a value. *Expressions*
evaluate to a resulting value. Lets look at some examples.
Creating a variable and assigning a value to it with the `let` keyword is a
statement. In Listing 3-1, `let y = 6;` is a statement:
statement. In Listing 3-1, `let y = 6;` is a statement.
<span class="filename">Filename: src/main.rs</span>

View File

@ -8,7 +8,7 @@ reading the source code may find useful.
Heres a simple comment:
```rust
// Hello, world.
// hello, world
```
In Rust, comments must start with two slashes and continue until the end of the
@ -27,7 +27,7 @@ Comments can also be placed at the end of lines containing code:
```rust
fn main() {
let lucky_number = 7; // Im feeling lucky today.
let lucky_number = 7; // Im feeling lucky today
}
```
@ -38,7 +38,7 @@ separate line above the code its annotating:
```rust
fn main() {
// Im feeling lucky today.
// Im feeling lucky today
let lucky_number = 7;
}
```

View File

@ -74,7 +74,8 @@ condition was false
```
Its also worth noting that the condition in this code *must* be a `bool`. If
the condition isnt a `bool`, well get an error. For example:
the condition isnt a `bool`, well get an error. For example, try running the
following code:
<span class="filename">Filename: src/main.rs</span>
@ -171,7 +172,7 @@ Rust branching construct called `match` for these cases.
#### Using `if` in a `let` Statement
Because `if` is an expression, we can use it on the right side of a `let`
statement, as in Listing 3-2:
statement, as in Listing 3-2.
<span class="filename">Filename: src/main.rs</span>
@ -226,9 +227,9 @@ fn main() {
}
```
When we try to compile this code, well get an error. The `if` and `else` arms have
value types that are incompatible, and Rust indicates exactly where to find the
problem in the program:
When we try to compile this code, well get an error. The `if` and `else` arms
have value types that are incompatible, and Rust indicates exactly where to
find the problem in the program:
```text
error[E0308]: if and else have incompatible types
@ -306,9 +307,8 @@ depending on where the code was in the loop when it received the halt signal.
Fortunately, Rust provides another, more reliable way to break out of a loop.
You can place the `break` keyword within the loop to tell the program when to
stop executing the loop. Recall that we did this in the guessing game in the
“Quitting After a Correct Guess” section of Chapter 2 to exit the
program when the user won the game by guessing the correct number.
“Quitting After a Correct Guess” section of Chapter 2 to exit the program when
the user won the game by guessing the correct number.
#### Returning from loops
@ -372,7 +372,7 @@ true, the code runs; otherwise, it exits the loop.
#### Looping Through a Collection with `for`
You could use the `while` construct to loop over the elements of a collection,
such as an array. For example, lets look at Listing 3-4:
such as an array. For example, lets look at Listing 3-4.
<span class="filename">Filename: src/main.rs</span>
@ -419,7 +419,7 @@ code to perform the conditional check on every element on every iteration
through the loop.
As a more concise alternative, you can use a `for` loop and execute some code
for each item in a collection. A `for` loop looks like this code in Listing 3-5:
for each item in a collection. A `for` loop looks like the code in Listing 3-5.
<span class="filename">Filename: src/main.rs</span>
@ -480,7 +480,7 @@ programs to do the following:
* Convert temperatures between Fahrenheit and Celsius.
* Generate the nth Fibonacci number.
* Print the lyrics to the Christmas carol “The Twelve Days of Christmas,”
taking advantage of the repetition in the song.
taking advantage of the repetition in the song.
When youre ready to move on, well talk about a concept in Rust that *doesnt*
commonly exist in other programming languages: ownership.

View File

@ -87,9 +87,9 @@ strings.
First, lets take a look at the ownership rules. Keep these rules in mind as we
work through the examples that illustrate them:
> 1. Each value in Rust has a variable thats called its *owner*.
> 2. There can only be one owner at a time.
> 3. When the owner goes out of scope, the value will be dropped.
* Each value in Rust has a variable thats called its *owner*.
* There can only be one owner at a time.
* When the owner goes out of scope, the value will be dropped.
### Variable Scope
@ -111,7 +111,7 @@ let s = "hello";
The variable `s` refers to a string literal, where the value of the string is
hardcoded into the text of our program. The variable is valid from the point at
which its declared until the end of the current *scope*. Listing 4-1 has
comments annotating where the variable `s` is valid:
comments annotating where the variable `s` is valid.
```rust
{ // s is not valid here, its not yet declared
@ -226,7 +226,7 @@ There is a natural point at which we can return the memory our `String` needs
to the operating system: when `s` goes out of scope. When a variable goes out
of scope, Rust calls a special function for us. This function is called `drop`,
and its where the author of `String` can put the code to return the memory.
Rust calls `drop` automatically at the closing `}`.
Rust calls `drop` automatically at the closing curly bracket.
> Note: In C++, this pattern of deallocating resources at the end of an items
> lifetime is sometimes called *Resource Acquisition Is Initialization (RAII)*.
@ -241,7 +241,7 @@ weve allocated on the heap. Lets explore some of those situations now.
#### Ways Variables and Data Interact: Move
Multiple variables can interact with the same data in different ways in Rust.
Lets look at an example using an integer in Listing 4-2:
Lets look at an example using an integer in Listing 4-2.
```rust
let x = 5;
@ -347,7 +347,7 @@ If youve heard the terms *shallow copy* and *deep copy* while working with
other languages, the concept of copying the pointer, length, and capacity
without copying the data probably sounds like making a shallow copy. But
because Rust also invalidates the first variable, instead of being called a
shallow copy, its known as a *move*. Here we would read this by saying that
shallow copy, its known as a *move*. In this example, we would say that
`s1` was *moved* into `s2`. So what actually happens is shown in Figure 4-4.
<img alt="s1 moved to s2" src="img/trpl04-04.svg" class="center" style="width: 50%;" />
@ -388,7 +388,7 @@ different is going on.
#### Stack-Only Data: Copy
Theres another wrinkle we havent talked about yet. This code using integers,
part of which was shown earlier in Listing 4-2, works and is valid:
part of which was shown in Listing 4-2, works and is valid:
```rust
let x = 5;
@ -413,7 +413,7 @@ in Chapter 10). If a type has the `Copy` trait, an older variable is still
usable after assignment. Rust wont let us annotate a type with the `Copy`
trait if the type, or any of its parts, has implemented the `Drop` trait. If
the type needs something special to happen when the value goes out of scope and
we add the `Copy` annotation to that type, well get a compile time error. To
we add the `Copy` annotation to that type, well get a compile-time error. To
learn about how to add the `Copy` annotation to your type, see “Derivable
Traits” in Appendix C.
@ -434,7 +434,7 @@ be sure, but as a general rule, any group of simple scalar values can be
The semantics for passing a value to a function are similar to those for
assigning a value to a variable. Passing a variable to a function will move or
copy, just as assignment does. Listing 4-3 has an example with some annotations
showing where variables go into and out of scope:
showing where variables go into and out of scope.
<span class="filename">Filename: src/main.rs</span>
@ -468,14 +468,14 @@ fn makes_copy(some_integer: i32) { // some_integer comes into scope
annotated</span>
If we tried to use `s` after the call to `takes_ownership`, Rust would throw a
compile time error. These static checks protect us from mistakes. Try adding
compile-time error. These static checks protect us from mistakes. Try adding
code to `main` that uses `s` and `x` to see where you can use them and where
the ownership rules prevent you from doing so.
### Return Values and Scope
Returning values can also transfer ownership. Listing 4-4 is an example with
similar annotations to those in Listing 4-3:
similar annotations to those in Listing 4-3.
<span class="filename">Filename: src/main.rs</span>
@ -500,10 +500,10 @@ fn gives_ownership() -> String { // gives_ownership will move its
some_string // some_string is returned and
// moves out to the calling
// function.
// function
}
// takes_and_gives_back will take a String and return one.
// takes_and_gives_back will take a String and return one
fn takes_and_gives_back(a_string: String) -> String { // a_string comes into
// scope
@ -525,7 +525,7 @@ Its quite annoying that anything we pass in also needs to be passed back if w
want to use it again, in addition to any data resulting from the body of the
function that we might want to return as well.
Its possible to return multiple values using a tuple, as shown in Listing 4-5:
Its possible to return multiple values using a tuple, as shown in Listing 4-5.
<span class="filename">Filename: src/main.rs</span>

View File

@ -134,7 +134,7 @@ First, we had to change `s` to be `mut`. Then we had to create a mutable
reference with `&mut s` and accept a mutable reference with `some_string: &mut
String`.
But mutable references have one big restriction: you can only have one mutable
But mutable references have one big restriction: you can have only one mutable
reference to a particular piece of data in a particular scope. This code will
fail:
@ -217,7 +217,7 @@ error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immuta
5 | let r2 = &s; // no problem
6 | let r3 = &mut s; // BIG PROBLEM
| ^^^^^^ mutable borrow occurs here
7 |
7 |
8 | println!("{}, {}, and {}", r1, r2, r3);
| -- borrow later used here
```
@ -264,7 +264,7 @@ Heres the error:
```text
error[E0106]: missing lifetime specifier
--> dangle.rs:5:16
--> main.rs:5:16
|
5 | fn dangle() -> &String {
| ^ expected lifetime parameter
@ -274,10 +274,9 @@ error[E0106]: missing lifetime specifier
= help: consider giving it a 'static lifetime
```
This error message refers to a feature we havent covered yet: *lifetimes*.
Well discuss lifetimes in detail in Chapter 10. But, if you disregard the
parts about lifetimes, the message does contain the key to why this code is a
problem:
This error message refers to a feature we havent covered yet: lifetimes. Well
discuss lifetimes in detail in Chapter 10. But, if you disregard the parts
about lifetimes, the message does contain the key to why this code is a problem:
```text
this function's return type contains a borrowed value, but there is no value
@ -319,8 +318,8 @@ deallocated.
Lets recap what weve discussed about references:
* At any given time, you can have *either* (but not both of) one mutable
reference or any number of immutable references.
* At any given time, you can have *either* one mutable reference *or* any
number of immutable references.
* References must always be valid.
Next, well look at a different kind of reference: slices.

View File

@ -18,7 +18,7 @@ fn first_word(s: &String) -> ?
This function, `first_word`, has a `&String` as a parameter. We dont want
ownership, so this is fine. But what should we return? We dont really have a
way to talk about *part* of a string. However, we could return the index of the
end of the word. Lets try that, as shown in Listing 4-7:
end of the word. Lets try that, as shown in Listing 4-7.
<span class="filename">Filename: src/main.rs</span>
@ -75,6 +75,7 @@ Otherwise, we return the length of the string by using `s.len()`:
return i;
}
}
s.len()
```
@ -83,7 +84,7 @@ string, but theres a problem. Were returning a `usize` on its own, but it
only a meaningful number in the context of the `&String`. In other words,
because its a separate value from the `String`, theres no guarantee that it
will still be valid in the future. Consider the program in Listing 4-8 that
uses the `first_word` function from Listing 4-7:
uses the `first_word` function from Listing 4-7.
<span class="filename">Filename: src/main.rs</span>
@ -105,7 +106,7 @@ fn main() {
let word = first_word(&s); // word will get the value 5
s.clear(); // This empties the String, making it equal to ""
s.clear(); // this empties the String, making it equal to ""
// word still has the value 5 here, but there's no more string that
// we could meaningfully use the value 5 with. word is now totally invalid!
@ -169,7 +170,7 @@ in the slice and `ending_index` is one more than the last position in the
slice. Internally, the slice data structure stores the starting position and
the length of the slice, which corresponds to `ending_index` minus
`starting_index`. So in the case of `let world = &s[6..11];`, `world` would be
a slice that contains a pointer to the 7th byte of `s` and a length value of 5.
a slice that contains a pointer to the 7th byte of `s` with a length value of 5.
Figure 4-6 shows this in a diagram.
@ -216,8 +217,8 @@ let slice = &s[..];
> boundaries. If you attempt to create a string slice in the middle of a
> multibyte character, your program will exit with an error. For the purposes
> of introducing string slices, we are assuming ASCII only in this section; a
> more thorough discussion of UTF-8 handling is in the “Strings” section of
> Chapter 8.
> more thorough discussion of UTF-8 handling is in the “Storing UTF-8 Encoded
> Text with Strings” section of Chapter 8.
With all this information in mind, lets rewrite `first_word` to return a
slice. The type that signifies “string slice” is written as `&str`:
@ -261,7 +262,7 @@ logically incorrect but didnt show any immediate errors. The problems would
show up later if we kept trying to use the first word index with an emptied
string. Slices make this bug impossible and let us know we have a problem with
our code much sooner. Using the slice version of `first_word` will throw a
compile time error:
compile-time error:
<span class="filename">Filename: src/main.rs</span>
@ -271,7 +272,7 @@ fn main() {
let word = first_word(&s);
s.clear(); // Error!
s.clear(); // error!
println!("the first word is: {}", word);
}
@ -285,10 +286,10 @@ error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immuta
|
8 | let word = first_word(&s);
| -- immutable borrow occurs here
9 |
10 | s.clear(); // Error!
9 |
10 | s.clear(); // error!
| ^^^^^^^^^ mutable borrow occurs here
11 |
11 |
12 | println!("the first word is: {}", word);
| ---- borrow later used here
```
@ -314,20 +315,24 @@ immutable reference.
#### String Slices as Parameters
Knowing that you can take slices of literals and `String`s leads us to one more
improvement on `first_word`, and thats its signature:
Knowing that you can take slices of literals and `String` values leads us to
one more improvement on `first_word`, and thats its signature:
```rust,ignore
fn first_word(s: &String) -> &str {
```
A more experienced Rustacean would write the following line instead because it
allows us to use the same function on both `String`s and `&str`s:
A more experienced Rustacean would write the signature shown in Listing 4-9
instead because it allows us to use the same function on both `String` values
and `&str` values.
```rust,ignore
fn first_word(s: &str) -> &str {
```
<span class="caption">Listing 4-9: Improving the `first_word` function by using
a string slice for the type of the `s` parameter</span>
If we have a string slice, we can pass that directly. If we have a `String`, we
can pass a slice of the entire `String`. Defining a function to take a string
slice instead of a reference to a `String` makes our API more general and useful

View File

@ -10,7 +10,7 @@ To define a struct, we enter the keyword `struct` and name the entire struct. A
structs name should describe the significance of the pieces of data being
grouped together. Then, inside curly brackets, we define the names and types of
the pieces of data, which we call *fields*. For example, Listing 5-1 shows a
struct that stores information about a user account:
struct that stores information about a user account.
```rust
struct User {
@ -31,7 +31,7 @@ data we want to store in those fields. We dont have to specify the fields in
the same order in which we declared them in the struct. In other words, the
struct definition is like a general template for the type, and instances fill
in that template with particular data to create values of the type. For
example, we can declare a particular user as shown in Listing 5-2:
example, we can declare a particular user as shown in Listing 5-2.
```rust
# struct User {
@ -56,7 +56,7 @@ To get a specific value from a struct, we can use dot notation. If we wanted
just this users email address, we could use `user1.email` wherever we wanted
to use this value. If the instance is mutable, we can change a value by using
the dot notation and assigning into a particular field. Listing 5-3 shows how
to change the value in the `email` field of a mutable `User` instance:
to change the value in the `email` field of a mutable `User` instance.
```rust
# struct User {
@ -80,10 +80,10 @@ user1.email = String::from("anotheremail@example.com");
`User` instance</span>
Note that the entire instance must be mutable; Rust doesnt allow us to mark
only certain fields as mutable.
only certain fields as mutable. As with any expression, we can construct a new
instance of the struct as the last expression in the function body to
implicitly return that new instance.
As with any expression, we can construct a new instance of the struct as the
last expression in the function body to implicitly return that new instance.
Listing 5-4 shows a `build_user` function that returns a `User` instance with
the given email and username. The `active` field gets the value of `true`, and
the `sign_in_count` gets a value of `1`.
@ -119,7 +119,7 @@ would get even more annoying. Luckily, theres a convenient shorthand!
Because the parameter names and the struct field names are exactly the same in
Listing 5-4, we can use the *field init shorthand* syntax to rewrite
`build_user` so that it behaves exactly the same but doesnt have the
repetition of `email` and `username` as shown in Listing 5-5.
repetition of `email` and `username`, as shown in Listing 5-5.
```rust
# struct User {
@ -156,7 +156,7 @@ instances values but changes some. Youll do this using *struct update synt
First, Listing 5-6 shows how we create a new `User` instance in `user2` without
the update syntax. We set new values for `email` and `username` but otherwise
use the same values from `user1` that we created in Listing 5-2:
use the same values from `user1` that we created in Listing 5-2.
```rust
# struct User {
@ -218,7 +218,7 @@ The code in Listing 5-7 also creates an instance in `user2` that has a
different value for `email` and `username` but has the same values for the
`active` and `sign_in_count` fields from `user1`.
### Tuple Structs without Named Fields to Create Different Types
### Using Tuple Structs without Named Fields to Create Different Types
You can also define structs that look similar to tuples, called *tuple
structs*. Tuple structs have the added meaning the struct name provides but
@ -227,7 +227,7 @@ of the fields. Tuple structs are useful when you want to give the whole tuple a
name and make the tuple be a different type than other tuples, and naming each
field as in a regular struct would be verbose or redundant.
To define a tuple struct start with the `struct` keyword and the struct name
To define a tuple struct, start with the `struct` keyword and the struct name
followed by the types in the tuple. For example, here are definitions and
usages of two tuple structs named `Color` and `Point`:

View File

@ -7,7 +7,7 @@ refactor the program until were using structs instead.
Lets make a new binary project with Cargo called *rectangles* that will take
the width and height of a rectangle specified in pixels and calculate the area
of the rectangle. Listing 5-8 shows a short program with one way of doing
exactly that in our projects *src/main.rs*:
exactly that in our projects *src/main.rs*.
<span class="filename">Filename: src/main.rs</span>
@ -55,7 +55,7 @@ we might do that in “The Tuple Type” section of Chapter 3: by using tuples.
### Refactoring with Tuples
Listing 5-9 shows another version of our program that uses tuples:
Listing 5-9 shows another version of our program that uses tuples.
<span class="filename">Filename: src/main.rs</span>
@ -94,7 +94,7 @@ our code.
We use structs to add meaning by labeling the data. We can transform the tuple
were using into a data type with a name for the whole as well as names for the
parts, as shown in Listing 5-10:
parts, as shown in Listing 5-10.
<span class="filename">Filename: src/main.rs</span>
@ -144,7 +144,7 @@ and `1`. This is a win for clarity.
Itd be nice to be able to print an instance of `Rectangle` while were
debugging our program and see the values for all its fields. Listing 5-11 tries
using the `println!` macro as we have used in previous chapters. This wont
work, however:
work, however.
<span class="filename">Filename: src/main.rs</span>
@ -170,7 +170,7 @@ When we run this code, we get an error with this core message:
error[E0277]: the trait bound `Rectangle: std::fmt::Display` is not satisfied
```
The `println!` macro can do many kinds of formatting, and by default, curly
The `println!` macro can do many kinds of formatting, and by default, the curly
brackets tell `println!` to use formatting known as `Display`: output intended
for direct end user consumption. The primitive types weve seen so far
implement `Display` by default, because theres only one way youd want to show
@ -190,9 +190,9 @@ If we continue reading the errors, well find this helpful note:
Lets try it! The `println!` macro call will now look like `println!("rect1 is
{:?}", rect1);`. Putting the specifier `:?` inside the curly brackets tells
`println!` we want to use an output format called `Debug`. `Debug` is a trait
that enables us to print our struct in a way that is useful for developers so
we can see its value while were debugging our code.
`println!` we want to use an output format called `Debug`. The `Debug` trait
enables us to print our struct in a way that is useful for developers so we can
see its value while were debugging our code.
Run the code with this change. Drat! We still get an error:
@ -210,7 +210,7 @@ crate, add `#[derive(Debug)]` or manually implement it
Rust *does* include functionality to print out debugging information, but we
have to explicitly opt in to make that functionality available for our struct.
To do that, we add the annotation `#[derive(Debug)]` just before the struct
definition, as shown in Listing 5-12:
definition, as shown in Listing 5-12.
<span class="filename">Filename: src/main.rs</span>
@ -253,9 +253,8 @@ rect1 is Rectangle {
Rust has provided a number of traits for us to use with the `derive` annotation
that can add useful behavior to our custom types. Those traits and their
behaviors are listed in Appendix C, “Derivable Traits.” Well cover how to
implement these traits with custom behavior as well as how to create your own
traits in Chapter 10.
behaviors are listed in Appendix C. Well cover how to implement these traits
with custom behavior as well as how to create your own traits in Chapter 10.
Our `area` function is very specific: it only computes the area of rectangles.
It would be helpful to tie this behavior more closely to our `Rectangle`

View File

@ -12,7 +12,7 @@ instance of the struct the method is being called on.
Lets change the `area` function that has a `Rectangle` instance as a parameter
and instead make an `area` method defined on the `Rectangle` struct, as shown
in Listing 5-13:
in Listing 5-13.
<span class="filename">Filename: src/main.rs</span>
@ -125,7 +125,7 @@ struct. This time, we want an instance of `Rectangle` to take another instance
of `Rectangle` and return `true` if the second `Rectangle` can fit completely
within `self`; otherwise it should return `false`. That is, we want to be able
to write the program shown in Listing 5-14, once weve defined the `can_hold`
method:
method.
<span class="filename">Filename: src/main.rs</span>
@ -164,7 +164,7 @@ calling the `can_hold` method. The return value of `can_hold` will be a
Boolean, and the implementation will check whether the width and height of
`self` are both greater than the width and height of the other `Rectangle`,
respectively. Lets add the new `can_hold` method to the `impl` block from
Listing 5-13, shown in Listing 5-15:
Listing 5-13, shown in Listing 5-15.
<span class="filename">Filename: src/main.rs</span>
@ -234,7 +234,7 @@ namespaces created by modules. Well discuss modules in Chapter 7.
Each struct is allowed to have multiple `impl` blocks. For example, Listing
5-15 is equivalent to the code shown in Listing 5-16, which has each method
in its own `impl` block:
in its own `impl` block.
```rust
# #[derive(Debug)]
@ -261,7 +261,7 @@ blocks</span>
Theres no reason to separate these methods into multiple `impl` blocks here,
but this is valid syntax. Well see a case in which multiple `impl` blocks are
useful in Chapter 10 where we discuss generic types and traits.
useful in Chapter 10, where we discuss generic types and traits.
## Summary

View File

@ -73,7 +73,7 @@ route(IpAddrKind::V6);
Using enums has even more advantages. Thinking more about our IP address type,
at the moment we dont have a way to store the actual IP address *data*; we
only know what *kind* it is. Given that you just learned about structs in
Chapter 5, you might tackle this problem as shown in Listing 6-1:
Chapter 5, you might tackle this problem as shown in Listing 6-1.
```rust
enum IpAddrKind {
@ -183,7 +183,7 @@ havent brought the standard librarys definition into our scope. Well ta
more about bringing types into scope in Chapter 7.
Lets look at another example of an enum in Listing 6-2: this one has a wide
variety of types embedded in its variants:
variety of types embedded in its variants.
```rust
enum Message {
@ -204,7 +204,7 @@ This enum has four variants with different types:
* `Write` includes a single `String`.
* `ChangeColor` includes three `i32` values.
Defining an enum with variants like the ones in Listing 6-2 is similar to
Defining an enum with variants such as the ones in Listing 6-2 is similar to
defining different kinds of struct definitions, except the enum doesnt use the
`struct` keyword and all the variants are grouped together under the `Message`
type. The following structs could hold the same data that the preceding enum

View File

@ -17,7 +17,7 @@ the value falls into the associated code block to be used during execution.
Because we just mentioned coins, lets use them as an example using `match`! We
can write a function that can take an unknown United States coin and, in a
similar way as the counting machine, determine which coin it is and return its
value in cents, as shown here in Listing 6-3:
value in cents, as shown here in Listing 6-3.
```rust
enum Coin {
@ -100,10 +100,10 @@ From 1999 through 2008, the United States minted quarters with different
designs for each of the 50 states on one side. No other coins got state
designs, so only quarters have this extra value. We can add this information to
our `enum` by changing the `Quarter` variant to include a `UsState` value stored
inside it, which weve done here in Listing 6-4:
inside it, which weve done here in Listing 6-4.
```rust
#[derive(Debug)] // So we can inspect the state in a minute
#[derive(Debug)] // so we can inspect the state in a minute
enum UsState {
Alabama,
Alaska,
@ -179,7 +179,7 @@ the function should return the `None` value and not attempt to perform any
operations.
This function is very easy to write, thanks to `match`, and will look like
Listing 6-5:
Listing 6-5.
```rust
fn plus_one(x: Option<i32>) -> Option<i32> {
@ -292,4 +292,4 @@ can say that we want to do nothing for all the possible values that we dont
list before the `_` placeholder.
However, the `match` expression can be a bit wordy in a situation in which we
only care about *one* of the cases. For this situation, Rust provides `if let`.
care about only *one* of the cases. For this situation, Rust provides `if let`.

View File

@ -3,7 +3,7 @@
The `if let` syntax lets you combine `if` and `let` into a less verbose way to
handle values that match one pattern while ignoring the rest. Consider the
program in Listing 6-6 that matches on an `Option<u8>` value but only wants to
execute code if the value is 3:
execute code if the value is 3.
```rust
let some_u8_value = Some(0u8);
@ -31,15 +31,15 @@ if let Some(3) = some_u8_value {
}
```
The syntax `if let` takes a pattern and an expression separated by an `=`. It
works the same way as a `match`, where the expression is given to the `match`
and the pattern is its first arm.
The syntax `if let` takes a pattern and an expression separated by an equal
sign. It works the same way as a `match`, where the expression is given to the
`match` and the pattern is its first arm.
Using `if let` means you have less typing, less indentation, and less
boilerplate code. However, you lose the exhaustive checking that `match`
enforces. Choosing between `match` and `if let` depends on what youre doing in
your particular situation and whether gaining conciseness is an appropriate
trade-off for losing exhaustive checking.
Using `if let` means less typing, less indentation, and less boilerplate code.
However, you lose the exhaustive checking that `match` enforces. Choosing
between `match` and `if let` depends on what youre doing in your particular
situation and whether gaining conciseness is an appropriate trade-off for
losing exhaustive checking.
In other words, you can think of `if let` as syntax sugar for a `match` that
runs code when the value matches one pattern and then ignores all other values.

View File

@ -9,7 +9,7 @@ lines of text in a file or the prices of items in a shopping cart.
### Creating a New Vector
To create a new, empty vector, we can call the `Vec::new` function, as shown in
Listing 8-1:
Listing 8-1.
```rust
let v: Vec<i32> = Vec::new();
@ -32,7 +32,7 @@ store once you insert values, so you rarely need to do this type annotation.
Its more common to create a `Vec<T>` that has initial values, and Rust
provides the `vec!` macro for convenience. The macro will create a new vector
that holds the values you give it. Listing 8-2 creates a new `Vec<i32>` that
holds the values `1`, `2`, and `3`:
holds the values `1`, `2`, and `3`.
```rust
let v = vec![1, 2, 3];
@ -48,7 +48,7 @@ to modify a vector.
### Updating a Vector
To create a vector and then add elements to it, we can use the `push` method,
as shown in Listing 8-3:
as shown in Listing 8-3.
```rust
let mut v = Vec::new();
@ -70,7 +70,7 @@ we dont need the `Vec<i32>` annotation.
### Dropping a Vector Drops Its Elements
Like any other `struct`, a vector is freed when it goes out of scope, as
annotated in Listing 8-4:
annotated in Listing 8-4.
```rust
{
@ -96,32 +96,22 @@ read their contents is a good next step. There are two ways to reference a
value stored in a vector. In the examples, weve annotated the types of the
values that are returned from these functions for extra clarity.
Listing 8-5 shows the method of accessing a value in a vector with
indexing syntax:
Listing 8-5 shows both methods of accessing a value in a vector, either with
indexing syntax or the `get` method.
```rust
let v = vec![1, 2, 3, 4, 5];
let third: &i32 = &v[2];
```
println!("The third element is {}", third);
<span class="caption">Listing 8-5: Using indexing syntax to
access an item in a vector</span>
Listing 8-6 shows the method of accessing a value in a vector, with
the `get` method:
```rust
let v = vec![1, 2, 3, 4, 5];
let v_index = 2;
match v.get(v_index) {
Some(_) => { println!("Reachable element at index: {}", v_index); },
None => { println!("Unreachable element at index: {}", v_index); }
match v.get(2) {
Some(third) => println!("The third element is {}", third),
None => println!("There is no third element."),
}
```
<span class="caption">Listing 8-6: Using the `get` method to
<span class="caption">Listing 8-5: Using indexing syntax or the `get` method to
access an item in a vector</span>
Note two details here. First, we use the index value of `2` to get the third
@ -134,7 +124,7 @@ Rust has two ways to reference an element so you can choose how the program
behaves when you try to use an index value that the vector doesnt have an
element for. As an example, lets see what a program will do if it has a vector
that holds five elements and then tries to access an element at index 100, as
shown in Listing 8-7:
shown in Listing 8-6.
```rust,should_panic,panics
let v = vec![1, 2, 3, 4, 5];
@ -143,7 +133,7 @@ let does_not_exist = &v[100];
let does_not_exist = v.get(100);
```
<span class="caption">Listing 8-7: Attempting to access the element at index
<span class="caption">Listing 8-6: Attempting to access the element at index
100 in a vector containing five elements</span>
When we run this code, the first `[]` method will cause the program to panic
@ -165,9 +155,9 @@ When the program has a valid reference, the borrow checker enforces the
ownership and borrowing rules (covered in Chapter 4) to ensure this reference
and any other references to the contents of the vector remain valid. Recall the
rule that states you cant have mutable and immutable references in the same
scope. That rule applies in Listing 8-8, where we hold an immutable reference to
scope. That rule applies in Listing 8-7, where we hold an immutable reference to
the first element in a vector and try to add an element to the end, which wont
work:
work.
```rust,ignore,does_not_compile
let mut v = vec![1, 2, 3, 4, 5];
@ -179,7 +169,7 @@ v.push(6);
println!("The first element is: {}", first);
```
<span class="caption">Listing 8-8: Attempting to add an element to a vector
<span class="caption">Listing 8-7: Attempting to add an element to a vector
while holding a reference to an item</span>
Compiling this code will result in this error:
@ -198,7 +188,7 @@ error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immuta
| ----- borrow later used here
```
The code in Listing 8-8 might look like it should work: why should a reference
The code in Listing 8-7 might look like it should work: why should a reference
to the first element care about what changes at the end of the vector? This
error is due to the way vectors work: adding a new element onto the end of the
vector might require allocating new memory and copying the old elements to the
@ -214,8 +204,8 @@ programs from ending up in that situation.
If we want to access each element in a vector in turn, we can iterate through
all of the elements rather than use indexes to access one at a time. Listing
8-9 shows how to use a `for` loop to get immutable references to each element
in a vector of `i32` values and print them:
8-8 shows how to use a `for` loop to get immutable references to each element
in a vector of `i32` values and print them.
```rust
let v = vec![100, 32, 57];
@ -224,12 +214,12 @@ for i in &v {
}
```
<span class="caption">Listing 8-9: Printing each element in a vector by
<span class="caption">Listing 8-8: Printing each element in a vector by
iterating over the elements using a `for` loop</span>
We can also iterate over mutable references to each element in a mutable vector
in order to make changes to all the elements. The `for` loop in Listing 8-10
will add `50` to each element:
in order to make changes to all the elements. The `for` loop in Listing 8-9
will add `50` to each element.
```rust
let mut v = vec![100, 32, 57];
@ -238,12 +228,12 @@ for i in &mut v {
}
```
<span class="caption">Listing 8-10: Iterating over mutable references to
<span class="caption">Listing 8-9: Iterating over mutable references to
elements in a vector</span>
To change the value that the mutable reference refers to, we have to use the
dereference operator (`*`) to get to the value in `i` before we can use the
`+=` operator . Well talk more about `*` in Chapter 15.
`+=` operator. Well talk more about `*` in Chapter 15.
### Using an Enum to Store Multiple Types
@ -258,7 +248,7 @@ some of the columns in the row contain integers, some floating-point numbers,
and some strings. We can define an enum whose variants will hold the different
value types, and then all the enum variants will be considered the same type:
that of the enum. Then we can create a vector that holds that enum and so,
ultimately, holds different types. Weve demonstrated this in Listing 8-11:
ultimately, holds different types. Weve demonstrated this in Listing 8-10.
```rust
enum SpreadsheetCell {
@ -274,7 +264,7 @@ let row = vec![
];
```
<span class="caption">Listing 8-11: Defining an `enum` to store values of
<span class="caption">Listing 8-10: Defining an `enum` to store values of
different types in one vector</span>
Rust needs to know what types will be in the vector at compile time so it knows

View File

@ -1,7 +1,7 @@
## Storing UTF-8 Encoded Text with Strings
We talked about strings in Chapter 4, but well look at them in more depth now.
New Rustaceans commonly get stuck on strings due to a combination of three
New Rustaceans commonly get stuck on strings for a combination of three
reasons: Rusts propensity for exposing possible errors, strings being a more
complicated data structure than many programmers give them credit for, and
UTF-8. These factors combine in a way that can seem difficult when youre
@ -45,7 +45,7 @@ API documentation for more about how to use them and when each is appropriate.
Many of the same operations available with `Vec<T>` are available with `String`
as well, starting with the `new` function to create a string, shown in Listing
8-11:
8-11.
```rust
let mut s = String::new();
@ -57,7 +57,7 @@ This line creates a new empty string called `s`, which we can then load data
into. Often, well have some initial data that we want to start the string
with. For that, we use the `to_string` method, which is available on any type
that implements the `Display` trait, as string literals do. Listing 8-12 shows
two examples:
two examples.
```rust
let data = "initial contents";
@ -75,7 +75,7 @@ This code creates a string containing `initial contents`.
We can also use the function `String::from` to create a `String` from a string
literal. The code in Listing 8-13 is equivalent to the code from Listing 8-12
that uses `to_string`:
that uses `to_string`.
```rust
let s = String::from("initial contents");
@ -90,7 +90,7 @@ redundant, but they all have their place! In this case, `String::from` and
`to_string` do the same thing, so which you choose is a matter of style.
Remember that strings are UTF-8 encoded, so we can include any properly encoded
data in them, as shown in Listing 8-14:
data in them, as shown in Listing 8-14.
```rust
let hello = String::from("السلام عليكم");
@ -120,7 +120,7 @@ use the `+` operator or the `format!` macro to concatenate `String` values.
#### Appending to a String with `push_str` and `push`
We can grow a `String` by using the `push_str` method to append a string slice,
as shown in Listing 8-15:
as shown in Listing 8-15.
```rust
let mut s = String::from("foo");
@ -133,7 +133,7 @@ using the `push_str` method</span>
After these two lines, `s` will contain `foobar`. The `push_str` method takes a
string slice because we dont necessarily want to take ownership of the
parameter. For example, the code in Listing 8-16 shows that it would be
unfortunate if we werent able to use `s2` after appending its contents to `s1`:
unfortunate if we werent able to use `s2` after appending its contents to `s1`.
```rust
let mut s1 = String::from("foo");
@ -149,8 +149,8 @@ If the `push_str` method took ownership of `s2`, we wouldnt be able to print
its value on the last line. However, this code works as wed expect!
The `push` method takes a single character as a parameter and adds it to the
`String`. Listing 8-17 shows code that adds the letter l to a `String` using
the `push` method:
`String`. Listing 8-17 shows code that adds the letter *l* to a `String` using
the `push` method.
```rust
let mut s = String::from("lo");
@ -165,12 +165,12 @@ As a result of this code, `s` will contain `lol`.
#### Concatenation with the `+` Operator or the `format!` Macro
Often, youll want to combine two existing strings. One way is to use the `+`
operator, as shown in Listing 8-18:
operator, as shown in Listing 8-18.
```rust
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2; // Note s1 has been moved here and can no longer be used
let s3 = s1 + &s2; // note s1 has been moved here and can no longer be used
```
<span class="caption">Listing 8-18: Using the `+` operator to combine two
@ -248,7 +248,7 @@ easier to read and doesnt take ownership of any of its parameters.
In many other programming languages, accessing individual characters in a
string by referencing them by index is a valid and common operation. However,
if you try to access parts of a `String` using indexing syntax in Rust, youll
get an error. Consider the invalid code in Listing 8-19:
get an error. Consider the invalid code in Listing 8-19.
```rust,ignore,does_not_compile
let s1 = String::from("hello");
@ -285,7 +285,7 @@ let len = String::from("Hola").len();
In this case, `len` will be 4, which means the vector storing the string “Hola”
is 4 bytes long. Each of these letters takes 1 byte when encoded in UTF-8. But
what about the following line? (Note that this line begins with the capital
what about the following line? (Note that this string begins with the capital
Cyrillic letter Ze, not the Arabic number 3.)
```rust
@ -393,7 +393,7 @@ Fortunately, you can access elements in a string in other ways.
If you need to perform operations on individual Unicode scalar values, the best
way to do so is to use the `chars` method. Calling `chars` on “नमस्ते” separates
out and returns six values of type `char`, and you can iterate over the result
in order to access each element:
to access each element:
```rust
for c in "नमस्ते".chars() {

View File

@ -22,7 +22,7 @@ As always, check the standard library documentation for more information.
You can create an empty hash map with `new` and add elements with `insert`. In
Listing 8-20, were keeping track of the scores of two teams whose names are
Blue and Yellow. The Blue team starts with 10 points, and the Yellow team
starts with 50:
starts with 50.
```rust
use std::collections::HashMap;
@ -53,7 +53,7 @@ vector of tuples, where each tuple consists of a key and its value. The
`HashMap`. For example, if we had the team names and initial scores in two
separate vectors, we could use the `zip` method to create a vector of tuples
where “Blue” is paired with 10, and so forth. Then we could use the `collect`
method to turn that vector of tuples into a hash map, as shown in Listing 8-21:
method to turn that vector of tuples into a hash map, as shown in Listing 8-21.
```rust
use std::collections::HashMap;
@ -77,7 +77,7 @@ contains based on the types of the data in the vectors.
For types that implement the `Copy` trait, like `i32`, the values are copied
into the hash map. For owned values like `String`, the values will be moved and
the hash map will be the owner of those values, as demonstrated in Listing 8-22:
the hash map will be the owner of those values, as demonstrated in Listing 8-22.
```rust
use std::collections::HashMap;
@ -105,7 +105,7 @@ the “Validating References with Lifetimes” section in Chapter 10.
### Accessing Values in a Hash Map
We can get a value out of the hash map by providing its key to the `get`
method, as shown in Listing 8-23:
method, as shown in Listing 8-23.
```rust
use std::collections::HashMap;
@ -168,7 +168,7 @@ If we insert a key and a value into a hash map and then insert that same key
with a different value, the value associated with that key will be replaced.
Even though the code in Listing 8-24 calls `insert` twice, the hash map will
only contain one key/value pair because were inserting the value for the Blue
teams key both times:
teams key both times.
```rust
use std::collections::HashMap;
@ -192,11 +192,11 @@ overwritten.
Its common to check whether a particular key has a value and, if it doesnt,
insert a value for it. Hash maps have a special API for this called `entry`
that takes the key you want to check as a parameter. The return value of the
`entry` function is an enum called `Entry` that represents a value that might
or might not exist. Lets say we want to check whether the key for the Yellow
team has a value associated with it. If it doesnt, we want to insert the value
50, and the same for the Blue team. Using the `entry` API, the code looks like
Listing 8-25:
`entry` method is an enum called `Entry` that represents a value that might or
might not exist. Lets say we want to check whether the key for the Yellow team
has a value associated with it. If it doesnt, we want to insert the value 50,
and the same for the Blue team. Using the `entry` API, the code looks like
Listing 8-25.
```rust
use std::collections::HashMap;
@ -221,9 +221,9 @@ logic ourselves and, in addition, plays more nicely with the borrow checker.
Running the code in Listing 8-25 will print `{"Yellow": 50, "Blue": 10}`. The
first call to `entry` will insert the key for the Yellow team with the value
`50` because the Yellow team doesnt have a value already. The second call to
50 because the Yellow team doesnt have a value already. The second call to
`entry` will not change the hash map because the Blue team already has the
value `10`.
value 10.
#### Updating a Value Based on the Old Value
@ -232,7 +232,7 @@ update it based on the old value. For instance, Listing 8-26 shows code that
counts how many times each word appears in some text. We use a hash map with
the words as keys and increment the value to keep track of how many times weve
seen that word. If its the first time weve seen a word, well first insert
the value `0`:
the value 0.
```rust
use std::collections::HashMap;
@ -261,17 +261,17 @@ loop, so all of these changes are safe and allowed by the borrowing rules.
### Hashing Functions
By default, `HashMap` uses a “cryptographically strong”[^siphash] hashing function that can
provide resistance to Denial of Service (DoS) attacks. This is not the fastest
hashing algorithm available, but the trade-off for better security that comes
with the drop in performance is worth it. If you profile your code and find
that the default hash function is too slow for your purposes, you can switch to
another function by specifying a different *hasher*. A hasher is a type that
implements the `BuildHasher` trait. Well talk about traits and how to
implement them in Chapter 10. You dont necessarily have to implement your own
hasher from scratch; [crates.io](https://crates.io) has libraries shared by
other Rust users that provide hashers implementing many common hashing
algorithms.
By default, `HashMap` uses a “cryptographically strong”[^siphash] hashing
function that can provide resistance to Denial of Service (DoS) attacks. This
is not the fastest hashing algorithm available, but the trade-off for better
security that comes with the drop in performance is worth it. If you profile
your code and find that the default hash function is too slow for your
purposes, you can switch to another function by specifying a different
*hasher*. A hasher is a type that implements the `BuildHasher` trait. Well
talk about traits and how to implement them in Chapter 10. You dont
necessarily have to implement your own hasher from scratch;
[crates.io](https://crates.io) has libraries shared by other Rust users that
provide hashers implementing many common hashing algorithms.
[^siphash]: [https://www.131002.net/siphash/siphash.pdf](https://www.131002.net/siphash/siphash.pdf)

View File

@ -45,10 +45,10 @@ thread 'main' panicked at 'crash and burn', src/main.rs:2:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.
```
The call to `panic!` causes the error message contained in the last two
lines. The first line shows our panic message and the place in our source code
where the panic occurred: *src/main.rs:2:4* indicates that its the second
line, fourth character of our *src/main.rs* file.
The call to `panic!` causes the error message contained in the last two lines.
The first line shows our panic message and the place in our source code where
the panic occurred: *src/main.rs:2:4* indicates that its the second line,
fourth character of our *src/main.rs* file.
In this case, the line indicated is part of our code, and if we go to that
line, we see the `panic!` macro call. In other cases, the `panic!` call might
@ -64,7 +64,7 @@ backtrace is in more detail next.
Lets look at another example to see what its like when a `panic!` call comes
from a library because of a bug in our code instead of from our code calling
the macro directly. Listing 9-1 has some code that attempts to access an
element by index in a vector:
element by index in a vector.
<span class="filename">Filename: src/main.rs</span>
@ -77,13 +77,13 @@ fn main() {
```
<span class="caption">Listing 9-1: Attempting to access an element beyond the
end of a vector, which will cause a `panic!`</span>
end of a vector, which will cause a call to `panic!`</span>
Here, were attempting to access the hundredth element of our vector (which is
at index 99 because indexing starts at zero), but it has only three elements.
In this situation, Rust will panic. Using `[]` is supposed to return an
element, but if you pass an invalid index, theres no element that Rust could
return here that would be correct.
Here, were attempting to access the 100th element of our vector (which is at
index 99 because indexing starts at zero), but it has only 3 elements. In this
situation, Rust will panic. Using `[]` is supposed to return an element, but if
you pass an invalid index, theres no element that Rust could return here that
would be correct.
Other languages, like C, will attempt to give you exactly what you asked for in
this situation, even though it isnt what you want: youll get whatever is at
@ -122,7 +122,7 @@ mentioning your files are code that your code called; the lines below are code
that called your code. These lines might include core Rust code, standard
library code, or crates that youre using. Lets try getting a backtrace by
setting the `RUST_BACKTRACE` environment variable to any value except 0.
Listing 9-2 shows output similar to what youll see:
Listing 9-2 shows output similar to what youll see.
```text
$ RUST_BACKTRACE=1 cargo run

View File

@ -29,7 +29,7 @@ library has defined on it in many different situations where the successful
value and error value we want to return may differ.
Lets call a function that returns a `Result` value because the function could
fail. In Listing 9-3 we try to open a file:
fail. In Listing 9-3 we try to open a file.
<span class="filename">Filename: src/main.rs</span>
@ -43,14 +43,13 @@ fn main() {
<span class="caption">Listing 9-3: Opening a file</span>
How do we know `File::open` returns a `Result`? We could look at the
[standard library API documentation](../std/index.html),
or we could ask the compiler! If we give `f` a type
annotation that we know is *not* the return type of the function and then try
to compile the code, the compiler will tell us that the types dont match. The
error message will then tell us what the type of `f` *is*. Lets try it! We
know that the return type of `File::open` isnt of type `u32`, so lets change
the `let f` statement to this:
How do we know `File::open` returns a `Result`? We could look at the [standard
library API documentation](../std/index.html)<!-- ignore -->, or we could ask
the compiler! If we give `f` a type annotation that we know is *not* the return
type of the function and then try to compile the code, the compiler will tell
us that the types dont match. The error message will then tell us what the
type of `f` *is*. Lets try it! We know that the return type of `File::open`
isnt of type `u32`, so lets change the `let f` statement to this:
```rust,ignore
let f: u32 = File::open("hello.txt");
@ -142,7 +141,7 @@ if `File::open` failed because the file doesnt exist, we want to create the
file and return the handle to the new file. If `File::open` failed for any
other reason—for example, because we didnt have permission to open the file—we
still want the code to `panic!` in the same way as it did in Listing 9-4. Look
at Listing 9-5, which adds another arm to the `match`:
at Listing 9-5, which adds another arm to the `match`.
<span class="filename">Filename: src/main.rs</span>
@ -178,21 +177,21 @@ has a method `kind` that we can call to get an `io::ErrorKind` value. The enum
`io::ErrorKind` is provided by the standard library and has variants
representing the different kinds of errors that might result from an `io`
operation. The variant we want to use is `ErrorKind::NotFound`, which indicates
the file were trying to open doesnt exist yet. So, we `match` on `f`, but we
also then have an inner `match` on `error.kind()`.
the file were trying to open doesnt exist yet. So we `match` on `f`, but we
also have an inner `match` on `error.kind()`.
The condition we want to check in the match guard is whether the value returned
by `error.kind()` is the `NotFound` variant of the `ErrorKind` enum. If it is,
we try to create the file with `File::create`. However, because `File::create`
could also fail, we need to add another inner `match` statement as well. When
could also fail, we need to add another inner `match` expression as well. When
the file cant be opened, a different error message will be printed. The last
arm of the outer `match` stays the same so the program panics on any error
besides the missing file error.
Thats a lot of `match`! `match` is very powerful, but also very much a primitive.
In Chapter 13, well learn about closures. The `Result<T, E>` type has many
methods that accept a closure, and are implemented as `match` statements. A more
seasoned Rustacean might write this:
Thats a lot of `match`! `match` is very powerful, but also very much a
primitive. In Chapter 13, well learn about closures. The `Result<T, E>` type
has many methods that accept a closure, and are implemented as `match`
expressions. A more seasoned Rustacean might write this:
```rust,ignore
use std::fs::File;
@ -213,16 +212,15 @@ fn main() {
Come back to this example after youve read Chapter 13, and look up what the
`map_err` and `unwrap_or_else` methods do in the standard library
documentation. Theres many more of these methods that can clean up huge
nested `match`es when dealing with errors. Well be looking at some other
strategies shortly!
documentation. Theres many more of these methods that can clean up huge nested
`match` expressions when dealing with errors.
### Shortcuts for Panic on Error: `unwrap` and `expect`
Using `match` works well enough, but it can be a bit verbose and doesnt always
communicate intent well. The `Result<T, E>` type has many helper methods
defined on it to do various tasks. One of those methods, called `unwrap`, is a
shortcut method that is implemented just like the `match` statement we wrote in
shortcut method that is implemented just like the `match` expression we wrote in
Listing 9-4. If the `Result` value is the `Ok` variant, `unwrap` will return
the value inside the `Ok`. If the `Result` is the `Err` variant, `unwrap` will
call the `panic!` macro for us. Here is an example of `unwrap` in action:

View File

@ -429,6 +429,7 @@ when you created the crate, your description, and a license added, the
name = "guessing_game"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
edition = "2018"
description = "A fun game where you guess what number the computer has chosen."
license = "MIT OR Apache-2.0"

View File

@ -161,12 +161,12 @@ impl<'a, T> LimitTracker<'a, T>
let percentage_of_max = self.value as f64 / self.max as f64;
if percentage_of_max >= 0.75 && percentage_of_max < 0.9 {
self.messenger.send("Warning: You've used up over 75% of your quota!");
} else if percentage_of_max >= 0.9 && percentage_of_max < 1.0 {
self.messenger.send("Urgent warning: You've used up over 90% of your quota!");
} else if percentage_of_max >= 1.0 {
if percentage_of_max >= 1.0 {
self.messenger.send("Error: You are over your quota!");
} else if percentage_of_max >= 0.9 {
self.messenger.send("Urgent warning: You've used up over 90% of your quota!");
} else if percentage_of_max >= 0.75 {
self.messenger.send("Warning: You've used up over 75% of your quota!");
}
}
}

View File

@ -175,7 +175,7 @@ fn main() {
separate variables</span>
This code creates the variables `a` and `b` that match the values of the `x`
and `y` fields of the `p` variable. This example shows that the names of the
and `y` fields of the `p` struct. This example shows that the names of the
variables in the pattern dont have to match the field names of the struct. But
its common to want the variable names to match the field names to make it
easier to remember which variables came from which fields.

View File

@ -327,12 +327,10 @@ wont compile until we add a definition for the `impl_hello_macro` function.
<span class="filename">Filename: hello_macro_derive/src/lib.rs</span>
<!--
This usage of `extern crate` is required for the moment with the 1.31 code
that's currently rustc 1.31.0-beta.4 (04da282bb 2018-11-01), see:
- https://github.com/rust-lang/rust/issues/54418
- https://github.com/rust-lang/rust/pull/54658
- https://github.com/rust-lang/rust/issues/55599
This usage of `extern crate` is required for the moment with 1.31.0, see:
https://github.com/rust-lang/rust/issues/54418
https://github.com/rust-lang/rust/pull/54658
https://github.com/rust-lang/rust/issues/55599
-->
```rust,ignore

View File

@ -248,7 +248,7 @@ impl CtorKind {
}
impl NonMacroAttrKind {
fn descr(self) -> &'static str {
pub fn descr(self) -> &'static str {
match self {
NonMacroAttrKind::Builtin => "built-in attribute",
NonMacroAttrKind::Tool => "tool attribute",

View File

@ -334,7 +334,12 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
continue;
}
let result = select.select(&Obligation::new(dummy_cause.clone(), new_env, pred));
// Call infcx.resolve_type_vars_if_possible to see if we can
// get rid of any inference variables.
let obligation = infcx.resolve_type_vars_if_possible(
&Obligation::new(dummy_cause.clone(), new_env, pred)
);
let result = select.select(&obligation);
match &result {
&Ok(Some(ref vtable)) => {
@ -369,7 +374,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
}
&Ok(None) => {}
&Err(SelectionError::Unimplemented) => {
if self.is_of_param(pred.skip_binder().trait_ref.substs) {
if self.is_param_no_infer(pred.skip_binder().trait_ref.substs) {
already_visited.remove(&pred);
self.add_user_pred(
&mut user_computed_preds,
@ -631,18 +636,28 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
finished_map
}
pub fn is_of_param(&self, substs: &Substs<'_>) -> bool {
if substs.is_noop() {
return false;
}
fn is_param_no_infer(&self, substs: &Substs<'_>) -> bool {
return self.is_of_param(substs.type_at(0)) &&
!substs.types().any(|t| t.has_infer_types());
}
return match substs.type_at(0).sty {
pub fn is_of_param(&self, ty: Ty<'_>) -> bool {
return match ty.sty {
ty::Param(_) => true,
ty::Projection(p) => self.is_of_param(p.substs),
ty::Projection(p) => self.is_of_param(p.self_ty()),
_ => false,
};
}
fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool {
match p.ty().skip_binder().sty {
ty::Projection(proj) if proj == p.skip_binder().projection_ty => {
true
},
_ => false
}
}
pub fn evaluate_nested_obligations<
'b,
'c,
@ -661,28 +676,77 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
) -> bool {
let dummy_cause = ObligationCause::misc(DUMMY_SP, ast::DUMMY_NODE_ID);
for (obligation, predicate) in nested
.filter(|o| o.recursion_depth == 1)
for (obligation, mut predicate) in nested
.map(|o| (o.clone(), o.predicate.clone()))
{
let is_new_pred =
fresh_preds.insert(self.clean_pred(select.infcx(), predicate.clone()));
// Resolve any inference variables that we can, to help selection succeed
predicate = select.infcx().resolve_type_vars_if_possible(&predicate);
// We only add a predicate as a user-displayable bound if
// it involves a generic parameter, and doesn't contain
// any inference variables.
//
// Displaying a bound involving a concrete type (instead of a generic
// parameter) would be pointless, since it's always true
// (e.g. u8: Copy)
// Displaying an inference variable is impossible, since they're
// an internal compiler detail without a defined visual representation
//
// We check this by calling is_of_param on the relevant types
// from the various possible predicates
match &predicate {
&ty::Predicate::Trait(ref p) => {
let substs = &p.skip_binder().trait_ref.substs;
if self.is_param_no_infer(p.skip_binder().trait_ref.substs)
&& !only_projections
&& is_new_pred {
if self.is_of_param(substs) && !only_projections && is_new_pred {
self.add_user_pred(computed_preds, predicate);
}
predicates.push_back(p.clone());
}
&ty::Predicate::Projection(p) => {
// If the projection isn't all type vars, then
// we don't want to add it as a bound
if self.is_of_param(p.skip_binder().projection_ty.substs) && is_new_pred {
self.add_user_pred(computed_preds, predicate);
} else {
debug!("evaluate_nested_obligations: examining projection predicate {:?}",
predicate);
// As described above, we only want to display
// bounds which include a generic parameter but don't include
// an inference variable.
// Additionally, we check if we've seen this predicate before,
// to avoid rendering duplicate bounds to the user.
if self.is_param_no_infer(p.skip_binder().projection_ty.substs)
&& !p.ty().skip_binder().is_ty_infer()
&& is_new_pred {
debug!("evaluate_nested_obligations: adding projection predicate\
to computed_preds: {:?}", predicate);
// Under unusual circumstances, we can end up with a self-refeential
// projection predicate. For example:
// <T as MyType>::Value == <T as MyType>::Value
// Not only is displaying this to the user pointless,
// having it in the ParamEnv will cause an issue if we try to call
// poly_project_and_unify_type on the predicate, since this kind of
// predicate will normally never end up in a ParamEnv.
//
// For these reasons, we ignore these weird predicates,
// ensuring that we're able to properly synthesize an auto trait impl
if self.is_self_referential_projection(p) {
debug!("evaluate_nested_obligations: encountered a projection
predicate equating a type with itself! Skipping");
} else {
self.add_user_pred(computed_preds, predicate);
}
}
// We can only call poly_project_and_unify_type when our predicate's
// Ty contains an inference variable - otherwise, there won't be anything to
// unify
if p.ty().skip_binder().has_infer_types() {
debug!("Projecting and unifying projection predicate {:?}",
predicate);
match poly_project_and_unify_type(select, &obligation.with(p.clone())) {
Err(e) => {
debug!(

View File

@ -190,7 +190,26 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
// In the case of a trait predicate, we can skip the "self" type.
data.skip_binder().input_types().skip(1).any(|t| t.has_self_ty())
}
ty::Predicate::Projection(..) |
ty::Predicate::Projection(ref data) => {
// And similarly for projections. This should be redundant with
// the previous check because any projection should have a
// matching `Trait` predicate with the same inputs, but we do
// the check to be safe.
//
// Note that we *do* allow projection *outputs* to contain
// `self` (i.e., `trait Foo: Bar<Output=Self::Result> { type Result; }`),
// we just require the user to specify *both* outputs
// in the object type (i.e., `dyn Foo<Output=(), Result=()>`).
//
// This is ALT2 in issue #56288, see that for discussion of the
// possible alternatives.
data.skip_binder()
.projection_ty
.trait_ref(self)
.input_types()
.skip(1)
.any(|t| t.has_self_ty())
}
ty::Predicate::WellFormed(..) |
ty::Predicate::ObjectSafe(..) |
ty::Predicate::TypeOutlives(..) |
@ -243,6 +262,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
method: &ty::AssociatedItem)
-> Option<MethodViolationCode>
{
debug!("object_safety_violation_for_method({:?}, {:?})", trait_def_id, method);
// Any method that has a `Self : Sized` requisite is otherwise
// exempt from the regulations.
if self.generics_require_sized_self(method.def_id) {
@ -261,6 +281,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
method: &ty::AssociatedItem)
-> bool
{
debug!("is_vtable_safe_method({:?}, {:?})", trait_def_id, method);
// Any method that has a `Self : Sized` requisite can't be called.
if self.generics_require_sized_self(method.def_id) {
return false;
@ -380,6 +401,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
fn receiver_for_self_ty(
self, receiver_ty: Ty<'tcx>, self_ty: Ty<'tcx>, method_def_id: DefId
) -> Ty<'tcx> {
debug!("receiver_for_self_ty({:?}, {:?}, {:?})", receiver_ty, self_ty, method_def_id);
let substs = Substs::for_item(self, method_def_id, |param, _| {
if param.index == 0 {
self_ty.into()
@ -388,7 +410,10 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
}
});
receiver_ty.subst(self, substs)
let result = receiver_ty.subst(self, substs);
debug!("receiver_for_self_ty({:?}, {:?}, {:?}) = {:?}",
receiver_ty, self_ty, method_def_id, result);
result
}
/// creates the object type for the current trait. For example,
@ -404,18 +429,26 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
);
let mut associated_types = traits::supertraits(self, ty::Binder::dummy(trait_ref))
.flat_map(|trait_ref| self.associated_items(trait_ref.def_id()))
.filter(|item| item.kind == ty::AssociatedKind::Type)
.flat_map(|super_trait_ref| {
self.associated_items(super_trait_ref.def_id())
.map(move |item| (super_trait_ref, item))
})
.filter(|(_, item)| item.kind == ty::AssociatedKind::Type)
.collect::<Vec<_>>();
// existential predicates need to be in a specific order
associated_types.sort_by_cached_key(|item| self.def_path_hash(item.def_id));
associated_types.sort_by_cached_key(|(_, item)| self.def_path_hash(item.def_id));
let projection_predicates = associated_types.into_iter().map(|item| {
let projection_predicates = associated_types.into_iter().map(|(super_trait_ref, item)| {
// We *can* get bound lifetimes here in cases like
// `trait MyTrait: for<'s> OtherTrait<&'s T, Output=bool>`.
//
// binder moved to (*)...
let super_trait_ref = super_trait_ref.skip_binder();
ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
ty: self.mk_projection(item.def_id, trait_ref.substs),
ty: self.mk_projection(item.def_id, super_trait_ref.substs),
item_def_id: item.def_id,
substs: trait_ref.substs,
substs: super_trait_ref.substs,
})
});
@ -424,7 +457,8 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
);
let object_ty = self.mk_dynamic(
ty::Binder::dummy(existential_predicates),
// (*) ... binder re-introduced here
ty::Binder::bind(existential_predicates),
lifetime,
);

View File

@ -1754,17 +1754,19 @@ bitflags! {
pub struct AdtFlags: u32 {
const NO_ADT_FLAGS = 0;
const IS_ENUM = 1 << 0;
const IS_PHANTOM_DATA = 1 << 1;
const IS_FUNDAMENTAL = 1 << 2;
const IS_UNION = 1 << 3;
const IS_BOX = 1 << 4;
const IS_UNION = 1 << 1;
const IS_STRUCT = 1 << 2;
const HAS_CTOR = 1 << 3;
const IS_PHANTOM_DATA = 1 << 4;
const IS_FUNDAMENTAL = 1 << 5;
const IS_BOX = 1 << 6;
/// Indicates whether the type is an `Arc`.
const IS_ARC = 1 << 5;
const IS_ARC = 1 << 7;
/// Indicates whether the type is an `Rc`.
const IS_RC = 1 << 6;
const IS_RC = 1 << 8;
/// Indicates whether the variant list of this ADT is `#[non_exhaustive]`.
/// (i.e., this flag is never set unless this ADT is an enum).
const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 7;
const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 9;
}
}
@ -2079,31 +2081,43 @@ impl<'a, 'gcx, 'tcx> AdtDef {
repr: ReprOptions) -> Self {
debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr);
let mut flags = AdtFlags::NO_ADT_FLAGS;
let attrs = tcx.get_attrs(did);
if attr::contains_name(&attrs, "fundamental") {
flags = flags | AdtFlags::IS_FUNDAMENTAL;
}
if Some(did) == tcx.lang_items().phantom_data() {
flags = flags | AdtFlags::IS_PHANTOM_DATA;
}
if Some(did) == tcx.lang_items().owned_box() {
flags = flags | AdtFlags::IS_BOX;
}
if Some(did) == tcx.lang_items().arc() {
flags = flags | AdtFlags::IS_ARC;
}
if Some(did) == tcx.lang_items().rc() {
flags = flags | AdtFlags::IS_RC;
}
if kind == AdtKind::Enum && tcx.has_attr(did, "non_exhaustive") {
debug!("found non-exhaustive variant list for {:?}", did);
flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE;
}
match kind {
AdtKind::Enum => flags = flags | AdtFlags::IS_ENUM,
AdtKind::Union => flags = flags | AdtFlags::IS_UNION,
AdtKind::Struct => {}
flags |= match kind {
AdtKind::Enum => AdtFlags::IS_ENUM,
AdtKind::Union => AdtFlags::IS_UNION,
AdtKind::Struct => AdtFlags::IS_STRUCT,
};
if let AdtKind::Struct = kind {
let variant_def = &variants[VariantIdx::new(0)];
let def_key = tcx.def_key(variant_def.did);
match def_key.disambiguated_data.data {
DefPathData::StructCtor => flags |= AdtFlags::HAS_CTOR,
_ => (),
}
}
let attrs = tcx.get_attrs(did);
if attr::contains_name(&attrs, "fundamental") {
flags |= AdtFlags::IS_FUNDAMENTAL;
}
if Some(did) == tcx.lang_items().phantom_data() {
flags |= AdtFlags::IS_PHANTOM_DATA;
}
if Some(did) == tcx.lang_items().owned_box() {
flags |= AdtFlags::IS_BOX;
}
if Some(did) == tcx.lang_items().arc() {
flags |= AdtFlags::IS_ARC;
}
if Some(did) == tcx.lang_items().rc() {
flags |= AdtFlags::IS_RC;
}
AdtDef {
did,
variants,
@ -2114,25 +2128,25 @@ impl<'a, 'gcx, 'tcx> AdtDef {
#[inline]
pub fn is_struct(&self) -> bool {
!self.is_union() && !self.is_enum()
self.flags.contains(AdtFlags::IS_STRUCT)
}
#[inline]
pub fn is_union(&self) -> bool {
self.flags.intersects(AdtFlags::IS_UNION)
self.flags.contains(AdtFlags::IS_UNION)
}
#[inline]
pub fn is_enum(&self) -> bool {
self.flags.intersects(AdtFlags::IS_ENUM)
self.flags.contains(AdtFlags::IS_ENUM)
}
#[inline]
pub fn is_variant_list_non_exhaustive(&self) -> bool {
self.flags.intersects(AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE)
self.flags.contains(AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE)
}
/// Returns the kind of the ADT - Struct or Enum.
/// Returns the kind of the ADT.
#[inline]
pub fn adt_kind(&self) -> AdtKind {
if self.is_enum() {
@ -2161,33 +2175,39 @@ impl<'a, 'gcx, 'tcx> AdtDef {
}
}
/// Returns whether this type is #[fundamental] for the purposes
/// If this function returns `true`, it implies that `is_struct` must return `true`.
#[inline]
pub fn has_ctor(&self) -> bool {
self.flags.contains(AdtFlags::HAS_CTOR)
}
/// Returns whether this type is `#[fundamental]` for the purposes
/// of coherence checking.
#[inline]
pub fn is_fundamental(&self) -> bool {
self.flags.intersects(AdtFlags::IS_FUNDAMENTAL)
self.flags.contains(AdtFlags::IS_FUNDAMENTAL)
}
/// Returns `true` if this is PhantomData<T>.
#[inline]
pub fn is_phantom_data(&self) -> bool {
self.flags.intersects(AdtFlags::IS_PHANTOM_DATA)
self.flags.contains(AdtFlags::IS_PHANTOM_DATA)
}
/// Returns `true` if this is `Arc<T>`.
pub fn is_arc(&self) -> bool {
self.flags.intersects(AdtFlags::IS_ARC)
self.flags.contains(AdtFlags::IS_ARC)
}
/// Returns `true` if this is `Rc<T>`.
pub fn is_rc(&self) -> bool {
self.flags.intersects(AdtFlags::IS_RC)
self.flags.contains(AdtFlags::IS_RC)
}
/// Returns `true` if this is Box<T>.
#[inline]
pub fn is_box(&self) -> bool {
self.flags.intersects(AdtFlags::IS_BOX)
self.flags.contains(AdtFlags::IS_BOX)
}
/// Returns whether this type has a destructor.

View File

@ -16,7 +16,7 @@ num_cpus = "1.0"
rustc-demangle = "0.1.4"
memmap = "0.6"
log = "0.4.5"
libc = "0.2.43"
libc = "0.2.44"
jobserver = "0.1.11"
serialize = { path = "../libserialize" }

View File

@ -335,11 +335,20 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> {
bx: &mut Bx,
llindex: V
) -> Self {
// Statically compute the offset if we can, otherwise just use the element size,
// as this will yield the lowest alignment.
let layout = self.layout.field(bx, 0);
let offset = if bx.is_const_integral(llindex) {
layout.size.checked_mul(bx.const_to_uint(llindex), bx).unwrap_or(layout.size)
} else {
layout.size
};
PlaceRef {
llval: bx.inbounds_gep(self.llval, &[bx.cx().const_usize(0), llindex]),
llextra: None,
layout: self.layout.field(bx.cx(), 0),
align: self.align
layout,
align: self.align.restrict_for_offset(offset),
}
}

View File

@ -131,8 +131,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let keep_going = header_bx.icmp(IntPredicate::IntNE, current, end);
header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb());
let align = dest.align.restrict_for_offset(dest.layout.field(bx.cx(), 0).size);
cg_elem.val.store(&mut body_bx,
PlaceRef::new_sized(current, cg_elem.layout, dest.align));
PlaceRef::new_sized(current, cg_elem.layout, align));
let next = body_bx.inbounds_gep(current, &[bx.cx().const_usize(1)]);
body_bx.br(header_bx.llbb());

View File

@ -1415,7 +1415,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
self.check_call_dest(mir, term, &sig, destination, term_location);
self.prove_predicates(
sig.inputs().iter().map(|ty| ty::Predicate::WellFormed(ty)),
sig.inputs_and_output.iter().map(|ty| ty::Predicate::WellFormed(ty)),
term_location.to_locations(),
ConstraintCategory::Boring,
);

View File

@ -86,7 +86,7 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
type MemoryExtra: Default;
/// Extra data stored in every allocation.
type AllocExtra: AllocationExtra<Self::PointerTag, Self::MemoryExtra>;
type AllocExtra: AllocationExtra<Self::PointerTag, Self::MemoryExtra> + 'static;
/// Memory's allocation map
type MemoryMap:

View File

@ -708,8 +708,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
relocations
.iter()
.map(|&(offset, reloc)| {
(offset + dest.offset - src.offset + (i * size * relocations.len() as u64),
reloc)
// compute offset for current repetition
let dest_offset = dest.offset + (i * size);
(
// shift offsets from source allocation to destination allocation
offset + dest_offset - src.offset,
reloc,
)
})
);
}

View File

@ -517,7 +517,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
// Only allow statics (not consts) to refer to other statics.
if self.mode == Mode::Static || self.mode == Mode::StaticMut {
if context.is_mutating_use() {
if self.mode == Mode::Static && context.is_mutating_use() {
// this is not strictly necessary as miri will also bail out
// For interior mutability we can't really catch this statically as that
// goes through raw pointers and intermediate temporaries, so miri has

View File

@ -230,13 +230,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
}
let subclass = SingleImport {
target: ident,
source: source.ident,
result: PerNS {
target: ident,
source_bindings: PerNS {
type_ns: Cell::new(Err(Undetermined)),
value_ns: Cell::new(Err(Undetermined)),
macro_ns: Cell::new(Err(Undetermined)),
},
target_bindings: PerNS {
type_ns: Cell::new(None),
value_ns: Cell::new(None),
macro_ns: Cell::new(None),
},
type_ns_only,
};
self.add_import_directive(

View File

@ -75,7 +75,7 @@ use syntax_pos::{Span, DUMMY_SP, MultiSpan};
use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
use std::cell::{Cell, RefCell};
use std::{cmp, fmt, iter, ptr};
use std::{cmp, fmt, iter, mem, ptr};
use std::collections::BTreeSet;
use std::mem::replace;
use rustc_data_structures::ptr_key::PtrKey;
@ -1022,11 +1022,11 @@ enum ModuleOrUniformRoot<'a> {
CurrentScope,
}
impl<'a> PartialEq for ModuleOrUniformRoot<'a> {
fn eq(&self, other: &Self) -> bool {
match (*self, *other) {
impl ModuleOrUniformRoot<'_> {
fn same_def(lhs: Self, rhs: Self) -> bool {
match (lhs, rhs) {
(ModuleOrUniformRoot::Module(lhs),
ModuleOrUniformRoot::Module(rhs)) => ptr::eq(lhs, rhs),
ModuleOrUniformRoot::Module(rhs)) => lhs.def() == rhs.def(),
(ModuleOrUniformRoot::CrateRootAndExternPrelude,
ModuleOrUniformRoot::CrateRootAndExternPrelude) |
(ModuleOrUniformRoot::ExternPrelude, ModuleOrUniformRoot::ExternPrelude) |
@ -1521,6 +1521,7 @@ pub struct Resolver<'a, 'b: 'a> {
/// FIXME: Refactor things so that this is passed through arguments and not resolver.
last_import_segment: bool,
blacklisted_binding: Option<&'a NameBinding<'a>>,
/// The idents for the primitive types.
primitive_type_table: PrimitiveTypeTable,
@ -1871,6 +1872,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
current_self_type: None,
current_self_item: None,
last_import_segment: false,
blacklisted_binding: None,
primitive_type_table: PrimitiveTypeTable::new(),
@ -2392,11 +2394,27 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
ast::UseTreeKind::Simple(..) if segments.len() == 1 => &[TypeNS, ValueNS][..],
_ => &[TypeNS],
};
let report_error = |this: &Self, ns| {
let what = if ns == TypeNS { "type parameters" } else { "local variables" };
this.session.span_err(ident.span, &format!("imports cannot refer to {}", what));
};
for &ns in nss {
if let Some(LexicalScopeBinding::Def(..)) =
self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) {
let what = if ns == TypeNS { "type parameters" } else { "local variables" };
self.session.span_err(ident.span, &format!("imports cannot refer to {}", what));
match self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) {
Some(LexicalScopeBinding::Def(..)) => {
report_error(self, ns);
}
Some(LexicalScopeBinding::Item(binding)) => {
let orig_blacklisted_binding =
mem::replace(&mut self.blacklisted_binding, Some(binding));
if let Some(LexicalScopeBinding::Def(..)) =
self.resolve_ident_in_lexical_scope(ident, ns, None,
use_tree.prefix.span) {
report_error(self, ns);
}
self.blacklisted_binding = orig_blacklisted_binding;
}
None => {}
}
}
} else if let ast::UseTreeKind::Nested(use_trees) = &use_tree.kind {
@ -3858,6 +3876,13 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
module = Some(ModuleOrUniformRoot::Module(next_module));
record_segment_def(self, def);
} else if def == Def::ToolMod && i + 1 != path.len() {
if binding.is_import() {
self.session.struct_span_err(
ident.span, "cannot use a tool module through an import"
).span_note(
binding.span, "the tool module imported here"
).emit();
}
let def = Def::NonMacroAttr(NonMacroAttrKind::Tool);
return PathResult::NonModule(PathResolution::new(def));
} else if def == Def::Err {

View File

@ -499,6 +499,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
.push((path, path_span, kind, parent_scope.clone(), def.ok()));
}
self.prohibit_imported_non_macro_attrs(None, def.ok(), path_span);
def
} else {
let binding = self.early_resolve_ident_in_lexical_scope(
@ -515,7 +516,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
.push((path[0].ident, kind, parent_scope.clone(), binding.ok()));
}
binding.map(|binding| binding.def_ignoring_ambiguity())
let def = binding.map(|binding| binding.def_ignoring_ambiguity());
self.prohibit_imported_non_macro_attrs(binding.ok(), def.ok(), path_span);
def
}
}
@ -953,36 +956,34 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
// but its `Def` should coincide with a crate passed with `--extern`
// (otherwise there would be ambiguity) and we can skip feature error in this case.
'ok: {
if !is_import || self.session.features_untracked().uniform_paths {
if !is_import || !rust_2015 {
break 'ok;
}
if ns == TypeNS && use_prelude && self.extern_prelude_get(ident, true).is_some() {
break 'ok;
}
if rust_2015 {
let root_ident = Ident::new(keywords::CrateRoot.name(), orig_ident.span);
let root_module = self.resolve_crate_root(root_ident);
if self.resolve_ident_in_module_ext(ModuleOrUniformRoot::Module(root_module),
orig_ident, ns, None, false, path_span)
.is_ok() {
break 'ok;
}
let root_ident = Ident::new(keywords::CrateRoot.name(), orig_ident.span);
let root_module = self.resolve_crate_root(root_ident);
if self.resolve_ident_in_module_ext(ModuleOrUniformRoot::Module(root_module),
orig_ident, ns, None, false, path_span)
.is_ok() {
break 'ok;
}
let msg = "imports can only refer to extern crate names \
passed with `--extern` on stable channel";
let mut err = feature_err(&self.session.parse_sess, "uniform_paths",
ident.span, GateIssue::Language, msg);
let msg = "imports can only refer to extern crate names passed with \
`--extern` in macros originating from 2015 edition";
let mut err = self.session.struct_span_err(ident.span, msg);
let what = self.binding_description(binding, ident,
flags.contains(Flags::MISC_FROM_PRELUDE));
let note_msg = format!("this import refers to {what}", what = what);
if binding.span.is_dummy() {
let label_span = if binding.span.is_dummy() {
err.note(&note_msg);
ident.span
} else {
err.span_note(binding.span, &note_msg);
err.span_label(binding.span, "not an extern crate passed with `--extern`");
}
binding.span
};
err.span_label(label_span, "not an extern crate passed with `--extern`");
err.emit();
}
@ -1091,6 +1092,20 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
}
}
fn prohibit_imported_non_macro_attrs(&self, binding: Option<&'a NameBinding<'a>>,
def: Option<Def>, span: Span) {
if let Some(Def::NonMacroAttr(kind)) = def {
if kind != NonMacroAttrKind::Tool && binding.map_or(true, |b| b.is_import()) {
let msg = format!("cannot use a {} through an import", kind.descr());
let mut err = self.session.struct_span_err(span, &msg);
if let Some(binding) = binding {
err.span_note(binding.span, &format!("the {} imported here", kind.descr()));
}
err.emit();
}
}
}
fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
err: &mut DiagnosticBuilder<'a>, span: Span) {
// First check if this is a locally-defined bang macro.
@ -1187,7 +1202,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let ident = ident.modern();
self.macro_names.insert(ident);
let def = Def::Macro(def_id, MacroKind::Bang);
let vis = ty::Visibility::Invisible; // Doesn't matter for legacy bindings
let is_macro_export = attr::contains_name(&item.attrs, "macro_export");
let vis = if is_macro_export {
ty::Visibility::Public
} else {
ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))
};
let binding = (def, vis, item.span, expansion).to_name_binding(self.arenas);
self.set_binding_parent_module(binding, self.current_module);
let legacy_binding = self.arenas.alloc_legacy_binding(LegacyBinding {
@ -1195,9 +1215,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
});
*current_legacy_scope = LegacyScope::Binding(legacy_binding);
self.all_macros.insert(ident.name, def);
if attr::contains_name(&item.attrs, "macro_export") {
if is_macro_export {
let module = self.graph_root;
let vis = ty::Visibility::Public;
self.define(module, ident, MacroNS,
(def, vis, item.span, expansion, IsMacroExport));
} else {

View File

@ -42,9 +42,10 @@ use std::{mem, ptr};
#[derive(Clone, Debug)]
pub enum ImportDirectiveSubclass<'a> {
SingleImport {
target: Ident,
source: Ident,
result: PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
target: Ident,
source_bindings: PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
target_bindings: PerNS<Cell<Option<&'a NameBinding<'a>>>>,
type_ns_only: bool,
},
GlobImport {
@ -227,6 +228,11 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
}
let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| {
if let Some(blacklisted_binding) = this.blacklisted_binding {
if ptr::eq(binding, blacklisted_binding) {
return Err((Determined, Weak::No));
}
}
// `extern crate` are always usable for backwards compatibility, see issue #37020,
// remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`.
let usable = this.is_accessible(binding.vis) || binding.is_extern_crate();
@ -234,7 +240,18 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
};
if record_used {
return resolution.binding.ok_or((Determined, Weak::No)).and_then(|binding| {
return resolution.binding.and_then(|binding| {
// If the primary binding is blacklisted, search further and return the shadowed
// glob binding if it exists. What we really want here is having two separate
// scopes in a module - one for non-globs and one for globs, but until that's done
// use this hack to avoid inconsistent resolution ICEs during import validation.
if let Some(blacklisted_binding) = self.blacklisted_binding {
if ptr::eq(binding, blacklisted_binding) {
return resolution.shadowed_glob;
}
}
Some(binding)
}).ok_or((Determined, Weak::No)).and_then(|binding| {
if self.last_import_segment && check_usable(self, binding).is_err() {
Err((Determined, Weak::No))
} else {
@ -465,6 +482,10 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
self.set_binding_parent_module(binding, module);
self.update_resolution(module, ident, ns, |this, resolution| {
if let Some(old_binding) = resolution.binding {
if binding.def() == Def::Err {
// Do not override real bindings with `Def::Err`s from error recovery.
return Ok(());
}
match (old_binding.is_glob_import(), binding.is_glob_import()) {
(true, true) => {
if binding.def() != old_binding.def() {
@ -642,10 +663,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
if let Some((span, err, note)) = self.finalize_import(import) {
errors = true;
if let SingleImport { source, ref result, .. } = import.subclass {
if let SingleImport { source, ref source_bindings, .. } = import.subclass {
if source.name == "self" {
// Silence `unresolved import` error if E0429 is already emitted
if let Err(Determined) = result.value_ns.get() {
if let Err(Determined) = source_bindings.value_ns.get() {
continue;
}
}
@ -765,9 +786,11 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
};
directive.imported_module.set(Some(module));
let (source, target, result, type_ns_only) = match directive.subclass {
SingleImport { source, target, ref result, type_ns_only } =>
(source, target, result, type_ns_only),
let (source, target, source_bindings, target_bindings, type_ns_only) =
match directive.subclass {
SingleImport { source, target, ref source_bindings,
ref target_bindings, type_ns_only } =>
(source, target, source_bindings, target_bindings, type_ns_only),
GlobImport { .. } => {
self.resolve_glob_import(directive);
return true;
@ -777,7 +800,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
let mut indeterminate = false;
self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
if let Err(Undetermined) = result[ns].get() {
if let Err(Undetermined) = source_bindings[ns].get() {
// For better failure detection, pretend that the import will
// not define any names while resolving its module path.
let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
@ -786,13 +809,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
);
directive.vis.set(orig_vis);
result[ns].set(binding);
source_bindings[ns].set(binding);
} else {
return
};
let parent = directive.parent_scope.module;
match result[ns].get() {
match source_bindings[ns].get() {
Err(Undetermined) => indeterminate = true,
Err(Determined) => {
this.update_resolution(parent, target, ns, |_, resolution| {
@ -810,6 +833,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
}
Ok(binding) => {
let imported_binding = this.import(binding, directive);
target_bindings[ns].set(Some(imported_binding));
let conflict = this.try_define(parent, target, ns, imported_binding);
if let Err(old_binding) = conflict {
this.report_conflict(parent, target, ns, imported_binding, old_binding);
@ -836,7 +860,9 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
PathResult::Module(module) => {
// Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
if let Some(initial_module) = directive.imported_module.get() {
if module != initial_module && self.ambiguity_errors.is_empty() {
if !ModuleOrUniformRoot::same_def(module, initial_module)
&& self.ambiguity_errors.is_empty()
{
span_bug!(directive.span, "inconsistent resolution for an import");
}
} else {
@ -879,8 +905,9 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
PathResult::Indeterminate | PathResult::NonModule(..) => unreachable!(),
};
let (ident, result, type_ns_only) = match directive.subclass {
SingleImport { source, ref result, type_ns_only, .. } => (source, result, type_ns_only),
let (ident, source_bindings, target_bindings, type_ns_only) = match directive.subclass {
SingleImport { source, ref source_bindings, ref target_bindings, type_ns_only, .. } =>
(source, source_bindings, target_bindings, type_ns_only),
GlobImport { is_prelude, ref max_vis } => {
if directive.module_path.len() <= 1 {
// HACK(eddyb) `lint_if_path_starts_with_module` needs at least
@ -919,17 +946,20 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
let mut all_ns_err = true;
self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
let orig_blacklisted_binding =
mem::replace(&mut this.blacklisted_binding, target_bindings[ns].get());
let orig_last_import_segment = mem::replace(&mut this.last_import_segment, true);
let binding = this.resolve_ident_in_module(
module, ident, ns, Some(&directive.parent_scope), true, directive.span
);
this.last_import_segment = orig_last_import_segment;
this.blacklisted_binding = orig_blacklisted_binding;
directive.vis.set(orig_vis);
match binding {
Ok(binding) => {
// Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
let initial_def = result[ns].get().map(|initial_binding| {
let initial_def = source_bindings[ns].get().map(|initial_binding| {
all_ns_err = false;
this.record_use(ident, ns, initial_binding,
directive.module_path.is_empty());
@ -1034,7 +1064,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
let mut reexport_error = None;
let mut any_successful_reexport = false;
self.per_ns(|this, ns| {
if let Ok(binding) = result[ns].get() {
if let Ok(binding) = source_bindings[ns].get() {
let vis = directive.vis.get();
if !binding.pseudo_vis().is_at_least(vis, &*this) {
reexport_error = Some((ns, binding));
@ -1078,7 +1108,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
let mut full_path = directive.module_path.clone();
full_path.push(Segment::from_ident(ident));
self.per_ns(|this, ns| {
if let Ok(binding) = result[ns].get() {
if let Ok(binding) = source_bindings[ns].get() {
this.lint_if_path_starts_with_module(
directive.crate_lint(),
&full_path,
@ -1092,7 +1122,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
// Record what this import resolves to for later uses in documentation,
// this may resolve to either a value or a type, but for documentation
// purposes it's good enough to just favor one over the other.
self.per_ns(|this, ns| if let Some(binding) = result[ns].get().ok() {
self.per_ns(|this, ns| if let Some(binding) = source_bindings[ns].get().ok() {
let mut def = binding.def();
if let Def::Macro(def_id, _) = def {
// `DefId`s from the "built-in macro crate" should not leak from resolve because

View File

@ -1013,6 +1013,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
let mut associated_types = BTreeSet::default();
for tr in traits::elaborate_trait_ref(tcx, principal) {
debug!("conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", tr);
match tr {
ty::Predicate::Trait(pred) => {
associated_types.extend(tcx.associated_items(pred.def_id())
@ -1020,8 +1021,31 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
.map(|item| item.def_id));
}
ty::Predicate::Projection(pred) => {
// Include projections defined on supertraits.
projection_bounds.push((pred, DUMMY_SP))
// A `Self` within the original bound will be substituted with a
// `TRAIT_OBJECT_DUMMY_SELF`, so check for that.
let references_self =
pred.skip_binder().ty.walk().any(|t| t == dummy_self);
// If the projection output contains `Self`, force the user to
// elaborate it explicitly to avoid a bunch of complexity.
//
// The "classicaly useful" case is the following:
// ```
// trait MyTrait: FnMut() -> <Self as MyTrait>::MyOutput {
// type MyOutput;
// }
// ```
//
// Here, the user could theoretically write `dyn MyTrait<Output=X>`,
// but actually supporting that would "expand" to an infinitely-long type
// `fix $ τ → dyn MyTrait<MyOutput=X, Output=<τ as MyTrait>::MyOutput`.
//
// Instead, we force the user to write `dyn MyTrait<MyOutput=X, Output=X>`,
// which is uglier but works. See the discussion in #56288 for alternatives.
if !references_self {
// Include projections defined on supertraits,
projection_bounds.push((pred, DUMMY_SP))
}
}
_ => ()
}

View File

@ -280,7 +280,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
Def::Local(id) | Def::Upvar(id, ..) => {
Some(self.tcx.hir.span(id))
}
_ => self.tcx.hir.span_if_local(def.def_id())
_ => def.opt_def_id().and_then(|did| self.tcx.hir.span_if_local(did)),
};
if let Some(span) = def_span {
let label = match (unit_variant, inner_callee_path) {

View File

@ -98,7 +98,8 @@ use rustc::mir::interpret::{ConstValue, GlobalId};
use rustc::ty::subst::{CanonicalUserSubsts, UnpackedKind, Subst, Substs,
UserSelfTy, UserSubsts};
use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate, RegionKind};
use rustc::ty::{self, AdtKind, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate,
RegionKind};
use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
use rustc::ty::fold::TypeFoldable;
use rustc::ty::query::Providers;
@ -914,6 +915,7 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
fcx.resolve_generator_interiors(def_id);
for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
let ty = fcx.normalize_ty(span, ty);
fcx.require_type_is_sized(ty, span, code);
}
fcx.select_all_obligations_or_error();
@ -3221,8 +3223,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
return_expr_ty);
}
// A generic function for checking the then and else in an if
// or if-else.
// A generic function for checking the 'then' and 'else' clauses in an 'if'
// or 'if-else' expression.
fn check_then_else(&self,
cond_expr: &'gcx hir::Expr,
then_expr: &'gcx hir::Expr,
@ -3547,8 +3549,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// we don't look at stability attributes on
// struct-like enums (yet...), but it's definitely not
// a bug to have construct one.
if adt_kind != ty::AdtKind::Enum {
// a bug to have constructed one.
if adt_kind != AdtKind::Enum {
tcx.check_stability(v_field.did, Some(expr_id), field.span);
}
@ -3969,7 +3971,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
//
// to work in stable even if the Sized bound on `drop` is relaxed.
for i in 0..fn_sig.inputs().skip_binder().len() {
let input = tcx.erase_late_bound_regions(&fn_sig.input(i));
// We just want to check sizedness, so instead of introducing
// placeholder lifetimes with probing, we just replace higher lifetimes
// with fresh vars.
let input = self.replace_bound_vars_with_fresh_vars(
expr.span,
infer::LateBoundRegionConversionTime::FnCall,
&fn_sig.input(i)).0;
self.require_type_is_sized_deferred(input, expr.span,
traits::SizedArgumentType);
}
@ -3977,7 +3985,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Here we want to prevent struct constructors from returning unsized types.
// There were two cases this happened: fn pointer coercion in stable
// and usual function call in presense of unsized_locals.
let output = tcx.erase_late_bound_regions(&fn_sig.output());
// Also, as we just want to check sizedness, instead of introducing
// placeholder lifetimes with probing, we just replace higher lifetimes
// with fresh vars.
let output = self.replace_bound_vars_with_fresh_vars(
expr.span,
infer::LateBoundRegionConversionTime::FnCall,
&fn_sig.output()).0;
self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
}
@ -5148,26 +5162,48 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}).unwrap_or(false);
let mut new_def = def;
let (def_id, ty) = if let Def::SelfCtor(impl_def_id) = def {
let ty = self.impl_self_ty(span, impl_def_id).ty;
let (def_id, ty) = match def {
Def::SelfCtor(impl_def_id) => {
let ty = self.impl_self_ty(span, impl_def_id).ty;
let adt_def = ty.ty_adt_def();
match ty.ty_adt_def() {
Some(adt_def) if adt_def.is_struct() => {
let variant = adt_def.non_enum_variant();
new_def = Def::StructCtor(variant.did, variant.ctor_kind);
(variant.did, self.tcx.type_of(variant.did))
}
_ => {
(impl_def_id, self.tcx.types.err)
match adt_def {
Some(adt_def) if adt_def.has_ctor() => {
let variant = adt_def.non_enum_variant();
new_def = Def::StructCtor(variant.did, variant.ctor_kind);
(variant.did, self.tcx.type_of(variant.did))
}
_ => {
let mut err = self.tcx.sess.struct_span_err(span,
"the `Self` constructor can only be used with tuple or unit structs");
if let Some(adt_def) = adt_def {
match adt_def.adt_kind() {
AdtKind::Enum => {
err.note("did you mean to use one of the enum's variants?");
},
AdtKind::Struct |
AdtKind::Union => {
err.span_label(
span,
format!("did you mean `Self {{ /* fields */ }}`?"),
);
}
}
}
err.emit();
(impl_def_id, self.tcx.types.err)
}
}
}
} else {
let def_id = def.def_id();
_ => {
let def_id = def.def_id();
// The things we are substituting into the type should not contain
// escaping late-bound regions, and nor should the base type scheme.
let ty = self.tcx.type_of(def_id);
(def_id, ty)
// The things we are substituting into the type should not contain
// escaping late-bound regions, and nor should the base type scheme.
let ty = self.tcx.type_of(def_id);
(def_id, ty)
}
};
let substs = AstConv::create_substs_for_generic_args(

View File

@ -283,7 +283,7 @@ nav.sub {
padding-left: 0;
}
:not(.source) .example-wrap {
.rustdoc:not(.source) .example-wrap {
display: inline-flex;
margin-bottom: 10px;
}
@ -301,11 +301,11 @@ nav.sub {
text-align: right;
}
:not(.source) .example-wrap > pre.rust {
.rustdoc:not(.source) .example-wrap > pre.rust {
width: 100%;
}
body:not(.source) .example-wrap > pre {
.rustdoc:not(.source) .example-wrap > pre {
margin: 0;
}

View File

@ -395,7 +395,7 @@ pub fn make_test(s: &str,
// Uses libsyntax to parse the doctest and find if there's a main fn and the extern
// crate already is included.
let (already_has_main, already_has_extern_crate) = crate::syntax::with_globals(|| {
let (already_has_main, already_has_extern_crate, found_macro) = crate::syntax::with_globals(|| {
use crate::syntax::{ast, parse::{self, ParseSess}, source_map::FilePathMapping};
use crate::syntax_pos::FileName;
use errors::emitter::EmitterWriter;
@ -415,6 +415,7 @@ pub fn make_test(s: &str,
let mut found_main = false;
let mut found_extern_crate = cratename.is_none();
let mut found_macro = false;
let mut parser = match parse::maybe_new_parser_from_source_str(&sess, filename, source) {
Ok(p) => p,
@ -423,7 +424,7 @@ pub fn make_test(s: &str,
err.cancel();
}
return (found_main, found_extern_crate);
return (found_main, found_extern_crate, found_macro);
}
};
@ -451,6 +452,12 @@ pub fn make_test(s: &str,
}
}
if !found_macro {
if let ast::ItemKind::Mac(..) = item.node {
found_macro = true;
}
}
if found_main && found_extern_crate {
break;
}
@ -463,9 +470,28 @@ pub fn make_test(s: &str,
}
}
(found_main, found_extern_crate)
(found_main, found_extern_crate, found_macro)
});
// If a doctest's `fn main` is being masked by a wrapper macro, the parsing loop above won't
// see it. In that case, run the old text-based scan to see if they at least have a main
// function written inside a macro invocation. See
// https://github.com/rust-lang/rust/issues/56898
let already_has_main = if found_macro && !already_has_main {
s.lines()
.map(|line| {
let comment = line.find("//");
if let Some(comment_begins) = comment {
&line[0..comment_begins]
} else {
line
}
})
.any(|code| code.contains("fn main"))
} else {
already_has_main
};
// Don't inject `extern crate std` because it's already injected by the
// compiler.
if !already_has_extern_crate && !opts.no_crate_inject && cratename != Some("std") {
@ -1106,4 +1132,23 @@ assert_eq!(asdf::foo, 4);
let output = make_test(input, Some("asdf"), false, &opts);
assert_eq!(output, (expected, 3));
}
#[test]
fn make_test_main_in_macro() {
let opts = TestOptions::default();
let input =
"#[macro_use] extern crate my_crate;
test_wrapper! {
fn main() {}
}";
let expected =
"#![allow(unused)]
#[macro_use] extern crate my_crate;
test_wrapper! {
fn main() {}
}".to_string();
let output = make_test(input, Some("my_crate"), false, &opts);
assert_eq!(output, (expected, 1));
}
}

View File

@ -459,10 +459,7 @@ declare_features! (
// Support for arbitrary delimited token streams in non-macro attributes
(active, unrestricted_attribute_tokens, "1.30.0", Some(55208), None),
// Allows `use x::y;` to resolve through `self::x`, not just `::x`
(active, uniform_paths, "1.30.0", Some(53130), None),
// Allows unsized rvalues at arguments and parameters
// Allows unsized rvalues at arguments and parameters.
(active, unsized_locals, "1.30.0", Some(48055), None),
// #![test_runner]
@ -689,6 +686,8 @@ declare_features! (
(accepted, self_struct_ctor, "1.32.0", Some(51994), None),
// `Self` in type definitions (RFC 2300)
(accepted, self_in_typedefs, "1.32.0", Some(49303), None),
// Allows `use x::y;` to search `x` in the current scope.
(accepted, uniform_paths, "1.32.0", Some(53130), None),
);
// If you change this, please modify `src/doc/unstable-book` as well. You must

View File

@ -1,4 +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.
2018-11-28
2018-12-13

View File

@ -12,8 +12,8 @@
# source tarball for a stable release you'll likely see `1.x.0` for rustc and
# `0.x.0` for Cargo where they were released on `date`.
date: 2018-12-06
rustc: 1.31.0
date: 2018-12-20
rustc: 1.31.1
cargo: 0.32.0
# When making a stable release the process currently looks like:

View File

@ -0,0 +1,44 @@
// compile-flags: -C no-prepopulate-passes
#![crate_type="rlib"]
use std::usize;
#[repr(align(16))]
pub struct S {
arr: [u32; 4],
}
// CHECK-LABEL: @test1
// CHECK: store i32 0, i32* %{{.+}}, align 16
// CHECK: store i32 1, i32* %{{.+}}, align 4
// CHECK: store i32 2, i32* %{{.+}}, align 8
// CHECK: store i32 3, i32* %{{.+}}, align 4
#[no_mangle]
pub fn test1(s: &mut S) {
s.arr[0] = 0;
s.arr[1] = 1;
s.arr[2] = 2;
s.arr[3] = 3;
}
// CHECK-LABEL: @test2
// CHECK: store i32 4, i32* %{{.+}}, align 4
#[allow(const_err)]
#[no_mangle]
pub fn test2(s: &mut S) {
s.arr[usize::MAX / 4 + 1] = 4;
}
// CHECK-LABEL: @test3
// CHECK: store i32 5, i32* %{{.+}}, align 4
#[no_mangle]
pub fn test3(s: &mut S, i: usize) {
s.arr[i] = 5;
}
// CHECK-LABEL: @test4
// CHECK: store i32 6, i32* %{{.+}}, align 4
#[no_mangle]
pub fn test4(s: &mut S) {
s.arr = [6; 4];
}

Some files were not shown because too many files have changed in this diff Show More