Skip to content

Commit 6fe6595

Browse files
committed
Properly set for_host for proc-macro tests.
1 parent 898ccde commit 6fe6595

File tree

3 files changed

+99
-1
lines changed

3 files changed

+99
-1
lines changed

src/cargo/core/compiler/unit_dependencies.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,13 @@ fn deps_of_roots(roots: &[Unit], mut state: &mut State<'_, '_>) -> CargoResult<(
161161
// without, once for `--test`). In particular, the lib included for
162162
// Doc tests and examples are `Build` mode here.
163163
let unit_for = if unit.mode.is_any_test() || state.global_mode.is_rustc_test() {
164-
UnitFor::new_test(state.config)
164+
if unit.target.proc_macro() {
165+
// Special-case for proc-macros, which are forced to for-host
166+
// since they need to link with the proc_macro crate.
167+
UnitFor::new_host_test(state.config)
168+
} else {
169+
UnitFor::new_test(state.config)
170+
}
165171
} else if unit.target.is_custom_build() {
166172
// This normally doesn't happen, except `clean` aggressively
167173
// generates all units.

src/cargo/core/profiles.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,16 @@ impl UnitFor {
967967
}
968968
}
969969

970+
/// This is a special case for unit tests of a proc-macro.
971+
///
972+
/// Proc-macro unit tests are forced to be run on the host.
973+
pub fn new_host_test(config: &Config) -> UnitFor {
974+
let mut unit_for = UnitFor::new_test(config);
975+
unit_for.host = true;
976+
unit_for.host_features = true;
977+
unit_for
978+
}
979+
970980
/// Returns a new copy based on `for_host` setting.
971981
///
972982
/// When `for_host` is true, this clears `panic_abort_ok` in a sticky

tests/testsuite/features2.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,3 +1864,85 @@ warning: feat: enabled
18641864
)
18651865
.run();
18661866
}
1867+
1868+
#[cargo_test]
1869+
fn test_proc_macro() {
1870+
// Running `cargo test` on a proc-macro, with a shared dependency that has
1871+
// different features.
1872+
//
1873+
// There was a bug where `shared` was built twice (once with feature "B"
1874+
// and once without), and both copies linked into the unit test. This
1875+
// would cause a type failure when used in an intermediate dependency
1876+
// (the-macro-support).
1877+
let p = project()
1878+
.file(
1879+
"Cargo.toml",
1880+
r#"
1881+
[package]
1882+
name = "runtime"
1883+
version = "0.1.0"
1884+
[dependencies]
1885+
the-macro = { path = "the-macro", features = ['a'] }
1886+
[build-dependencies]
1887+
shared = { path = "shared", features = ['b'] }
1888+
"#,
1889+
)
1890+
.file("src/lib.rs", "")
1891+
.file(
1892+
"the-macro/Cargo.toml",
1893+
r#"
1894+
[package]
1895+
name = "the-macro"
1896+
version = "0.1.0"
1897+
[lib]
1898+
proc-macro = true
1899+
test = false
1900+
[dependencies]
1901+
the-macro-support = { path = "../the-macro-support" }
1902+
shared = { path = "../shared" }
1903+
[dev-dependencies]
1904+
runtime = { path = ".." }
1905+
[features]
1906+
a = []
1907+
"#,
1908+
)
1909+
.file(
1910+
"the-macro/src/lib.rs",
1911+
"
1912+
fn _test() {
1913+
the_macro_support::foo(shared::Foo);
1914+
}
1915+
",
1916+
)
1917+
.file(
1918+
"the-macro-support/Cargo.toml",
1919+
r#"
1920+
[package]
1921+
name = "the-macro-support"
1922+
version = "0.1.0"
1923+
[dependencies]
1924+
shared = { path = "../shared" }
1925+
"#,
1926+
)
1927+
.file(
1928+
"the-macro-support/src/lib.rs",
1929+
"
1930+
pub fn foo(_: shared::Foo) {}
1931+
",
1932+
)
1933+
.file(
1934+
"shared/Cargo.toml",
1935+
r#"
1936+
[package]
1937+
name = "shared"
1938+
version = "0.1.0"
1939+
[features]
1940+
b = []
1941+
"#,
1942+
)
1943+
.file("shared/src/lib.rs", "pub struct Foo;")
1944+
.build();
1945+
p.cargo("test -Zfeatures=all --manifest-path the-macro/Cargo.toml")
1946+
.masquerade_as_nightly_cargo()
1947+
.run();
1948+
}

0 commit comments

Comments
 (0)