diff --git a/.gitmodules b/.gitmodules index fc2f8bbc8a35..55f586389b11 100644 --- a/.gitmodules +++ b/.gitmodules @@ -41,12 +41,15 @@ [submodule "src/dlmalloc"] path = src/dlmalloc url = https://github.com/alexcrichton/dlmalloc-rs.git -[submodule "src/binaryen"] - path = src/binaryen - url = https://github.com/alexcrichton/binaryen.git [submodule "src/doc/rust-by-example"] path = src/doc/rust-by-example url = https://github.com/rust-lang/rust-by-example [submodule "src/llvm-emscripten"] path = src/llvm-emscripten url = https://github.com/rust-lang/llvm +[submodule "src/stdsimd"] + path = src/stdsimd + url = https://github.com/rust-lang-nursery/stdsimd +[submodule "src/tools/lld"] + path = src/tools/lld + url = https://github.com/rust-lang/lld.git diff --git a/.travis.yml b/.travis.yml index 0d8641e45ed1..4738f91665db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -81,7 +81,7 @@ matrix: # OSX 10.7 and `xcode7` is the latest Xcode able to compile LLVM for 10.7. - env: > RUST_CHECK_TARGET=dist - RUST_CONFIGURE_ARGS="--build=i686-apple-darwin --enable-extended --enable-profiler --enable-emscripten" + RUST_CONFIGURE_ARGS="--build=i686-apple-darwin --enable-full-tools --enable-profiler" SRC=. DEPLOY=1 RUSTC_RETRY_LINKER_ON_SEGFAULT=1 @@ -95,7 +95,7 @@ matrix: - env: > RUST_CHECK_TARGET=dist - RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-extended --enable-sanitizers --enable-profiler --enable-emscripten" + RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler" SRC=. DEPLOY=1 RUSTC_RETRY_LINKER_ON_SEGFAULT=1 diff --git a/README.md b/README.md index e78bbb82711a..19ef96fae015 100644 --- a/README.md +++ b/README.md @@ -129,9 +129,6 @@ CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64. python x.py build ``` -If you are seeing build failure when compiling `rustc_binaryen`, make sure the path -length of the rust folder is not longer than 22 characters. - #### Specifying an ABI [specifying-an-abi]: #specifying-an-abi diff --git a/appveyor.yml b/appveyor.yml index 0ea15dd671c8..0735ead8923c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -67,21 +67,19 @@ environment: # 32/64 bit MSVC and GNU deployment - RUST_CONFIGURE_ARGS: > --build=x86_64-pc-windows-msvc - --enable-extended + --enable-full-tools --enable-profiler - --enable-emscripten SCRIPT: python x.py dist DEPLOY: 1 - RUST_CONFIGURE_ARGS: > --build=i686-pc-windows-msvc --target=i586-pc-windows-msvc - --enable-extended + --enable-full-tools --enable-profiler - --enable-emscripten SCRIPT: python x.py dist DEPLOY: 1 - MSYS_BITS: 32 - RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-extended --enable-emscripten + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-full-tools SCRIPT: python x.py dist MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z @@ -89,7 +87,7 @@ environment: DEPLOY: 1 - MSYS_BITS: 64 SCRIPT: python x.py dist - RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-extended --enable-emscripten + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-full-tools MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z MINGW_DIR: mingw64 diff --git a/config.toml.example b/config.toml.example index 8d1fa3eec5cf..b47f9163c0da 100644 --- a/config.toml.example +++ b/config.toml.example @@ -321,11 +321,18 @@ # bootstrap) #codegen-backends = ["llvm"] +# This is the name of the directory in which codegen backends will get installed +#codegen-backends-dir = "codegen-backends" + # Flag indicating whether `libstd` calls an imported function to handle basic IO # when targeting WebAssembly. Enable this to debug tests for the `wasm32-unknown-unknown` # target, as without this option the test output will not be captured. #wasm-syscall = false +# Indicates whether LLD will be compiled and made available in the sysroot for +# rustc to execute. +#lld = false + # ============================================================================= # Options for specific targets # diff --git a/src/Cargo.lock b/src/Cargo.lock index 7b4bfecea3fa..7620fe8ddb3c 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1818,15 +1818,6 @@ dependencies = [ "syntax 0.0.0", ] -[[package]] -name = "rustc_binaryen" -version = "0.0.0" -dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rustc_borrowck" version = "0.0.0" @@ -2107,7 +2098,6 @@ dependencies = [ "rustc_allocator 0.0.0", "rustc_apfloat 0.0.0", "rustc_back 0.0.0", - "rustc_binaryen 0.0.0", "rustc_const_math 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", diff --git a/src/binaryen b/src/binaryen deleted file mode 160000 index 17841e155edf..000000000000 --- a/src/binaryen +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 17841e155edf858c8ea7802dd5f5ecbef54b989f diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index ca35a896e08c..6c3c48aba72f 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -224,7 +224,7 @@ fn main() { // flesh out rpath support more fully in the future. cmd.arg("-Z").arg("osx-rpath-install-name"); Some("-Wl,-rpath,@loader_path/../lib") - } else if !target.contains("windows") { + } else if !target.contains("windows") && !target.contains("wasm32") { Some("-Wl,-rpath,$ORIGIN/../lib") } else { None diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 5966bb65df9c..d8f7cd7ed922 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -314,7 +314,6 @@ class RustBuild(object): self.build_dir = os.path.join(os.getcwd(), "build") self.clean = False self.config_toml = '' - self.printed = False self.rust_root = os.path.abspath(os.path.join(__file__, '../../..')) self.use_locked_deps = '' self.use_vendored_sources = '' @@ -336,7 +335,6 @@ class RustBuild(object): if self.rustc().startswith(self.bin_root()) and \ (not os.path.exists(self.rustc()) or self.program_out_of_date(self.rustc_stamp())): - self.print_what_bootstrap_means() if os.path.exists(self.bin_root()): shutil.rmtree(self.bin_root()) filename = "rust-std-{}-{}.tar.gz".format( @@ -351,10 +349,17 @@ class RustBuild(object): with open(self.rustc_stamp(), 'w') as rust_stamp: rust_stamp.write(self.date) + # This is required so that we don't mix incompatible MinGW + # libraries/binaries that are included in rust-std with + # the system MinGW ones. + if "pc-windows-gnu" in self.build: + filename = "rust-mingw-{}-{}.tar.gz".format( + rustc_channel, self.build) + self._download_stage0_helper(filename, "rust-mingw") + if self.cargo().startswith(self.bin_root()) and \ (not os.path.exists(self.cargo()) or self.program_out_of_date(self.cargo_stamp())): - self.print_what_bootstrap_means() filename = "cargo-{}-{}.tar.gz".format(cargo_channel, self.build) self._download_stage0_helper(filename, "cargo") self.fix_executable("{}/bin/cargo".format(self.bin_root())) @@ -555,23 +560,6 @@ class RustBuild(object): return '.exe' return '' - def print_what_bootstrap_means(self): - """Prints more information about the build system""" - if hasattr(self, 'printed'): - return - self.printed = True - if os.path.exists(self.bootstrap_binary()): - return - if '--help' not in sys.argv or len(sys.argv) == 1: - return - - print('info: the build system for Rust is written in Rust, so this') - print(' script is now going to download a stage0 rust compiler') - print(' and then compile the build system itself') - print('') - print('info: in the meantime you can read more about rustbuild at') - print(' src/bootstrap/README.md before the download finishes') - def bootstrap_binary(self): """Return the path of the boostrap binary @@ -585,7 +573,6 @@ class RustBuild(object): def build_bootstrap(self): """Build bootstrap""" - self.print_what_bootstrap_means() build_dir = os.path.join(self.build_dir, "bootstrap") if self.clean and os.path.exists(build_dir): shutil.rmtree(build_dir) @@ -654,6 +641,10 @@ class RustBuild(object): continue if self.get_toml('jemalloc'): continue + if module.endswith("lld"): + config = self.get_toml('lld') + if config is None or config == 'false': + continue filtered_submodules.append(module) run(["git", "submodule", "update", "--init", "--recursive"] + filtered_submodules, @@ -670,8 +661,16 @@ class RustBuild(object): self._download_url = 'https://dev-static.rust-lang.org' -def bootstrap(): +def bootstrap(help_triggered): """Configure, fetch, build and run the initial bootstrap""" + + # If the user is asking for help, let them know that the whole download-and-build + # process has to happen before anything is printed out. + if help_triggered: + print("info: Downloading and building bootstrap before processing --help") + print(" command. See src/bootstrap/README.md for help with common") + print(" commands.") + parser = argparse.ArgumentParser(description='Build rust') parser.add_argument('--config') parser.add_argument('--build') @@ -708,7 +707,7 @@ def bootstrap(): print(' and so in order to preserve your $HOME this will now') print(' use vendored sources by default. Note that if this') print(' does not work you should run a normal build first') - print(' before running a command like `sudo make install`') + print(' before running a command like `sudo ./x.py install`') if build.use_vendored_sources: if not os.path.exists('.cargo'): @@ -734,7 +733,10 @@ def bootstrap(): if 'dev' in data: build.set_dev_environment() - build.update_submodules() + # No help text depends on submodules. This check saves ~1 minute of git commands, even if + # all the submodules are present and downloaded! + if not help_triggered: + build.update_submodules() # Fetch/build the bootstrap build.build = args.build or build.build_triple() @@ -760,7 +762,7 @@ def main(): help_triggered = ( '-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1) try: - bootstrap() + bootstrap(help_triggered) if not help_triggered: print("Build completed successfully in {}".format( format_build_time(time() - start_time))) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 1df85323c41e..22656e5a9da4 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -316,7 +316,7 @@ impl<'a> Builder<'a> { tool::UnstableBookGen, tool::Tidy, tool::Linkchecker, tool::CargoTest, tool::Compiletest, tool::RemoteTestServer, tool::RemoteTestClient, tool::RustInstaller, tool::Cargo, tool::Rls, tool::Rustdoc, tool::Clippy, - native::Llvm, tool::Rustfmt, tool::Miri), + native::Llvm, tool::Rustfmt, tool::Miri, native::Lld), Kind::Check => describe!(check::Std, check::Test, check::Rustc), Kind::Test => describe!(test::Tidy, test::Bootstrap, test::Ui, test::RunPass, test::CompileFail, test::ParseFail, test::RunFail, test::RunPassValgrind, @@ -464,7 +464,7 @@ impl<'a> Builder<'a> { pub fn sysroot_codegen_backends(&self, compiler: Compiler) -> PathBuf { self.sysroot_libdir(compiler, compiler.host) - .with_file_name("codegen-backends") + .with_file_name(self.build.config.rust_codegen_backends_dir.clone()) } /// Returns the compiler's libdir where it stores the dynamic libraries that @@ -688,9 +688,25 @@ impl<'a> Builder<'a> { // // FIXME: the guard against msvc shouldn't need to be here if !target.contains("msvc") { - let cc = self.cc(target); - cargo.env(format!("CC_{}", target), cc) - .env("CC", cc); + let ccache = self.config.ccache.as_ref(); + let ccacheify = |s: &Path| { + let ccache = match ccache { + Some(ref s) => s, + None => return s.display().to_string(), + }; + // FIXME: the cc-rs crate only recognizes the literal strings + // `ccache` and `sccache` when doing caching compilations, so we + // mirror that here. It should probably be fixed upstream to + // accept a new env var or otherwise work with custom ccache + // vars. + match &ccache[..] { + "ccache" | "sccache" => format!("{} {}", ccache, s.display()), + _ => s.display().to_string(), + } + }; + let cc = ccacheify(&self.cc(target)); + cargo.env(format!("CC_{}", target), &cc) + .env("CC", &cc); let cflags = self.cflags(target).join(" "); cargo.env(format!("CFLAGS_{}", target), cflags.clone()) @@ -705,8 +721,9 @@ impl<'a> Builder<'a> { } if let Ok(cxx) = self.cxx(target) { - cargo.env(format!("CXX_{}", target), cxx) - .env("CXX", cxx) + let cxx = ccacheify(&cxx); + cargo.env(format!("CXX_{}", target), &cxx) + .env("CXX", &cxx) .env(format!("CXXFLAGS_{}", target), cflags.clone()) .env("CXXFLAGS", cflags); } diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs index e531fdaf2923..9e1b1f7db2f9 100644 --- a/src/bootstrap/cc_detect.rs +++ b/src/bootstrap/cc_detect.rs @@ -79,6 +79,9 @@ pub fn find(build: &mut Build) { let mut cfg = cc::Build::new(); cfg.cargo_metadata(false).opt_level(0).warnings(false).debug(false) .target(&target).host(&build.build); + if target.contains("msvc") { + cfg.static_crt(true); + } let config = build.config.target_config.get(&target); if let Some(cc) = config.and_then(|c| c.cc.as_ref()) { diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 408d63be6c6b..695cf04a82c1 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -514,7 +514,8 @@ fn rustc_cargo_env(build: &Build, cargo: &mut Command) { cargo.env("CFG_RELEASE", build.rust_release()) .env("CFG_RELEASE_CHANNEL", &build.config.channel) .env("CFG_VERSION", build.rust_version()) - .env("CFG_PREFIX", build.config.prefix.clone().unwrap_or_default()); + .env("CFG_PREFIX", build.config.prefix.clone().unwrap_or_default()) + .env("CFG_CODEGEN_BACKENDS_DIR", &build.config.rust_codegen_backends_dir); let libdir_relative = build.config.libdir_relative().unwrap_or(Path::new("lib")); cargo.env("CFG_LIBDIR_RELATIVE", libdir_relative); @@ -746,6 +747,21 @@ fn copy_codegen_backends_to_sysroot(builder: &Builder, } } +fn copy_lld_to_sysroot(builder: &Builder, + target_compiler: Compiler, + lld_install_root: &Path) { + let target = target_compiler.host; + + let dst = builder.sysroot_libdir(target_compiler, target) + .parent() + .unwrap() + .join("bin"); + t!(fs::create_dir_all(&dst)); + + let exe = exe("lld", &target); + copy(&lld_install_root.join("bin").join(&exe), &dst.join(&exe)); +} + /// Cargo's output path for the standard library in a given stage, compiled /// by a particular compiler for the specified target. pub fn libstd_stamp(build: &Build, compiler: Compiler, target: Interned) -> PathBuf { @@ -895,6 +911,14 @@ impl Step for Assemble { } } + let lld_install = if build.config.lld_enabled && target_compiler.stage > 0 { + Some(builder.ensure(native::Lld { + target: target_compiler.host, + })) + } else { + None + }; + let stage = target_compiler.stage; let host = target_compiler.host; println!("Assembling stage{} compiler ({})", stage, host); @@ -914,6 +938,9 @@ impl Step for Assemble { copy_codegen_backends_to_sysroot(builder, build_compiler, target_compiler); + if let Some(lld_install) = lld_install { + copy_lld_to_sysroot(builder, target_compiler, &lld_install); + } // Link the compiler binary itself into place let out_dir = build.cargo_out(build_compiler, Mode::Librustc, host); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 6bc20181a033..f15d4d358583 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -81,6 +81,8 @@ pub struct Config { pub llvm_experimental_targets: String, pub llvm_link_jobs: Option, + pub lld_enabled: bool, + // rust codegen options pub rust_optimize: bool, pub rust_codegen_units: Option, @@ -96,6 +98,7 @@ pub struct Config { pub rust_debuginfo_tests: bool, pub rust_dist_src: bool, pub rust_codegen_backends: Vec>, + pub rust_codegen_backends_dir: String, pub build: Interned, pub hosts: Vec>, @@ -289,7 +292,9 @@ struct Rust { test_miri: Option, save_toolstates: Option, codegen_backends: Option>, + codegen_backends_dir: Option, wasm_syscall: Option, + lld: Option, } /// TOML representation of how each build target is configured. @@ -330,6 +335,7 @@ impl Config { config.rust_dist_src = true; config.test_miri = false; config.rust_codegen_backends = vec![INTERNER.intern_str("llvm")]; + config.rust_codegen_backends_dir = "codegen-backends".to_owned(); config.rustc_error_format = flags.rustc_error_format; config.on_fail = flags.on_fail; @@ -477,6 +483,7 @@ impl Config { set(&mut config.quiet_tests, rust.quiet_tests); set(&mut config.test_miri, rust.test_miri); set(&mut config.wasm_syscall, rust.wasm_syscall); + set(&mut config.lld_enabled, rust.lld); config.rustc_parallel_queries = rust.experimental_parallel_queries.unwrap_or(false); config.rustc_default_linker = rust.default_linker.clone(); config.musl_root = rust.musl_root.clone().map(PathBuf::from); @@ -488,6 +495,8 @@ impl Config { .collect(); } + set(&mut config.rust_codegen_backends_dir, rust.codegen_backends_dir.clone()); + match rust.codegen_units { Some(0) => config.rust_codegen_units = Some(num_cpus::get() as u32), Some(n) => config.rust_codegen_units = Some(n), diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 99a3ee4e4c36..e9b4a233d0af 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -66,6 +66,7 @@ o("dist-src", "rust.dist-src", "when building tarballs enables building a source o("cargo-openssl-static", "build.openssl-static", "static openssl in cargo") o("profiler", "build.profiler", "build the profiler runtime") o("emscripten", None, "compile the emscripten backend as well as LLVM") +o("full-tools", None, "enable all tools") # Optimization and debugging options. These may be overridden by the release # channel, etc. @@ -326,6 +327,10 @@ for key in known_args: set('build.target', value.split(',')) elif option.name == 'emscripten': set('rust.codegen-backends', ['llvm', 'emscripten']) + elif option.name == 'full-tools': + set('rust.codegen-backends', ['llvm', 'emscripten']) + set('rust.lld', True) + set('build.extended', True) elif option.name == 'option-checking': # this was handled above pass diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index e7aed7eb4fea..576e50782474 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -28,7 +28,7 @@ use build_helper::output; use {Build, Compiler, Mode}; use channel; -use util::{cp_r, libdir, is_dylib, cp_filtered, copy, replace_in_file}; +use util::{cp_r, libdir, is_dylib, cp_filtered, copy, replace_in_file, exe}; use builder::{Builder, RunConfig, ShouldRun, Step}; use compile; use native; @@ -443,6 +443,22 @@ impl Step for Rustc { t!(fs::create_dir_all(&backends_dst)); cp_r(&backends_src, &backends_dst); + // Copy over lld if it's there + if builder.config.lld_enabled { + let exe = exe("lld", &compiler.host); + let src = builder.sysroot_libdir(compiler, host) + .parent() + .unwrap() + .join("bin") + .join(&exe); + let dst = image.join("lib/rustlib") + .join(&*host) + .join("bin") + .join(&exe); + t!(fs::create_dir_all(&dst.parent().unwrap())); + copy(&src, &dst); + } + // Man pages t!(fs::create_dir_all(image.join("share/man/man1"))); let man_src = build.src.join("src/doc/man"); @@ -590,7 +606,10 @@ impl Step for Std { let mut src = builder.sysroot_libdir(compiler, target).to_path_buf(); src.pop(); // Remove the trailing /lib folder from the sysroot_libdir cp_filtered(&src, &dst, &|path| { - path.file_name().and_then(|s| s.to_str()) != Some("codegen-backends") + let name = path.file_name().and_then(|s| s.to_str()); + name != Some(build.config.rust_codegen_backends_dir.as_str()) && + name != Some("bin") + }); let mut cmd = rust_installer(builder); diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 55d9723527e6..a791dd13f0f4 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -312,6 +312,7 @@ fn invoke_rustdoc(builder: &Builder, compiler: Compiler, target: Interned) -> PathBuf { + self.out.join(&*target).join("lld") + } + /// Output directory for all documentation for a target fn doc_out(&self, target: Interned) -> PathBuf { self.out.join(&*target).join("doc") @@ -685,7 +689,9 @@ impl Build { .and_then(|c| c.linker.as_ref()) { Some(linker) } else if target != self.config.build && - !target.contains("msvc") && !target.contains("emscripten") { + !target.contains("msvc") && + !target.contains("emscripten") && + !target.contains("wasm32") { Some(self.cc(target)) } else { None diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 653606e5d24b..7888f0b938d9 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -81,11 +81,11 @@ impl Step for Llvm { let (out_dir, llvm_config_ret_dir) = if emscripten { let dir = build.emscripten_llvm_out(target); - let config_dir = dir.join("bin"); + let config_dir = dir.join("build/bin"); (dir, config_dir) } else { (build.llvm_out(target), - build.llvm_out(build.config.build).join("bin")) + build.llvm_out(build.config.build).join("build/bin")) }; let done_stamp = out_dir.join("llvm-finished-building"); let build_llvm_config = llvm_config_ret_dir @@ -110,9 +110,6 @@ impl Step for Llvm { // http://llvm.org/docs/CMake.html let root = if self.emscripten { "src/llvm-emscripten" } else { "src/llvm" }; let mut cfg = cmake::Config::new(build.src.join(root)); - if build.config.ninja { - cfg.generator("Ninja"); - } let profile = match (build.config.llvm_optimize, build.config.llvm_release_debuginfo) { (false, _) => "Debug", @@ -139,9 +136,7 @@ impl Step for Llvm { let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"}; - cfg.target(&target) - .host(&build.build) - .out_dir(&out_dir) + cfg.out_dir(&out_dir) .profile(profile) .define("LLVM_ENABLE_ASSERTIONS", assertions) .define("LLVM_TARGETS_TO_BUILD", llvm_targets) @@ -213,67 +208,7 @@ impl Step for Llvm { cfg.define("LLVM_NATIVE_BUILD", build.llvm_out(build.build).join("build")); } - let sanitize_cc = |cc: &Path| { - if target.contains("msvc") { - OsString::from(cc.to_str().unwrap().replace("\\", "/")) - } else { - cc.as_os_str().to_owned() - } - }; - - let configure_compilers = |cfg: &mut cmake::Config| { - // MSVC with CMake uses msbuild by default which doesn't respect these - // vars that we'd otherwise configure. In that case we just skip this - // entirely. - if target.contains("msvc") && !build.config.ninja { - return - } - - let cc = build.cc(target); - let cxx = build.cxx(target).unwrap(); - - // Handle msvc + ninja + ccache specially (this is what the bots use) - if target.contains("msvc") && - build.config.ninja && - build.config.ccache.is_some() { - let mut cc = env::current_exe().expect("failed to get cwd"); - cc.set_file_name("sccache-plus-cl.exe"); - - cfg.define("CMAKE_C_COMPILER", sanitize_cc(&cc)) - .define("CMAKE_CXX_COMPILER", sanitize_cc(&cc)); - cfg.env("SCCACHE_PATH", - build.config.ccache.as_ref().unwrap()) - .env("SCCACHE_TARGET", target); - - // If ccache is configured we inform the build a little differently hwo - // to invoke ccache while also invoking our compilers. - } else if let Some(ref ccache) = build.config.ccache { - cfg.define("CMAKE_C_COMPILER", ccache) - .define("CMAKE_C_COMPILER_ARG1", sanitize_cc(cc)) - .define("CMAKE_CXX_COMPILER", ccache) - .define("CMAKE_CXX_COMPILER_ARG1", sanitize_cc(cxx)); - } else { - cfg.define("CMAKE_C_COMPILER", sanitize_cc(cc)) - .define("CMAKE_CXX_COMPILER", sanitize_cc(cxx)); - } - - cfg.build_arg("-j").build_arg(build.jobs().to_string()); - cfg.define("CMAKE_C_FLAGS", build.cflags(target).join(" ")); - cfg.define("CMAKE_CXX_FLAGS", build.cflags(target).join(" ")); - if let Some(ar) = build.ar(target) { - if ar.is_absolute() { - // LLVM build breaks if `CMAKE_AR` is a relative path, for some reason it - // tries to resolve this path in the LLVM build directory. - cfg.define("CMAKE_AR", sanitize_cc(ar)); - } - } - }; - - configure_compilers(&mut cfg); - - if env::var_os("SCCACHE_ERROR_LOG").is_some() { - cfg.env("RUST_LOG", "sccache=warn"); - } + configure_cmake(build, target, &mut cfg, false); // FIXME: we don't actually need to build all LLVM tools and all LLVM // libraries here, e.g. we just want a few components and a few @@ -304,6 +239,134 @@ fn check_llvm_version(build: &Build, llvm_config: &Path) { panic!("\n\nbad LLVM version: {}, need >=3.9\n\n", version) } +fn configure_cmake(build: &Build, + target: Interned, + cfg: &mut cmake::Config, + building_dist_binaries: bool) { + if build.config.ninja { + cfg.generator("Ninja"); + } + cfg.target(&target) + .host(&build.config.build); + + let sanitize_cc = |cc: &Path| { + if target.contains("msvc") { + OsString::from(cc.to_str().unwrap().replace("\\", "/")) + } else { + cc.as_os_str().to_owned() + } + }; + + // MSVC with CMake uses msbuild by default which doesn't respect these + // vars that we'd otherwise configure. In that case we just skip this + // entirely. + if target.contains("msvc") && !build.config.ninja { + return + } + + let cc = build.cc(target); + let cxx = build.cxx(target).unwrap(); + + // Handle msvc + ninja + ccache specially (this is what the bots use) + if target.contains("msvc") && + build.config.ninja && + build.config.ccache.is_some() { + let mut cc = env::current_exe().expect("failed to get cwd"); + cc.set_file_name("sccache-plus-cl.exe"); + + cfg.define("CMAKE_C_COMPILER", sanitize_cc(&cc)) + .define("CMAKE_CXX_COMPILER", sanitize_cc(&cc)); + cfg.env("SCCACHE_PATH", + build.config.ccache.as_ref().unwrap()) + .env("SCCACHE_TARGET", target); + + // If ccache is configured we inform the build a little differently hwo + // to invoke ccache while also invoking our compilers. + } else if let Some(ref ccache) = build.config.ccache { + cfg.define("CMAKE_C_COMPILER", ccache) + .define("CMAKE_C_COMPILER_ARG1", sanitize_cc(cc)) + .define("CMAKE_CXX_COMPILER", ccache) + .define("CMAKE_CXX_COMPILER_ARG1", sanitize_cc(cxx)); + } else { + cfg.define("CMAKE_C_COMPILER", sanitize_cc(cc)) + .define("CMAKE_CXX_COMPILER", sanitize_cc(cxx)); + } + + cfg.build_arg("-j").build_arg(build.jobs().to_string()); + cfg.define("CMAKE_C_FLAGS", build.cflags(target).join(" ")); + let mut cxxflags = build.cflags(target).join(" "); + if building_dist_binaries { + if build.config.llvm_static_stdcpp && !target.contains("windows") { + cxxflags.push_str(" -static-libstdc++"); + } + } + cfg.define("CMAKE_CXX_FLAGS", cxxflags); + if let Some(ar) = build.ar(target) { + if ar.is_absolute() { + // LLVM build breaks if `CMAKE_AR` is a relative path, for some reason it + // tries to resolve this path in the LLVM build directory. + cfg.define("CMAKE_AR", sanitize_cc(ar)); + } + } + + if env::var_os("SCCACHE_ERROR_LOG").is_some() { + cfg.env("RUST_LOG", "sccache=warn"); + } +} + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Lld { + pub target: Interned, +} + +impl Step for Lld { + type Output = PathBuf; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun) -> ShouldRun { + run.path("src/tools/lld") + } + + fn make_run(run: RunConfig) { + run.builder.ensure(Lld { target: run.target }); + } + + /// Compile LLVM for `target`. + fn run(self, builder: &Builder) -> PathBuf { + let target = self.target; + let build = builder.build; + + let llvm_config = builder.ensure(Llvm { + target: self.target, + emscripten: false, + }); + + let out_dir = build.lld_out(target); + let done_stamp = out_dir.join("lld-finished-building"); + if done_stamp.exists() { + return out_dir + } + + let _folder = build.fold_output(|| "lld"); + println!("Building LLD for {}", target); + let _time = util::timeit(); + t!(fs::create_dir_all(&out_dir)); + + let mut cfg = cmake::Config::new(build.src.join("src/tools/lld")); + configure_cmake(build, target, &mut cfg, true); + + cfg.out_dir(&out_dir) + .profile("Release") + .define("LLVM_CONFIG_PATH", llvm_config) + .define("LLVM_INCLUDE_TESTS", "OFF"); + + cfg.build(); + + t!(File::create(&done_stamp)); + out_dir + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct TestHelpers { pub target: Interned, diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index b27ddfdbc5e5..c0998c1e42c9 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -914,7 +914,7 @@ impl Step for Compiletest { } if build.config.llvm_enabled { - let llvm_config = build.llvm_config(target); + let llvm_config = build.llvm_config(build.config.build); let llvm_version = output(Command::new(&llvm_config).arg("--version")); cmd.arg("--llvm-version").arg(llvm_version); if !build.is_rust_llvm(target) { diff --git a/src/ci/docker/arm-android/Dockerfile b/src/ci/docker/arm-android/Dockerfile index f2773a720cfb..e10ccd56a4a5 100644 --- a/src/ci/docker/arm-android/Dockerfile +++ b/src/ci/docker/arm-android/Dockerfile @@ -31,9 +31,7 @@ ENV PATH=$PATH:/android/sdk/platform-tools ENV TARGETS=arm-linux-androideabi -ENV RUST_CONFIGURE_ARGS \ - --target=$TARGETS \ - --arm-linux-androideabi-ndk=/android/ndk/arm-14 +ENV RUST_CONFIGURE_ARGS --arm-linux-androideabi-ndk=/android/ndk/arm-14 ENV SCRIPT python2.7 ../x.py test --target $TARGETS diff --git a/src/ci/docker/armhf-gnu/Dockerfile b/src/ci/docker/armhf-gnu/Dockerfile index 191f8e3a2895..2b7624d53ee0 100644 --- a/src/ci/docker/armhf-gnu/Dockerfile +++ b/src/ci/docker/armhf-gnu/Dockerfile @@ -76,9 +76,7 @@ RUN curl -O http://ftp.nl.debian.org/debian/dists/jessie/main/installer-armhf/cu COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh -ENV RUST_CONFIGURE_ARGS \ - --target=arm-unknown-linux-gnueabihf \ - --qemu-armhf-rootfs=/tmp/rootfs +ENV RUST_CONFIGURE_ARGS --qemu-armhf-rootfs=/tmp/rootfs ENV SCRIPT python2.7 ../x.py test --target arm-unknown-linux-gnueabihf ENV NO_CHANGE_USER=1 diff --git a/src/ci/docker/asmjs/Dockerfile b/src/ci/docker/asmjs/Dockerfile index ff0708459bc8..2a0901691a55 100644 --- a/src/ci/docker/asmjs/Dockerfile +++ b/src/ci/docker/asmjs/Dockerfile @@ -29,6 +29,6 @@ ENV EM_CONFIG=/emsdk-portable/.emscripten ENV TARGETS=asmjs-unknown-emscripten -ENV RUST_CONFIGURE_ARGS --target=$TARGETS --enable-emscripten +ENV RUST_CONFIGURE_ARGS --enable-emscripten ENV SCRIPT python2.7 ../x.py test --target $TARGETS diff --git a/src/ci/docker/disabled/aarch64-gnu/Dockerfile b/src/ci/docker/disabled/aarch64-gnu/Dockerfile index fedb4094c8aa..b2a3ba3ec260 100644 --- a/src/ci/docker/disabled/aarch64-gnu/Dockerfile +++ b/src/ci/docker/disabled/aarch64-gnu/Dockerfile @@ -74,7 +74,6 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS \ - --target=aarch64-unknown-linux-gnu \ --qemu-aarch64-rootfs=/tmp/rootfs ENV SCRIPT python2.7 ../x.py test --target aarch64-unknown-linux-gnu ENV NO_CHANGE_USER=1 diff --git a/src/ci/docker/disabled/dist-aarch64-android/Dockerfile b/src/ci/docker/disabled/dist-aarch64-android/Dockerfile index ce5e8cfaf095..a7903b6f4250 100644 --- a/src/ci/docker/disabled/dist-aarch64-android/Dockerfile +++ b/src/ci/docker/disabled/dist-aarch64-android/Dockerfile @@ -14,8 +14,6 @@ ENV DEP_Z_ROOT=/android/ndk/arm64-21/sysroot/usr/ ENV HOSTS=aarch64-linux-android ENV RUST_CONFIGURE_ARGS \ - --host=$HOSTS \ - --target=$HOSTS \ --aarch64-linux-android-ndk=/android/ndk/arm64-21 \ --disable-rpath \ --enable-extended \ diff --git a/src/ci/docker/disabled/dist-armv7-android/Dockerfile b/src/ci/docker/disabled/dist-armv7-android/Dockerfile index 3177fa2147fa..c02a5e5a0954 100644 --- a/src/ci/docker/disabled/dist-armv7-android/Dockerfile +++ b/src/ci/docker/disabled/dist-armv7-android/Dockerfile @@ -20,8 +20,6 @@ ENV DEP_Z_ROOT=/android/ndk/arm-14/sysroot/usr/ ENV HOSTS=armv7-linux-androideabi ENV RUST_CONFIGURE_ARGS \ - --host=$HOSTS \ - --target=$HOSTS \ --armv7-linux-androideabi-ndk=/android/ndk/arm \ --disable-rpath \ --enable-extended \ diff --git a/src/ci/docker/disabled/dist-i686-android/Dockerfile b/src/ci/docker/disabled/dist-i686-android/Dockerfile index ace9c4feb4f3..04e83a431c45 100644 --- a/src/ci/docker/disabled/dist-i686-android/Dockerfile +++ b/src/ci/docker/disabled/dist-i686-android/Dockerfile @@ -20,8 +20,6 @@ ENV DEP_Z_ROOT=/android/ndk/x86-14/sysroot/usr/ ENV HOSTS=i686-linux-android ENV RUST_CONFIGURE_ARGS \ - --host=$HOSTS \ - --target=$HOSTS \ --i686-linux-android-ndk=/android/ndk/x86 \ --disable-rpath \ --enable-extended \ diff --git a/src/ci/docker/disabled/dist-x86_64-android/Dockerfile b/src/ci/docker/disabled/dist-x86_64-android/Dockerfile index 322d26f0adc4..937301864cd0 100644 --- a/src/ci/docker/disabled/dist-x86_64-android/Dockerfile +++ b/src/ci/docker/disabled/dist-x86_64-android/Dockerfile @@ -14,8 +14,6 @@ ENV DEP_Z_ROOT=/android/ndk/x86_64-21/sysroot/usr/ ENV HOSTS=x86_64-linux-android ENV RUST_CONFIGURE_ARGS \ - --host=$HOSTS \ - --target=$HOSTS \ --x86_64-linux-android-ndk=/android/ndk/x86_64-21 \ --disable-rpath \ --enable-extended \ diff --git a/src/ci/docker/disabled/dist-x86_64-dragonfly/Dockerfile b/src/ci/docker/disabled/dist-x86_64-dragonfly/Dockerfile index f3509efdb988..dbff9e32e131 100644 --- a/src/ci/docker/disabled/dist-x86_64-dragonfly/Dockerfile +++ b/src/ci/docker/disabled/dist-x86_64-dragonfly/Dockerfile @@ -32,5 +32,5 @@ ENV \ ENV HOSTS=x86_64-unknown-dragonfly -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/disabled/dist-x86_64-haiku/Dockerfile b/src/ci/docker/disabled/dist-x86_64-haiku/Dockerfile index 621976b5cbe3..440afd7c97f5 100644 --- a/src/ci/docker/disabled/dist-x86_64-haiku/Dockerfile +++ b/src/ci/docker/disabled/dist-x86_64-haiku/Dockerfile @@ -42,8 +42,8 @@ RUN sh /scripts/sccache.sh ENV HOST=x86_64-unknown-haiku ENV TARGET=target.$HOST -ENV RUST_CONFIGURE_ARGS --host=$HOST --target=$HOST --disable-jemalloc \ +ENV RUST_CONFIGURE_ARGS --disable-jemalloc \ --set=$TARGET.cc=x86_64-unknown-haiku-gcc \ --set=$TARGET.cxx=x86_64-unknown-haiku-g++ \ --set=$TARGET.llvm-config=/bin/llvm-config-haiku -ENV SCRIPT python2.7 ../x.py dist +ENV SCRIPT python2.7 ../x.py dist --host=$HOST --target=$HOST diff --git a/src/ci/docker/disabled/dist-x86_64-redox/Dockerfile b/src/ci/docker/disabled/dist-x86_64-redox/Dockerfile index ed19939545f6..f4c25f791bc3 100644 --- a/src/ci/docker/disabled/dist-x86_64-redox/Dockerfile +++ b/src/ci/docker/disabled/dist-x86_64-redox/Dockerfile @@ -18,5 +18,5 @@ ENV \ CC_x86_64_unknown_redox=x86_64-unknown-redox-gcc \ CXX_x86_64_unknown_redox=x86_64-unknown-redox-g++ -ENV RUST_CONFIGURE_ARGS --target=x86_64-unknown-redox --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --target x86_64-unknown-redox diff --git a/src/ci/docker/disabled/wasm32-exp/Dockerfile b/src/ci/docker/disabled/wasm32-exp/Dockerfile index 8653b0e8b465..420d47b314c0 100644 --- a/src/ci/docker/disabled/wasm32-exp/Dockerfile +++ b/src/ci/docker/disabled/wasm32-exp/Dockerfile @@ -30,6 +30,6 @@ ENV EM_CONFIG=/root/.emscripten ENV TARGETS=wasm32-experimental-emscripten -ENV RUST_CONFIGURE_ARGS --target=$TARGETS --experimental-targets=WebAssembly +ENV RUST_CONFIGURE_ARGS --experimental-targets=WebAssembly ENV SCRIPT python2.7 ../x.py test --target $TARGETS diff --git a/src/ci/docker/disabled/wasm32/Dockerfile b/src/ci/docker/disabled/wasm32/Dockerfile index 7f6f8ae08827..6ac90d17450a 100644 --- a/src/ci/docker/disabled/wasm32/Dockerfile +++ b/src/ci/docker/disabled/wasm32/Dockerfile @@ -29,7 +29,4 @@ ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.37.13_64bit/binaryen/ ENV EM_CONFIG=/emsdk-portable/.emscripten ENV TARGETS=wasm32-unknown-emscripten - -ENV RUST_CONFIGURE_ARGS --target=$TARGETS - ENV SCRIPT python2.7 ../x.py test --target $TARGETS diff --git a/src/ci/docker/dist-aarch64-linux/Dockerfile b/src/ci/docker/dist-aarch64-linux/Dockerfile index 841d3012125f..dbc319312aa9 100644 --- a/src/ci/docker/dist-aarch64-linux/Dockerfile +++ b/src/ci/docker/dist-aarch64-linux/Dockerfile @@ -32,5 +32,5 @@ ENV CC_aarch64_unknown_linux_gnu=aarch64-unknown-linux-gnueabi-gcc \ ENV HOSTS=aarch64-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-android/Dockerfile b/src/ci/docker/dist-android/Dockerfile index 5d7545a3c2a9..aa5da136758a 100644 --- a/src/ci/docker/dist-android/Dockerfile +++ b/src/ci/docker/dist-android/Dockerfile @@ -21,7 +21,6 @@ ENV TARGETS=$TARGETS,aarch64-linux-android ENV TARGETS=$TARGETS,x86_64-linux-android ENV RUST_CONFIGURE_ARGS \ - --target=$TARGETS \ --enable-extended \ --arm-linux-androideabi-ndk=/android/ndk/arm-14 \ --armv7-linux-androideabi-ndk=/android/ndk/arm-14 \ diff --git a/src/ci/docker/dist-arm-linux/Dockerfile b/src/ci/docker/dist-arm-linux/Dockerfile index ecd5090ea05f..89f7f85cb3b1 100644 --- a/src/ci/docker/dist-arm-linux/Dockerfile +++ b/src/ci/docker/dist-arm-linux/Dockerfile @@ -32,5 +32,5 @@ ENV CC_arm_unknown_linux_gnueabi=arm-unknown-linux-gnueabi-gcc \ ENV HOSTS=arm-unknown-linux-gnueabi -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-armhf-linux/Dockerfile b/src/ci/docker/dist-armhf-linux/Dockerfile index 5bbd17bd4142..e0c1b9a9e858 100644 --- a/src/ci/docker/dist-armhf-linux/Dockerfile +++ b/src/ci/docker/dist-armhf-linux/Dockerfile @@ -32,5 +32,5 @@ ENV CC_arm_unknown_linux_gnueabihf=arm-unknown-linux-gnueabihf-gcc \ ENV HOSTS=arm-unknown-linux-gnueabihf -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-armv7-linux/Dockerfile b/src/ci/docker/dist-armv7-linux/Dockerfile index ea9034d71788..e7d4f464ffcd 100644 --- a/src/ci/docker/dist-armv7-linux/Dockerfile +++ b/src/ci/docker/dist-armv7-linux/Dockerfile @@ -32,5 +32,5 @@ ENV CC_armv7_unknown_linux_gnueabihf=armv7-unknown-linux-gnueabihf-gcc \ ENV HOSTS=armv7-unknown-linux-gnueabihf -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile b/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile index 035846b4f643..7bcc649f4aa5 100644 --- a/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile +++ b/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile @@ -30,7 +30,6 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS \ - --target=i686-unknown-linux-musl,i586-unknown-linux-gnu \ --musl-root-i586=/musl-i586 \ --musl-root-i686=/musl-i686 \ --enable-extended @@ -46,8 +45,7 @@ ENV CFLAGS_i586_unknown_linux_gnu=-Wa,-mrelax-relocations=no # https://github.com/alexcrichton/cc-rs/pull/281 ENV CFLAGS_i586_unknown_linux_musl="-Wa,-mrelax-relocations=no -Wl,-melf_i386" -ENV TARGETS=i586-unknown-linux-gnu -ENV TARGETS=$TARGETS,i686-unknown-linux-musl +ENV TARGETS=i586-unknown-linux-gnu,i686-unknown-linux-musl ENV SCRIPT \ python2.7 ../x.py test --target $TARGETS && \ diff --git a/src/ci/docker/dist-i686-freebsd/Dockerfile b/src/ci/docker/dist-i686-freebsd/Dockerfile index 673fa4c0c4bc..1f595ba7a290 100644 --- a/src/ci/docker/dist-i686-freebsd/Dockerfile +++ b/src/ci/docker/dist-i686-freebsd/Dockerfile @@ -29,5 +29,5 @@ ENV \ ENV HOSTS=i686-unknown-freebsd -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-i686-linux/Dockerfile b/src/ci/docker/dist-i686-linux/Dockerfile index 5e405aa72e83..0ec57ee08868 100644 --- a/src/ci/docker/dist-i686-linux/Dockerfile +++ b/src/ci/docker/dist-i686-linux/Dockerfile @@ -82,13 +82,10 @@ RUN sh /scripts/sccache.sh ENV HOSTS=i686-unknown-linux-gnu ENV RUST_CONFIGURE_ARGS \ - --host=$HOSTS \ - --enable-extended \ + --enable-full-tools \ --enable-sanitizers \ - --enable-profiler \ - --enable-emscripten \ - --build=i686-unknown-linux-gnu -ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS + --enable-profiler +ENV SCRIPT python2.7 ../x.py dist --build $HOSTS --host $HOSTS --target $HOSTS # This is the only builder which will create source tarballs ENV DIST_SRC 1 diff --git a/src/ci/docker/dist-mips-linux/Dockerfile b/src/ci/docker/dist-mips-linux/Dockerfile index 94a3cf8a3820..37ab5bdcce55 100644 --- a/src/ci/docker/dist-mips-linux/Dockerfile +++ b/src/ci/docker/dist-mips-linux/Dockerfile @@ -22,5 +22,5 @@ RUN sh /scripts/sccache.sh ENV HOSTS=mips-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-mips64-linux/Dockerfile b/src/ci/docker/dist-mips64-linux/Dockerfile index 0b0dfff1fe36..a5180780b225 100644 --- a/src/ci/docker/dist-mips64-linux/Dockerfile +++ b/src/ci/docker/dist-mips64-linux/Dockerfile @@ -21,5 +21,5 @@ RUN sh /scripts/sccache.sh ENV HOSTS=mips64-unknown-linux-gnuabi64 -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-mips64el-linux/Dockerfile b/src/ci/docker/dist-mips64el-linux/Dockerfile index 1810b1cdc5ab..d38ed24f6255 100644 --- a/src/ci/docker/dist-mips64el-linux/Dockerfile +++ b/src/ci/docker/dist-mips64el-linux/Dockerfile @@ -22,5 +22,5 @@ RUN sh /scripts/sccache.sh ENV HOSTS=mips64el-unknown-linux-gnuabi64 -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-mipsel-linux/Dockerfile b/src/ci/docker/dist-mipsel-linux/Dockerfile index f5be07484758..491c57ba6773 100644 --- a/src/ci/docker/dist-mipsel-linux/Dockerfile +++ b/src/ci/docker/dist-mipsel-linux/Dockerfile @@ -21,5 +21,5 @@ RUN sh /scripts/sccache.sh ENV HOSTS=mipsel-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-powerpc-linux/Dockerfile b/src/ci/docker/dist-powerpc-linux/Dockerfile index 14ce3654fce7..c503f2af9cda 100644 --- a/src/ci/docker/dist-powerpc-linux/Dockerfile +++ b/src/ci/docker/dist-powerpc-linux/Dockerfile @@ -34,7 +34,7 @@ ENV \ ENV HOSTS=powerpc-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS # FIXME(#36150) this will fail the bootstrap. Probably means something bad is diff --git a/src/ci/docker/dist-powerpc64-linux/Dockerfile b/src/ci/docker/dist-powerpc64-linux/Dockerfile index 1f6e83e2f49e..4a3691777360 100644 --- a/src/ci/docker/dist-powerpc64-linux/Dockerfile +++ b/src/ci/docker/dist-powerpc64-linux/Dockerfile @@ -35,5 +35,5 @@ ENV \ ENV HOSTS=powerpc64-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-powerpc64le-linux/Dockerfile b/src/ci/docker/dist-powerpc64le-linux/Dockerfile index d4677e180609..bf6c8b4b7121 100644 --- a/src/ci/docker/dist-powerpc64le-linux/Dockerfile +++ b/src/ci/docker/dist-powerpc64le-linux/Dockerfile @@ -32,5 +32,5 @@ ENV \ ENV HOSTS=powerpc64le-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-s390x-linux/Dockerfile b/src/ci/docker/dist-s390x-linux/Dockerfile index 39478e92f7c9..a2ebf590bab7 100644 --- a/src/ci/docker/dist-s390x-linux/Dockerfile +++ b/src/ci/docker/dist-s390x-linux/Dockerfile @@ -34,5 +34,5 @@ ENV \ ENV HOSTS=s390x-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile index c83f101d0ac4..a23153645cde 100644 --- a/src/ci/docker/dist-various-1/Dockerfile +++ b/src/ci/docker/dist-various-1/Dockerfile @@ -89,7 +89,6 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \ CFLAGS_armv5te_unknown_linux_gnueabi="-march=armv5te -marm -mfloat-abi=soft" ENV RUST_CONFIGURE_ARGS \ - --target=$TARGETS \ --musl-root-arm=/musl-arm \ --musl-root-armhf=/musl-armhf \ --musl-root-armv7=/musl-armv7 \ diff --git a/src/ci/docker/dist-various-2/Dockerfile b/src/ci/docker/dist-various-2/Dockerfile index 5f342eb57050..4505a60e4639 100644 --- a/src/ci/docker/dist-various-2/Dockerfile +++ b/src/ci/docker/dist-various-2/Dockerfile @@ -55,5 +55,5 @@ ENV TARGETS=$TARGETS,x86_64-sun-solaris ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32 ENV TARGETS=$TARGETS,x86_64-unknown-cloudabi -ENV RUST_CONFIGURE_ARGS --target=$TARGETS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --target $TARGETS diff --git a/src/ci/docker/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/dist-x86_64-freebsd/Dockerfile index f9f5b7062f8a..dd595a192051 100644 --- a/src/ci/docker/dist-x86_64-freebsd/Dockerfile +++ b/src/ci/docker/dist-x86_64-freebsd/Dockerfile @@ -29,5 +29,5 @@ ENV \ ENV HOSTS=x86_64-unknown-freebsd -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-x86_64-linux/Dockerfile b/src/ci/docker/dist-x86_64-linux/Dockerfile index d368a00b55bd..3b98b0aa926b 100644 --- a/src/ci/docker/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/dist-x86_64-linux/Dockerfile @@ -82,11 +82,9 @@ RUN sh /scripts/sccache.sh ENV HOSTS=x86_64-unknown-linux-gnu ENV RUST_CONFIGURE_ARGS \ - --host=$HOSTS \ - --enable-extended \ + --enable-full-tools \ --enable-sanitizers \ - --enable-profiler \ - --enable-emscripten + --enable-profiler ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS # This is the only builder which will create source tarballs diff --git a/src/ci/docker/dist-x86_64-musl/Dockerfile b/src/ci/docker/dist-x86_64-musl/Dockerfile index c1061309c30f..3a9ad178c639 100644 --- a/src/ci/docker/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/dist-x86_64-musl/Dockerfile @@ -30,7 +30,6 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS \ - --target=x86_64-unknown-linux-musl \ --musl-root-x86_64=/musl-x86_64 \ --enable-extended diff --git a/src/ci/docker/dist-x86_64-netbsd/Dockerfile b/src/ci/docker/dist-x86_64-netbsd/Dockerfile index 4fd2503c31bb..06298a12fc70 100644 --- a/src/ci/docker/dist-x86_64-netbsd/Dockerfile +++ b/src/ci/docker/dist-x86_64-netbsd/Dockerfile @@ -33,5 +33,5 @@ ENV \ ENV HOSTS=x86_64-unknown-netbsd -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/wasm32-unknown/Dockerfile b/src/ci/docker/wasm32-unknown/Dockerfile index dc1727b7014c..0972eb85191a 100644 --- a/src/ci/docker/wasm32-unknown/Dockerfile +++ b/src/ci/docker/wasm32-unknown/Dockerfile @@ -22,8 +22,8 @@ RUN sh /scripts/sccache.sh ENV TARGETS=wasm32-unknown-unknown ENV RUST_CONFIGURE_ARGS \ - --target=$TARGETS \ - --set build.nodejs=/node-v9.2.0-linux-x64/bin/node + --set build.nodejs=/node-v9.2.0-linux-x64/bin/node \ + --set rust.lld ENV SCRIPT python2.7 /checkout/x.py test --target $TARGETS \ src/test/ui \ diff --git a/src/ci/run.sh b/src/ci/run.sh index 02480c6937de..3be1c255c164 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -67,6 +67,12 @@ else fi fi +# We've had problems in the past of shell scripts leaking fds into the sccache +# server (#48192) which causes Cargo to erroneously think that a build script +# hasn't finished yet. Try to solve that problem by starting a very long-lived +# sccache server at the start of the build, but no need to worry if this fails. +SCCACHE_IDLE_TIMEOUT=10800 sccache --start-server || true + travis_fold start configure travis_time_start $SRC/configure $RUST_CONFIGURE_ARGS diff --git a/src/etc/wasm32-shim.js b/src/etc/wasm32-shim.js index 69647f37eecc..98d6202a63fb 100644 --- a/src/etc/wasm32-shim.js +++ b/src/etc/wasm32-shim.js @@ -107,6 +107,8 @@ imports.env = { exp2f: function(x) { return Math.pow(2, x); }, ldexp: function(x, y) { return x * Math.pow(2, y); }, ldexpf: function(x, y) { return x * Math.pow(2, y); }, + log: Math.log, + log2: Math.log2, log10: Math.log10, log10f: Math.log10, diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 3c9b6b94b440..feed7c8699a3 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1527,142 +1527,26 @@ impl Hash for Vec { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl Index for Vec { - type Output = T; +impl Index for Vec +where + I: ::core::slice::SliceIndex<[T]>, +{ + type Output = I::Output; #[inline] - fn index(&self, index: usize) -> &T { - // NB built-in indexing via `&[T]` - &(**self)[index] - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl IndexMut for Vec { - #[inline] - fn index_mut(&mut self, index: usize) -> &mut T { - // NB built-in indexing via `&mut [T]` - &mut (**self)[index] - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::Index> for Vec { - type Output = [T]; - - #[inline] - fn index(&self, index: ops::Range) -> &[T] { + fn index(&self, index: I) -> &Self::Output { Index::index(&**self, index) } } #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::Index> for Vec { - type Output = [T]; - +impl IndexMut for Vec +where + I: ::core::slice::SliceIndex<[T]>, +{ #[inline] - fn index(&self, index: ops::RangeTo) -> &[T] { - Index::index(&**self, index) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::Index> for Vec { - type Output = [T]; - - #[inline] - fn index(&self, index: ops::RangeFrom) -> &[T] { - Index::index(&**self, index) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::Index for Vec { - type Output = [T]; - - #[inline] - fn index(&self, _index: ops::RangeFull) -> &[T] { - self - } -} - -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::Index> for Vec { - type Output = [T]; - - #[inline] - fn index(&self, index: ops::RangeInclusive) -> &[T] { - Index::index(&**self, index) - } -} - -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::Index> for Vec { - type Output = [T]; - - #[inline] - fn index(&self, index: ops::RangeToInclusive) -> &[T] { - Index::index(&**self, index) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::IndexMut> for Vec { - #[inline] - fn index_mut(&mut self, index: ops::Range) -> &mut [T] { - IndexMut::index_mut(&mut **self, index) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::IndexMut> for Vec { - #[inline] - fn index_mut(&mut self, index: ops::RangeTo) -> &mut [T] { - IndexMut::index_mut(&mut **self, index) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::IndexMut> for Vec { - #[inline] - fn index_mut(&mut self, index: ops::RangeFrom) -> &mut [T] { - IndexMut::index_mut(&mut **self, index) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::IndexMut for Vec { - #[inline] - fn index_mut(&mut self, _index: ops::RangeFull) -> &mut [T] { - self - } -} - -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::IndexMut> for Vec { - #[inline] - fn index_mut(&mut self, index: ops::RangeInclusive) -> &mut [T] { - IndexMut::index_mut(&mut **self, index) - } -} - -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::IndexMut> for Vec { - #[inline] - fn index_mut(&mut self, index: ops::RangeToInclusive) -> &mut [T] { + fn index_mut(&mut self, index: I) -> &mut Self::Output { IndexMut::index_mut(&mut **self, index) } } diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 3dd30ee1c69e..1efd605112dc 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -68,16 +68,21 @@ #![feature(allow_internal_unstable)] #![feature(asm)] #![feature(associated_type_defaults)] +#![feature(attr_literals)] #![feature(cfg_target_feature)] #![feature(cfg_target_has_atomic)] #![feature(concat_idents)] #![feature(const_fn)] #![feature(custom_attribute)] +#![feature(doc_spotlight)] #![feature(fundamental)] #![feature(i128_type)] #![feature(inclusive_range_syntax)] #![feature(intrinsics)] +#![feature(iterator_flatten)] +#![feature(iterator_repeat_with)] #![feature(lang_items)] +#![feature(link_llvm_intrinsics)] #![feature(never_type)] #![feature(no_core)] #![feature(on_unimplemented)] @@ -85,15 +90,17 @@ #![feature(prelude_import)] #![feature(repr_simd, platform_intrinsics)] #![feature(rustc_attrs)] +#![feature(rustc_const_unstable)] +#![feature(simd_ffi)] #![feature(specialization)] #![feature(staged_api)] +#![feature(stmt_expr_attributes)] +#![feature(target_feature)] #![feature(unboxed_closures)] #![feature(untagged_unions)] #![feature(unwind_attributes)] -#![feature(doc_spotlight)] -#![feature(rustc_const_unstable)] -#![feature(iterator_repeat_with)] -#![feature(iterator_flatten)] + +#![cfg_attr(stage0, allow(unused_attributes))] #[prelude_import] #[allow(unused)] @@ -179,3 +186,21 @@ mod char_private; mod iter_private; mod tuple; mod unit; + +// Pull in the the `coresimd` crate directly into libcore. This is where all the +// architecture-specific (and vendor-specific) intrinsics are defined. AKA +// things like SIMD and such. Note that the actual source for all this lies in a +// different repository, rust-lang-nursery/stdsimd. That's why the setup here is +// a bit wonky. +#[path = "../stdsimd/coresimd/mod.rs"] +#[allow(missing_docs, missing_debug_implementations, dead_code)] +#[unstable(feature = "stdsimd", issue = "48556")] +#[cfg(not(stage0))] // allow changes to how stdsimd works in stage0 +mod coresimd; + +#[unstable(feature = "stdsimd", issue = "48556")] +#[cfg(not(stage0))] +pub use coresimd::simd; +#[unstable(feature = "stdsimd", issue = "48556")] +#[cfg(not(stage0))] +pub use coresimd::arch; diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index 8bf60b091a7a..9de56cca3394 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -43,14 +43,32 @@ use std::str::FromStr; use serialize::json::{Json, ToJson}; -macro_rules! linker_flavor { - ($(($variant:ident, $string:expr),)+) => { - #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash, - RustcEncodable, RustcDecodable)] - pub enum LinkerFlavor { - $($variant,)+ - } +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash, + RustcEncodable, RustcDecodable)] +pub enum LinkerFlavor { + Em, + Gcc, + Ld, + Msvc, + Lld(LldFlavor), +} +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash, + RustcEncodable, RustcDecodable)] +pub enum LldFlavor { + Wasm, + Ld64, + Ld, + Link, +} + +impl ToJson for LinkerFlavor { + fn to_json(&self) -> Json { + self.desc().to_json() + } +} +macro_rules! flavor_mappings { + ($((($($flavor:tt)*), $string:expr),)*) => ( impl LinkerFlavor { pub const fn one_of() -> &'static str { concat!("one of: ", $($string, " ",)+) @@ -58,32 +76,30 @@ macro_rules! linker_flavor { pub fn from_str(s: &str) -> Option { Some(match s { - $($string => LinkerFlavor::$variant,)+ + $($string => $($flavor)*,)+ _ => return None, }) } pub fn desc(&self) -> &str { match *self { - $(LinkerFlavor::$variant => $string,)+ + $($($flavor)* => $string,)+ } } } - - impl ToJson for LinkerFlavor { - fn to_json(&self) -> Json { - self.desc().to_json() - } - } - } + ) } -linker_flavor! { - (Em, "em"), - (Binaryen, "binaryen"), - (Gcc, "gcc"), - (Ld, "ld"), - (Msvc, "msvc"), + +flavor_mappings! { + ((LinkerFlavor::Em), "em"), + ((LinkerFlavor::Gcc), "gcc"), + ((LinkerFlavor::Ld), "ld"), + ((LinkerFlavor::Msvc), "msvc"), + ((LinkerFlavor::Lld(LldFlavor::Wasm)), "wasm-ld"), + ((LinkerFlavor::Lld(LldFlavor::Ld64)), "ld64.lld"), + ((LinkerFlavor::Lld(LldFlavor::Ld)), "ld.lld"), + ((LinkerFlavor::Lld(LldFlavor::Link)), "lld-link"), } #[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)] diff --git a/src/librustc_back/target/aarch64_unknown_cloudabi.rs b/src/librustc_back/target/aarch64_unknown_cloudabi.rs index 59c82e06a679..a5d0e5bf166d 100644 --- a/src/librustc_back/target/aarch64_unknown_cloudabi.rs +++ b/src/librustc_back/target/aarch64_unknown_cloudabi.rs @@ -15,7 +15,7 @@ pub fn target() -> TargetResult { let mut base = super::cloudabi_base::opts(); base.max_atomic_width = Some(128); base.abi_blacklist = super::arm_base::abi_blacklist(); - base.linker = "aarch64-unknown-cloudabi-cc".to_string(); + base.linker = Some("aarch64-unknown-cloudabi-cc".to_string()); Ok(Target { llvm_target: "aarch64-unknown-cloudabi".to_string(), diff --git a/src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs b/src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs index faa2c4fdceb9..fa66a35abbf3 100644 --- a/src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs +++ b/src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs @@ -17,7 +17,7 @@ pub fn target() -> TargetResult { base.max_atomic_width = Some(64); base.features = "+v7,+vfp3,+neon".to_string(); base.abi_blacklist = super::arm_base::abi_blacklist(); - base.linker = "armv7-unknown-cloudabi-eabihf-cc".to_string(); + base.linker = Some("armv7-unknown-cloudabi-eabihf-cc".to_string()); Ok(Target { llvm_target: "armv7-unknown-cloudabi-eabihf".to_string(), diff --git a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs index a36e26c0b7d5..88f2b5967518 100644 --- a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs +++ b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs @@ -12,13 +12,7 @@ use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::linux_musl_base::opts(); - - // Most of these settings are copied from the armv7_unknown_linux_gnueabihf - // target. - base.features = "+v7,+vfp3,+neon".to_string(); - base.cpu = "cortex-a8".to_string(); - base.max_atomic_width = Some(64); + let base = super::linux_musl_base::opts(); Ok(Target { // It's important we use "gnueabihf" and not "musleabihf" here. LLVM // uses it to determine the calling convention and float ABI, and LLVM @@ -33,9 +27,15 @@ pub fn target() -> TargetResult { target_env: "musl".to_string(), target_vendor: "unknown".to_string(), linker_flavor: LinkerFlavor::Gcc, + + // Most of these settings are copied from the armv7_unknown_linux_gnueabihf + // target. options: TargetOptions { + features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(), + cpu: "generic".to_string(), + max_atomic_width: Some(64), abi_blacklist: super::arm_base::abi_blacklist(), .. base - }, + } }) } diff --git a/src/librustc_back/target/asmjs_unknown_emscripten.rs b/src/librustc_back/target/asmjs_unknown_emscripten.rs index 5d9f0f6012bf..f114926740a5 100644 --- a/src/librustc_back/target/asmjs_unknown_emscripten.rs +++ b/src/librustc_back/target/asmjs_unknown_emscripten.rs @@ -10,7 +10,6 @@ use LinkerFlavor; use super::{LinkArgs, Target, TargetOptions}; -use super::emscripten_base::{cmd}; pub fn target() -> Result { let mut args = LinkArgs::new(); @@ -19,8 +18,6 @@ pub fn target() -> Result { "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()]); let opts = TargetOptions { - linker: cmd("emcc"), - dynamic_linking: false, executables: true, exe_suffix: ".js".to_string(), diff --git a/src/librustc_back/target/emscripten_base.rs b/src/librustc_back/target/emscripten_base.rs deleted file mode 100644 index bacada3f5ab0..000000000000 --- a/src/librustc_back/target/emscripten_base.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub fn cmd(name: &str) -> String { - if cfg!(windows) { - format!("{}.bat", name) - } else { - name.to_string() - } -} diff --git a/src/librustc_back/target/haiku_base.rs b/src/librustc_back/target/haiku_base.rs index 112f424f7a8b..a1ccb632cab7 100644 --- a/src/librustc_back/target/haiku_base.rs +++ b/src/librustc_back/target/haiku_base.rs @@ -13,7 +13,6 @@ use std::default::Default; pub fn opts() -> TargetOptions { TargetOptions { - linker: "cc".to_string(), dynamic_linking: true, executables: true, has_rpath: false, diff --git a/src/librustc_back/target/i686_unknown_cloudabi.rs b/src/librustc_back/target/i686_unknown_cloudabi.rs index e244f443d3e3..69c3b298caba 100644 --- a/src/librustc_back/target/i686_unknown_cloudabi.rs +++ b/src/librustc_back/target/i686_unknown_cloudabi.rs @@ -15,7 +15,7 @@ pub fn target() -> TargetResult { let mut base = super::cloudabi_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.linker = "i686-unknown-cloudabi-cc".to_string(); + base.linker = Some("i686-unknown-cloudabi-cc".to_string()); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); base.stack_probes = true; diff --git a/src/librustc_back/target/l4re_base.rs b/src/librustc_back/target/l4re_base.rs index 31d428d26683..7cb7f8d613de 100644 --- a/src/librustc_back/target/l4re_base.rs +++ b/src/librustc_back/target/l4re_base.rs @@ -73,7 +73,6 @@ pub fn opts() -> Result { has_elf_tls: false, exe_allocation_crate: None, panic_strategy: PanicStrategy::Abort, - linker: "ld".to_string(), pre_link_args, post_link_args, target_family: Some("unix".to_string()), diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index be69127d8f2a..0a3e1826f3a1 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -58,7 +58,6 @@ mod arm_base; mod bitrig_base; mod cloudabi_base; mod dragonfly_base; -mod emscripten_base; mod freebsd_base; mod haiku_base; mod linux_base; @@ -279,8 +278,8 @@ pub struct TargetOptions { /// Whether the target is built-in or loaded from a custom target specification. pub is_builtin: bool, - /// Linker to invoke. Defaults to "cc". - pub linker: String, + /// Linker to invoke + pub linker: Option, /// Linker arguments that are unconditionally passed *before* any /// user-defined libraries. @@ -482,7 +481,7 @@ impl Default for TargetOptions { fn default() -> TargetOptions { TargetOptions { is_builtin: false, - linker: option_env!("CFG_DEFAULT_LINKER").unwrap_or("cc").to_string(), + linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.to_string()), pre_link_args: LinkArgs::new(), post_link_args: LinkArgs::new(), asm_args: Vec::new(), @@ -732,7 +731,7 @@ impl Target { } key!(is_builtin, bool); - key!(linker); + key!(linker, optional); key!(pre_link_args, link_args); key!(pre_link_objects_exe, list); key!(pre_link_objects_dll, list); diff --git a/src/librustc_back/target/msp430_none_elf.rs b/src/librustc_back/target/msp430_none_elf.rs index 966df897f01f..d0f512ae47cd 100644 --- a/src/librustc_back/target/msp430_none_elf.rs +++ b/src/librustc_back/target/msp430_none_elf.rs @@ -32,7 +32,7 @@ pub fn target() -> TargetResult { // to gcc to get object files. For this reason we have a hard // dependency on this specific gcc. asm_args: vec!["-mcpu=msp430".to_string()], - linker: "msp430-elf-gcc".to_string(), + linker: Some("msp430-elf-gcc".to_string()), no_integrated_as: true, // There are no atomic instructions available in the MSP430 diff --git a/src/librustc_back/target/thumb_base.rs b/src/librustc_back/target/thumb_base.rs index 6bb496649a85..6a8f52f50931 100644 --- a/src/librustc_back/target/thumb_base.rs +++ b/src/librustc_back/target/thumb_base.rs @@ -45,7 +45,7 @@ pub fn opts() -> TargetOptions { executables: true, // In 99%+ of cases, we want to use the `arm-none-eabi-gcc` compiler (there aren't many // options around) - linker: "arm-none-eabi-gcc".to_string(), + linker: Some("arm-none-eabi-gcc".to_string()), // Because these devices have very little resources having an unwinder is too onerous so we // default to "abort" because the "unwind" strategy is very rare. panic_strategy: PanicStrategy::Abort, diff --git a/src/librustc_back/target/wasm32_experimental_emscripten.rs b/src/librustc_back/target/wasm32_experimental_emscripten.rs index a261c982b3f2..13dee3a57686 100644 --- a/src/librustc_back/target/wasm32_experimental_emscripten.rs +++ b/src/librustc_back/target/wasm32_experimental_emscripten.rs @@ -10,7 +10,6 @@ use LinkerFlavor; use super::{LinkArgs, Target, TargetOptions}; -use super::emscripten_base::{cmd}; pub fn target() -> Result { let mut post_link_args = LinkArgs::new(); @@ -24,8 +23,6 @@ pub fn target() -> Result { "-g3".to_string()]); let opts = TargetOptions { - linker: cmd("emcc"), - dynamic_linking: false, executables: true, // Today emcc emits two files - a .js file to bootstrap and diff --git a/src/librustc_back/target/wasm32_unknown_emscripten.rs b/src/librustc_back/target/wasm32_unknown_emscripten.rs index 4823541f2262..2770e67e30a5 100644 --- a/src/librustc_back/target/wasm32_unknown_emscripten.rs +++ b/src/librustc_back/target/wasm32_unknown_emscripten.rs @@ -10,7 +10,6 @@ use LinkerFlavor; use super::{LinkArgs, Target, TargetOptions}; -use super::emscripten_base::{cmd}; pub fn target() -> Result { let mut post_link_args = LinkArgs::new(); @@ -21,8 +20,6 @@ pub fn target() -> Result { "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()]); let opts = TargetOptions { - linker: cmd("emcc"), - dynamic_linking: false, executables: true, // Today emcc emits two files - a .js file to bootstrap and diff --git a/src/librustc_back/target/wasm32_unknown_unknown.rs b/src/librustc_back/target/wasm32_unknown_unknown.rs index 242860e5c6e9..1d84e1375174 100644 --- a/src/librustc_back/target/wasm32_unknown_unknown.rs +++ b/src/librustc_back/target/wasm32_unknown_unknown.rs @@ -8,41 +8,20 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// The wasm32-unknown-unknown target is currently a highly experimental version -// of a wasm-based target which does *not* use the Emscripten toolchain. Instead -// this is a pretty flavorful (aka hacked up) target right now. The definition -// and semantics of this target are likely to change and so this shouldn't be -// relied on just yet. +// The wasm32-unknown-unknown target is currently an experimental version of a +// wasm-based target which does *not* use the Emscripten toolchain. Instead +// this toolchain is based purely on LLVM's own toolchain, using LLVM's native +// WebAssembly backend as well as LLD for a native linker. // -// In general everyone is currently waiting on a linker for wasm code. In the -// meantime we have no means of actually making use of the traditional separate -// compilation model. At a high level this means that assembling Rust programs -// into a WebAssembly program looks like: -// -// 1. All intermediate artifacts are LLVM bytecode. We'll be using LLVM as -// a linker later on. -// 2. For the final artifact we emit one giant assembly file (WebAssembly -// doesn't have an object file format). To do this we force LTO to be turned -// on (`requires_lto` below) to ensure all Rust code is in one module. Any -// "linked" C library is basically just ignored. -// 3. Using LLVM we emit a `foo.s` file (assembly) with some... what I can only -// describe as arcane syntax. From there we need to actually change this -// into a wasm module. For this step we use the `binaryen` project. This -// project is mostly intended as a WebAssembly code generator, but for now -// we're just using its LLVM-assembly-to-wasm-module conversion utilities. -// -// And voila, out comes a web assembly module! There's some various tweaks here -// and there, but that's the high level at least. Note that this will be -// rethought from the ground up once a linker (lld) is available, so this is all -// temporary and should improve in the future. +// There's some trickery below on crate types supported and various defaults +// (aka panic=abort by default), but otherwise this is in general a relatively +// standard target. -use LinkerFlavor; +use {LinkerFlavor, LldFlavor}; use super::{Target, TargetOptions, PanicStrategy}; pub fn target() -> Result { let opts = TargetOptions { - linker: "not-used".to_string(), - // we allow dynamic linking, but only cdylibs. Basically we allow a // final library artifact that exports some symbols (a wasm module) but // we don't allow intermediate `dylib` crate types @@ -58,9 +37,6 @@ pub fn target() -> Result { dll_suffix: ".wasm".to_string(), linker_is_gnu: false, - // We're storing bitcode for now in all the rlibs - obj_is_bitcode: true, - // A bit of a lie, but "eh" max_atomic_width: Some(32), @@ -69,27 +45,17 @@ pub fn target() -> Result { // the future once unwinding is implemented. Don't rely on this. panic_strategy: PanicStrategy::Abort, - // There's no linker yet so we're forced to use LLVM as a linker. This - // means that we must always enable LTO for final artifacts. - requires_lto: true, - // Wasm doesn't have atomics yet, so tell LLVM that we're in a single // threaded model which will legalize atomics to normal operations. singlethread: true, - // Because we're always enabling LTO we can't enable builtin lowering as - // otherwise we'll lower the definition of the `memcpy` function to - // memcpy itself. Note that this is specifically because we're - // performing LTO with compiler-builtins. - no_builtins: true, - // no dynamic linking, no need for default visibility! default_hidden_visibility: true, .. Default::default() }; Ok(Target { - llvm_target: "wasm32-unknown-unknown".to_string(), + llvm_target: "wasm32-unknown-unknown-wasm".to_string(), target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), @@ -100,8 +66,7 @@ pub fn target() -> Result { target_vendor: "unknown".to_string(), data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(), arch: "wasm32".to_string(), - // A bit of a lie, but it gets the job done - linker_flavor: LinkerFlavor::Binaryen, + linker_flavor: LinkerFlavor::Lld(LldFlavor::Wasm), options: opts, }) } diff --git a/src/librustc_back/target/windows_base.rs b/src/librustc_back/target/windows_base.rs index 30038400f6c8..05b6247c9518 100644 --- a/src/librustc_back/target/windows_base.rs +++ b/src/librustc_back/target/windows_base.rs @@ -75,7 +75,7 @@ pub fn opts() -> TargetOptions { TargetOptions { // FIXME(#13846) this should be enabled for windows function_sections: false, - linker: "gcc".to_string(), + linker: Some("gcc".to_string()), dynamic_linking: true, executables: true, dll_prefix: "".to_string(), diff --git a/src/librustc_back/target/windows_msvc_base.rs b/src/librustc_back/target/windows_msvc_base.rs index e0bf36ee4077..34aa17267f8b 100644 --- a/src/librustc_back/target/windows_msvc_base.rs +++ b/src/librustc_back/target/windows_msvc_base.rs @@ -20,7 +20,6 @@ pub fn opts() -> TargetOptions { TargetOptions { function_sections: true, - linker: "link.exe".to_string(), dynamic_linking: true, executables: true, dll_prefix: "".to_string(), diff --git a/src/librustc_back/target/x86_64_rumprun_netbsd.rs b/src/librustc_back/target/x86_64_rumprun_netbsd.rs index 18f6380b6eed..3158665a2e28 100644 --- a/src/librustc_back/target/x86_64_rumprun_netbsd.rs +++ b/src/librustc_back/target/x86_64_rumprun_netbsd.rs @@ -15,7 +15,7 @@ pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); base.cpu = "x86-64".to_string(); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); - base.linker = "x86_64-rumprun-netbsd-gcc".to_string(); + base.linker = Some("x86_64-rumprun-netbsd-gcc".to_string()); base.max_atomic_width = Some(64); base.dynamic_linking = false; diff --git a/src/librustc_back/target/x86_64_unknown_cloudabi.rs b/src/librustc_back/target/x86_64_unknown_cloudabi.rs index 1ce3c6444f1e..d1a9cb1cd7e7 100644 --- a/src/librustc_back/target/x86_64_unknown_cloudabi.rs +++ b/src/librustc_back/target/x86_64_unknown_cloudabi.rs @@ -15,7 +15,7 @@ pub fn target() -> TargetResult { let mut base = super::cloudabi_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.linker = "x86_64-unknown-cloudabi-cc".to_string(); + base.linker = Some("x86_64-unknown-cloudabi-cc".to_string()); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); base.stack_probes = true; diff --git a/src/librustc_binaryen/BinaryenWrapper.cpp b/src/librustc_binaryen/BinaryenWrapper.cpp deleted file mode 100644 index 55f11665f6d0..000000000000 --- a/src/librustc_binaryen/BinaryenWrapper.cpp +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This is a small C API inserted on top of the Binaryen C++ API which we use -// from Rust. Once we have a real linker for we'll be able to remove all this, -// and otherwise this is just all on a "as we need it" basis for now. - -#include -#include -#include -#include - -#include "s2wasm.h" -#include "wasm-binary.h" -#include "wasm-linker.h" - -using namespace wasm; - -struct BinaryenRustModule { - BufferWithRandomAccess buffer; - std::string sourceMapJSON; -}; - -struct BinaryenRustModuleOptions { - uint64_t globalBase; - bool debug; - uint64_t stackAllocation; - uint64_t initialMem; - uint64_t maxMem; - bool importMemory; - bool ignoreUnknownSymbols; - bool debugInfo; - std::string startFunction; - std::string sourceMapUrl; - - BinaryenRustModuleOptions() : - globalBase(0), - debug(false), - stackAllocation(0), - initialMem(0), - maxMem(0), - importMemory(false), - ignoreUnknownSymbols(false), - debugInfo(false), - startFunction(""), - sourceMapUrl("") - {} - -}; - -extern "C" BinaryenRustModuleOptions* -BinaryenRustModuleOptionsCreate() { - return new BinaryenRustModuleOptions; -} - -extern "C" void -BinaryenRustModuleOptionsFree(BinaryenRustModuleOptions *options) { - delete options; -} - -extern "C" void -BinaryenRustModuleOptionsSetDebugInfo(BinaryenRustModuleOptions *options, - bool debugInfo) { - options->debugInfo = debugInfo; -} - -extern "C" void -BinaryenRustModuleOptionsSetStart(BinaryenRustModuleOptions *options, - char *start) { - options->startFunction = start; -} - -extern "C" void -BinaryenRustModuleOptionsSetSourceMapUrl(BinaryenRustModuleOptions *options, - char *sourceMapUrl) { - options->sourceMapUrl = sourceMapUrl; -} - -extern "C" void -BinaryenRustModuleOptionsSetStackAllocation(BinaryenRustModuleOptions *options, - uint64_t stack) { - options->stackAllocation = stack; -} - -extern "C" void -BinaryenRustModuleOptionsSetImportMemory(BinaryenRustModuleOptions *options, - bool import) { - options->importMemory = import; -} - -extern "C" BinaryenRustModule* -BinaryenRustModuleCreate(const BinaryenRustModuleOptions *options, - const char *assembly) { - Linker linker( - options->globalBase, - options->stackAllocation, - options->initialMem, - options->maxMem, - options->importMemory, - options->ignoreUnknownSymbols, - options->startFunction, - options->debug); - - S2WasmBuilder mainbuilder(assembly, options->debug); - linker.linkObject(mainbuilder); - linker.layout(); - - auto ret = make_unique(); - { - WasmBinaryWriter writer(&linker.getOutput().wasm, ret->buffer, options->debug); - writer.setNamesSection(options->debugInfo); - - std::unique_ptr sourceMapStream = nullptr; - { - sourceMapStream = make_unique(); - writer.setSourceMap(sourceMapStream.get(), options->sourceMapUrl); - } - - // FIXME: support symbol maps? - // writer.setSymbolMap(symbolMap); - writer.write(); - - if (sourceMapStream) { - ret->sourceMapJSON = sourceMapStream->str(); - } - } - return ret.release(); -} - -extern "C" const uint8_t* -BinaryenRustModulePtr(const BinaryenRustModule *M) { - return M->buffer.data(); -} - -extern "C" size_t -BinaryenRustModuleLen(const BinaryenRustModule *M) { - return M->buffer.size(); -} - -extern "C" const char* -BinaryenRustModuleSourceMapPtr(const BinaryenRustModule *M) { - return M->sourceMapJSON.data(); -} - -extern "C" size_t -BinaryenRustModuleSourceMapLen(const BinaryenRustModule *M) { - return M->sourceMapJSON.length(); -} - -extern "C" void -BinaryenRustModuleFree(BinaryenRustModule *M) { - delete M; -} diff --git a/src/librustc_binaryen/Cargo.toml b/src/librustc_binaryen/Cargo.toml deleted file mode 100644 index 9573c8947140..000000000000 --- a/src/librustc_binaryen/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -# Wondering what this crate is? Take a look at the `lib.rs`! - -[package] -name = "rustc_binaryen" -version = "0.0.0" -authors = ["The Rust Project Developers"] - -[lib] -path = "lib.rs" - -[dependencies] -libc = "0.2" - -[build-dependencies] -cmake = "0.1" -cc = "1.0" diff --git a/src/librustc_binaryen/build.rs b/src/librustc_binaryen/build.rs deleted file mode 100644 index f23ff3cee555..000000000000 --- a/src/librustc_binaryen/build.rs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern crate cc; -extern crate cmake; - -use std::env; - -use cmake::Config; - -fn main() { - let target = env::var("TARGET").unwrap(); - - // Bring in `__emutls_get_address` which is apparently needed for now - if target.contains("pc-windows-gnu") { - println!("cargo:rustc-link-lib=gcc_eh"); - println!("cargo:rustc-link-lib=pthread"); - } - - Config::new("../binaryen") - .define("BUILD_STATIC_LIB", "ON") - .build_target("binaryen") - .build(); - - // I couldn't figure out how to link just one of these, so link everything. - println!("cargo:rustc-link-lib=static=asmjs"); - println!("cargo:rustc-link-lib=static=binaryen"); - println!("cargo:rustc-link-lib=static=cfg"); - println!("cargo:rustc-link-lib=static=emscripten-optimizer"); - println!("cargo:rustc-link-lib=static=ir"); - println!("cargo:rustc-link-lib=static=passes"); - println!("cargo:rustc-link-lib=static=support"); - println!("cargo:rustc-link-lib=static=wasm"); - - let out_dir = env::var("OUT_DIR").unwrap(); - println!("cargo:rustc-link-search=native={}/build/lib", out_dir); - - // Add in our own little shim along with some extra files that weren't - // included in the main build. - let mut cfg = cc::Build::new(); - cfg.file("BinaryenWrapper.cpp") - .file("../binaryen/src/wasm-linker.cpp") - .file("../binaryen/src/wasm-emscripten.cpp") - .include("../binaryen/src") - .cpp_link_stdlib(None) - .warnings(false) - .cpp(true); - - if !target.contains("msvc") { - cfg.flag("-std=c++11"); - } - cfg.compile("binaryen_wrapper"); -} diff --git a/src/librustc_binaryen/lib.rs b/src/librustc_binaryen/lib.rs deleted file mode 100644 index 36174e11ba04..000000000000 --- a/src/librustc_binaryen/lib.rs +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Rustc bindings to the binaryen project. -//! -//! This crate is a small shim around the binaryen project which provides us the -//! ability to take LLVM's output and generate a wasm module. Specifically this -//! only supports one operation, creating a module from LLVM's assembly format -//! and then serializing that module to a wasm module. - -extern crate libc; - -use std::slice; -use std::ffi::{CString, CStr}; - -/// In-memory representation of a serialized wasm module. -pub struct Module { - ptr: *mut BinaryenRustModule, -} - -impl Module { - /// Creates a new wasm module from the LLVM-assembly provided (in a C string - /// format). - /// - /// The actual module creation can be tweaked through the various options in - /// `ModuleOptions` as well. Any errors are just returned as a bland string. - pub fn new(assembly: &CStr, opts: &ModuleOptions) -> Result { - unsafe { - let ptr = BinaryenRustModuleCreate(opts.ptr, assembly.as_ptr()); - if ptr.is_null() { - Err(format!("failed to create binaryen module")) - } else { - Ok(Module { ptr }) - } - } - } - - /// Returns the data of the serialized wasm module. This is a `foo.wasm` - /// file contents. - pub fn data(&self) -> &[u8] { - unsafe { - let ptr = BinaryenRustModulePtr(self.ptr); - let len = BinaryenRustModuleLen(self.ptr); - slice::from_raw_parts(ptr, len) - } - } - - /// Returns the data of the source map JSON. - pub fn source_map(&self) -> &[u8] { - unsafe { - let ptr = BinaryenRustModuleSourceMapPtr(self.ptr); - let len = BinaryenRustModuleSourceMapLen(self.ptr); - slice::from_raw_parts(ptr, len) - } - } -} - -impl Drop for Module { - fn drop(&mut self) { - unsafe { - BinaryenRustModuleFree(self.ptr); - } - } -} - -pub struct ModuleOptions { - ptr: *mut BinaryenRustModuleOptions, -} - -impl ModuleOptions { - pub fn new() -> ModuleOptions { - unsafe { - let ptr = BinaryenRustModuleOptionsCreate(); - ModuleOptions { ptr } - } - } - - /// Turns on or off debug info. - /// - /// From what I can tell this just creates a "names" section of the wasm - /// module which contains a table of the original function names. - pub fn debuginfo(&mut self, debug: bool) -> &mut Self { - unsafe { - BinaryenRustModuleOptionsSetDebugInfo(self.ptr, debug); - } - self - } - - /// Configures a `start` function for the module, to be executed when it's - /// loaded. - pub fn start(&mut self, func: &str) -> &mut Self { - let func = CString::new(func).unwrap(); - unsafe { - BinaryenRustModuleOptionsSetStart(self.ptr, func.as_ptr()); - } - self - } - - /// Configures a `sourceMappingURL` custom section value for the module. - pub fn source_map_url(&mut self, url: &str) -> &mut Self { - let url = CString::new(url).unwrap(); - unsafe { - BinaryenRustModuleOptionsSetSourceMapUrl(self.ptr, url.as_ptr()); - } - self - } - - /// Configures how much stack is initially allocated for the module. 1MB is - /// probably good enough for now. - pub fn stack(&mut self, amt: u64) -> &mut Self { - unsafe { - BinaryenRustModuleOptionsSetStackAllocation(self.ptr, amt); - } - self - } - - /// Flags whether the initial memory should be imported or exported. So far - /// we export it by default. - pub fn import_memory(&mut self, import: bool) -> &mut Self { - unsafe { - BinaryenRustModuleOptionsSetImportMemory(self.ptr, import); - } - self - } -} - -impl Drop for ModuleOptions { - fn drop(&mut self) { - unsafe { - BinaryenRustModuleOptionsFree(self.ptr); - } - } -} - -enum BinaryenRustModule {} -enum BinaryenRustModuleOptions {} - -extern { - fn BinaryenRustModuleCreate(opts: *const BinaryenRustModuleOptions, - assembly: *const libc::c_char) - -> *mut BinaryenRustModule; - fn BinaryenRustModulePtr(module: *const BinaryenRustModule) -> *const u8; - fn BinaryenRustModuleLen(module: *const BinaryenRustModule) -> usize; - fn BinaryenRustModuleSourceMapPtr(module: *const BinaryenRustModule) -> *const u8; - fn BinaryenRustModuleSourceMapLen(module: *const BinaryenRustModule) -> usize; - fn BinaryenRustModuleFree(module: *mut BinaryenRustModule); - - fn BinaryenRustModuleOptionsCreate() - -> *mut BinaryenRustModuleOptions; - fn BinaryenRustModuleOptionsSetDebugInfo(module: *mut BinaryenRustModuleOptions, - debuginfo: bool); - fn BinaryenRustModuleOptionsSetStart(module: *mut BinaryenRustModuleOptions, - start: *const libc::c_char); - fn BinaryenRustModuleOptionsSetSourceMapUrl(module: *mut BinaryenRustModuleOptions, - sourceMapUrl: *const libc::c_char); - fn BinaryenRustModuleOptionsSetStackAllocation( - module: *mut BinaryenRustModuleOptions, - stack: u64, - ); - fn BinaryenRustModuleOptionsSetImportMemory( - module: *mut BinaryenRustModuleOptions, - import: bool, - ); - fn BinaryenRustModuleOptionsFree(module: *mut BinaryenRustModuleOptions); -} diff --git a/src/librustc_data_structures/transitive_relation.rs b/src/librustc_data_structures/transitive_relation.rs index ba7ab0c07c66..6d63bc4436fe 100644 --- a/src/librustc_data_structures/transitive_relation.rs +++ b/src/librustc_data_structures/transitive_relation.rs @@ -10,16 +10,16 @@ use bitvec::BitMatrix; use fx::FxHashMap; +use sync::Lock; use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; use stable_hasher::{HashStable, StableHasher, StableHasherResult}; -use std::cell::RefCell; use std::fmt::Debug; use std::hash::Hash; use std::mem; #[derive(Clone, Debug)] -pub struct TransitiveRelation { +pub struct TransitiveRelation { // List of elements. This is used to map from a T to a usize. elements: Vec, @@ -32,14 +32,14 @@ pub struct TransitiveRelation { // This is a cached transitive closure derived from the edges. // Currently, we build it lazilly and just throw out any existing - // copy whenever a new edge is added. (The RefCell is to permit + // copy whenever a new edge is added. (The Lock is to permit // the lazy computation.) This is kind of silly, except for the // fact its size is tied to `self.elements.len()`, so I wanted to // wait before building it up to avoid reallocating as new edges // are added with new elements. Perhaps better would be to ask the // user for a batch of edges to minimize this effect, but I // already wrote the code this way. :P -nmatsakis - closure: RefCell>, + closure: Lock>, } #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)] @@ -51,13 +51,13 @@ struct Edge { target: Index, } -impl TransitiveRelation { +impl TransitiveRelation { pub fn new() -> TransitiveRelation { TransitiveRelation { elements: vec![], map: FxHashMap(), edges: vec![], - closure: RefCell::new(None), + closure: Lock::new(None), } } @@ -72,7 +72,7 @@ impl TransitiveRelation { fn add_index(&mut self, a: T) -> Index { let &mut TransitiveRelation { ref mut elements, - ref closure, + ref mut closure, ref mut map, .. } = self; @@ -82,7 +82,7 @@ impl TransitiveRelation { elements.push(a); // if we changed the dimensions, clear the cache - *closure.borrow_mut() = None; + *closure.get_mut() = None; Index(elements.len() - 1) }) @@ -122,7 +122,7 @@ impl TransitiveRelation { self.edges.push(edge); // added an edge, clear the cache - *self.closure.borrow_mut() = None; + *self.closure.get_mut() = None; } } @@ -443,7 +443,7 @@ impl Decodable for TransitiveRelation .enumerate() .map(|(index, elem)| (elem.clone(), Index(index))) .collect(); - Ok(TransitiveRelation { elements, edges, map, closure: RefCell::new(None) }) + Ok(TransitiveRelation { elements, edges, map, closure: Lock::new(None) }) }) } } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 4d1ec111c470..d89a3e9d907e 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -303,7 +303,9 @@ fn get_trans_sysroot(backend_name: &str) -> fn() -> Box { let sysroot = sysroot_candidates.iter() .map(|sysroot| { let libdir = filesearch::relative_target_lib_path(&sysroot, &target); - sysroot.join(libdir).with_file_name("codegen-backends") + sysroot.join(libdir) + .with_file_name(option_env!("CFG_CODEGEN_BACKENDS_DIR") + .unwrap_or("codegen-backends")) }) .filter(|f| { info!("codegen backend candidate: {}", f.display()); diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml index 500c4fdf4e8d..805d2086ee4f 100644 --- a/src/librustc_trans/Cargo.toml +++ b/src/librustc_trans/Cargo.toml @@ -11,6 +11,7 @@ test = false [dependencies] bitflags = "1.0" +cc = "1.0.1" flate2 = "1.0" jobserver = "0.1.5" libc = "0.2" @@ -21,7 +22,6 @@ rustc-demangle = "0.1.4" rustc_allocator = { path = "../librustc_allocator" } rustc_apfloat = { path = "../librustc_apfloat" } rustc_back = { path = "../librustc_back" } -rustc_binaryen = { path = "../librustc_binaryen" } rustc_const_math = { path = "../librustc_const_math" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } @@ -35,9 +35,6 @@ syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } tempdir = "0.3" -[target."cfg(windows)".dependencies] -cc = "1.0.1" - [features] # Used to communicate the feature to `rustc_back` in the same manner that the # `rustc` driver script communicate this. diff --git a/src/librustc_trans/back/command.rs b/src/librustc_trans/back/command.rs index 0bccef1e62a8..ecf7bf5036e0 100644 --- a/src/librustc_trans/back/command.rs +++ b/src/librustc_trans/back/command.rs @@ -17,6 +17,8 @@ use std::io; use std::mem; use std::process::{self, Output}; +use rustc_back::LldFlavor; + #[derive(Clone)] pub struct Command { program: Program, @@ -28,6 +30,7 @@ pub struct Command { enum Program { Normal(OsString), CmdBatScript(OsString), + Lld(OsString, LldFlavor) } impl Command { @@ -39,6 +42,10 @@ impl Command { Command::_new(Program::CmdBatScript(program.as_ref().to_owned())) } + pub fn lld>(program: P, flavor: LldFlavor) -> Command { + Command::_new(Program::Lld(program.as_ref().to_owned(), flavor)) + } + fn _new(program: Program) -> Command { Command { program, @@ -74,17 +81,6 @@ impl Command { self } - pub fn envs(&mut self, envs: I) -> &mut Command - where I: IntoIterator, - K: AsRef, - V: AsRef - { - for (key, value) in envs { - self._env(key.as_ref(), value.as_ref()); - } - self - } - fn _env(&mut self, key: &OsStr, value: &OsStr) { self.env.push((key.to_owned(), value.to_owned())); } @@ -101,6 +97,16 @@ impl Command { c.arg("/c").arg(p); c } + Program::Lld(ref p, flavor) => { + let mut c = process::Command::new(p); + c.arg("-flavor").arg(match flavor { + LldFlavor::Wasm => "wasm", + LldFlavor::Ld => "gnu", + LldFlavor::Link => "link", + LldFlavor::Ld64 => "darwin", + }); + c + } }; ret.args(&self.args); ret.envs(self.env.clone()); diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 8f308e726865..636b3984117d 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use cc::windows_registry; use super::archive::{ArchiveBuilder, ArchiveConfig}; use super::bytecode::RLIB_BYTECODE_EXTENSION; use super::linker::Linker; @@ -15,6 +16,7 @@ use super::command::Command; use super::rpath::RPathConfig; use super::rpath; use metadata::METADATA_FILENAME; +use rustc_back::LinkerFlavor; use rustc::session::config::{self, NoDebugInfo, OutputFilenames, OutputType, PrintRequest}; use rustc::session::config::{RUST_CGU_EXT, Lto}; use rustc::session::filesearch; @@ -27,14 +29,13 @@ use rustc::util::common::time; use rustc::util::fs::fix_windows_verbatim_for_gcc; use rustc::hir::def_id::CrateNum; use tempdir::TempDir; -use rustc_back::{PanicStrategy, RelroLevel, LinkerFlavor}; +use rustc_back::{PanicStrategy, RelroLevel}; use context::get_reloc_model; use llvm; use std::ascii; use std::char; use std::env; -use std::ffi::OsString; use std::fmt; use std::fs; use std::io; @@ -57,9 +58,7 @@ pub use rustc_trans_utils::link::{find_crate_name, filename_for_input, default_o // The third parameter is for env vars, used on windows to set up the // path for MSVC to find its DLLs, and gcc to find its bundled // toolchain -pub fn get_linker(sess: &Session) -> (PathBuf, Command, Vec<(OsString, OsString)>) { - let envs = vec![("PATH".into(), command_path(sess))]; - +pub fn get_linker(sess: &Session) -> (PathBuf, Command) { // If our linker looks like a batch script on Windows then to execute this // we'll need to spawn `cmd` explicitly. This is primarily done to handle // emscripten where the linker is `emcc.bat` and needs to be spawned as @@ -74,56 +73,57 @@ pub fn get_linker(sess: &Session) -> (PathBuf, Command, Vec<(OsString, OsString) return Command::bat_script(linker) } } - Command::new(linker) + match sess.linker_flavor() { + LinkerFlavor::Lld(f) => Command::lld(linker, f), + _ => Command::new(linker), + + } }; - if let Some(ref linker) = sess.opts.cg.linker { - (linker.clone(), cmd(linker), envs) - } else if sess.target.target.options.is_like_msvc { - let (cmd, envs) = msvc_link_exe_cmd(sess); - (PathBuf::from("link.exe"), cmd, envs) - } else { - let linker = PathBuf::from(&sess.target.target.options.linker); - let cmd = cmd(&linker); - (linker, cmd, envs) - } -} + let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple, "link.exe"); -#[cfg(windows)] -pub fn msvc_link_exe_cmd(sess: &Session) -> (Command, Vec<(OsString, OsString)>) { - use cc::windows_registry; + let linker_path = sess.opts.cg.linker.as_ref().map(|s| &**s) + .or(sess.target.target.options.linker.as_ref().map(|s| s.as_ref())) + .unwrap_or(match sess.linker_flavor() { + LinkerFlavor::Msvc => { + msvc_tool.as_ref().map(|t| t.path()).unwrap_or("link.exe".as_ref()) + } + LinkerFlavor::Em if cfg!(windows) => "emcc.bat".as_ref(), + LinkerFlavor::Em => "emcc".as_ref(), + LinkerFlavor::Gcc => "cc".as_ref(), + LinkerFlavor::Ld => "ld".as_ref(), + LinkerFlavor::Lld(_) => "lld".as_ref(), + }); - let target = &sess.opts.target_triple; - let tool = windows_registry::find_tool(target, "link.exe"); + let mut cmd = cmd(linker_path); - if let Some(tool) = tool { - let mut cmd = Command::new(tool.path()); - cmd.args(tool.args()); - for &(ref k, ref v) in tool.env() { - cmd.env(k, v); - } - let envs = tool.env().to_vec(); - (cmd, envs) - } else { - debug!("Failed to locate linker."); - (Command::new("link.exe"), vec![]) - } -} - -#[cfg(not(windows))] -pub fn msvc_link_exe_cmd(_sess: &Session) -> (Command, Vec<(OsString, OsString)>) { - (Command::new("link.exe"), vec![]) -} - -fn command_path(sess: &Session) -> OsString { // The compiler's sysroot often has some bundled tools, so add it to the // PATH for the child. let mut new_path = sess.host_filesearch(PathKind::All) .get_tools_search_paths(); - if let Some(path) = env::var_os("PATH") { - new_path.extend(env::split_paths(&path)); + let mut msvc_changed_path = false; + if sess.target.target.options.is_like_msvc { + if let Some(ref tool) = msvc_tool { + cmd.args(tool.args()); + for &(ref k, ref v) in tool.env() { + if k == "PATH" { + new_path.extend(env::split_paths(v)); + msvc_changed_path = true; + } else { + cmd.env(k, v); + } + } + } } - env::join_paths(new_path).unwrap() + + if !msvc_changed_path { + if let Some(path) = env::var_os("PATH") { + new_path.extend(env::split_paths(&path)); + } + } + cmd.env("PATH", env::join_paths(new_path).unwrap()); + + (linker_path.to_path_buf(), cmd) } pub fn remove(sess: &Session, path: &Path) { @@ -612,15 +612,8 @@ fn link_natively(sess: &Session, info!("preparing {:?} to {:?}", crate_type, out_filename); let flavor = sess.linker_flavor(); - // The "binaryen linker" is massively special, so skip everything below. - if flavor == LinkerFlavor::Binaryen { - return link_binaryen(sess, crate_type, out_filename, trans, tmpdir); - } - // The invocations of cc share some flags across platforms - let (pname, mut cmd, envs) = get_linker(sess); - // This will set PATH on windows - cmd.envs(envs); + let (pname, mut cmd) = get_linker(sess); let root = sess.target_filesearch(PathKind::Native).get_lib_path(); if let Some(args) = sess.target.target.options.pre_link_args.get(&flavor) { @@ -1485,33 +1478,6 @@ fn relevant_lib(sess: &Session, lib: &NativeLibrary) -> bool { } } -/// For now "linking with binaryen" is just "move the one module we generated in -/// the backend to the final output" -/// -/// That is, all the heavy lifting happens during the `back::write` phase. Here -/// we just clean up after that. -/// -/// Note that this is super temporary and "will not survive the night", this is -/// guaranteed to get removed as soon as a linker for wasm exists. This should -/// not be used for anything other than wasm. -fn link_binaryen(sess: &Session, - _crate_type: config::CrateType, - out_filename: &Path, - trans: &CrateTranslation, - _tmpdir: &Path) { - assert!(trans.allocator_module.is_none()); - assert_eq!(trans.modules.len(), 1); - - let object = trans.modules[0].object.as_ref().expect("object must exist"); - let res = fs::hard_link(object, out_filename) - .or_else(|_| fs::copy(object, out_filename).map(|_| ())); - if let Err(e) = res { - sess.fatal(&format!("failed to create `{}`: {}", - out_filename.display(), - e)); - } -} - fn is_full_lto_enabled(sess: &Session) -> bool { match sess.lto() { Lto::Yes | diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index 7e7811c56c74..a3ff39a47a29 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -23,7 +23,7 @@ use rustc::middle::dependency_format::Linkage; use rustc::session::Session; use rustc::session::config::{self, CrateType, OptLevel, DebugInfoLevel}; use rustc::ty::TyCtxt; -use rustc_back::LinkerFlavor; +use rustc_back::{LinkerFlavor, LldFlavor}; use serialize::{json, Encoder}; /// For all the linkers we support, and information they might @@ -45,6 +45,7 @@ impl LinkerInfo { cmd: Command, sess: &'a Session) -> Box { match sess.linker_flavor() { + LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => { Box::new(MsvcLinker { cmd, @@ -68,6 +69,9 @@ impl LinkerInfo { is_ld: false, }) as Box } + + LinkerFlavor::Lld(LldFlavor::Ld) | + LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Ld => { Box::new(GccLinker { cmd, @@ -77,8 +81,11 @@ impl LinkerInfo { is_ld: true, }) as Box } - LinkerFlavor::Binaryen => { - panic!("can't instantiate binaryen linker") + + LinkerFlavor::Lld(LldFlavor::Wasm) => { + Box::new(WasmLd { + cmd, + }) as Box } } } @@ -785,3 +792,111 @@ fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec { symbols } + +pub struct WasmLd { + cmd: Command, +} + +impl Linker for WasmLd { + fn link_dylib(&mut self, lib: &str) { + self.cmd.arg("-l").arg(lib); + } + + fn link_staticlib(&mut self, lib: &str) { + self.cmd.arg("-l").arg(lib); + } + + fn link_rlib(&mut self, lib: &Path) { + self.cmd.arg(lib); + } + + fn include_path(&mut self, path: &Path) { + self.cmd.arg("-L").arg(path); + } + + fn framework_path(&mut self, _path: &Path) { + panic!("frameworks not supported") + } + + fn output_filename(&mut self, path: &Path) { + self.cmd.arg("-o").arg(path); + } + + fn add_object(&mut self, path: &Path) { + self.cmd.arg(path); + } + + fn position_independent_executable(&mut self) { + } + + fn partial_relro(&mut self) { + } + + fn full_relro(&mut self) { + } + + fn build_static_executable(&mut self) { + } + + fn args(&mut self, args: &[String]) { + self.cmd.args(args); + } + + fn link_rust_dylib(&mut self, lib: &str, _path: &Path) { + self.cmd.arg("-l").arg(lib); + } + + fn link_framework(&mut self, _framework: &str) { + panic!("frameworks not supported") + } + + fn link_whole_staticlib(&mut self, lib: &str, _search_path: &[PathBuf]) { + self.cmd.arg("-l").arg(lib); + } + + fn link_whole_rlib(&mut self, lib: &Path) { + self.cmd.arg(lib); + } + + fn gc_sections(&mut self, _keep_metadata: bool) { + } + + fn optimize(&mut self) { + } + + fn debuginfo(&mut self) { + } + + fn no_default_libraries(&mut self) { + } + + fn build_dylib(&mut self, _out_filename: &Path) { + } + + fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType) { + } + + fn subsystem(&mut self, _subsystem: &str) { + } + + fn no_position_independent_executable(&mut self) { + } + + fn finalize(&mut self) -> Command { + self.cmd.arg("--threads"); + + // FIXME we probably shouldn't pass this but instead pass an explicit + // whitelist of symbols we'll allow to be undefined. Unfortunately + // though we can't handle symbols like `log10` that LLVM injects at a + // super late date without actually parsing object files. For now let's + // stick to this and hopefully fix it before stabilization happens. + self.cmd.arg("--allow-undefined"); + + // For now we just never have an entry symbol + self.cmd.arg("--no-entry"); + + let mut cmd = Command::new(""); + ::std::mem::swap(&mut cmd, &mut self.cmd); + cmd + } +} diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index 68c0ba026500..55ef4e7ed3ae 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -21,7 +21,6 @@ use rustc::ty::TyCtxt; use rustc::ty::maps::Providers; use rustc::util::nodemap::FxHashMap; use rustc_allocator::ALLOCATOR_METHODS; -use rustc_back::LinkerFlavor; use syntax::attr; pub type ExportedSymbols = FxHashMap< @@ -156,26 +155,12 @@ pub fn provide_extern(providers: &mut Providers) { let special_runtime_crate = tcx.is_panic_runtime(cnum) || tcx.is_compiler_builtins(cnum); - // Dealing with compiler-builtins and wasm right now is super janky. - // There's no linker! As a result we need all of the compiler-builtins - // exported symbols to make their way through all the way to the end of - // compilation. We want to make sure that LLVM doesn't remove them as - // well because we may or may not need them in the final output - // artifact. For now just force them to always get exported at the C - // layer, and we'll worry about gc'ing them later. - let compiler_builtins_and_binaryen = - tcx.is_compiler_builtins(cnum) && - tcx.sess.linker_flavor() == LinkerFlavor::Binaryen; - let mut crate_exports: Vec<_> = tcx .exported_symbol_ids(cnum) .iter() .map(|&def_id| { let name = tcx.symbol_name(Instance::mono(tcx, def_id)); - let export_level = if compiler_builtins_and_binaryen && - tcx.contains_extern_indicator(def_id) { - SymbolExportLevel::C - } else if special_runtime_crate { + let export_level = if special_runtime_crate { // We can probably do better here by just ensuring that // it has hidden visibility rather than public // visibility, as this is primarily here to ensure it's diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index af5178eb565d..78b26a37485e 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -23,7 +23,6 @@ use rustc::session::config::{self, OutputFilenames, OutputType, Passes, SomePass AllPasses, Sanitizer, Lto}; use rustc::session::Session; use rustc::util::nodemap::FxHashMap; -use rustc_back::LinkerFlavor; use time_graph::{self, TimeGraph, Timeline}; use llvm; use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef}; @@ -344,9 +343,7 @@ pub struct CodegenContext { pub tm_factory: Arc Result + Send + Sync>, pub msvc_imps_needed: bool, pub target_pointer_width: String, - binaryen_linker: bool, debuginfo: config::DebugInfoLevel, - wasm_import_memory: bool, // Number of cgus excluding the allocator/metadata modules pub total_cgus: usize, @@ -639,13 +636,6 @@ unsafe fn codegen(cgcx: &CodegenContext, f(cpm) } - // If we're going to generate wasm code from the assembly that llvm - // generates then we'll be transitively affecting a ton of options below. - // This only happens on the wasm target now. - let asm2wasm = cgcx.binaryen_linker && - !cgcx.crate_types.contains(&config::CrateTypeRlib) && - mtrans.kind == ModuleKind::Regular; - // If we don't have the integrated assembler, then we need to emit asm // from LLVM and use `gcc` to create the object file. let asm_to_obj = config.emit_obj && config.no_integrated_as; @@ -654,10 +644,10 @@ unsafe fn codegen(cgcx: &CodegenContext, // just llvm bitcode. In that case write bitcode, and possibly // delete the bitcode if it wasn't requested. Don't generate the // machine code, instead copy the .o file from the .bc - let write_bc = config.emit_bc || (config.obj_is_bitcode && !asm2wasm); - let rm_bc = !config.emit_bc && config.obj_is_bitcode && !asm2wasm; - let write_obj = config.emit_obj && !config.obj_is_bitcode && !asm2wasm && !asm_to_obj; - let copy_bc_to_obj = config.emit_obj && config.obj_is_bitcode && !asm2wasm; + let write_bc = config.emit_bc || config.obj_is_bitcode; + let rm_bc = !config.emit_bc && config.obj_is_bitcode; + let write_obj = config.emit_obj && !config.obj_is_bitcode && !asm_to_obj; + let copy_bc_to_obj = config.emit_obj && config.obj_is_bitcode; let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name); let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name); @@ -736,13 +726,13 @@ unsafe fn codegen(cgcx: &CodegenContext, timeline.record("ir"); } - if config.emit_asm || (asm2wasm && config.emit_obj) || asm_to_obj { + if config.emit_asm || asm_to_obj { let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); // We can't use the same module for asm and binary output, because that triggers // various errors like invalid IR or broken binaries, so we might have to clone the // module to produce the asm output - let llmod = if config.emit_obj && !asm2wasm { + let llmod = if config.emit_obj { llvm::LLVMCloneModule(llmod) } else { llmod @@ -751,24 +741,13 @@ unsafe fn codegen(cgcx: &CodegenContext, write_output_file(diag_handler, tm, cpm, llmod, &path, llvm::FileType::AssemblyFile) })?; - if config.emit_obj && !asm2wasm { + if config.emit_obj { llvm::LLVMDisposeModule(llmod); } timeline.record("asm"); } - if asm2wasm && config.emit_obj { - let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); - let suffix = ".wasm.map"; // FIXME use target suffix - let map = cgcx.output_filenames.path(OutputType::Exe) - .with_extension(&suffix[1..]); - binaryen_assemble(cgcx, diag_handler, &assembly, &obj_out, &map); - timeline.record("binaryen"); - - if !config.emit_asm { - drop(fs::remove_file(&assembly)); - } - } else if write_obj { + if write_obj { with_codegen(tm, llmod, config.no_builtins, |cpm| { write_output_file(diag_handler, tm, cpm, llmod, &obj_out, llvm::FileType::ObjectFile) @@ -808,49 +787,6 @@ unsafe fn codegen(cgcx: &CodegenContext, &cgcx.output_filenames)) } -/// Translates the LLVM-generated `assembly` on the filesystem into a wasm -/// module using binaryen, placing the output at `object`. -/// -/// In this case the "object" is actually a full and complete wasm module. We -/// won't actually be doing anything else to the output for now. This is all -/// pretty janky and will get removed as soon as a linker for wasm exists. -fn binaryen_assemble(cgcx: &CodegenContext, - handler: &Handler, - assembly: &Path, - object: &Path, - map: &Path) { - use rustc_binaryen::{Module, ModuleOptions}; - - let input = fs::read(&assembly).and_then(|contents| { - Ok(CString::new(contents)?) - }); - let mut options = ModuleOptions::new(); - if cgcx.debuginfo != config::NoDebugInfo { - options.debuginfo(true); - let map_file_name = map.file_name().unwrap(); - options.source_map_url(map_file_name.to_str().unwrap()); - } - - options.stack(1024 * 1024); - options.import_memory(cgcx.wasm_import_memory); - let assembled = input.and_then(|input| { - Module::new(&input, &options) - .map_err(|e| io::Error::new(io::ErrorKind::Other, e)) - }); - let err = assembled.and_then(|binary| { - fs::write(&object, binary.data()).and_then(|()| { - if cgcx.debuginfo != config::NoDebugInfo { - fs::write(map, binary.source_map()) - } else { - Ok(()) - } - }) - }); - if let Err(e) = err { - handler.err(&format!("failed to run binaryen assembler: {}", e)); - } -} - pub(crate) struct CompiledModules { pub modules: Vec, pub metadata_module: CompiledModule, @@ -1431,12 +1367,9 @@ fn start_executing_work(tcx: TyCtxt, each_linked_rlib_for_lto.push((cnum, path.to_path_buf())); })); - let wasm_import_memory = - attr::contains_name(&tcx.hir.krate().attrs, "wasm_import_memory"); - let assembler_cmd = if modules_config.no_integrated_as { // HACK: currently we use linker (gcc) as our assembler - let (name, mut cmd, _) = get_linker(sess); + let (name, mut cmd) = get_linker(sess); cmd.args(&sess.target.target.options.asm_args); Some(Arc::new(AssemblerCommand { name, @@ -1471,9 +1404,7 @@ fn start_executing_work(tcx: TyCtxt, total_cgus, msvc_imps_needed: msvc_imps_needed(tcx), target_pointer_width: tcx.sess.target.target.target_pointer_width.clone(), - binaryen_linker: tcx.sess.linker_flavor() == LinkerFlavor::Binaryen, debuginfo: tcx.sess.opts.debuginfo, - wasm_import_memory, assembler_cmd, }; diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 6cb9d2027c74..0b8da10b78e7 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -49,7 +49,6 @@ extern crate rustc_mir; extern crate rustc_allocator; extern crate rustc_apfloat; extern crate rustc_back; -extern crate rustc_binaryen; extern crate rustc_const_math; extern crate rustc_data_structures; extern crate rustc_demangle; @@ -63,7 +62,6 @@ extern crate rustc_trans_utils; extern crate syntax_pos; extern crate rustc_errors as errors; extern crate serialize; -#[cfg(windows)] extern crate cc; // Used to locate MSVC extern crate tempdir; diff --git a/src/librustdoc/README.md b/src/librustdoc/README.md new file mode 100644 index 000000000000..b0a5ae3718df --- /dev/null +++ b/src/librustdoc/README.md @@ -0,0 +1,172 @@ +# The walking tour of rustdoc + +Rustdoc is implemented entirely within the crate `librustdoc`. After partially compiling a crate to +get its AST (technically the HIR map) from rustc, librustdoc performs two major steps past that to +render a set of documentation: + +* "Clean" the AST into a form that's more suited to creating documentation (and slightly more + resistant to churn in the compiler). +* Use this cleaned AST to render a crate's documentation, one page at a time. + +Naturally, there's more than just this, and those descriptions simplify out lots of details, but +that's the high-level overview. + +(Side note: this is a library crate! The `rustdoc` binary is crated using the project in +`src/tools/rustdoc`. Note that literally all that does is call the `main()` that's in this crate's +`lib.rs`, though.) + +## Cheat sheet + +* Use `x.py build --stage 1 src/libstd src/tools/rustdoc` to make a useable rustdoc you can run on + other projects. + * Add `src/libtest` to be able to use `rustdoc --test`. + * If you've used `rustup toolchain link local /path/to/build/$TARGET/stage1` previously, then + after the previous build command, `cargo +local doc` will Just Work. +* Use `x.py doc --stage 1 src/libstd` to use this rustdoc to generate the standard library docs. + * The completed docs will be available in `build/$TARGET/doc/std`, though the bundle is meant to + be used as though you would copy out the `doc` folder to a web server, since that's where the + CSS/JS and landing page are. +* Most of the HTML printing code is in `html/format.rs` and `html/render.rs`. It's in a bunch of + `fmt::Display` implementations and supplementary functions. +* The types that got `Display` impls above are defined in `clean/mod.rs`, right next to the custom + `Clean` trait used to process them out of the rustc HIR. +* The bits specific to using rustdoc as a test harness are in `test.rs`. +* The Markdown renderer is loaded up in `html/markdown.rs`, including functions for extracting + doctests from a given block of Markdown. +* The tests on rustdoc *output* are located in `src/test/rustdoc`, where they're handled by the test + runner of rustbuild and the supplementary script `src/etc/htmldocck.py`. +* Tests on search index generation are located in `src/test/rustdoc-js`, as a series of JavaScript + files that encode queries on the standard library search index and expected results. + +## From crate to clean + +In `core.rs` are two central items: the `DocContext` struct, and the `run_core` function. The latter +is where rustdoc calls out to rustc to compile a crate to the point where rustdoc can take over. The +former is a state container used when crawling through a crate to gather its documentation. + +The main process of crate crawling is done in `clean/mod.rs` through several implementations of the +`Clean` trait defined within. This is a conversion trait, which defines one method: + +```rust +pub trait Clean { + fn clean(&self, cx: &DocContext) -> T; +} +``` + +`clean/mod.rs` also defines the types for the "cleaned" AST used later on to render documentation +pages. Each usually accompanies an implementation of `Clean` that takes some AST or HIR type from +rustc and converts it into the appropriate "cleaned" type. "Big" items like modules or associated +items may have some extra processing in its `Clean` implementation, but for the most part these +impls are straightforward conversions. The "entry point" to this module is the `impl Clean +for visit_ast::RustdocVisitor`, which is called by `run_core` above. + +You see, I actually lied a little earlier: There's another AST transformation that happens before +the events in `clean/mod.rs`. In `visit_ast.rs` is the type `RustdocVisitor`, which *actually* +crawls a `hir::Crate` to get the first intermediate representation, defined in `doctree.rs`. This +pass is mainly to get a few intermediate wrappers around the HIR types and to process visibility +and inlining. This is where `#[doc(inline)]`, `#[doc(no_inline)]`, and `#[doc(hidden)]` are +processed, as well as the logic for whether a `pub use` should get the full page or a "Reexport" +line in the module page. + +The other major thing that happens in `clean/mod.rs` is the collection of doc comments and +`#[doc=""]` attributes into a separate field of the Attributes struct, present on anything that gets +hand-written documentation. This makes it easier to collect this documentation later in the process. + +The primary output of this process is a clean::Crate with a tree of Items which describe the +publicly-documentable items in the target crate. + +### Hot potato + +Before moving on to the next major step, a few important "passes" occur over the documentation. +These do things like combine the separate "attributes" into a single string and strip leading +whitespace to make the document easier on the markdown parser, or drop items that are not public or +deliberately hidden with `#[doc(hidden)]`. These are all implemented in the `passes/` directory, one +file per pass. By default, all of these passes are run on a crate, but the ones regarding dropping +private/hidden items can be bypassed by passing `--document-private-items` to rustdoc. + +(Strictly speaking, you can fine-tune the passes run and even add your own, but [we're trying to +deprecate that][44136]. If you need finer-grain control over these passes, please let us know!) + +[44136]: https://github.com/rust-lang/rust/issues/44136 + +## From clean to crate + +This is where the "second phase" in rustdoc begins. This phase primarily lives in the `html/` +folder, and it all starts with `run()` in `html/render.rs`. This code is responsible for setting up +the `Context`, `SharedContext`, and `Cache` which are used during rendering, copying out the static +files which live in every rendered set of documentation (things like the fonts, CSS, and JavaScript +that live in `html/static/`), creating the search index, and printing out the source code rendering, +before beginning the process of rendering all the documentation for the crate. + +Several functions implemented directly on `Context` take the `clean::Crate` and set up some state +between rendering items or recursing on a module's child items. From here the "page rendering" +begins, via an enormous `write!()` call in `html/layout.rs`. The parts that actually generate HTML +from the items and documentation occurs within a series of `std::fmt::Display` implementations and +functions that pass around a `&mut std::fmt::Formatter`. The top-level implementation that writes +out the page body is the `impl<'a> fmt::Display for Item<'a>` in `html/render.rs`, which switches +out to one of several `item_*` functions based on the kind of `Item` being rendered. + +Depending on what kind of rendering code you're looking for, you'll probably find it either in +`html/render.rs` for major items like "what sections should I print for a struct page" or +`html/format.rs` for smaller component pieces like "how should I print a where clause as part of +some other item". + +Whenever rustdoc comes across an item that should print hand-written documentation alongside, it +calls out to `html/markdown.rs` which interfaces with the Markdown parser. This is exposed as a +series of types that wrap a string of Markdown, and implement `fmt::Display` to emit HTML text. It +takes special care to enable certain features like footnotes and tables and add syntax highlighting +to Rust code blocks (via `html/highlight.rs`) before running the Markdown parser. There's also a +function in here (`find_testable_code`) that specifically scans for Rust code blocks so the +test-runner code can find all the doctests in the crate. + +### From soup to nuts + +(alternate title: ["An unbroken thread that stretches from those first `Cell`s to us"][video]) + +[video]: https://www.youtube.com/watch?v=hOLAGYmUQV0 + +It's important to note that the AST cleaning can ask the compiler for information (crucially, +`DocContext` contains a `TyCtxt`), but page rendering cannot. The `clean::Crate` created within +`run_core` is passed outside the compiler context before being handed to `html::render::run`. This +means that a lot of the "supplementary data" that isn't immediately available inside an item's +definition, like which trait is the `Deref` trait used by the language, needs to be collected during +cleaning, stored in the `DocContext`, and passed along to the `SharedContext` during HTML rendering. +This manifests as a bunch of shared state, context variables, and `RefCell`s. + +Also of note is that some items that come from "asking the compiler" don't go directly into the +`DocContext` - for example, when loading items from a foreign crate, rustdoc will ask about trait +implementations and generate new `Item`s for the impls based on that information. This goes directly +into the returned `Crate` rather than roundabout through the `DocContext`. This way, these +implementations can be collected alongside the others, right before rendering the HTML. + +## Other tricks up its sleeve + +All this describes the process for generating HTML documentation from a Rust crate, but there are +couple other major modes that rustdoc runs in. It can also be run on a standalone Markdown file, or +it can run doctests on Rust code or standalone Markdown files. For the former, it shortcuts straight +to `html/markdown.rs`, optionally including a mode which inserts a Table of Contents to the output +HTML. + +For the latter, rustdoc runs a similar partial-compilation to get relevant documentation in +`test.rs`, but instead of going through the full clean and render process, it runs a much simpler +crate walk to grab *just* the hand-written documentation. Combined with the aforementioned +"`find_testable_code`" in `html/markdown.rs`, it builds up a collection of tests to run before +handing them off to the libtest test runner. One notable location in `test.rs` is the function +`make_test`, which is where hand-written doctests get transformed into something that can be +executed. + +## Dotting i's and crossing t's + +So that's rustdoc's code in a nutshell, but there's more things in the repo that deal with it. Since +we have the full `compiletest` suite at hand, there's a set of tests in `src/test/rustdoc` that make +sure the final HTML is what we expect in various situations. These tests also use a supplementary +script, `src/etc/htmldocck.py`, that allows it to look through the final HTML using XPath notation +to get a precise look at the output. The full description of all the commands available to rustdoc +tests is in `htmldocck.py`. + +In addition, there are separate tests for the search index and rustdoc's ability to query it. The +files in `src/test/rustdoc-js` each contain a different search query and the expected results, +broken out by search tab. These files are processed by a script in `src/tools/rustdoc-js` and the +Node.js runtime. These tests don't have as thorough of a writeup, but a broad example that features +results in all tabs can be found in `basic.js`. The basic idea is that you match a given `QUERY` +with a set of `EXPECTED` results, complete with the full item path of each item. diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index d7d856fe3ad0..a7e1c0ce732e 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -299,6 +299,7 @@ #![feature(rand)] #![feature(raw)] #![feature(rustc_attrs)] +#![feature(stdsimd)] #![feature(sip_hash_13)] #![feature(slice_bytes)] #![feature(slice_concat_ext)] @@ -501,6 +502,35 @@ mod memchr; // compiler pub mod rt; +// Pull in the the `stdsimd` crate directly into libstd. This is the same as +// libcore's arch/simd modules where the source of truth here is in a different +// repository, but we pull things in here manually to get it into libstd. +// +// Note that the #[cfg] here is intended to do two things. First it allows us to +// change the rustc implementation of intrinsics in stage0 by not compiling simd +// intrinsics in stage0. Next it doesn't compile anything in test mode as +// stdsimd has tons of its own tests which we don't want to run. +#[path = "../stdsimd/stdsimd/mod.rs"] +#[allow(missing_debug_implementations, missing_docs, dead_code)] +#[unstable(feature = "stdsimd", issue = "48556")] +#[cfg(all(not(stage0), not(test)))] +mod stdsimd; + +// A "fake" module needed by the `stdsimd` module to compile, not actually +// exported though. +#[cfg(not(stage0))] +mod coresimd { + pub use core::arch; + pub use core::simd; +} + +#[unstable(feature = "stdsimd", issue = "48556")] +#[cfg(all(not(stage0), not(test)))] +pub use stdsimd::simd; +#[unstable(feature = "stdsimd", issue = "48556")] +#[cfg(all(not(stage0), not(test)))] +pub use stdsimd::arch; + // Include a number of private modules that exist solely to provide // the rustdoc documentation for primitive types. Using `include!` // because rustdoc only looks for these modules at the crate level. diff --git a/src/libstd_unicode/char.rs b/src/libstd_unicode/char.rs index 844ff7a3c125..5dd9c6277509 100644 --- a/src/libstd_unicode/char.rs +++ b/src/libstd_unicode/char.rs @@ -59,7 +59,7 @@ pub use version::UnicodeVersion; /// [`to_lowercase`]: ../../std/primitive.char.html#method.to_lowercase /// [`char`]: ../../std/primitive.char.html #[stable(feature = "rust1", since = "1.0.0")] -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ToLowercase(CaseMappingIter); #[stable(feature = "rust1", since = "1.0.0")] @@ -81,7 +81,7 @@ impl FusedIterator for ToLowercase {} /// [`to_uppercase`]: ../../std/primitive.char.html#method.to_uppercase /// [`char`]: ../../std/primitive.char.html #[stable(feature = "rust1", since = "1.0.0")] -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ToUppercase(CaseMappingIter); #[stable(feature = "rust1", since = "1.0.0")] @@ -95,7 +95,7 @@ impl Iterator for ToUppercase { #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for ToUppercase {} -#[derive(Debug)] +#[derive(Debug, Clone)] enum CaseMappingIter { Three(char, char, char), Two(char, char), diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 70ea015de4e3..058df1d51690 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -414,9 +414,6 @@ declare_features! ( // Allow trait methods with arbitrary self types (active, arbitrary_self_types, "1.23.0", Some(44874)), - // #![wasm_import_memory] attribute - (active, wasm_import_memory, "1.22.0", None), - // `crate` in paths (active, crate_in_paths, "1.23.0", Some(45477)), @@ -985,11 +982,6 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG never be stable", cfg_fn!(rustc_attrs))), - ("wasm_import_memory", Whitelisted, Gated(Stability::Unstable, - "wasm_import_memory", - "wasm_import_memory attribute is currently unstable", - cfg_fn!(wasm_import_memory))), - ("rustc_args_required_const", Whitelisted, Gated(Stability::Unstable, "rustc_attrs", "never will be stable", diff --git a/src/stdsimd b/src/stdsimd new file mode 160000 index 000000000000..678cbd325c84 --- /dev/null +++ b/src/stdsimd @@ -0,0 +1 @@ +Subproject commit 678cbd325c84070c9dbe4303969fbd2734c0b4ee diff --git a/src/test/compile-fail/integral-indexing.rs b/src/test/compile-fail/integral-indexing.rs index 659b08b55a00..4b01afb8131b 100644 --- a/src/test/compile-fail/integral-indexing.rs +++ b/src/test/compile-fail/integral-indexing.rs @@ -13,10 +13,10 @@ pub fn main() { let s: String = "abcdef".to_string(); v[3_usize]; v[3]; - v[3u8]; //~ERROR : std::ops::Index` is not satisfied - v[3i8]; //~ERROR : std::ops::Index` is not satisfied - v[3u32]; //~ERROR : std::ops::Index` is not satisfied - v[3i32]; //~ERROR : std::ops::Index` is not satisfied + v[3u8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied + v[3i8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied + v[3u32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied + v[3i32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied s.as_bytes()[3_usize]; s.as_bytes()[3]; s.as_bytes()[3u8]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied diff --git a/src/test/run-pass/issue-15487.rs b/src/test/run-pass/issue-15487.rs index cc5db0af88be..3616ab9e6c73 100644 --- a/src/test/run-pass/issue-15487.rs +++ b/src/test/run-pass/issue-15487.rs @@ -9,6 +9,7 @@ // except according to those terms. // ignore-windows +// ignore-wasm32-bare no libs to link #![feature(link_args)] diff --git a/src/test/ui/feature-gate-wasm_import_memory.rs b/src/test/ui/feature-gate-wasm_import_memory.rs deleted file mode 100644 index a010ebb3551d..000000000000 --- a/src/test/ui/feature-gate-wasm_import_memory.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![wasm_import_memory] //~ ERROR: currently unstable - -fn main() {} - diff --git a/src/test/ui/feature-gate-wasm_import_memory.stderr b/src/test/ui/feature-gate-wasm_import_memory.stderr deleted file mode 100644 index 0ec502724672..000000000000 --- a/src/test/ui/feature-gate-wasm_import_memory.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: wasm_import_memory attribute is currently unstable - --> $DIR/feature-gate-wasm_import_memory.rs:11:1 - | -LL | #![wasm_import_memory] //~ ERROR: currently unstable - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(wasm_import_memory)] to the crate attributes to enable - -error: aborting due to previous error - -If you want more information on this error, try using "rustc --explain E0658" diff --git a/src/test/ui/index-help.stderr b/src/test/ui/index-help.stderr index f4dde95b1046..ae3cd529ac42 100644 --- a/src/test/ui/index-help.stderr +++ b/src/test/ui/index-help.stderr @@ -1,10 +1,11 @@ -error[E0277]: the trait bound `std::vec::Vec<{integer}>: std::ops::Index` is not satisfied +error[E0277]: the trait bound `i32: std::slice::SliceIndex<[{integer}]>` is not satisfied --> $DIR/index-help.rs:13:5 | LL | x[0i32]; //~ ERROR E0277 - | ^^^^^^^ vector indices are of type `usize` or ranges of `usize` + | ^^^^^^^ slice indices are of type `usize` or ranges of `usize` | - = help: the trait `std::ops::Index` is not implemented for `std::vec::Vec<{integer}>` + = help: the trait `std::slice::SliceIndex<[{integer}]>` is not implemented for `i32` + = note: required because of the requirements on the impl of `std::ops::Index` for `std::vec::Vec<{integer}>` error: aborting due to previous error diff --git a/src/tools/lld b/src/tools/lld new file mode 160000 index 000000000000..b87873eaceb7 --- /dev/null +++ b/src/tools/lld @@ -0,0 +1 @@ +Subproject commit b87873eaceb75cf9342d5273f01ba2c020f61ca8 diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 4d89008d5ca5..5134c8699126 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -50,7 +50,6 @@ pub mod unstable_book; fn filter_dirs(path: &Path) -> bool { let skip = [ - "src/binaryen", "src/dlmalloc", "src/jemalloc", "src/llvm", @@ -68,9 +67,11 @@ fn filter_dirs(path: &Path) -> bool { "src/tools/rust-installer", "src/tools/rustfmt", "src/tools/miri", + "src/tools/lld", "src/librustc/mir/interpret", "src/librustc_mir/interpret", "src/target", + "src/stdsimd", ]; skip.iter().any(|p| path.ends_with(p)) }