diff --git a/src/cargo/core/compiler/build_context/target_info.rs b/src/cargo/core/compiler/build_context/target_info.rs index 3c23d2d8b75..cfe01e72fba 100644 --- a/src/cargo/core/compiler/build_context/target_info.rs +++ b/src/cargo/core/compiler/build_context/target_info.rs @@ -39,6 +39,8 @@ pub struct TargetInfo { pub rustflags: Vec, /// Extra flags to pass to `rustdoc`, see `env_args`. pub rustdocflags: Vec, + // Remove this when it hits stable (1.41). + pub supports_pathless_extern: Option, } /// Kind of each file generated by a Unit, part of `FileType`. @@ -101,6 +103,13 @@ impl TargetInfo { .args(&rustflags) .env_remove("RUSTC_LOG"); + let mut pathless_test = process.clone(); + pathless_test.args(&["--extern", "proc_macro"]); + let supports_pathless_extern = match kind { + CompileKind::Host => Some(rustc.cached_output(&pathless_test).is_ok()), + _ => None, + }; + if let CompileKind::Target(target) = kind { process.arg("--target").arg(target.rustc_target()); } @@ -183,6 +192,7 @@ impl TargetInfo { "RUSTDOCFLAGS", )?, cfg, + supports_pathless_extern, }) } diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index e44356e98ac..2fe7504820e 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -1010,6 +1010,17 @@ pub fn extern_args<'a>( link_to(&dep, dep.extern_crate_name, dep.noprelude)?; } } + if unit.target.proc_macro() + && cx + .bcx + .info(CompileKind::Host) + .supports_pathless_extern + .unwrap() + { + // Automatically import `proc_macro`. + result.push(OsString::from("--extern")); + result.push(OsString::from("proc_macro")); + } Ok(result) } diff --git a/tests/testsuite/proc_macro.rs b/tests/testsuite/proc_macro.rs index 8c5326c365a..32abb29f5f3 100644 --- a/tests/testsuite/proc_macro.rs +++ b/tests/testsuite/proc_macro.rs @@ -440,3 +440,37 @@ Caused by: .with_status(101) .run(); } + +#[cargo_test] +fn proc_macro_extern_prelude() { + if !is_nightly() { + // remove once pathless `--extern` hits stable (1.41) + return; + } + // Check that proc_macro is in the extern prelude. + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2018" + [lib] + proc-macro = true + "#, + ) + .file( + "src/lib.rs", + r#" + use proc_macro::TokenStream; + #[proc_macro] + pub fn foo(input: TokenStream) -> TokenStream { + "".parse().unwrap() + } + "#, + ) + .build(); + p.cargo("test").run(); + p.cargo("doc").run(); +} diff --git a/tests/testsuite/rustc_info_cache.rs b/tests/testsuite/rustc_info_cache.rs index 52d0eccdec1..5375b0bc93e 100644 --- a/tests/testsuite/rustc_info_cache.rs +++ b/tests/testsuite/rustc_info_cache.rs @@ -6,6 +6,11 @@ use std::env; #[cargo_test] fn rustc_info_cache() { + if !cargo_test_support::is_nightly() { + // remove once pathless `--extern` hits stable (1.41) + return; + } + let p = project() .file("src/main.rs", r#"fn main() { println!("hello"); }"#) .build();