if: branch = auto
- env: IMAGE=dist-armv7-linux DEPLOY=1
if: branch = auto
- - env: IMAGE=dist-i586-gnu-i686-musl DEPLOY=1
+ - env: IMAGE=dist-i586-gnu-i586-i686-musl DEPLOY=1
if: branch = auto
- env: IMAGE=dist-i686-freebsd DEPLOY=1
if: branch = auto
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"dbghelp-sys 0.2.0 (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.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
"filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.15 (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.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.9 (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.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"libgit2-sys 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
"diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"curl-sys 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (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.23 (registry+https://github.com/rust-lang/crates.io-index)",
"socket2 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"libgit2-sys 0.6.18 (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.23 (registry+https://github.com/rust-lang/crates.io-index)",
[[package]]
name = "jobserver"
-version = "0.1.8"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libc"
-version = "0.2.34"
+version = "0.2.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
"cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"curl-sys 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)",
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
dependencies = [
"cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
dependencies = [
"cfg-if 0.1.2 (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.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
"bitflags 0.9.1 (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.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-zircon 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
dependencies = [
"coco 0.1.1 (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.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fmt_macros 0.0.0",
"graphviz 0.0.0",
- "jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_apfloat 0.0.0",
"rustc_back 0.0.0",
"rustc_const_math 0.0.0",
name = "rustc_back"
version = "0.0.0"
dependencies = [
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serialize 0.0.0",
"syntax 0.0.0",
dependencies = [
"cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
version = "0.0.0"
dependencies = [
"graphviz 0.0.0",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_errors 0.0.0",
"rustc_mir 0.0.0",
version = "0.0.0"
dependencies = [
"arena 0.0.0",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_const_math 0.0.0",
"rustc_data_structures 0.0.0",
version = "0.0.0"
dependencies = [
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serialize 0.0.0",
"arena 0.0.0",
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"graphviz 0.0.0",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_allocator 0.0.0",
"rustc_back 0.0.0",
version = "0.0.0"
dependencies = [
"graphviz 0.0.0",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_data_structures 0.0.0",
name = "rustc_lint"
version = "0.0.0"
dependencies = [
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_const_eval 0.0.0",
"syntax 0.0.0",
version = "0.0.0"
dependencies = [
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"proc_macro 0.0.0",
"rustc 0.0.0",
"rustc_back 0.0.0",
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"graphviz 0.0.0",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log_settings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_apfloat 0.0.0",
name = "rustc_passes"
version = "0.0.0"
dependencies = [
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_const_eval 0.0.0",
"rustc_const_math 0.0.0",
version = "0.0.0"
dependencies = [
"arena 0.0.0",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
name = "rustc_save_analysis"
version = "0.0.0"
dependencies = [
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rls-data 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
dependencies = [
"ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_back 0.0.0",
"rustc_data_structures 0.0.0",
dependencies = [
"arena 0.0.0",
"fmt_macros 0.0.0",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_const_math 0.0.0",
"rustc_data_structures 0.0.0",
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.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.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
dependencies = [
"cfg-if 0.1.2 (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.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
version = "0.0.0"
dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_cratesio_shim 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)",
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)",
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
"checksum ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3fcaf2365eb14b28ec7603c98c06cc531f19de9eb283d89a3dff8417c8c99f5"
"checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21"
"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c"
-"checksum jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "931b04e5e57d88cc909528f0d701db36a870b72a052648ded8baf80f9f445e0f"
+"checksum jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "565f6106bd87b394398f813bea4e5ecad6d6b0f6aa077592d088f882a506481d"
"checksum json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)" = "39ebf0fac977ee3a4a3242b6446004ff64514889e3e2730bbd4f764a67a2e483"
"checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
"checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b"
-"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0"
+"checksum libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "96264e9b293e95d25bfcbbf8a88ffd1aedc85b754eba8b7d78012f638ba220eb"
"checksum libgit2-sys 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)" = "82fc20bd8beefe7c9f98aae2d3cff78e57f544cdd83d58fe181ec37a5fbe0c77"
"checksum libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0db4ec23611747ef772db1c4d650f8bd762f07b461727ec998f953c614024b75"
"checksum libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "87f737ad6cc6fd6eefe3d9dc5412f1573865bded441300904d2f42269e140f16"
fn main() {
let args = env::args_os().skip(1).collect::<Vec<_>>();
let rustdoc = env::var_os("RUSTDOC_REAL").expect("RUSTDOC_REAL was not set");
- let libdir = env::var_os("RUSTC_LIBDIR").expect("RUSTC_LIBDIR was not set");
+ let libdir = env::var_os("RUSTDOC_LIBDIR").expect("RUSTDOC_LIBDIR was not set");
let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set");
let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set");
+ use std::str::FromStr;
+
+ let verbose = match env::var("RUSTC_VERBOSE") {
+ Ok(s) => usize::from_str(&s).expect("RUSTC_VERBOSE should be an integer"),
+ Err(_) => 0,
+ };
+
let mut dylib_path = bootstrap::util::dylib_path();
dylib_path.insert(0, PathBuf::from(libdir));
cmd.arg("--deny-render-differences");
}
+ if verbose > 1 {
+ eprintln!("rustdoc command: {:?}", cmd);
+ }
+
std::process::exit(match cmd.status() {
Ok(s) => s.code().unwrap_or(1),
Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e),
fn run(self, builder: &Builder) -> Interned<PathBuf> {
let compiler = self.compiler;
- let lib = if compiler.stage >= 2 && builder.build.config.libdir_relative.is_some() {
- builder.build.config.libdir_relative.clone().unwrap()
+ let lib = if compiler.stage >= 1 && builder.build.config.libdir.is_some() {
+ builder.build.config.libdir.clone().unwrap()
} else {
PathBuf::from("lib")
};
let compiler = self.compiler(self.top_stage, host);
cmd.env("RUSTC_STAGE", compiler.stage.to_string())
.env("RUSTC_SYSROOT", self.sysroot(compiler))
- .env("RUSTC_LIBDIR", self.sysroot_libdir(compiler, self.build.build))
+ .env("RUSTDOC_LIBDIR", self.sysroot_libdir(compiler, self.build.build))
.env("CFG_RELEASE_CHANNEL", &self.build.config.channel)
.env("RUSTDOC_REAL", self.rustdoc(host))
.env("RUSTDOC_CRATE_VERSION", self.build.rust_version())
if let Some(target_linker) = self.build.linker(target) {
cargo.env("RUSTC_TARGET_LINKER", target_linker);
}
+ if cmd != "build" {
+ cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(self.compiler(2, self.build.build)));
+ }
if mode != Mode::Tool {
// Tools don't get debuginfo right now, e.g. cargo and rls don't
}
Mode::Librustc => {
builder.ensure(compile::Rustc { compiler, target });
- compile::rustc_cargo(build, &compiler, target, &mut cargo);
+ compile::rustc_cargo(build, target, &mut cargo);
("librustc", "rustc-main")
}
_ => panic!("can only test libraries"),
build.clear_if_dirty(&stage_out, &libtest_stamp(build, compiler, target));
let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build");
- rustc_cargo(build, &compiler, target, &mut cargo);
+ rustc_cargo(build, target, &mut cargo);
run_cargo(build,
&mut cargo,
&librustc_stamp(build, compiler, target));
/// Same as `std_cargo`, but for libtest
pub fn rustc_cargo(build: &Build,
- compiler: &Compiler,
target: Interned<String>,
cargo: &mut Command) {
cargo.arg("--features").arg(build.rustc_features())
.env("CFG_VERSION", build.rust_version())
.env("CFG_PREFIX", build.config.prefix.clone().unwrap_or_default());
- if compiler.stage == 0 {
- cargo.env("CFG_LIBDIR_RELATIVE", "lib");
- } else {
- let libdir_relative =
- build.config.libdir_relative.clone().unwrap_or(PathBuf::from("lib"));
- cargo.env("CFG_LIBDIR_RELATIVE", libdir_relative);
- }
+ let libdir_relative =
+ build.config.libdir.clone().unwrap_or(PathBuf::from("lib"));
+ cargo.env("CFG_LIBDIR_RELATIVE", libdir_relative);
// If we're not building a compiler with debugging information then remove
// these two env vars which would be set otherwise.
pub docdir: Option<PathBuf>,
pub bindir: Option<PathBuf>,
pub libdir: Option<PathBuf>,
- pub libdir_relative: Option<PathBuf>,
pub mandir: Option<PathBuf>,
pub codegen_tests: bool,
pub nodejs: Option<PathBuf>,
"MUSL root installation directory (deprecated)")
v("musl-root-x86_64", "target.x86_64-unknown-linux-musl.musl-root",
"x86_64-unknown-linux-musl install directory")
+v("musl-root-i586", "target.i586-unknown-linux-musl.musl-root",
+ "i586-unknown-linux-musl install directory")
v("musl-root-i686", "target.i686-unknown-linux-musl.musl-root",
"i686-unknown-linux-musl install directory")
v("musl-root-arm", "target.arm-unknown-linux-musleabi.musl-root",
t!(symlink_dir_force(&my_out, &out_dir));
let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc");
- compile::rustc_cargo(build, &compiler, target, &mut cargo);
+ compile::rustc_cargo(build, target, &mut cargo);
if build.config.compiler_docs {
// src/rustc/Cargo.toml contains a bin crate called rustc which
"arm-unknown-linux-gnueabihf" => "linux-armv4",
"armv7-linux-androideabi" => "android-armv7",
"armv7-unknown-linux-gnueabihf" => "linux-armv4",
+ "i586-unknown-linux-gnu" => "linux-elf",
+ "i586-unknown-linux-musl" => "linux-elf",
"i686-apple-darwin" => "darwin-i386-cc",
"i686-linux-android" => "android-x86",
"i686-unknown-freebsd" => "BSD-x86-elf",
--- /dev/null
+FROM ubuntu:16.04
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ g++-multilib \
+ make \
+ file \
+ curl \
+ ca-certificates \
+ python2.7 \
+ git \
+ cmake \
+ xz-utils \
+ sudo \
+ gdb \
+ patch \
+ libssl-dev \
+ pkg-config
+
+WORKDIR /build/
+COPY scripts/musl.sh /build/
+RUN CC=gcc CFLAGS="-m32 -fPIC -Wa,-mrelax-relocations=no" \
+ CXX=g++ CXXFLAGS="-m32 -Wa,-mrelax-relocations=no" \
+ bash musl.sh i686 --target=i686 && \
+ CC=gcc CFLAGS="-march=pentium -m32 -fPIC -Wa,-mrelax-relocations=no" \
+ CXX=g++ CXXFLAGS="-march=pentium -m32 -Wa,-mrelax-relocations=no" \
+ bash musl.sh i586 --target=i586 && \
+ rm -rf /build
+
+COPY scripts/sccache.sh /scripts/
+RUN sh /scripts/sccache.sh
+
+ENV RUST_CONFIGURE_ARGS \
+ --target=i686-unknown-linux-musl,i586-unknown-linux-gnu \
+ --musl-root-i586=/musl-i586 \
+ --musl-root-i686=/musl-i686 \
+ --enable-extended
+
+# Newer binutils broke things on some vms/distros (i.e., linking against
+# unknown relocs disabled by the following flag), so we need to go out of our
+# way to produce "super compatible" binaries.
+#
+# See: https://github.com/rust-lang/rust/issues/34978
+ENV CFLAGS_i686_unknown_linux_musl=-Wa,-mrelax-relocations=no
+ENV CFLAGS_i586_unknown_linux_gnu=-Wa,-mrelax-relocations=no
+# FIXME remove -Wl,-melf_i386 after cc is updated to include
+# https://github.com/alexcrichton/cc-rs/pull/281
+ENV CFLAGS_i586_unknown_linux_musl="-Wa,-mrelax-relocations=no -Wl,-melf_i386"
+
+ENV TARGETS=i586-unknown-linux-gnu
+ENV TARGETS=$TARGETS,i686-unknown-linux-musl
+
+ENV SCRIPT \
+ python2.7 ../x.py test --target $TARGETS && \
+ python2.7 ../x.py dist --target $TARGETS,i586-unknown-linux-musl
+++ /dev/null
-FROM ubuntu:16.04
-
-RUN apt-get update && apt-get install -y --no-install-recommends \
- g++-multilib \
- make \
- file \
- curl \
- ca-certificates \
- python2.7 \
- git \
- cmake \
- xz-utils \
- sudo \
- gdb \
- patch \
- libssl-dev \
- pkg-config
-
-WORKDIR /build/
-COPY dist-i586-gnu-i686-musl/musl-libunwind-patch.patch dist-i586-gnu-i686-musl/build-musl.sh /build/
-RUN sh /build/build-musl.sh && rm -rf /build
-
-COPY scripts/sccache.sh /scripts/
-RUN sh /scripts/sccache.sh
-
-ENV RUST_CONFIGURE_ARGS \
- --target=i686-unknown-linux-musl,i586-unknown-linux-gnu \
- --musl-root-i686=/musl-i686 \
- --enable-extended
-
-# Newer binutils broke things on some vms/distros (i.e., linking against
-# unknown relocs disabled by the following flag), so we need to go out of our
-# way to produce "super compatible" binaries.
-#
-# See: https://github.com/rust-lang/rust/issues/34978
-ENV CFLAGS_i686_unknown_linux_musl=-Wa,-mrelax-relocations=no
-ENV CFLAGS_i586_unknown_linux_gnu=-Wa,-mrelax-relocations=no
-
-ENV SCRIPT \
- python2.7 ../x.py test \
- --target i686-unknown-linux-musl \
- --target i586-unknown-linux-gnu \
- && \
- python2.7 ../x.py dist \
- --target i686-unknown-linux-musl \
- --target i586-unknown-linux-gnu
+++ /dev/null
-#!/bin/sh
-# Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-# file at the top-level directory of this distribution and at
-# http://rust-lang.org/COPYRIGHT.
-#
-# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-# option. This file may not be copied, modified, or distributed
-# except according to those terms.
-
-set -ex
-
-# We need to mitigate rust-lang/rust#34978 when compiling musl itself as well
-export CFLAGS="-fPIC -Wa,-mrelax-relocations=no"
-export CXXFLAGS="-Wa,-mrelax-relocations=no"
-
-MUSL=musl-1.1.17
-curl https://www.musl-libc.org/releases/$MUSL.tar.gz | tar xzf -
-cd $MUSL
-CC=gcc \
- CFLAGS="$CFLAGS -m32" \
- ./configure --prefix=/musl-i686 --disable-shared \
- --target=i686
-make AR=ar RANLIB=ranlib -j10
-make install
-cd ..
-
-# To build MUSL we're going to need a libunwind lying around, so acquire that
-# here and build it.
-curl -L https://github.com/llvm-mirror/llvm/archive/release_37.tar.gz | tar xzf -
-curl -L https://github.com/llvm-mirror/libunwind/archive/release_37.tar.gz | tar xzf -
-
-# Whoa what's this mysterious patch we're applying to libunwind! Why are we
-# swapping the values of ESP/EBP in libunwind?!
-#
-# Discovered in #35599 it turns out that the vanilla build of libunwind is not
-# suitable for unwinding 32-bit musl. After some investigation it ended up
-# looking like the register values for ESP/EBP were indeed incorrect (swapped)
-# in the source. Similar commits in libunwind (r280099 and r282589) have noticed
-# this for other platforms, and we just need to realize it for musl linux as
-# well.
-#
-# More technical info can be found at #35599
-cd libunwind-release_37
-patch -Np1 < /build/musl-libunwind-patch.patch
-cd ..
-
-mkdir libunwind-build
-cd libunwind-build
-CFLAGS="$CFLAGS -m32" CXXFLAGS="$CXXFLAGS -m32" cmake ../libunwind-release_37 \
- -DLLVM_PATH=/build/llvm-release_37 \
- -DLIBUNWIND_ENABLE_SHARED=0
-make -j10
-cp lib/libunwind.a /musl-i686/lib
+++ /dev/null
-diff --git a/include/libunwind.h b/include/libunwind.h
-index c5b9633..1360eb2 100644
---- a/include/libunwind.h
-+++ b/include/libunwind.h
-@@ -151,8 +151,8 @@ enum {
- UNW_X86_ECX = 1,
- UNW_X86_EDX = 2,
- UNW_X86_EBX = 3,
-- UNW_X86_EBP = 4,
-- UNW_X86_ESP = 5,
-+ UNW_X86_ESP = 4,
-+ UNW_X86_EBP = 5,
- UNW_X86_ESI = 6,
- UNW_X86_EDI = 7
- };
libssl-dev \
pkg-config
-WORKDIR /tmp
+WORKDIR /build
-COPY dist-various-1/build-rumprun.sh /tmp/
+COPY dist-various-1/build-rumprun.sh /build
RUN ./build-rumprun.sh
-COPY dist-various-1/build-arm-musl.sh /tmp/
-RUN ./build-arm-musl.sh
+COPY dist-various-1/install-x86_64-redox.sh /build
+RUN ./install-x86_64-redox.sh
+
+COPY scripts/musl.sh /build
+RUN env \
+ CC=arm-linux-gnueabi-gcc CFLAGS="-march=armv6 -marm" \
+ CXX=arm-linux-gnueabi-g++ CXXFLAGS="-march=armv6 -marm" \
+ bash musl.sh arm && \
+ env \
+ CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv6 -marm" \
+ CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv6 -marm" \
+ bash musl.sh armhf && \
+ env \
+ CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv7-a" \
+ CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv7-a" \
+ bash musl.sh armv7 && \
+ env \
+ CC=aarch64-linux-gnu-gcc \
+ CXX=aarch64-linux-gnu-g++ \
+ bash musl.sh aarch64 && \
+ rm -rf /build/*
-COPY dist-various-1/install-mips-musl.sh /tmp/
+COPY dist-various-1/install-mips-musl.sh /build
RUN ./install-mips-musl.sh
-COPY dist-various-1/install-mipsel-musl.sh /tmp/
+COPY dist-various-1/install-mipsel-musl.sh /build
RUN ./install-mipsel-musl.sh
-COPY dist-various-1/install-x86_64-redox.sh /tmp/
-RUN ./install-x86_64-redox.sh
-
ENV TARGETS=asmjs-unknown-emscripten
ENV TARGETS=$TARGETS,wasm32-unknown-emscripten
ENV TARGETS=$TARGETS,x86_64-rumprun-netbsd
ENV RUST_CONFIGURE_ARGS \
--enable-extended \
--target=$TARGETS \
- --musl-root-arm=/usr/local/arm-linux-musleabi \
- --musl-root-armhf=/usr/local/arm-linux-musleabihf \
- --musl-root-armv7=/usr/local/armv7-linux-musleabihf \
- --musl-root-aarch64=/usr/local/aarch64-linux-musl
+ --musl-root-arm=/musl-arm \
+ --musl-root-armhf=/musl-armhf \
+ --musl-root-armv7=/musl-armv7 \
+ --musl-root-aarch64=/musl-aarch64
ENV SCRIPT python2.7 ../x.py dist --target $TARGETS
# sccache
+++ /dev/null
-#!/usr/bin/env bash
-# Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-# file at the top-level directory of this distribution and at
-# http://rust-lang.org/COPYRIGHT.
-#
-# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-# option. This file may not be copied, modified, or distributed
-# except according to those terms.
-
-set -ex
-
-MUSL=1.1.17
-
-hide_output() {
- set +x
- on_err="
-echo ERROR: An error was encountered with the build.
-cat /tmp/build.log
-exit 1
-"
- trap "$on_err" ERR
- bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
- PING_LOOP_PID=$!
- $@ &> /tmp/build.log
- trap - ERR
- kill $PING_LOOP_PID
- rm /tmp/build.log
- set -x
-}
-
-curl -O https://www.musl-libc.org/releases/musl-$MUSL.tar.gz
-tar xf musl-$MUSL.tar.gz
-cd musl-$MUSL
-CC=arm-linux-gnueabi-gcc \
-CFLAGS="-march=armv6 -marm" \
- hide_output ./configure \
- --prefix=/usr/local/arm-linux-musleabi \
- --enable-wrapper=gcc
-hide_output make -j$(nproc)
-hide_output make install
-cd ..
-rm -rf musl-$MUSL
-
-tar xf musl-$MUSL.tar.gz
-cd musl-$MUSL
-CC=arm-linux-gnueabihf-gcc \
-CFLAGS="-march=armv6 -marm" \
- hide_output ./configure \
- --prefix=/usr/local/arm-linux-musleabihf \
- --enable-wrapper=gcc
-hide_output make -j$(nproc)
-hide_output make install
-cd ..
-rm -rf musl-$MUSL
-
-tar xf musl-$MUSL.tar.gz
-cd musl-$MUSL
-CC=arm-linux-gnueabihf-gcc \
-CFLAGS="-march=armv7-a" \
- hide_output ./configure \
- --prefix=/usr/local/armv7-linux-musleabihf \
- --enable-wrapper=gcc
-hide_output make -j$(nproc)
-hide_output make install
-cd ..
-rm -rf musl-$MUSL
-
-tar xf musl-$MUSL.tar.gz
-cd musl-$MUSL
-CC=aarch64-linux-gnu-gcc \
-CFLAGS="" \
- hide_output ./configure \
- --prefix=/usr/local/aarch64-linux-musl \
- --enable-wrapper=gcc
-hide_output make -j$(nproc)
-hide_output make install
-cd ..
-rm -rf musl-$MUSL*
-
-ln -nsf ../arm-linux-musleabi/bin/musl-gcc /usr/local/bin/arm-linux-musleabi-gcc
-ln -nsf ../arm-linux-musleabihf/bin/musl-gcc /usr/local/bin/arm-linux-musleabihf-gcc
-ln -nsf ../armv7-linux-musleabihf/bin/musl-gcc /usr/local/bin/armv7-linux-musleabihf-gcc
-ln -nsf ../aarch64-linux-musl/bin/musl-gcc /usr/local/bin/aarch64-unknown-linux-musl-gcc
-
-curl -L https://github.com/llvm-mirror/llvm/archive/release_39.tar.gz | tar xzf -
-curl -L https://github.com/llvm-mirror/libunwind/archive/release_39.tar.gz | tar xzf -
-
-mkdir libunwind-build
-cd libunwind-build
-cmake ../libunwind-release_39 \
- -DLLVM_PATH=/tmp/llvm-release_39 \
- -DLIBUNWIND_ENABLE_SHARED=0 \
- -DCMAKE_C_COMPILER=arm-linux-gnueabi-gcc \
- -DCMAKE_CXX_COMPILER=arm-linux-gnueabi-g++ \
- -DCMAKE_C_FLAGS="-march=armv6 -marm" \
- -DCMAKE_CXX_FLAGS="-march=armv6 -marm"
-make -j$(nproc)
-cp lib/libunwind.a /usr/local/arm-linux-musleabi/lib
-cd ..
-rm -rf libunwind-build
-
-mkdir libunwind-build
-cd libunwind-build
-cmake ../libunwind-release_39 \
- -DLLVM_PATH=/tmp/llvm-release_39 \
- -DLIBUNWIND_ENABLE_SHARED=0 \
- -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc \
- -DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ \
- -DCMAKE_C_FLAGS="-march=armv6 -marm" \
- -DCMAKE_CXX_FLAGS="-march=armv6 -marm"
-make -j$(nproc)
-cp lib/libunwind.a /usr/local/arm-linux-musleabihf/lib
-cd ..
-rm -rf libunwind-build
-
-mkdir libunwind-build
-cd libunwind-build
-cmake ../libunwind-release_39 \
- -DLLVM_PATH=/tmp/llvm-release_39 \
- -DLIBUNWIND_ENABLE_SHARED=0 \
- -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc \
- -DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ \
- -DCMAKE_C_FLAGS="-march=armv7-a" \
- -DCMAKE_CXX_FLAGS="-march=armv7-a"
-make -j$(nproc)
-cp lib/libunwind.a /usr/local/armv7-linux-musleabihf/lib
-cd ..
-rm -rf libunwind-build
-
-mkdir libunwind-build
-cd libunwind-build
-cmake ../libunwind-release_39 \
- -DLLVM_PATH=/tmp/llvm-release_39 \
- -DLIBUNWIND_ENABLE_SHARED=0 \
- -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc \
- -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ \
- -DCMAKE_C_FLAGS="" \
- -DCMAKE_CXX_FLAGS=""
-make -j$(nproc)
-cp lib/libunwind.a /usr/local/aarch64-linux-musl/lib
-cd ..
-rm -rf libunwind-build
-
-rm -rf libunwind-release_39
-rm -rf llvm-release_39
pkg-config
WORKDIR /build/
-COPY dist-x86_64-musl/build-musl.sh /build/
-RUN sh /build/build-musl.sh && rm -rf /build
+
+COPY scripts/musl.sh /build/
+# We need to mitigate rust-lang/rust#34978 when compiling musl itself as well
+RUN CC=gcc \
+ CFLAGS="-fPIC -Wa,-mrelax-relocations=no" \
+ CXX=g++ \
+ CXXFLAGS="-Wa,-mrelax-relocations=no" \
+ bash musl.sh x86_64 && rm -rf /build
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
+++ /dev/null
-#!/bin/sh
-# Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-# file at the top-level directory of this distribution and at
-# http://rust-lang.org/COPYRIGHT.
-#
-# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-# option. This file may not be copied, modified, or distributed
-# except according to those terms.
-
-set -ex
-
-# We need to mitigate rust-lang/rust#34978 when compiling musl itself as well
-export CFLAGS="-fPIC -Wa,-mrelax-relocations=no"
-export CXXFLAGS="-Wa,-mrelax-relocations=no"
-
-MUSL=musl-1.1.17
-curl https://www.musl-libc.org/releases/$MUSL.tar.gz | tar xzf -
-cd $MUSL
-./configure --prefix=/musl-x86_64 --disable-shared
-make -j10
-make install
-
-cd ..
-rm -rf $MUSL
-
-# To build MUSL we're going to need a libunwind lying around, so acquire that
-# here and build it.
-curl -L https://github.com/llvm-mirror/llvm/archive/release_37.tar.gz | tar xzf -
-curl -L https://github.com/llvm-mirror/libunwind/archive/release_37.tar.gz | tar xzf -
-
-mkdir libunwind-build
-cd libunwind-build
-cmake ../libunwind-release_37 -DLLVM_PATH=/build/llvm-release_37 \
- -DLIBUNWIND_ENABLE_SHARED=0
-make -j10
-cp lib/libunwind.a /musl-x86_64/lib
--- /dev/null
+# Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+# file at the top-level directory of this distribution and at
+# http://rust-lang.org/COPYRIGHT.
+#
+# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+set -ex
+
+hide_output() {
+ set +x
+ on_err="
+echo ERROR: An error was encountered with the build.
+cat /tmp/build.log
+exit 1
+"
+ trap "$on_err" ERR
+ bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
+ PING_LOOP_PID=$!
+ $@ &> /tmp/build.log
+ trap - ERR
+ kill $PING_LOOP_PID
+ rm /tmp/build.log
+ set -x
+}
+
+TAG=$1
+shift
+
+MUSL=musl-1.1.18
+
+# may have been downloaded in a previous run
+if [ ! -d $MUSL ]; then
+ curl https://www.musl-libc.org/releases/$MUSL.tar.gz | tar xzf -
+fi
+
+cd $MUSL
+./configure --disable-shared --prefix=/musl-$TAG $@
+if [ "$TAG" = "i586" -o "$TAG" = "i686" ]; then
+ hide_output make -j$(nproc) AR=ar RANLIB=ranlib
+else
+ hide_output make -j$(nproc)
+fi
+hide_output make install
+hide_output make clean
+
+cd ..
+
+LLVM=39
+# may have been downloaded in a previous run
+if [ ! -d libunwind-release_$LLVM ]; then
+ curl -L https://github.com/llvm-mirror/llvm/archive/release_$LLVM.tar.gz | tar xzf -
+ curl -L https://github.com/llvm-mirror/libunwind/archive/release_$LLVM.tar.gz | tar xzf -
+ # Whoa what's this mysterious patch we're applying to libunwind! Why are we
+ # swapping the values of ESP/EBP in libunwind?!
+ #
+ # Discovered in #35599 it turns out that the vanilla build of libunwind is not
+ # suitable for unwinding i686 musl. After some investigation it ended up
+ # looking like the register values for ESP/EBP were indeed incorrect (swapped)
+ # in the source. Similar commits in libunwind (r280099 and r282589) have noticed
+ # this for other platforms, and we just need to realize it for musl linux as
+ # well.
+ #
+ # More technical info can be found at #35599
+ cd libunwind-release_$LLVM
+ patch -Np1 << EOF
+diff --git a/include/libunwind.h b/include/libunwind.h
+index c5b9633..1360eb2 100644
+--- a/include/libunwind.h
++++ b/include/libunwind.h
+@@ -151,8 +151,8 @@ enum {
+ UNW_X86_ECX = 1,
+ UNW_X86_EDX = 2,
+ UNW_X86_EBX = 3,
+- UNW_X86_EBP = 4,
+- UNW_X86_ESP = 5,
++ UNW_X86_ESP = 4,
++ UNW_X86_EBP = 5,
+ UNW_X86_ESI = 6,
+ UNW_X86_EDI = 7
+ };
+fi
+EOF
+ cd ..
+fi
+
+mkdir libunwind-build
+cd libunwind-build
+cmake ../libunwind-release_$LLVM \
+ -DLLVM_PATH=/build/llvm-release_$LLVM \
+ -DLIBUNWIND_ENABLE_SHARED=0 \
+ -DCMAKE_C_COMPILER=$CC \
+ -DCMAKE_CXX_COMPILER=$CXX \
+ -DCMAKE_C_FLAGS="$CFLAGS" \
+ -DCMAKE_CXX_FLAGS="$CXXFLAGS"
+
+hide_output make -j$(nproc)
+cp lib/libunwind.a /musl-$TAG/lib
+cd ../ && rm -rf libunwind-build
* except according to those terms.
*/
@font-face {
- font-family: 'Fira Sans';
- font-style: normal;
- font-weight: 400;
- src: local('Fira Sans'), url("FiraSans-Regular.woff") format('woff');
+ font-family: 'Fira Sans';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Fira Sans'), url("FiraSans-Regular.woff") format('woff');
}
@font-face {
- font-family: 'Fira Sans';
- font-style: normal;
- font-weight: 500;
- src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff');
+ font-family: 'Fira Sans';
+ font-style: normal;
+ font-weight: 500;
+ src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff');
}
@font-face {
- font-family: 'Source Serif Pro';
- font-style: normal;
- font-weight: 400;
- src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff');
+ font-family: 'Source Serif Pro';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff');
}
@font-face {
- font-family: 'Source Serif Pro';
- font-style: italic;
- font-weight: 400;
- src: url("Heuristica-Italic.woff") format('woff');
+ font-family: 'Source Serif Pro';
+ font-style: italic;
+ font-weight: 400;
+ src: url("Heuristica-Italic.woff") format('woff');
}
@font-face {
- font-family: 'Source Serif Pro';
- font-style: normal;
- font-weight: 700;
- src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff');
+ font-family: 'Source Serif Pro';
+ font-style: normal;
+ font-weight: 700;
+ src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff');
}
@font-face {
- font-family: 'Source Code Pro';
- font-style: normal;
- font-weight: 400;
- /* Avoid using locally installed font because bad versions are in circulation:
- * see https://github.com/rust-lang/rust/issues/24355 */
- src: url("SourceCodePro-Regular.woff") format('woff');
+ font-family: 'Source Code Pro';
+ font-style: normal;
+ font-weight: 400;
+ /* Avoid using locally installed font because bad versions are in circulation:
+ * see https://github.com/rust-lang/rust/issues/24355 */
+ src: url("SourceCodePro-Regular.woff") format('woff');
}
*:not(body) {
-webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
}
/* General structure */
body {
- background-color: white;
- margin: 0 auto;
- padding: 0 15px;
- font-family: "Source Serif Pro", Georgia, Times, "Times New Roman", serif;
- font-size: 18px;
- color: #333;
- line-height: 1.428571429;
-
- -webkit-font-feature-settings: "kern", "liga";
- -moz-font-feature-settings: "kern", "liga";
- font-feature-settings: "kern", "liga";
+ background-color: white;
+ margin: 0 auto;
+ padding: 0 15px;
+ font-family: "Source Serif Pro", Georgia, Times, "Times New Roman", serif;
+ font-size: 18px;
+ color: #333;
+ line-height: 1.428571429;
+
+ -webkit-font-feature-settings: "kern", "liga";
+ -moz-font-feature-settings: "kern", "liga";
+ font-feature-settings: "kern", "liga";
}
@media (min-width: 768px) {
- body {
- max-width: 750px;
- }
+ body {
+ max-width: 750px;
+ }
}
h1, h2, h3, h4, h5, h6, nav, #versioninfo {
- font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
h1, h2, h3, h4, h5, h6 {
- color: black;
- font-weight: 400;
- line-height: 1.1;
+ color: black;
+ font-weight: 400;
+ line-height: 1.1;
}
h1, h2, h3 {
- margin-top: 20px;
- margin-bottom: 15px;
+ margin-top: 20px;
+ margin-bottom: 15px;
}
h1 {
- margin-bottom: 20px;
+ margin-bottom: 20px;
}
h4, h5, h6 {
- margin-top: 12px;
- margin-bottom: 10px;
- padding: 5px 10px;
+ margin-top: 12px;
+ margin-bottom: 10px;
+ padding: 5px 10px;
}
h5, h6 {
- text-decoration: underline;
+ text-decoration: underline;
}
h1 {
- font-size: 28px;
- font-weight: 500;
- padding: .1em .4em;
- border-bottom: 2px solid #ddd;
+ font-size: 28px;
+ font-weight: 500;
+ padding: .1em .4em;
+ border-bottom: 2px solid #ddd;
}
h1.title {
- line-height: 1.5em;
+ line-height: 1.5em;
}
h2 {
- font-size: 26px;
- padding: .2em .5em;
- border-bottom: 1px solid #ddd;
+ font-size: 26px;
+ padding: .2em .5em;
+ border-bottom: 1px solid #ddd;
}
h3 {
- font-size: 24px;
- padding: .2em .7em;
- border-bottom: 1px solid #DDE8FC;
+ font-size: 24px;
+ padding: .2em .7em;
+ border-bottom: 1px solid #DDE8FC;
}
h4 {
- font-size: 22px;
+ font-size: 22px;
}
h5 {
- font-size: 20px;
+ font-size: 20px;
}
h6 {
- font-size: 18px;
+ font-size: 18px;
}
@media (min-width: 992px) {
- h1 {
- font-size: 36px;
- }
- h2 {
- font-size: 30px;
- }
- h3 {
- font-size: 26px;
- }
+ h1 {
+ font-size: 36px;
+ }
+ h2 {
+ font-size: 30px;
+ }
+ h3 {
+ font-size: 26px;
+ }
}
nav {
- column-count: 2;
- -moz-column-count: 2;
- -webkit-column-count: 2;
- font-size: 15px;
- margin: 0 0 1em 0;
+ column-count: 2;
+ -moz-column-count: 2;
+ -webkit-column-count: 2;
+ font-size: 15px;
+ margin: 0 0 1em 0;
}
p {
- margin: 0 0 1em 0;
+ margin: 0 0 1em 0;
}
strong {
- font-weight: bold;
+ font-weight: bold;
}
em {
- font-style: italic;
+ font-style: italic;
}
footer {
- border-top: 1px solid #ddd;
- font-size: 14px;
- font-style: italic;
- padding-top: 5px;
- margin-top: 3em;
- margin-bottom: 1em;
+ border-top: 1px solid #ddd;
+ font-size: 14px;
+ font-style: italic;
+ padding-top: 5px;
+ margin-top: 3em;
+ margin-bottom: 1em;
}
/* Links layout */
a {
- text-decoration: none;
- color: #428BCA;
- background: transparent;
+ text-decoration: none;
+ color: #428BCA;
+ background: transparent;
}
a:hover, a:focus {
- color: #2A6496;
- text-decoration: underline;
+ color: #2A6496;
+ text-decoration: underline;
}
a:focus {
- outline: thin dotted #333;
- outline: 5px auto -webkit-focus-ring-color;
- outline-offset: -2px;
+ outline: thin dotted #333;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
}
a:hover, a:active {
- outline: 0;
+ outline: 0;
}
h1 a:link, h1 a:visited, h2 a:link, h2 a:visited,
/* Code */
pre, code {
- font-family: "Source Code Pro", Menlo, Monaco, Consolas, "DejaVu Sans Mono", monospace;
- word-wrap: break-word;
+ font-family: "Source Code Pro", Menlo, Monaco, Consolas, "DejaVu Sans Mono", monospace;
+ word-wrap: break-word;
}
pre {
- border-left: 2px solid #eee;
- white-space: pre-wrap;
- padding: 14px;
- padding-right: 0;
- margin: 20px 0;
- font-size: 13px;
- word-break: break-all;
+ border-left: 2px solid #eee;
+ white-space: pre-wrap;
+ padding: 14px;
+ padding-right: 0;
+ margin: 20px 0;
+ font-size: 15px;
+ word-break: break-all;
}
code {
- padding: 0 2px;
- color: #8D1A38;
+ padding: 0 2px;
+ color: #8D1A38;
}
pre code {
- padding: 0;
- font-size: inherit;
- color: inherit;
+ padding: 0;
+ font-size: inherit;
+ color: inherit;
}
a > code {
- color: #428BCA;
+ color: #428BCA;
}
.section-header > a > code {
- color: #8D1A38;
+ color: #8D1A38;
}
/* Code highlighting */
/* The rest */
#versioninfo {
- text-align: center;
- margin: 0.5em;
- font-size: 1.1em;
+ text-align: center;
+ margin: 0.5em;
+ font-size: 1.1em;
}
@media (min-width: 992px) {
- #versioninfo {
- font-size: 0.8em;
- position: fixed;
- bottom: 0px;
- right: 0px;
- }
- .white-sticker {
- background-color: #fff;
- margin: 2px;
- padding: 0 2px;
- border-radius: .2em;
- }
+ #versioninfo {
+ font-size: 0.8em;
+ position: fixed;
+ bottom: 0px;
+ right: 0px;
+ }
+ .white-sticker {
+ background-color: #fff;
+ margin: 2px;
+ padding: 0 2px;
+ border-radius: .2em;
+ }
}
#versioninfo a.hash {
- color: gray;
- font-size: 80%;
+ color: gray;
+ font-size: 80%;
}
blockquote {
- color: #000;
- margin: 20px 0;
- padding: 15px 20px;
- background-color: #f2f7f9;
- border-top: .1em solid #e5eef2;
- border-bottom: .1em solid #e5eef2;
+ color: #000;
+ margin: 20px 0;
+ padding: 15px 20px;
+ background-color: #f2f7f9;
+ border-top: .1em solid #e5eef2;
+ border-bottom: .1em solid #e5eef2;
}
blockquote p {
- font-size: 17px;
- font-weight: 300;
- line-height: 1.4;
+ font-size: 17px;
+ font-weight: 300;
+ line-height: 1.4;
}
blockquote p:last-child {
- margin-bottom: 0;
+ margin-bottom: 0;
}
ul, ol {
- padding-left: 25px;
+ padding-left: 25px;
}
ul ul, ol ul, ul ol, ol ol {
- margin-bottom: 0;
+ margin-bottom: 0;
}
dl {
- margin-bottom: 20px;
+ margin-bottom: 20px;
}
dd {
- margin-left: 0;
+ margin-left: 0;
}
nav ul {
- list-style-type: none;
- margin: 0;
- padding-left: 0px;
+ list-style-type: none;
+ margin: 0;
+ padding-left: 0px;
}
/* Only display one level of hierarchy in the TOC */
nav ul ul {
- display: none;
+ display: none;
}
sub,
sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
}
hr {
- margin-top: 20px;
- margin-bottom: 20px;
- border: 0;
- border-top: 1px solid #eeeeee;
+ margin-top: 20px;
+ margin-bottom: 20px;
+ border: 0;
+ border-top: 1px solid #eeeeee;
}
table {
- border-collapse: collapse;
- border-spacing: 0;
- overflow-x: auto;
- display: block;
+ border-collapse: collapse;
+ border-spacing: 0;
+ overflow-x: auto;
+ display: block;
}
table tr.odd {
- background: #eee;
+ background: #eee;
}
table td,
table th {
- border: 1px solid #ddd;
- padding: 5px;
+ border: 1px solid #ddd;
+ padding: 5px;
}
/* Code snippets */
pre.rust { position: relative; }
a.test-arrow {
- background-color: rgba(78, 139, 202, 0.2);
- display: inline-block;
- position: absolute;
- color: #f5f5f5;
- padding: 5px 10px 5px 10px;
- border-radius: 5px;
- font-size: 130%;
- top: 5px;
- right: 5px;
+ background-color: rgba(78, 139, 202, 0.2);
+ display: inline-block;
+ position: absolute;
+ color: #f5f5f5;
+ padding: 5px 10px 5px 10px;
+ border-radius: 5px;
+ font-size: 130%;
+ top: 5px;
+ right: 5px;
}
a.test-arrow:hover{
- background-color: #4e8bca;
- text-decoration: none;
+ background-color: #4e8bca;
+ text-decoration: none;
}
.unstable-feature {
- border: 2px solid red;
- padding: 5px;
+ border: 2px solid red;
+ padding: 5px;
}
@media (min-width: 1170px) {
- pre {
- font-size: 15px;
- }
+ pre {
+ font-size: 15px;
+ }
}
@media print {
- * {
- text-shadow: none !important;
- color: #000 !important;
- background: transparent !important;
- box-shadow: none !important;
- }
- a, a:visited {
- text-decoration: underline;
- }
- p a[href]:after {
- content: " (" attr(href) ")";
- }
- footer a[href]:after {
- content: "";
- }
- a[href^="javascript:"]:after, a[href^="#"]:after {
- content: "";
- }
- pre, blockquote {
- border: 1px solid #999;
- page-break-inside: avoid;
- }
- @page {
- margin: 2cm .5cm;
- }
- h1:not(.title), h2, h3 {
- border-bottom: 0px none;
- }
- p, h2, h3 {
- orphans: 3;
- widows: 3;
- }
- h2, h3 {
- page-break-after: avoid;
- }
- table {
- border-collapse: collapse !important;
- }
- table td, table th {
- background-color: #fff !important;
- }
+ * {
+ text-shadow: none !important;
+ color: #000 !important;
+ background: transparent !important;
+ box-shadow: none !important;
+ }
+ a, a:visited {
+ text-decoration: underline;
+ }
+ p a[href]:after {
+ content: " (" attr(href) ")";
+ }
+ footer a[href]:after {
+ content: "";
+ }
+ a[href^="javascript:"]:after, a[href^="#"]:after {
+ content: "";
+ }
+ pre, blockquote {
+ border: 1px solid #999;
+ page-break-inside: avoid;
+ }
+ @page {
+ margin: 2cm .5cm;
+ }
+ h1:not(.title), h2, h3 {
+ border-bottom: 0px none;
+ }
+ p, h2, h3 {
+ orphans: 3;
+ widows: 3;
+ }
+ h2, h3 {
+ page-break-after: avoid;
+ }
+ table {
+ border-collapse: collapse !important;
+ }
+ table td, table th {
+ background-color: #fff !important;
+ }
}
#keyword-table-marker + table thead { display: none; }
#keyword-table-marker + table td { border: none; }
#keyword-table-marker + table {
- margin-left: 2em;
- margin-bottom: 1em;
+ margin-left: 2em;
+ margin-bottom: 1em;
+}
+
+.error-described {
+ position: relative;
+}
+
+.information {
+ position: absolute;
+ left: -25px;
+ margin-top: 7px;
+ z-index: 1;
+}
+
+.tooltip {
+ position: relative;
+ display: inline-block;
+ cursor: pointer;
+}
+
+.tooltip .tooltiptext {
+ width: 120px;
+ display: none;
+ text-align: center;
+ padding: 5px 3px;
+ border-radius: 6px;
+ margin-left: 5px;
+ top: -5px;
+ left: 105%;
+ z-index: 1;
+}
+
+.tooltip:hover .tooltiptext {
+ display: inline;
+}
+
+.tooltip .tooltiptext::after {
+ content: " ";
+ position: absolute;
+ top: 50%;
+ left: 13px;
+ margin-top: -5px;
+ border-width: 5px;
+ border-style: solid;
}
--- /dev/null
+# `crate_in_paths`
+
+The tracking issue for this feature is: [#44660]
+
+[#44660]: https://github.com/rust-lang/rust/issues/44660
+
+------------------------
+
+The `crate_in_paths` feature allows to explicitly refer to the crate root in absolute paths
+using keyword `crate`.
+
+`crate` can be used *only* in absolute paths, i.e. either in `::crate::a::b::c` form or in `use`
+items where the starting `::` is added implicitly.
+Paths like `crate::a::b::c` are not accepted currently.
+
+This feature is required in `feature(extern_absolute_paths)` mode to refer to any absolute path
+in the local crate (absolute paths refer to extern crates by default in that mode), but can be
+used without `feature(extern_absolute_paths)` as well.
+
+```rust
+#![feature(crate_in_paths)]
+
+// Imports, `::` is added implicitly
+use crate::m::f;
+use crate as root;
+
+mod m {
+ pub fn f() -> u8 { 1 }
+ pub fn g() -> u8 { 2 }
+ pub fn h() -> u8 { 3 }
+
+ // OK, visibilities implicitly add starting `::` as well, like imports
+ pub(in crate::m) struct S;
+}
+
+mod n
+{
+ use crate::m::f;
+ use crate as root;
+ pub fn check() {
+ assert_eq!(f(), 1);
+ // `::` is required in non-import paths
+ assert_eq!(::crate::m::g(), 2);
+ assert_eq!(root::m::h(), 3);
+ }
+}
+
+fn main() {
+ assert_eq!(f(), 1);
+ assert_eq!(::crate::m::g(), 2);
+ assert_eq!(root::m::h(), 3);
+ n::check();
+}
+```
--- /dev/null
+# `extern_absolute_paths`
+
+The tracking issue for this feature is: [#44660]
+
+[#44660]: https://github.com/rust-lang/rust/issues/44660
+
+------------------------
+
+The `extern_absolute_paths` feature enables mode allowing to refer to names from other crates
+"inline", without introducing `extern crate` items, using absolute paths like `::my_crate::a::b`.
+
+`::my_crate::a::b` will resolve to path `a::b` in crate `my_crate`.
+
+`feature(crate_in_paths)` can be used in `feature(extern_absolute_paths)` mode for referring
+to absolute paths in the local crate (`::crate::a::b`).
+
+`feature(extern_in_paths)` provides the same effect by using keyword `extern` to refer to
+paths from other crates (`extern::my_crate::a::b`).
+
+```rust,ignore
+#![feature(extern_absolute_paths)]
+
+// Suppose we have a dependency crate `xcrate` available through `Cargo.toml`, or `--extern`
+// options, or standard Rust distribution, or some other means.
+
+use xcrate::Z;
+
+fn f() {
+ use xcrate;
+ use xcrate as ycrate;
+ let s = xcrate::S;
+ assert_eq!(format!("{:?}", s), "S");
+ let z = ycrate::Z;
+ assert_eq!(format!("{:?}", z), "Z");
+}
+
+fn main() {
+ let s = ::xcrate::S;
+ assert_eq!(format!("{:?}", s), "S");
+ let z = Z;
+ assert_eq!(format!("{:?}", z), "Z");
+}
+```
--- /dev/null
+# `extern_in_paths`
+
+The tracking issue for this feature is: [#44660]
+
+[#44660]: https://github.com/rust-lang/rust/issues/44660
+
+------------------------
+
+The `extern_in_paths` feature allows to refer to names from other crates "inline", without
+introducing `extern crate` items, using keyword `extern`.
+
+For example, `extern::my_crat::a::b` will resolve to path `a::b` in crate `my_crate`.
+
+`feature(extern_absolute_paths)` mode provides the same effect by resolving absolute paths like
+`::my_crate::a::b` to paths from extern crates by default.
+
+```rust,ignore
+#![feature(extern_in_paths)]
+
+// Suppose we have a dependency crate `xcrate` available through `Cargo.toml`, or `--extern`
+// options, or standard Rust distribution, or some other means.
+
+use extern::xcrate::Z;
+
+fn f() {
+ use extern::xcrate;
+ use extern::xcrate as ycrate;
+ let s = xcrate::S;
+ assert_eq!(format!("{:?}", s), "S");
+ let z = ycrate::Z;
+ assert_eq!(format!("{:?}", z), "Z");
+}
+
+fn main() {
+ let s = extern::xcrate::S;
+ assert_eq!(format!("{:?}", s), "S");
+ let z = Z;
+ assert_eq!(format!("{:?}", z), "Z");
+}
+```
fn $name(b: &mut Bencher) {
let size = mem::size_of_val(&$gen(1)[0]);
let mut v = $gen($len * 8 / size);
- b.iter(|| black_box(&mut v).rotate(($mid*8+size-1)/size));
+ b.iter(|| black_box(&mut v).rotate_left(($mid*8+size-1)/size));
b.bytes = (v.len() * size) as u64;
}
}
core_slice::SliceExt::sort_unstable_by_key(self, f);
}
- /// Permutes the slice in-place such that `self[mid..]` moves to the
- /// beginning of the slice while `self[..mid]` moves to the end of the
- /// slice. Equivalently, rotates the slice `mid` places to the left
- /// or `k = self.len() - mid` places to the right.
+ /// Rotates the slice in-place such that the first `mid` elements of the
+ /// slice move to the end while the last `self.len() - mid` elements move to
+ /// the front. After calling `rotate_left`, the element previously at index
+ /// `mid` will become the first element in the slice.
///
- /// This is a "k-rotation", a permutation in which item `i` moves to
- /// position `i + k`, modulo the length of the slice. See _Elements
- /// of Programming_ [§10.4][eop].
+ /// # Panics
+ ///
+ /// This function will panic if `mid` is greater than the length of the
+ /// slice. Note that `mid == self.len()` does _not_ panic and is a no-op
+ /// rotation.
+ ///
+ /// # Complexity
+ ///
+ /// Takes linear (in `self.len()`) time.
+ ///
+ /// # Examples
///
- /// Rotation by `mid` and rotation by `k` are inverse operations.
+ /// ```
+ /// #![feature(slice_rotate)]
///
- /// [eop]: https://books.google.com/books?id=CO9ULZGINlsC&pg=PA178&q=k-rotation
+ /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+ /// a.rotate_left(2);
+ /// assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+ /// ```
+ ///
+ /// Rotating a subslice:
+ ///
+ /// ```
+ /// #![feature(slice_rotate)]
+ ///
+ /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+ /// a[1..5].rotate_left(1);
+ /// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+ /// ```
+ #[unstable(feature = "slice_rotate", issue = "41891")]
+ pub fn rotate_left(&mut self, mid: usize) {
+ core_slice::SliceExt::rotate_left(self, mid);
+ }
+
+ #[unstable(feature = "slice_rotate", issue = "41891")]
+ #[rustc_deprecated(since = "", reason = "renamed to `rotate_left`")]
+ pub fn rotate(&mut self, mid: usize) {
+ core_slice::SliceExt::rotate_left(self, mid);
+ }
+
+ /// Rotates the slice in-place such that the first `self.len() - k`
+ /// elements of the slice move to the end while the last `k` elements move
+ /// to the front. After calling `rotate_right`, the element previously at
+ /// index `self.len() - k` will become the first element in the slice.
///
/// # Panics
///
- /// This function will panic if `mid` is greater than the length of the
- /// slice. (Note that `mid == self.len()` does _not_ panic; it's a nop
- /// rotation with `k == 0`, the inverse of a rotation with `mid == 0`.)
+ /// This function will panic if `k` is greater than the length of the
+ /// slice. Note that `k == self.len()` does _not_ panic and is a no-op
+ /// rotation.
///
/// # Complexity
///
/// ```
/// #![feature(slice_rotate)]
///
- /// let mut a = [1, 2, 3, 4, 5, 6, 7];
- /// let mid = 2;
- /// a.rotate(mid);
- /// assert_eq!(&a, &[3, 4, 5, 6, 7, 1, 2]);
- /// let k = a.len() - mid;
- /// a.rotate(k);
- /// assert_eq!(&a, &[1, 2, 3, 4, 5, 6, 7]);
- ///
- /// use std::ops::Range;
- /// fn slide<T>(slice: &mut [T], range: Range<usize>, to: usize) {
- /// if to < range.start {
- /// slice[to..range.end].rotate(range.start-to);
- /// } else if to > range.end {
- /// slice[range.start..to].rotate(range.end-range.start);
- /// }
- /// }
- /// let mut v: Vec<_> = (0..10).collect();
- /// slide(&mut v, 1..4, 7);
- /// assert_eq!(&v, &[0, 4, 5, 6, 1, 2, 3, 7, 8, 9]);
- /// slide(&mut v, 6..8, 1);
- /// assert_eq!(&v, &[0, 3, 7, 4, 5, 6, 1, 2, 8, 9]);
+ /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+ /// a.rotate_right(2);
+ /// assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+ /// ```
+ ///
+ /// Rotate a subslice:
+ ///
+ /// ```
+ /// #![feature(slice_rotate)]
+ ///
+ /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+ /// a[1..5].rotate_right(1);
+ /// assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
/// ```
#[unstable(feature = "slice_rotate", issue = "41891")]
- pub fn rotate(&mut self, mid: usize) {
- core_slice::SliceExt::rotate(self, mid);
+ pub fn rotate_right(&mut self, k: usize) {
+ core_slice::SliceExt::rotate_right(self, k);
}
/// Copies the elements from `src` into `self`.
/// let x = s.to_vec();
/// // Here, `s` and `x` can be modified independently.
/// ```
+ #[rustc_conversion_suggestion]
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn to_vec(&self) -> Vec<T>
///
/// assert_eq!(five, i.to_string());
/// ```
+ #[rustc_conversion_suggestion]
#[stable(feature = "rust1", since = "1.0.0")]
fn to_string(&self) -> String;
}
}
#[test]
-fn test_rotate() {
+fn test_rotate_left() {
let expected: Vec<_> = (0..13).collect();
let mut v = Vec::new();
// no-ops
v.clone_from(&expected);
- v.rotate(0);
+ v.rotate_left(0);
assert_eq!(v, expected);
- v.rotate(expected.len());
+ v.rotate_left(expected.len());
assert_eq!(v, expected);
let mut zst_array = [(), (), ()];
- zst_array.rotate(2);
+ zst_array.rotate_left(2);
// happy path
v = (5..13).chain(0..5).collect();
- v.rotate(8);
+ v.rotate_left(8);
assert_eq!(v, expected);
let expected: Vec<_> = (0..1000).collect();
// small rotations in large slice, uses ptr::copy
v = (2..1000).chain(0..2).collect();
- v.rotate(998);
+ v.rotate_left(998);
assert_eq!(v, expected);
v = (998..1000).chain(0..998).collect();
- v.rotate(2);
+ v.rotate_left(2);
assert_eq!(v, expected);
// non-small prime rotation, has a few rounds of swapping
v = (389..1000).chain(0..389).collect();
- v.rotate(1000-389);
+ v.rotate_left(1000-389);
+ assert_eq!(v, expected);
+}
+
+#[test]
+fn test_rotate_right() {
+ let expected: Vec<_> = (0..13).collect();
+ let mut v = Vec::new();
+
+ // no-ops
+ v.clone_from(&expected);
+ v.rotate_right(0);
+ assert_eq!(v, expected);
+ v.rotate_right(expected.len());
+ assert_eq!(v, expected);
+ let mut zst_array = [(), (), ()];
+ zst_array.rotate_right(2);
+
+ // happy path
+ v = (5..13).chain(0..5).collect();
+ v.rotate_right(5);
+ assert_eq!(v, expected);
+
+ let expected: Vec<_> = (0..1000).collect();
+
+ // small rotations in large slice, uses ptr::copy
+ v = (2..1000).chain(0..2).collect();
+ v.rotate_right(2);
+ assert_eq!(v, expected);
+ v = (998..1000).chain(0..998).collect();
+ v.rotate_right(998);
+ assert_eq!(v, expected);
+
+ // non-small prime rotation, has a few rounds of swapping
+ v = (389..1000).chain(0..389).collect();
+ v.rotate_right(389);
assert_eq!(v, expected);
}
impl<T> TypedArenaChunk<T> {
#[inline]
unsafe fn new(capacity: usize) -> TypedArenaChunk<T> {
- TypedArenaChunk { storage: RawVec::with_capacity(capacity) }
+ TypedArenaChunk {
+ storage: RawVec::with_capacity(capacity),
+ }
}
/// Destroys this arena chunk.
unsafe {
if mem::size_of::<T>() == 0 {
- self.ptr.set(intrinsics::arith_offset(self.ptr.get() as *mut u8, 1) as *mut T);
+ self.ptr
+ .set(intrinsics::arith_offset(self.ptr.get() as *mut u8, 1)
+ as *mut T);
let ptr = mem::align_of::<T>() as *mut T;
// Don't drop the object. This `write` is equivalent to `forget`.
ptr::write(ptr, object);
/// - Zero-length slices
#[inline]
pub fn alloc_slice(&self, slice: &[T]) -> &mut [T]
- where T: Copy {
+ where
+ T: Copy,
+ {
assert!(mem::size_of::<T>() != 0);
assert!(slice.len() != 0);
let (chunk, mut new_capacity);
if let Some(last_chunk) = chunks.last_mut() {
let used_bytes = self.ptr.get() as usize - last_chunk.start() as usize;
- if last_chunk.storage.reserve_in_place(used_bytes, needed_bytes) {
+ if last_chunk
+ .storage
+ .reserve_in_place(used_bytes, needed_bytes)
+ {
self.end.set(last_chunk.end());
return;
} else {
let ptr = self.ptr.get();
// Set the pointer past ourselves
- self.ptr.set(intrinsics::arith_offset(
- self.ptr.get(), mem::size_of::<T>() as isize
- ) as *mut u8);
+ self.ptr.set(
+ intrinsics::arith_offset(self.ptr.get(), mem::size_of::<T>() as isize) as *mut u8,
+ );
// Write into uninitialized memory.
ptr::write(ptr as *mut T, object);
&mut *(ptr as *mut T)
/// - Zero-length slices
#[inline]
pub fn alloc_slice<T>(&self, slice: &[T]) -> &mut [T]
- where T: Copy {
+ where
+ T: Copy,
+ {
assert!(!mem::needs_drop::<T>());
assert!(mem::size_of::<T>() != 0);
assert!(slice.len() != 0);
unsafe {
let arena_slice = slice::from_raw_parts_mut(self.ptr.get() as *mut T, slice.len());
self.ptr.set(intrinsics::arith_offset(
- self.ptr.get(), (slice.len() * mem::size_of::<T>()) as isize
+ self.ptr.get(),
+ (slice.len() * mem::size_of::<T>()) as isize,
) as *mut u8);
arena_slice.copy_from_slice(slice);
arena_slice
let arena = Wrap(TypedArena::new());
- let result =
- arena.alloc_outer(|| Outer { inner: arena.alloc_inner(|| Inner { value: 10 }) });
+ let result = arena.alloc_outer(|| Outer {
+ inner: arena.alloc_inner(|| Inner { value: 10 }),
+ });
assert_eq!(result.inner.value, 10);
}
/// some other means.
///
/// An important thing to remember is that the type `fmt::Error` should not be
-/// confused with `std::io::Error` or `std::error::Error`, which you may also
+/// confused with [`std::io::Error`] or [`std::error::Error`], which you may also
/// have in scope.
///
+/// [`std::io::Error`]: ../../std/io/struct.Error.html
+/// [`std::error::Error`]: ../../std/error/trait.Error.html
+///
/// # Examples
///
/// ```rust
self.start = self.end.clone();
None
}
+
+ #[inline]
+ fn last(mut self) -> Option<A> {
+ self.next_back()
+ }
+
+ #[inline]
+ fn min(mut self) -> Option<A> {
+ self.next()
+ }
+
+ #[inline]
+ fn max(mut self) -> Option<A> {
+ self.next_back()
+ }
}
// These macros generate `ExactSizeIterator` impls for various range types.
self.end.replace_zero();
None
}
+
+ #[inline]
+ fn last(mut self) -> Option<A> {
+ self.next_back()
+ }
+
+ #[inline]
+ fn min(mut self) -> Option<A> {
+ self.next()
+ }
+
+ #[inline]
+ fn max(mut self) -> Option<A> {
+ self.next_back()
+ }
}
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
#[unstable(feature = "slice_rotate", issue = "41891")]
- fn rotate(&mut self, mid: usize);
+ fn rotate_left(&mut self, mid: usize);
+
+ #[unstable(feature = "slice_rotate", issue = "41891")]
+ fn rotate_right(&mut self, k: usize);
#[stable(feature = "clone_from_slice", since = "1.7.0")]
fn clone_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Clone;
self.binary_search_by(|p| p.cmp(x))
}
- fn rotate(&mut self, mid: usize) {
+ fn rotate_left(&mut self, mid: usize) {
assert!(mid <= self.len());
let k = self.len() - mid;
}
}
+ fn rotate_right(&mut self, k: usize) {
+ assert!(k <= self.len());
+ let mid = self.len() - k;
+
+ unsafe {
+ let p = self.as_mut_ptr();
+ rotate::ptr_rotate(mid, p.offset(mid as isize), k);
+ }
+ }
+
#[inline]
fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
assert!(self.len() == src.len(),
#[inline]
fn next(&mut self) -> SearchStep {
let old_finger = self.finger;
- let slice = unsafe { self.haystack.get_unchecked(old_finger..self.haystack.len()) };
+ let slice = unsafe { self.haystack.get_unchecked(old_finger..self.finger_back) };
let mut iter = slice.chars();
let old_len = iter.iter.len();
if let Some(ch) = iter.next() {
fn next_match(&mut self) -> Option<(usize, usize)> {
loop {
// get the haystack after the last character found
- let bytes = if let Some(slice) = self.haystack.as_bytes().get(self.finger..) {
+ let bytes = if let Some(slice) = self.haystack.as_bytes()
+ .get(self.finger..self.finger_back) {
slice
} else {
return None;
}
} else {
// found nothing, exit
- self.finger = self.haystack.len();
+ self.finger = self.finger_back;
return None;
}
}
#[inline]
fn next_back(&mut self) -> SearchStep {
let old_finger = self.finger_back;
- let slice = unsafe { self.haystack.slice_unchecked(0, old_finger) };
+ let slice = unsafe { self.haystack.slice_unchecked(self.finger, old_finger) };
let mut iter = slice.chars();
let old_len = iter.iter.len();
if let Some(ch) = iter.next_back() {
let haystack = self.haystack.as_bytes();
loop {
// get the haystack up to but not including the last character searched
- let bytes = if let Some(slice) = haystack.get(..self.finger_back) {
+ let bytes = if let Some(slice) = haystack.get(self.finger..self.finger_back) {
slice
} else {
return None;
// the last byte of the utf8 encoded needle
let last_byte = unsafe { *self.utf8_encoded.get_unchecked(self.utf8_size - 1) };
if let Some(index) = memchr::memrchr(last_byte, bytes) {
+ // we searched a slice that was offset by self.finger,
+ // add self.finger to recoup the original index
+ let index = self.finger + index;
// memrchr will return the index of the byte we wish to
// find. In case of an ASCII character, this is indeed
// were we wish our new finger to be ("after" the found
// found the last byte when searching in reverse.
self.finger_back = index;
} else {
- self.finger_back = 0;
+ self.finger_back = self.finger;
// found nothing, exit
return None;
}
assert_eq!((isize::MIN..isize::MAX).step_by(1).size_hint(), (usize::MAX, Some(usize::MAX)));
}
+#[test]
+fn test_range_last_max() {
+ assert_eq!((0..20).last(), Some(19));
+ assert_eq!((-20..0).last(), Some(-1));
+ assert_eq!((5..5).last(), None);
+
+ assert_eq!((0..20).max(), Some(19));
+ assert_eq!((-20..0).max(), Some(-1));
+ assert_eq!((5..5).max(), None);
+}
+
+#[test]
+fn test_range_inclusive_last_max() {
+ assert_eq!((0..=20).last(), Some(20));
+ assert_eq!((-20..=0).last(), Some(0));
+ assert_eq!((5..=5).last(), Some(5));
+ let mut r = 10..=10;
+ r.next();
+ assert_eq!(r.last(), None);
+
+ assert_eq!((0..=20).max(), Some(20));
+ assert_eq!((-20..=0).max(), Some(0));
+ assert_eq!((5..=5).max(), Some(5));
+ let mut r = 10..=10;
+ r.next();
+ assert_eq!(r.max(), None);
+}
+
+#[test]
+fn test_range_min() {
+ assert_eq!((0..20).min(), Some(0));
+ assert_eq!((-20..0).min(), Some(-20));
+ assert_eq!((5..5).min(), None);
+}
+
+#[test]
+fn test_range_inclusive_min() {
+ assert_eq!((0..=20).min(), Some(0));
+ assert_eq!((-20..=0).min(), Some(-20));
+ assert_eq!((5..=5).min(), Some(5));
+ let mut r = 10..=10;
+ r.next();
+ assert_eq!(r.min(), None);
+}
+
#[test]
fn test_repeat() {
let mut it = repeat(42);
test_impl_from! { test_u32f64, u32, f64 }
// Float -> Float
-#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
#[test]
fn test_f32f64() {
use core::f32;
[InRange(37, 40), Rejects(34, 37), InRange(10, 13), Rejects(8, 10), Done]
);
}
+
+#[test]
+fn double_ended_regression_test() {
+ // https://github.com/rust-lang/rust/issues/47175
+ // Ensures that double ended searching comes to a convergence
+ search_asserts!("abcdeabcdeabcde", 'a', "alternating double ended search",
+ [next_match, next_match_back, next_match, next_match_back],
+ [InRange(0, 1), InRange(10, 11), InRange(5, 6), Done]
+ );
+ search_asserts!("abcdeabcdeabcde", 'a', "triple double ended search for a",
+ [next_match, next_match_back, next_match_back, next_match_back],
+ [InRange(0, 1), InRange(10, 11), InRange(5, 6), Done]
+ );
+ search_asserts!("abcdeabcdeabcde", 'd', "triple double ended search for d",
+ [next_match, next_match_back, next_match_back, next_match_back],
+ [InRange(3, 4), InRange(13, 14), InRange(8, 9), Done]
+ );
+ search_asserts!(STRESS, 'Á', "Double ended search for two-byte Latin character",
+ [next_match, next_match_back, next_match, next_match_back],
+ [InRange(0, 2), InRange(32, 34), InRange(8, 10), Done]
+ );
+ search_asserts!(STRESS, '각', "Reverse double ended search for three-byte Hangul character",
+ [next_match_back, next_back, next_match, next, next_match_back, next_match],
+ [InRange(34, 37), Rejects(32, 34), InRange(19, 22), Rejects(22, 25), InRange(28, 31), Done]
+ );
+ search_asserts!(STRESS, 'ก', "Double ended search for three-byte Thai character",
+ [next_match, next_back, next, next_match_back, next_match],
+ [InRange(22, 25), Rejects(47, 48), Rejects(25, 28), InRange(40, 43), Done]
+ );
+ search_asserts!(STRESS, '😁', "Double ended search for four-byte emoji",
+ [next_match_back, next, next_match, next_back, next_match],
+ [InRange(43, 47), Rejects(0, 2), InRange(15, 19), Rejects(40, 43), Done]
+ );
+ search_asserts!(STRESS, 'ꁁ', "Double ended search for three-byte Yi character with repeated bytes",
+ [next_match, next, next_match_back, next_back, next_match],
+ [InRange(10, 13), Rejects(13, 14), InRange(37, 40), Rejects(34, 37), Done]
+ );
+}
}
#[test]
-fn test_rotate() {
+fn test_rotate_left() {
const N: usize = 600;
let a: &mut [_] = &mut [0; N];
for i in 0..N {
a[i] = i;
}
- a.rotate(42);
+ a.rotate_left(42);
let k = N - 42;
for i in 0..N {
- assert_eq!(a[(i+k)%N], i);
+ assert_eq!(a[(i + k) % N], i);
+ }
+}
+
+#[test]
+fn test_rotate_right() {
+ const N: usize = 600;
+ let a: &mut [_] = &mut [0; N];
+ for i in 0..N {
+ a[i] = i;
+ }
+
+ a.rotate_right(42);
+
+ for i in 0..N {
+ assert_eq!(a[(i + 42) % N], i);
}
}
-Subproject commit ef9eefb6df3f3a2cb989e8050519661faa7d7118
+Subproject commit 2b4cd1016bdba92becb4f982a4dcb18fe6653bc4
// notify the expansion info that it is unhygienic
let mark = Mark::fresh(mark);
mark.set_expn_info(expn_info);
- let span = call_site.with_ctxt(call_site.ctxt().apply_mark(mark));
+ let span = call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark));
let stream = parse::parse_stream_from_source_str(name, src, sess, Some(span));
Ok(__internal::token_stream_wrap(stream))
})
fmt_macros = { path = "../libfmt_macros" }
graphviz = { path = "../libgraphviz" }
jobserver = "0.1"
-log = "0.3"
+log = "0.4"
rustc_apfloat = { path = "../librustc_apfloat" }
rustc_back = { path = "../librustc_back" }
rustc_const_math = { path = "../librustc_const_math" }
[anon] NormalizeTy,
// We use this for most things when incr. comp. is turned off.
[] Null,
+
+ [] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) },
);
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
DepGraphQuery::new(&nodes[..], &edges[..])
}
- pub fn in_ignore<'graph>(&'graph self) -> Option<raii::IgnoreTask<'graph>> {
- self.data.as_ref().map(|data| raii::IgnoreTask::new(&data.current))
+ pub fn assert_ignored(&self)
+ {
+ if let Some(ref data) = self.data {
+ match data.current.borrow().task_stack.last() {
+ Some(&OpenTask::Ignore) | None => {
+ // ignored
+ }
+ _ => panic!("expected an ignore context")
+ }
+ }
}
pub fn with_ignore<OP,R>(&self, op: OP) -> R
where OP: FnOnce() -> R
{
- let _task = self.in_ignore();
+ let _task = self.data.as_ref().map(|data| raii::IgnoreTask::new(&data.current));
op()
}
/// particular definition. It should really be considered an interned
/// shorthand for a particular DefPath.
///
-/// At the moment we are allocating the numerical values of DefIndexes into two
-/// ranges: the "low" range (starting at zero) and the "high" range (starting at
-/// DEF_INDEX_HI_START). This allows us to allocate the DefIndexes of all
-/// item-likes (Items, TraitItems, and ImplItems) into one of these ranges and
+/// At the moment we are allocating the numerical values of DefIndexes from two
+/// address spaces: DefIndexAddressSpace::Low and DefIndexAddressSpace::High.
+/// This allows us to allocate the DefIndexes of all item-likes
+/// (Items, TraitItems, and ImplItems) into one of these spaces and
/// consequently use a simple array for lookup tables keyed by DefIndex and
/// known to be densely populated. This is especially important for the HIR map.
///
/// Since the DefIndex is mostly treated as an opaque ID, you probably
-/// don't have to care about these ranges.
-newtype_index!(DefIndex
- {
- ENCODABLE = custom
- DEBUG_FORMAT = custom,
+/// don't have to care about these address spaces.
- /// The start of the "high" range of DefIndexes.
- const DEF_INDEX_HI_START = 1 << 31,
+#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, Hash, Copy)]
+pub struct DefIndex(u32);
+
+/// The crate root is always assigned index 0 by the AST Map code,
+/// thanks to `NodeCollector::new`.
+pub const CRATE_DEF_INDEX: DefIndex = DefIndex(0);
- /// The crate root is always assigned index 0 by the AST Map code,
- /// thanks to `NodeCollector::new`.
- const CRATE_DEF_INDEX = 0,
- });
impl fmt::Debug for DefIndex {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
impl DefIndex {
#[inline]
- pub fn from_u32(x: u32) -> DefIndex {
- DefIndex(x)
+ pub fn address_space(&self) -> DefIndexAddressSpace {
+ match self.0 & 1 {
+ 0 => DefIndexAddressSpace::Low,
+ 1 => DefIndexAddressSpace::High,
+ _ => unreachable!()
+ }
}
+ /// Converts this DefIndex into a zero-based array index.
+ /// This index is the offset within the given DefIndexAddressSpace.
#[inline]
- pub fn as_usize(&self) -> usize {
- self.0 as usize
+ pub fn as_array_index(&self) -> usize {
+ (self.0 >> 1) as usize
}
#[inline]
- pub fn as_u32(&self) -> u32 {
- self.0
+ pub fn from_array_index(i: usize, address_space: DefIndexAddressSpace) -> DefIndex {
+ DefIndex::from_raw_u32(((i << 1) | (address_space as usize)) as u32)
}
- #[inline]
- pub fn address_space(&self) -> DefIndexAddressSpace {
- if self.0 < DEF_INDEX_HI_START.0 {
- DefIndexAddressSpace::Low
- } else {
- DefIndexAddressSpace::High
- }
+ // Proc macros from a proc-macro crate have a kind of virtual DefIndex. This
+ // function maps the index of the macro within the crate (which is also the
+ // index of the macro in the CrateMetadata::proc_macros array) to the
+ // corresponding DefIndex.
+ pub fn from_proc_macro_index(proc_macro_index: usize) -> DefIndex {
+ let def_index = DefIndex::from_array_index(proc_macro_index,
+ DefIndexAddressSpace::High);
+ assert!(def_index != CRATE_DEF_INDEX);
+ def_index
}
- /// Converts this DefIndex into a zero-based array index.
- /// This index is the offset within the given "range" of the DefIndex,
- /// that is, if the DefIndex is part of the "high" range, the resulting
- /// index will be (DefIndex - DEF_INDEX_HI_START).
- #[inline]
- pub fn as_array_index(&self) -> usize {
- (self.0 & !DEF_INDEX_HI_START.0) as usize
+ // This function is the reverse of from_proc_macro_index() above.
+ pub fn to_proc_macro_index(self: DefIndex) -> usize {
+ self.as_array_index()
}
- pub fn from_array_index(i: usize, address_space: DefIndexAddressSpace) -> DefIndex {
- DefIndex::new(address_space.start() + i)
+ // Don't use this if you don't know about the DefIndex encoding.
+ pub fn from_raw_u32(x: u32) -> DefIndex {
+ DefIndex(x)
+ }
+
+ // Don't use this if you don't know about the DefIndex encoding.
+ pub fn as_raw_u32(&self) -> u32 {
+ self.0
}
}
pub fn index(&self) -> usize {
*self as usize
}
-
- #[inline]
- pub fn start(&self) -> usize {
- self.index() * DEF_INDEX_HI_START.as_usize()
- }
}
/// A DefId identifies a particular *definition*, by combining a crate
// We're constructing the HIR here; we don't care what we will
// read, since we haven't even constructed the *input* to
// incr. comp. yet.
- let _ignore = dep_graph.in_ignore();
+ dep_graph.assert_ignored();
LoweringContext {
crate_root: std_inject::injected_crate_name(),
CRATE_DEF_INDEX};
use ich::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::indexed_vec::{IndexVec, Idx};
+use rustc_data_structures::indexed_vec::{IndexVec};
use rustc_data_structures::stable_hasher::StableHasher;
use serialize::{Encodable, Decodable, Encoder, Decoder};
use session::CrateDisambiguator;
-> DefIndex {
let index = {
let index_to_key = &mut self.index_to_key[address_space.index()];
- let index = DefIndex::new(index_to_key.len() + address_space.start());
+ let index = DefIndex::from_array_index(index_to_key.len(), address_space);
debug!("DefPathTable::insert() - {:?} <-> {:?}", key, index);
index_to_key.push(key);
index
pub fn add_def_path_hashes_to(&self,
cnum: CrateNum,
out: &mut FxHashMap<DefPathHash, DefId>) {
- for address_space in &[DefIndexAddressSpace::Low, DefIndexAddressSpace::High] {
- let start_index = address_space.start();
+ for &address_space in &[DefIndexAddressSpace::Low, DefIndexAddressSpace::High] {
out.extend(
(&self.def_path_hashes[address_space.index()])
.iter()
.map(|(index, &hash)| {
let def_id = DefId {
krate: cnum,
- index: DefIndex::new(index + start_index),
+ index: DefIndex::from_array_index(index, address_space),
};
(hash, def_id)
})
errors: vec![],
};
- hir_map.dep_graph.with_ignore(|| {
- hir_map.krate().visit_all_item_likes(&mut outer_visitor);
- if !outer_visitor.errors.is_empty() {
- let message = outer_visitor
- .errors
- .iter()
- .fold(String::new(), |s1, s2| s1 + "\n" + s2);
- bug!("{}", message);
- }
- });
+ hir_map.dep_graph.assert_ignored();
+
+ hir_map.krate().visit_all_item_likes(&mut outer_visitor);
+ if !outer_visitor.errors.is_empty() {
+ let message = outer_visitor
+ .errors
+ .iter()
+ .fold(String::new(), |s1, s2| s1 + "\n" + s2);
+ bug!("{}", message);
+ }
}
struct HirIdValidator<'a, 'hir: 'a> {
cmdline_args)
};
- if log_enabled!(::log::LogLevel::Debug) {
+ if log_enabled!(::log::Level::Debug) {
// This only makes sense for ordered stores; note the
// enumerate to count the number of entries.
let (entries_less_1, _) = map.iter().filter(|&x| {
}
/// A "Path" is essentially Rust's notion of a name; for instance:
-/// std::cmp::PartialEq . It's represented as a sequence of identifiers,
+/// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
/// along with a bunch of supporting information.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub struct Path {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+use std::mem;
use rustc_data_structures::stable_hasher;
+use serialize;
+use serialize::opaque::{EncodeResult, Encoder, Decoder};
-#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy, RustcEncodable, RustcDecodable)]
+#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)]
pub struct Fingerprint(u64, u64);
impl Fingerprint {
format!("{:x}{:x}", self.0, self.1)
}
+ pub fn encode_opaque(&self, encoder: &mut Encoder) -> EncodeResult {
+ let bytes: [u8; 16] = unsafe { mem::transmute([self.0.to_le(), self.1.to_le()]) };
+
+ encoder.emit_raw_bytes(&bytes)
+ }
+
+ pub fn decode_opaque<'a>(decoder: &mut Decoder<'a>) -> Result<Fingerprint, String> {
+ let mut bytes = [0; 16];
+
+ decoder.read_raw_bytes(&mut bytes)?;
+
+ let [l, r]: [u64; 2] = unsafe { mem::transmute(bytes) };
+
+ Ok(Fingerprint(u64::from_le(l), u64::from_le(r)))
+ }
}
impl ::std::fmt::Display for Fingerprint {
::std::hash::Hash::hash(self, hasher);
}
}
+
+impl serialize::UseSpecializedEncodable for Fingerprint { }
+
+impl serialize::UseSpecializedDecodable for Fingerprint { }
+
+impl<'a> serialize::SpecializedEncoder<Fingerprint> for serialize::opaque::Encoder<'a> {
+ fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
+ f.encode_opaque(self)
+ }
+}
+
+impl<'a> serialize::SpecializedDecoder<Fingerprint> for serialize::opaque::Decoder<'a> {
+ fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
+ Fingerprint::decode_opaque(self)
+ }
+}
use graphviz as dot;
use hir::def_id::DefIndex;
-use rustc_data_structures::indexed_vec::Idx;
use ty;
use middle::free_region::RegionRelations;
use middle::region;
}
let requested_node = env::var("RUST_REGION_GRAPH_NODE")
- .ok().and_then(|s| s.parse().map(DefIndex::new).ok());
+ .ok().and_then(|s| s.parse().map(DefIndex::from_raw_u32).ok());
if requested_node.is_some() && requested_node != Some(context.index) {
return;
let mut new_str = String::new();
for c in output_template.chars() {
if c == '%' {
- new_str.push_str(&context.index.as_usize().to_string());
+ new_str.push_str(&context.index.as_raw_u32().to_string());
} else {
new_str.push(c);
}
#![feature(drain_filter)]
#![feature(dyn_trait)]
#![feature(from_ref)]
+#![feature(fs_read_write)]
#![feature(i128)]
#![feature(i128_type)]
#![feature(inclusive_range)]
// calculated the lint levels for all AST nodes.
for (_id, lints) in cx.buffered.map {
for early_lint in lints {
- span_bug!(early_lint.span, "failed to process bufferd lint here");
+ span_bug!(early_lint.span, "failed to process buffered lint here");
}
}
}
tcx: TyCtxt<'a, 'tcx, 'tcx>,
tables: &'a ty::TypeckTables<'tcx>,
live_symbols: Box<FxHashSet<ast::NodeId>>,
- struct_has_extern_repr: bool,
+ repr_has_repr_c: bool,
in_pat: bool,
inherited_pub_visibility: bool,
ignore_variant_stack: Vec<DefId>,
fn handle_field_access(&mut self, lhs: &hir::Expr, name: ast::Name) {
match self.tables.expr_ty_adjusted(lhs).sty {
ty::TyAdt(def, _) => {
- self.insert_def_id(def.struct_variant().field_named(name).did);
+ self.insert_def_id(def.non_enum_variant().field_named(name).did);
}
_ => span_bug!(lhs.span, "named field access on non-ADT"),
}
fn handle_tup_field_access(&mut self, lhs: &hir::Expr, idx: usize) {
match self.tables.expr_ty_adjusted(lhs).sty {
ty::TyAdt(def, _) => {
- self.insert_def_id(def.struct_variant().fields[idx].did);
+ self.insert_def_id(def.non_enum_variant().fields[idx].did);
}
ty::TyTuple(..) => {}
_ => span_bug!(lhs.span, "numeric field access on non-ADT"),
}
fn visit_node(&mut self, node: &hir_map::Node<'tcx>) {
- let had_extern_repr = self.struct_has_extern_repr;
- self.struct_has_extern_repr = false;
+ let had_repr_c = self.repr_has_repr_c;
+ self.repr_has_repr_c = false;
let had_inherited_pub_visibility = self.inherited_pub_visibility;
self.inherited_pub_visibility = false;
match *node {
hir::ItemStruct(..) | hir::ItemUnion(..) => {
let def_id = self.tcx.hir.local_def_id(item.id);
let def = self.tcx.adt_def(def_id);
- self.struct_has_extern_repr = def.repr.c();
+ self.repr_has_repr_c = def.repr.c();
intravisit::walk_item(self, &item);
}
}
_ => ()
}
- self.struct_has_extern_repr = had_extern_repr;
+ self.repr_has_repr_c = had_repr_c;
self.inherited_pub_visibility = had_inherited_pub_visibility;
}
fn visit_variant_data(&mut self, def: &'tcx hir::VariantData, _: ast::Name,
_: &hir::Generics, _: ast::NodeId, _: syntax_pos::Span) {
- let has_extern_repr = self.struct_has_extern_repr;
+ let has_repr_c = self.repr_has_repr_c;
let inherited_pub_visibility = self.inherited_pub_visibility;
let live_fields = def.fields().iter().filter(|f| {
- has_extern_repr || inherited_pub_visibility || f.vis == hir::Public
+ has_repr_c || inherited_pub_visibility || f.vis == hir::Public
});
self.live_symbols.extend(live_fields.map(|f| f.id));
tcx,
tables: &ty::TypeckTables::empty(None),
live_symbols: box FxHashSet(),
- struct_has_extern_repr: false,
+ repr_has_repr_c: false,
in_pat: false,
inherited_pub_visibility: false,
ignore_variant_stack: vec![],
match with_cmt.ty.sty {
ty::TyAdt(adt, substs) if adt.is_struct() => {
// Consume those fields of the with expression that are needed.
- for with_field in &adt.struct_variant().fields {
+ for with_field in &adt.non_enum_variant().fields {
if !contains_field_named(with_field, fields) {
let cmt_field = self.mc.cat_field(
&*with_expr,
Def::StructCtor(_, CtorKind::Fn) => {
match self.pat_ty(&pat)?.sty {
ty::TyAdt(adt_def, _) => {
- (cmt, adt_def.struct_variant().fields.len())
+ (cmt, adt_def.non_enum_variant().fields.len())
}
ref ty => {
span_bug!(pat.span, "tuple struct pattern unexpected type {:?}", ty);
use syntax::symbol::InternedString;
use ty::Instance;
use util::nodemap::FxHashMap;
+use rustc_data_structures::base_n;
use rustc_data_structures::stable_hasher::{HashStable, StableHasherResult,
StableHasher};
use ich::{Fingerprint, StableHashingContext, NodeIdHashingMode};
+use std::hash::Hash;
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
pub enum MonoItem<'tcx> {
{
&mut self.items
}
+
+ pub fn mangle_name(human_readable_name: &str) -> String {
+ // We generate a 80 bit hash from the name. This should be enough to
+ // avoid collisions and is still reasonably short for filenames.
+ let mut hasher = StableHasher::new();
+ human_readable_name.hash(&mut hasher);
+ let hash: u128 = hasher.finish();
+ let hash = hash & ((1u128 << 80) - 1);
+ base_n::encode(hash, base_n::CASE_INSENSITIVE)
+ }
}
impl<'tcx> HashStable<StableHashingContext<'tcx>> for CodegenUnit<'tcx> {
"omit landing pads for unwinding"),
fewer_names: bool = (false, parse_bool, [TRACKED],
"reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR)"),
- debug_llvm: bool = (false, parse_bool, [UNTRACKED],
- "enable debug output from LLVM"),
meta_stats: bool = (false, parse_bool, [UNTRACKED],
"gather metadata statistics"),
print_link_args: bool = (false, parse_bool, [UNTRACKED],
"rewrite operators on i128 and u128 into lang item calls (typically provided \
by compiler-builtins) so translation doesn't need to support them,
overriding the default for the current target"),
+ human_readable_cgu_names: bool = (false, parse_bool, [TRACKED],
+ "generate human-readable, predictable names for codegen units"),
}
pub fn default_lib_output() -> CrateType {
assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
opts.debugging_opts.borrowck_stats = true;
assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
- opts.debugging_opts.debug_llvm = true;
- assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
opts.debugging_opts.meta_stats = true;
assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
opts.debugging_opts.print_link_args = true;
index: DefIndex)
-> String {
format!("__rustc_plugin_registrar__{}_{}", disambiguator.to_fingerprint().to_hex(),
- index.as_usize())
+ index.to_proc_macro_index())
}
pub fn generate_derive_registrar_symbol(&self, disambiguator: CrateDisambiguator,
index: DefIndex)
-> String {
format!("__rustc_derive_registrar__{}_{}", disambiguator.to_fingerprint().to_hex(),
- index.as_usize())
+ index.to_proc_macro_index())
}
pub fn sysroot<'a>(&'a self) -> &'a Path {
/// environment. If this returns false, then either normalize
/// encountered an error or one of the predicates did not hold. Used
/// when creating vtables to check for unsatisfiable methods.
-pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
- predicates: Vec<ty::Predicate<'tcx>>)
- -> bool
+fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ predicates: Vec<ty::Predicate<'tcx>>)
+ -> bool
{
debug!("normalize_and_test_predicates(predicates={:?})",
predicates);
result
}
+fn substitute_normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ key: (DefId, &'tcx Substs<'tcx>))
+ -> bool
+{
+ use ty::subst::Subst;
+ debug!("substitute_normalize_and_test_predicates(key={:?})",
+ key);
+
+ let predicates = tcx.predicates_of(key.0).predicates.subst(tcx, key.1);
+ let result = normalize_and_test_predicates(tcx, predicates);
+
+ debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}",
+ key, result);
+ result
+}
+
/// Given a trait `trait_ref`, iterates the vtable entries
/// that come from `trait_ref`, including its supertraits.
#[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
specializes: specialize::specializes,
trans_fulfill_obligation: trans::trans_fulfill_obligation,
vtable_methods,
+ substitute_normalize_and_test_predicates,
..*providers
};
}
}, niche_start))
};
+ // Locals variables which live across yields are stored
+ // in the generator type as fields. These may be uninitialized
+ // so we don't look for niches there.
+ if let ty::TyGenerator(..) = self.ty.sty {
+ return Ok(None);
+ }
+
match self.abi {
Abi::Scalar(ref scalar) => {
return Ok(scalar_component(scalar, Size::from_bytes(0)));
}
}
+impl<'tcx> QueryDescription<'tcx> for queries::substitute_normalize_and_test_predicates<'tcx> {
+ fn describe(tcx: TyCtxt, key: (DefId, &'tcx Substs<'tcx>)) -> String {
+ format!("testing substituted normalized predicates:`{}`", tcx.item_path_str(key.0))
+ }
+}
+
macro_rules! impl_disk_cacheable_query(
($query_name:ident, |$key:tt| $cond:expr) => {
impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> {
// however, which uses this query as a kind of cache.
[] fn erase_regions_ty: erase_regions_ty(Ty<'tcx>) -> Ty<'tcx>,
[] fn fully_normalize_monormophic_ty: normalize_ty_node(Ty<'tcx>) -> Ty<'tcx>,
+
+ [] fn substitute_normalize_and_test_predicates:
+ substitute_normalize_and_test_predicates_node((DefId, &'tcx Substs<'tcx>)) -> bool,
}
//////////////////////////////////////////////////////////////////////
fn normalize_ty_node<'tcx>(_: Ty<'tcx>) -> DepConstructor<'tcx> {
DepConstructor::NormalizeTy
}
+
+fn substitute_normalize_and_test_predicates_node<'tcx>(key: (DefId, &'tcx Substs<'tcx>))
+ -> DepConstructor<'tcx> {
+ DepConstructor::SubstituteNormalizeAndTestPredicates { key }
+}
use hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId,
RESERVED_FOR_INCR_COMP_CACHE, LOCAL_CRATE};
use hir::map::definitions::DefPathHash;
-use ich::CachingCodemapView;
+use ich::{CachingCodemapView, Fingerprint};
use mir;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
where E: ty_codec::TyEncoder
{
// Serializing the DepGraph should not modify it:
- let _in_ignore = tcx.dep_graph.in_ignore();
-
- // Allocate FileMapIndices
- let (file_to_file_index, file_index_to_stable_id) = {
- let mut file_to_file_index = FxHashMap();
- let mut file_index_to_stable_id = FxHashMap();
-
- for (index, file) in tcx.sess.codemap().files().iter().enumerate() {
- let index = FileMapIndex(index as u32);
- let file_ptr: *const FileMap = &**file as *const _;
- file_to_file_index.insert(file_ptr, index);
- file_index_to_stable_id.insert(index, StableFilemapId::new(&file));
- }
-
- (file_to_file_index, file_index_to_stable_id)
- };
-
- let mut encoder = CacheEncoder {
- tcx,
- encoder,
- type_shorthands: FxHashMap(),
- predicate_shorthands: FxHashMap(),
- expn_info_shorthands: FxHashMap(),
- codemap: CachingCodemapView::new(tcx.sess.codemap()),
- file_to_file_index,
- };
-
- // Load everything into memory so we can write it out to the on-disk
- // cache. The vast majority of cacheable query results should already
- // be in memory, so this should be a cheap operation.
- tcx.dep_graph.exec_cache_promotions(tcx);
-
- // Encode query results
- let mut query_result_index = EncodedQueryResultIndex::new();
-
- {
- use ty::maps::queries::*;
- let enc = &mut encoder;
- let qri = &mut query_result_index;
-
- // Encode TypeckTables
- encode_query_results::<typeck_tables_of, _>(tcx, enc, qri)?;
- encode_query_results::<optimized_mir, _>(tcx, enc, qri)?;
- encode_query_results::<unsafety_check_result, _>(tcx, enc, qri)?;
- encode_query_results::<borrowck, _>(tcx, enc, qri)?;
- encode_query_results::<mir_borrowck, _>(tcx, enc, qri)?;
- encode_query_results::<mir_const_qualif, _>(tcx, enc, qri)?;
- encode_query_results::<def_symbol_name, _>(tcx, enc, qri)?;
- encode_query_results::<const_is_rvalue_promotable_to_static, _>(tcx, enc, qri)?;
- encode_query_results::<contains_extern_indicator, _>(tcx, enc, qri)?;
- encode_query_results::<symbol_name, _>(tcx, enc, qri)?;
- encode_query_results::<trans_fulfill_obligation, _>(tcx, enc, qri)?;
- encode_query_results::<check_match, _>(tcx, enc, qri)?;
- }
+ tcx.dep_graph.with_ignore(|| {
+ // Allocate FileMapIndices
+ let (file_to_file_index, file_index_to_stable_id) = {
+ let mut file_to_file_index = FxHashMap();
+ let mut file_index_to_stable_id = FxHashMap();
+
+ for (index, file) in tcx.sess.codemap().files().iter().enumerate() {
+ let index = FileMapIndex(index as u32);
+ let file_ptr: *const FileMap = &**file as *const _;
+ file_to_file_index.insert(file_ptr, index);
+ file_index_to_stable_id.insert(index, StableFilemapId::new(&file));
+ }
- // Encode diagnostics
- let diagnostics_index = {
- let mut diagnostics_index = EncodedDiagnosticsIndex::new();
-
- for (dep_node_index, diagnostics) in self.current_diagnostics
- .borrow()
- .iter() {
- let pos = AbsoluteBytePos::new(encoder.position());
- // Let's make sure we get the expected type here:
- let diagnostics: &EncodedDiagnostics = diagnostics;
- let dep_node_index =
- SerializedDepNodeIndex::new(dep_node_index.index());
- encoder.encode_tagged(dep_node_index, diagnostics)?;
- diagnostics_index.push((dep_node_index, pos));
+ (file_to_file_index, file_index_to_stable_id)
+ };
+
+ let mut encoder = CacheEncoder {
+ tcx,
+ encoder,
+ type_shorthands: FxHashMap(),
+ predicate_shorthands: FxHashMap(),
+ expn_info_shorthands: FxHashMap(),
+ codemap: CachingCodemapView::new(tcx.sess.codemap()),
+ file_to_file_index,
+ };
+
+ // Load everything into memory so we can write it out to the on-disk
+ // cache. The vast majority of cacheable query results should already
+ // be in memory, so this should be a cheap operation.
+ tcx.dep_graph.exec_cache_promotions(tcx);
+
+ // Encode query results
+ let mut query_result_index = EncodedQueryResultIndex::new();
+
+ {
+ use ty::maps::queries::*;
+ let enc = &mut encoder;
+ let qri = &mut query_result_index;
+
+ // Encode TypeckTables
+ encode_query_results::<typeck_tables_of, _>(tcx, enc, qri)?;
+ encode_query_results::<optimized_mir, _>(tcx, enc, qri)?;
+ encode_query_results::<unsafety_check_result, _>(tcx, enc, qri)?;
+ encode_query_results::<borrowck, _>(tcx, enc, qri)?;
+ encode_query_results::<mir_borrowck, _>(tcx, enc, qri)?;
+ encode_query_results::<mir_const_qualif, _>(tcx, enc, qri)?;
+ encode_query_results::<def_symbol_name, _>(tcx, enc, qri)?;
+ encode_query_results::<const_is_rvalue_promotable_to_static, _>(tcx, enc, qri)?;
+ encode_query_results::<contains_extern_indicator, _>(tcx, enc, qri)?;
+ encode_query_results::<symbol_name, _>(tcx, enc, qri)?;
+ encode_query_results::<trans_fulfill_obligation, _>(tcx, enc, qri)?;
+ encode_query_results::<check_match, _>(tcx, enc, qri)?;
}
- diagnostics_index
- };
+ // Encode diagnostics
+ let diagnostics_index = {
+ let mut diagnostics_index = EncodedDiagnosticsIndex::new();
+
+ for (dep_node_index, diagnostics) in self.current_diagnostics
+ .borrow()
+ .iter() {
+ let pos = AbsoluteBytePos::new(encoder.position());
+ // Let's make sure we get the expected type here:
+ let diagnostics: &EncodedDiagnostics = diagnostics;
+ let dep_node_index =
+ SerializedDepNodeIndex::new(dep_node_index.index());
+ encoder.encode_tagged(dep_node_index, diagnostics)?;
+ diagnostics_index.push((dep_node_index, pos));
+ }
- let sorted_cnums = sorted_cnums_including_local_crate(tcx);
- let prev_cnums: Vec<_> = sorted_cnums.iter().map(|&cnum| {
- let crate_name = tcx.original_crate_name(cnum).as_str().to_string();
- let crate_disambiguator = tcx.crate_disambiguator(cnum);
- (cnum.as_u32(), crate_name, crate_disambiguator)
- }).collect();
-
- // Encode the file footer
- let footer_pos = encoder.position() as u64;
- encoder.encode_tagged(TAG_FILE_FOOTER, &Footer {
- file_index_to_stable_id,
- prev_cnums,
- query_result_index,
- diagnostics_index,
- })?;
-
- // Encode the position of the footer as the last 8 bytes of the
- // file so we know where to look for it.
- IntEncodedWithFixedSize(footer_pos).encode(encoder.encoder)?;
-
- // DO NOT WRITE ANYTHING TO THE ENCODER AFTER THIS POINT! The address
- // of the footer must be the last thing in the data stream.
-
- return Ok(());
-
- fn sorted_cnums_including_local_crate(tcx: TyCtxt) -> Vec<CrateNum> {
- let mut cnums = vec![LOCAL_CRATE];
- cnums.extend_from_slice(&tcx.crates()[..]);
- cnums.sort_unstable();
- // Just to be sure...
- cnums.dedup();
- cnums
- }
+ diagnostics_index
+ };
+
+ let sorted_cnums = sorted_cnums_including_local_crate(tcx);
+ let prev_cnums: Vec<_> = sorted_cnums.iter().map(|&cnum| {
+ let crate_name = tcx.original_crate_name(cnum).as_str().to_string();
+ let crate_disambiguator = tcx.crate_disambiguator(cnum);
+ (cnum.as_u32(), crate_name, crate_disambiguator)
+ }).collect();
+
+ // Encode the file footer
+ let footer_pos = encoder.position() as u64;
+ encoder.encode_tagged(TAG_FILE_FOOTER, &Footer {
+ file_index_to_stable_id,
+ prev_cnums,
+ query_result_index,
+ diagnostics_index,
+ })?;
+
+ // Encode the position of the footer as the last 8 bytes of the
+ // file so we know where to look for it.
+ IntEncodedWithFixedSize(footer_pos).encode(encoder.encoder)?;
+
+ // DO NOT WRITE ANYTHING TO THE ENCODER AFTER THIS POINT! The address
+ // of the footer must be the last thing in the data stream.
+
+ return Ok(());
+
+ fn sorted_cnums_including_local_crate(tcx: TyCtxt) -> Vec<CrateNum> {
+ let mut cnums = vec![LOCAL_CRATE];
+ cnums.extend_from_slice(&tcx.crates()[..]);
+ cnums.sort_unstable();
+ // Just to be sure...
+ cnums.dedup();
+ cnums
+ }
+ })
}
/// Load a diagnostic emitted during the previous compilation session.
prev_cnums: &[(u32, String, CrateDisambiguator)])
-> IndexVec<CrateNum, Option<CrateNum>>
{
- let _in_ignore = tcx.dep_graph.in_ignore();
-
- let current_cnums = tcx.all_crate_nums(LOCAL_CRATE).iter().map(|&cnum| {
- let crate_name = tcx.original_crate_name(cnum)
- .as_str()
- .to_string();
- let crate_disambiguator = tcx.crate_disambiguator(cnum);
- ((crate_name, crate_disambiguator), cnum)
- }).collect::<FxHashMap<_,_>>();
-
- let map_size = prev_cnums.iter()
- .map(|&(cnum, ..)| cnum)
- .max()
- .unwrap_or(0) + 1;
- let mut map = IndexVec::new();
- map.resize(map_size as usize, None);
-
- for &(prev_cnum, ref crate_name, crate_disambiguator) in prev_cnums {
- let key = (crate_name.clone(), crate_disambiguator);
- map[CrateNum::from_u32(prev_cnum)] = current_cnums.get(&key).cloned();
- }
+ tcx.dep_graph.with_ignore(|| {
+ let current_cnums = tcx.all_crate_nums(LOCAL_CRATE).iter().map(|&cnum| {
+ let crate_name = tcx.original_crate_name(cnum)
+ .as_str()
+ .to_string();
+ let crate_disambiguator = tcx.crate_disambiguator(cnum);
+ ((crate_name, crate_disambiguator), cnum)
+ }).collect::<FxHashMap<_,_>>();
+
+ let map_size = prev_cnums.iter()
+ .map(|&(cnum, ..)| cnum)
+ .max()
+ .unwrap_or(0) + 1;
+ let mut map = IndexVec::new();
+ map.resize(map_size as usize, None);
+
+ for &(prev_cnum, ref crate_name, crate_disambiguator) in prev_cnums {
+ let key = (crate_name.clone(), crate_disambiguator);
+ map[CrateNum::from_u32(prev_cnum)] = current_cnums.get(&key).cloned();
+ }
- map[LOCAL_CRATE] = Some(LOCAL_CRATE);
- map
+ map[LOCAL_CRATE] = Some(LOCAL_CRATE);
+ map
+ })
}
}
}
}
+impl<'a, 'tcx, 'x> SpecializedDecoder<Fingerprint> for CacheDecoder<'a, 'tcx, 'x> {
+ fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
+ Fingerprint::decode_opaque(&mut self.opaque)
+ }
+}
+
impl<'a, 'tcx, 'x, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
for CacheDecoder<'a, 'tcx, 'x> {
#[inline]
}
}
+impl<'enc, 'a, 'tcx> SpecializedEncoder<Fingerprint>
+for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder<'enc>>
+{
+ fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
+ f.encode_opaque(&mut self.encoder)
+ }
+}
+
impl<'enc, 'a, 'tcx, E, T> SpecializedEncoder<mir::ClearCrossCrate<T>>
for CacheEncoder<'enc, 'a, 'tcx, E>
where E: 'enc + ty_codec::TyEncoder,
DepKind::VtableMethods |
DepKind::EraseRegionsTy |
DepKind::NormalizeTy |
+ DepKind::SubstituteNormalizeAndTestPredicates |
// This one should never occur in this context
DepKind::Null => {
for attr in tcx.get_attrs(did).iter() {
for r in attr::find_repr_attrs(tcx.sess.diagnostic(), attr) {
flags.insert(match r {
- attr::ReprExtern => ReprFlags::IS_C,
+ attr::ReprC => ReprFlags::IS_C,
attr::ReprPacked => ReprFlags::IS_PACKED,
attr::ReprSimd => ReprFlags::IS_SIMD,
attr::ReprInt(i) => {
self.destructor(tcx).is_some()
}
- /// Asserts this is a struct and returns the struct's unique
- /// variant.
- pub fn struct_variant(&self) -> &VariantDef {
- assert!(!self.is_enum());
+ /// Asserts this is a struct or union and returns its unique variant.
+ pub fn non_enum_variant(&self) -> &VariantDef {
+ assert!(self.is_struct() || self.is_union());
&self.variants[0]
}
match def {
Def::Variant(vid) | Def::VariantCtor(vid, ..) => self.variant_with_id(vid),
Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) |
- Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => self.struct_variant(),
+ Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => self.non_enum_variant(),
_ => bug!("unexpected def {:?} in variant_of_def", def)
}
}
self.adt_def(enum_did).variant_with_id(did)
}
Def::Struct(did) | Def::Union(did) => {
- self.adt_def(did).struct_variant()
+ self.adt_def(did).non_enum_variant()
}
Def::StructCtor(ctor_did, ..) => {
let did = self.parent_def_id(ctor_did).expect("struct ctor has no parent");
- self.adt_def(did).struct_variant()
+ self.adt_def(did).non_enum_variant()
}
_ => bug!("expect_variant_def used with unexpected def {:?}", def)
}
pub fn simd_type(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
match self.sty {
TyAdt(def, substs) => {
- def.struct_variant().fields[0].ty(tcx, substs)
+ def.non_enum_variant().fields[0].ty(tcx, substs)
}
_ => bug!("simd_type called on invalid type")
}
pub fn simd_size(&self, _cx: TyCtxt) -> usize {
match self.sty {
- TyAdt(def, _) => def.struct_variant().fields.len(),
+ TyAdt(def, _) => def.non_enum_variant().fields.len(),
_ => bug!("simd_size called on invalid type")
}
}
adt.variant_with_id(vid).fields.get(i).map(|f| f.ty(self, substs))
}
(&TyAdt(adt, substs), None) => {
- // Don't use `struct_variant`, this may be a univariant enum.
+ // Don't use `non_enum_variant`, this may be a univariant enum.
adt.variants[0].fields.get(i).map(|f| f.ty(self, substs))
}
(&TyTuple(ref v, _), None) => v.get(i).cloned(),
adt.variant_with_id(vid).find_field_named(n).map(|f| f.ty(self, substs))
}
(&TyAdt(adt, substs), None) => {
- adt.struct_variant().find_field_named(n).map(|f| f.ty(self, substs))
+ adt.non_enum_variant().find_field_named(n).map(|f| f.ty(self, substs))
}
_ => return None
}
if !def.is_struct() {
break;
}
- match def.struct_variant().fields.last() {
+ match def.non_enum_variant().fields.last() {
Some(f) => ty = f.ty(self, substs),
None => break,
}
match (&a.sty, &b.sty) {
(&TyAdt(a_def, a_substs), &TyAdt(b_def, b_substs))
if a_def == b_def && a_def.is_struct() => {
- if let Some(f) = a_def.struct_variant().fields.last() {
+ if let Some(f) = a_def.non_enum_variant().fields.last() {
a = f.ty(self, a_substs);
b = f.ty(self, b_substs);
} else {
// Memory reporting
#[cfg(unix)]
fn get_resident() -> Option<usize> {
- use std::fs::File;
- use std::io::Read;
+ use std::fs;
let field = 1;
- let mut f = File::open("/proc/self/statm").ok()?;
- let mut contents = String::new();
- f.read_to_string(&mut contents).ok()?;
+ let contents = fs::read_string("/proc/self/statm").ok()?;
let s = contents.split_whitespace().nth(field)?;
let npages = s.parse::<usize>().ok()?;
Some(npages * 4096)
[dependencies]
syntax = { path = "../libsyntax" }
serialize = { path = "../libserialize" }
-log = "0.3"
+log = "0.4"
rand = "0.3"
[features]
#![feature(box_syntax)]
#![feature(const_fn)]
+#![feature(fs_read_write)]
extern crate syntax;
extern crate rand;
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use target::TargetResult;
+
+pub fn target() -> TargetResult {
+ let mut base = super::i686_unknown_linux_musl::target()?;
+ base.options.cpu = "pentium".to_string();
+ base.llvm_target = "i586-unknown-linux-musl".to_string();
+ Ok(base)
+}
use serialize::json::{Json, ToJson};
use std::collections::BTreeMap;
use std::default::Default;
-use std::io::prelude::*;
use syntax::abi::{Abi, lookup as lookup_abi};
use {LinkerFlavor, PanicStrategy, RelroLevel};
("powerpc64-unknown-linux-gnu", powerpc64_unknown_linux_gnu),
("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu),
("s390x-unknown-linux-gnu", s390x_unknown_linux_gnu),
+ ("sparc64-unknown-linux-gnu", sparc64_unknown_linux_gnu),
("arm-unknown-linux-gnueabi", arm_unknown_linux_gnueabi),
("arm-unknown-linux-gnueabihf", arm_unknown_linux_gnueabihf),
("arm-unknown-linux-musleabi", arm_unknown_linux_musleabi),
("armv7-unknown-linux-gnueabihf", armv7_unknown_linux_gnueabihf),
("armv7-unknown-linux-musleabihf", armv7_unknown_linux_musleabihf),
("aarch64-unknown-linux-gnu", aarch64_unknown_linux_gnu),
+
("aarch64-unknown-linux-musl", aarch64_unknown_linux_musl),
("x86_64-unknown-linux-musl", x86_64_unknown_linux_musl),
("i686-unknown-linux-musl", i686_unknown_linux_musl),
+ ("i586-unknown-linux-musl", i586_unknown_linux_musl),
("mips-unknown-linux-musl", mips_unknown_linux_musl),
("mipsel-unknown-linux-musl", mipsel_unknown_linux_musl),
+
("mips-unknown-linux-uclibc", mips_unknown_linux_uclibc),
("mipsel-unknown-linux-uclibc", mipsel_unknown_linux_uclibc),
- ("sparc64-unknown-linux-gnu", sparc64_unknown_linux_gnu),
-
("i686-linux-android", i686_linux_android),
("x86_64-linux-android", x86_64_linux_android),
("arm-linux-androideabi", arm_linux_androideabi),
pub fn search(target: &str) -> Result<Target, String> {
use std::env;
use std::ffi::OsString;
- use std::fs::File;
+ use std::fs;
use std::path::{Path, PathBuf};
use serialize::json;
fn load_file(path: &Path) -> Result<Target, String> {
- let mut f = File::open(path).map_err(|e| e.to_string())?;
- let mut contents = Vec::new();
- f.read_to_end(&mut contents).map_err(|e| e.to_string())?;
+ let contents = fs::read(path).map_err(|e| e.to_string())?;
let obj = json::from_reader(&mut &contents[..])
.map_err(|e| e.to_string())?;
Target::from_json(obj)
test = false
[dependencies]
-log = "0.3"
+log = "0.4"
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
graphviz = { path = "../libgraphviz" }
ty::TyAdt(adt_def, _) if adt_def.is_union() => match result {
RestrictionResult::Safe => RestrictionResult::Safe,
RestrictionResult::SafeIf(base_lp, mut base_vec) => {
- for field in &adt_def.struct_variant().fields {
+ for field in &adt_def.non_enum_variant().fields {
let field = InteriorKind::InteriorField(mc::NamedField(field.name));
let field_ty = if field == interior {
cmt.ty
if let (&ty::TyAdt(adt_def, _), LpInterior(opt_variant_id, interior))
= (&base_lp.ty.sty, lp_elem) {
if adt_def.is_union() {
- for field in &adt_def.struct_variant().fields {
+ for field in &adt_def.non_enum_variant().fields {
let field = InteriorKind::InteriorField(mc::NamedField(field.name));
if field != interior {
let sibling_lp_kind =
if let LpExtend(ref base_lp, mutbl, LpInterior(opt_variant_id, interior)) = lp.kind {
if let ty::TyAdt(adt_def, _) = base_lp.ty.sty {
if adt_def.is_union() {
- for field in &adt_def.struct_variant().fields {
+ for field in &adt_def.non_enum_variant().fields {
let field = InteriorKind::InteriorField(mc::NamedField(field.name));
let field_ty = if field == interior {
lp.ty
[dependencies]
arena = { path = "../libarena" }
-log = "0.3"
+log = "0.4"
rustc = { path = "../librustc" }
rustc_const_math = { path = "../librustc_const_math" }
rustc_data_structures = { path = "../librustc_data_structures" }
let mut pcx = PatternContext::new(tcx, param_env_and_substs, tables);
let result = pcx.lower_pattern(pat);
if !pcx.errors.is_empty() {
- span_bug!(pat.span, "encountered errors lowering pattern: {:?}", pcx.errors)
+ let msg = format!("encountered errors lowering pattern: {:?}", pcx.errors);
+ tcx.sess.delay_span_bug(pat.span, &msg);
}
debug!("Pattern::from_hir({:?}) = {:?}", pat, result);
result
crate-type = ["dylib"]
[dependencies]
-log = "0.3"
+log = "0.4"
serialize = { path = "../libserialize" }
cfg-if = "0.1.2"
stable_deref_trait = "1.0.0"
[dependencies.parking_lot]
version = "0.5"
-features = ["nightly"]
\ No newline at end of file
+features = ["nightly"]
use std::str;
-pub const MAX_BASE: u64 = 64;
-pub const ALPHANUMERIC_ONLY: u64 = 62;
+pub const MAX_BASE: usize = 64;
+pub const ALPHANUMERIC_ONLY: usize = 62;
+pub const CASE_INSENSITIVE: usize = 36;
const BASE_64: &'static [u8; MAX_BASE as usize] =
b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@$";
#[inline]
-pub fn push_str(mut n: u64, base: u64, output: &mut String) {
+pub fn push_str(mut n: u128, base: usize, output: &mut String) {
debug_assert!(base >= 2 && base <= MAX_BASE);
- let mut s = [0u8; 64];
+ let mut s = [0u8; 128];
let mut index = 0;
+ let base = base as u128;
+
loop {
s[index] = BASE_64[(n % base) as usize];
index += 1;
}
#[inline]
-pub fn encode(n: u64, base: u64) -> String {
- let mut s = String::with_capacity(13);
+pub fn encode(n: u128, base: usize) -> String {
+ let mut s = String::new();
push_str(n, base, &mut s);
s
}
#[test]
fn test_encode() {
- fn test(n: u64, base: u64) {
- assert_eq!(Ok(n), u64::from_str_radix(&encode(n, base), base as u32));
+ fn test(n: u128, base: usize) {
+ assert_eq!(Ok(n), u128::from_str_radix(&encode(n, base), base as u32));
}
for base in 2..37 {
test(35, base);
test(36, base);
test(37, base);
- test(u64::max_value(), base);
+ test(u64::max_value() as u128, base);
+ test(u128::max_value(), base);
for i in 0 .. 1_000 {
test(i * 983, base);
[dependencies]
arena = { path = "../libarena" }
graphviz = { path = "../libgraphviz" }
-log = { version = "0.3", features = ["release_max_level_info"] }
+log = { version = "0.4", features = ["release_max_level_info"] }
env_logger = { version = "0.4", default-features = false }
rustc = { path = "../librustc" }
rustc_allocator = { path = "../librustc_allocator" }
|| hir_map::map_crate(sess, cstore, &mut hir_forest, &defs));
{
- let _ignore = hir_map.dep_graph.in_ignore();
+ hir_map.dep_graph.assert_ignored();
controller_entry_point!(after_hir_lowering,
sess,
CompileState::state_after_hir_lowering(input,
|tcx, analysis, rx, result| {
{
// Eventually, we will want to track plugins.
- let _ignore = tcx.dep_graph.in_ignore();
-
- let mut state = CompileState::state_after_analysis(input,
- sess,
- outdir,
- output,
- opt_crate,
- tcx.hir.krate(),
- &analysis,
- tcx,
- &crate_name);
- (control.after_analysis.callback)(&mut state);
+ tcx.dep_graph.with_ignore(|| {
+ let mut state = CompileState::state_after_analysis(input,
+ sess,
+ outdir,
+ output,
+ opt_crate,
+ tcx.hir.krate(),
+ &analysis,
+ tcx,
+ &crate_name);
+ (control.after_analysis.callback)(&mut state);
+ });
if control.after_analysis.stop == Compilation::Stop {
return result.and_then(|_| Err(CompileIncomplete::Stopped));
result?;
- if log_enabled!(::log::LogLevel::Info) {
+ if log_enabled!(::log::Level::Info) {
println!("Pre-trans");
tcx.print_debug_stats();
}
let trans = phase_4_translate_to_llvm::<DefaultTransCrate>(tcx, rx);
- if log_enabled!(::log::LogLevel::Info) {
+ if log_enabled!(::log::Level::Info) {
println!("Post-trans");
tcx.print_debug_stats();
}
let dep_graph = match future_dep_graph {
None => DepGraph::new_disabled(),
Some(future) => {
- let prev_graph = future
- .open()
- .expect("Could not join with background dep_graph thread")
- .open(sess);
+ let prev_graph = time(time_passes, "blocked while dep-graph loading finishes", || {
+ future.open()
+ .expect("Could not join with background dep_graph thread")
+ .open(sess)
+ });
DepGraph::new(prev_graph)
}
};
pub use rustc_trans_utils::trans_crate::TranslatedCrate as CrateTranslation;
pub fn init(_sess: &Session) {}
- pub fn enable_llvm_debug() {}
pub fn print_version() {}
pub fn print_passes() {}
pub fn print(_req: PrintRequest, _sess: &Session) {}
let (sopts, cfg) = config::build_session_options_and_crate_config(&matches);
- if sopts.debugging_opts.debug_llvm {
- rustc_trans::enable_llvm_debug();
- }
-
let descriptions = diagnostics_registry();
do_or_return!(callbacks.early_callback(&matches,
tcx,
tables: Cell::new(&empty_tables)
};
- let _ignore = tcx.dep_graph.in_ignore();
- f(&annotation, hir_map.forest.krate())
+ tcx.dep_graph.with_ignore(|| {
+ f(&annotation, hir_map.forest.krate())
+ })
}),
sess)
}
self.continue_after_error.set(continue_after_error);
}
- // NOTE: DO NOT call this function from rustc, as it relies on `err_count` being non-zero
- // if an error happened to avoid ICEs. This function should only be called from tools.
+ /// Resets the diagnostic error count as well as the cached emitted diagnostics.
+ ///
+ /// NOTE: DO NOT call this function from rustc. It is only meant to be called from external
+ /// tools that want to reuse a `Parser` cleaning the previously emitted diagnostics as well as
+ /// the overall count of emitted error diagnostics.
pub fn reset_err_count(&self) {
+ self.emitted_diagnostics.replace(FxHashSet());
self.err_count.store(0, SeqCst);
}
[dependencies]
graphviz = { path = "../libgraphviz" }
-log = "0.3"
+log = "0.4"
rand = "0.3"
rustc = { path = "../librustc" }
rustc_data_structures = { path = "../librustc_data_structures" }
use rustc::ich::{ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED};
use graphviz::IntoCow;
use std::env;
-use std::fs::File;
+use std::fs::{self, File};
use std::io::Write;
use syntax::ast;
use syntax_pos::Span;
pub fn assert_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
- let _ignore = tcx.dep_graph.in_ignore();
-
- if tcx.sess.opts.debugging_opts.dump_dep_graph {
- dump_graph(tcx);
- }
-
- // if the `rustc_attrs` feature is not enabled, then the
- // attributes we are interested in cannot be present anyway, so
- // skip the walk.
- if !tcx.sess.features.borrow().rustc_attrs {
- return;
- }
+ tcx.dep_graph.with_ignore(|| {
+ if tcx.sess.opts.debugging_opts.dump_dep_graph {
+ dump_graph(tcx);
+ }
- // Find annotations supplied by user (if any).
- let (if_this_changed, then_this_would_need) = {
- let mut visitor = IfThisChanged { tcx,
- if_this_changed: vec![],
- then_this_would_need: vec![] };
- visitor.process_attrs(ast::CRATE_NODE_ID, &tcx.hir.krate().attrs);
- tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
- (visitor.if_this_changed, visitor.then_this_would_need)
- };
+ // if the `rustc_attrs` feature is not enabled, then the
+ // attributes we are interested in cannot be present anyway, so
+ // skip the walk.
+ if !tcx.sess.features.borrow().rustc_attrs {
+ return;
+ }
- if !if_this_changed.is_empty() || !then_this_would_need.is_empty() {
- assert!(tcx.sess.opts.debugging_opts.query_dep_graph,
- "cannot use the `#[{}]` or `#[{}]` annotations \
- without supplying `-Z query-dep-graph`",
- ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED);
- }
+ // Find annotations supplied by user (if any).
+ let (if_this_changed, then_this_would_need) = {
+ let mut visitor = IfThisChanged { tcx,
+ if_this_changed: vec![],
+ then_this_would_need: vec![] };
+ visitor.process_attrs(ast::CRATE_NODE_ID, &tcx.hir.krate().attrs);
+ tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
+ (visitor.if_this_changed, visitor.then_this_would_need)
+ };
+
+ if !if_this_changed.is_empty() || !then_this_would_need.is_empty() {
+ assert!(tcx.sess.opts.debugging_opts.query_dep_graph,
+ "cannot use the `#[{}]` or `#[{}]` annotations \
+ without supplying `-Z query-dep-graph`",
+ ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED);
+ }
- // Check paths.
- check_paths(tcx, &if_this_changed, &then_this_would_need);
+ // Check paths.
+ check_paths(tcx, &if_this_changed, &then_this_would_need);
+ })
}
type Sources = Vec<(Span, DefId, DepNode)>;
let dot_path = format!("{}.dot", path);
let mut v = Vec::new();
dot::render(&GraphvizDepGraph(nodes, edges), &mut v).unwrap();
- File::create(&dot_path).and_then(|mut f| f.write_all(&v)).unwrap();
+ fs::write(dot_path, v).unwrap();
}
}
#![deny(warnings)]
#![feature(conservative_impl_trait)]
+#![feature(fs_read_write)]
#![feature(i128_type)]
#![feature(inclusive_range_syntax)]
#![feature(specialization)]
return;
}
- let _ignore = tcx.dep_graph.in_ignore();
- let krate = tcx.hir.krate();
- let mut dirty_clean_visitor = DirtyCleanVisitor {
- tcx,
- checked_attrs: FxHashSet(),
- };
- krate.visit_all_item_likes(&mut dirty_clean_visitor);
-
- let mut all_attrs = FindAllAttrs {
- tcx,
- attr_names: vec![ATTR_DIRTY, ATTR_CLEAN],
- found_attrs: vec![],
- };
- intravisit::walk_crate(&mut all_attrs, krate);
-
- // Note that we cannot use the existing "unused attribute"-infrastructure
- // here, since that is running before trans. This is also the reason why
- // all trans-specific attributes are `Whitelisted` in syntax::feature_gate.
- all_attrs.report_unchecked_attrs(&dirty_clean_visitor.checked_attrs);
+ tcx.dep_graph.with_ignore(|| {
+ let krate = tcx.hir.krate();
+ let mut dirty_clean_visitor = DirtyCleanVisitor {
+ tcx,
+ checked_attrs: FxHashSet(),
+ };
+ krate.visit_all_item_likes(&mut dirty_clean_visitor);
+
+ let mut all_attrs = FindAllAttrs {
+ tcx,
+ attr_names: vec![ATTR_DIRTY, ATTR_CLEAN],
+ found_attrs: vec![],
+ };
+ intravisit::walk_crate(&mut all_attrs, krate);
+
+ // Note that we cannot use the existing "unused attribute"-infrastructure
+ // here, since that is running before trans. This is also the reason why
+ // all trans-specific attributes are `Whitelisted` in syntax::feature_gate.
+ all_attrs.report_unchecked_attrs(&dirty_clean_visitor.checked_attrs);
+ })
}
pub struct DirtyCleanVisitor<'a, 'tcx:'a> {
use std::io::{self, Read};
use std::path::Path;
-use std::fs::File;
+use std::fs;
use std::env;
use rustc::session::config::nightly_options;
return Ok(None);
}
- let mut file = File::open(path)?;
- let file_size = file.metadata()?.len() as usize;
-
- let mut data = Vec::with_capacity(file_size);
- file.read_to_end(&mut data)?;
+ let data = fs::read(path)?;
let mut file = io::Cursor::new(data);
// or hexadecimal numbers (we want short file and directory names). Since these
// numbers will be used in file names, we choose an encoding that is not
// case-sensitive (as opposed to base64, for example).
-const INT_ENCODE_BASE: u64 = 36;
+const INT_ENCODE_BASE: usize = base_n::CASE_INSENSITIVE;
pub fn dep_graph_path(sess: &Session) -> PathBuf {
in_incr_comp_dir_sess(sess, DEP_GRAPH_FILENAME)
let mut new_sub_dir_name = String::from(&old_sub_dir_name[.. dash_indices[2] + 1]);
// Append the svh
- base_n::push_str(svh.as_u64(), INT_ENCODE_BASE, &mut new_sub_dir_name);
+ base_n::push_str(svh.as_u64() as u128, INT_ENCODE_BASE, &mut new_sub_dir_name);
// Create the full path
let new_path = incr_comp_session_dir.parent().unwrap().join(new_sub_dir_name);
let directory_name = format!("s-{}-{}-working",
timestamp,
- base_n::encode(random_number as u64,
+ base_n::encode(random_number as u128,
INT_ENCODE_BASE));
debug!("generate_session_dir_path: directory_name = {}", directory_name);
let directory_path = crate_dir.join(directory_name);
let duration = timestamp.duration_since(UNIX_EPOCH).unwrap();
let micros = duration.as_secs() * 1_000_000 +
(duration.subsec_nanos() as u64) / 1000;
- base_n::encode(micros, INT_ENCODE_BASE)
+ base_n::encode(micros as u128, INT_ENCODE_BASE)
}
fn string_to_timestamp(s: &str) -> Result<SystemTime, ()> {
// The full crate disambiguator is really long. 64 bits of it should be
// sufficient.
let crate_disambiguator = crate_disambiguator.to_fingerprint().to_smaller_hash();
- let crate_disambiguator = base_n::encode(crate_disambiguator, INT_ENCODE_BASE);
+ let crate_disambiguator = base_n::encode(crate_disambiguator as u128,
+ INT_ENCODE_BASE);
let crate_name = format!("{}-{}", crate_name, crate_disambiguator);
incr_dir.join(crate_name)
use rustc_data_structures::fx::FxHashMap;
use rustc_serialize::Encodable as RustcEncodable;
use rustc_serialize::opaque::Encoder;
-use std::io::{self, Cursor, Write};
-use std::fs::{self, File};
+use std::io::{self, Cursor};
+use std::fs;
use std::path::PathBuf;
use super::data::*;
pub fn save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
debug!("save_dep_graph()");
- let _ignore = tcx.dep_graph.in_ignore();
- let sess = tcx.sess;
- if sess.opts.incremental.is_none() {
- return;
- }
-
- time(sess.time_passes(), "persist query result cache", || {
- save_in(sess,
- query_cache_path(sess),
- |e| encode_query_cache(tcx, e));
- });
+ tcx.dep_graph.with_ignore(|| {
+ let sess = tcx.sess;
+ if sess.opts.incremental.is_none() {
+ return;
+ }
- if tcx.sess.opts.debugging_opts.incremental_queries {
- time(sess.time_passes(), "persist dep-graph", || {
+ time(sess.time_passes(), "persist query result cache", || {
save_in(sess,
- dep_graph_path(sess),
- |e| encode_dep_graph(tcx, e));
+ query_cache_path(sess),
+ |e| encode_query_cache(tcx, e));
});
- }
- dirty_clean::check_dirty_clean_annotations(tcx);
+ if tcx.sess.opts.debugging_opts.incremental_queries {
+ time(sess.time_passes(), "persist dep-graph", || {
+ save_in(sess,
+ dep_graph_path(sess),
+ |e| encode_dep_graph(tcx, e));
+ });
+ }
+
+ dirty_clean::check_dirty_clean_annotations(tcx);
+ })
}
pub fn save_work_products(sess: &Session, dep_graph: &DepGraph) {
}
debug!("save_work_products()");
- let _ignore = dep_graph.in_ignore();
+ dep_graph.assert_ignored();
let path = work_products_path(sess);
save_in(sess, path, |e| encode_work_products(dep_graph, e));
// write the data out
let data = wr.into_inner();
- match File::create(&path_buf).and_then(|mut file| file.write_all(&data)) {
+ match fs::write(&path_buf, data) {
Ok(_) => {
debug!("save: data written to disk successfully");
}
let extension = match kind {
WorkProductFileKind::Object => "o",
WorkProductFileKind::Bytecode => "bc",
- WorkProductFileKind::BytecodeCompressed => "bc-compressed",
+ WorkProductFileKind::BytecodeCompressed => "bc.z",
};
- let file_name = format!("cgu-{}.{}", cgu_name, extension);
+ let file_name = format!("{}.{}", cgu_name, extension);
let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name);
match link_or_copy(path, &path_in_incr_dir) {
Ok(_) => Some((kind, file_name)),
test = false
[dependencies]
-log = "0.3"
+log = "0.4"
rustc = { path = "../librustc" }
rustc_const_eval = { path = "../librustc_const_eval" }
syntax = { path = "../libsyntax" }
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCamelCaseTypes {
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
- let extern_repr_count = it.attrs
+ let has_repr_c = it.attrs
.iter()
- .filter(|attr| {
+ .any(|attr| {
attr::find_repr_attrs(cx.tcx.sess.diagnostic(), attr)
.iter()
- .any(|r| r == &attr::ReprExtern)
- })
- .count();
- let has_extern_repr = extern_repr_count > 0;
+ .any(|r| r == &attr::ReprC)
+ });
- if has_extern_repr {
+ if has_repr_c {
return;
}
// don't have anything to attach a symbol to
let msg = "const items should never be #[no_mangle]";
let mut err = cx.struct_span_lint(NO_MANGLE_CONST_ITEMS, it.span, msg);
+
+ // account for "pub const" (#45562)
+ let start = cx.tcx.sess.codemap().span_to_snippet(it.span)
+ .map(|snippet| snippet.find("const").unwrap_or(0))
+ .unwrap_or(0) as u32;
// `const` is 5 chars
- let const_span = it.span.with_hi(BytePos(it.span.lo().0 + 5));
+ let const_span = it.span.with_hi(BytePos(it.span.lo().0 + start + 5));
err.span_suggestion(const_span,
"try a static value",
"pub static".to_owned());
consider adding a #[repr(C)] attribute to the type");
}
- if def.struct_variant().fields.is_empty() {
+ if def.non_enum_variant().fields.is_empty() {
return FfiUnsafe("found zero-size struct in foreign module, consider \
adding a member to this struct");
}
// We can't completely trust repr(C) markings; make sure the
// fields are actually safe.
let mut all_phantom = true;
- for field in &def.struct_variant().fields {
+ for field in &def.non_enum_variant().fields {
let field_ty = cx.fully_normalize_associated_types_in(
&field.ty(cx, substs)
);
consider adding a #[repr(C)] attribute to the type");
}
- if def.struct_variant().fields.is_empty() {
+ if def.non_enum_variant().fields.is_empty() {
return FfiUnsafe("found zero-size union in foreign module, consider \
adding a member to this union");
}
let mut all_phantom = true;
- for field in &def.struct_variant().fields {
+ for field in &def.non_enum_variant().fields {
let field_ty = cx.fully_normalize_associated_types_in(
&field.ty(cx, substs)
);
ElementCount: c_uint,
Packed: Bool);
- /// Enables LLVM debug output.
- pub fn LLVMRustSetDebug(Enabled: c_int);
-
/// Prepares inline assembly.
pub fn LLVMRustInlineAsm(Ty: TypeRef,
AsmString: *const c_char,
pub fn LLVMRustSetNormalizedTarget(M: ModuleRef, triple: *const c_char);
pub fn LLVMRustAddAlwaysInlinePass(P: PassManagerBuilderRef, AddLifetimes: bool);
pub fn LLVMRustLinkInExternalBitcode(M: ModuleRef, bc: *const c_char, len: size_t) -> bool;
- pub fn LLVMRustLinkInParsedExternalBitcode(M: ModuleRef, M: ModuleRef) -> bool;
pub fn LLVMRustRunRestrictionPass(M: ModuleRef, syms: *const *const c_char, len: size_t);
pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef);
pub fn LLVMRustWriteDiagnosticInfoToString(DI: DiagnosticInfoRef, s: RustStringRef);
pub fn LLVMRustGetDiagInfoKind(DI: DiagnosticInfoRef) -> DiagnosticKind;
- pub fn LLVMRustWriteDebugLocToString(C: ContextRef, DL: DebugLocRef, s: RustStringRef);
-
pub fn LLVMRustSetInlineAsmDiagnosticHandler(C: ContextRef,
H: InlineAsmDiagHandler,
CX: *mut c_void);
build_string(|s| LLVMRustWriteTwineToString(tr, s)).expect("got a non-UTF8 Twine from LLVM")
}
-pub unsafe fn debug_loc_to_string(c: ContextRef, tr: DebugLocRef) -> String {
- build_string(|s| LLVMRustWriteDebugLocToString(c, tr, s))
- .expect("got a non-UTF8 DebugLoc from LLVM")
-}
-
pub fn initialize_available_targets() {
macro_rules! init_target(
($cfg:meta, $($method:ident),*) => { {
[dependencies]
flate2 = "1.0"
-log = "0.3"
+log = "0.4"
proc_macro = { path = "../libproc_macro" }
rustc = { path = "../librustc" }
rustc_back = { path = "../librustc_back" }
self.inject_allocator_crate(krate);
self.inject_panic_runtime(krate);
- if log_enabled!(log::LogLevel::Info) {
+ if log_enabled!(log::Level::Info) {
dump_crates(&self.cstore);
}
}
fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
let data = self.get_crate_data(id.krate);
if let Some(ref proc_macros) = data.proc_macros {
- return LoadedMacro::ProcMacro(proc_macros[id.index.as_usize() - 1].1.clone());
+ return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone());
} else if data.name == "proc_macro" &&
self.get_crate_data(id.krate).item_name(id.index) == "quote" {
let ext = SyntaxExtension::ProcMacro(Box::new(::proc_macro::__internal::Quoter));
use rustc::middle::cstore::{LinkagePreference, ExternConstBody,
ExternBodyNestedBodies};
use rustc::hir::def::{self, Def, CtorKind};
-use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc::hir::def_id::{CrateNum, DefId, DefIndex,
+ CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::ich::Fingerprint;
use rustc::middle::lang_items;
use rustc::mir;
use std::u32;
use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque};
-use rustc_data_structures::indexed_vec::Idx;
use syntax::attr;
use syntax::ast::{self, Ident};
use syntax::codemap;
impl<'a, 'tcx> SpecializedDecoder<DefIndex> for DecodeContext<'a, 'tcx> {
#[inline]
fn specialized_decode(&mut self) -> Result<DefIndex, Self::Error> {
- Ok(DefIndex::from_u32(self.read_u32()?))
+ Ok(DefIndex::from_raw_u32(self.read_u32()?))
}
}
impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
- let lo = BytePos::decode(self)?;
- let hi = BytePos::decode(self)?;
+ let tag = u8::decode(self)?;
- if lo == BytePos(0) && hi == BytePos(0) {
- // Don't try to rebase DUMMY_SP. Otherwise it will look like a valid
- // Span again.
+ if tag == TAG_INVALID_SPAN {
return Ok(DUMMY_SP)
}
- if hi < lo {
- // Consistently map invalid spans to DUMMY_SP.
- return Ok(DUMMY_SP)
- }
+ debug_assert_eq!(tag, TAG_VALID_SPAN);
+
+ let lo = BytePos::decode(self)?;
+ let len = BytePos::decode(self)?;
+ let hi = lo + len;
let sess = if let Some(sess) = self.sess {
sess
let last_filemap = &imported_filemaps[self.last_filemap_index];
if lo >= last_filemap.original_start_pos &&
- lo <= last_filemap.original_end_pos &&
- hi >= last_filemap.original_start_pos &&
- hi <= last_filemap.original_end_pos {
+ lo <= last_filemap.original_end_pos {
last_filemap
} else {
let mut a = 0;
debug_assert!(lo >= filemap.original_start_pos &&
lo <= filemap.original_end_pos);
- if hi < filemap.original_start_pos || hi > filemap.original_end_pos {
- // `hi` points to a different FileMap than `lo` which is invalid.
- // Again, map invalid Spans to DUMMY_SP.
- return Ok(DUMMY_SP)
- }
+ // Make sure we correctly filtered out invalid spans during encoding
+ debug_assert!(hi >= filemap.original_start_pos &&
+ hi <= filemap.original_end_pos);
let lo = (lo + filemap.translated_filemap.start_pos) - filemap.original_start_pos;
let hi = (hi + filemap.translated_filemap.start_pos) - filemap.original_start_pos;
}
}
+impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for DecodeContext<'a, 'tcx> {
+ fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
+ Fingerprint::decode_opaque(&mut self.opaque)
+ }
+}
+
impl<'a, 'tcx, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
for DecodeContext<'a, 'tcx> {
#[inline]
if !self.is_proc_macro(index) {
self.entry(index).kind.to_def(self.local_def_id(index))
} else {
- let kind = self.proc_macros.as_ref().unwrap()[index.as_usize() - 1].1.kind();
+ let kind = self.proc_macros.as_ref().unwrap()[index.to_proc_macro_index()].1.kind();
Some(Def::Macro(self.local_def_id(index), kind))
}
}
let def = Def::Macro(
DefId {
krate: self.cnum,
- index: DefIndex::new(id + 1)
+ index: DefIndex::from_proc_macro_index(id),
},
ext.kind()
);
use rustc::hir::def::CtorKind;
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE};
use rustc::hir::map::definitions::DefPathTable;
+use rustc::ich::Fingerprint;
use rustc::middle::dependency_format::Linkage;
use rustc::middle::lang_items;
use rustc::mir;
use syntax::codemap::Spanned;
use syntax::attr;
use syntax::symbol::Symbol;
-use syntax_pos::{self, FileName};
+use syntax_pos::{self, FileName, FileMap, Span, DUMMY_SP};
use rustc::hir::{self, PatKind};
use rustc::hir::itemlikevisit::ItemLikeVisitor;
lazy_state: LazyState,
type_shorthands: FxHashMap<Ty<'tcx>, usize>,
predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
+
+ // This is used to speed up Span encoding.
+ filemap_cache: Rc<FileMap>,
}
macro_rules! encoder_methods {
impl<'a, 'tcx> SpecializedEncoder<DefIndex> for EncodeContext<'a, 'tcx> {
#[inline]
fn specialized_encode(&mut self, def_index: &DefIndex) -> Result<(), Self::Error> {
- self.emit_u32(def_index.as_u32())
+ self.emit_u32(def_index.as_raw_u32())
+ }
+}
+
+impl<'a, 'tcx> SpecializedEncoder<Span> for EncodeContext<'a, 'tcx> {
+ fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> {
+ if *span == DUMMY_SP {
+ return TAG_INVALID_SPAN.encode(self)
+ }
+
+ let span = span.data();
+
+ // The Span infrastructure should make sure that this invariant holds:
+ debug_assert!(span.lo <= span.hi);
+
+ if !self.filemap_cache.contains(span.lo) {
+ let codemap = self.tcx.sess.codemap();
+ let filemap_index = codemap.lookup_filemap_idx(span.lo);
+ self.filemap_cache = codemap.files()[filemap_index].clone();
+ }
+
+ if !self.filemap_cache.contains(span.hi) {
+ // Unfortunately, macro expansion still sometimes generates Spans
+ // that malformed in this way.
+ return TAG_INVALID_SPAN.encode(self)
+ }
+
+ TAG_VALID_SPAN.encode(self)?;
+ span.lo.encode(self)?;
+
+ // Encode length which is usually less than span.hi and profits more
+ // from the variable-length integer encoding that we use.
+ let len = span.hi - span.lo;
+ len.encode(self)
+
+ // Don't encode the expansion context.
}
}
}
}
+impl<'a, 'tcx> SpecializedEncoder<Fingerprint> for EncodeContext<'a, 'tcx> {
+ fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
+ f.encode_opaque(&mut self.opaque)
+ }
+}
+
impl<'a, 'tcx, T: Encodable> SpecializedEncoder<mir::ClearCrossCrate<T>>
for EncodeContext<'a, 'tcx> {
fn specialized_encode(&mut self,
debug!("IsolatedEncoder::encode_struct_ctor({:?})", def_id);
let tcx = self.tcx;
let adt_def = tcx.adt_def(adt_def_id);
- let variant = adt_def.struct_variant();
+ let variant = adt_def.non_enum_variant();
let data = VariantData {
ctor_kind: variant.ctor_kind,
fn encode_fn_arg_names_for_body(&mut self, body_id: hir::BodyId)
-> LazySeq<ast::Name> {
- let _ignore = self.tcx.dep_graph.in_ignore();
- let body = self.tcx.hir.body(body_id);
- self.lazy_seq(body.arguments.iter().map(|arg| {
- match arg.pat.node {
- PatKind::Binding(_, _, name, _) => name.node,
- _ => Symbol::intern("")
- }
- }))
+ self.tcx.dep_graph.with_ignore(|| {
+ let body = self.tcx.hir.body(body_id);
+ self.lazy_seq(body.arguments.iter().map(|arg| {
+ match arg.pat.node {
+ PatKind::Binding(_, _, name, _) => name.node,
+ _ => Symbol::intern("")
+ }
+ }))
+ })
}
fn encode_fn_arg_names(&mut self, names: &[Spanned<ast::Name>])
hir::ItemTy(..) => EntryKind::Type,
hir::ItemEnum(..) => EntryKind::Enum(get_repr_options(&tcx, def_id)),
hir::ItemStruct(ref struct_def, _) => {
- let variant = tcx.adt_def(def_id).struct_variant();
+ let variant = tcx.adt_def(def_id).non_enum_variant();
// Encode def_ids for each field and method
// for methods, write all the stuff get_trait_method
}), repr_options)
}
hir::ItemUnion(..) => {
- let variant = tcx.adt_def(def_id).struct_variant();
+ let variant = tcx.adt_def(def_id).non_enum_variant();
let repr_options = get_repr_options(&tcx, def_id);
EntryKind::Union(self.lazy(&VariantData {
hir::ItemStruct(..) |
hir::ItemUnion(..) => {
let def = self.tcx.adt_def(def_id);
- self.lazy_seq(def.struct_variant().fields.iter().map(|f| {
+ self.lazy_seq(def.non_enum_variant().fields.iter().map(|f| {
assert!(f.did.is_local());
f.did.index
}))
lazy_state: LazyState::NoNode,
type_shorthands: Default::default(),
predicate_shorthands: Default::default(),
+ filemap_cache: tcx.sess.codemap().files()[0].clone(),
};
// Encode the rustc version string in a predictable location.
#[inline(never)]
pub fn lookup(&self, bytes: &[u8], def_index: DefIndex) -> Option<Lazy<Entry<'tcx>>> {
let words = &bytes_to_words(&bytes[self.position..])[..self.len];
- let index = def_index.as_usize();
debug!("Index::lookup: index={:?} words.len={:?}",
- index,
+ def_index,
words.len());
let positions = match def_index.address_space() {
where DATA: DepGraphRead
{
assert!(id.is_local());
- let tcx: TyCtxt<'b, 'tcx, 'tcx> = self.ecx.tcx;
// We don't track this since we are explicitly computing the incr. comp.
// hashes anyway. In theory we could do some tracking here and use it to
// avoid rehashing things (and instead cache the hashes) but it's
// unclear whether that would be a win since hashing is cheap enough.
- let _task = tcx.dep_graph.in_ignore();
+ self.ecx.tcx.dep_graph.with_ignore(move || {
+ let mut entry_builder = IsolatedEncoder::new(self.ecx);
+ let entry = op(&mut entry_builder, data);
+ let entry = entry_builder.lazy(&entry);
- let mut entry_builder = IsolatedEncoder::new(self.ecx);
- let entry = op(&mut entry_builder, data);
- let entry = entry_builder.lazy(&entry);
-
- self.items.record(id, entry);
+ self.items.record(id, entry);
+ })
}
pub fn into_items(self) -> Index {
#![feature(box_patterns)]
#![feature(conservative_impl_trait)]
+#![feature(fs_read_write)]
#![feature(i128_type)]
#![feature(libc)]
#![feature(proc_macro_internals)]
use std::cmp;
use std::fmt;
-use std::fs::{self, File};
+use std::fs;
use std::io::{self, Read};
use std::path::{Path, PathBuf};
use std::time::Instant;
}
}
CrateFlavor::Rmeta => {
- let mut file = File::open(filename).map_err(|_|
- format!("could not open file: '{}'", filename.display()))?;
- let mut buf = vec![];
- file.read_to_end(&mut buf).map_err(|_|
+ let buf = fs::read(filename).map_err(|_|
format!("failed to read rmeta metadata: '{}'", filename.display()))?;
OwningRef::new(buf).map_owner_box().erase_owner()
}
pub layout: mir::GeneratorLayout<'tcx>,
}
impl_stable_hash_for!(struct GeneratorData<'tcx> { layout });
+
+// Tags used for encoding Spans:
+pub const TAG_VALID_SPAN: u8 = 0;
+pub const TAG_INVALID_SPAN: u8 = 1;
[dependencies]
bitflags = "1.0"
graphviz = { path = "../libgraphviz" }
-log = "0.3"
+log = "0.4"
log_settings = "0.1.1"
rustc = { path = "../librustc" }
rustc_back = { path = "../librustc_back" }
ty::TyAdt(def, _) => if def.is_enum() {
format!("{}", field.index())
} else {
- format!("{}", def.struct_variant().fields[field.index()].name)
+ format!("{}", def.non_enum_variant().fields[field.index()].name)
},
ty::TyTuple(_, _) => format!("{}", field.index()),
ty::TyRef(_, tnm) | ty::TyRawPtr(tnm) => {
use dot;
use dot::IntoCow;
-use std::fs::File;
+use std::fs;
use std::io;
use std::io::prelude::*;
use std::marker::PhantomData;
dot::render(&g, &mut v)?;
debug!("print_borrowck_graph_to path: {} node_id: {}",
path.display(), mbcx.node_id);
- File::create(path).and_then(|mut f| f.write_all(&v))
+ fs::write(path, v)
}
pub type Node = BasicBlock;
miri_place = ecx.place_downcast(miri_place, variant).unwrap();
&def.variants[variant]
} else {
- def.struct_variant()
+ def.non_enum_variant()
};
let vec = match ctfe {
ConstVal::Aggregate(Struct(v)) => v,
}
}
- if log_enabled!(::log::LogLevel::Trace) {
+ if log_enabled!(::log::Level::Trace) {
self.dump_local(dest);
}
}
};
- if log_enabled!(::log::LogLevel::Trace) {
+ if log_enabled!(::log::Level::Trace) {
self.dump_local(place);
}
#![feature(core_intrinsics)]
#![feature(decl_macro)]
#![feature(dyn_trait)]
+#![feature(fs_read_write)]
#![feature(i128_type)]
#![feature(inclusive_range_syntax)]
#![feature(inclusive_range)]
CustomCoerceUnsized::Struct(i) => i
};
- let source_fields = &source_adt_def.struct_variant().fields;
- let target_fields = &target_adt_def.struct_variant().fields;
+ let source_fields = &source_adt_def.non_enum_variant().fields;
+ let target_fields = &target_adt_def.non_enum_variant().fields;
assert!(coerce_index < source_fields.len() &&
source_fields.len() == target_fields.len());
use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::session::config::OptLevel;
-use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::subst::{Subst, Substs};
+use rustc::ty::subst::Substs;
use syntax::ast;
use syntax::attr::{self, InlineAttr};
use std::fmt::{self, Write};
MonoItem::GlobalAsm(..) => return true
};
- let predicates = tcx.predicates_of(def_id).predicates.subst(tcx, substs);
- traits::normalize_and_test_predicates(tcx, predicates)
+ tcx.substitute_normalize_and_test_predicates((def_id, &substs))
}
fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
}
// Anything we can't find a proper codegen unit for goes into this.
-const FALLBACK_CODEGEN_UNIT: &'static str = "__rustc_fallback_codegen_unit";
+fn fallback_cgu_name(tcx: TyCtxt) -> InternedString {
+ const FALLBACK_CODEGEN_UNIT: &'static str = "__rustc_fallback_codegen_unit";
+
+ if tcx.sess.opts.debugging_opts.human_readable_cgu_names {
+ Symbol::intern(FALLBACK_CODEGEN_UNIT).as_str()
+ } else {
+ Symbol::intern(&CodegenUnit::mangle_name(FALLBACK_CODEGEN_UNIT)).as_str()
+ }
+}
+
pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
trans_items: I,
let codegen_unit_name = match characteristic_def_id {
Some(def_id) => compute_codegen_unit_name(tcx, def_id, is_volatile),
- None => Symbol::intern(FALLBACK_CODEGEN_UNIT).as_str(),
+ None => fallback_cgu_name(tcx),
};
let make_codegen_unit = || {
// always ensure we have at least one CGU; otherwise, if we have a
// crate with just types (for example), we could wind up with no CGU
if codegen_units.is_empty() {
- let codegen_unit_name = Symbol::intern(FALLBACK_CODEGEN_UNIT).as_str();
+ let codegen_unit_name = fallback_cgu_name(tcx);
codegen_units.insert(codegen_unit_name.clone(),
CodegenUnit::new(codegen_unit_name.clone()));
}
// Unfortunately we cannot just use the `ty::item_path` infrastructure here
// because we need paths to modules and the DefIds of those are not
// available anymore for external items.
- let mut mod_path = String::with_capacity(64);
+ let mut cgu_name = String::with_capacity(64);
let def_path = tcx.def_path(def_id);
- mod_path.push_str(&tcx.crate_name(def_path.krate).as_str());
+ cgu_name.push_str(&tcx.crate_name(def_path.krate).as_str());
for part in tcx.def_path(def_id)
.data
_ => false,
}
}) {
- mod_path.push_str("-");
- mod_path.push_str(&part.data.as_interned_str());
+ cgu_name.push_str("-");
+ cgu_name.push_str(&part.data.as_interned_str());
}
if volatile {
- mod_path.push_str(".volatile");
+ cgu_name.push_str(".volatile");
}
- return Symbol::intern(&mod_path[..]).as_str();
+ let cgu_name = if tcx.sess.opts.debugging_opts.human_readable_cgu_names {
+ cgu_name
+ } else {
+ CodegenUnit::mangle_name(&cgu_name)
+ };
+
+ Symbol::intern(&cgu_name[..]).as_str()
}
fn numbered_codegen_unit_name(crate_name: &str, index: usize) -> InternedString {
return_qualif: Option<Qualif>,
qualif: Qualif,
const_fn_arg_vars: BitVector,
- local_needs_drop: IndexVec<Local, Option<Span>>,
temp_promotion_state: IndexVec<Local, TempState>,
promotion_candidates: Vec<Candidate>
}
let mut rpo = traversal::reverse_postorder(mir);
let temps = promote_consts::collect_temps(mir, &mut rpo);
rpo.reset();
+
+ let param_env = tcx.param_env(def_id);
+
+ let mut temp_qualif = IndexVec::from_elem(None, &mir.local_decls);
+ for arg in mir.args_iter() {
+ let mut qualif = Qualif::NEEDS_DROP;
+ qualif.restrict(mir.local_decls[arg].ty, tcx, param_env);
+ temp_qualif[arg] = Some(qualif);
+ }
+
Qualifier {
mode,
span: mir.span,
mir,
rpo,
tcx,
- param_env: tcx.param_env(def_id),
- temp_qualif: IndexVec::from_elem(None, &mir.local_decls),
+ param_env,
+ temp_qualif,
return_qualif: None,
qualif: Qualif::empty(),
const_fn_arg_vars: BitVector::new(mir.local_decls.len()),
- local_needs_drop: IndexVec::from_elem(None, &mir.local_decls),
temp_promotion_state: temps,
promotion_candidates: vec![]
}
return;
}
- // When initializing a local, record whether the *value* being
- // stored in it needs dropping, which it may not, even if its
- // type does, e.g. `None::<String>`.
- if let Place::Local(local) = *dest {
- if qualif.intersects(Qualif::NEEDS_DROP) {
- self.local_needs_drop[local] = Some(self.span);
- }
- }
-
match *dest {
Place::Local(index) if self.mir.local_kind(index) == LocalKind::Temp => {
debug!("store to temp {:?}", index);
&local: &Local,
_: PlaceContext<'tcx>,
_: Location) {
- match self.mir.local_kind(local) {
+ let kind = self.mir.local_kind(local);
+ match kind {
LocalKind::ReturnPointer => {
self.not_const();
}
- LocalKind::Arg => {
- self.add(Qualif::FN_ARGUMENT);
- }
LocalKind::Var => {
self.add(Qualif::NOT_CONST);
}
+ LocalKind::Arg |
LocalKind::Temp => {
+ if let LocalKind::Arg = kind {
+ self.add(Qualif::FN_ARGUMENT);
+ }
+
if !self.temp_promotion_state[local].is_promotable() {
self.add(Qualif::NOT_PROMOTABLE);
}
fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
match *operand {
- Operand::Copy(ref place) |
- Operand::Move(ref place) => {
+ Operand::Copy(_) |
+ Operand::Move(_) => {
self.nest(|this| {
this.super_operand(operand, location);
this.try_consume();
});
// Mark the consumed locals to indicate later drops are noops.
- if let Place::Local(local) = *place {
- self.local_needs_drop[local] = None;
+ if let Operand::Move(Place::Local(local)) = *operand {
+ self.temp_qualif[local] = self.temp_qualif[local].map(|q|
+ q - Qualif::NEEDS_DROP
+ );
}
}
Operand::Constant(ref constant) => {
// HACK(eddyb) Emulate a bit of dataflow analysis,
// conservatively, that drop elaboration will do.
let needs_drop = if let Place::Local(local) = *place {
- self.local_needs_drop[local]
+ if self.temp_qualif[local].map_or(true, |q| q.intersects(Qualif::NEEDS_DROP)) {
+ Some(self.mir.local_decls[local].source_info.span)
+ } else {
+ None
+ }
} else {
- None
+ Some(self.span)
};
if let Some(span) = needs_drop {
crate-type = ["dylib"]
[dependencies]
-log = "0.3"
+log = "0.4"
rustc = { path = "../librustc" }
rustc_const_eval = { path = "../librustc_const_eval" }
rustc_const_math = { path = "../librustc_const_math" }
test = false
[dependencies]
-log = "0.3"
+log = "0.4"
syntax = { path = "../libsyntax" }
rustc = { path = "../librustc" }
arena = { path = "../libarena" }
// Disallow `use $crate;`
if source.name == keywords::DollarCrate.name() && path.segments.len() == 1 {
- let crate_root = self.resolve_crate_root(source.ctxt);
+ let crate_root = self.resolve_crate_root(source.ctxt, true);
let crate_name = match crate_root.kind {
ModuleKind::Def(_, name) => name,
ModuleKind::Block(..) => unreachable!(),
use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
use syntax::codemap::{dummy_spanned, respan};
-use syntax::ext::hygiene::{Mark, SyntaxContext};
+use syntax::ext::hygiene::{Mark, MarkKind, SyntaxContext};
use syntax::ast::{self, Name, NodeId, Ident, SpannedIdent, FloatTy, IntTy, UintTy};
use syntax::ext::base::SyntaxExtension;
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
result
}
- fn resolve_crate_root(&mut self, mut ctxt: SyntaxContext) -> Module<'a> {
- let module = match ctxt.adjust(Mark::root()) {
+ fn resolve_crate_root(&mut self, mut ctxt: SyntaxContext, legacy: bool) -> Module<'a> {
+ let mark = if legacy {
+ // When resolving `$crate` from a `macro_rules!` invoked in a `macro`,
+ // we don't want to pretend that the `macro_rules!` definition is in the `macro`
+ // as described in `SyntaxContext::apply_mark`, so we ignore prepended modern marks.
+ ctxt.marks().into_iter().find(|&mark| mark.kind() != MarkKind::Modern)
+ } else {
+ ctxt = ctxt.modern();
+ ctxt.adjust(Mark::root())
+ };
+ let module = match mark {
Some(def) => self.macro_def_scope(def),
None => return self.graph_root,
};
let msg = "There are too many initial `super`s.".to_string();
return PathResult::Failed(ident.span, msg, false);
}
+ } else if i == 0 && ns == TypeNS && name == keywords::Extern.name() {
+ continue;
}
allow_super = false;
(i == 1 && name == keywords::Crate.name() &&
path[0].node.name == keywords::CrateRoot.name()) {
// `::a::b` or `::crate::a::b`
- module = Some(self.resolve_crate_root(ident.node.ctxt.modern()));
+ module = Some(self.resolve_crate_root(ident.node.ctxt, false));
continue
} else if i == 0 && name == keywords::DollarCrate.name() {
// `$crate::a::b`
- module = Some(self.resolve_crate_root(ident.node.ctxt));
- continue
- } else if i == 1 && self.session.features.borrow().extern_absolute_paths &&
- path[0].node.name == keywords::CrateRoot.name() &&
- !token::Ident(ident.node).is_path_segment_keyword() {
- // `::extern_crate::a::b`
- let crate_id = self.crate_loader.resolve_crate_from_path(name, ident.span);
- let crate_root =
- self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
- self.populate_module_if_necessary(crate_root);
- module = Some(crate_root);
+ module = Some(self.resolve_crate_root(ident.node.ctxt, true));
continue
+ } else if i == 1 && !token::Ident(ident.node).is_path_segment_keyword() {
+ let prev_name = path[0].node.name;
+ if prev_name == keywords::Extern.name() ||
+ prev_name == keywords::CrateRoot.name() &&
+ self.session.features.borrow().extern_absolute_paths {
+ // `::extern_crate::a::b`
+ let crate_id = self.crate_loader.resolve_crate_from_path(name, ident.span);
+ let crate_root =
+ self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
+ self.populate_module_if_necessary(crate_root);
+ module = Some(crate_root);
+ continue
+ }
}
}
name == keywords::SelfValue.name() && i != 0 ||
name == keywords::SelfType.name() && i != 0 ||
name == keywords::Super.name() && i != 0 ||
+ name == keywords::Extern.name() && i != 0 ||
name == keywords::Crate.name() && i != 1 &&
path[0].node.name != keywords::CrateRoot.name() {
let name_str = if name == keywords::CrateRoot.name() {
use Namespace::{self, MacroNS};
use build_reduced_graph::BuildReducedGraphVisitor;
use resolve_imports::ImportResolver;
-use rustc_data_structures::indexed_vec::Idx;
-use rustc::hir::def_id::{DefId, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefIndex};
+use rustc::hir::def_id::{DefId, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefIndex,
+ DefIndexAddressSpace};
use rustc::hir::def::{Def, Export};
use rustc::hir::map::{self, DefCollector};
use rustc::{ty, lint};
let ident = path.segments[0].identifier;
if ident.name == keywords::DollarCrate.name() {
path.segments[0].identifier.name = keywords::CrateRoot.name();
- let module = self.0.resolve_crate_root(ident.ctxt);
+ let module = self.0.resolve_crate_root(ident.ctxt, true);
if !module.is_local() {
let span = path.segments[0].span;
path.segments.insert(1, match module.kind {
fn add_builtin(&mut self, ident: ast::Ident, ext: Rc<SyntaxExtension>) {
let def_id = DefId {
krate: BUILTIN_MACROS_CRATE,
- index: DefIndex::new(self.macro_map.len()),
+ index: DefIndex::from_array_index(self.macro_map.len(),
+ DefIndexAddressSpace::Low),
};
let kind = ext.kind();
self.macro_map.insert(def_id, ext);
self.current_module = directive.parent;
let ImportDirective { ref module_path, span, .. } = *directive;
- // Extern crate mode for absolute paths needs some
- // special support for single-segment imports.
- let extern_absolute_paths = self.session.features.borrow().extern_absolute_paths;
- if module_path.len() == 1 && module_path[0].node.name == keywords::CrateRoot.name() {
+ // FIXME: Last path segment is treated specially in import resolution, so extern crate
+ // mode for absolute paths needs some special support for single-segment imports.
+ if module_path.len() == 1 && (module_path[0].node.name == keywords::CrateRoot.name() ||
+ module_path[0].node.name == keywords::Extern.name()) {
+ let is_extern = module_path[0].node.name == keywords::Extern.name() ||
+ self.session.features.borrow().extern_absolute_paths;
match directive.subclass {
- GlobImport { .. } if extern_absolute_paths => {
+ GlobImport { .. } if is_extern => {
return Some((directive.span,
"cannot glob-import all possible crates".to_string()));
}
SingleImport { source, target, .. } => {
- let crate_root = if source.name == keywords::Crate.name() {
+ let crate_root = if source.name == keywords::Crate.name() &&
+ module_path[0].node.name != keywords::Extern.name() {
if target.name == keywords::Crate.name() {
return Some((directive.span,
"crate root imports need to be explicitly named: \
`use crate as name;`".to_string()));
} else {
- Some(self.resolve_crate_root(source.ctxt.modern()))
+ Some(self.resolve_crate_root(source.ctxt.modern(), false))
}
- } else if extern_absolute_paths &&
- !token::Ident(source).is_path_segment_keyword() {
+ } else if is_extern && !token::Ident(source).is_path_segment_keyword() {
let crate_id =
self.crate_loader.resolve_crate_from_path(source.name, directive.span);
let crate_root =
crate-type = ["dylib"]
[dependencies]
-log = "0.3"
+log = "0.4"
rustc = { path = "../librustc" }
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_typeck = { path = "../librustc_typeck" }
root_item: &'l ast::Item,
prefix: &ast::Path) {
let path = &use_tree.prefix;
- let access = access_from!(self.save_ctxt, root_item);
+
+ // The access is calculated using the current tree ID, but with the root tree's visibility
+ // (since nested trees don't have their own visibility).
+ let access = Access {
+ public: root_item.vis == ast::Visibility::Public,
+ reachable: self.save_ctxt.analysis.access_levels.is_reachable(id),
+ };
// The parent def id of a given use tree is always the enclosing item.
let parent = self.save_ctxt.tcx.hir.opt_local_def_id(id)
if !self.span.filter_generated(sub_span, ex.span) {
let span =
self.span_from_span(sub_span.expect("No span found for var ref"));
+ let ref_id =
+ ::id_from_def_id(def.non_enum_variant().fields[idx.node].did);
self.dumper.dump_ref(Ref {
kind: RefKind::Variable,
span,
- ref_id: ::id_from_def_id(def.struct_variant().fields[idx.node].did),
+ ref_id,
});
}
}
};
match self.tables.expr_ty_adjusted(&hir_node).sty {
ty::TyAdt(def, _) if !def.is_enum() => {
- let f = def.struct_variant().field_named(ident.node.name);
+ let f = def.non_enum_variant().field_named(ident.node.name);
let sub_span = self.span_utils.span_for_last_ident(expr.span);
filter!(self.span_utils, sub_span, expr.span, None);
let span = self.span_from_span(sub_span.unwrap());
config: Option<Config>,
mut handler: H,
) {
- let _ignore = tcx.dep_graph.in_ignore();
+ tcx.dep_graph.with_ignore(|| {
+ assert!(analysis.glob_map.is_some());
- assert!(analysis.glob_map.is_some());
+ info!("Dumping crate {}", cratename);
- info!("Dumping crate {}", cratename);
-
- let save_ctxt = SaveContext {
- tcx,
- tables: &ty::TypeckTables::empty(None),
- analysis,
- span_utils: SpanUtils::new(&tcx.sess),
- config: find_config(config),
- };
+ let save_ctxt = SaveContext {
+ tcx,
+ tables: &ty::TypeckTables::empty(None),
+ analysis,
+ span_utils: SpanUtils::new(&tcx.sess),
+ config: find_config(config),
+ };
- handler.save(save_ctxt, krate, cratename)
+ handler.save(save_ctxt, krate, cratename)
+ })
}
fn find_config(supplied: Option<Config>) -> Config {
fn id_from_def_id(id: DefId) -> rls_data::Id {
rls_data::Id {
krate: id.krate.as_u32(),
- index: id.index.as_u32(),
+ index: id.index.as_raw_u32(),
}
}
bitflags = "1.0"
flate2 = "1.0"
jobserver = "0.1.5"
-log = "0.3"
+log = "0.4"
num_cpus = "1.0"
rustc = { path = "../librustc" }
rustc-demangle = "0.1.4"
//! perturb the reuse results.
use rustc::dep_graph::{DepNode, DepConstructor};
+use rustc::mir::mono::CodegenUnit;
use rustc::ty::TyCtxt;
use syntax::ast;
+use syntax_pos::symbol::Symbol;
use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_TRANSLATED};
const MODULE: &'static str = "module";
enum Disposition { Reused, Translated }
pub(crate) fn assert_module_sources<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
- let _ignore = tcx.dep_graph.in_ignore();
-
- if tcx.sess.opts.incremental.is_none() {
- return;
- }
+ tcx.dep_graph.with_ignore(|| {
+ if tcx.sess.opts.incremental.is_none() {
+ return;
+ }
- let ams = AssertModuleSource { tcx };
- for attr in &tcx.hir.krate().attrs {
- ams.check_attr(attr);
- }
+ let ams = AssertModuleSource { tcx };
+ for attr in &tcx.hir.krate().attrs {
+ ams.check_attr(attr);
+ }
+ })
}
struct AssertModuleSource<'a, 'tcx: 'a> {
}
let mname = self.field(attr, MODULE);
+ let mangled_cgu_name = CodegenUnit::mangle_name(&mname.as_str());
+ let mangled_cgu_name = Symbol::intern(&mangled_cgu_name).as_str();
let dep_node = DepNode::new(self.tcx,
- DepConstructor::CompileCodegenUnit(mname.as_str()));
+ DepConstructor::CompileCodegenUnit(mangled_cgu_name));
if let Some(loaded_from_cache) = self.tcx.dep_graph.was_loaded_from_cache(&dep_node) {
match (disposition, loaded_from_cache) {
// The version number this compiler will write to bytecode objects in rlibs
pub const RLIB_BYTECODE_OBJECT_VERSION: u8 = 2;
-pub const RLIB_BYTECODE_EXTENSION: &str = "bytecode.encoded";
+pub const RLIB_BYTECODE_EXTENSION: &str = "bc.z";
pub fn encode(identifier: &str, bytecode: &[u8]) -> Vec<u8> {
let mut encoded = Vec::new();
fn emit_metadata<'a>(sess: &'a Session, trans: &CrateTranslation, tmpdir: &TempDir)
-> PathBuf {
let out_filename = tmpdir.path().join(METADATA_FILENAME);
- let result = fs::File::create(&out_filename).and_then(|mut f| {
- f.write_all(&trans.metadata.raw_data)
- });
+ let result = fs::write(&out_filename, &trans.metadata.raw_data);
if let Err(e) = result {
sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
use std::any::Any;
use std::ffi::{CString, CStr};
-use std::fs::{self, File};
-use std::io;
-use std::io::{Read, Write};
+use std::fs;
+use std::io::{self, Write};
use std::mem;
use std::path::{Path, PathBuf};
use std::str;
timeline.record("make-bc");
if write_bc {
- if let Err(e) = File::create(&bc_out).and_then(|mut f| f.write_all(data)) {
+ if let Err(e) = fs::write(&bc_out, data) {
diag_handler.err(&format!("failed to write bytecode: {}", e));
}
timeline.record("write-bc");
if config.emit_bc_compressed {
let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION);
let data = bytecode::encode(&mtrans.llmod_id, data);
- if let Err(e) = File::create(&dst).and_then(|mut f| f.write_all(&data)) {
+ if let Err(e) = fs::write(&dst, data) {
diag_handler.err(&format!("failed to write bytecode: {}", e));
}
timeline.record("compress-bc");
object: &Path) {
use rustc_binaryen::{Module, ModuleOptions};
- let input = File::open(&assembly).and_then(|mut f| {
- let mut contents = Vec::new();
- f.read_to_end(&mut contents)?;
+ let input = fs::read(&assembly).and_then(|contents| {
Ok(CString::new(contents)?)
});
let mut options = ModuleOptions::new();
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
});
let err = assembled.and_then(|binary| {
- File::create(&object).and_then(|mut f| f.write_all(binary.data()))
+ fs::write(&object, binary.data())
});
if let Err(e) = err {
handler.err(&format!("failed to run binaryen assembler: {}", e));
let mut name = String::with_capacity(prefix.len() + 6);
name.push_str(prefix);
name.push_str(".");
- base_n::push_str(idx as u64, base_n::ALPHANUMERIC_ONLY, &mut name);
+ base_n::push_str(idx as u128, base_n::ALPHANUMERIC_ONLY, &mut name);
name
}
let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
let (struct_def_id, variant) = match struct_type.sty {
- ty::TyAdt(def, _) => (def.did, def.struct_variant()),
+ ty::TyAdt(def, _) => (def.did, def.non_enum_variant()),
_ => bug!("prepare_struct_metadata on a non-ADT")
};
let union_name = compute_debuginfo_type_name(cx, union_type, false);
let (union_def_id, variant) = match union_type.sty {
- ty::TyAdt(def, _) => (def.did, def.struct_variant()),
+ ty::TyAdt(def, _) => (def.did, def.non_enum_variant()),
_ => bug!("prepare_union_metadata on a non-ADT")
};
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(custom_attribute)]
+#![feature(fs_read_write)]
#![allow(unused_attributes)]
#![feature(i128_type)]
#![feature(i128)]
use back::bytecode::RLIB_BYTECODE_EXTENSION;
pub use metadata::LlvmMetadataLoader;
-pub use llvm_util::{init, target_features, print_version, print_passes, print, enable_llvm_debug};
+pub use llvm_util::{init, target_features, print_version, print_passes, print};
use std::any::Any;
use std::path::PathBuf;
}
}
}
-
-pub fn enable_llvm_debug() {
- unsafe { llvm::LLVMRustSetDebug(1); }
-}
return;
}
- let _ignore = tcx.dep_graph.in_ignore();
- let mut visitor = SymbolNamesTest { tcx: tcx };
- // FIXME(#37712) could use ItemLikeVisitor if trait items were item-like
- tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
+ tcx.dep_graph.with_ignore(|| {
+ let mut visitor = SymbolNamesTest { tcx: tcx };
+ // FIXME(#37712) could use ItemLikeVisitor if trait items were item-like
+ tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
+ })
}
struct SymbolNamesTest<'a, 'tcx:'a> {
[dependencies]
ar = "0.3.0"
flate2 = "1.0"
-log = "0.3"
+log = "0.4"
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
test = false
[dependencies]
-log = "0.3"
+log = "0.4"
syntax = { path = "../libsyntax" }
arena = { path = "../libarena" }
fmt_macros = { path = "../libfmt_macros" }
use super::method::MethodCallee;
use rustc::infer::InferOk;
+use rustc::session::DiagnosticMessageId;
use rustc::traits;
use rustc::ty::{self, Ty, TraitRef};
use rustc::ty::{ToPredicate, TypeFoldable};
return Some((self.cur_ty, 0));
}
- if self.steps.len() == tcx.sess.recursion_limit.get() {
+ if self.steps.len() >= tcx.sess.recursion_limit.get() {
// We've reached the recursion limit, error gracefully.
let suggested_limit = tcx.sess.recursion_limit.get() * 2;
- struct_span_err!(tcx.sess,
- self.span,
- E0055,
- "reached the recursion limit while auto-dereferencing {:?}",
- self.cur_ty)
- .span_label(self.span, "deref recursion limit reached")
- .help(&format!(
- "consider adding a `#[recursion_limit=\"{}\"]` attribute to your crate",
+ let msg = format!("reached the recursion limit while auto-dereferencing {:?}",
+ self.cur_ty);
+ let error_id = (DiagnosticMessageId::ErrorId(55), Some(self.span), msg.clone());
+ let fresh = tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id);
+ if fresh {
+ struct_span_err!(tcx.sess,
+ self.span,
+ E0055,
+ "reached the recursion limit while auto-dereferencing {:?}",
+ self.cur_ty)
+ .span_label(self.span, "deref recursion limit reached")
+ .help(&format!(
+ "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
suggested_limit))
- .emit();
+ .emit();
+ }
return None;
}
ty::TyDynamic(ref tty, ..) =>
Some(PointerKind::Vtable(tty.principal().map(|p| p.def_id()))),
ty::TyAdt(def, substs) if def.is_struct() => {
- match def.struct_variant().fields.last() {
+ match def.non_enum_variant().fields.last() {
None => Some(PointerKind::Thin),
Some(f) => {
let field_ty = self.field_ty(span, f, substs);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+use std::iter;
use check::FnCtxt;
use rustc::infer::InferOk;
if let Some((msg, suggestion)) = self.check_ref(expr, checked_ty, expected) {
err.span_suggestion(expr.span, msg, suggestion);
} else {
- let mode = probe::Mode::MethodCall;
- let suggestions = self.probe_for_return_type(syntax_pos::DUMMY_SP,
- mode,
- expected,
- checked_ty,
- ast::DUMMY_NODE_ID);
- if suggestions.len() > 0 {
- err.help(&format!("here are some functions which \
- might fulfill your needs:\n{}",
- self.get_best_match(&suggestions).join("\n")));
+ let methods = self.get_conversion_methods(expected, checked_ty);
+ if let Ok(expr_text) = self.tcx.sess.codemap().span_to_snippet(expr.span) {
+ let suggestions = iter::repeat(expr_text).zip(methods.iter())
+ .map(|(receiver, method)| format!("{}.{}()", receiver, method.name))
+ .collect::<Vec<_>>();
+ if !suggestions.is_empty() {
+ err.span_suggestions(expr.span,
+ "try using a conversion method",
+ suggestions);
+ }
}
}
(expected, Some(err))
}
- fn format_method_suggestion(&self, method: &AssociatedItem) -> String {
- format!("- .{}({})",
- method.name,
- if self.has_no_input_arg(method) {
- ""
- } else {
- "..."
- })
- }
-
- fn display_suggested_methods(&self, methods: &[AssociatedItem]) -> Vec<String> {
- methods.iter()
- .take(5)
- .map(|method| self.format_method_suggestion(&*method))
- .collect::<Vec<String>>()
- }
+ fn get_conversion_methods(&self, expected: Ty<'tcx>, checked_ty: Ty<'tcx>)
+ -> Vec<AssociatedItem> {
+ let mut methods = self.probe_for_return_type(syntax_pos::DUMMY_SP,
+ probe::Mode::MethodCall,
+ expected,
+ checked_ty,
+ ast::DUMMY_NODE_ID);
+ methods.retain(|m| {
+ self.has_no_input_arg(m) &&
+ self.tcx.get_attrs(m.def_id).iter()
+ // This special internal attribute is used to whitelist
+ // "identity-like" conversion methods to be suggested here.
+ //
+ // FIXME (#46459 and #46460): ideally
+ // `std::convert::Into::into` and `std::borrow:ToOwned` would
+ // also be `#[rustc_conversion_suggestion]`, if not for
+ // method-probing false-positives and -negatives (respectively).
+ //
+ // FIXME? Other potential candidate methods: `as_ref` and
+ // `as_mut`?
+ .find(|a| a.check_name("rustc_conversion_suggestion")).is_some()
+ });
- fn get_best_match(&self, methods: &[AssociatedItem]) -> Vec<String> {
- let no_argument_methods: Vec<_> =
- methods.iter()
- .filter(|ref x| self.has_no_input_arg(&*x))
- .map(|x| x.clone())
- .collect();
- if no_argument_methods.len() > 0 {
- self.display_suggested_methods(&no_argument_methods)
- } else {
- self.display_suggested_methods(&methods)
- }
+ methods
}
// This function checks if the method isn't static and takes other arguments than `self`.
scope_expr_id);
let method_names =
self.probe_op(span, mode, None, Some(return_type), IsSuggestion(true),
- self_ty, scope_expr_id, ProbeScope::TraitsInScope,
+ self_ty, scope_expr_id, ProbeScope::AllTraits,
|probe_cx| Ok(probe_cx.candidate_method_names()))
.unwrap_or(vec![]);
method_names
self.probe_op(
span, mode, Some(method_name), Some(return_type),
IsSuggestion(true), self_ty, scope_expr_id,
- ProbeScope::TraitsInScope, |probe_cx| probe_cx.pick()
+ ProbeScope::AllTraits, |probe_cx| probe_cx.pick()
).ok().map(|pick| pick.item)
})
.collect()
}
};
let mut err = if !actual.references_error() {
- struct_span_err!(
- tcx.sess,
- span,
- E0599,
- "no {} named `{}` found for type `{}` in the current scope",
- type_str,
- item_name,
- ty_string
- )
+ // Suggest clamping down the type if the method that is being attempted to
+ // be used exists at all, and the type is an ambiuous numeric type
+ // ({integer}/{float}).
+ let mut candidates = all_traits(self.tcx)
+ .filter(|info| {
+ self.associated_item(info.def_id, item_name, Namespace::Value).is_some()
+ });
+ if let (true, false, Some(expr), Some(_)) = (actual.is_numeric(),
+ actual.has_concrete_skeleton(),
+ rcvr_expr,
+ candidates.next()) {
+ let mut err = struct_span_err!(
+ tcx.sess,
+ span,
+ E0689,
+ "can't call {} `{}` on ambiguous numeric type `{}`",
+ type_str,
+ item_name,
+ ty_string
+ );
+ let concrete_type = if actual.is_integral() {
+ "i32"
+ } else {
+ "f32"
+ };
+ match expr.node {
+ hir::ExprLit(_) => { // numeric literal
+ let snippet = tcx.sess.codemap().span_to_snippet(expr.span)
+ .unwrap_or("<numeric literal>".to_string());
+ // FIXME: use the literal for missing snippet
+
+ err.span_suggestion(expr.span,
+ &format!("you must specify a concrete type for \
+ this numeric value, like `{}`",
+ concrete_type),
+ format!("{}_{}",
+ snippet,
+ concrete_type));
+ }
+ hir::ExprPath(ref qpath) => { // local binding
+ if let &hir::QPath::Resolved(_, ref path) = &qpath {
+ if let hir::def::Def::Local(node_id) = path.def {
+ let span = tcx.hir.span(node_id);
+ let snippet = tcx.sess.codemap().span_to_snippet(span)
+ .unwrap();
+ err.span_suggestion(span,
+ &format!("you must specify a type for \
+ this binding, like `{}`",
+ concrete_type),
+ format!("{}: {}",
+ snippet,
+ concrete_type));
+ }
+ }
+ }
+ _ => {}
+ }
+ err.emit();
+ return;
+ } else {
+ struct_span_err!(
+ tcx.sess,
+ span,
+ E0599,
+ "no {} named `{}` found for type `{}` in the current scope",
+ type_str,
+ item_name,
+ ty_string
+ )
+ }
} else {
tcx.sess.diagnostic().struct_dummy()
};
for (ty, _) in self.autoderef(span, rcvr_ty) {
match ty.sty {
ty::TyAdt(def, substs) if !def.is_enum() => {
- if let Some(field) = def.struct_variant()
+ if let Some(field) = def.non_enum_variant()
.find_field_named(item_name) {
let snippet = tcx.sess.codemap().span_to_snippet(expr.span);
let expr_string = match snippet {
bound_list));
}
- self.suggest_traits_to_import(&mut err,
- span,
- rcvr_ty,
- item_name,
- rcvr_expr,
- out_of_scope_traits);
+ if actual.is_numeric() && actual.is_fresh() {
+
+ } else {
+ self.suggest_traits_to_import(&mut err,
+ span,
+ rcvr_ty,
+ item_name,
+ rcvr_expr,
+ out_of_scope_traits);
+ }
if let Some(lev_candidate) = lev_candidate {
err.help(&format!("did you mean `{}`?", lev_candidate.name));
let t = tcx.type_of(def_id);
match t.sty {
ty::TyAdt(def, substs) if def.is_struct() => {
- let fields = &def.struct_variant().fields;
+ let fields = &def.non_enum_variant().fields;
if fields.is_empty() {
span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
return;
}
// push struct def_id before checking fields
stack.push(def_id);
- for field in &def.struct_variant().fields {
+ for field in &def.non_enum_variant().fields {
let f = field.ty(tcx, substs);
match f.sty {
ty::TyAdt(def, _) => {
adjusted_ty,
index_ty);
- // First, try built-in indexing.
- match (adjusted_ty.builtin_index(), &index_ty.sty) {
- (Some(ty), &ty::TyUint(ast::UintTy::Usize)) |
- (Some(ty), &ty::TyInfer(ty::IntVar(_))) => {
- debug!("try_index_step: success, using built-in indexing");
- let adjustments = autoderef.adjust_steps(lvalue_pref);
- self.apply_adjustments(base_expr, adjustments);
- return Some((self.tcx.types.usize, ty));
- }
- _ => {}
- }
-
for &unsize in &[false, true] {
let mut self_ty = adjusted_ty;
if unsize {
debug!("struct named {:?}", base_t);
let (ident, def_scope) =
self.tcx.adjust(field.node, base_def.did, self.body_id);
- let fields = &base_def.struct_variant().fields;
+ let fields = &base_def.non_enum_variant().fields;
if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
let field_ty = self.field_ty(expr.span, field, substs);
if field.vis.is_accessible_from(def_scope, self.tcx) {
match expr_t.sty {
ty::TyAdt(def, _) if !def.is_enum() => {
if let Some(suggested_field_name) =
- Self::suggest_field_name(def.struct_variant(), field, vec![]) {
+ Self::suggest_field_name(def.non_enum_variant(), field, vec![]) {
err.span_label(field.span,
format!("did you mean `{}`?", suggested_field_name));
} else {
err.span_label(field.span, "unknown field");
- let struct_variant_def = def.struct_variant();
+ let struct_variant_def = def.non_enum_variant();
let field_names = self.available_field_names(struct_variant_def);
if !field_names.is_empty() {
err.note(&format!("available fields are: {}",
while let Some((base_t, _)) = autoderef.next() {
let field = match base_t.sty {
ty::TyAdt(base_def, substs) if base_def.is_struct() => {
- tuple_like = base_def.struct_variant().ctor_kind == CtorKind::Fn;
+ tuple_like = base_def.non_enum_variant().ctor_kind == CtorKind::Fn;
if !tuple_like { continue }
debug!("tuple struct named {:?}", base_t);
};
let (ident, def_scope) =
self.tcx.adjust_ident(ident, base_def.did, self.body_id);
- let fields = &base_def.struct_variant().fields;
+ let fields = &base_def.non_enum_variant().fields;
if let Some(field) = fields.iter().find(|f| f.name.to_ident() == ident) {
let field_ty = self.field_ty(expr.span, field, substs);
if field.vis.is_accessible_from(def_scope, self.tcx) {
Def::AssociatedTy(..) | Def::SelfTy(..) => {
match ty.sty {
ty::TyAdt(adt, substs) if !adt.is_enum() => {
- Some((adt.struct_variant(), adt.did, substs))
+ Some((adt.non_enum_variant(), adt.did, substs))
}
_ => None,
}
self.check_expr_has_type_or_error(base_expr, struct_ty);
match struct_ty.sty {
ty::TyAdt(adt, substs) if adt.is_struct() => {
- let fru_field_types = adt.struct_variant().fields.iter().map(|f| {
+ let fru_field_types = adt.non_enum_variant().fields.iter().map(|f| {
self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
}).collect();
}
hir::ItemStruct(ref struct_def, ref ast_generics) => {
self.check_type_defn(item, false, |fcx| {
- vec![fcx.struct_variant(struct_def)]
+ vec![fcx.non_enum_variant(struct_def)]
});
self.check_variances_for_type_defn(item, ast_generics);
}
hir::ItemUnion(ref struct_def, ref ast_generics) => {
self.check_type_defn(item, true, |fcx| {
- vec![fcx.struct_variant(struct_def)]
+ vec![fcx.non_enum_variant(struct_def)]
});
self.check_variances_for_type_defn(item, ast_generics);
}
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
- fn struct_variant(&self, struct_def: &hir::VariantData) -> AdtVariant<'tcx> {
+ fn non_enum_variant(&self, struct_def: &hir::VariantData) -> AdtVariant<'tcx> {
let fields =
struct_def.fields().iter()
.map(|field| {
fn enum_variants(&self, enum_def: &hir::EnumDef) -> Vec<AdtVariant<'tcx>> {
enum_def.variants.iter()
- .map(|variant| self.struct_variant(&variant.node.data))
+ .map(|variant| self.non_enum_variant(&variant.node.data))
.collect()
}
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc::infer::InferCtxt;
use rustc::ty::{self, Ty, TyCtxt};
+use rustc::ty::adjustment::{Adjust, Adjustment};
use rustc::ty::fold::{TypeFoldable, TypeFolder};
use rustc::util::nodemap::DefIdSet;
use syntax::ast;
_ => {}
}
}
+
+ // Similar to operators, indexing is always assumed to be overloaded
+ // Here, correct cases where an indexing expression can be simplified
+ // to use builtin indexing because the index type is known to be
+ // usize-ish
+ fn fix_index_builtin_expr(&mut self, e: &hir::Expr) {
+ if let hir::ExprIndex(ref base, ref index) = e.node {
+ let mut tables = self.fcx.tables.borrow_mut();
+
+ match tables.expr_ty_adjusted(&base).sty {
+ // All valid indexing looks like this
+ ty::TyRef(_, ty::TypeAndMut { ty: ref base_ty, .. }) => {
+ let index_ty = tables.expr_ty_adjusted(&index);
+ let index_ty = self.fcx.resolve_type_vars_if_possible(&index_ty);
+
+ if base_ty.builtin_index().is_some()
+ && index_ty == self.fcx.tcx.types.usize {
+ // Remove the method call record
+ tables.type_dependent_defs_mut().remove(e.hir_id);
+ tables.node_substs_mut().remove(e.hir_id);
+
+ tables.adjustments_mut().get_mut(base.hir_id).map(|a| {
+ // Discard the need for a mutable borrow
+ match a.pop() {
+ // Extra adjustment made when indexing causes a drop
+ // of size information - we need to get rid of it
+ // Since this is "after" the other adjustment to be
+ // discarded, we do an extra `pop()`
+ Some(Adjustment { kind: Adjust::Unsize, .. }) => {
+ // So the borrow discard actually happens here
+ a.pop();
+ },
+ _ => {}
+ }
+ });
+ }
+ },
+ // Might encounter non-valid indexes at this point, so there
+ // has to be a fall-through
+ _ => {},
+ }
+ }
+ }
}
+
///////////////////////////////////////////////////////////////////////////
// Impl of Visitor for Resolver
//
fn visit_expr(&mut self, e: &'gcx hir::Expr) {
self.fix_scalar_builtin_expr(e);
+ self.fix_index_builtin_expr(e);
self.visit_node_id(e.span, e.hir_id);
// conversion). This will work out because `U:
// Unsize<V>`, and we have a builtin rule that `*mut
// U` can be coerced to `*mut V` if `U: Unsize<V>`.
- let fields = &def_a.struct_variant().fields;
+ let fields = &def_a.non_enum_variant().fields;
let diff_fields = fields.iter()
.enumerate()
.filter_map(|(i, f)| {
```
"##,
+E0689: r##"
+This error indicates that the numeric value for the method being passed exists
+but the type of the numeric value or binding could not be identified.
+
+The error happens on numeric literals:
+
+```compile_fail,E0689
+2.0.powi(2);
+```
+
+and on numeric bindings without an identified concrete type:
+
+```compile_fail,E0689
+let x = 2.0;
+x.powi(2); // same error as above
+```
+
+Because of this, you must give the numeric literal or binding a type:
+
+```
+let _ = 2.0_f32.powi(2);
+let x: f32 = 2.0;
+let _ = x.powi(2);
+let _ = (2.0 as f32).powi(2);
+```
+"##,
}
register_diagnostics! {
fn build_struct(cx: &DocContext, did: DefId) -> clean::Struct {
let predicates = cx.tcx.predicates_of(did);
- let variant = cx.tcx.adt_def(did).struct_variant();
+ let variant = cx.tcx.adt_def(did).non_enum_variant();
clean::Struct {
struct_type: match variant.ctor_kind {
fn build_union(cx: &DocContext, did: DefId) -> clean::Union {
let predicates = cx.tcx.predicates_of(did);
- let variant = cx.tcx.adt_def(did).struct_variant();
+ let variant = cx.tcx.adt_def(did).non_enum_variant();
clean::Union {
struct_type: doctree::Plain,
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::fs::File;
-use std::io::prelude::*;
+use std::fs;
use std::path::Path;
use std::str;
use html::markdown::{Markdown, RenderType};
pub fn load_string<P: AsRef<Path>>(file_path: P) -> Result<String, LoadStringError> {
let file_path = file_path.as_ref();
- let mut contents = vec![];
- let result = File::open(file_path)
- .and_then(|mut f| f.read_to_end(&mut contents));
- if let Err(e) = result {
- eprintln!("error reading `{}`: {}", file_path.display(), e);
- return Err(LoadStringError::ReadFail);
- }
+ let contents = match fs::read(file_path) {
+ Ok(bytes) => bytes,
+ Err(e) => {
+ eprintln!("error reading `{}`: {}", file_path.display(), e);
+ return Err(LoadStringError::ReadFail);
+ }
+ };
match str::from_utf8(&contents) {
Ok(s) => Ok(s.to_string()),
Err(_) => {
Unknown,
}
-/// Metadata about an implementor of a trait.
-pub struct Implementor {
- pub def_id: DefId,
- pub stability: Option<clean::Stability>,
- pub impl_: clean::Impl,
-}
-
-/// Metadata about implementations for a type.
+/// Metadata about implementations for a type or trait.
#[derive(Clone)]
pub struct Impl {
pub impl_item: clean::Item,
/// When rendering traits, it's often useful to be able to list all
/// implementors of the trait, and this mapping is exactly, that: a mapping
/// of trait ids to the list of known implementors of the trait
- pub implementors: FxHashMap<DefId, Vec<Implementor>>,
+ pub implementors: FxHashMap<DefId, Vec<Impl>>,
/// Cache of where external crate documentation can be found.
pub extern_locations: FxHashMap<CrateNum, (String, PathBuf, ExternalLocation)>,
write(cx.dst.join("main.css"),
include_bytes!("static/styles/main.css"))?;
if let Some(ref css) = cx.shared.css_file_extension {
- let mut content = String::new();
- let css = css.as_path();
- let mut f = try_err!(File::open(css), css);
-
- try_err!(f.read_to_string(&mut content), css);
- let css = cx.dst.join("theme.css");
- let css = css.as_path();
- let mut f = try_err!(File::create(css), css);
- try_err!(write!(f, "{}", &content), css);
+ let out = cx.dst.join("theme.css");
+ try_err!(fs::copy(css, out), css);
}
write(cx.dst.join("normalize.css"),
include_bytes!("static/normalize.css"))?;
// there's no need to emit information about it (there's inlining
// going on). If they're in different crates then the crate defining
// the trait will be interested in our implementation.
- if imp.def_id.krate == did.krate { continue }
+ if imp.impl_item.def_id.krate == did.krate { continue }
// If the implementation is from another crate then that crate
// should add it.
- if !imp.def_id.is_local() { continue }
+ if !imp.impl_item.def_id.is_local() { continue }
have_impls = true;
- write!(implementors, "{},", as_json(&imp.impl_.to_string())).unwrap();
+ write!(implementors, "{},", as_json(&imp.inner_impl().to_string())).unwrap();
}
implementors.push_str("];");
/// Writes the entire contents of a string to a destination, not attempting to
/// catch any errors.
fn write(dst: PathBuf, contents: &[u8]) -> Result<(), Error> {
- Ok(try_err!(try_err!(File::create(&dst), &dst).write_all(contents), &dst))
+ Ok(try_err!(fs::write(&dst, contents), &dst))
}
/// Takes a path to a source file and cleans the path to it. This canonicalizes
return Ok(());
}
- let mut contents = Vec::new();
- File::open(&p).and_then(|mut f| f.read_to_end(&mut contents))?;
-
- let contents = str::from_utf8(&contents).unwrap();
+ let contents = fs::read_string(&p)?;
// Remove the utf-8 BOM if any
let contents = if contents.starts_with("\u{feff}") {
&contents[3..]
} else {
- contents
+ &contents[..]
};
// Create the intermediate directories
if !self.masked_crates.contains(&item.def_id.krate) {
if let Some(did) = i.trait_.def_id() {
if i.for_.def_id().map_or(true, |d| !self.masked_crates.contains(&d.krate)) {
- self.implementors.entry(did).or_insert(vec![]).push(Implementor {
- def_id: item.def_id,
- stability: item.stability.clone(),
- impl_: i.clone(),
+ self.implementors.entry(did).or_insert(vec![]).push(Impl {
+ impl_item: item.clone(),
});
}
}
document(w, cx, it)
}
-fn implementor2item<'a>(cache: &'a Cache, imp : &Implementor) -> Option<&'a clean::Item> {
- if let Some(t_did) = imp.impl_.for_.def_id() {
- if let Some(impl_item) = cache.impls.get(&t_did).and_then(|i| i.iter()
- .find(|i| i.impl_item.def_id == imp.def_id))
- {
- let i = &impl_item.impl_item;
- return Some(i);
- }
- }
- None
-}
-
fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
t: &clean::Trait) -> fmt::Result {
let mut bounds = String::new();
// if any Types with the same name but different DefId have been found.
let mut implementor_dups: FxHashMap<&str, (DefId, bool)> = FxHashMap();
for implementor in implementors {
- match implementor.impl_.for_ {
+ match implementor.inner_impl().for_ {
clean::ResolvedPath { ref path, did, is_generic: false, .. } |
clean::BorrowedRef {
type_: box clean::ResolvedPath { ref path, did, is_generic: false, .. },
}
let (local, foreign) = implementors.iter()
- .partition::<Vec<_>, _>(|i| i.impl_.for_.def_id()
+ .partition::<Vec<_>, _>(|i| i.inner_impl().for_.def_id()
.map_or(true, |d| cache.paths.contains_key(&d)));
if !foreign.is_empty() {
")?;
for implementor in foreign {
- if let Some(i) = implementor2item(&cache, implementor) {
- let impl_ = Impl { impl_item: i.clone() };
- let assoc_link = AssocItemLink::GotoSource(
- i.def_id, &implementor.impl_.provided_trait_methods
- );
- render_impl(w, cx, &impl_, assoc_link,
- RenderMode::Normal, i.stable_since(), false)?;
- }
+ let assoc_link = AssocItemLink::GotoSource(
+ implementor.impl_item.def_id, &implementor.inner_impl().provided_trait_methods
+ );
+ render_impl(w, cx, &implementor, assoc_link,
+ RenderMode::Normal, implementor.impl_item.stable_since(), false)?;
}
}
for implementor in local {
write!(w, "<li>")?;
- if let Some(item) = implementor2item(&cache, implementor) {
- if let Some(l) = (Item { cx, item }).src_href() {
- write!(w, "<div class='out-of-band'>")?;
- write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>",
- l, "goto source code")?;
- write!(w, "</div>")?;
- }
+ if let Some(l) = (Item { cx, item: &implementor.impl_item }).src_href() {
+ write!(w, "<div class='out-of-band'>")?;
+ write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>",
+ l, "goto source code")?;
+ write!(w, "</div>")?;
}
write!(w, "<code>")?;
// If there's already another implementor that has the same abbridged name, use the
// full path, for example in `std::iter::ExactSizeIterator`
- let use_absolute = match implementor.impl_.for_ {
+ let use_absolute = match implementor.inner_impl().for_ {
clean::ResolvedPath { ref path, is_generic: false, .. } |
clean::BorrowedRef {
type_: box clean::ResolvedPath { ref path, is_generic: false, .. },
} => implementor_dups[path.last_name()].1,
_ => false,
};
- fmt_impl_for_trait_page(&implementor.impl_, w, use_absolute)?;
- for it in &implementor.impl_.items {
+ fmt_impl_for_trait_page(&implementor.inner_impl(), w, use_absolute)?;
+ for it in &implementor.inner_impl().items {
if let clean::TypedefItem(ref tydef, _) = it.inner {
write!(w, "<span class=\"where fmt-newline\"> ")?;
assoc_type(w, it, &vec![], Some(&tydef.type_), AssocItemLink::Anchor(None))?;
if let Some(implementors) = c.implementors.get(&it.def_id) {
let res = implementors.iter()
- .filter(|i| i.impl_.for_.def_id()
- .map_or(false, |d| !c.paths.contains_key(&d)))
+ .filter(|i| i.inner_impl().for_.def_id()
+ .map_or(false, |d| !c.paths.contains_key(&d)))
.filter_map(|i| {
- if let Some(item) = implementor2item(&c, i) {
- match extract_for_impl_name(&item) {
- Some((ref name, ref url)) => {
- Some(format!("<a href=\"#impl-{}\">{}</a>",
- small_url_encode(url),
- Escape(name)))
- }
- _ => None,
+ match extract_for_impl_name(&i.impl_item) {
+ Some((ref name, ref url)) => {
+ Some(format!("<a href=\"#impl-{}\">{}</a>",
+ small_url_encode(url),
+ Escape(name)))
}
- } else {
- None
+ _ => None,
}
})
.collect::<String>();
#![feature(rustc_private)]
#![feature(box_patterns)]
#![feature(box_syntax)]
+#![feature(fs_read_write)]
#![feature(libc)]
#![feature(set_stdio)]
#![feature(slice_patterns)]
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::middle::cstore::{LoadedMacro, CrateStore};
use rustc::middle::privacy::AccessLevel;
+use rustc::ty::Visibility;
use rustc::util::nodemap::FxHashSet;
use rustc::hir;
self.inside_public_path = orig_inside_public_path;
let def_id = self.cx.tcx.hir.local_def_id(id);
if let Some(exports) = self.cx.tcx.module_exports(def_id) {
- for export in exports.iter() {
+ for export in exports.iter().filter(|e| e.vis == Visibility::Public) {
if let Def::Macro(def_id, ..) = export.def {
if def_id.krate == LOCAL_CRATE || self.reexported_macros.contains(&def_id) {
continue // These are `krate.exported_macros`, handled in `self.visit()`.
pub fn new(cursor: &'a mut io::Cursor<Vec<u8>>) -> Encoder<'a> {
Encoder { cursor: cursor }
}
+
+ pub fn emit_raw_bytes(&mut self, s: &[u8]) -> EncodeResult {
+ self.cursor.write_all(s)
+ }
}
pub fn advance(&mut self, bytes: usize) {
self.position += bytes;
}
+
+ pub fn read_raw_bytes(&mut self, s: &mut [u8]) -> Result<(), String> {
+ let start = self.position;
+ let end = start + s.len();
+
+ s.copy_from_slice(&self.data[start..end]);
+
+ self.position = end;
+
+ Ok(())
+ }
}
macro_rules! read_uleb128 {
self.search_mut(k).into_occupied_bucket().map(|bucket| pop_internal(bucket).1)
}
+ /// Removes a key from the map, returning the stored key and value if the
+ /// key was previously in the map.
+ ///
+ /// The key may be any borrowed form of the map's key type, but
+ /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
+ /// the key type.
+ ///
+ /// [`Eq`]: ../../std/cmp/trait.Eq.html
+ /// [`Hash`]: ../../std/hash/trait.Hash.html
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(hash_map_remove_entry)]
+ /// use std::collections::HashMap;
+ ///
+ /// # fn main() {
+ /// let mut map = HashMap::new();
+ /// map.insert(1, "a");
+ /// assert_eq!(map.remove_entry(&1), Some((1, "a")));
+ /// assert_eq!(map.remove(&1), None);
+ /// # }
+ /// ```
+ #[unstable(feature = "hash_map_remove_entry", issue = "46344")]
+ pub fn remove_entry<Q: ?Sized>(&mut self, k: &Q) -> Option<(K, V)>
+ where K: Borrow<Q>,
+ Q: Hash + Eq
+ {
+ if self.table.size() == 0 {
+ return None;
+ }
+
+ self.search_mut(k)
+ .into_occupied_bucket()
+ .map(|bucket| {
+ let (k, v, _) = pop_internal(bucket);
+ (k, v)
+ })
+ }
+
/// Retains only the elements specified by the predicate.
///
/// In other words, remove all pairs `(k, v)` such that `f(&k,&mut v)` returns `false`.
}
#[test]
- fn test_pop() {
+ fn test_remove() {
let mut m = HashMap::new();
m.insert(1, 2);
assert_eq!(m.remove(&1), Some(2));
assert_eq!(m.remove(&1), None);
}
+ #[test]
+ fn test_remove_entry() {
+ let mut m = HashMap::new();
+ m.insert(1, 2);
+ assert_eq!(m.remove_entry(&1), Some((1, 2)));
+ assert_eq!(m.remove(&1), None);
+ }
+
#[test]
fn test_iterate() {
let mut m = HashMap::with_capacity(4);
//! terminator, so the buffer length is really `len+1` characters.
//! Rust strings don't have a nul terminator; their length is always
//! stored and does not need to be calculated. While in Rust
-//! accessing a string's length is a O(1) operation (becasue the
+//! accessing a string's length is a O(1) operation (because the
//! length is stored); in C it is an O(length) operation because the
//! length needs to be computed by scanning the string for the nul
//! terminator.
/// and platform-native string values, and in particular allowing a Rust string
/// to be converted into an "OS" string with no cost if possible.
///
-/// `OsString` is to [`OsStr`] as [`String`] is to [`&str`]: the former
+/// `OsString` is to [`&OsStr`] as [`String`] is to [`&str`]: the former
/// in each pair are owned strings; the latter are borrowed
/// references.
///
/// the traits which `OsString` implements for conversions from/to native representations.
///
/// [`OsStr`]: struct.OsStr.html
+/// [`&OsStr`]: struct.OsStr.html
/// [`From`]: ../convert/trait.From.html
/// [`String`]: ../string/struct.String.html
/// [`&str`]: ../primitive.str.html
/// This type represents a borrowed reference to a string in the operating system's preferred
/// representation.
///
-/// `OsStr` is to [`OsString`] as [`String`] is to [`&str`]: the former in each pair are borrowed
+/// `&OsStr` is to [`OsString`] as [`&str`] is to [`String`]: the former in each pair are borrowed
/// references; the latter are owned strings.
///
/// See the [module's toplevel documentation about conversions][conversions] for a discussion on
/// the traits which `OsStr` implements for conversions from/to native representations.
///
/// [`OsString`]: struct.OsString.html
+/// [`&str`]: ../primitive.str.html
+/// [`String`]: ../string/struct.String.html
/// [conversions]: index.html#conversions
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OsStr {
recursive: bool,
}
+/// How large a buffer to pre-allocate before reading the entire file at `path`.
+fn initial_buffer_size<P: AsRef<Path>>(path: P) -> usize {
+ // Allocate one extra byte so the buffer doesn't need to grow before the
+ // final `read` call at the end of the file. Don't worry about `usize`
+ // overflow because reading will fail regardless in that case.
+ metadata(path).map(|m| m.len() as usize + 1).unwrap_or(0)
+}
+
/// Read the entire contents of a file into a bytes vector.
///
/// This is a convenience function for using [`File::open`] and [`read_to_end`]
/// ```
#[unstable(feature = "fs_read_write", issue = "46588")]
pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
- let mut bytes = Vec::new();
+ let mut bytes = Vec::with_capacity(initial_buffer_size(&path));
File::open(path)?.read_to_end(&mut bytes)?;
Ok(bytes)
}
/// ```
#[unstable(feature = "fs_read_write", issue = "46588")]
pub fn read_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
- let mut string = String::new();
+ let mut string = String::with_capacity(initial_buffer_size(&path));
File::open(path)?.read_to_string(&mut string)?;
Ok(string)
}
fn consume(&mut self, amt: usize) { self.pos += amt as u64; }
}
+// Non-resizing write implementation
+fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<usize> {
+ let pos = cmp::min(*pos_mut, slice.len() as u64);
+ let amt = (&mut slice[(pos as usize)..]).write(buf)?;
+ *pos_mut += amt as u64;
+ Ok(amt)
+}
+
+// Resizing write implementation
+fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usize> {
+ let pos: usize = (*pos_mut).try_into().map_err(|_| {
+ Error::new(ErrorKind::InvalidInput,
+ "cursor position exceeds maximum possible vector length")
+ })?;
+ // Make sure the internal buffer is as least as big as where we
+ // currently are
+ let len = vec.len();
+ if len < pos {
+ // use `resize` so that the zero filling is as efficient as possible
+ vec.resize(pos, 0);
+ }
+ // Figure out what bytes will be used to overwrite what's currently
+ // there (left), and what will be appended on the end (right)
+ {
+ let space = vec.len() - pos;
+ let (left, right) = buf.split_at(cmp::min(space, buf.len()));
+ vec[pos..pos + left.len()].copy_from_slice(left);
+ vec.extend_from_slice(right);
+ }
+
+ // Bump us forward
+ *pos_mut = (pos + buf.len()) as u64;
+ Ok(buf.len())
+}
+
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for Cursor<&'a mut [u8]> {
#[inline]
- fn write(&mut self, data: &[u8]) -> io::Result<usize> {
- let pos = cmp::min(self.pos, self.inner.len() as u64);
- let amt = (&mut self.inner[(pos as usize)..]).write(data)?;
- self.pos += amt as u64;
- Ok(amt)
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ slice_write(&mut self.pos, self.inner, buf)
+ }
+ fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
+
+#[unstable(feature = "cursor_mut_vec", issue = "30132")]
+impl<'a> Write for Cursor<&'a mut Vec<u8>> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ vec_write(&mut self.pos, self.inner, buf)
}
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Cursor<Vec<u8>> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- let pos: usize = self.position().try_into().map_err(|_| {
- Error::new(ErrorKind::InvalidInput,
- "cursor position exceeds maximum possible vector length")
- })?;
- // Make sure the internal buffer is as least as big as where we
- // currently are
- let len = self.inner.len();
- if len < pos {
- // use `resize` so that the zero filling is as efficient as possible
- self.inner.resize(pos, 0);
- }
- // Figure out what bytes will be used to overwrite what's currently
- // there (left), and what will be appended on the end (right)
- {
- let space = self.inner.len() - pos;
- let (left, right) = buf.split_at(cmp::min(space, buf.len()));
- self.inner[pos..pos + left.len()].copy_from_slice(left);
- self.inner.extend_from_slice(right);
- }
-
- // Bump us forward
- self.set_position((pos + buf.len()) as u64);
- Ok(buf.len())
+ vec_write(&mut self.pos, &mut self.inner, buf)
}
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
impl Write for Cursor<Box<[u8]>> {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- let pos = cmp::min(self.pos, self.inner.len() as u64);
- let amt = (&mut self.inner[(pos as usize)..]).write(buf)?;
- self.pos += amt as u64;
- Ok(amt)
+ slice_write(&mut self.pos, &mut self.inner, buf)
}
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
assert_eq!(&writer.get_ref()[..], b);
}
+ #[test]
+ fn test_mem_mut_writer() {
+ let mut vec = Vec::new();
+ let mut writer = Cursor::new(&mut vec);
+ assert_eq!(writer.write(&[0]).unwrap(), 1);
+ assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
+ assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
+ let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
+ assert_eq!(&writer.get_ref()[..], b);
+ }
+
#[test]
fn test_box_slice_writer() {
let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice());
///
/// Calls to `write` are not guaranteed to block waiting for data to be
/// written, and a write which would otherwise block can be indicated through
- /// an `Err` variant.
+ /// an [`Err`] variant.
///
- /// If the return value is `Ok(n)` then it must be guaranteed that
+ /// If the return value is [`Ok(n)`] then it must be guaranteed that
/// `0 <= n <= buf.len()`. A return value of `0` typically means that the
/// underlying object is no longer able to accept bytes and will likely not
/// be able to in the future as well, or that the buffer provided is empty.
/// It is **not** considered an error if the entire buffer could not be
/// written to this writer.
///
- /// An error of the `ErrorKind::Interrupted` kind is non-fatal and the
+ /// An error of the [`ErrorKind::Interrupted`] kind is non-fatal and the
/// write operation should be retried if there is nothing else to do.
///
+ /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
+ /// [`Ok(n)`]: ../../std/result/enum.Result.html#variant.Ok
+ /// [`ErrorKind::Interrupted`]: ../../std/io/enum.ErrorKind.html#variant.Interrupted
+ ///
/// # Examples
///
/// ```
/// Attempts to write an entire buffer into this write.
///
- /// This method will continuously call `write` until there is no more data
- /// to be written or an error of non-`ErrorKind::Interrupted` kind is
+ /// This method will continuously call [`write`] until there is no more data
+ /// to be written or an error of non-[`ErrorKind::Interrupted`] kind is
/// returned. This method will not return until the entire buffer has been
/// successfully written or such an error occurs. The first error that is
- /// not of `ErrorKind::Interrupted` kind generated from this method will be
+ /// not of [`ErrorKind::Interrupted`] kind generated from this method will be
/// returned.
///
/// # Errors
///
/// This function will return the first error of
- /// non-`ErrorKind::Interrupted` kind that `write` returns.
+ /// non-[`ErrorKind::Interrupted`] kind that [`write`] returns.
+ ///
+ /// [`ErrorKind::Interrupted`]: ../../std/io/enum.ErrorKind.html#variant.Interrupted
+ /// [`write`]: #tymethod.write
///
/// # Examples
///
// Turn warnings into errors, but only after stage0, where it can be useful for
// code to emit warnings during language transitions
-#![deny(warnings)]
+#![cfg_attr(not(stage0), deny(warnings))]
// std may use features in a platform-specific way
#![allow(unused_features)]
#![feature(rand)]
#![feature(raw)]
#![feature(repr_align)]
-#![feature(repr_simd)]
#![feature(rustc_attrs)]
#![feature(shared)]
#![feature(sip_hash_13)]
/// Unconditionally causes compilation to fail with the given error message when encountered.
///
/// This macro should be used when a crate uses a conditional compilation strategy to provide
- /// better error messages for errornous conditions.
+ /// better error messages for erroneous conditions.
///
/// # Examples
///
/// # Examples
///
/// ```should_panic
- /// #![feature(panic_col)]
/// use std::panic;
///
/// panic::set_hook(Box::new(|panic_info| {
///
/// panic!("Normal panic");
/// ```
- #[unstable(feature = "panic_col", reason = "recently added", issue = "42939")]
+ #[stable(feature = "panic_col", since = "1.25")]
pub fn column(&self) -> u32 {
self.col
}
}
}
+#[stable(feature = "path_component_asref", since = "1.24.0")]
+impl<'a> AsRef<Path> for Component<'a> {
+ fn as_ref(&self) -> &Path {
+ self.as_os_str().as_ref()
+ }
+}
+
/// An iterator over the [`Component`]s of a [`Path`].
///
/// This `struct` is created by the [`components`] method on [`Path`].
/// let path_buf = Path::new("foo.txt").to_path_buf();
/// assert_eq!(path_buf, std::path::PathBuf::from("foo.txt"));
/// ```
+ #[rustc_conversion_suggestion]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn to_path_buf(&self) -> PathBuf {
PathBuf::from(self.inner.to_os_string())
/// required that `T` satisfies [`Send`] to be shared across threads and
/// [`Sync`] to allow concurrent access through readers. The RAII guards
/// returned from the locking methods implement [`Deref`][] (and [`DerefMut`]
-/// for the `write` methods) to allow access to the contained of the lock.
+/// for the `write` methods) to allow access to the content of the lock.
///
/// # Poisoning
///
const DEBUG: bool = false;
pub mod args;
+#[cfg(feature = "backtrace")]
pub mod backtrace;
pub mod cmath;
pub mod condvar;
use libc::{wchar_t, size_t, c_void};
use ptr;
-#[repr(simd)]
-#[repr(C)]
-#[cfg(target_arch = "x86_64")]
-struct u64x2(u64, u64);
-
pub use self::FILE_INFO_BY_HANDLE_CLASS::*;
pub use self::EXCEPTION_DISPOSITION::*;
}
#[cfg(target_arch = "x86_64")]
-#[repr(C)]
+#[repr(C, align(16))]
pub struct CONTEXT {
- _align_hack: [u64x2; 0], // FIXME align on 16-byte
pub P1Home: DWORDLONG,
pub P2Home: DWORDLONG,
pub P3Home: DWORDLONG,
}
#[cfg(target_arch = "x86_64")]
-#[repr(C)]
+#[repr(C, align(16))]
pub struct M128A {
- _align_hack: [u64x2; 0], // FIXME align on 16-byte
pub Low: c_ulonglong,
pub High: c_longlong
}
#[cfg(target_arch = "x86_64")]
-#[repr(C)]
+#[repr(C, align(16))]
pub struct FLOATING_SAVE_AREA {
- _align_hack: [u64x2; 0], // FIXME align on 16-byte
_Dummy: [u8; 512] // FIXME: Fill this out
}
///
/// let duration = Duration::from_millis(5432);
/// assert_eq!(duration.as_secs(), 5);
- /// assert_eq!(duration.subsec_nanos(), 432_000_000);
+ /// assert_eq!(duration.subsec_millis(), 432);
/// ```
#[unstable(feature = "duration_extras", issue = "46507")]
#[inline]
///
/// let duration = Duration::from_micros(1_234_567);
/// assert_eq!(duration.as_secs(), 1);
- /// assert_eq!(duration.subsec_nanos(), 234_567_000);
+ /// assert_eq!(duration.subsec_micros(), 234_567);
/// ```
#[unstable(feature = "duration_extras", issue = "46507")]
#[inline]
[dependencies]
bitflags = "1.0"
serialize = { path = "../libserialize" }
-log = "0.3"
+log = "0.4"
syntax_pos = { path = "../libsyntax_pos" }
rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
rustc_errors = { path = "../librustc_errors" }
if let Some(mi) = item.word() {
let word = &*mi.name().as_str();
let hint = match word {
- // Can't use "extern" because it's not a lexical identifier.
- "C" => Some(ReprExtern),
+ "C" => Some(ReprC),
"packed" => Some(ReprPacked),
"simd" => Some(ReprSimd),
_ => match int_type_of_word(word) {
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
pub enum ReprAttr {
ReprInt(IntType),
- ReprExtern,
+ ReprC,
ReprPacked,
ReprSimd,
ReprAlign(u32),
// Allows use of the :lifetime macro fragment specifier
(active, macro_lifetime_matcher, "1.24.0", Some(46895)),
+
+ // `extern` in paths
+ (active, extern_in_paths, "1.23.0", Some(44660)),
);
declare_features! (
never be stable",
cfg_fn!(rustc_attrs))),
+ // whitelists "identity-like" conversion methods to suggest on type mismatch
+ ("rustc_conversion_suggestion", Whitelisted, Gated(Stability::Unstable,
+ "rustc_attrs",
+ "this is an internal attribute that will \
+ never be stable",
+ cfg_fn!(rustc_attrs))),
+
("wasm_import_memory", Whitelisted, Gated(Stability::Unstable,
"wasm_import_memory",
"wasm_import_memory attribute is currently unstable",
if segment.identifier.name == keywords::Crate.name() {
gate_feature_post!(&self, crate_in_paths, segment.span,
"`crate` in paths is experimental");
+ } else if segment.identifier.name == keywords::Extern.name() {
+ gate_feature_post!(&self, extern_in_paths, segment.span,
+ "`extern` in paths is experimental");
}
}
break;
}
}
- if i > line.len() {
+ if i >= line.len() {
can_trim = false;
}
if !can_trim {
Parser::token_to_string(&self.token)
}
+ pub fn token_descr(&self) -> Option<&'static str> {
+ Some(match &self.token {
+ t if t.is_special_ident() => "reserved identifier",
+ t if t.is_used_keyword() => "keyword",
+ t if t.is_unused_keyword() => "reserved keyword",
+ _ => return None,
+ })
+ }
+
pub fn this_token_descr(&self) -> String {
- let prefix = match &self.token {
- t if t.is_special_ident() => "reserved identifier ",
- t if t.is_used_keyword() => "keyword ",
- t if t.is_unused_keyword() => "reserved keyword ",
- _ => "",
- };
- format!("{}`{}`", prefix, self.this_token_to_string())
+ if let Some(prefix) = self.token_descr() {
+ format!("{} `{}`", prefix, self.this_token_to_string())
+ } else {
+ format!("`{}`", self.this_token_to_string())
+ }
}
pub fn unexpected_last<T>(&self, t: &token::Token) -> PResult<'a, T> {
}
pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> {
+ self.parse_ident_common(true)
+ }
+
+ fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> {
match self.token {
token::Ident(i) => {
if self.token.is_reserved_ident() {
- self.span_err(self.span, &format!("expected identifier, found {}",
- self.this_token_descr()));
+ let mut err = self.struct_span_err(self.span,
+ &format!("expected identifier, found {}",
+ self.this_token_descr()));
+ if let Some(token_descr) = self.token_descr() {
+ err.span_label(self.span, format!("expected identifier, found {}",
+ token_descr));
+ } else {
+ err.span_label(self.span, "expected identifier");
+ }
+ if recover {
+ err.emit();
+ } else {
+ return Err(err);
+ }
}
self.bump();
Ok(i)
} else {
let mut err = self.fatal(&format!("expected identifier, found `{}`",
self.this_token_to_string()));
+ if let Some(token_descr) = self.token_descr() {
+ err.span_label(self.span, format!("expected identifier, found {}",
+ token_descr));
+ } else {
+ err.span_label(self.span, "expected identifier");
+ }
if self.token == token::Underscore {
err.note("`_` is a wildcard pattern, not an identifier");
}
None
};
(ident, TraitItemKind::Const(ty, default), ast::Generics::default())
- } else if self.token.is_path_start() {
+ } else if self.token.is_path_start() && !self.is_extern_non_path() {
// trait item macro.
// code copied from parse_macro_use_or_failure... abstraction!
let prev_span = self.prev_span;
self.bump();
Ok(Ident::with_empty_ctxt(name))
} else {
- self.parse_ident()
+ self.parse_ident_common(false)
}
}
hi = self.prev_span;
(fieldname, self.parse_expr()?, false)
} else {
- let fieldname = self.parse_ident()?;
+ let fieldname = self.parse_ident_common(false)?;
hi = self.prev_span;
// Mimic `x: x` for the `x` field shorthand.
fn parse_struct_expr(&mut self, lo: Span, pth: ast::Path, mut attrs: ThinVec<Attribute>)
-> PResult<'a, P<Expr>> {
+ let struct_sp = lo.to(self.prev_span);
self.bump();
let mut fields = Vec::new();
let mut base = None;
match self.parse_field() {
Ok(f) => fields.push(f),
Err(mut e) => {
+ e.span_label(struct_sp, "while parsing this struct");
e.emit();
self.recover_stmt();
break;
let mut pats = Vec::new();
loop {
pats.push(self.parse_pat()?);
- if self.check(&token::BinOp(token::Or)) { self.bump();}
- else { return Ok(pats); }
+
+ if self.token == token::OrOr {
+ let mut err = self.struct_span_err(self.span,
+ "unexpected token `||` after pattern");
+ err.span_suggestion(self.span,
+ "use a single `|` to specify multiple patterns",
+ "|".to_owned());
+ err.emit();
+ self.bump();
+ } else if self.check(&token::BinOp(token::Or)) {
+ self.bump();
+ } else {
+ return Ok(pats);
+ }
};
}
self.token.is_keyword(keywords::Crate) && self.look_ahead(1, |t| t != &token::ModSep)
}
+ fn is_extern_non_path(&self) -> bool {
+ self.token.is_keyword(keywords::Extern) && self.look_ahead(1, |t| t != &token::ModSep)
+ }
+
fn eat_auto_trait(&mut self) -> bool {
if self.token.is_keyword(keywords::Auto)
&& self.look_ahead(1, |t| t.is_keyword(keywords::Trait))
// like a path (1 token), but it fact not a path.
// `union::b::c` - path, `union U { ... }` - not a path.
// `crate::b::c` - path, `crate struct S;` - not a path.
+ // `extern::b::c` - path, `extern crate c;` - not a path.
} else if self.token.is_path_start() &&
!self.token.is_qpath_start() &&
!self.is_union_item() &&
- !self.is_crate_vis() {
+ !self.is_crate_vis() &&
+ !self.is_extern_non_path() {
let pth = self.parse_path(PathStyle::Expr)?;
if !self.eat(&token::Not) {
-> PResult<'a, (Ident, Vec<ast::Attribute>, ast::Generics,
ast::ImplItemKind)> {
// code copied from parse_macro_use_or_failure... abstraction!
- if self.token.is_path_start() {
+ if self.token.is_path_start() && !self.is_extern_non_path() {
// Method macro.
let prev_span = self.prev_span;
if let Some(path) = Parser::submod_path_from_attr(outer_attrs, &self.directory.path) {
return Ok(ModulePathSuccess {
directory_ownership: match path.file_name().and_then(|s| s.to_str()) {
- Some("mod.rs") => DirectoryOwnership::Owned { relative: None },
- Some(_) => {
- DirectoryOwnership::Owned { relative: Some(id) }
- }
+ // All `#[path]` files are treated as though they are a `mod.rs` file.
+ // This means that `mod foo;` declarations inside `#[path]`-included
+ // files are siblings,
+ //
+ // Note that this will produce weirdness when a file named `foo.rs` is
+ // `#[path]` included and contains a `mod foo;` declaration.
+ // If you encounter this, it's your own darn fault :P
+ Some(_) => DirectoryOwnership::Owned { relative: None },
_ => DirectoryOwnership::UnownedViaMod(true),
},
path,
return Ok(Some(item));
}
- if self.eat_keyword(keywords::Extern) {
+ if self.check_keyword(keywords::Extern) && self.is_extern_non_path() {
+ self.bump(); // `extern`
if self.eat_keyword(keywords::Crate) {
return Ok(Some(self.parse_item_extern_crate(lo, visibility, attrs)?));
}
Some(id) => id.name == keywords::Super.name() ||
id.name == keywords::SelfValue.name() ||
id.name == keywords::SelfType.name() ||
+ id.name == keywords::Extern.name() ||
id.name == keywords::Crate.name() ||
id.name == keywords::DollarCrate.name(),
None => false,
TokenStream::concat(result)
}
- fn first_tree(&self) -> Option<TokenTree> {
+ fn first_tree_and_joint(&self) -> Option<(TokenTree, bool)> {
match self.kind {
TokenStreamKind::Empty => None,
- TokenStreamKind::Tree(ref tree) |
- TokenStreamKind::JointTree(ref tree) => Some(tree.clone()),
- TokenStreamKind::Stream(ref stream) => stream.first().unwrap().first_tree(),
+ TokenStreamKind::Tree(ref tree) => Some((tree.clone(), false)),
+ TokenStreamKind::JointTree(ref tree) => Some((tree.clone(), true)),
+ TokenStreamKind::Stream(ref stream) => stream.first().unwrap().first_tree_and_joint(),
}
}
let stream = stream.into();
let last_tree_if_joint = self.0.last().and_then(TokenStream::last_tree_if_joint);
if let Some(TokenTree::Token(last_span, last_tok)) = last_tree_if_joint {
- if let Some(TokenTree::Token(span, tok)) = stream.first_tree() {
+ if let Some((TokenTree::Token(span, tok), is_joint)) = stream.first_tree_and_joint() {
if let Some(glued_tok) = last_tok.glue(tok) {
let last_stream = self.0.pop().unwrap();
self.push_all_but_last_tree(&last_stream);
let glued_span = last_span.to(span);
- self.0.push(TokenTree::Token(glued_span, glued_tok).into());
+ let glued_tt = TokenTree::Token(glued_span, glued_tok);
+ let glued_tokenstream = if is_joint {
+ glued_tt.joint()
+ } else {
+ glued_tt.into()
+ };
+ self.0.push(glued_tokenstream);
self.push_all_but_first_tree(&stream);
return
}
assert_eq!(test1.is_empty(), false);
assert_eq!(test2.is_empty(), false);
}
+
+ #[test]
+ fn test_dotdotdot() {
+ let mut builder = TokenStreamBuilder::new();
+ builder.push(TokenTree::Token(sp(0, 1), Token::Dot).joint());
+ builder.push(TokenTree::Token(sp(1, 2), Token::Dot).joint());
+ builder.push(TokenTree::Token(sp(2, 3), Token::Dot));
+ let stream = builder.build();
+ assert!(stream.eq_unspanned(&string_to_ts("...")));
+ assert_eq!(stream.trees().count(), 1);
+ }
+
}
for r in &attr::find_repr_attrs(diagnostic, a) {
repr_type_name = match *r {
attr::ReprPacked | attr::ReprSimd | attr::ReprAlign(_) => continue,
- attr::ReprExtern => "i32",
+ attr::ReprC => "i32",
attr::ReprInt(attr::SignedInt(ast::IntTy::Isize)) => "isize",
attr::ReprInt(attr::SignedInt(ast::IntTy::I8)) => "i8",
/// Extend a syntax context with a given mark
pub fn apply_mark(self, mark: Mark) -> SyntaxContext {
+ if mark.kind() == MarkKind::Modern {
+ return self.apply_mark_internal(mark);
+ }
+
+ let call_site_ctxt =
+ mark.expn_info().map_or(SyntaxContext::empty(), |info| info.call_site.ctxt()).modern();
+ if call_site_ctxt == SyntaxContext::empty() {
+ return self.apply_mark_internal(mark);
+ }
+
+ // Otherwise, `mark` is a macros 1.0 definition and the call site is in a
+ // macros 2.0 expansion, i.e. a macros 1.0 invocation is in a macros 2.0 definition.
+ //
+ // In this case, the tokens from the macros 1.0 definition inherit the hygiene
+ // at their invocation. That is, we pretend that the macros 1.0 definition
+ // was defined at its invocation (i.e. inside the macros 2.0 definition)
+ // so that the macros 2.0 definition remains hygienic.
+ //
+ // See the example at `test/run-pass/hygiene/legacy_interaction.rs`.
+ let mut ctxt = call_site_ctxt;
+ for mark in self.marks() {
+ ctxt = ctxt.apply_mark_internal(mark);
+ }
+ ctxt.apply_mark_internal(mark)
+ }
+
+ fn apply_mark_internal(self, mark: Mark) -> SyntaxContext {
HygieneData::with(|data| {
let syntax_contexts = &mut data.syntax_contexts;
let mut modern = syntax_contexts[self.0 as usize].modern;
})
}
+ pub fn marks(mut self) -> Vec<Mark> {
+ HygieneData::with(|data| {
+ let mut marks = Vec::new();
+ while self != SyntaxContext::empty() {
+ marks.push(data.syntax_contexts[self.0 as usize].outer_mark);
+ self = data.syntax_contexts[self.0 as usize].prev_ctxt;
+ }
+ marks.reverse();
+ marks
+ })
+ }
+
/// Adjust this context for resolution in a scope created by the given expansion.
/// For example, consider the following three resolutions of `f`:
///
#![feature(asm)]
#![feature(fnbox)]
-#![cfg_attr(unix, feature(libc))]
+#![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc))]
#![feature(set_stdio)]
#![feature(panic_unwind)]
#![feature(staged_api)]
extern crate getopts;
extern crate term;
-#[cfg(unix)]
+#[cfg(any(unix, target_os = "cloudabi"))]
extern crate libc;
extern crate panic_unwind;
1
}
- #[cfg(any(target_os = "linux",
- target_os = "macos",
- target_os = "ios",
- target_os = "android",
- target_os = "solaris",
+ #[cfg(any(target_os = "android",
+ target_os = "cloudabi",
target_os = "emscripten",
- target_os = "fuchsia"))]
+ target_os = "fuchsia",
+ target_os = "ios",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "solaris"))]
fn num_cpus() -> usize {
unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize }
}
return wrap(unwrap(B)->CreateFence(fromRust(Order), fromRust(Scope)));
}
-extern "C" void LLVMRustSetDebug(int Enabled) {
-#ifndef NDEBUG
- DebugFlag = Enabled;
-#endif
-}
-
enum class LLVMRustAsmDialect {
Other,
Att,
return true;
}
-extern "C" bool LLVMRustLinkInParsedExternalBitcode(
- LLVMModuleRef DstRef, LLVMModuleRef SrcRef) {
-#if LLVM_VERSION_GE(4, 0)
- Module *Dst = unwrap(DstRef);
- std::unique_ptr<Module> Src(unwrap(SrcRef));
-
- if (Linker::linkModules(*Dst, std::move(Src))) {
- LLVMRustSetLastError("failed to link modules");
- return false;
- }
- return true;
-#else
- LLVMRustSetLastError("can't link parsed modules on this LLVM");
- return false;
-#endif
-}
-
// Note that the two following functions look quite similar to the
// LLVMGetSectionName function. Sadly, it appears that this function only
// returns a char* pointer, which isn't guaranteed to be null-terminated. The
}
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
-DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef)
extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
RawRustStringOstream OS(Str);
report_fatal_error("Unhandled TypeID.");
}
-extern "C" void LLVMRustWriteDebugLocToString(LLVMContextRef C,
- LLVMDebugLocRef DL,
- RustStringRef Str) {
- RawRustStringOstream OS(Str);
- unwrap(DL)->print(OS);
-}
-
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
typedef struct OpaqueRustString *RustStringRef;
typedef struct LLVMOpaqueTwine *LLVMTwineRef;
-typedef struct LLVMOpaqueDebugLoc *LLVMDebugLocRef;
typedef struct LLVMOpaqueSMDiagnostic *LLVMSMDiagnosticRef;
-typedef struct LLVMOpaqueRustJITMemoryManager *LLVMRustJITMemoryManagerRef;
extern "C" void LLVMRustStringWriteImpl(RustStringRef Str, const char *Ptr,
size_t Size);
+++ /dev/null
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern: mod statements in non-mod.rs files are unstable
-
-#[path="mod_file_not_owning_aux3.rs"]
-mod foo;
-
-fn main() {}
enum bird {
pub duck,
//~^ ERROR: expected identifier, found keyword `pub`
- //~^^ ERROR: expected
+ //~| ERROR: expected
goose
}
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(fn_traits)]
+
+fn main() {
+ <fn() as Fn()>::call;
+ //~^ ERROR associated type bindings are not allowed here [E0229]
+}
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn xyz() -> u8 { 42 }
+
+const NUM: u8 = xyz();
+//~^ ERROR calls in constants are limited to constant functions, struct and enum constructors
+
+fn main() {
+ match 1 {
+ NUM => unimplemented!(),
+ _ => unimplemented!(),
+ }
+}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(extern_in_paths)]
+
+fn main() {
+ let extern = 0; //~ ERROR expected unit struct/variant or constant, found module `extern`
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[derive(Debug)]
+pub struct S;
+
+#[derive(Debug)]
+pub struct Z;
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(extern_in_paths)]
+
+use extern::xcrate::S; //~ ERROR can't find crate for `xcrate`
+
+fn main() {}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(extern_in_paths)]
+
+fn main() {
+ let s = extern::xcrate::S; //~ ERROR can't find crate for `xcrate`
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(extern_in_paths)]
+
+use extern::ycrate; //~ ERROR can't find crate for `ycrate`
+
+fn main() {}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:xcrate.rs
+
+#![feature(extern_in_paths)]
+
+use extern; //~ ERROR unresolved import `extern`
+ //~^ NOTE no `extern` in the root
+use extern::*; //~ ERROR unresolved import `extern::*`
+ //~^ NOTE cannot glob-import all possible crates
+
+fn main() {
+ let s = extern::xcrate; //~ ERROR expected value, found module `extern::xcrate`
+ //~^ NOTE not a value
+}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(const_fn)]
+
struct WithDtor;
impl Drop for WithDtor {
const EARLY_DROP_C: i32 = (WithDtor, 0).1;
//~^ ERROR destructors cannot be evaluated at compile-time
+const fn const_drop<T>(_: T) {}
+//~^ ERROR destructors cannot be evaluated at compile-time
+
+const fn const_drop2<T>(x: T) {
+ (x, ()).1
+ //~^ ERROR destructors cannot be evaluated at compile-time
+}
+
fn main () {}
let mut _b = 0;
let mut _ = 0; //~ ERROR expected identifier, found `_`
//~^ NOTE `_` is a wildcard pattern, not an identifier
+ //~| NOTE expected identifier
}
+++ /dev/null
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags: -Z parse-only
-
-// This file was auto-generated using 'src/etc/generate-keyword-tests.py extern'
-
-fn main() {
- let extern = "foo"; //~ error: expected pattern, found keyword `extern`
-}
# Make sure we don't ICE if the linker prints a non-UTF-8 error message.
-ifdef IS_WINDOWS
-# ignore windows
+# Ignore Windows and Apple
# This does not work in its current form on windows, possibly due to
# gcc bugs or something about valid Windows paths. See issue #29151
# for more information.
-all:
+ifndef IS_WINDOWS
-else
+# This also does not work on Apple APFS due to the filesystem requiring
+# valid UTF-8 paths.
+ifneq ($(shell uname),Darwin)
# The zzz it to allow humans to tab complete or glob this thing.
bad_dir := $(TMPDIR)/zzz$$'\xff'
mkdir $(bad_dir)
mv $(TMPDIR)/liblibrary.a $(bad_dir)
LIBRARY_PATH=$(bad_dir) $(RUSTC) exec.rs 2>&1 | $(CGREP) this_symbol_not_defined
+else
+all:
+
+endif
+
+else
+all:
endif
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-pretty pretty-printing is unhygienic
+
+#[macro_export]
+macro_rules! m {
+ () => {
+ fn f() {} // (2)
+ g(); // (1)
+ }
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn f() {}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "lib"]
+
+extern crate my_crate;
+
+pub fn g() {} // (a)
+
+#[macro_export]
+macro_rules! unhygienic_macro {
+ () => {
+ // (1) unhygienic: depends on `my_crate` in the crate root at the invocation site.
+ ::my_crate::f();
+
+ // (2) unhygienic: defines `f` at the invocation site (in addition to the above point).
+ use my_crate::f;
+ f();
+
+ g(); // (3) unhygienic: `g` needs to be in scope at use site.
+
+ $crate::g(); // (4) hygienic: this always resolves to (a)
+ }
+}
+
+#[allow(unused)]
+fn test_unhygienic() {
+ unhygienic_macro!();
+ f(); // `f` was defined at the use site
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-pretty pretty-printing is unhygienic
+
+// aux-build:legacy_interaction.rs
+
+#![feature(decl_macro)]
+#[allow(unused)]
+
+extern crate legacy_interaction;
+// ^ defines
+// ```rust
+// macro_rules! m {
+// () => {
+// fn f() // (1)
+// g() // (2)
+// }
+// }
+// ```rust
+
+mod def_site {
+ // Unless this macro opts out of hygiene, it should resolve the same wherever it is invoked.
+ pub macro m2() {
+ ::legacy_interaction::m!();
+ f(); // This should resolve to (1)
+ fn g() {} // We want (2) resolve to this, not to (4)
+ }
+}
+
+mod use_site {
+ fn test() {
+ fn f() -> bool { true } // (3)
+ fn g() -> bool { true } // (4)
+
+ ::def_site::m2!();
+
+ let _: bool = f(); // This should resolve to (3)
+ let _: bool = g(); // This should resolve to (4)
+ }
+}
+
+fn main() {}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-pretty pretty-printing is unhygienic
+
+// aux-build:my_crate.rs
+// aux-build:unhygienic_example.rs
+
+#![feature(decl_macro)]
+
+extern crate unhygienic_example;
+extern crate my_crate; // (b)
+
+// Hygienic version of `unhygienic_macro`.
+pub macro hygienic_macro() {
+ fn g() {} // (c)
+ ::unhygienic_example::unhygienic_macro!();
+ // ^ Even though we invoke an unhygienic macro, `hygienic_macro` remains hygienic.
+ // In the above expansion:
+ // (1) `my_crate` always resolves to (b) regardless of invocation site.
+ // (2) The defined function `f` is only usable inside this macro definition.
+ // (3) `g` always resolves to (c) regardless of invocation site.
+ // (4) `$crate::g` remains hygienic and continues to resolve to (a).
+
+ f();
+}
+
+#[allow(unused)]
+fn test_hygienic_macro() {
+ hygienic_macro!();
+
+ fn f() {} // (d) no conflict
+ f(); // resolves to (d)
+}
+
+fn main() {}
universal_impl_trait,
fn_traits,
step_trait,
- unboxed_closures
+ unboxed_closures,
+ copy_closures,
+ clone_closures
)]
//! Derived from: <https://raw.githubusercontent.com/quickfur/dcal/master/dcal.d>.
}
}
-/// Wrapper for zero-sized closures.
-// HACK(eddyb) Only needed because closures can't implement Copy.
-struct Fn0<F>(std::marker::PhantomData<F>);
-
-impl<F> Copy for Fn0<F> {}
-impl<F> Clone for Fn0<F> {
- fn clone(&self) -> Self { *self }
-}
-
-impl<F: FnOnce<A>, A> FnOnce<A> for Fn0<F> {
- type Output = F::Output;
-
- extern "rust-call" fn call_once(self, args: A) -> Self::Output {
- let f = unsafe { std::mem::uninitialized::<F>() };
- f.call_once(args)
- }
-}
-
-impl<F: FnMut<A>, A> FnMut<A> for Fn0<F> {
- extern "rust-call" fn call_mut(&mut self, args: A) -> Self::Output {
- let mut f = unsafe { std::mem::uninitialized::<F>() };
- f.call_mut(args)
- }
-}
-
-trait AsFn0<A>: Sized {
- fn copyable(self) -> Fn0<Self>;
-}
-
-impl<F: FnMut<A>, A> AsFn0<A> for F {
- fn copyable(self) -> Fn0<Self> {
- assert_eq!(std::mem::size_of::<F>(), 0);
- Fn0(std::marker::PhantomData)
- }
-}
-
/// GroupBy implementation.
struct GroupBy<It: Iterator, F> {
it: std::iter::Peekable<It>,
}
impl<It, F> Clone for GroupBy<It, F>
-where It: Iterator + Clone, It::Item: Clone, F: Clone {
- fn clone(&self) -> GroupBy<It, F> {
+where
+ It: Iterator + Clone,
+ It::Item: Clone,
+ F: Clone,
+{
+ fn clone(&self) -> Self {
GroupBy {
it: self.it.clone(),
- f: self.f.clone()
+ f: self.f.clone(),
}
}
}
}
trait IteratorExt: Iterator + Sized {
- fn group_by<G, F>(self, f: F) -> GroupBy<Self, Fn0<F>>
- where F: FnMut(&Self::Item) -> G,
+ fn group_by<G, F>(self, f: F) -> GroupBy<Self, F>
+ where F: Clone + FnMut(&Self::Item) -> G,
G: Eq
{
- GroupBy {
- it: self.peekable(),
- f: f.copyable(),
- }
+ GroupBy { it: self.peekable(), f }
}
fn join(mut self, sep: &str) -> String
fn dates_in_year(year: i32) -> impl Iterator<Item=NaiveDate>+Clone {
InGroup {
it: NaiveDate::from_ymd(year, 1, 1)..,
- f: (|d: &NaiveDate| d.year()).copyable(),
+ f: |d: &NaiveDate| d.year(),
g: year
}
}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Issue 33903:
+// Built-in indexing should be used even when the index is not
+// trivially an integer
+// Only built-in indexing can be used in constant expresssions
+
+const FOO: i32 = [12, 34][0 + 1];
+
+fn main() {}
+
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(conservative_impl_trait)]
+fn foo() -> impl Copy {
+ foo
+}
+fn main() {
+ foo();
+}
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(specialization)]
+
+trait Iterate<'a> {
+ type Ty: Valid;
+ fn iterate(self);
+}
+impl<'a, T> Iterate<'a> for T where T: Check {
+ default type Ty = ();
+ default fn iterate(self) {}
+}
+
+trait Check {}
+impl<'a, T> Check for T where <T as Iterate<'a>>::Ty: Valid {}
+
+trait Valid {}
+
+fn main() {
+ Iterate::iterate(0);
+}
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Zst;
+
+fn main() {
+ unsafe { ::std::ptr::write_volatile(1 as *mut Zst, Zst) }
+}
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(associated_consts)]
+
+impl A for i32 {
+ type Foo = u32;
+}
+impl B for u32 {
+ const BAR: i32 = 0;
+}
+
+trait A {
+ type Foo: B;
+}
+
+trait B {
+ const BAR: i32;
+}
+
+fn generic<T: A>() {
+ // This panics if the universal function call syntax is used as well
+ println!("{}", T::Foo::BAR);
+}
+
+fn main() {}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct A;
+
+impl A {
+ fn take_mutably(&mut self) {}
+}
+
+fn identity<T>(t: T) -> T {
+ t
+}
+
+// Issue 46095
+// Built-in indexing should be used even when the index is not
+// trivially an integer
+// Overloaded indexing would cause wrapped to be borrowed mutably
+
+fn main() {
+ let mut a1 = A;
+ let mut a2 = A;
+
+ let wrapped = [&mut a1, &mut a2];
+
+ {
+ wrapped[0 + 1 - 1].take_mutably();
+ }
+
+ {
+ wrapped[identity(0)].take_mutably();
+ }
+}
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub fn foo() {}
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub mod innest;
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn foo() {}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub mod innest;
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:xcrate.rs
+
+#![feature(extern_in_paths)]
+
+use extern::xcrate::Z;
+
+fn f() {
+ use extern::xcrate;
+ use extern::xcrate as ycrate;
+ let s = xcrate::S;
+ assert_eq!(format!("{:?}", s), "S");
+ let z = ycrate::Z;
+ assert_eq!(format!("{:?}", z), "Z");
+}
+
+fn main() {
+ let s = extern::xcrate::S;
+ assert_eq!(format!("{:?}", s), "S");
+ let z = Z;
+ assert_eq!(format!("{:?}", z), "Z");
+}
impl SomeTrait for SomeStruct {
// deliberately multi-line impl
}
+
+pub trait AnotherTrait {}
+
+// @has foo/trait.AnotherTrait.html '//a/@href' '../src/foo/issue-43893.rs.html#29'
+impl<T> AnotherTrait for T {}
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(decl_macro)]
+
+#![crate_name = "foo"]
+
+use std::vec;
+
+// @has 'foo/index.html'
+// @!has - '//*[@id="macros"]' 'Macros'
+// @!has - '//a/@href' 'macro.vec.html'
+// @!has 'foo/macro.vec.html'
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// @has issue_47197_blank_line_in_doc_block/fn.whose_woods_these_are_i_think_i_know.html
+
+/**
+* snow
+
+* ice
+*/
+pub fn whose_woods_these_are_i_think_i_know() {}
--> $DIR/deref-suggestion.rs:18:9
|
18 | foo(s); //~ ERROR mismatched types
- | ^ expected struct `std::string::String`, found reference
+ | ^
+ | |
+ | expected struct `std::string::String`, found reference
+ | help: try using a conversion method: `s.to_string()`
|
= note: expected type `std::string::String`
found type `&std::string::String`
- = help: here are some functions which might fulfill your needs:
- - .escape_debug()
- - .escape_default()
- - .escape_unicode()
- - .to_ascii_lowercase()
- - .to_ascii_uppercase()
error[E0308]: mismatched types
--> $DIR/deref-suggestion.rs:23:10
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+ let x = 3;
+ match x {
+ 1 | 2 || 3 => (), //~ ERROR unexpected token `||` after pattern
+ _ => (),
+ }
+}
--- /dev/null
+error: unexpected token `||` after pattern
+ --> $DIR/multiple-pattern-typo.rs:14:15
+ |
+14 | 1 | 2 || 3 => (), //~ ERROR unexpected token `||` after pattern
+ | ^^ help: use a single `|` to specify multiple patterns: `|`
+
+error: aborting due to previous error
+
62 | let x: &Bottom = &t; //~ ERROR mismatched types
| ^^ deref recursion limit reached
|
- = help: consider adding a `#[recursion_limit="20"]` attribute to your crate
+ = help: consider adding a `#![recursion_limit="20"]` attribute to your crate
error[E0055]: reached the recursion limit while auto-dereferencing I
|
- = help: consider adding a `#[recursion_limit="20"]` attribute to your crate
+ = help: consider adding a `#![recursion_limit="20"]` attribute to your crate
error[E0308]: mismatched types
--> $DIR/recursion_limit_deref.rs:62:22
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct S;
+
+fn main() {
+ let _ = extern::std::vec::Vec::new(); //~ ERROR `extern` in paths is experimental
+}
--- /dev/null
+error: `extern` in paths is experimental (see issue #44660)
+ --> $DIR/feature-gate-extern_in_paths.rs:14:13
+ |
+14 | let _ = extern::std::vec::Vec::new(); //~ ERROR `extern` in paths is experimental
+ | ^^^^^^
+ |
+ = help: add #![feature(extern_in_paths)] to the crate attributes to enable
+
+error: aborting due to previous error
+
impl issue_41652_b::Tr for S {
fn f() {
3.f()
- //~^ ERROR no method named `f` found for type `{integer}` in the current scope
+ //~^ ERROR can't call method `f` on ambiguous numeric type `{integer}`
}
}
-error[E0599]: no method named `f` found for type `{integer}` in the current scope
+error[E0689]: can't call method `f` on ambiguous numeric type `{integer}`
--> $DIR/issue_41652.rs:19:11
|
19 | 3.f()
| ^
+help: you must specify a concrete type for this numeric value, like `i32`
|
- = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
- = help: try with `{integer}::f`
-note: candidate #1 is defined in the trait `issue_41652_b::Tr`
- --> $DIR/auxiliary/issue_41652_b.rs:14:5
- |
-14 | / fn f()
-15 | | where Self: Sized;
- | |__________________________^
- = help: to disambiguate the method call, write `issue_41652_b::Tr::f(3)` instead
+19 | 3_i32.f()
+ | ^^^^^
error: aborting due to previous error
--> $DIR/issue-44406.rs:18:10
|
18 | foo!(true); //~ ERROR expected type, found keyword
- | ^^^^
+ | ^^^^ expected identifier, found keyword
error: expected type, found keyword `true`
--> $DIR/issue-44406.rs:18:10
}
}
+macro_rules! real_method_stmt {
+ () => {
+ 2.0.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+ }
+}
+
+macro_rules! real_method_expr {
+ () => {
+ 2.0.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+ }
+}
+
fn main() {
fake_method_stmt!();
fake_field_stmt!();
fake_anon_field_stmt!();
+ real_method_stmt!();
let _ = fake_method_expr!();
let _ = fake_field_expr!();
let _ = fake_anon_field_expr!();
+ let _ = real_method_expr!();
}
15 | 1.fake() //~ ERROR no method
| ^^^^
...
-50 | fake_method_stmt!();
+62 | fake_method_stmt!();
| -------------------- in this macro invocation
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
21 | 1.fake //~ ERROR doesn't have fields
| ^^^^
...
-51 | fake_field_stmt!();
+63 | fake_field_stmt!();
| ------------------- in this macro invocation
error[E0609]: no field `0` on type `{integer}`
27 | (1).0 //~ ERROR no field
| ^^^^^
...
-52 | fake_anon_field_stmt!();
+64 | fake_anon_field_stmt!();
| ------------------------ in this macro invocation
+error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
+ --> $DIR/macro-backtrace-invalid-internals.rs:51:15
+ |
+51 | 2.0.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+ | ^^^^
+...
+65 | real_method_stmt!();
+ | -------------------- in this macro invocation
+help: you must specify a concrete type for this numeric value, like `f32`
+ |
+51 | 2.0_f32.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+ | ^^^^^^^
+
error[E0599]: no method named `fake` found for type `{integer}` in the current scope
--> $DIR/macro-backtrace-invalid-internals.rs:33:13
|
33 | 1.fake() //~ ERROR no method
| ^^^^
...
-54 | let _ = fake_method_expr!();
+67 | let _ = fake_method_expr!();
| ------------------- in this macro invocation
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
39 | 1.fake //~ ERROR doesn't have fields
| ^^^^
...
-55 | let _ = fake_field_expr!();
+68 | let _ = fake_field_expr!();
| ------------------ in this macro invocation
error[E0609]: no field `0` on type `{integer}`
45 | (1).0 //~ ERROR no field
| ^^^^^
...
-56 | let _ = fake_anon_field_expr!();
+69 | let _ = fake_anon_field_expr!();
| ----------------------- in this macro invocation
-error: aborting due to 6 previous errors
+error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
+ --> $DIR/macro-backtrace-invalid-internals.rs:57:15
+ |
+57 | 2.0.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+ | ^^^^
+...
+70 | let _ = real_method_expr!();
+ | ------------------- in this macro invocation
+help: you must specify a concrete type for this numeric value, like `f32`
+ |
+57 | 2.0_f32.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+ | ^^^^^^^
+
+error: aborting due to 8 previous errors
= help: add #![feature(non_modrs_mods)] to the crate attributes to enable
= help: on stable builds, rename this file to inner_foors_mod/mod.rs
-error: mod statements in non-mod.rs files are unstable (see issue #44660)
- --> $DIR/some_crazy_attr_mod_dir/arbitrary_name.rs:11:9
- |
-11 | pub mod inner_modrs_mod;
- | ^^^^^^^^^^^^^^^
- |
- = help: add #![feature(non_modrs_mods)] to the crate attributes to enable
- = help: on stable builds, rename this file to attr_mod/mod.rs
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub fn foo() {}
+++ /dev/null
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub mod innest;
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn foo() {}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub mod innest;
--> $DIR/pub-restricted-error.rs:16:16
|
16 | pub(crate) () foo: usize, //~ ERROR expected identifier
- | ^
+ | ^ expected identifier
error: aborting due to previous error
--> $DIR/pub-restricted-non-path.rs:13:6
|
13 | pub (.) fn afn() {} //~ ERROR expected identifier
- | ^
+ | ^ expected identifier
error: aborting due to previous error
|
= note: expected type `usize`
found type `std::string::String`
- = help: here are some functions which might fulfill your needs:
- - .capacity()
- - .len()
error[E0308]: mismatched types
--> $DIR/coerce-suggestions.rs:19:19
--> $DIR/coerce-suggestions.rs:27:9
|
27 | f = box f;
- | ^^^^^ cyclic type of infinite size
+ | ^^^^^
+ | |
+ | cyclic type of infinite size
+ | help: try using a conversion method: `box f.to_string()`
error[E0308]: mismatched types
--> $DIR/coerce-suggestions.rs:31:9
|
= note: expected type `usize`
found type `&'static str`
- = help: here are some functions which might fulfill your needs:
- - .len()
error[E0061]: this function takes 2 parameters but 3 parameters were supplied
--> $DIR/issue-34264.rs:20:5
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::path::{Path, PathBuf};
+
+
+fn main() {
+ let _tis_an_instants_play: String = "'Tis a fond Ambush—"; //~ ERROR mismatched types
+ let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise");
+ //~^ ERROR mismatched types
+
+ let _but_should_the_play: String = 2; // Perhaps surprisingly, we suggest .to_string() here
+ //~^ ERROR mismatched types
+
+ let _prove_piercing_earnest: Vec<usize> = &[1, 2, 3]; //~ ERROR mismatched types
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/conversion-methods.rs:15:41
+ |
+15 | let _tis_an_instants_play: String = "'Tis a fond Ambush—"; //~ ERROR mismatched types
+ | ^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected struct `std::string::String`, found reference
+ | help: try using a conversion method: `"'Tis a fond Ambush—".to_string()`
+ |
+ = note: expected type `std::string::String`
+ found type `&'static str`
+
+error[E0308]: mismatched types
+ --> $DIR/conversion-methods.rs:16:40
+ |
+16 | let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected struct `std::path::PathBuf`, found reference
+ | help: try using a conversion method: `Path::new("/ern/her/own/surprise").to_path_buf()`
+ |
+ = note: expected type `std::path::PathBuf`
+ found type `&std::path::Path`
+
+error[E0308]: mismatched types
+ --> $DIR/conversion-methods.rs:19:40
+ |
+19 | let _but_should_the_play: String = 2; // Perhaps surprisingly, we suggest .to_string() here
+ | ^
+ | |
+ | expected struct `std::string::String`, found integral variable
+ | help: try using a conversion method: `2.to_string()`
+ |
+ = note: expected type `std::string::String`
+ found type `{integer}`
+
+error[E0308]: mismatched types
+ --> $DIR/conversion-methods.rs:22:47
+ |
+22 | let _prove_piercing_earnest: Vec<usize> = &[1, 2, 3]; //~ ERROR mismatched types
+ | ^^^^^^^^^^
+ | |
+ | expected struct `std::vec::Vec`, found reference
+ | help: try using a conversion method: `&[1, 2, 3].to_vec()`
+ |
+ = note: expected type `std::vec::Vec<usize>`
+ found type `&[{integer}; 3]`
+
+error: aborting due to 4 previous errors
+
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[no_mangle] pub const RAH: usize = 5;
+//~^ ERROR const items should never be #[no_mangle]
+
+fn main() {}
--- /dev/null
+error: const items should never be #[no_mangle]
+ --> $DIR/issue-45562.rs:11:14
+ |
+11 | #[no_mangle] pub const RAH: usize = 5;
+ | ---------^^^^^^^^^^^^^^^^
+ | |
+ | help: try a static value: `pub static`
+ |
+ = note: #[deny(no_mangle_const_items)] on by default
+
+error: aborting due to previous error
+
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+ let x = 2.0.powi(2);
+ //~^ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+ let y = 2.0;
+ let x = y.powi(2);
+ //~^ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+ println!("{:?}", x);
+}
--- /dev/null
+error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
+ --> $DIR/method-on-ambiguous-numeric-type.rs:12:17
+ |
+12 | let x = 2.0.powi(2);
+ | ^^^^
+help: you must specify a concrete type for this numeric value, like `f32`
+ |
+12 | let x = 2.0_f32.powi(2);
+ | ^^^^^^^
+
+error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
+ --> $DIR/method-on-ambiguous-numeric-type.rs:15:15
+ |
+15 | let x = y.powi(2);
+ | ^^^^
+help: you must specify a type for this binding, like `f32`
+ |
+14 | let y: f32 = 2.0;
+ | ^^^^^^
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::io;
+
+fn main(){
+ let x: io::IoResult<()> = Ok(());
+ //~^ ERROR cannot find type `IoResult` in module `io`
+ //~| NOTE did you mean `Result`?
+ match x {
+ Err(ref e) if e.kind == io::EndOfFile {
+ //~^ NOTE while parsing this struct
+ return
+ //~^ ERROR expected identifier, found keyword `return`
+ //~| NOTE expected identifier, found keyword
+ }
+ //~^ NOTE expected one of `.`, `=>`, `?`, or an operator here
+ _ => {}
+ //~^ ERROR expected one of `.`, `=>`, `?`, or an operator, found `_`
+ //~| NOTE unexpected token
+ }
+}
--- /dev/null
+error: expected identifier, found keyword `return`
+ --> $DIR/issue-15980.rs:20:13
+ |
+18 | Err(ref e) if e.kind == io::EndOfFile {
+ | ------------- while parsing this struct
+19 | //~^ NOTE while parsing this struct
+20 | return
+ | ^^^^^^ expected identifier, found keyword
+
+error: expected one of `.`, `=>`, `?`, or an operator, found `_`
+ --> $DIR/issue-15980.rs:25:9
+ |
+23 | }
+ | - expected one of `.`, `=>`, `?`, or an operator here
+24 | //~^ NOTE expected one of `.`, `=>`, `?`, or an operator here
+25 | _ => {}
+ | ^ unexpected token
+
+error[E0412]: cannot find type `IoResult` in module `io`
+ --> $DIR/issue-15980.rs:14:16
+ |
+14 | let x: io::IoResult<()> = Ok(());
+ | ^^^^^^^^ did you mean `Result`?
+
+error: aborting due to 3 previous errors
+
"i386-apple-ios",
"i586-pc-windows-msvc",
"i586-unknown-linux-gnu",
+ "i586-unknown-linux-musl",
"i686-apple-darwin",
"i686-linux-android",
"i686-pc-windows-gnu",
env_logger = { version = "0.4", default-features = false }
filetime = "0.1"
getopts = "0.2"
-log = "0.3"
+log = "0.4"
regex = "0.2"
rustc-serialize = "0.3"
use util::logv;
use regex::Regex;
+use std::collections::VecDeque;
use std::collections::HashMap;
use std::collections::HashSet;
use std::env;
}
}
+#[derive(Debug, PartialEq)]
+pub enum DiffLine {
+ Context(String),
+ Expected(String),
+ Resulting(String),
+}
+
+#[derive(Debug, PartialEq)]
+pub struct Mismatch {
+ pub line_number: u32,
+ pub lines: Vec<DiffLine>,
+}
+
+impl Mismatch {
+ fn new(line_number: u32) -> Mismatch {
+ Mismatch {
+ line_number: line_number,
+ lines: Vec::new(),
+ }
+ }
+}
+
+// Produces a diff between the expected output and actual output.
+pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Mismatch> {
+ let mut line_number = 1;
+ let mut context_queue: VecDeque<&str> = VecDeque::with_capacity(context_size);
+ let mut lines_since_mismatch = context_size + 1;
+ let mut results = Vec::new();
+ let mut mismatch = Mismatch::new(0);
+
+ for result in diff::lines(actual, expected) {
+ match result {
+ diff::Result::Left(str) => {
+ if lines_since_mismatch >= context_size && lines_since_mismatch > 0 {
+ results.push(mismatch);
+ mismatch = Mismatch::new(line_number - context_queue.len() as u32);
+ }
+
+ while let Some(line) = context_queue.pop_front() {
+ mismatch.lines.push(DiffLine::Context(line.to_owned()));
+ }
+
+ mismatch.lines.push(DiffLine::Resulting(str.to_owned()));
+ lines_since_mismatch = 0;
+ }
+ diff::Result::Right(str) => {
+ if lines_since_mismatch >= context_size && lines_since_mismatch > 0 {
+ results.push(mismatch);
+ mismatch = Mismatch::new(line_number - context_queue.len() as u32);
+ }
+
+ while let Some(line) = context_queue.pop_front() {
+ mismatch.lines.push(DiffLine::Context(line.to_owned()));
+ }
+
+ mismatch.lines.push(DiffLine::Expected(str.to_owned()));
+ line_number += 1;
+ lines_since_mismatch = 0;
+ }
+ diff::Result::Both(str, _) => {
+ if context_queue.len() >= context_size {
+ let _ = context_queue.pop_front();
+ }
+
+ if lines_since_mismatch < context_size {
+ mismatch.lines.push(DiffLine::Context(str.to_owned()));
+ } else if context_size > 0 {
+ context_queue.push_back(str);
+ }
+
+ line_number += 1;
+ lines_since_mismatch += 1;
+ }
+ }
+ }
+
+ results.push(mismatch);
+ results.remove(0);
+
+ results
+}
+
pub fn run(config: Config, testpaths: &TestPaths) {
match &*config.target {
"arm-linux-androideabi" | "armv7-linux-androideabi" | "aarch64-linux-android" => {
rustc.args(&["-Z", "incremental-queries"]);
}
+ if self.config.mode == CodegenUnits {
+ rustc.args(&["-Z", "human_readable_cgu_names"]);
+ }
+
match self.config.mode {
CompileFail | ParseFail | Incremental => {
// If we are extracting and matching errors in the new
return 0;
}
- println!("normalized {}:\n{}\n", kind, actual);
- println!("expected {}:\n{}\n", kind, expected);
- println!("diff of {}:\n", kind);
-
- for diff in diff::lines(expected, actual) {
- match diff {
- diff::Result::Left(l) => println!("-{}", l),
- diff::Result::Both(l, _) => println!(" {}", l),
- diff::Result::Right(r) => println!("+{}", r),
+ if expected.is_empty() {
+ println!("normalized {}:\n{}\n", kind, actual);
+ } else {
+ println!("diff of {}:\n", kind);
+ let diff_results = make_diff(expected, actual, 3);
+ for result in diff_results {
+ let mut line_number = result.line_number;
+ for line in result.lines {
+ match line {
+ DiffLine::Expected(e) => {
+ println!("-\t{}", e);
+ line_number += 1;
+ },
+ DiffLine::Context(c) => {
+ println!("{}\t{}", line_number, c);
+ line_number += 1;
+ },
+ DiffLine::Resulting(r) => {
+ println!("+\t{}", r);
+ },
+ }
+ }
+ println!("");
}
}
*skipped += data.len();
if data.len() <= TAIL_LEN {
tail[..data.len()].copy_from_slice(data);
- tail.rotate(data.len());
+ tail.rotate_left(data.len());
} else {
tail.copy_from_slice(&data[(data.len() - TAIL_LEN)..]);
}
}
fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> {
- write!(output, "</body>\n</html>")?;
+ write!(output, r##"<script>
+function onEach(arr, func) {{
+ if (arr && arr.length > 0 && func) {{
+ for (var i = 0; i < arr.length; i++) {{
+ func(arr[i]);
+ }}
+ }}
+}}
+
+function hasClass(elem, className) {{
+ if (elem && className && elem.className) {{
+ var elemClass = elem.className;
+ var start = elemClass.indexOf(className);
+ if (start === -1) {{
+ return false;
+ }} else if (elemClass.length === className.length) {{
+ return true;
+ }} else {{
+ if (start > 0 && elemClass[start - 1] !== ' ') {{
+ return false;
+ }}
+ var end = start + className.length;
+ if (end < elemClass.length && elemClass[end] !== ' ') {{
+ return false;
+ }}
+ return true;
+ }}
+ if (start > 0 && elemClass[start - 1] !== ' ') {{
+ return false;
+ }}
+ var end = start + className.length;
+ if (end < elemClass.length && elemClass[end] !== ' ') {{
+ return false;
+ }}
+ return true;
+ }}
+ return false;
+}}
+
+onEach(document.getElementsByClassName('rust-example-rendered'), function(e) {{
+ if (hasClass(e, 'compile_fail')) {{
+ e.addEventListener("mouseover", function(event) {{
+ e.previousElementSibling.childNodes[0].style.color = '#f00';
+ }});
+ e.addEventListener("mouseout", function(event) {{
+ e.previousElementSibling.childNodes[0].style.color = '';
+ }});
+ }} else if (hasClass(e, 'ignore')) {{
+ e.addEventListener("mouseover", function(event) {{
+ e.previousElementSibling.childNodes[0].style.color = '#ff9200';
+ }});
+ e.addEventListener("mouseout", function(event) {{
+ e.previousElementSibling.childNodes[0].style.color = '';
+ }});
+ }}
+}});
+</script>
+</body>
+</html>"##)?;
Ok(())
}
}
file.ends_with("sync/struct.RwLock.html") {
return None;
}
- // FIXME(#47038)
- if file.ends_with("deriving/generic/index.html") ||
- file.ends_with("deriving/generic/macro.vec.html") ||
- file.ends_with("deriving/custom/macro.panic.html") ||
- file.ends_with("proc_macro_impl/macro.panic.html") {
- return None;
- }
let res = load_file(cache, root, file, SkipRedirect);
let (pretty_file, contents) = match res {