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
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:
```
- 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
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'.
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 ',' ' ')"
putvar CFG_NACL_CROSS_PATH
putvar CFG_MANDIR
putvar CFG_DOCDIR
+putvar CFG_BINDIR
putvar CFG_USING_LIBCPP
msg
"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"
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"
"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]]
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"
"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"
"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"
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)",
"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"
[[package]]
name = "lazy_static"
-version = "0.2.5"
+version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
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"
"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"
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"
"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"
"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",
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",
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",
"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"
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"
"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"
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"
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"
"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"
"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"
"tools/build-manifest",
"tools/remote-test-client",
"tools/remote-test-server",
+ "tools/rust-installer",
]
# These projects have their own Cargo.lock
// Fallback musl-root for all targets
pub musl_root: Option<PathBuf>,
pub prefix: Option<PathBuf>,
+ pub sysconfdir: Option<PathBuf>,
pub docdir: Option<PathBuf>,
+ pub bindir: Option<PathBuf>,
pub libdir: Option<PathBuf>,
pub libdir_relative: Option<PathBuf>,
pub mandir: Option<PathBuf>,
#[derive(RustcDecodable, Default, Clone)]
struct Install {
prefix: Option<String>,
- mandir: Option<String>,
+ sysconfdir: Option<String>,
docdir: Option<String>,
+ bindir: Option<String>,
libdir: Option<String>,
+ mandir: Option<String>,
}
/// TOML representation of how the LLVM build is configured.
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 {
"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));
}
# 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
# =============================================================================
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};
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`.
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")
.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");
}
// 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");
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");
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");
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);
}
// 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");
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");
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");
// 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();
/// 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);
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);
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");
.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)
.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| {
})
.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)
.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"))
.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)
.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")
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)]
- [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)
--- /dev/null
+# `vec_resize_default`
+
+The tracking issue for this feature is: [#41758]
+
+[#41758]: https://github.com/rust-lang/rust/issues/41758
+
+------------------------
}
impl<T: Clone> Vec<T> {
- /// 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
///
/// 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<T: Default> Vec<T> {
+ /// 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<T> {
+ fn next(&self) -> T;
+ fn last(self) -> T;
+}
+
+struct ExtendElement<T>(T);
+impl<T: Clone> ExtendWith<T> for ExtendElement<T> {
+ fn next(&self) -> T { self.0.clone() }
+ fn last(self) -> T { self.0 }
+}
+
+struct ExtendDefault;
+impl<T: Default> ExtendWith<T> for ExtendDefault {
+ fn next(&self) -> T { Default::default() }
+ fn last(self) -> T { Default::default() }
+}
+impl<T> Vec<T> {
+ /// Extend the vector by `n` values, using the given generator.
+ fn extend_with<E: ExtendWith<T>>(&mut self, n: usize, value: E) {
self.reserve(n);
unsafe {
// 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.
impl<T: Clone> SpecFromElem for T {
default fn from_elem(elem: Self, n: usize) -> Vec<Self> {
let mut v = Vec::with_capacity(n);
- v.extend_with_element(n, elem);
+ v.extend_with(n, ExtendElement(elem));
v
}
}
}
}
let mut v = Vec::with_capacity(n);
- v.extend_with_element(n, elem);
+ v.extend_with(n, ExtendElement(elem));
v
}
}
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" }
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;
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;
}
}
+/// 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<ErasedBoxRef<[u8]>, String>;
+ fn get_dylib_metadata(&self,
+ target: &Target,
+ filename: &Path)
+ -> Result<ErasedBoxRef<[u8]>, 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<Any>;
+ // 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<DefId>>;
fn used_link_args(&self) -> Vec<String>;
// 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<CrateNum>;
fn used_link_args(&self) -> Vec<String> { 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") }
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 {
}
);
-#[derive(Clone, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum PrintRequest {
FileNames,
Sysroot,
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;
out_of_fuel: Cell::new(false),
};
- init_llvm(&sess);
-
sess
}
}
}
-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<Emitter> = match output {
config::ErrorOutputType::HumanReadable(color_config) => {
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" }
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;
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};
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();
};
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);
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);
&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 { .. } => {
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() {
}
println!("");
}
+ PrintRequest::TargetCPUs | PrintRequest::TargetFeatures => {
+ rustc_trans::print(*req, sess);
+ }
}
}
return Compilation::Stop;
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();
}
}
}
if cg_flags.contains(&"passes=list".to_string()) {
- unsafe {
- ::llvm::LLVMRustPrintPasses();
- }
+ rustc_trans::print_passes();
return None;
}
// 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.).
/// 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(',');
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};
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(),
[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" }
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(|| {
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 {
// 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;
// own crate numbers.
pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
-pub enum MetadataBlob {
- Inflated(Bytes),
- Archive(locator::ArchiveMetadata),
- Raw(Vec<u8>),
-}
+pub struct MetadataBlob(pub ErasedBoxRef<[u8]>);
/// Holds information about a syntax_pos::FileMap imported from another crate.
/// See `imported_filemaps()` for more information.
statically_included_foreign_items: RefCell<FxHashSet<DefIndex>>,
pub dllimport_foreign_items: RefCell<FxHashSet<DefIndex>>,
pub visible_parent_map: RefCell<DefIdMap<DefId>>,
+ pub metadata_loader: Box<MetadataLoader>,
}
impl CStore {
- pub fn new(dep_graph: &DepGraph) -> CStore {
+ pub fn new(dep_graph: &DepGraph, metadata_loader: Box<MetadataLoader>) -> CStore {
CStore {
dep_graph: dep_graph.clone(),
metas: RefCell::new(FxHashMap()),
statically_included_foreign_items: RefCell::new(FxHashSet()),
dllimport_foreign_items: RefCell::new(FxHashSet()),
visible_parent_map: RefCell::new(FxHashMap()),
+ metadata_loader: metadata_loader,
}
}
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;
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 {
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)
{
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)
drop(visible_parent_map);
self.visible_parent_map.borrow()
}
-}
+}
\ No newline at end of file
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
}
}
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;
extern crate rustc_back;
extern crate rustc_const_math;
extern crate rustc_data_structures;
-extern crate rustc_llvm;
mod diagnostics;
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;
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,
pub rejected_via_filename: Vec<CrateMismatch>,
pub should_match_name: bool,
pub is_proc_macro: Option<bool>,
-}
-
-pub struct ArchiveMetadata {
- _archive: ArchiveRO,
- // points into self._archive
- data: *const [u8],
+ pub metadata_loader: &'a MetadataLoader,
}
pub struct CratePaths {
pub rmeta: Option<PathBuf>,
}
-pub const METADATA_FILENAME: &'static str = "rust.metadata.bin";
-
#[derive(Copy, Clone, PartialEq)]
enum CrateFlavor {
Rlib,
let mut err: Option<DiagnosticBuilder> = 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,
err.note(&format!("crate name: {}", name));
}
-impl ArchiveMetadata {
- fn new(ar: ArchiveRO) -> Option<ArchiveMetadata> {
- 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<MetadataBlob, String> {
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());
fn get_metadata_section_imp(target: &Target,
flavor: CrateFlavor,
- filename: &Path)
+ filename: &Path,
+ loader: &MetadataLoader)
-> Result<MetadataBlob, String> {
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
} 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),
}
[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" }
use libc;
use llvm::archive_ro::{ArchiveRO, Child};
use llvm::{self, ArchiveKind};
+use metadata::METADATA_FILENAME;
use rustc::session::Session;
pub struct ArchiveConfig<'a> {
// 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
}
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};
// 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);
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
}
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
}
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;
};
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());
extern crate flate;
extern crate libc;
+extern crate owning_ref;
#[macro_use] extern crate rustc;
extern crate rustc_back;
extern crate rustc_data_structures;
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;
mod declare;
mod glue;
mod intrinsic;
+mod llvm_util;
mod machine;
+mod metadata;
mod meth;
mod mir;
mod monomorphize;
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use 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<Symbol> {
+ 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); }
+}
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use 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<ErasedBoxRef<[u8]>, 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<ErasedBoxRef<[u8]>, 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"
+}
let bound_list = unsatisfied_predicates.iter()
.map(|p| format!("`{} : {}`", p.self_ty(), p))
.collect::<Vec<_>>()
- .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));
}
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;
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));
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()),
}
}
top: 0;
}
+h3 > .collapse-toggle, h4 > .collapse-toggle {
+ font-size: 0.8em;
+ top: 5px;
+}
+
.toggle-wrapper > .collapse-toggle {
left: -24px;
margin-top: 0px;
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;
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()));
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"));
/// 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
/// 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<T: 'static> {
// This outer `LocalKey<T>` type is what's going to be stored in statics,
}
}
-/// 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
///
/// # 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]
#[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`
/// `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
/// 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,
}
/// 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")]
// 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
///
///
/// 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 {
/// 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
///
/// ```
///
/// 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 {
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.
///
/// [`spawn`]: ../../std/thread/fn.spawn.html
/// [`io::Result`]: ../../std/io/type.Result.html
+ /// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
///
/// # Examples
///
/// 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
///
/// ```
///
/// 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()
/// 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
}
}
+++ /dev/null
-Subproject commit 2e6417f6af5218a29a8ee72ed17af085560b9b9c
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-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`
-}
extern crate rustc_lint;
extern crate rustc_metadata;
extern crate rustc_errors;
+extern crate rustc_trans;
extern crate syntax;
use rustc::dep_graph::DepGraph;
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)
}
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")]
--- /dev/null
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/// 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);
+}
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() {}
// @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() {}
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);
}
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();
}
}
// @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 \
// 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, ...);
}
17 | once::<&str>("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<std::iter::Fuse<std::iter::Once<&str>>, [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<std::iter::Fuse<std::iter::Once<&str>>, [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
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+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
+}
--- /dev/null
+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
+
--- /dev/null
+Subproject commit 6a2c5d129101762d204185b888d62a244011c422
"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))
}