Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use cfg_os_version_min in std #136868

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3460,6 +3460,7 @@ dependencies = [
"rustc_serialize",
"rustc_session",
"rustc_span",
"rustc_target",
]

[[package]]
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_attr_parsing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ rustc_macros = { path = "../rustc_macros" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
# tidy-alphabetical-end
15 changes: 15 additions & 0 deletions compiler/rustc_attr_parsing/messages.ftl
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
attr_parsing_apple_version_invalid =
failed parsing version: {$error}

attr_parsing_apple_version_unnecessarily_low =
version is set unnecessarily low, the minimum supported by Rust on this platform is {$os_min}

attr_parsing_cfg_predicate_identifier =
`cfg` predicate key must be an identifier

Expand All @@ -9,6 +15,12 @@ attr_parsing_deprecated_item_suggestion =
attr_parsing_expected_one_cfg_pattern =
expected 1 cfg-pattern

attr_parsing_expected_platform_and_version_literals =
expected two literals, a platform and a version

attr_parsing_expected_platform_literal =
expected a platform literal

attr_parsing_expected_single_version_literal =
expected single version literal

Expand Down Expand Up @@ -104,6 +116,9 @@ attr_parsing_unknown_meta_item =
unknown meta item '{$item}'
.label = expected one of {$expected}

attr_parsing_unknown_platform_literal =
unknown platform literal, expected values are: {$possibilities}

attr_parsing_unknown_version_literal =
unknown version literal format, assuming it refers to a future version

Expand Down
122 changes: 122 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use rustc_session::lint::BuiltinLintDiag;
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
use rustc_session::parse::feature_err;
use rustc_span::{Span, Symbol, kw, sym};
use rustc_target::spec::apple;

use crate::util::UnsupportedLiteralReason;
use crate::{fluent_generated, parse_version, session_diagnostics};
Expand Down Expand Up @@ -150,6 +151,122 @@ pub fn eval_condition(
RustcVersion::CURRENT >= min_version
}
}
ast::MetaItemKind::List(mis) if cfg.name_or_empty() == sym::os_version_min => {
try_gate_cfg(sym::os_version_min, cfg.span, sess, features);

let (platform, version) = match &mis[..] {
[platform, version] => (platform, version),
[..] => {
dcx.emit_err(session_diagnostics::ExpectedPlatformAndVersionLiterals {
span: cfg.span,
});
return false;
}
};

let (platform_sym, platform_span) = match platform {
MetaItemInner::Lit(MetaItemLit {
kind: LitKind::Str(platform_sym, ..),
span: platform_span,
..
}) => (platform_sym, platform_span),
MetaItemInner::Lit(MetaItemLit { span, .. })
| MetaItemInner::MetaItem(MetaItem { span, .. }) => {
dcx.emit_err(session_diagnostics::ExpectedPlatformLiteral { span: *span });
return false;
}
};

let (version_sym, version_span) = match version {
MetaItemInner::Lit(MetaItemLit {
kind: LitKind::Str(version_sym, ..),
span: version_span,
..
}) => (version_sym, version_span),
MetaItemInner::Lit(MetaItemLit { span, .. })
| MetaItemInner::MetaItem(MetaItem { span, .. }) => {
dcx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span });
return false;
}
};

