diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index c56114f14caa9..99421a65a7e1d 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -838,12 +838,12 @@ pub fn run_cargo( let mut deps = Vec::new(); let mut toplevel = Vec::new(); let ok = stream_cargo(builder, cargo, tail_args, &mut |msg| { - let (filenames, crate_types) = match msg { + let (filenames, crate_types, kind, name) = match msg { CargoMessage::CompilerArtifact { filenames, - target: CargoTarget { crate_types }, + target: CargoTarget { crate_types, kind, name }, .. - } => (filenames, crate_types), + } => (filenames, crate_types, kind, name), _ => return, }; for filename in filenames { @@ -859,12 +859,24 @@ pub fn run_cargo( let filename = Path::new(&*filename); - // If this was an output file in the "host dir" we don't actually - // worry about it, it's not relevant for us + // If this was an output file in the "host dir", we want + // to ignore it if it's a build script. if filename.starts_with(&host_root_dir) { - // Unless it's a proc macro used in the compiler if crate_types.iter().any(|t| t == "proc-macro") { - deps.push((filename.to_path_buf(), true)); + deps.push((filename.to_path_buf(), /* host_dep */ true)); + } + + let is_build_script = kind == &["custom_build"] + && crate_types == &["bin"] + && name == "build-script-build"; + // We don't care about build scripts, but we *do* care about proc-macro + // dependencies - the compiler needs their metadata when loading proc-macro + // crates. Anything that's not a build script should be a proc-macro dependency. + // + // FIXME: Have Cargo explicitly indicate build-script vs proc-macro dependencies, + // instead of relying on this check. + if !is_build_script { + deps.push((filename.to_path_buf(), /* host_dep */ true)); } continue; } @@ -933,8 +945,8 @@ pub fn run_cargo( deps.extend(additional_target_deps.into_iter().map(|d| (d, false))); deps.sort(); let mut new_contents = Vec::new(); - for (dep, proc_macro) in deps.iter() { - new_contents.extend(if *proc_macro { b"h" } else { b"t" }); + for (dep, host_dep) in deps.iter() { + new_contents.extend(if *host_dep { b"h" } else { b"t" }); new_contents.extend(dep.to_str().unwrap().as_bytes()); new_contents.extend(b"\0"); } @@ -1003,6 +1015,8 @@ pub fn stream_cargo( #[derive(Deserialize)] pub struct CargoTarget<'a> { crate_types: Vec>, + kind: Vec>, + name: Cow<'a, str>, } #[derive(Deserialize)] diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index a9e7a9f35dc36..1fd9762a4eae1 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -558,9 +558,10 @@ impl<'a> CrateLoader<'a> { dep_kind: DepKind, ) -> CrateNumMap { debug!("resolving deps of external crate"); - if crate_root.is_proc_macro_crate() { - return CrateNumMap::new(); - } + + // Note that we need to resolve deps for proc-macro crates (just like normal crates) + // since we may need to decode `Span`s that reference the `CrateNums` + // of transitive dependencies // The map from crate numbers in the crate we're resolving to local crate numbers. // We map 0 and all other holes in the map to our parent crate. The "additional" diff --git a/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py index 927edff4c22a5..d9b883856c231 100644 --- a/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py +++ b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py @@ -11,6 +11,10 @@ 'rsbegin.o', 'rsend.o', 'dllcrt2.o', 'crt2.o', 'clang_rt'] +# This is a whitelist of crates which give an "compiled by an incompatible version of rustc" +# error, due to being copied into the sysroot as proc-macro deps. See #69976 +INCOMPATIBLE_VER_CRATES = ['autocfg', 'cc'] + def convert_to_string(s): if s.__class__.__name__ == 'bytes': return s.decode('utf-8') @@ -34,6 +38,11 @@ def check_lib(lib): stdout, stderr = exec_command([os.environ['RUSTC'], '-', '--crate-type', 'rlib', '--extern', '{}={}'.format(lib['name'], lib['path'])], to_input=('extern crate {};'.format(lib['name'])).encode('utf-8')) + + if 'compiled by an incompatible version of rustc' in '{}{}'.format(stdout, stderr): + if lib['name'] in INCOMPATIBLE_VER_CRATES: + return True + if not 'use of unstable library feature' in '{}{}'.format(stdout, stderr): print('crate {} "{}" is not unstable'.format(lib['name'], lib['path'])) print('{}{}'.format(stdout, stderr))