From f4d215ea91e233d5208d687548222183d4d279d8 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sat, 28 Dec 2024 23:28:41 +0000 Subject: [PATCH 1/2] Add tidy check for list of proc-macro crate transitive dependencies --- Cargo.lock | 28 ++++++-- src/bootstrap/src/utils/proc_macro_deps.rs | 71 ++++++++++++++++++++ src/tools/tidy/Cargo.toml | 2 +- src/tools/tidy/src/deps.rs | 75 +++++++++++++++++++++- src/tools/tidy/src/main.rs | 2 +- 5 files changed, 167 insertions(+), 11 deletions(-) create mode 100644 src/bootstrap/src/utils/proc_macro_deps.rs diff --git a/Cargo.lock b/Cargo.lock index eeb3c99a294a3..8009451fcedea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -367,7 +367,7 @@ dependencies = [ name = "cargo-miri" version = "0.1.0" dependencies = [ - "cargo_metadata", + "cargo_metadata 0.18.1", "directories", "rustc-build-sysroot", "rustc_tools_util", @@ -399,6 +399,20 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "cargo_metadata" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8769706aad5d996120af43197bf46ef6ad0fda35216b4505f926a365a232d924" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror 2.0.9", +] + [[package]] name = "cargotest2" version = "0.1.0" @@ -533,7 +547,7 @@ name = "clippy" version = "0.1.85" dependencies = [ "anstream", - "cargo_metadata", + "cargo_metadata 0.18.1", "clippy_config", "clippy_lints", "clippy_utils", @@ -589,7 +603,7 @@ name = "clippy_lints" version = "0.1.85" dependencies = [ "arrayvec", - "cargo_metadata", + "cargo_metadata 0.18.1", "clippy_config", "clippy_utils", "itertools", @@ -1389,7 +1403,7 @@ name = "generate-copyright" version = "0.1.0" dependencies = [ "anyhow", - "cargo_metadata", + "cargo_metadata 0.18.1", "rinja", "serde", "serde_json", @@ -4750,7 +4764,7 @@ dependencies = [ "annotate-snippets 0.9.2", "anyhow", "bytecount", - "cargo_metadata", + "cargo_metadata 0.18.1", "clap", "clap-cargo", "diff", @@ -5344,7 +5358,7 @@ name = "tidy" version = "0.1.0" dependencies = [ "build_helper", - "cargo_metadata", + "cargo_metadata 0.19.1", "fluent-syntax", "ignore", "miropt-test-tools", @@ -5622,7 +5636,7 @@ dependencies = [ "anyhow", "bstr", "cargo-platform", - "cargo_metadata", + "cargo_metadata 0.18.1", "color-eyre", "colored", "comma", diff --git a/src/bootstrap/src/utils/proc_macro_deps.rs b/src/bootstrap/src/utils/proc_macro_deps.rs new file mode 100644 index 0000000000000..dbfd6f47dc67f --- /dev/null +++ b/src/bootstrap/src/utils/proc_macro_deps.rs @@ -0,0 +1,71 @@ +/// Do not update manually - use `./x.py test tidy --bless` +/// Holds all direct and indirect dependencies of proc-macro crates in tree. +/// See +pub static CRATES: &[&str] = &[ + // tidy-alphabetical-start + "annotate-snippets", + "anstyle", + "basic-toml", + "block-buffer", + "bumpalo", + "cfg-if", + "cpufeatures", + "crypto-common", + "darling", + "darling_core", + "derive_builder_core", + "digest", + "fluent-bundle", + "fluent-langneg", + "fluent-syntax", + "fnv", + "generic-array", + "heck", + "ident_case", + "intl-memoizer", + "intl_pluralrules", + "libc", + "log", + "memchr", + "mime", + "mime_guess", + "minimal-lexical", + "nom", + "num-conv", + "once_cell", + "pest", + "pest_generator", + "pest_meta", + "proc-macro2", + "quote", + "rinja_parser", + "rustc-hash", + "self_cell", + "serde", + "sha2", + "smallvec", + "stable_deref_trait", + "strsim", + "syn", + "synstructure", + "thiserror", + "time-core", + "tinystr", + "type-map", + "typenum", + "ucd-trie", + "unic-langid", + "unic-langid-impl", + "unic-langid-macros", + "unicase", + "unicode-ident", + "unicode-width", + "version_check", + "wasm-bindgen-backend", + "wasm-bindgen-macro-support", + "wasm-bindgen-shared", + "yoke", + "zerofrom", + "zerovec", + // tidy-alphabetical-end +]; diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index bc75787fb1abe..2f424a482b5bb 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -6,7 +6,7 @@ autobins = false [dependencies] build_helper = { path = "../../build_helper" } -cargo_metadata = "0.18" +cargo_metadata = "0.19" regex = "1" miropt-test-tools = { path = "../miropt-test-tools" } walkdir = "2" diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index beeb33b46ff2d..1794d0fbca785 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -1,12 +1,16 @@ //! Checks the licenses of third-party dependencies. use std::collections::HashSet; -use std::fs::read_dir; +use std::fs::{File, read_dir}; +use std::io::Write; use std::path::Path; use build_helper::ci::CiEnv; use cargo_metadata::{Metadata, Package, PackageId}; +#[path = "../../../bootstrap/src/utils/proc_macro_deps.rs"] +mod proc_macro_deps; + /// These are licenses that are allowed for all crates, including the runtime, /// rustc, tools, etc. #[rustfmt::skip] @@ -564,9 +568,11 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ /// /// `root` is path to the directory with the root `Cargo.toml` (for the workspace). `cargo` is path /// to the cargo executable. -pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { +pub fn check(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) { let mut checked_runtime_licenses = false; + check_proc_macro_dep_list(root, cargo, bless, bad); + for &(workspace, exceptions, permitted_deps, submodules) in WORKSPACES { if has_missing_submodule(root, submodules) { continue; @@ -600,6 +606,71 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { assert!(checked_runtime_licenses); } +/// Ensure the list of proc-macro crate transitive dependencies is up to date +fn check_proc_macro_dep_list(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) { + let mut cmd = cargo_metadata::MetadataCommand::new(); + cmd.cargo_path(cargo) + .manifest_path(root.join("Cargo.toml")) + .features(cargo_metadata::CargoOpt::AllFeatures) + .other_options(vec!["--locked".to_owned()]); + let metadata = t!(cmd.exec()); + let is_proc_macro_pkg = |pkg: &Package| pkg.targets.iter().any(|target| target.is_proc_macro()); + + let mut proc_macro_deps = HashSet::new(); + for pkg in metadata.packages.iter().filter(|pkg| is_proc_macro_pkg(*pkg)) { + deps_of(&metadata, &pkg.id, &mut proc_macro_deps); + } + // Remove the proc-macro crates themselves + proc_macro_deps.retain(|pkg| !is_proc_macro_pkg(&metadata[pkg])); + let proc_macro_deps_iter = proc_macro_deps.into_iter().map(|dep| metadata[dep].name.clone()); + + if bless { + let mut proc_macro_deps: Vec<_> = proc_macro_deps_iter.collect(); + proc_macro_deps.sort(); + proc_macro_deps.dedup(); + let mut file = File::create(root.join("src/bootstrap/src/utils/proc_macro_deps.rs")) + .expect("`proc_macro_deps` should exist"); + writeln!( + &mut file, + "/// Do not update manually - use `./x.py test tidy --bless` +/// Holds all direct and indirect dependencies of proc-macro crates in tree. +/// See +pub static CRATES: &[&str] = &[ + // tidy-alphabetical-start" + ) + .unwrap(); + for dep in proc_macro_deps { + writeln!(&mut file, " {dep:?},").unwrap(); + } + writeln!( + &mut file, + " // tidy-alphabetical-end +];" + ) + .unwrap(); + } else { + let proc_macro_deps: HashSet<_> = proc_macro_deps_iter.collect(); + let expected = + proc_macro_deps::CRATES.iter().map(|s| s.to_string()).collect::>(); + let old_bad = *bad; + for missing in proc_macro_deps.difference(&expected) { + tidy_error!( + bad, + "proc-macro crate dependency `{missing}` is not registered in `src/bootstrap/src/utils/proc_macro_deps.rs`", + ); + } + for extra in expected.difference(&proc_macro_deps) { + tidy_error!( + bad, + "`{extra}` is not registered in `src/bootstrap/src/utils/proc_macro_deps.rs`, but is not a proc-macro crate dependency", + ); + } + if *bad != old_bad { + eprintln!("Run `./x.py test tidy --bless` to regenerate the list"); + } + } +} + /// Used to skip a check if a submodule is not checked out, and not in a CI environment. /// /// This helps prevent enforcing developers to fetch submodules for tidy. diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 40608952c0b70..13a558fea48ea 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -95,7 +95,7 @@ fn main() { check!(target_specific_tests, &tests_path); // Checks that are done on the cargo workspace. - check!(deps, &root_path, &cargo); + check!(deps, &root_path, &cargo, bless); check!(extdeps, &root_path); // Checks over tests. From f0734626cd177b7719b9b1d13edff2c9bab4b341 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sat, 28 Dec 2024 23:31:16 +0000 Subject: [PATCH 2/2] bootstrap: Don't apply `-Ztls-model=initial-exec` to deps of proc-macros --- src/bootstrap/src/bin/rustc.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index 88595ff7e5198..6104506759282 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -28,6 +28,9 @@ use shared_helpers::{ #[path = "../utils/shared_helpers.rs"] mod shared_helpers; +#[path = "../utils/proc_macro_deps.rs"] +mod proc_macro_deps; + fn main() { let orig_args = env::args_os().skip(1).collect::>(); let mut args = orig_args.clone(); @@ -167,7 +170,7 @@ fn main() { // issue https://github.com/rust-lang/rust/issues/100530 if env::var("RUSTC_TLS_MODEL_INITIAL_EXEC").is_ok() && crate_type != Some("proc-macro") - && !matches!(crate_name, Some("proc_macro2" | "quote" | "syn" | "synstructure")) + && proc_macro_deps::CRATES.binary_search(&crate_name.unwrap_or_default()).is_err() { cmd.arg("-Ztls-model=initial-exec"); }