From: Mark Simulacrum Date: Tue, 16 May 2017 23:31:49 +0000 (-0600) Subject: Rollup merge of #41937 - nikomatsakis:issue-41936-variance-coerce-unsized-cycle,... X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=8f61055c529d12a04ee077ad42a80b9f9b952cb1;hp=6db4beb3e833eb7d8daad30e2a9ecc27d54a0318;p=rust.git Rollup merge of #41937 - nikomatsakis:issue-41936-variance-coerce-unsized-cycle, r=eddyb use equality in the coerce-unsized check This seems both to be a safe, conservative choice, and it sidesteps the cycle in #41849. Note that, before I converted variance into proper queries, we were using a hybrid of subtyping and equality, due to the presence of a flag that forced invariance if variance had not yet been computed. (Also, Coerce Unsized is unstable.) Fixes #41936. r? @eddyb --- diff --git a/.gitmodules b/.gitmodules index 7cd896b763f..791404344ef 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,7 +13,7 @@ path = src/jemalloc url = https://github.com/rust-lang/jemalloc.git [submodule "src/rust-installer"] - path = src/rust-installer + path = src/tools/rust-installer url = https://github.com/rust-lang/rust-installer.git [submodule "src/liblibc"] path = src/liblibc diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0314a5dfd8d..8f121f8d6ed 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -177,7 +177,7 @@ python x.py test src/test/rustdoc python x.py build src/libcore --stage 0 ``` -You can explore the build system throught the various `--help` pages for each +You can explore the build system through the various `--help` pages for each subcommand. For example to learn more about a command you can run: ``` diff --git a/appveyor.yml b/appveyor.yml index 42c6256a95a..96de1d90f25 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -141,9 +141,9 @@ install: - set PATH="C:\Program Files (x86)\Inno Setup 5";%PATH% # Help debug some handle issues on AppVeyor - - ps: Invoke-WebRequest -Uri https://download.sysinternals.com/files/Handle.zip -OutFile handle.zip + - appveyor-retry appveyor DownloadFile https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-15-Handle.zip - mkdir handle - - ps: Expand-Archive handle.zip -dest handle + - 7z x -ohandle 2017-05-15-Handle.zip - set PATH=%PATH%;%CD%\handle - handle.exe -accepteula -help diff --git a/configure b/configure index db41f0dfb94..af59d5b0bb8 100755 --- a/configure +++ b/configure @@ -519,6 +519,7 @@ valopt_nosave host "${CFG_BUILD}" "GNUs ./configure syntax LLVM host triples" valopt_nosave target "${CFG_HOST}" "GNUs ./configure syntax LLVM target triples" valopt_nosave mandir "${CFG_PREFIX}/share/man" "install man pages in PATH" valopt_nosave docdir "${CFG_PREFIX}/share/doc/rust" "install documentation in PATH" +valopt_nosave bindir "${CFG_PREFIX}/bin" "install binaries" # On Windows this determines root of the subtree for target libraries. # Host runtime libs always go to 'bin'. @@ -710,6 +711,7 @@ envopt LDFLAGS CFG_PREFIX=${CFG_PREFIX%/} CFG_MANDIR=${CFG_MANDIR%/} CFG_DOCDIR=${CFG_DOCDIR%/} +CFG_BINDIR=${CFG_BINDIR%/} CFG_HOST="$(echo $CFG_HOST | tr ',' ' ')" CFG_TARGET="$(echo $CFG_TARGET | tr ',' ' ')" @@ -750,6 +752,7 @@ putvar CFG_X86_64_LINUX_ANDROID_NDK putvar CFG_NACL_CROSS_PATH putvar CFG_MANDIR putvar CFG_DOCDIR +putvar CFG_BINDIR putvar CFG_USING_LIBCPP msg diff --git a/src/Cargo.lock b/src/Cargo.lock index 776a268aa8d..c9de8f99008 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -58,6 +58,29 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "backtrace" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.0 (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.21 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bitflags" version = "0.5.0" @@ -102,6 +125,11 @@ dependencies = [ name = "cargotest2" version = "0.1.0" +[[package]] +name = "cfg-if" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "clap" version = "2.22.1" @@ -115,6 +143,7 @@ dependencies = [ "unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "vec_map 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -158,6 +187,15 @@ dependencies = [ name = "core" version = "0.0.0" +[[package]] +name = "dbghelp-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "diff" version = "0.1.10" @@ -177,6 +215,14 @@ dependencies = [ "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "error-chain" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "error_index_generator" version = "0.0.0" @@ -197,6 +243,15 @@ dependencies = [ "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "flate2" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fmt_macros" version = "0.0.0" @@ -224,7 +279,7 @@ name = "handlebars" version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -233,6 +288,21 @@ dependencies = [ "serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "installer" +version = "0.0.0" +dependencies = [ + "clap 2.22.1 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tar 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "xz2 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.3.1" @@ -249,7 +319,7 @@ dependencies = [ [[package]] name = "lazy_static" -version = "0.2.5" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -273,6 +343,16 @@ name = "log" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lzma-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mdbook" version = "0.0.21" @@ -298,6 +378,15 @@ dependencies = [ "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "miniz-sys" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num-traits" version = "0.1.37" @@ -316,6 +405,14 @@ name = "open" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "owning_ref" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "panic_abort" version = "0.0.0" @@ -442,17 +539,22 @@ dependencies = [ "fmt_macros 0.0.0", "graphviz 0.0.0", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_back 0.0.0", "rustc_bitflags 0.0.0", "rustc_const_math 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", - "rustc_llvm 0.0.0", "serialize 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] +[[package]] +name = "rustc-demangle" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc-main" version = "0.0.0" @@ -552,7 +654,6 @@ dependencies = [ "rustc_errors 0.0.0", "rustc_incremental 0.0.0", "rustc_lint 0.0.0", - "rustc_llvm 0.0.0", "rustc_metadata 0.0.0", "rustc_mir 0.0.0", "rustc_passes 0.0.0", @@ -626,13 +727,13 @@ version = "0.0.0" dependencies = [ "flate 0.0.0", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "proc_macro 0.0.0", "rustc 0.0.0", "rustc_back 0.0.0", "rustc_const_math 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", - "rustc_llvm 0.0.0", "serialize 0.0.0", "syntax 0.0.0", "syntax_ext 0.0.0", @@ -734,6 +835,7 @@ version = "0.0.0" dependencies = [ "flate 0.0.0", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_back 0.0.0", "rustc_bitflags 0.0.0", @@ -800,6 +902,15 @@ dependencies = [ "syntax_pos 0.0.0", ] +[[package]] +name = "same-file" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "serde" version = "0.9.11" @@ -820,6 +931,11 @@ dependencies = [ name = "serialize" version = "0.0.0" +[[package]] +name = "stable_deref_trait" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "std" version = "0.0.0" @@ -887,6 +1003,16 @@ dependencies = [ "serialize 0.0.0", ] +[[package]] +name = "tar" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "term" version = "0.0.0" @@ -980,6 +1106,16 @@ name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "walkdir" +version = "1.0.7" +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)", + "same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi" version = "0.2.8" @@ -990,31 +1126,61 @@ name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "xattr" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "xz2" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lzma-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "yaml-rust" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [metadata] "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" "checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159" +"checksum backtrace 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f551bc2ddd53aea015d453ef0b635af89444afa5ed2405dd0b2062ad5d600d80" +"checksum backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d192fd129132fbc97497c1f2ec2c2c5174e376b95f535199ef4fe0a293d33842" "checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23" "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4" +"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c" "checksum clap 2.22.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e17a4a72ffea176f77d6e2db609c6c919ef221f23862c9915e687fb54d833485" "checksum cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "92278eb79412c8f75cfc89e707a1bb3a6490b68f7f2e78d15c774f30fe701122" +"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum diff 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0a515461b6c8c08419850ced27bc29e86166dcdcde8fbe76f8b1f0589bb49472" "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90" "checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83" +"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" "checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922" +"checksum flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "36df0166e856739905cd3d7e0b210fe818592211a008862599845e012d8d304c" "checksum gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)" = "181e3cebba1d663bd92eb90e2da787e10597e027eb00de8d742b260a7850948f" "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685" "checksum handlebars 0.25.2 (registry+https://github.com/rust-lang/crates.io-index)" = "663e1728d8037fb0d4e13bcd1b1909fb5d913690a9929eb385922df157c2ff8f" "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum lazy_static 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4732c563b9a21a406565c4747daa7b46742f082911ae4753f390dc9ec7ee1a97" +"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" "checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135" "checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad" +"checksum lzma-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fedff6a5cbb24494ec6ee4784e9ac5c187161fede04c7767d49bf87544013afa" "checksum mdbook 0.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "f1e2e9d848514dcfad4195788d0d42ae5153a477c191d75d5b84fab10f222fbd" "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" +"checksum miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "28eaee17666671fa872e567547e8428e83308ebe5808cdf6a0e28397dbe2c726" "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99" "checksum num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca313f1862c7ec3e0dfe8ace9fa91b1d9cb5c84ace3d00f5ec4216238e93c167" "checksum open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3478ed1686bd1300c8a981a940abc92b06fac9cbef747f4c668d4e032ff7b842" +"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8" "checksum pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ab1e588ef8efd702c7ed9d2bd774db5e6f4d878bb5a1a9f371828fbdff6973" "checksum pulldown-cmark 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1058d7bb927ca067656537eec4e02c2b4b70eaaa129664c5b90c111e20326f41" @@ -1023,10 +1189,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457" "checksum rls-data 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fc4277ce3c57f456b11fe3145b181a844a25201bab5cbaa1978457e6e2f27d47" "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a" +"checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95" "checksum rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "684ce48436d6465300c9ea783b6b14c4361d6b8dcbb1375b486a69cc19e2dfb0" +"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7" "checksum serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a702319c807c016e51f672e5c77d6f0b46afddd744b5e437d6b8436b888b458f" "checksum serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc45439552eb8fb86907a2c41c1fd0ef97458efb87ff7f878db466eb581824e" +"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" +"checksum tar 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ab0ef9ead2fe0aa9e18475a96a207bfd5143f4124779ef7429503a8665416ce8" "checksum term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "07b6c1ac5b3fffd75073276bca1ceed01f67a28537097a2a9539e116e50fb21a" "checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a" "checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7" @@ -1038,5 +1208,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum vec_map 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8cdc8b93bd0198ed872357fb2e667f7125646b1762f16d60b2c96350d361897" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "5f04de8a1346489a2f9e9bd8526b73d135ec554227b17568456e86aa35b6f3fc" +"checksum xz2 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e9510bdf100731599107c61f77daf46713a69a568f75458999c1f9dbf6ba25b0" +"checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" diff --git a/src/Cargo.toml b/src/Cargo.toml index 9aca3e134d6..99e8b9f256a 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -13,6 +13,7 @@ members = [ "tools/build-manifest", "tools/remote-test-client", "tools/remote-test-server", + "tools/rust-installer", ] # These projects have their own Cargo.lock diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 9c536111811..0fb597564e3 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -99,7 +99,9 @@ pub struct Config { // Fallback musl-root for all targets pub musl_root: Option, pub prefix: Option, + pub sysconfdir: Option, pub docdir: Option, + pub bindir: Option, pub libdir: Option, pub libdir_relative: Option, pub mandir: Option, @@ -165,9 +167,11 @@ struct Build { #[derive(RustcDecodable, Default, Clone)] struct Install { prefix: Option, - mandir: Option, + sysconfdir: Option, docdir: Option, + bindir: Option, libdir: Option, + mandir: Option, } /// TOML representation of how the LLVM build is configured. @@ -315,9 +319,11 @@ pub fn parse(build: &str, file: Option) -> Config { if let Some(ref install) = toml.install { config.prefix = install.prefix.clone().map(PathBuf::from); - config.mandir = install.mandir.clone().map(PathBuf::from); + config.sysconfdir = install.sysconfdir.clone().map(PathBuf::from); config.docdir = install.docdir.clone().map(PathBuf::from); + config.bindir = install.bindir.clone().map(PathBuf::from); config.libdir = install.libdir.clone().map(PathBuf::from); + config.mandir = install.mandir.clone().map(PathBuf::from); } if let Some(ref llvm) = toml.llvm { @@ -523,9 +529,15 @@ macro_rules! check { "CFG_PREFIX" => { self.prefix = Some(PathBuf::from(value)); } + "CFG_SYSCONFDIR" => { + self.sysconfdir = Some(PathBuf::from(value)); + } "CFG_DOCDIR" => { self.docdir = Some(PathBuf::from(value)); } + "CFG_BINDIR" => { + self.bindir = Some(PathBuf::from(value)); + } "CFG_LIBDIR" => { self.libdir = Some(PathBuf::from(value)); } diff --git a/src/bootstrap/config.toml.example b/src/bootstrap/config.toml.example index 25da976a555..df180be4e27 100644 --- a/src/bootstrap/config.toml.example +++ b/src/bootstrap/config.toml.example @@ -160,15 +160,22 @@ # Instead of installing to /usr/local, install to this path instead. #prefix = "/usr/local" +# Where to install system configuration files +# If this is a relative path, it will get installed in `prefix` above +#sysconfdir = "/etc" + +# Where to install documentation in `prefix` above +#docdir = "share/doc/rust" + +# Where to install binaries in `prefix` above +#bindir = "bin" + # Where to install libraries in `prefix` above #libdir = "lib" # Where to install man pages in `prefix` above #mandir = "share/man" -# Where to install documentation in `prefix` above -#docdir = "share/doc/rust" - # ============================================================================= # Options for compiling Rust code itself # ============================================================================= diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 1b69f7413b5..6557b8410b1 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -26,12 +26,6 @@ use build_helper::output; -#[cfg(not(target_os = "solaris"))] -const SH_CMD: &'static str = "sh"; -// On Solaris, sh is the historical bourne shell, not a POSIX shell, or bash. -#[cfg(target_os = "solaris")] -const SH_CMD: &'static str = "bash"; - use {Build, Compiler, Mode}; use channel; use util::{cp_r, libdir, is_dylib, cp_filtered, copy, exe}; @@ -55,6 +49,10 @@ pub fn tmpdir(build: &Build) -> PathBuf { build.out.join("tmp/dist") } +fn rust_installer(build: &Build) -> Command { + build.tool_cmd(&Compiler::new(0, &build.config.build), "rust-installer") +} + /// Builds the `rust-docs` installer component. /// /// Slurps up documentation from the `stage`'s `host`. @@ -74,14 +72,14 @@ pub fn docs(build: &Build, stage: u32, host: &str) { let src = build.out.join(host).join("doc"); cp_r(&src, &dst); - let mut cmd = Command::new(SH_CMD); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust-Documentation") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-documentation-is-installed.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) .arg(format!("--package-name={}-{}", name, host)) .arg("--component-name=rust-docs") .arg("--legacy-manifest-dirs=rustlib,cargo") @@ -124,14 +122,14 @@ pub fn mingw(build: &Build, host: &str) { .arg(host); build.run(&mut cmd); - let mut cmd = Command::new(SH_CMD); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust-MinGW") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-MinGW-is-installed.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) .arg(format!("--package-name={}-{}", name, host)) .arg("--component-name=rust-mingw") .arg("--legacy-manifest-dirs=rustlib,cargo"); @@ -190,15 +188,15 @@ pub fn rustc(build: &Build, stage: u32, host: &str) { } // Finally, wrap everything up in a nice tarball! - let mut cmd = Command::new(SH_CMD); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-is-ready-to-roll.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) - .arg(format!("--non-installed-overlay={}", sanitize_sh(&overlay))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) + .arg("--non-installed-overlay").arg(&overlay) .arg(format!("--package-name={}-{}", name, host)) .arg("--component-name=rustc") .arg("--legacy-manifest-dirs=rustlib,cargo"); @@ -300,14 +298,14 @@ pub fn std(build: &Build, compiler: &Compiler, target: &str) { let src = build.sysroot(compiler).join("lib/rustlib"); cp_r(&src.join(target), &dst); - let mut cmd = Command::new(SH_CMD); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=std-is-standing-at-the-ready.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) .arg(format!("--package-name={}-{}", name, target)) .arg(format!("--component-name=rust-std-{}", target)) .arg("--legacy-manifest-dirs=rustlib,cargo"); @@ -356,14 +354,14 @@ pub fn analysis(build: &Build, compiler: &Compiler, target: &str) { println!("image_src: {:?}, dst: {:?}", image_src, dst); cp_r(&image_src, &dst); - let mut cmd = Command::new(SH_CMD); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=save-analysis-saved.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) .arg(format!("--package-name={}-{}", name, target)) .arg(format!("--component-name=rust-analysis-{}", target)) .arg("--legacy-manifest-dirs=rustlib,cargo"); @@ -471,13 +469,17 @@ pub fn rust_src(build: &Build) { write_file(&plain_dst_src.join("version"), build.rust_version().as_bytes()); // Create plain source tarball - let tarball = rust_src_location(build); + let mut tarball = rust_src_location(build); + tarball.set_extension(""); // strip .gz + tarball.set_extension(""); // strip .tar if let Some(dir) = tarball.parent() { t!(fs::create_dir_all(dir)); } - let mut cmd = Command::new("tar"); - cmd.arg("-czf").arg(sanitize_sh(&tarball)) - .arg(&plain_name) + let mut cmd = rust_installer(build); + cmd.arg("tarball") + .arg("--input").arg(&plain_name) + .arg("--output").arg(&tarball) + .arg("--work-dir=.") .current_dir(tmpdir(build)); build.run(&mut cmd); @@ -521,14 +523,14 @@ pub fn rust_src(build: &Build) { } // Create source tarball in rust-installer format - let mut cmd = Command::new(SH_CMD); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Awesome-Source.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) .arg(format!("--package-name={}", name)) .arg("--component-name=rust-src") .arg("--legacy-manifest-dirs=rustlib,cargo"); @@ -622,15 +624,15 @@ pub fn cargo(build: &Build, stage: u32, target: &str) { t!(t!(File::create(overlay.join("version"))).write_all(version.as_bytes())); // Generate the installer tarball - let mut cmd = Command::new("sh"); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-is-ready-to-roll.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) - .arg(format!("--non-installed-overlay={}", sanitize_sh(&overlay))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) + .arg("--non-installed-overlay").arg(&overlay) .arg(format!("--package-name={}-{}", name, target)) .arg("--component-name=cargo") .arg("--legacy-manifest-dirs=rustlib,cargo"); @@ -671,15 +673,15 @@ pub fn rls(build: &Build, stage: u32, target: &str) { t!(t!(File::create(overlay.join("version"))).write_all(version.as_bytes())); // Generate the installer tarball - let mut cmd = Command::new("sh"); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=RLS-ready-to-serve.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) - .arg(format!("--non-installed-overlay={}", sanitize_sh(&overlay))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) + .arg("--non-installed-overlay").arg(&overlay) .arg(format!("--package-name={}-{}", name, target)) .arg("--component-name=rls") .arg("--legacy-manifest-dirs=rustlib,cargo"); @@ -730,29 +732,28 @@ pub fn extended(build: &Build, stage: u32, target: &str) { // upgrades rustc was upgraded before rust-std. To avoid rustc clobbering // the std files during uninstall. To do this ensure that rustc comes // before rust-std in the list below. - let mut input_tarballs = format!("{},{},{},{},{},{}", - sanitize_sh(&rustc_installer), - sanitize_sh(&cargo_installer), - sanitize_sh(&rls_installer), - sanitize_sh(&analysis_installer), - sanitize_sh(&docs_installer), - sanitize_sh(&std_installer)); + let mut tarballs = vec![rustc_installer, cargo_installer, rls_installer, + analysis_installer, docs_installer, std_installer]; if target.contains("pc-windows-gnu") { - input_tarballs.push_str(","); - input_tarballs.push_str(&sanitize_sh(&mingw_installer)); + tarballs.push(mingw_installer); + } + let mut input_tarballs = tarballs[0].as_os_str().to_owned(); + for tarball in &tarballs[1..] { + input_tarballs.push(","); + input_tarballs.push(tarball); } - let mut cmd = Command::new(SH_CMD); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/combine-installers.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("combine") .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-is-ready-to-roll.") - .arg(format!("--work-dir={}", sanitize_sh(&work))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) + .arg("--work-dir").arg(&work) + .arg("--output-dir").arg(&distdir(build)) .arg(format!("--package-name={}-{}", pkgname(build, "rust"), target)) .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg(format!("--input-tarballs={}", input_tarballs)) - .arg(format!("--non-installed-overlay={}", sanitize_sh(&overlay))); + .arg("--input-tarballs").arg(input_tarballs) + .arg("--non-installed-overlay").arg(&overlay); build.run(&mut cmd); let mut license = String::new(); diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index c805522fbf5..386b001971b 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -24,22 +24,30 @@ /// Installs everything. pub fn install(build: &Build, stage: u32, host: &str) { let prefix_default = PathBuf::from("/usr/local"); + let sysconfdir_default = PathBuf::from("/etc"); let docdir_default = PathBuf::from("share/doc/rust"); - let mandir_default = PathBuf::from("share/man"); + let bindir_default = PathBuf::from("bin"); let libdir_default = PathBuf::from("lib"); + let mandir_default = PathBuf::from("share/man"); let prefix = build.config.prefix.as_ref().unwrap_or(&prefix_default); + let sysconfdir = build.config.sysconfdir.as_ref().unwrap_or(&sysconfdir_default); let docdir = build.config.docdir.as_ref().unwrap_or(&docdir_default); + let bindir = build.config.bindir.as_ref().unwrap_or(&bindir_default); let libdir = build.config.libdir.as_ref().unwrap_or(&libdir_default); let mandir = build.config.mandir.as_ref().unwrap_or(&mandir_default); + let sysconfdir = prefix.join(sysconfdir); let docdir = prefix.join(docdir); + let bindir = prefix.join(bindir); let libdir = prefix.join(libdir); let mandir = prefix.join(mandir); let destdir = env::var_os("DESTDIR").map(PathBuf::from); let prefix = add_destdir(&prefix, &destdir); + let sysconfdir = add_destdir(&sysconfdir, &destdir); let docdir = add_destdir(&docdir, &destdir); + let bindir = add_destdir(&bindir, &destdir); let libdir = add_destdir(&libdir, &destdir); let mandir = add_destdir(&mandir, &destdir); @@ -47,29 +55,35 @@ pub fn install(build: &Build, stage: u32, host: &str) { t!(fs::create_dir_all(&empty_dir)); if build.config.docs { install_sh(&build, "docs", "rust-docs", &build.rust_package_vers(), - stage, host, &prefix, &docdir, &libdir, &mandir, &empty_dir); + stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, + &mandir, &empty_dir); } for target in build.config.target.iter() { install_sh(&build, "std", "rust-std", &build.rust_package_vers(), - stage, target, &prefix, &docdir, &libdir, &mandir, &empty_dir); + stage, target, &prefix, &sysconfdir, &docdir, &bindir, &libdir, + &mandir, &empty_dir); } if build.config.extended { install_sh(&build, "cargo", "cargo", &build.cargo_package_vers(), - stage, host, &prefix, &docdir, &libdir, &mandir, &empty_dir); + stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, + &mandir, &empty_dir); install_sh(&build, "rls", "rls", &build.rls_package_vers(), - stage, host, &prefix, &docdir, &libdir, &mandir, &empty_dir); + stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, + &mandir, &empty_dir); } install_sh(&build, "rustc", "rustc", &build.rust_package_vers(), - stage, host, &prefix, &docdir, &libdir, &mandir, &empty_dir); + stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, + &mandir, &empty_dir); t!(fs::remove_dir_all(&empty_dir)); } fn install_sh(build: &Build, package: &str, name: &str, version: &str, stage: u32, host: &str, - prefix: &Path, docdir: &Path, libdir: &Path, mandir: &Path, empty_dir: &Path) { + prefix: &Path, sysconfdir: &Path, docdir: &Path, bindir: &Path, libdir: &Path, + mandir: &Path, empty_dir: &Path) { println!("Install {} stage{} ({})", package, stage, host); let package_name = format!("{}-{}-{}", name, version, host); @@ -77,7 +91,9 @@ fn install_sh(build: &Build, package: &str, name: &str, version: &str, stage: u3 cmd.current_dir(empty_dir) .arg(sanitize_sh(&tmpdir(build).join(&package_name).join("install.sh"))) .arg(format!("--prefix={}", sanitize_sh(prefix))) + .arg(format!("--sysconfdir={}", sanitize_sh(sysconfdir))) .arg(format!("--docdir={}", sanitize_sh(docdir))) + .arg(format!("--bindir={}", sanitize_sh(bindir))) .arg(format!("--libdir={}", sanitize_sh(libdir))) .arg(format!("--mandir={}", sanitize_sh(mandir))) .arg("--disable-ldconfig"); diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs index 970c0bc565d..92666e8e639 100644 --- a/src/bootstrap/step.rs +++ b/src/bootstrap/step.rs @@ -574,6 +574,10 @@ fn crate_rule<'a, 'b>(build: &'a Build, .dep(|s| s.name("maybe-clean-tools")) .dep(|s| s.name("libstd-tool")) .run(move |s| compile::tool(build, s.stage, s.target, "remote-test-client")); + rules.build("tool-rust-installer", "src/tools/rust-installer") + .dep(|s| s.name("maybe-clean-tools")) + .dep(|s| s.name("libstd-tool")) + .run(move |s| compile::tool(build, s.stage, s.target, "rust-installer")); rules.build("tool-cargo", "src/tools/cargo") .host(true) .default(build.config.extended) @@ -704,6 +708,7 @@ fn crate_rule<'a, 'b>(build: &'a Build, .host(true) .only_host_build(true) .default(true) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| dist::rustc(build, s.stage, s.target)); rules.dist("dist-std", "src/libstd") .dep(move |s| { @@ -718,10 +723,12 @@ fn crate_rule<'a, 'b>(build: &'a Build, }) .default(true) .only_host_build(true) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| dist::std(build, &s.compiler(), s.target)); rules.dist("dist-mingw", "path/to/nowhere") .default(true) .only_host_build(true) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| { if s.target.contains("pc-windows-gnu") { dist::mingw(build, s.target) @@ -732,21 +739,25 @@ fn crate_rule<'a, 'b>(build: &'a Build, .host(true) .only_build(true) .only_host_build(true) + .dep(move |s| tool_rust_installer(build, s)) .run(move |_| dist::rust_src(build)); rules.dist("dist-docs", "src/doc") .default(true) .only_host_build(true) .dep(|s| s.name("default:doc")) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| dist::docs(build, s.stage, s.target)); rules.dist("dist-analysis", "analysis") .default(build.config.extended) .dep(|s| s.name("dist-std")) .only_host_build(true) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| dist::analysis(build, &s.compiler(), s.target)); rules.dist("dist-rls", "rls") .host(true) .only_host_build(true) .dep(|s| s.name("tool-rls")) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| dist::rls(build, s.stage, s.target)); rules.dist("install", "path/to/nowhere") .dep(|s| s.name("default:dist")) @@ -755,6 +766,7 @@ fn crate_rule<'a, 'b>(build: &'a Build, .host(true) .only_host_build(true) .dep(|s| s.name("tool-cargo")) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| dist::cargo(build, s.stage, s.target)); rules.dist("dist-extended", "extended") .default(build.config.extended) @@ -767,6 +779,7 @@ fn crate_rule<'a, 'b>(build: &'a Build, .dep(|d| d.name("dist-cargo")) .dep(|d| d.name("dist-rls")) .dep(|d| d.name("dist-analysis")) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| dist::extended(build, s.stage, s.target)); rules.dist("dist-sign", "hash-and-sign") @@ -778,6 +791,14 @@ fn crate_rule<'a, 'b>(build: &'a Build, rules.verify(); return rules; + + /// Helper to depend on a stage0 build-only rust-installer tool. + fn tool_rust_installer<'a>(build: &'a Build, step: &Step<'a>) -> Step<'a> { + step.name("tool-rust-installer") + .host(&build.config.build) + .target(&build.config.build) + .stage(0) + } } #[derive(PartialEq, Eq, Hash, Clone, Debug)] diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md index 8f26e4d36cd..39f80059148 100644 --- a/src/doc/unstable-book/src/SUMMARY.md +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -217,6 +217,7 @@ - [unique](library-features/unique.md) - [unsize](library-features/unsize.md) - [utf8_error_error_len](library-features/utf8-error-error-len.md) + - [vec_resize_default](library-features/vec-resize-default.md) - [vec_remove_item](library-features/vec-remove-item.md) - [windows_c](library-features/windows-c.md) - [windows_handle](library-features/windows-handle.md) diff --git a/src/doc/unstable-book/src/library-features/vec-resize-default.md b/src/doc/unstable-book/src/library-features/vec-resize-default.md new file mode 100644 index 00000000000..5803d3215a5 --- /dev/null +++ b/src/doc/unstable-book/src/library-features/vec-resize-default.md @@ -0,0 +1,7 @@ +# `vec_resize_default` + +The tracking issue for this feature is: [#41758] + +[#41758]: https://github.com/rust-lang/rust/issues/41758 + +------------------------ diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 7ec5c29de6b..1cf713290d8 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1220,11 +1220,14 @@ pub fn split_off(&mut self, at: usize) -> Self { } impl Vec { - /// Resizes the `Vec` in-place so that `len()` is equal to `new_len`. + /// Resizes the `Vec` in-place so that `len` is equal to `new_len`. /// - /// If `new_len` is greater than `len()`, the `Vec` is extended by the + /// If `new_len` is greater than `len`, the `Vec` is extended by the /// difference, with each additional slot filled with `value`. - /// If `new_len` is less than `len()`, the `Vec` is simply truncated. + /// If `new_len` is less than `len`, the `Vec` is simply truncated. + /// + /// This method requires `Clone` to clone the passed value. If you'd + /// rather create a value with `Default` instead, see [`resize_default`]. /// /// # Examples /// @@ -1237,19 +1240,100 @@ impl Vec { /// vec.resize(2, 0); /// assert_eq!(vec, [1, 2]); /// ``` + /// + /// [`resize_default`]: #method.resize_default #[stable(feature = "vec_resize", since = "1.5.0")] pub fn resize(&mut self, new_len: usize, value: T) { let len = self.len(); if new_len > len { - self.extend_with_element(new_len - len, value); + self.extend_with(new_len - len, ExtendElement(value)) + } else { + self.truncate(new_len); + } + } + + /// Clones and appends all elements in a slice to the `Vec`. + /// + /// Iterates over the slice `other`, clones each element, and then appends + /// it to this `Vec`. The `other` vector is traversed in-order. + /// + /// Note that this function is same as `extend` except that it is + /// specialized to work with slices instead. If and when Rust gets + /// specialization this function will likely be deprecated (but still + /// available). + /// + /// # Examples + /// + /// ``` + /// let mut vec = vec![1]; + /// vec.extend_from_slice(&[2, 3, 4]); + /// assert_eq!(vec, [1, 2, 3, 4]); + /// ``` + #[stable(feature = "vec_extend_from_slice", since = "1.6.0")] + pub fn extend_from_slice(&mut self, other: &[T]) { + self.spec_extend(other.iter()) + } +} + +impl Vec { + /// Resizes the `Vec` in-place so that `len` is equal to `new_len`. + /// + /// If `new_len` is greater than `len`, the `Vec` is extended by the + /// difference, with each additional slot filled with `Default::default()`. + /// If `new_len` is less than `len`, the `Vec` is simply truncated. + /// + /// This method uses `Default` to create new values on every push. If + /// you'd rather `Clone` a given value, use [`resize`]. + /// + /// + /// # Examples + /// + /// ``` + /// #![feature(vec_resize_default)] + /// + /// let mut vec = vec![1, 2, 3]; + /// vec.resize_default(5); + /// assert_eq!(vec, [1, 2, 3, 0, 0]); + /// + /// let mut vec = vec![1, 2, 3, 4]; + /// vec.resize_default(2); + /// assert_eq!(vec, [1, 2]); + /// ``` + /// + /// [`resize`]: #method.resize + #[unstable(feature = "vec_resize_default", issue = "41758")] + pub fn resize_default(&mut self, new_len: usize) { + let len = self.len(); + + if new_len > len { + self.extend_with(new_len - len, ExtendDefault); } else { self.truncate(new_len); } } +} - /// Extend the vector by `n` additional clones of `value`. - fn extend_with_element(&mut self, n: usize, value: T) { +// This code generalises `extend_with_{element,default}`. +trait ExtendWith { + fn next(&self) -> T; + fn last(self) -> T; +} + +struct ExtendElement(T); +impl ExtendWith for ExtendElement { + fn next(&self) -> T { self.0.clone() } + fn last(self) -> T { self.0 } +} + +struct ExtendDefault; +impl ExtendWith for ExtendDefault { + fn next(&self) -> T { Default::default() } + fn last(self) -> T { Default::default() } +} +impl Vec { + /// Extend the vector by `n` values, using the given generator. + fn extend_with>(&mut self, n: usize, value: E) { self.reserve(n); unsafe { @@ -1261,43 +1345,21 @@ fn extend_with_element(&mut self, n: usize, value: T) { // Write all elements except the last one for _ in 1..n { - ptr::write(ptr, value.clone()); + ptr::write(ptr, value.next()); ptr = ptr.offset(1); - // Increment the length in every step in case clone() panics + // Increment the length in every step in case next() panics local_len.increment_len(1); } if n > 0 { // We can write the last element directly without cloning needlessly - ptr::write(ptr, value); + ptr::write(ptr, value.last()); local_len.increment_len(1); } // len set by scope guard } } - - /// Clones and appends all elements in a slice to the `Vec`. - /// - /// Iterates over the slice `other`, clones each element, and then appends - /// it to this `Vec`. The `other` vector is traversed in-order. - /// - /// Note that this function is same as `extend` except that it is - /// specialized to work with slices instead. If and when Rust gets - /// specialization this function will likely be deprecated (but still - /// available). - /// - /// # Examples - /// - /// ``` - /// let mut vec = vec![1]; - /// vec.extend_from_slice(&[2, 3, 4]); - /// assert_eq!(vec, [1, 2, 3, 4]); - /// ``` - #[stable(feature = "vec_extend_from_slice", since = "1.6.0")] - pub fn extend_from_slice(&mut self, other: &[T]) { - self.spec_extend(other.iter()) - } } // Set the length of the vec when the `SetLenOnDrop` value goes out of scope. @@ -1389,7 +1451,7 @@ trait SpecFromElem: Sized { impl SpecFromElem for T { default fn from_elem(elem: Self, n: usize) -> Vec { let mut v = Vec::with_capacity(n); - v.extend_with_element(n, elem); + v.extend_with(n, ExtendElement(elem)); v } } @@ -1424,7 +1486,7 @@ fn from_elem(elem: $t, n: usize) -> Vec<$t> { } } let mut v = Vec::with_capacity(n); - v.extend_with_element(n, elem); + v.extend_with(n, ExtendElement(elem)); v } } diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index fa217acd9f9..9d64f511914 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -13,12 +13,12 @@ arena = { path = "../libarena" } fmt_macros = { path = "../libfmt_macros" } graphviz = { path = "../libgraphviz" } log = "0.3" +owning_ref = "0.3.3" rustc_back = { path = "../librustc_back" } rustc_bitflags = { path = "../librustc_bitflags" } rustc_const_math = { path = "../librustc_const_math" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } -rustc_llvm = { path = "../librustc_llvm" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 5cf26ea8bfc..f32ee790064 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -54,7 +54,7 @@ extern crate getopts; extern crate graphviz; extern crate libc; -extern crate rustc_llvm as llvm; +extern crate owning_ref; extern crate rustc_back; extern crate rustc_data_structures; extern crate serialize; diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 569b1aeeb09..a68aca46000 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -36,8 +36,9 @@ use util::nodemap::{NodeSet, DefIdMap}; use std::any::Any; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::rc::Rc; +use owning_ref::ErasedBoxRef; use syntax::ast; use syntax::ext::base::SyntaxExtension; use syntax::symbol::Symbol; @@ -201,11 +202,33 @@ pub fn new() -> EncodedMetadataHashes { } } +/// The backend's way to give the crate store access to the metadata in a library. +/// Note that it returns the raw metadata bytes stored in the library file, whether +/// it is compressed, uncompressed, some weird mix, etc. +/// rmeta files are backend independent and not handled here. +/// +/// At the time of this writing, there is only one backend and one way to store +/// metadata in library -- this trait just serves to decouple rustc_metadata from +/// the archive reader, which depends on LLVM. +pub trait MetadataLoader { + fn get_rlib_metadata(&self, + target: &Target, + filename: &Path) + -> Result, String>; + fn get_dylib_metadata(&self, + target: &Target, + filename: &Path) + -> Result, String>; +} + /// A store of Rust crates, through with their metadata /// can be accessed. pub trait CrateStore { fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc; + // access to the metadata loader + fn metadata_loader(&self) -> &MetadataLoader; + // item info fn visibility(&self, def: DefId) -> ty::Visibility; fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap>; @@ -275,8 +298,6 @@ fn item_body<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) fn used_link_args(&self) -> Vec; // utility functions - fn metadata_filename(&self) -> &str; - fn metadata_section_name(&self, target: &Target) -> &str; fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>; fn used_crate_source(&self, cnum: CrateNum) -> CrateSource; fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option; @@ -413,8 +434,6 @@ fn used_libraries(&self) -> Vec { vec![] } fn used_link_args(&self) -> Vec { vec![] } // utility functions - fn metadata_filename(&self) -> &str { bug!("metadata_filename") } - fn metadata_section_name(&self, target: &Target) -> &str { bug!("metadata_section_name") } fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> { vec![] } fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") } @@ -427,6 +446,9 @@ fn encode_metadata<'a, 'tcx>(&self, bug!("encode_metadata") } fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") } + + // access to the metadata loader + fn metadata_loader(&self) -> &MetadataLoader { bug!("metadata_loader") } } pub trait CrateLoader { diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 884a71f0d32..4212fa1f8b1 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -328,7 +328,7 @@ pub struct Options { } ); -#[derive(Clone, PartialEq, Eq)] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum PrintRequest { FileNames, Sysroot, diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 2e2d5a6bd4d..814246330a4 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -37,19 +37,16 @@ use rustc_back::{LinkerFlavor, PanicStrategy}; use rustc_back::target::Target; use rustc_data_structures::flock; -use llvm; use std::path::{Path, PathBuf}; use std::cell::{self, Cell, RefCell}; use std::collections::HashMap; use std::env; -use std::ffi::CString; use std::io::Write; use std::rc::Rc; use std::fmt; use std::time::Duration; use std::sync::Arc; -use libc::c_int; mod code_stats; pub mod config; @@ -713,8 +710,6 @@ pub fn build_session_(sopts: config::Options, out_of_fuel: Cell::new(false), }; - init_llvm(&sess); - sess } @@ -743,55 +738,6 @@ pub enum IncrCompSession { } } -fn init_llvm(sess: &Session) { - unsafe { - // Before we touch LLVM, make sure that multithreading is enabled. - use std::sync::Once; - static INIT: Once = Once::new(); - static mut POISONED: bool = false; - INIT.call_once(|| { - if llvm::LLVMStartMultithreaded() != 1 { - // use an extra bool to make sure that all future usage of LLVM - // cannot proceed despite the Once not running more than once. - POISONED = true; - } - - configure_llvm(sess); - }); - - if POISONED { - bug!("couldn't enable multi-threaded LLVM"); - } - } -} - -unsafe fn configure_llvm(sess: &Session) { - let mut llvm_c_strs = Vec::new(); - let mut llvm_args = Vec::new(); - - { - let mut add = |arg: &str| { - let s = CString::new(arg).unwrap(); - llvm_args.push(s.as_ptr()); - llvm_c_strs.push(s); - }; - add("rustc"); // fake program name - if sess.time_llvm_passes() { add("-time-passes"); } - if sess.print_llvm_passes() { add("-debug-pass=Structure"); } - - for arg in &sess.opts.cg.llvm_args { - add(&(*arg)); - } - } - - llvm::LLVMInitializePasses(); - - llvm::initialize_available_targets(); - - llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, - llvm_args.as_ptr()); -} - pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { let emitter: Box = match output { config::ErrorOutputType::HumanReadable(color_config) => { diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 5b5113caa8e..2e949f48c17 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -22,7 +22,6 @@ rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_incremental = { path = "../librustc_incremental" } rustc_lint = { path = "../librustc_lint" } -rustc_llvm = { path = "../librustc_llvm" } rustc_metadata = { path = "../librustc_metadata" } rustc_mir = { path = "../librustc_mir" } rustc_passes = { path = "../librustc_passes" } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 024fc546a15..34f636d0b9a 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -56,7 +56,6 @@ extern crate rustc_trans; extern crate rustc_typeck; extern crate serialize; -extern crate rustc_llvm as llvm; #[macro_use] extern crate log; extern crate syntax; @@ -70,7 +69,7 @@ use rustc_save_analysis as save; use rustc_save_analysis::DumpHandler; use rustc_trans::back::link; -use rustc_trans::back::write::{create_target_machine, RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS}; +use rustc_trans::back::write::{RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS}; use rustc::dep_graph::DepGraph; use rustc::session::{self, config, Session, build_session, CompileResult}; use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType}; @@ -182,7 +181,7 @@ macro_rules! do_or_return {($expr: expr, $sess: expr) => { let (sopts, cfg) = config::build_session_options_and_crate_config(&matches); if sopts.debugging_opts.debug_llvm { - unsafe { llvm::LLVMRustSetDebug(1); } + rustc_trans::enable_llvm_debug(); } let descriptions = diagnostics_registry(); @@ -204,13 +203,14 @@ macro_rules! do_or_return {($expr: expr, $sess: expr) => { }; let dep_graph = DepGraph::new(sopts.build_dep_graph()); - let cstore = Rc::new(CStore::new(&dep_graph)); + let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader)); let loader = file_loader.unwrap_or(box RealFileLoader); let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping())); let mut sess = session::build_session_with_codemap( sopts, &dep_graph, input_file_path, descriptions, cstore.clone(), codemap, emitter_dest, ); + rustc_trans::init(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let mut cfg = config::build_configuration(&sess, cfg); @@ -409,12 +409,13 @@ fn no_input(&mut self, return None; } let dep_graph = DepGraph::new(sopts.build_dep_graph()); - let cstore = Rc::new(CStore::new(&dep_graph)); + let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader)); let mut sess = build_session(sopts.clone(), &dep_graph, None, descriptions.clone(), cstore.clone()); + rustc_trans::init(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let mut cfg = config::build_configuration(&sess, cfg.clone()); target_features::add_configuration(&mut cfg, &sess); @@ -558,7 +559,11 @@ pub fn list_metadata(sess: &Session, matches: &getopts::Matches, input: &Input) &Input::File(ref ifile) => { let path = &(*ifile); let mut v = Vec::new(); - locator::list_file_metadata(&sess.target.target, path, &mut v).unwrap(); + locator::list_file_metadata(&sess.target.target, + path, + sess.cstore.metadata_loader(), + &mut v) + .unwrap(); println!("{}", String::from_utf8(v).unwrap()); } &Input::Str { .. } => { @@ -665,14 +670,6 @@ fn print_crate_info(sess: &Session, println!("{}", cfg); } } - PrintRequest::TargetCPUs => { - let tm = create_target_machine(sess); - unsafe { llvm::LLVMRustPrintTargetCPUs(tm); } - } - PrintRequest::TargetFeatures => { - let tm = create_target_machine(sess); - unsafe { llvm::LLVMRustPrintTargetFeatures(tm); } - } PrintRequest::RelocationModels => { println!("Available relocation models:"); for &(name, _) in RELOC_MODEL_ARGS.iter() { @@ -687,6 +684,9 @@ fn print_crate_info(sess: &Session, } println!(""); } + PrintRequest::TargetCPUs | PrintRequest::TargetFeatures => { + rustc_trans::print(*req, sess); + } } } return Compilation::Stop; @@ -724,10 +724,7 @@ fn unw(x: Option<&str>) -> &str { println!("commit-date: {}", unw(commit_date_str())); println!("host: {}", config::host_triple()); println!("release: {}", unw(release_str())); - unsafe { - println!("LLVM version: {}.{}", - llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor()); - } + rustc_trans::print_version(); } } @@ -1020,9 +1017,7 @@ pub fn handle_options(args: &[String]) -> Option { } if cg_flags.contains(&"passes=list".to_string()) { - unsafe { - ::llvm::LLVMRustPrintPasses(); - } + rustc_trans::print_passes(); return None; } diff --git a/src/librustc_driver/target_features.rs b/src/librustc_driver/target_features.rs index 61bc7c6eb4c..bee61bb3980 100644 --- a/src/librustc_driver/target_features.rs +++ b/src/librustc_driver/target_features.rs @@ -9,24 +9,9 @@ // except according to those terms. use syntax::ast; -use llvm::LLVMRustHasFeature; use rustc::session::Session; -use rustc_trans::back::write::create_target_machine; use syntax::symbol::Symbol; -use libc::c_char; - -// WARNING: the features must be known to LLVM or the feature -// detection code will walk past the end of the feature array, -// leading to crashes. - -const ARM_WHITELIST: &'static [&'static str] = &["neon\0", "vfp2\0", "vfp3\0", "vfp4\0"]; - -const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bmi2\0", "sse\0", - "sse2\0", "sse3\0", "sse4.1\0", "sse4.2\0", - "ssse3\0", "tbm\0", "lzcnt\0", "popcnt\0", - "sse4a\0", "rdrnd\0", "rdseed\0", "fma\0"]; - -const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"]; +use rustc_trans; /// Add `target_feature = "..."` cfgs for a variety of platform /// specific features (SSE, NEON etc.). @@ -34,21 +19,10 @@ /// This is performed by checking whether a whitelisted set of /// features is available on the target machine, by querying LLVM. pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) { - let target_machine = create_target_machine(sess); - - let whitelist = match &*sess.target.target.arch { - "arm" => ARM_WHITELIST, - "x86" | "x86_64" => X86_WHITELIST, - "hexagon" => HEXAGON_WHITELIST, - _ => &[], - }; - let tf = Symbol::intern("target_feature"); - for feat in whitelist { - assert_eq!(feat.chars().last(), Some('\0')); - if unsafe { LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } { - cfg.insert((tf, Some(Symbol::intern(&feat[..feat.len() - 1])))); - } + + for feat in rustc_trans::target_features(sess) { + cfg.insert((tf, Some(feat))); } let requested_features = sess.opts.cg.target_feature.split(','); diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index e2cbc480715..1d236a96bf6 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -14,6 +14,7 @@ use rustc::dep_graph::DepGraph; use rustc_lint; use rustc_resolve::MakeGlobMap; +use rustc_trans; use rustc::middle::lang_items; use rustc::middle::free_region::FreeRegionMap; use rustc::middle::region::{CodeExtent, RegionMaps}; @@ -104,13 +105,14 @@ fn test_env(source_string: &str, let dep_graph = DepGraph::new(false); let _ignore = dep_graph.in_ignore(); - let cstore = Rc::new(CStore::new(&dep_graph)); + let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader)); let sess = session::build_session_(options, &dep_graph, None, diagnostic_handler, Rc::new(CodeMap::new(FilePathMapping::empty())), cstore.clone()); + rustc_trans::init(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let input = config::Input::Str { name: driver::anon_src(), diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index e8b90609273..f47788ee036 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -11,13 +11,13 @@ crate-type = ["dylib"] [dependencies] flate = { path = "../libflate" } log = "0.3" +owning_ref = "0.3.3" proc_macro = { path = "../libproc_macro" } rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_const_math = { path = "../librustc_const_math" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } -rustc_llvm = { path = "../librustc_llvm" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_ext = { path = "../libsyntax_ext" } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index d2874f16289..dc7be42e452 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -393,6 +393,7 @@ fn resolve_crate(&mut self, rejected_via_filename: vec![], should_match_name: true, is_proc_macro: Some(false), + metadata_loader: &*self.cstore.metadata_loader, }; self.load(&mut locate_ctxt).or_else(|| { @@ -554,6 +555,7 @@ fn read_extension_crate(&mut self, span: Span, info: &ExternCrateInfo) -> Extens rejected_via_filename: vec![], should_match_name: true, is_proc_macro: None, + metadata_loader: &*self.cstore.metadata_loader, }; let library = self.load(&mut locate_ctxt).or_else(|| { if !is_cross { diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index c12b4209675..d2ad6d0ab34 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -11,21 +11,20 @@ // The crate store - a central repo for information collected about external // crates and libraries -use locator; use schema::{self, Tracked}; use rustc::dep_graph::{DepGraph, DepNode, GlobalMetaDataKind}; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefIndex, DefId}; use rustc::hir::map::definitions::DefPathTable; use rustc::hir::svh::Svh; -use rustc::middle::cstore::{DepKind, ExternCrate}; +use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader}; use rustc_back::PanicStrategy; use rustc_data_structures::indexed_vec::IndexVec; use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap, DefIdMap}; use std::cell::{RefCell, Cell}; use std::rc::Rc; -use flate::Bytes; +use owning_ref::ErasedBoxRef; use syntax::{ast, attr}; use syntax::ext::base::SyntaxExtension; use syntax::symbol::Symbol; @@ -43,11 +42,7 @@ // own crate numbers. pub type CrateNumMap = IndexVec; -pub enum MetadataBlob { - Inflated(Bytes), - Archive(locator::ArchiveMetadata), - Raw(Vec), -} +pub struct MetadataBlob(pub ErasedBoxRef<[u8]>); /// Holds information about a syntax_pos::FileMap imported from another crate. /// See `imported_filemaps()` for more information. @@ -103,10 +98,11 @@ pub struct CStore { statically_included_foreign_items: RefCell>, pub dllimport_foreign_items: RefCell>, pub visible_parent_map: RefCell>, + pub metadata_loader: Box, } impl CStore { - pub fn new(dep_graph: &DepGraph) -> CStore { + pub fn new(dep_graph: &DepGraph, metadata_loader: Box) -> CStore { CStore { dep_graph: dep_graph.clone(), metas: RefCell::new(FxHashMap()), @@ -116,6 +112,7 @@ pub fn new(dep_graph: &DepGraph) -> CStore { statically_included_foreign_items: RefCell::new(FxHashSet()), dllimport_foreign_items: RefCell::new(FxHashSet()), visible_parent_map: RefCell::new(FxHashMap()), + metadata_loader: metadata_loader, } } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index dbf3e94832f..1a2298d3fb1 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -10,12 +10,11 @@ use cstore; use encoder; -use locator; use schema; use rustc::dep_graph::DepTrackingMapConfig; use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind, - ExternCrate, NativeLibrary, LinkMeta, + ExternCrate, NativeLibrary, MetadataLoader, LinkMeta, LinkagePreference, LoadedMacro, EncodedMetadata}; use rustc::hir::def; use rustc::middle::lang_items; @@ -38,7 +37,6 @@ use syntax::symbol::Symbol; use syntax_pos::{Span, NO_EXPANSION}; use rustc::hir::svh::Svh; -use rustc_back::target::Target; use rustc::hir; macro_rules! provide { @@ -135,6 +133,10 @@ fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc { self.get_crate_data(krate) } + fn metadata_loader(&self) -> &MetadataLoader { + &*self.metadata_loader + } + fn visibility(&self, def: DefId) -> ty::Visibility { self.dep_graph.read(DepNode::MetaData(def)); self.get_crate_data(def.krate).get_visibility(def.index) @@ -420,17 +422,6 @@ fn used_link_args(&self) -> Vec { self.get_used_link_args().borrow().clone() } - - fn metadata_filename(&self) -> &str - { - locator::METADATA_FILENAME - } - - fn metadata_section_name(&self, target: &Target) -> &str - { - locator::meta_section_name(target) - } - fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> { self.do_get_used_crates(prefer) @@ -522,4 +513,4 @@ fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap> { drop(visible_parent_map); self.visible_parent_map.borrow() } -} +} \ No newline at end of file diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 819095e2628..c734b9f411c 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -77,11 +77,7 @@ fn decoder(self, pos: usize) -> DecodeContext<'a, 'tcx> { impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob { fn raw_bytes(self) -> &'a [u8] { - match *self { - MetadataBlob::Inflated(ref vec) => vec, - MetadataBlob::Archive(ref ar) => ar.as_slice(), - MetadataBlob::Raw(ref vec) => vec, - } + &self.0 } } diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 27555f49e57..e3d9e5ac74a 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -37,6 +37,7 @@ extern crate syntax_pos; extern crate flate; extern crate serialize as rustc_serialize; // used by deriving +extern crate owning_ref; extern crate rustc_errors as errors; extern crate syntax_ext; extern crate proc_macro; @@ -46,7 +47,6 @@ extern crate rustc_back; extern crate rustc_const_math; extern crate rustc_data_structures; -extern crate rustc_llvm; mod diagnostics; diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 84bb82de370..34b07af9f01 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -224,15 +224,12 @@ use schema::{METADATA_HEADER, rustc_version}; use rustc::hir::svh::Svh; +use rustc::middle::cstore::MetadataLoader; use rustc::session::{config, Session}; use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch}; use rustc::session::search_paths::PathKind; -use rustc::util::common; use rustc::util::nodemap::FxHashMap; -use rustc_llvm as llvm; -use rustc_llvm::{False, ObjectFile, mk_section_iter}; -use rustc_llvm::archive_ro::ArchiveRO; use errors::DiagnosticBuilder; use syntax::symbol::Symbol; use syntax_pos::Span; @@ -243,11 +240,10 @@ use std::fs::{self, File}; use std::io::{self, Read}; use std::path::{Path, PathBuf}; -use std::ptr; -use std::slice; use std::time::Instant; use flate; +use owning_ref::{ErasedBoxRef, OwningRef}; pub struct CrateMismatch { path: PathBuf, @@ -272,12 +268,7 @@ pub struct Context<'a> { pub rejected_via_filename: Vec, pub should_match_name: bool, pub is_proc_macro: Option, -} - -pub struct ArchiveMetadata { - _archive: ArchiveRO, - // points into self._archive - data: *const [u8], + pub metadata_loader: &'a MetadataLoader, } pub struct CratePaths { @@ -287,8 +278,6 @@ pub struct CratePaths { pub rmeta: Option, } -pub const METADATA_FILENAME: &'static str = "rust.metadata.bin"; - #[derive(Copy, Clone, PartialEq)] enum CrateFlavor { Rlib, @@ -596,20 +585,21 @@ fn extract_one(&mut self, let mut err: Option = None; for (lib, kind) in m { info!("{} reading metadata from: {}", flavor, lib.display()); - let (hash, metadata) = match get_metadata_section(self.target, flavor, &lib) { - Ok(blob) => { - if let Some(h) = self.crate_matches(&blob, &lib) { - (h, blob) - } else { - info!("metadata mismatch"); + let (hash, metadata) = + match get_metadata_section(self.target, flavor, &lib, self.metadata_loader) { + Ok(blob) => { + if let Some(h) = self.crate_matches(&blob, &lib) { + (h, blob) + } else { + info!("metadata mismatch"); + continue; + } + } + Err(err) => { + info!("no metadata found: {}", err); continue; } - } - Err(err) => { - info!("no metadata found: {}", err); - continue; - } - }; + }; // If we see multiple hashes, emit an error about duplicate candidates. if slot.as_ref().map_or(false, |s| s.0 != hash) { let mut e = struct_span_err!(self.sess, @@ -833,50 +823,14 @@ pub fn note_crate_name(err: &mut DiagnosticBuilder, name: &str) { err.note(&format!("crate name: {}", name)); } -impl ArchiveMetadata { - fn new(ar: ArchiveRO) -> Option { - let data = { - let section = ar.iter() - .filter_map(|s| s.ok()) - .find(|sect| sect.name() == Some(METADATA_FILENAME)); - match section { - Some(s) => s.data() as *const [u8], - None => { - debug!("didn't find '{}' in the archive", METADATA_FILENAME); - return None; - } - } - }; - - Some(ArchiveMetadata { - _archive: ar, - data: data, - }) - } - - pub fn as_slice<'a>(&'a self) -> &'a [u8] { - unsafe { &*self.data } - } -} - -fn verify_decompressed_encoding_version(blob: &MetadataBlob, - filename: &Path) - -> Result<(), String> { - if !blob.is_compatible() { - Err((format!("incompatible metadata version found: '{}'", - filename.display()))) - } else { - Ok(()) - } -} - // Just a small wrapper to time how long reading metadata takes. fn get_metadata_section(target: &Target, flavor: CrateFlavor, - filename: &Path) + filename: &Path, + loader: &MetadataLoader) -> Result { let start = Instant::now(); - let ret = get_metadata_section_imp(target, flavor, filename); + let ret = get_metadata_section_imp(target, flavor, filename, loader); info!("reading {:?} => {:?}", filename.file_name().unwrap(), start.elapsed()); @@ -885,118 +839,61 @@ fn get_metadata_section(target: &Target, fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, - filename: &Path) + filename: &Path, + loader: &MetadataLoader) -> Result { if !filename.exists() { return Err(format!("no such file: '{}'", filename.display())); } - if flavor == CrateFlavor::Rlib { - // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap - // internally to read the file. We also avoid even using a memcpy by - // just keeping the archive along while the metadata is in use. - let archive = match ArchiveRO::open(filename) { - Some(ar) => ar, - None => { - debug!("llvm didn't like `{}`", filename.display()); - return Err(format!("failed to read rlib metadata: '{}'", filename.display())); + let raw_bytes: ErasedBoxRef<[u8]> = match flavor { + CrateFlavor::Rlib => loader.get_rlib_metadata(target, filename)?, + CrateFlavor::Dylib => { + let buf = loader.get_dylib_metadata(target, filename)?; + // The header is uncompressed + let header_len = METADATA_HEADER.len(); + debug!("checking {} bytes of metadata-version stamp", header_len); + let header = &buf[..cmp::min(header_len, buf.len())]; + if header != METADATA_HEADER { + return Err(format!("incompatible metadata version found: '{}'", + filename.display())); } - }; - return match ArchiveMetadata::new(archive).map(|ar| MetadataBlob::Archive(ar)) { - None => Err(format!("failed to read rlib metadata: '{}'", filename.display())), - Some(blob) => { - verify_decompressed_encoding_version(&blob, filename)?; - Ok(blob) - } - }; - } else if flavor == 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(|_| - format!("failed to read rlib metadata: '{}'", filename.display()))?; - let blob = MetadataBlob::Raw(buf); - verify_decompressed_encoding_version(&blob, filename)?; - return Ok(blob); - } - unsafe { - let buf = common::path2cstr(filename); - let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr()); - if mb as isize == 0 { - return Err(format!("error reading library: '{}'", filename.display())); - } - let of = match ObjectFile::new(mb) { - Some(of) => of, - _ => { - return Err((format!("provided path not an object file: '{}'", filename.display()))) - } - }; - let si = mk_section_iter(of.llof); - while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False { - let mut name_buf = ptr::null(); - let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf); - let name = slice::from_raw_parts(name_buf as *const u8, name_len as usize).to_vec(); - let name = String::from_utf8(name).unwrap(); - debug!("get_metadata_section: name {}", name); - if read_meta_section_name(target) == name { - let cbuf = llvm::LLVMGetSectionContents(si.llsi); - let csz = llvm::LLVMGetSectionSize(si.llsi) as usize; - let cvbuf: *const u8 = cbuf as *const u8; - let vlen = METADATA_HEADER.len(); - debug!("checking {} bytes of metadata-version stamp", vlen); - let minsz = cmp::min(vlen, csz); - let buf0 = slice::from_raw_parts(cvbuf, minsz); - let version_ok = buf0 == METADATA_HEADER; - if !version_ok { - return Err((format!("incompatible metadata version found: '{}'", - filename.display()))); - } - let cvbuf1 = cvbuf.offset(vlen as isize); - debug!("inflating {} bytes of compressed metadata", csz - vlen); - let bytes = slice::from_raw_parts(cvbuf1, csz - vlen); - match flate::inflate_bytes(bytes) { - Ok(inflated) => { - let blob = MetadataBlob::Inflated(inflated); - verify_decompressed_encoding_version(&blob, filename)?; - return Ok(blob); - } - Err(_) => {} + // Header is okay -> inflate the actual metadata + let compressed_bytes = &buf[header_len..]; + debug!("inflating {} bytes of compressed metadata", compressed_bytes.len()); + match flate::inflate_bytes(compressed_bytes) { + Ok(inflated) => { + let buf = unsafe { OwningRef::new_assert_stable_address(inflated) }; + buf.map_owner_box().erase_owner() + } + Err(_) => { + return Err(format!("failed to decompress metadata: {}", filename.display())); } } - llvm::LLVMMoveToNextSection(si.llsi); } - Err(format!("metadata not found: '{}'", filename.display())) - } -} - -pub fn meta_section_name(target: &Target) -> &'static str { - // Historical note: - // - // When using link.exe it was seen that the section name `.note.rustc` - // was getting shortened to `.note.ru`, and according to the PE and COFF - // specification: - // - // > Executable images do not use a string table and do not support - // > section names longer than 8 characters - // - // https://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx - // - // As a result, we choose a slightly shorter name! As to why - // `.note.rustc` works on MinGW, that's another good question... - - if target.options.is_like_osx { - "__DATA,.rustc" + 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(|_| + format!("failed to read rmeta metadata: '{}'", filename.display()))?; + OwningRef::new(buf).map_owner_box().erase_owner() + } + }; + let blob = MetadataBlob(raw_bytes); + if blob.is_compatible() { + Ok(blob) } else { - ".rustc" + Err(format!("incompatible metadata version found: '{}'", filename.display())) } } -pub fn read_meta_section_name(_target: &Target) -> &'static str { - ".rustc" -} - // A diagnostic function for dumping crate metadata to an output stream -pub fn list_file_metadata(target: &Target, path: &Path, out: &mut io::Write) -> io::Result<()> { +pub fn list_file_metadata(target: &Target, + path: &Path, + loader: &MetadataLoader, + out: &mut io::Write) + -> io::Result<()> { let filename = path.file_name().unwrap().to_str().unwrap(); let flavor = if filename.ends_with(".rlib") { CrateFlavor::Rlib @@ -1005,7 +902,7 @@ pub fn list_file_metadata(target: &Target, path: &Path, out: &mut io::Write) -> } else { CrateFlavor::Dylib }; - match get_metadata_section(target, flavor, path) { + match get_metadata_section(target, flavor, path, loader) { Ok(metadata) => metadata.list_crate_metadata(out), Err(msg) => write!(out, "{}\n", msg), } diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml index af477f5a152..4ccc85257f3 100644 --- a/src/librustc_trans/Cargo.toml +++ b/src/librustc_trans/Cargo.toml @@ -12,6 +12,7 @@ test = false [dependencies] flate = { path = "../libflate" } log = "0.3" +owning_ref = "0.3.3" rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_bitflags = { path = "../librustc_bitflags" } diff --git a/src/librustc_trans/back/archive.rs b/src/librustc_trans/back/archive.rs index 0f908b7d069..902065c8688 100644 --- a/src/librustc_trans/back/archive.rs +++ b/src/librustc_trans/back/archive.rs @@ -20,6 +20,7 @@ use libc; use llvm::archive_ro::{ArchiveRO, Child}; use llvm::{self, ArchiveKind}; +use metadata::METADATA_FILENAME; use rustc::session::Session; pub struct ArchiveConfig<'a> { @@ -158,11 +159,9 @@ pub fn add_rlib(&mut self, // Ignoring all bytecode files, no matter of // name let bc_ext = ".bytecode.deflate"; - let metadata_filename = - self.config.sess.cstore.metadata_filename().to_owned(); self.add_archive(rlib, move |fname: &str| { - if fname.ends_with(bc_ext) || fname == metadata_filename { + if fname.ends_with(bc_ext) || fname == METADATA_FILENAME { return true } diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index e42e69d2a76..b8aabef65a9 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -13,6 +13,7 @@ use super::rpath::RPathConfig; use super::rpath; use super::msvc; +use metadata::METADATA_FILENAME; use session::config; use session::config::NoDebugInfo; use session::config::{OutputFilenames, Input, OutputType}; @@ -521,7 +522,7 @@ fn link_rlib<'a>(sess: &'a Session, // contain the metadata in a separate file. We use a temp directory // here so concurrent builds in the same directory don't try to use // the same filename for metadata (stomping over one another) - let metadata = tmpdir.join(sess.cstore.metadata_filename()); + let metadata = tmpdir.join(METADATA_FILENAME); emit_metadata(sess, trans, &metadata); ab.add_file(&metadata); @@ -1141,8 +1142,7 @@ fn link_sanitizer_runtime(cmd: &mut Linker, archive.update_symbols(); for f in archive.src_files() { - if f.ends_with("bytecode.deflate") || - f == sess.cstore.metadata_filename() { + if f.ends_with("bytecode.deflate") || f == METADATA_FILENAME { archive.remove_file(&f); continue } @@ -1217,8 +1217,7 @@ fn add_static_crate(cmd: &mut Linker, let mut any_objects = false; for f in archive.src_files() { - if f.ends_with("bytecode.deflate") || - f == sess.cstore.metadata_filename() { + if f.ends_with("bytecode.deflate") || f == METADATA_FILENAME { archive.remove_file(&f); continue } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 8689e176f7a..437ced85b2e 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -34,6 +34,7 @@ use back::symbol_export::{self, ExportedSymbols}; use llvm::{ContextRef, Linkage, ModuleRef, ValueRef, Vector, get_param}; use llvm; +use metadata; use rustc::hir::def_id::LOCAL_CRATE; use middle::lang_items::StartFnLangItem; use middle::cstore::EncodedMetadata; @@ -778,8 +779,7 @@ enum MetadataKind { }; unsafe { llvm::LLVMSetInitializer(llglobal, llconst); - let section_name = - tcx.sess.cstore.metadata_section_name(&tcx.sess.target.target); + let section_name = metadata::metadata_section_name(&tcx.sess.target.target); let name = CString::new(section_name).unwrap(); llvm::LLVMSetSection(llglobal, name.as_ptr()); diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 8e633ee59b6..3ac0d88b90d 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -45,6 +45,7 @@ extern crate flate; extern crate libc; +extern crate owning_ref; #[macro_use] extern crate rustc; extern crate rustc_back; extern crate rustc_data_structures; @@ -70,6 +71,9 @@ pub use base::trans_crate; pub use back::symbol_names::provide; +pub use metadata::LlvmMetadataLoader; +pub use llvm_util::{init, target_features, print_version, print_passes, print, enable_llvm_debug}; + pub mod back { pub use rustc::hir::svh; @@ -119,7 +123,9 @@ pub mod back { mod declare; mod glue; mod intrinsic; +mod llvm_util; mod machine; +mod metadata; mod meth; mod mir; mod monomorphize; diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs new file mode 100644 index 00000000000..15f56036b0c --- /dev/null +++ b/src/librustc_trans/llvm_util.rs @@ -0,0 +1,127 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use syntax_pos::symbol::Symbol; +use back::write::create_target_machine; +use llvm; +use rustc::session::Session; +use rustc::session::config::PrintRequest; +use libc::{c_int, c_char}; +use std::ffi::CString; + +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Once; + +pub fn init(sess: &Session) { + unsafe { + // Before we touch LLVM, make sure that multithreading is enabled. + static POISONED: AtomicBool = AtomicBool::new(false); + static INIT: Once = Once::new(); + INIT.call_once(|| { + if llvm::LLVMStartMultithreaded() != 1 { + // use an extra bool to make sure that all future usage of LLVM + // cannot proceed despite the Once not running more than once. + POISONED.store(true, Ordering::SeqCst); + } + + configure_llvm(sess); + }); + + if POISONED.load(Ordering::SeqCst) { + bug!("couldn't enable multi-threaded LLVM"); + } + } +} + +unsafe fn configure_llvm(sess: &Session) { + let mut llvm_c_strs = Vec::new(); + let mut llvm_args = Vec::new(); + + { + let mut add = |arg: &str| { + let s = CString::new(arg).unwrap(); + llvm_args.push(s.as_ptr()); + llvm_c_strs.push(s); + }; + add("rustc"); // fake program name + if sess.time_llvm_passes() { add("-time-passes"); } + if sess.print_llvm_passes() { add("-debug-pass=Structure"); } + + for arg in &sess.opts.cg.llvm_args { + add(&(*arg)); + } + } + + llvm::LLVMInitializePasses(); + + llvm::initialize_available_targets(); + + llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, + llvm_args.as_ptr()); +} + +// WARNING: the features must be known to LLVM or the feature +// detection code will walk past the end of the feature array, +// leading to crashes. + +const ARM_WHITELIST: &'static [&'static str] = &["neon\0", "vfp2\0", "vfp3\0", "vfp4\0"]; + +const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bmi2\0", "sse\0", + "sse2\0", "sse3\0", "sse4.1\0", "sse4.2\0", + "ssse3\0", "tbm\0", "lzcnt\0", "popcnt\0", + "sse4a\0", "rdrnd\0", "rdseed\0", "fma\0"]; + +const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"]; + +pub fn target_features(sess: &Session) -> Vec { + let target_machine = create_target_machine(sess); + + let whitelist = match &*sess.target.target.arch { + "arm" => ARM_WHITELIST, + "x86" | "x86_64" => X86_WHITELIST, + "hexagon" => HEXAGON_WHITELIST, + _ => &[], + }; + + let mut features = Vec::new(); + for feat in whitelist { + assert_eq!(feat.chars().last(), Some('\0')); + if unsafe { llvm::LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } { + features.push(Symbol::intern(&feat[..feat.len() - 1])); + } + } + features +} + +pub fn print_version() { + unsafe { + println!("LLVM version: {}.{}", + llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor()); + } +} + +pub fn print_passes() { + unsafe { llvm::LLVMRustPrintPasses(); } +} + +pub fn print(req: PrintRequest, sess: &Session) { + let tm = create_target_machine(sess); + unsafe { + match req { + PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm), + PrintRequest::TargetFeatures => llvm::LLVMRustPrintTargetFeatures(tm), + _ => bug!("rustc_trans can't handle print request: {:?}", req), + } + } +} + +pub fn enable_llvm_debug() { + unsafe { llvm::LLVMRustSetDebug(1); } +} diff --git a/src/librustc_trans/metadata.rs b/src/librustc_trans/metadata.rs new file mode 100644 index 00000000000..2c0148dfbb3 --- /dev/null +++ b/src/librustc_trans/metadata.rs @@ -0,0 +1,122 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use rustc::util::common; +use rustc::middle::cstore::MetadataLoader; +use rustc_back::target::Target; +use llvm; +use llvm::{False, ObjectFile, mk_section_iter}; +use llvm::archive_ro::ArchiveRO; + +use owning_ref::{ErasedBoxRef, OwningRef}; +use std::path::Path; +use std::ptr; +use std::slice; + +pub const METADATA_FILENAME: &str = "rust.metadata.bin"; + +pub struct LlvmMetadataLoader; + +impl MetadataLoader for LlvmMetadataLoader { + fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result, String> { + // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap + // internally to read the file. We also avoid even using a memcpy by + // just keeping the archive along while the metadata is in use. + let archive = ArchiveRO::open(filename) + .map(|ar| OwningRef::new(box ar)) + .ok_or_else(|| { + debug!("llvm didn't like `{}`", filename.display()); + format!("failed to read rlib metadata: '{}'", filename.display()) + })?; + let buf: OwningRef<_, [u8]> = archive + .try_map(|ar| { + ar.iter() + .filter_map(|s| s.ok()) + .find(|sect| sect.name() == Some(METADATA_FILENAME)) + .map(|s| s.data()) + .ok_or_else(|| { + debug!("didn't find '{}' in the archive", METADATA_FILENAME); + format!("failed to read rlib metadata: '{}'", + filename.display()) + }) + })?; + Ok(buf.erase_owner()) + } + + fn get_dylib_metadata(&self, + target: &Target, + filename: &Path) + -> Result, String> { + unsafe { + let buf = common::path2cstr(filename); + let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr()); + if mb as isize == 0 { + return Err(format!("error reading library: '{}'", filename.display())); + } + let of = ObjectFile::new(mb) + .map(|of| OwningRef::new(box of)) + .ok_or_else(|| format!("provided path not an object file: '{}'", + filename.display()))?; + let buf = of.try_map(|of| search_meta_section(of, target, filename))?; + Ok(buf.erase_owner()) + } + } +} + +fn search_meta_section<'a>(of: &'a ObjectFile, + target: &Target, + filename: &Path) + -> Result<&'a [u8], String> { + unsafe { + let si = mk_section_iter(of.llof); + while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False { + let mut name_buf = ptr::null(); + let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf); + let name = slice::from_raw_parts(name_buf as *const u8, name_len as usize).to_vec(); + let name = String::from_utf8(name).unwrap(); + debug!("get_metadata_section: name {}", name); + if read_metadata_section_name(target) == name { + let cbuf = llvm::LLVMGetSectionContents(si.llsi); + let csz = llvm::LLVMGetSectionSize(si.llsi) as usize; + // The buffer is valid while the object file is around + let buf: &'a [u8] = slice::from_raw_parts(cbuf as *const u8, csz); + return Ok(buf); + } + llvm::LLVMMoveToNextSection(si.llsi); + } + } + Err(format!("metadata not found: '{}'", filename.display())) +} + +pub fn metadata_section_name(target: &Target) -> &'static str { + // Historical note: + // + // When using link.exe it was seen that the section name `.note.rustc` + // was getting shortened to `.note.ru`, and according to the PE and COFF + // specification: + // + // > Executable images do not use a string table and do not support + // > section names longer than 8 characters + // + // https://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx + // + // As a result, we choose a slightly shorter name! As to why + // `.note.rustc` works on MinGW, that's another good question... + + if target.options.is_like_osx { + "__DATA,.rustc" + } else { + ".rustc" + } +} + +fn read_metadata_section_name(_target: &Target) -> &'static str { + ".rustc" +} diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index c7ec379b0de..7e70bb92cd6 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -251,9 +251,9 @@ macro_rules! report_function { let bound_list = unsatisfied_predicates.iter() .map(|p| format!("`{} : {}`", p.self_ty(), p)) .collect::>() - .join(", "); + .join("\n"); err.note(&format!("the method `{}` exists but the following trait bounds \ - were not satisfied: {}", + were not satisfied:\n{}", item_name, bound_list)); } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 9e2d8516333..9a689ed079e 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -19,6 +19,7 @@ use rustc::hir::map as hir_map; use rustc::lint; use rustc::util::nodemap::FxHashMap; +use rustc_trans; use rustc_trans::back::link; use rustc_resolve as resolve; use rustc_metadata::cstore::CStore; @@ -138,10 +139,11 @@ pub fn run_core(search_paths: SearchPaths, let dep_graph = DepGraph::new(false); let _ignore = dep_graph.in_ignore(); - let cstore = Rc::new(CStore::new(&dep_graph)); + let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader)); let mut sess = session::build_session_( sessopts, &dep_graph, cpath, diagnostic_handler, codemap, cstore.clone() ); + rustc_trans::init(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let mut cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs)); diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 5db82e23bbf..612793e2567 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1177,7 +1177,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let quot = if f.alternate() { "\"" } else { """ }; match self.0 { Abi::Rust => Ok(()), - Abi::C => write!(f, "extern "), abi => write!(f, "extern {0}{1}{0} ", quot, abi.name()), } } diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 60ea6ed1d8d..570a1980782 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -617,6 +617,11 @@ a.test-arrow:hover{ top: 0; } +h3 > .collapse-toggle, h4 > .collapse-toggle { + font-size: 0.8em; + top: 5px; +} + .toggle-wrapper > .collapse-toggle { left: -24px; margin-top: 0px; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index d5237d629cf..cfe2fad0fa4 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -34,6 +34,7 @@ use rustc_driver::driver::phase_2_configure_and_expand; use rustc_metadata::cstore::CStore; use rustc_resolve::MakeGlobMap; +use rustc_trans; use rustc_trans::back::link; use syntax::ast; use syntax::codemap::CodeMap; @@ -81,10 +82,11 @@ pub fn run(input: &str, let dep_graph = DepGraph::new(false); let _ignore = dep_graph.in_ignore(); - let cstore = Rc::new(CStore::new(&dep_graph)); + let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader)); let mut sess = session::build_session_( sessopts, &dep_graph, Some(input_path.clone()), handler, codemap.clone(), cstore.clone(), ); + rustc_trans::init(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); sess.parse_sess.config = config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone())); @@ -229,10 +231,11 @@ fn drop(&mut self) { let diagnostic_handler = errors::Handler::with_emitter(true, false, box emitter); let dep_graph = DepGraph::new(false); - let cstore = Rc::new(CStore::new(&dep_graph)); + let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader)); let mut sess = session::build_session_( sessopts, &dep_graph, None, diagnostic_handler, codemap, cstore.clone(), ); + rustc_trans::init(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let outdir = Mutex::new(TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir")); diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index e2b22b1d89f..c2c6e6cf87d 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -19,16 +19,16 @@ /// A thread local storage key which owns its contents. /// /// This key uses the fastest possible implementation available to it for the -/// target platform. It is instantiated with the `thread_local!` macro and the -/// primary method is the `with` method. +/// target platform. It is instantiated with the [`thread_local!`] macro and the +/// primary method is the [`with`] method. /// -/// The `with` method yields a reference to the contained value which cannot be +/// The [`with`] method yields a reference to the contained value which cannot be /// sent across threads or escape the given closure. /// /// # Initialization and Destruction /// -/// Initialization is dynamically performed on the first call to `with()` -/// within a thread, and values that implement `Drop` get destructed when a +/// Initialization is dynamically performed on the first call to [`with`] +/// within a thread, and values that implement [`Drop`] get destructed when a /// thread exits. Some caveats apply, which are explained below. /// /// # Examples @@ -77,6 +77,10 @@ /// 3. On macOS, initializing TLS during destruction of other TLS slots can /// sometimes cancel *all* destructors for the current thread, whether or not /// the slots have already had their destructors run or not. +/// +/// [`with`]: ../../std/thread/struct.LocalKey.html#method.with +/// [`thread_local!`]: ../../std/macro.thread_local.html +/// [`Drop`]: ../../std/ops/trait.Drop.html #[stable(feature = "rust1", since = "1.0.0")] pub struct LocalKey { // This outer `LocalKey` type is what's going to be stored in statics, @@ -106,7 +110,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -/// Declare a new thread local storage key of type `std::thread::LocalKey`. +/// Declare a new thread local storage key of type [`std::thread::LocalKey`]. /// /// # Syntax /// @@ -124,8 +128,10 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { /// # fn main() {} /// ``` /// -/// See [LocalKey documentation](thread/struct.LocalKey.html) for more +/// See [LocalKey documentation][`std::thread::LocalKey`] for more /// information. +/// +/// [`std::thread::LocalKey`]: ../std/thread/struct.LocalKey.html #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable] @@ -195,11 +201,13 @@ fn __getit() -> $crate::option::Option< #[derive(Debug, Eq, PartialEq, Copy, Clone)] pub enum LocalKeyState { /// All keys are in this state whenever a thread starts. Keys will - /// transition to the `Valid` state once the first call to `with` happens + /// transition to the `Valid` state once the first call to [`with`] happens /// and the initialization expression succeeds. /// /// Keys in the `Uninitialized` state will yield a reference to the closure - /// passed to `with` so long as the initialization routine does not panic. + /// passed to [`with`] so long as the initialization routine does not panic. + /// + /// [`with`]: ../../std/thread/struct.LocalKey.html#method.with Uninitialized, /// Once a key has been accessed successfully, it will enter the `Valid` @@ -208,7 +216,9 @@ pub enum LocalKeyState { /// `Destroyed` state. /// /// Keys in the `Valid` state will be guaranteed to yield a reference to the - /// closure passed to `with`. + /// closure passed to [`with`]. + /// + /// [`with`]: ../../std/thread/struct.LocalKey.html#method.with Valid, /// When a thread exits, the destructors for keys will be run (if @@ -216,7 +226,9 @@ pub enum LocalKeyState { /// destructor has run, a key is in the `Destroyed` state. /// /// Keys in the `Destroyed` states will trigger a panic when accessed via - /// `with`. + /// [`with`]. + /// + /// [`with`]: ../../std/thread/struct.LocalKey.html#method.with Destroyed, } @@ -283,23 +295,26 @@ unsafe fn init(&self, slot: &UnsafeCell>) -> &T { /// Query the current state of this key. /// /// A key is initially in the `Uninitialized` state whenever a thread - /// starts. It will remain in this state up until the first call to `with` + /// starts. It will remain in this state up until the first call to [`with`] /// within a thread has run the initialization expression successfully. /// /// Once the initialization expression succeeds, the key transitions to the - /// `Valid` state which will guarantee that future calls to `with` will + /// `Valid` state which will guarantee that future calls to [`with`] will /// succeed within the thread. /// /// When a thread exits, each key will be destroyed in turn, and as keys are /// destroyed they will enter the `Destroyed` state just before the /// destructor starts to run. Keys may remain in the `Destroyed` state after /// destruction has completed. Keys without destructors (e.g. with types - /// that are `Copy`), may never enter the `Destroyed` state. + /// that are [`Copy`]), may never enter the `Destroyed` state. /// /// Keys in the `Uninitialized` state can be accessed so long as the /// initialization does not panic. Keys in the `Valid` state are guaranteed /// to be able to be accessed. Keys in the `Destroyed` state will panic on - /// any call to `with`. + /// any call to [`with`]. + /// + /// [`with`]: ../../std/thread/struct.LocalKey.html#method.with + /// [`Copy`]: ../../std/marker/trait.Copy.html #[unstable(feature = "thread_local_state", reason = "state querying was recently added", issue = "27716")] diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 200368be275..154406a1d8b 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -180,8 +180,33 @@ // Builder //////////////////////////////////////////////////////////////////////////////// -/// Thread configuration. Provides detailed control over the properties -/// and behavior of new threads. +/// Thread factory, which can be used in order to configure the properties of +/// a new thread. +/// +/// Methods can be chained on it in order to configure it. +/// +/// The two configurations available are: +/// +/// - [`name`]: allows to give a name to the thread which is currently +/// only used in `panic` messages. +/// - [`stack_size`]: specifies the desired stack size. Note that this can +/// be overriden by the OS. +/// +/// If the [`stack_size`] field is not specified, the stack size +/// will be the `RUST_MIN_STACK` environment variable. If it is +/// not specified either, a sensible default will be set. +/// +/// If the [`name`] field is not specified, the thread will not be named. +/// +/// The [`spawn`] method will take ownership of the builder and create an +/// [`io::Result`] to the thread handle with the given configuration. +/// +/// The [`thread::spawn`] free function uses a `Builder` with default +/// configuration and [`unwrap`]s its return value. +/// +/// You may want to use [`spawn`] instead of [`thread::spawn`], when you want +/// to recover from a failure to launch a thread, indeed the free function will +/// panick where the `Builder` method will return a [`io::Result`]. /// /// # Examples /// @@ -196,6 +221,13 @@ /// /// handler.join().unwrap(); /// ``` +/// +/// [`thread::spawn`]: ../../std/thread/fn.spawn.html +/// [`stack_size`]: ../../std/thread/struct.Builder.html#method.stack_size +/// [`name`]: ../../std/thread/struct.Builder.html#method.name +/// [`spawn`]: ../../std/thread/struct.Builder.html#method.spawn +/// [`io::Result`]: ../../std/io/type.Result.html +/// [`unwrap`]: ../../std/result/enum.Result.html#method.unwrap #[stable(feature = "rust1", since = "1.0.0")] #[derive(Debug)] pub struct Builder { @@ -209,11 +241,6 @@ impl Builder { /// Generates the base configuration for spawning a thread, from which /// configuration methods can be chained. /// - /// If the [`stack_size`] field is not specified, the stack size - /// will be the `RUST_MIN_STACK` environment variable. If it is - /// not specified either, a sensible default will be set (2MB as - /// of the writting of this doc). - /// /// # Examples /// /// ``` @@ -229,8 +256,6 @@ impl Builder { /// /// handler.join().unwrap(); /// ``` - /// - /// [`stack_size`]: ../../std/thread/struct.Builder.html#method.stack_size #[stable(feature = "rust1", since = "1.0.0")] pub fn new() -> Builder { Builder { @@ -280,9 +305,10 @@ pub fn stack_size(mut self, size: usize) -> Builder { self } - /// Spawns a new thread, and returns a join handle for it. + /// Spawns a new thread by taking ownership of the `Builder`, and returns an + /// [`io::Result`] to its [`JoinHandle`]. /// - /// The child thread may outlive the parent (unless the parent thread + /// The spawned thread may outlive the caller (unless the caller thread /// is the main thread; the whole process is terminated when the main /// thread finishes). The join handle can be used to block on /// termination of the child thread, including recovering its panics. @@ -297,6 +323,7 @@ pub fn stack_size(mut self, size: usize) -> Builder { /// /// [`spawn`]: ../../std/thread/fn.spawn.html /// [`io::Result`]: ../../std/io/type.Result.html + /// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html /// /// # Examples /// @@ -468,6 +495,23 @@ pub fn current() -> Thread { /// Cooperatively gives up a timeslice to the OS scheduler. /// +/// This is used when the programmer knows that the thread will have nothing +/// to do for some time, and thus avoid wasting computing time. +/// +/// For example when polling on a resource, it is common to check that it is +/// available, and if not to yield in order to avoid busy waiting. +/// +/// Thus the pattern of `yield`ing after a failed poll is rather common when +/// implementing low-level shared resources or synchronization primitives. +/// +/// However programmers will usualy prefer to use, [`channel`]s, [`Condvar`]s, +/// [`Mutex`]es or [`join`] for their synchronisation routines, as they avoid +/// thinking about thread schedulling. +/// +/// Note that [`channel`]s for example are implemented using this primitive. +/// Indeed when you call `send` or `recv`, which are blocking, they will yield +/// if the channel is not available. +/// /// # Examples /// /// ``` @@ -475,6 +519,12 @@ pub fn current() -> Thread { /// /// thread::yield_now(); /// ``` +/// +/// [`channel`]: ../../std/sync/mpsc/index.html +/// [`spawn`]: ../../std/thread/fn.spawn.html +/// [`join`]: ../../std/thread/struct.JoinHandle.html#method.join +/// [`Mutex`]: ../../std/sync/struct.Mutex.html +/// [`Condvar`]: ../../std/sync/struct.Condvar.html #[stable(feature = "rust1", since = "1.0.0")] pub fn yield_now() { imp::Thread::yield_now() diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index eb0b7c29f8d..780b7ec8c2a 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -267,11 +267,12 @@ pub fn parse_failure_msg(tok: Token) -> String { /// Perform a token equality check, ignoring syntax context (that is, an unhygienic comparison) fn token_name_eq(t1 : &Token, t2 : &Token) -> bool { - match (t1,t2) { - (&token::Ident(id1),&token::Ident(id2)) - | (&token::Lifetime(id1),&token::Lifetime(id2)) => - id1.name == id2.name, - _ => *t1 == *t2 + if let (Some(id1), Some(id2)) = (t1.ident(), t2.ident()) { + id1.name == id2.name + } else if let (&token::Lifetime(id1), &token::Lifetime(id2)) = (t1, t2) { + id1.name == id2.name + } else { + *t1 == *t2 } } diff --git a/src/rust-installer b/src/rust-installer deleted file mode 160000 index 2e6417f6af5..00000000000 --- a/src/rust-installer +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2e6417f6af5218a29a8ee72ed17af085560b9b9c diff --git a/src/test/compile-fail/method-help-unsatisfied-bound.rs b/src/test/compile-fail/method-help-unsatisfied-bound.rs deleted file mode 100644 index 6416d5467c8..00000000000 --- a/src/test/compile-fail/method-help-unsatisfied-bound.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -struct Foo; - -fn main() { - let a: Result<(), Foo> = Ok(()); - a.unwrap(); - //~^ ERROR no method named `unwrap` found for type `std::result::Result<(), Foo>` - //~| NOTE the following trait bounds were not satisfied: `Foo : std::fmt::Debug` -} diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make/issue-19371/foo.rs index 0336fe277c5..e96588c6e5a 100644 --- a/src/test/run-make/issue-19371/foo.rs +++ b/src/test/run-make/issue-19371/foo.rs @@ -15,6 +15,7 @@ extern crate rustc_lint; extern crate rustc_metadata; extern crate rustc_errors; +extern crate rustc_trans; extern crate syntax; use rustc::dep_graph::DepGraph; @@ -58,8 +59,9 @@ fn basic_sess(sysroot: PathBuf) -> (Session, Rc) { let descriptions = Registry::new(&rustc::DIAGNOSTICS); let dep_graph = DepGraph::new(opts.build_dep_graph()); - let cstore = Rc::new(CStore::new(&dep_graph)); + let cstore = Rc::new(CStore::new(&dep_graph, Box::new(rustc_trans::LlvmMetadataLoader))); let sess = build_session(opts, &dep_graph, None, descriptions, cstore.clone()); + rustc_trans::init(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); (sess, cstore) } diff --git a/src/test/run-make/llvm-pass/plugin.rs b/src/test/run-make/llvm-pass/plugin.rs index f77b2fca857..37aab2bbd05 100644 --- a/src/test/run-make/llvm-pass/plugin.rs +++ b/src/test/run-make/llvm-pass/plugin.rs @@ -14,6 +14,7 @@ extern crate rustc; extern crate rustc_plugin; +extern crate rustc_trans; #[link(name = "llvm-function-pass", kind = "static")] #[link(name = "llvm-module-pass", kind = "static")] diff --git a/src/test/run-pass/issue-41803.rs b/src/test/run-pass/issue-41803.rs new file mode 100644 index 00000000000..e18b4204584 --- /dev/null +++ b/src/test/run-pass/issue-41803.rs @@ -0,0 +1,30 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/// A compile-time map from identifiers to arbitrary (heterogeneous) expressions +macro_rules! ident_map { + ( $name:ident = { $($key:ident => $e:expr,)* } ) => { + macro_rules! $name { + $( + ( $key ) => { $e }; + )* + // Empty invocation expands to nothing. Needed when the map is empty. + () => {}; + } + }; +} + +ident_map!(my_map = { + main => 0, +}); + +fn main() { + my_map!(main); +} diff --git a/src/test/rustdoc/extern-impl.rs b/src/test/rustdoc/extern-impl.rs index 0e78746704f..5c64b4118c3 100644 --- a/src/test/rustdoc/extern-impl.rs +++ b/src/test/rustdoc/extern-impl.rs @@ -18,9 +18,9 @@ impl Foo { pub fn rust0() {} // @has - '//code' 'fn rust1()' pub extern "Rust" fn rust1() {} - // @has - '//code' 'extern fn c0()' + // @has - '//code' 'extern "C" fn c0()' pub extern fn c0() {} - // @has - '//code' 'extern fn c1()' + // @has - '//code' 'extern "C" fn c1()' pub extern "C" fn c1() {} // @has - '//code' 'extern "system" fn system0()' pub extern "system" fn system0() {} @@ -31,7 +31,7 @@ pub trait Bar {} // @has - '//code' 'impl Bar for fn()' impl Bar for fn() {} -// @has - '//code' 'impl Bar for extern fn()' +// @has - '//code' 'impl Bar for extern "C" fn()' impl Bar for extern fn() {} // @has - '//code' 'impl Bar for extern "system" fn()' impl Bar for extern "system" fn() {} diff --git a/src/test/rustdoc/ffi.rs b/src/test/rustdoc/ffi.rs index 3997dcd81e1..8511d461703 100644 --- a/src/test/rustdoc/ffi.rs +++ b/src/test/rustdoc/ffi.rs @@ -13,10 +13,10 @@ extern crate rustdoc_ffi as lib; -// @has ffi/fn.foreigner.html //pre 'pub unsafe extern fn foreigner(cold_as_ice: u32)' +// @has ffi/fn.foreigner.html //pre 'pub unsafe extern "C" fn foreigner(cold_as_ice: u32)' pub use lib::foreigner; extern "C" { - // @has ffi/fn.another.html //pre 'pub unsafe extern fn another(cold_as_ice: u32)' + // @has ffi/fn.another.html //pre 'pub unsafe extern "C" fn another(cold_as_ice: u32)' pub fn another(cold_as_ice: u32); } diff --git a/src/test/rustdoc/issue-22038.rs b/src/test/rustdoc/issue-22038.rs index 6f84428b079..75df5358945 100644 --- a/src/test/rustdoc/issue-22038.rs +++ b/src/test/rustdoc/issue-22038.rs @@ -10,7 +10,7 @@ extern { // @has issue_22038/fn.foo1.html \ - // '//*[@class="rust fn"]' 'pub unsafe extern fn foo1()' + // '//*[@class="rust fn"]' 'pub unsafe extern "C" fn foo1()' pub fn foo1(); } @@ -21,7 +21,7 @@ } // @has issue_22038/fn.bar.html \ -// '//*[@class="rust fn"]' 'pub extern fn bar()' +// '//*[@class="rust fn"]' 'pub extern "C" fn bar()' pub extern fn bar() {} // @has issue_22038/fn.baz.html \ diff --git a/src/test/rustdoc/variadic.rs b/src/test/rustdoc/variadic.rs index 1b60c2a334f..6ba776ba467 100644 --- a/src/test/rustdoc/variadic.rs +++ b/src/test/rustdoc/variadic.rs @@ -9,6 +9,6 @@ // except according to those terms. extern "C" { - // @has variadic/fn.foo.html //pre 'pub unsafe extern fn foo(x: i32, ...)' + // @has variadic/fn.foo.html //pre 'pub unsafe extern "C" fn foo(x: i32, ...)' pub fn foo(x: i32, ...); } diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr index adc229aaacc..78e0f7e619b 100644 --- a/src/test/ui/mismatched_types/issue-36053-2.stderr +++ b/src/test/ui/mismatched_types/issue-36053-2.stderr @@ -4,7 +4,9 @@ error: no method named `count` found for type `std::iter::Filter("str").fuse().filter(|a: &str| true).count(); | ^^^^^ | - = note: the method `count` exists but the following trait bounds were not satisfied: `[closure@$DIR/issue-36053-2.rs:17:39: 17:53] : std::ops::FnMut<(&_,)>`, `std::iter::Filter>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator` + = note: the method `count` exists but the following trait bounds were not satisfied: + `[closure@$DIR/issue-36053-2.rs:17:39: 17:53] : std::ops::FnMut<(&_,)>` + `std::iter::Filter>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator` error[E0281]: type mismatch: `[closure@$DIR/issue-36053-2.rs:17:39: 17:53]` implements the trait `for<'r> std::ops::FnMut<(&'r str,)>`, but the trait `for<'r> std::ops::FnMut<(&'r &str,)>` is required --> $DIR/issue-36053-2.rs:17:32 diff --git a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.rs b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.rs new file mode 100644 index 00000000000..a4eb4455551 --- /dev/null +++ b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.rs @@ -0,0 +1,18 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Foo; + +fn main() { + let a: Result<(), Foo> = Ok(()); + a.unwrap(); + //~^ ERROR no method named `unwrap` found for type `std::result::Result<(), Foo>` + //~| NOTE the method `unwrap` exists but the following trait bounds were not satisfied +} diff --git a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr new file mode 100644 index 00000000000..2bd786c20fe --- /dev/null +++ b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr @@ -0,0 +1,11 @@ +error: no method named `unwrap` found for type `std::result::Result<(), Foo>` in the current scope + --> $DIR/method-help-unsatisfied-bound.rs:15:7 + | +15 | a.unwrap(); + | ^^^^^^ + | + = note: the method `unwrap` exists but the following trait bounds were not satisfied: + `Foo : std::fmt::Debug` + +error: aborting due to previous error + diff --git a/src/tools/rust-installer b/src/tools/rust-installer new file mode 160000 index 00000000000..6a2c5d12910 --- /dev/null +++ b/src/tools/rust-installer @@ -0,0 +1 @@ +Subproject commit 6a2c5d129101762d204185b888d62a244011c422 diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index f14a6a03893..6b666fa809f 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -81,12 +81,12 @@ fn filter_dirs(path: &Path) -> bool { "src/libbacktrace", "src/compiler-rt", "src/rustllvm", - "src/rust-installer", "src/liblibc", "src/vendor", "src/rt/hoedown", "src/tools/cargo", "src/tools/rls", + "src/tools/rust-installer", ]; skip.iter().any(|p| path.ends_with(p)) }