|
1 | 1 | use std::env; |
| 2 | +use std::fmt::{Display, from_fn}; |
2 | 3 | use std::num::ParseIntError; |
3 | 4 |
|
4 | 5 | use rustc_session::Session; |
5 | 6 | use rustc_target::spec::Target; |
6 | 7 |
|
| 8 | +use crate::errors::AppleDeploymentTarget; |
| 9 | + |
7 | 10 | #[cfg(test)] |
8 | 11 | mod tests; |
9 | 12 |
|
@@ -42,6 +45,17 @@ fn parse_version(version: &str) -> Result<OSVersion, ParseIntError> { |
42 | 45 | } |
43 | 46 | } |
44 | 47 |
|
| 48 | +pub fn pretty_version(version: OSVersion) -> impl Display { |
| 49 | + let (major, minor, patch) = version; |
| 50 | + from_fn(move |f| { |
| 51 | + write!(f, "{major}.{minor}")?; |
| 52 | + if patch != 0 { |
| 53 | + write!(f, ".{patch}")?; |
| 54 | + } |
| 55 | + Ok(()) |
| 56 | + }) |
| 57 | +} |
| 58 | + |
45 | 59 | /// Minimum operating system versions currently supported by `rustc`. |
46 | 60 | fn os_minimum_deployment_target(os: &str) -> OSVersion { |
47 | 61 | // 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 { |
98 | 112 | /// minimum version supported by `rustc`. |
99 | 113 | pub fn deployment_target(sess: &Session) -> OSVersion { |
100 | 114 | let min = minimum_deployment_target(&sess.target); |
| 115 | + let env_var = deployment_target_env_var(&sess.target.os); |
101 | 116 |
|
102 | | - if let Ok(deployment_target) = env::var(deployment_target_env_var(&sess.target.os)) { |
| 117 | + if let Ok(deployment_target) = env::var(env_var) { |
103 | 118 | match parse_version(&deployment_target) { |
104 | | - // It is common that the deployment target is set too low, e.g. on macOS Aarch64 to also |
105 | | - // target older x86_64, the user may set a lower deployment target than supported. |
106 | | - // |
107 | | - // To avoid such issues, we silently raise the deployment target here. |
108 | | - // FIXME: We want to show a warning when `version < os_min`. |
109 | | - Ok(version) => version.max(min), |
110 | | - // FIXME: Report erroneous environment variable to user. |
111 | | - Err(_) => min, |
| 119 | + Ok(version) => { |
| 120 | + let os_min = os_minimum_deployment_target(&sess.target.os); |
| 121 | + // It is common that the deployment target is set a bit too low, for example on |
| 122 | + // macOS Aarch64 to also target older x86_64. So we only want to warn when variable |
| 123 | + // is lower than the minimum OS supported by rustc, not when the variable is lower |
| 124 | + // than the minimum for a specific target. |
| 125 | + if version < os_min { |
| 126 | + sess.dcx().emit_warn(AppleDeploymentTarget::TooLow { |
| 127 | + env_var, |
| 128 | + version: pretty_version(version).to_string(), |
| 129 | + os_min: pretty_version(os_min).to_string(), |
| 130 | + }); |
| 131 | + } |
| 132 | + |
| 133 | + // Raise the deployment target to the minimum supported. |
| 134 | + version.max(min) |
| 135 | + } |
| 136 | + Err(error) => { |
| 137 | + sess.dcx().emit_err(AppleDeploymentTarget::Invalid { env_var, error }); |
| 138 | + min |
| 139 | + } |
112 | 140 | } |
113 | 141 | } else { |
114 | 142 | // If no deployment target variable is set, default to the minimum found above. |
|
0 commit comments