about summary refs log tree commit diff
path: root/src/bootstrap
diff options
context:
space:
mode:
authoronur-ozkan <work@onurozkan.dev>2025-01-02 18:24:28 +0300
committeronur-ozkan <work@onurozkan.dev>2025-01-03 08:57:13 +0300
commita8516c052e35951f86ccdc0a2ee9ce670bd159c8 (patch)
treeb76b212684c8e4b937f2a20685eb6950e7b49cbb /src/bootstrap
parentab3924b298eb78bf4c96cf7e6b5824f8debbf2b9 (diff)
downloadrust-a8516c052e35951f86ccdc0a2ee9ce670bd159c8.tar.gz
rust-a8516c052e35951f86ccdc0a2ee9ce670bd159c8.zip
refactor bootstrap path resolution
Previously we removed paths as soon as we found the first intersection, which made
it impossible to find other intersecting paths. This patch changes that by marking
the intersecting paths instead, so we can collect them all and remove them together
when needed.

Signed-off-by: onur-ozkan <work@onurozkan.dev>
Diffstat (limited to 'src/bootstrap')
-rw-r--r--src/bootstrap/src/core/builder/mod.rs37
1 files changed, 29 insertions, 8 deletions
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index 30e42a5bfb7..2a95301c414 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -3,7 +3,7 @@ mod cargo;
 use std::any::{Any, type_name};
 use std::cell::{Cell, RefCell};
 use std::collections::BTreeSet;
-use std::fmt::{Debug, Write};
+use std::fmt::{self, Debug, Write};
 use std::hash::Hash;
 use std::ops::Deref;
 use std::path::{Path, PathBuf};
@@ -271,12 +271,12 @@ impl PathSet {
     /// This is used for `StepDescription::krate`, which passes all matching crates at once to
     /// `Step::make_run`, rather than calling it many times with a single crate.
     /// See `tests.rs` for examples.
-    fn intersection_removing_matches(&self, needles: &mut Vec<PathBuf>, module: Kind) -> PathSet {
+    fn intersection_removing_matches(&self, needles: &mut [CLIStepPath], module: Kind) -> PathSet {
         let mut check = |p| {
-            for (i, n) in needles.iter().enumerate() {
-                let matched = Self::check(p, n, module);
+            for n in needles.iter_mut() {
+                let matched = Self::check(p, &n.path, module);
                 if matched {
-                    needles.remove(i);
+                    n.will_be_executed = true;
                     return true;
                 }
             }
@@ -361,6 +361,24 @@ fn remap_paths(paths: &mut Vec<PathBuf>) {
     paths.append(&mut add);
 }
 
+#[derive(Clone, PartialEq)]
+struct CLIStepPath {
+    path: PathBuf,
+    will_be_executed: bool,
+}
+
+impl Debug for CLIStepPath {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", self.path.display())
+    }
+}
+
+impl From<PathBuf> for CLIStepPath {
+    fn from(path: PathBuf) -> Self {
+        Self { path, will_be_executed: false }
+    }
+}
+
 impl StepDescription {
     fn from<S: Step>(kind: Kind) -> StepDescription {
         StepDescription {
@@ -478,7 +496,8 @@ impl StepDescription {
             return;
         }
 
-        let mut path_lookup: Vec<(PathBuf, bool)> =
+        let mut paths: Vec<CLIStepPath> = paths.into_iter().map(|p| p.into()).collect();
+        let mut path_lookup: Vec<(CLIStepPath, bool)> =
             paths.clone().into_iter().map(|p| (p, false)).collect();
 
         // List of `(usize, &StepDescription, Vec<PathSet>)` where `usize` is the closest index of a path
@@ -518,8 +537,10 @@ impl StepDescription {
             }
         }
 
+        paths.retain(|p| !p.will_be_executed);
+
         if !paths.is_empty() {
-            eprintln!("ERROR: no `{}` rules matched {:?}", builder.kind.as_str(), paths,);
+            eprintln!("ERROR: no `{}` rules matched {:?}", builder.kind.as_str(), paths);
             eprintln!(
                 "HELP: run `x.py {} --help --verbose` to show a list of available paths",
                 builder.kind.as_str()
@@ -682,7 +703,7 @@ impl<'a> ShouldRun<'a> {
     /// (for now, just `all_krates` and `paths`, but we may want to add an `aliases` function in the future?)
     fn pathset_for_paths_removing_matches(
         &self,
-        paths: &mut Vec<PathBuf>,
+        paths: &mut [CLIStepPath],
         kind: Kind,
     ) -> Vec<PathSet> {
         let mut sets = vec![];