diff --git a/src/cargo/core/compiler/standard_lib.rs b/src/cargo/core/compiler/standard_lib.rs index fb58363f0..a6fced9cc 100644 --- a/src/cargo/core/compiler/standard_lib.rs +++ b/src/cargo/core/compiler/standard_lib.rs @@ -7,6 +7,7 @@ use crate::core::{Dependency, PackageId, PackageSet, Resolve, SourceId, Workspac use crate::ops::{self, Packages}; use crate::util::errors::CargoResult; use std::collections::{HashMap, HashSet}; +use std::env; use std::path::PathBuf; /// Parse the `-Zbuild-std` flag. @@ -148,6 +149,10 @@ pub fn generate_std_roots<'a>( } fn detect_sysroot_src_path(ws: &Workspace<'_>) -> CargoResult { + if let Some(s) = env::var_os("__CARGO_TESTS_ONLY_SRC_ROOT") { + return Ok(s.into()); + } + // NOTE: This is temporary until we figure out how to acquire the source. // If we decide to keep the sysroot probe, then BuildConfig will need to // be restructured so that the TargetInfo is created earlier and passed diff --git a/tests/testsuite/mock-std/Cargo.toml b/tests/testsuite/mock-std/Cargo.toml new file mode 100644 index 000000000..a2fdae3b7 --- /dev/null +++ b/tests/testsuite/mock-std/Cargo.toml @@ -0,0 +1,9 @@ +[workspace] +members = [ + "src/libtest", +] + +[patch.crates-io] +rustc-std-workspace-std = { path = 'src/tools/rustc-std-workspace-std' } +rustc-std-workspace-core = { path = 'src/tools/rustc-std-workspace-core' } +rustc-std-workspace-alloc = { path = 'src/tools/rustc-std-workspace-alloc' } diff --git a/tests/testsuite/mock-std/src/liballoc/Cargo.toml b/tests/testsuite/mock-std/src/liballoc/Cargo.toml new file mode 100644 index 000000000..128600df5 --- /dev/null +++ b/tests/testsuite/mock-std/src/liballoc/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "alloc" +version = "0.1.0" +authors = ["Alex Crichton "] +edition = "2018" + +[lib] +path = "lib.rs" + +[dependencies] +core = { path = "../libcore" } diff --git a/tests/testsuite/mock-std/src/liballoc/lib.rs b/tests/testsuite/mock-std/src/liballoc/lib.rs new file mode 100644 index 000000000..e29525b6a --- /dev/null +++ b/tests/testsuite/mock-std/src/liballoc/lib.rs @@ -0,0 +1 @@ +pub fn custom_api() {} diff --git a/tests/testsuite/mock-std/src/libcompiler_builtins/Cargo.toml b/tests/testsuite/mock-std/src/libcompiler_builtins/Cargo.toml new file mode 100644 index 000000000..27141f232 --- /dev/null +++ b/tests/testsuite/mock-std/src/libcompiler_builtins/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "compiler_builtins" +version = "0.1.0" +authors = ["Alex Crichton "] +edition = "2018" + +[lib] +path = "lib.rs" + +[dependencies] +core = { path = "../libcore" } diff --git a/tests/testsuite/mock-std/src/libcompiler_builtins/lib.rs b/tests/testsuite/mock-std/src/libcompiler_builtins/lib.rs new file mode 100644 index 000000000..65e2cc340 --- /dev/null +++ b/tests/testsuite/mock-std/src/libcompiler_builtins/lib.rs @@ -0,0 +1 @@ +// intentionally blank diff --git a/tests/testsuite/mock-std/src/libcore/Cargo.toml b/tests/testsuite/mock-std/src/libcore/Cargo.toml new file mode 100644 index 000000000..b448bdb08 --- /dev/null +++ b/tests/testsuite/mock-std/src/libcore/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "core" +version = "0.1.0" +authors = ["Alex Crichton "] +edition = "2018" + +[lib] +path = "lib.rs" diff --git a/tests/testsuite/mock-std/src/libcore/build.rs b/tests/testsuite/mock-std/src/libcore/build.rs new file mode 100644 index 000000000..53d4e145d --- /dev/null +++ b/tests/testsuite/mock-std/src/libcore/build.rs @@ -0,0 +1,23 @@ +//! This build script is basically the whole hack that makes this entire "mock +//! std" feature work. Here we print out `rustc-link-search` pointing to the +//! sysroot of the actual compiler itself, and that way we can indeed implicitly +//! pull in those crates, but only via `extern crate`. That means that we can +//! build tiny shim core/std/etc crates while they actually load all the various +//! language/library details from the actual crates, meaning that instead of +//! literally compiling libstd we compile just our own tiny shims. + +use std::process::Command; +use std::env; + +fn main() { + let output = Command::new("rustc") + .arg("--print") + .arg("sysroot") + .output() + .unwrap(); + assert!(output.status.success()); + let stdout = String::from_utf8(output.stdout).unwrap(); + let stdout = stdout.trim(); + let host = env::var("HOST").unwrap(); + println!("cargo:rustc-link-search={}/lib/rustlib/{}/lib", stdout, host); +} diff --git a/tests/testsuite/mock-std/src/libcore/lib.rs b/tests/testsuite/mock-std/src/libcore/lib.rs new file mode 100644 index 000000000..73e79b9a9 --- /dev/null +++ b/tests/testsuite/mock-std/src/libcore/lib.rs @@ -0,0 +1,4 @@ +#![no_std] +pub use core::*; + +pub fn custom_api() {} diff --git a/tests/testsuite/mock-std/src/libpanic_unwind/Cargo.toml b/tests/testsuite/mock-std/src/libpanic_unwind/Cargo.toml new file mode 100644 index 000000000..af06d7736 --- /dev/null +++ b/tests/testsuite/mock-std/src/libpanic_unwind/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "panic_unwind" +version = "0.1.0" +authors = ["Alex Crichton "] +edition = "2018" + +[lib] +path = "lib.rs" + +[dependencies] +core = { path = "../libcore" } diff --git a/tests/testsuite/mock-std/src/libpanic_unwind/lib.rs b/tests/testsuite/mock-std/src/libpanic_unwind/lib.rs new file mode 100644 index 000000000..6af65d875 --- /dev/null +++ b/tests/testsuite/mock-std/src/libpanic_unwind/lib.rs @@ -0,0 +1,5 @@ +#![feature(panic_unwind, panic_runtime)] +#![panic_runtime] +#![no_std] + +extern crate panic_unwind; diff --git a/tests/testsuite/mock-std/src/libproc_macro/Cargo.toml b/tests/testsuite/mock-std/src/libproc_macro/Cargo.toml new file mode 100644 index 000000000..bc93bfcc7 --- /dev/null +++ b/tests/testsuite/mock-std/src/libproc_macro/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "proc_macro" +version = "0.1.0" +authors = ["Alex Crichton "] +edition = "2018" + +[lib] +path = "lib.rs" + +[dependencies] +std = { path = "../libstd" } diff --git a/tests/testsuite/mock-std/src/libproc_macro/lib.rs b/tests/testsuite/mock-std/src/libproc_macro/lib.rs new file mode 100644 index 000000000..73825ac07 --- /dev/null +++ b/tests/testsuite/mock-std/src/libproc_macro/lib.rs @@ -0,0 +1,3 @@ +extern crate proc_macro; +pub use proc_macro::*; +pub fn custom_api() {} diff --git a/tests/testsuite/mock-std/src/libstd/Cargo.toml b/tests/testsuite/mock-std/src/libstd/Cargo.toml new file mode 100644 index 000000000..9338f0368 --- /dev/null +++ b/tests/testsuite/mock-std/src/libstd/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "std" +version = "0.1.0" +authors = ["Alex Crichton "] +edition = "2018" + +[lib] +path = "lib.rs" + +[dependencies] +core = { path = "../libcore" } +compiler_builtins = { path = "../libcompiler_builtins" } +panic_unwind = { path = "../libpanic_unwind" } +registry-dep-using-core = { version = "1.0", features = ['mockbuild'] } +registry-dep-using-alloc = { version = "1.0", features = ['mockbuild'] } diff --git a/tests/testsuite/mock-std/src/libstd/lib.rs b/tests/testsuite/mock-std/src/libstd/lib.rs new file mode 100644 index 000000000..e7e64f1f6 --- /dev/null +++ b/tests/testsuite/mock-std/src/libstd/lib.rs @@ -0,0 +1,6 @@ +pub use std::*; + +pub fn custom_api() { + registry_dep_using_core::custom_api(); + registry_dep_using_alloc::custom_api(); +} diff --git a/tests/testsuite/mock-std/src/libtest/Cargo.toml b/tests/testsuite/mock-std/src/libtest/Cargo.toml new file mode 100644 index 000000000..a81a2dd6a --- /dev/null +++ b/tests/testsuite/mock-std/src/libtest/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "test" +version = "0.1.0" +authors = ["Alex Crichton "] +edition = "2018" + +[lib] +path = "lib.rs" + +[dependencies] +proc_macro = { path = "../libproc_macro" } +registry-dep-using-std = { version = "1.0", features = ['mockbuild'] } +std = { path = "../libstd" } + +[features] +panic-unwind = [] +backtrace = [] diff --git a/tests/testsuite/mock-std/src/libtest/lib.rs b/tests/testsuite/mock-std/src/libtest/lib.rs new file mode 100644 index 000000000..34c0e532b --- /dev/null +++ b/tests/testsuite/mock-std/src/libtest/lib.rs @@ -0,0 +1,9 @@ +#![feature(test)] + +extern crate test; + +pub use test::*; + +pub fn custom_api() { + registry_dep_using_std::custom_api(); +} diff --git a/tests/testsuite/mock-std/src/tools/rustc-std-workspace-alloc/Cargo.toml b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-alloc/Cargo.toml new file mode 100644 index 000000000..54d9ff4fd --- /dev/null +++ b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-alloc/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "rustc-std-workspace-alloc" +version = "1.9.0" +authors = ["Alex Crichton "] +edition = "2018" + +[lib] +name = "alloc" +path = "lib.rs" + +[dependencies] +alloc = { path = "../../liballoc" } diff --git a/tests/testsuite/mock-std/src/tools/rustc-std-workspace-alloc/lib.rs b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-alloc/lib.rs new file mode 100644 index 000000000..2bbfa1a49 --- /dev/null +++ b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-alloc/lib.rs @@ -0,0 +1,3 @@ +#![no_std] + +pub use alloc::*; diff --git a/tests/testsuite/mock-std/src/tools/rustc-std-workspace-core/Cargo.toml b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-core/Cargo.toml new file mode 100644 index 000000000..d62698f62 --- /dev/null +++ b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-core/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "rustc-std-workspace-core" +version = "1.9.0" +authors = ["Alex Crichton "] +edition = "2018" + +[lib] +name = "core" +path = "lib.rs" + +[dependencies] +core = { path = "../../libcore" } diff --git a/tests/testsuite/mock-std/src/tools/rustc-std-workspace-core/lib.rs b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-core/lib.rs new file mode 100644 index 000000000..816251790 --- /dev/null +++ b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-core/lib.rs @@ -0,0 +1,3 @@ +#![no_std] + +pub use core::*; diff --git a/tests/testsuite/mock-std/src/tools/rustc-std-workspace-std/Cargo.toml b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-std/Cargo.toml new file mode 100644 index 000000000..0a4bd3a7e --- /dev/null +++ b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-std/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "rustc-std-workspace-std" +version = "1.9.0" +authors = ["Alex Crichton "] +edition = "2018" + +[lib] +name = "std" +path = "lib.rs" + +[dependencies] +std = { path = "../../libstd" } diff --git a/tests/testsuite/mock-std/src/tools/rustc-std-workspace-std/lib.rs b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-std/lib.rs new file mode 100644 index 000000000..f40d09caf --- /dev/null +++ b/tests/testsuite/mock-std/src/tools/rustc-std-workspace-std/lib.rs @@ -0,0 +1 @@ +pub use std::*; diff --git a/tests/testsuite/standard_lib.rs b/tests/testsuite/standard_lib.rs index 0ca7856d9..ca2f75374 100644 --- a/tests/testsuite/standard_lib.rs +++ b/tests/testsuite/standard_lib.rs @@ -1,283 +1,396 @@ -use crate::support::{is_nightly, paths, project, rustc_host, Execs, Project}; +use crate::support::registry::{Dependency, Package}; +use crate::support::{is_nightly, paths, project, rustc_host, Execs}; -fn cargo_build_std(project: &Project, cmd: &str, crates: &str) -> Execs { - let unstable = if crates.is_empty() { - "-Zbuild-std".to_string() - } else { - format!("-Zbuild-std={}", crates) - }; - let target = paths::root().join("target"); - let mut execs = project.cargo(cmd); - if !cmd.contains("--target") { - execs.arg("--target").arg(rustc_host()); - } - execs - .arg(unstable) - .arg("-Zno-index-update") - .env_remove("CARGO_HOME") - .env_remove("HOME") - .env("CARGO_TARGET_DIR", target.as_os_str()) - .masquerade_as_nightly_cargo(); - execs -} - -#[cargo_test] -fn std_lib() { +fn setup() -> bool { if !is_nightly() { // -Zbuild-std is nightly // -Zno-index-update is nightly // We don't want these tests to run on rust-lang/rust. - return; + return false; } - simple_lib_std(); - simple_bin_std(); - lib_nostd(); - check_core(); - cross_custom(); - hashbrown(); - libc(); - test(); - custom_test_framework(); - target_proc_macro(); - bench(); - doc(); - check_std(); - doctest(); + + // Our mock sysroot requires a few packages from crates.io, so make sure + // they're "published" to crates.io. Also edit their code a bit to make sure + // that they have access to our custom crates with custom apis. + Package::new("registry-dep-using-core", "1.0.0") + .file( + "src/lib.rs", + " + #![no_std] + + #[cfg(feature = \"mockbuild\")] + pub fn custom_api() { + core::custom_api(); + } + + #[cfg(not(feature = \"mockbuild\"))] + pub fn non_sysroot_api() { + core::custom_api(); + } + ", + ) + .add_dep(Dependency::new("rustc-std-workspace-core", "*").optional(true)) + .feature("mockbuild", &["rustc-std-workspace-core"]) + .publish(); + Package::new("registry-dep-using-alloc", "1.0.0") + .file( + "src/lib.rs", + " + #![no_std] + + extern crate alloc; + + #[cfg(feature = \"mockbuild\")] + pub fn custom_api() { + core::custom_api(); + alloc::custom_api(); + } + + #[cfg(not(feature = \"mockbuild\"))] + pub fn non_sysroot_api() { + core::custom_api(); + alloc::custom_api(); + } + ", + ) + .add_dep(Dependency::new("rustc-std-workspace-core", "*").optional(true)) + .add_dep(Dependency::new("rustc-std-workspace-alloc", "*").optional(true)) + .feature( + "mockbuild", + &["rustc-std-workspace-core", "rustc-std-workspace-alloc"], + ) + .publish(); + Package::new("registry-dep-using-std", "1.0.0") + .file( + "src/lib.rs", + " + #[cfg(feature = \"mockbuild\")] + pub fn custom_api() { + std::custom_api(); + } + + #[cfg(not(feature = \"mockbuild\"))] + pub fn non_sysroot_api() { + std::custom_api(); + } + ", + ) + .add_dep(Dependency::new("rustc-std-workspace-std", "*").optional(true)) + .feature("mockbuild", &["rustc-std-workspace-std"]) + .publish(); + return true; } +fn enable_build_std(e: &mut Execs, arg: Option<&str>) { + // First up, force Cargo to use our "mock sysroot" which mimics what + // libstd looks like upstream. + let root = paths::root(); + let root = root + .parent() // chop off test name + .unwrap() + .parent() // chop off `citN` + .unwrap() + .parent() // chop off `target` + .unwrap() + .join("tests/testsuite/mock-std"); + e.env("__CARGO_TESTS_ONLY_SRC_ROOT", &root); + + // Next, make sure it doesn't have implicit access to the host's sysroot + e.env("RUSTFLAGS", "--sysroot=/path/to/nowhere"); + + // And finally actually enable `build-std` for now + let arg = match arg { + Some(s) => format!("-Zbuild-std={}", s), + None => "-Zbuild-std".to_string(), + }; + e.arg(arg); + e.masquerade_as_nightly_cargo(); +} + +// Helper methods used in the tests below +trait BuildStd: Sized { + fn build_std(&mut self) -> &mut Self; + fn build_std_arg(&mut self, arg: &str) -> &mut Self; + fn target_host(&mut self) -> &mut Self; +} + +impl BuildStd for Execs { + fn build_std(&mut self) -> &mut Self { + enable_build_std(self, None); + self + } + + fn build_std_arg(&mut self, arg: &str) -> &mut Self { + enable_build_std(self, Some(arg)); + self + } + + fn target_host(&mut self) -> &mut Self { + self.arg("--target").arg(rustc_host()); + self + } +} + +#[cargo_test] +fn basic() { + if !setup() { + return; + } + + let p = project() + .file( + "src/main.rs", + " + fn main() { + std::custom_api(); + foo::f(); + } + + #[test] + fn smoke_bin_unit() { + std::custom_api(); + foo::f(); + } + ", + ) + .file( + "src/lib.rs", + " + extern crate alloc; + extern crate proc_macro; + + /// ``` + /// foo::f(); + /// ``` + pub fn f() { + core::custom_api(); + std::custom_api(); + alloc::custom_api(); + proc_macro::custom_api(); + } + + #[test] + fn smoke_lib_unit() { + std::custom_api(); + f(); + } + ", + ) + .file( + "tests/smoke.rs", + " + #[test] + fn smoke_integration() { + std::custom_api(); + foo::f(); + } + ", + ) + .build(); + + p.cargo("check").build_std().target_host().run(); + p.cargo("build").build_std().target_host().run(); + p.cargo("run").build_std().target_host().run(); + p.cargo("test").build_std().target_host().run(); +} + +#[cargo_test] fn simple_lib_std() { + if !setup() { + return; + } let p = project().file("src/lib.rs", "").build(); - cargo_build_std(&p, "build -v", "") + p.cargo("build -v") + .build_std() + .target_host() .with_stderr_contains("[RUNNING] `rustc [..]--crate-name std [..]") .run(); // Check freshness. p.change_file("src/lib.rs", " "); - cargo_build_std(&p, "build -v", "std") + p.cargo("build -v") + .build_std() + .target_host() .with_stderr_contains("[FRESH] std[..]") .run(); } +#[cargo_test] fn simple_bin_std() { + if !setup() { + return; + } let p = project().file("src/main.rs", "fn main() {}").build(); - cargo_build_std(&p, "run -v", "std").run(); + p.cargo("run -v").build_std().target_host().run(); } +#[cargo_test] fn lib_nostd() { + if !setup() { + return; + } let p = project() .file( "src/lib.rs", r#" - #![no_std] - pub fn foo() { - assert_eq!(core::u8::MIN, 0); - } + #![no_std] + pub fn foo() { + assert_eq!(core::u8::MIN, 0); + } "#, ) .build(); - cargo_build_std(&p, "build -v --lib", "core") + p.cargo("build -v --lib") + .build_std_arg("core") + .target_host() .with_stderr_does_not_contain("[..]libstd[..]") .run(); } +#[cargo_test] fn check_core() { + if !setup() { + return; + } let p = project() .file("src/lib.rs", "#![no_std] fn unused_fn() {}") .build(); - cargo_build_std(&p, "check -v", "core") + p.cargo("check -v") + .build_std_arg("core") + .target_host() .with_stderr_contains("[WARNING] [..]unused_fn[..]`") .run(); } -fn cross_custom() { - let p = project() - .file("src/lib.rs", "#![no_std] pub fn f() {}") - .file( - "custom-target.json", - r#" - { - "llvm-target": "x86_64-unknown-none-gnu", - "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", - "arch": "x86_64", - "target-endian": "little", - "target-pointer-width": "64", - "target-c-int-width": "32", - "os": "none", - "linker-flavor": "ld.lld" - } - "#, - ) - .build(); +#[cargo_test] +fn depend_same_as_std() { + if !setup() { + return; + } - cargo_build_std(&p, "build --target custom-target.json -v", "core").run(); -} - -fn hashbrown() { let p = project() .file( "src/lib.rs", r#" - pub fn f() -> hashbrown::HashMap { - hashbrown::HashMap::new() - } - "#, - ) - .file( - "Cargo.toml", - r#" - [package] - name = "foo" - version = "0.1.0" - edition = "2018" - - [dependencies] - hashbrown = "=0.4.0" - "#, - ) - .build(); - - cargo_build_std(&p, "build -v", "std").run(); -} - -fn libc() { - let p = project() - .file( - "src/lib.rs", - r#" - pub fn f() -> ! { - unsafe { libc::exit(123); } - } - "#, - ) - .file( - "Cargo.toml", - r#" - [package] - name = "foo" - version = "0.1.0" - edition = "2018" - - [dependencies] - libc = "=0.2.54" - "#, - ) - .build(); - - cargo_build_std(&p, "build -v", "std").run(); -} - -fn test() { - let p = project() - .file( - "src/lib.rs", - r#" - #[cfg(test)] - mod tests { - #[test] - fn it_works() { - assert_eq!(2 + 2, 4); + pub fn f() { + registry_dep_using_core::non_sysroot_api(); + registry_dep_using_alloc::non_sysroot_api(); + registry_dep_using_std::non_sysroot_api(); } - } + "#, + ) + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2018" + + [dependencies] + registry-dep-using-core = "1.0" + registry-dep-using-alloc = "1.0" + registry-dep-using-std = "1.0" "#, ) .build(); - cargo_build_std(&p, "test -v", "std") + p.cargo("build -v").build_std().target_host().run(); +} + +#[cargo_test] +fn test() { + if !setup() { + return; + } + let p = project() + .file( + "src/lib.rs", + r#" + #[cfg(test)] + mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } + } + "#, + ) + .build(); + + p.cargo("test -v") + .build_std() + .target_host() .with_stdout_contains("test tests::it_works ... ok") .run(); } -fn custom_test_framework() { - let p = project() - .file( - "src/lib.rs", - r#" - #![no_std] - #![cfg_attr(test, no_main)] - #![feature(custom_test_frameworks)] - #![test_runner(crate::test_runner)] - - pub fn test_runner(_tests: &[&dyn Fn()]) {} - - #[panic_handler] - fn panic(_info: &core::panic::PanicInfo) -> ! { - loop {} - } - "#, - ) - .file( - "target.json", - r#" - { - "llvm-target": "x86_64-unknown-none-gnu", - "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", - "arch": "x86_64", - "target-endian": "little", - "target-pointer-width": "64", - "target-c-int-width": "32", - "os": "none", - "linker-flavor": "ld.lld", - "linker": "rust-lld", - "executables": true, - "panic-strategy": "abort" - } - "#, - ) - .build(); - - cargo_build_std(&p, "test --target target.json --no-run -v", "core").run(); -} - +#[cargo_test] fn target_proc_macro() { + if !setup() { + return; + } let p = project() .file( "src/lib.rs", r#" - extern crate proc_macro; - pub fn f() { - let _ts = proc_macro::TokenStream::new(); - } + extern crate proc_macro; + pub fn f() { + let _ts = proc_macro::TokenStream::new(); + } "#, ) .build(); - cargo_build_std(&p, "build -v", "std,proc_macro").run(); + p.cargo("build -v").build_std().target_host().run(); } +#[cargo_test] fn bench() { + if !setup() { + return; + } let p = project() .file( "src/lib.rs", r#" - #![feature(test)] - extern crate test; + #![feature(test)] + extern crate test; - #[bench] - fn b1(b: &mut test::Bencher) { - b.iter(|| ()) - } + #[bench] + fn b1(b: &mut test::Bencher) { + b.iter(|| ()) + } "#, ) .build(); - cargo_build_std(&p, "bench -v", "std").run(); + p.cargo("bench -v").build_std().target_host().run(); } +#[cargo_test] fn doc() { + if !setup() { + return; + } let p = project() .file( "src/lib.rs", r#" - /// Doc - pub fn f() -> Result<(), ()> {Ok(())} + /// Doc + pub fn f() -> Result<(), ()> {Ok(())} "#, ) .build(); - cargo_build_std(&p, "doc -v", "std").run(); + p.cargo("doc -v").build_std().target_host().run(); } +#[cargo_test] fn check_std() { + if !setup() { + return; + } let p = project() .file( "src/lib.rs", @@ -292,31 +405,112 @@ fn check_std() { .file( "tests/t1.rs", r#" - #[test] - fn t1() { - assert_eq!(1, 2); - } + #[test] + fn t1() { + assert_eq!(1, 2); + } "#, ) .build(); - cargo_build_std(&p, "check -v --all-targets", "std").run(); - cargo_build_std(&p, "check -v --all-targets --profile=test", "std").run(); + p.cargo("check -v --all-targets") + .build_std() + .target_host() + .run(); + p.cargo("check -v --all-targets --profile=test") + .build_std() + .target_host() + .run(); } +#[cargo_test] fn doctest() { + if !setup() { + return; + } let p = project() .file( "src/lib.rs", r#" - /// Doc - /// ``` - /// assert_eq!(1, 1); - /// ``` - pub fn f() {} + /// Doc + /// ``` + /// assert_eq!(1, 1); + /// ``` + pub fn f() {} "#, ) .build(); - cargo_build_std(&p, "test --doc -v", "std").run(); + p.cargo("test --doc -v").build_std().target_host().run(); } + +// FIXME: set up a dedicated builder to run a full integration test? +// #[cargo_test] +// fn cross_custom() { +// if !setup() { +// return; +// } +// let p = project() +// .file("src/lib.rs", "#![no_std] pub fn f() {}") +// .file( +// "custom-target.json", +// r#" +// { +// "llvm-target": "x86_64-unknown-none-gnu", +// "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", +// "arch": "x86_64", +// "target-endian": "little", +// "target-pointer-width": "64", +// "target-c-int-width": "32", +// "os": "none", +// "linker-flavor": "ld.lld" +// } +// "#, +// ) +// .build(); +// +// p.cargo("build --target custom-target.json -v") +// .build_std() +// .run(); +// } +// +// fn custom_test_framework() { +// let p = project() +// .file( +// "src/lib.rs", +// r#" +// #![no_std] +// #![cfg_attr(test, no_main)] +// #![feature(custom_test_frameworks)] +// #![test_runner(crate::test_runner)] +// +// pub fn test_runner(_tests: &[&dyn Fn()]) {} +// +// #[panic_handler] +// fn panic(_info: &core::panic::PanicInfo) -> ! { +// loop {} +// } +// "#, +// ) +// .file( +// "target.json", +// r#" +// { +// "llvm-target": "x86_64-unknown-none-gnu", +// "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", +// "arch": "x86_64", +// "target-endian": "little", +// "target-pointer-width": "64", +// "target-c-int-width": "32", +// "os": "none", +// "linker-flavor": "ld.lld", +// "linker": "rust-lld", +// "executables": true, +// "panic-strategy": "abort" +// } +// "#, +// ) +// .build(); +// +// cargo_build_std(&p, "test --target target.json --no-run -v", "core").run(); +// }