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

Implement cfg_os_version_min #136867

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
@@ -3340,6 +3340,7 @@ dependencies = [
"rustc_macros",
"rustc_session",
"rustc_span",
"rustc_target",
"thin-vec",
]

1 change: 1 addition & 0 deletions compiler/rustc_attr_parsing/Cargo.toml
Original file line number Diff line number Diff line change
@@ -17,5 +17,6 @@ rustc_lexer = { path = "../rustc_lexer" }
rustc_macros = { path = "../rustc_macros" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
thin-vec = "0.2.12"
# 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

@@ -11,6 +17,12 @@ attr_parsing_empty_confusables =
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

@@ -108,6 +120,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

130 changes: 130 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/cfg.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NodeId};
use rustc_ast_pretty::pprust;
use rustc_attr_data_structures::RustcVersion;
use rustc_errors::Applicability;
use rustc_feature::{Features, GatedCfg, find_gated_cfg};
use rustc_session::Session;
use rustc_session::config::ExpectedValues;
@@ -9,6 +10,7 @@ use rustc_session::lint::builtin::UNEXPECTED_CFGS;
use rustc_session::parse::feature_err;
use rustc_span::symbol::kw;
use rustc_span::{Span, Symbol, sym};
use rustc_target::spec::apple;

use crate::session_diagnostics::{self, UnsupportedLiteralReason};
use crate::{fluent_generated, parse_version};
@@ -149,6 +151,129 @@ pub fn eval_condition(
RustcVersion::CURRENT >= min_version
}
}
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()
.create_warn(
session_diagnostics::AppleVersionUnnecessarilyLow {
span: *version_span,
os_min: os_min.fmt_pretty().to_string(),
},
)
.with_span_suggestion(
cfg.span,
"use `target_os` instead",
format!("target_os = \"{platform_sym}\""),
Applicability::MachineApplicable,
)
.emit();
}

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,
}
}
MetaItemKind::List(mis) => {
for mi in mis.iter() {
if mi.meta_item_or_bool().is_none() {
@@ -245,3 +370,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,8 +1,10 @@
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};

@@ -16,6 +18,22 @@ pub(crate) enum UnsupportedLiteralReason {
DeprecatedKvPair,
}

#[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 {
@@ -386,6 +404,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 {
@@ -432,6 +464,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 {
8 changes: 0 additions & 8 deletions compiler/rustc_codegen_ssa/messages.ftl
Original file line number Diff line number Diff line change
@@ -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}
@@ -391,8 +385,6 @@ codegen_ssa_unknown_atomic_ordering = unknown ordering in atomic intrinsic

codegen_ssa_unknown_reuse_kind = unknown cgu-reuse-kind `{$kind}` specified

codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}`

codegen_ssa_unsupported_instruction_set = target does not support `#[instruction_set]`

codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target
Loading
Loading