// Always parse version, regardless of current target platform.
let version = match *platform_sym {
// Apple platforms follow the same versioning schema.
sym::macos | sym::ios | sym::tvos | sym::watchos | sym::visionos => {
match version_sym.as_str().parse() {
Ok(version) => {
let os_min = apple::OSVersion::os_minimum_deployment_target(
&platform_sym.as_str(),
);

// It's unnecessary to specify `cfg_target_os(...)` for a platform
// version that is lower than the minimum targetted by `rustc` (instead,
// make the item always available).
//
// This is correct _now_, but once we bump versions next time, we should
// maybe make this a lint so that users can opt-in to supporting older
// `rustc` versions? Or perhaps only fire the warning when Cargo's
// `rust-version` field is above the version where the bump happened? Or
// perhaps keep the version we check against low for a sufficiently long
// time?
if version <= os_min {
sess.dcx().emit_warn(
session_diagnostics::AppleVersionUnnecessarilyLow {
span: *version_span,
os_min: os_min.fmt_pretty().to_string(),
},
);
// TODO(madsmtm): Add suggestion for replacing with `target_os = "..."`
}

PlatformVersion::Apple { os: *platform_sym, version }
}
Err(error) => {
sess.dcx().emit_err(session_diagnostics::AppleVersionInvalid {
span: *version_span,
error,
});
return false;
}
}
}
// FIXME(madsmtm): Handle further platforms as specified in the RFC.
sym::windows | sym::libc => {
#[allow(rustc::untranslatable_diagnostic)] // Temporary
dcx.span_err(*platform_span, "unimplemented platform");
return false;
}
_ => {
// Unknown platform. This is intentionally a warning (and not an error) to be
// future-compatible with later additions.
let known_platforms = [
sym::macos,
sym::ios,
sym::tvos,
sym::watchos,
sym::visionos,
// sym::windows,
// sym::libc,
];
dcx.emit_warn(session_diagnostics::UnknownPlatformLiteral {
span: *platform_span,
possibilities: known_platforms.into_iter().collect(),
});
return false;
}
};

// Figure out actual cfg-status based on current platform.
match version {
PlatformVersion::Apple { os, version } if os.as_str() == sess.target.os => {
let deployment_target = sess.apple_deployment_target();
version <= deployment_target
}
// If a `cfg`-value does not apply to a specific platform, assume
_ => false,
}
}
ast::MetaItemKind::List(mis) => {
for mi in mis.iter() {
if mi.meta_item_or_bool().is_none() {
Expand Down Expand Up @@ -251,3 +368,8 @@ pub fn eval_condition(
}
}
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
enum PlatformVersion {
Apple { os: Symbol, version: apple::OSVersion },
}
44 changes: 42 additions & 2 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,32 @@
use std::num::IntErrorKind;
use std::num::{IntErrorKind, ParseIntError};

use rustc_ast as ast;
use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level};
use rustc_errors::{
Applicability, Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level,
};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Span, Symbol};

use crate::attributes::util::UnsupportedLiteralReason;
use crate::fluent_generated as fluent;

#[derive(Diagnostic)]
#[diag(attr_parsing_apple_version_invalid)]
pub(crate) struct AppleVersionInvalid {
#[primary_span]
pub span: Span,
pub error: ParseIntError,
}

#[derive(Diagnostic)]
#[diag(attr_parsing_apple_version_unnecessarily_low)]
pub(crate) struct AppleVersionUnnecessarilyLow {
#[primary_span]
pub span: Span,
pub os_min: String,
}

#[derive(Diagnostic)]
#[diag(attr_parsing_expected_one_cfg_pattern, code = E0536)]
pub(crate) struct ExpectedOneCfgPattern {
Expand Down Expand Up @@ -371,6 +389,20 @@ pub(crate) struct DeprecatedItemSuggestion {
pub details: (),
}

#[derive(Diagnostic)]
#[diag(attr_parsing_expected_platform_and_version_literals)]
pub(crate) struct ExpectedPlatformAndVersionLiterals {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(attr_parsing_expected_platform_literal)]
pub(crate) struct ExpectedPlatformLiteral {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(attr_parsing_expected_single_version_literal)]
pub(crate) struct ExpectedSingleVersionLiteral {
Expand Down Expand Up @@ -417,6 +449,14 @@ pub(crate) struct SoftNoArgs {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(attr_parsing_unknown_platform_literal)]
pub(crate) struct UnknownPlatformLiteral {
#[primary_span]
pub span: Span,
pub possibilities: DiagSymbolList,
}

#[derive(Diagnostic)]
#[diag(attr_parsing_unknown_version_literal)]
pub(crate) struct UnknownVersionLiteral {
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_codegen_ssa/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ codegen_ssa_add_native_library = failed to add native library {$library_path}: {

codegen_ssa_aix_strip_not_used = using host's `strip` binary to cross-compile to AIX which is not guaranteed to work

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}
Expand Down
Loading
Loading