about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-12-30 07:26:13 +0000
committerbors <bors@rust-lang.org>2024-12-30 07:26:13 +0000
commitc1566141b6ed24eaa11075aa7dfe6511fdf32231 (patch)
treece7aa8888f091d4e0e71a4d0a8f770e300675714
parent84e930871f3918d7654b13e0b716857e0980d93f (diff)
parentf0734626cd177b7719b9b1d13edff2c9bab4b341 (diff)
downloadrust-c1566141b6ed24eaa11075aa7dfe6511fdf32231.tar.gz
rust-c1566141b6ed24eaa11075aa7dfe6511fdf32231.zip
Auto merge of #134865 - clubby789:proc-macro-tls, r=onur-ozkan
bootstrap: Don't apply -Ztls-model=initial-exec to deps of proc-macros

Fixes #134863

1. Checks if a crate name is in a static list before applying the flag
2. Adds a tidy check that gathers transitive deps of proc macros and ensures the list is up to date

cc `@bjorn3` - the issue specifies `rustc_fluent_macro` but I assume this applies to all proc macro crates.
-rw-r--r--Cargo.lock28
-rw-r--r--src/bootstrap/src/bin/rustc.rs5
-rw-r--r--src/bootstrap/src/utils/proc_macro_deps.rs71
-rw-r--r--src/tools/tidy/Cargo.toml2
-rw-r--r--src/tools/tidy/src/deps.rs75
-rw-r--r--src/tools/tidy/src/main.rs2
6 files changed, 171 insertions, 12 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 06576c703e2..7d22abc8611 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",
@@ -400,6 +400,20 @@ dependencies = [
 ]
 
 [[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/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs
index 88595ff7e51..61045067592 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::<Vec<_>>();
     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");
         }
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 00000000000..dbfd6f47dc6
--- /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 <https://github.com/rust-lang/rust/issues/134863>
+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 bc75787fb1a..2f424a482b5 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 beeb33b46ff..1794d0fbca7 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 <https://github.com/rust-lang/rust/issues/134863>
+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::<HashSet<_>>();
+        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 40608952c0b..13a558fea48 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.