about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMads Marquart <mads@marquart.dk>2024-09-29 22:14:55 +0200
committerMads Marquart <mads@marquart.dk>2024-11-01 17:07:19 +0100
commit1ef1af1c607fe268b5622041ff586ca603b8ec8d (patch)
tree7feb7e4172e76ae899c5989e2d372b9daabdffaa /compiler
parente75a7ddad37feea205df1e4b568a5316b31da641 (diff)
downloadrust-1ef1af1c607fe268b5622041ff586ca603b8ec8d.tar.gz
rust-1ef1af1c607fe268b5622041ff586ca603b8ec8d.zip
Emit diagnostics for incorrect deployment targets
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_codegen_ssa/messages.ftl6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/apple.rs46
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs1
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs7
5 files changed, 57 insertions, 12 deletions
diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl
index d07274920fe..3b34eb063ec 100644
--- a/compiler/rustc_codegen_ssa/messages.ftl
+++ b/compiler/rustc_codegen_ssa/messages.ftl
@@ -2,6 +2,12 @@ codegen_ssa_L4Bender_exporting_symbols_unimplemented = exporting symbols not imp
 
 codegen_ssa_add_native_library = failed to add native library {$library_path}: {$error}
 
+codegen_ssa_apple_deployment_target_invalid =
+    failed to parse deployment target specified in {$env_var}: {$error}
+
+codegen_ssa_apple_deployment_target_too_low =
+    deployment target in {$env_var} was set to {$version}, but the minimum supported by `rustc` is {$os_min}
+
 codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {$error}
 
 codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error}
diff --git a/compiler/rustc_codegen_ssa/src/back/apple.rs b/compiler/rustc_codegen_ssa/src/back/apple.rs
index 23460ae9e1e..93d90cd16b2 100644
--- a/compiler/rustc_codegen_ssa/src/back/apple.rs
+++ b/compiler/rustc_codegen_ssa/src/back/apple.rs
@@ -1,9 +1,12 @@
 use std::env;
+use std::fmt::{Display, from_fn};
 use std::num::ParseIntError;
 
 use rustc_session::Session;
 use rustc_target::spec::Target;
 
+use crate::errors::AppleDeploymentTarget;
+
 #[cfg(test)]
 mod tests;
 
@@ -42,6 +45,17 @@ fn parse_version(version: &str) -> Result<OSVersion, ParseIntError> {
     }
 }
 
+pub fn pretty_version(version: OSVersion) -> impl Display {
+    let (major, minor, patch) = version;
+    from_fn(move |f| {
+        write!(f, "{major}.{minor}")?;
+        if patch != 0 {
+            write!(f, ".{patch}")?;
+        }
+        Ok(())
+    })
+}
+
 /// Minimum operating system versions currently supported by `rustc`.
 fn os_minimum_deployment_target(os: &str) -> OSVersion {
     // When bumping a version in here, remember to update the platform-support docs too.
@@ -98,17 +112,31 @@ fn deployment_target_env_var(os: &str) -> &'static str {
 /// minimum version supported by `rustc`.
 pub fn deployment_target(sess: &Session) -> OSVersion {
     let min = minimum_deployment_target(&sess.target);
+    let env_var = deployment_target_env_var(&sess.target.os);
 
-    if let Ok(deployment_target) = env::var(deployment_target_env_var(&sess.target.os)) {
+    if let Ok(deployment_target) = env::var(env_var) {
         match parse_version(&deployment_target) {
-            // It is common that the deployment target is set too low, e.g. on macOS Aarch64 to also
-            // target older x86_64, the user may set a lower deployment target than supported.
-            //
-            // To avoid such issues, we silently raise the deployment target here.
-            // FIXME: We want to show a warning when `version < os_min`.
-            Ok(version) => version.max(min),
-            // FIXME: Report erroneous environment variable to user.
-            Err(_) => min,
+            Ok(version) => {
+                let os_min = os_minimum_deployment_target(&sess.target.os);
+                // It is common that the deployment target is set a bit too low, for example on
+                // macOS Aarch64 to also target older x86_64. So we only want to warn when variable
+                // is lower than the minimum OS supported by rustc, not when the variable is lower
+                // than the minimum for a specific target.
+                if version < os_min {
+                    sess.dcx().emit_warn(AppleDeploymentTarget::TooLow {
+                        env_var,
+                        version: pretty_version(version).to_string(),
+                        os_min: pretty_version(os_min).to_string(),
+                    });
+                }
+
+                // Raise the deployment target to the minimum supported.
+                version.max(min)
+            }
+            Err(error) => {
+                sess.dcx().emit_err(AppleDeploymentTarget::Invalid { env_var, error });
+                min
+            }
         }
     } else {
         // If no deployment target variable is set, default to the minimum found above.
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index d67cf0e3a6d..cf8d1cfa0d1 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -2,6 +2,7 @@
 
 use std::borrow::Cow;
 use std::io::Error;
+use std::num::ParseIntError;
 use std::path::{Path, PathBuf};
 use std::process::ExitStatus;
 
@@ -540,6 +541,14 @@ pub(crate) struct UnsupportedArch<'a> {
 }
 
 #[derive(Diagnostic)]
+pub(crate) enum AppleDeploymentTarget {
+    #[diag(codegen_ssa_apple_deployment_target_invalid)]
+    Invalid { env_var: &'static str, error: ParseIntError },
+    #[diag(codegen_ssa_apple_deployment_target_too_low)]
+    TooLow { env_var: &'static str, version: String, os_min: String },
+}
+
+#[derive(Diagnostic)]
 pub(crate) enum AppleSdkRootError<'a> {
     #[diag(codegen_ssa_apple_sdk_error_sdk_path)]
     SdkPath { sdk_name: &'a str, error: Error },
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 73bfa9dbd10..7dc8ab38a97 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -6,6 +6,7 @@
 #![doc(rust_logo)]
 #![feature(assert_matches)]
 #![feature(box_patterns)]
+#![feature(debug_closure_helpers)]
 #![feature(file_buffered)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 06b4c89946d..92b622fccf2 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -857,9 +857,10 @@ fn print_crate_info(
             }
             DeploymentTarget => {
                 if sess.target.is_like_osx {
-                    let (major, minor, patch) = apple::deployment_target(sess);
-                    let patch = if patch != 0 { format!(".{patch}") } else { String::new() };
-                    println_info!("deployment_target={major}.{minor}{patch}")
+                    println_info!(
+                        "deployment_target={}",
+                        apple::pretty_version(apple::deployment_target(sess))
+                    )
                 } else {
                     #[allow(rustc::diagnostic_outside_of_impl)]
                     sess.dcx().fatal("only Apple targets currently support deployment version info")