about summary refs log tree commit diff
path: root/compiler/rustc_session/src/utils.rs
diff options
context:
space:
mode:
authorMartin Nordholts <enselic@gmail.com>2023-08-24 06:31:10 +0200
committerMartin Nordholts <enselic@gmail.com>2023-08-24 06:31:11 +0200
commit9f1de6171c209ae20438827f42ffd625963adfc1 (patch)
treeb9e676ba618e7262e4ca7bfa1cbdee308095ed3f /compiler/rustc_session/src/utils.rs
parentd8c69dfb37241a2b750a2acbbab48d1201d00766 (diff)
downloadrust-9f1de6171c209ae20438827f42ffd625963adfc1.tar.gz
rust-9f1de6171c209ae20438827f42ffd625963adfc1.zip
Move extra_compiler_flags() to rustc_session
To make it available to other parts of the compiler.
Diffstat (limited to 'compiler/rustc_session/src/utils.rs')
-rw-r--r--compiler/rustc_session/src/utils.rs47
1 files changed, 47 insertions, 0 deletions
diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs
index 71f2591fe66..f76c69af526 100644
--- a/compiler/rustc_session/src/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
@@ -111,3 +111,50 @@ impl CanonicalizedPath {
         &self.original
     }
 }
+
+/// Gets a list of extra command-line flags provided by the user, as strings.
+///
+/// This function is used during ICEs to show more information useful for
+/// debugging, since some ICEs only happens with non-default compiler flags
+/// (and the users don't always report them).
+pub fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
+    const ICE_REPORT_COMPILER_FLAGS: &[&str] = &["-Z", "-C", "--crate-type"];
+
+    const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &[&str] = &["metadata", "extra-filename"];
+
+    const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &[&str] = &["incremental"];
+
+    let mut args = std::env::args_os().map(|arg| arg.to_string_lossy().to_string()).peekable();
+
+    let mut result = Vec::new();
+    let mut excluded_cargo_defaults = false;
+    while let Some(arg) = args.next() {
+        if let Some(a) = ICE_REPORT_COMPILER_FLAGS.iter().find(|a| arg.starts_with(*a)) {
+            let content = if arg.len() == a.len() {
+                // A space-separated option, like `-C incremental=foo` or `--crate-type rlib`
+                match args.next() {
+                    Some(arg) => arg.to_string(),
+                    None => continue,
+                }
+            } else if arg.get(a.len()..a.len() + 1) == Some("=") {
+                // An equals option, like `--crate-type=rlib`
+                arg[a.len() + 1..].to_string()
+            } else {
+                // A non-space option, like `-Cincremental=foo`
+                arg[a.len()..].to_string()
+            };
+            let option = content.split_once('=').map(|s| s.0).unwrap_or(&content);
+            if ICE_REPORT_COMPILER_FLAGS_EXCLUDE.iter().any(|exc| option == *exc) {
+                excluded_cargo_defaults = true;
+            } else {
+                result.push(a.to_string());
+                match ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.iter().find(|s| option == **s) {
+                    Some(s) => result.push(format!("{s}=[REDACTED]")),
+                    None => result.push(content),
+                }
+            }
+        }
+    }
+
+    if !result.is_empty() { Some((result, excluded_cargo_defaults)) } else { None }
+}