about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock15
-rw-r--r--Cargo.toml1
-rw-r--r--src/bootstrap/src/core/build_steps/check.rs1
-rw-r--r--src/bootstrap/src/core/build_steps/run.rs31
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs1
-rw-r--r--src/bootstrap/src/core/builder/mod.rs2
-rw-r--r--src/tools/features-status-dump/Cargo.toml12
-rw-r--r--src/tools/features-status-dump/src/main.rs53
-rw-r--r--src/tools/tidy/Cargo.toml4
-rw-r--r--src/tools/tidy/src/features.rs2
-rw-r--r--src/tools/tidy/src/features/version.rs1
11 files changed, 123 insertions, 0 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 77653530925..18d5b66eb73 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -186,6 +186,9 @@ name = "anyhow"
 version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
+dependencies = [
+ "backtrace",
+]
 
 [[package]]
 name = "ar_archive_writer"
@@ -1196,6 +1199,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
 
 [[package]]
+name = "features-status-dump"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "clap",
+ "serde",
+ "serde_json",
+ "tidy",
+]
+
+[[package]]
 name = "field-offset"
 version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5418,6 +5432,7 @@ dependencies = [
  "regex",
  "rustc-hash 2.1.0",
  "semver",
+ "serde",
  "similar",
  "termcolor",
  "walkdir",
diff --git a/Cargo.toml b/Cargo.toml
index b773030b4ca..68d142ebe92 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -47,6 +47,7 @@ members = [
   "src/tools/coverage-dump",
   "src/tools/rustc-perf-wrapper",
   "src/tools/wasm-component-ld",
+  "src/tools/features-status-dump",
 ]
 
 exclude = [
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index f4a86e26396..21afb031203 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -455,6 +455,7 @@ tool_check_step!(Rls { path: "src/tools/rls" });
 tool_check_step!(Rustfmt { path: "src/tools/rustfmt" });
 tool_check_step!(MiroptTestTools { path: "src/tools/miropt-test-tools" });
 tool_check_step!(TestFloatParse { path: "src/etc/test-float-parse" });
+tool_check_step!(FeaturesStatusDump { path: "src/tools/features-status-dump" });
 
 tool_check_step!(Bootstrap { path: "src/bootstrap", default: false });
 
diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs
index 8513c59808c..167b8a5b168 100644
--- a/src/bootstrap/src/core/build_steps/run.rs
+++ b/src/bootstrap/src/core/build_steps/run.rs
@@ -311,3 +311,34 @@ impl Step for UnicodeTableGenerator {
         cmd.run(builder);
     }
 }
+
+#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
+pub struct FeaturesStatusDump;
+
+impl Step for FeaturesStatusDump {
+    type Output = ();
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.path("src/tools/features-status-dump")
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(FeaturesStatusDump);
+    }
+
+    fn run(self, builder: &Builder<'_>) {
+        let mut cmd = builder.tool_cmd(Tool::FeaturesStatusDump);
+
+        cmd.arg("--library-path");
+        cmd.arg(builder.src.join("library"));
+
+        cmd.arg("--compiler-path");
+        cmd.arg(builder.src.join("compiler"));
+
+        cmd.arg("--output-path");
+        cmd.arg(builder.out.join("features-status-dump.json"));
+
+        cmd.run(builder);
+    }
+}
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index a0abd439de0..75fac88252b 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -365,6 +365,7 @@ bootstrap_tool!(
     RustcPerfWrapper, "src/tools/rustc-perf-wrapper", "rustc-perf-wrapper";
     WasmComponentLd, "src/tools/wasm-component-ld", "wasm-component-ld", is_unstable_tool = true, allow_features = "min_specialization";
     UnicodeTableGenerator, "src/tools/unicode-table-generator", "unicode-table-generator";
+    FeaturesStatusDump, "src/tools/features-status-dump", "features-status-dump";
 );
 
 /// These are the submodules that are required for rustbook to work due to
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index 04a00fde3ab..08421dc1f5b 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -938,6 +938,7 @@ impl<'a> Builder<'a> {
                 check::Bootstrap,
                 check::RunMakeSupport,
                 check::Compiletest,
+                check::FeaturesStatusDump,
             ),
             Kind::Test => describe!(
                 crate::core::build_steps::toolstate::ToolStateCheck,
@@ -1089,6 +1090,7 @@ impl<'a> Builder<'a> {
                 run::GenerateWindowsSys,
                 run::GenerateCompletions,
                 run::UnicodeTableGenerator,
+                run::FeaturesStatusDump,
             ),
             Kind::Setup => {
                 describe!(setup::Profile, setup::Hook, setup::Link, setup::Editor)
diff --git a/src/tools/features-status-dump/Cargo.toml b/src/tools/features-status-dump/Cargo.toml
new file mode 100644
index 00000000000..35be71a46e5
--- /dev/null
+++ b/src/tools/features-status-dump/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "features-status-dump"
+version = "0.1.0"
+license = "MIT OR Apache-2.0"
+edition = "2021"
+
+[dependencies]
+anyhow = { version = "1", features = ["backtrace"] }
+clap = { version = "4", features = ["derive"] }
+serde = { version = "1.0.125", features = [ "derive" ] }
+serde_json = "1.0.59"
+tidy = { path = "../tidy", features = ["build-metrics"] }
diff --git a/src/tools/features-status-dump/src/main.rs b/src/tools/features-status-dump/src/main.rs
new file mode 100644
index 00000000000..1ce98d1506d
--- /dev/null
+++ b/src/tools/features-status-dump/src/main.rs
@@ -0,0 +1,53 @@
+use std::collections::HashMap;
+use std::fs::File;
+use std::io::BufWriter;
+use std::path::PathBuf;
+
+use anyhow::{Context, Result};
+use clap::Parser;
+use tidy::features::{Feature, collect_lang_features, collect_lib_features};
+
+#[derive(Debug, Parser)]
+struct Cli {
+    /// Path to `library/` directory.
+    #[arg(long)]
+    library_path: PathBuf,
+    /// Path to `compiler/` directory.
+    #[arg(long)]
+    compiler_path: PathBuf,
+    /// Path to `output/` directory.
+    #[arg(long)]
+    output_path: PathBuf,
+}
+
+#[derive(Debug, serde::Serialize)]
+struct FeaturesStatus {
+    lang_features_status: HashMap<String, Feature>,
+    lib_features_status: HashMap<String, Feature>,
+}
+
+fn main() -> Result<()> {
+    let Cli { compiler_path, library_path, output_path } = Cli::parse();
+
+    let lang_features_status = collect_lang_features(&compiler_path, &mut false);
+    let lib_features_status = collect_lib_features(&library_path)
+        .into_iter()
+        .filter(|&(ref name, _)| !lang_features_status.contains_key(name))
+        .collect();
+    let features_status = FeaturesStatus { lang_features_status, lib_features_status };
+
+    let output_dir = output_path.parent().with_context(|| {
+        format!("failed to get parent dir of output path `{}`", output_path.display())
+    })?;
+    std::fs::create_dir_all(output_dir).with_context(|| {
+        format!("failed to create output directory at `{}`", output_dir.display())
+    })?;
+
+    let output_file = File::create(&output_path).with_context(|| {
+        format!("failed to create file at given output path `{}`", output_path.display())
+    })?;
+    let writer = BufWriter::new(output_file);
+    serde_json::to_writer_pretty(writer, &features_status)
+        .context("failed to write json output")?;
+    Ok(())
+}
diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml
index 2f424a482b5..9a4d0891b4a 100644
--- a/src/tools/tidy/Cargo.toml
+++ b/src/tools/tidy/Cargo.toml
@@ -12,11 +12,15 @@ miropt-test-tools = { path = "../miropt-test-tools" }
 walkdir = "2"
 ignore = "0.4.18"
 semver = "1.0"
+serde = { version = "1.0.125", features = ["derive"], optional = true }
 termcolor = "1.1.3"
 rustc-hash = "2.0.0"
 fluent-syntax = "0.11.1"
 similar = "2.5.0"
 
+[features]
+build-metrics = ["dep:serde"]
+
 [[bin]]
 name = "rust-tidy"
 path = "src/main.rs"
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index 4f24eb21242..fcd7943e6e0 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -27,6 +27,7 @@ const FEATURE_GROUP_START_PREFIX: &str = "// feature-group-start";
 const FEATURE_GROUP_END_PREFIX: &str = "// feature-group-end";
 
 #[derive(Debug, PartialEq, Clone)]
+#[cfg_attr(feature = "build-metrics", derive(serde::Serialize))]
 pub enum Status {
     Accepted,
     Removed,
@@ -45,6 +46,7 @@ impl fmt::Display for Status {
 }
 
 #[derive(Debug, Clone)]
+#[cfg_attr(feature = "build-metrics", derive(serde::Serialize))]
 pub struct Feature {
     pub level: Status,
     pub since: Option<Version>,
diff --git a/src/tools/tidy/src/features/version.rs b/src/tools/tidy/src/features/version.rs
index 0830c226caf..6a902e80f8e 100644
--- a/src/tools/tidy/src/features/version.rs
+++ b/src/tools/tidy/src/features/version.rs
@@ -8,6 +8,7 @@ mod tests;
 pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION";
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+#[cfg_attr(feature = "build-metrics", derive(serde::Serialize))]
 pub enum Version {
     Explicit { parts: [u32; 3] },
     CurrentPlaceholder,