diff options
| author | David Tolnay <dtolnay@gmail.com> | 2023-10-26 10:14:29 -0700 |
|---|---|---|
| committer | David Tolnay <dtolnay@gmail.com> | 2023-10-29 22:42:32 -0700 |
| commit | 2fe7d17bd9aabe3948b8693c2a3d4841ce9fbd14 (patch) | |
| tree | c8006b654e380b47fdea85fea88f84cb3e9b8d37 /compiler/rustc_attr/src | |
| parent | 5c7cf837395db7221bd1061eee230fd27f81e6ad (diff) | |
| download | rust-2fe7d17bd9aabe3948b8693c2a3d4841ce9fbd14.tar.gz rust-2fe7d17bd9aabe3948b8693c2a3d4841ce9fbd14.zip | |
Store version of `deprecated` attribute in structured form
Diffstat (limited to 'compiler/rustc_attr/src')
| -rw-r--r-- | compiler/rustc_attr/src/builtin.rs | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 592c9ff115b..62709ef4db9 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -13,6 +13,7 @@ use rustc_session::parse::{feature_err, ParseSess}; use rustc_session::{RustcVersion, Session}; use rustc_span::hygiene::Transparency; use rustc_span::{symbol::sym, symbol::Symbol, Span}; +use std::fmt::{self, Display}; use std::num::NonZeroU32; use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause}; @@ -720,17 +721,37 @@ pub fn eval_condition( #[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)] pub struct Deprecation { - pub since: Option<Symbol>, + pub since: Option<DeprecatedSince>, /// The note to issue a reason. pub note: Option<Symbol>, /// A text snippet used to completely replace any use of the deprecated item in an expression. /// /// This is currently unstable. pub suggestion: Option<Symbol>, +} + +/// Release in which an API is deprecated. +#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)] +pub enum DeprecatedSince { + RustcVersion(RustcVersion), + /// Deprecated in the future ("to be determined"). + Future, + /// `feature(staged_api)` is off, or it's on but the deprecation version + /// cannot be parsed as a RustcVersion. In the latter case, an error has + /// already been emitted. In the former case, deprecation versions outside + /// the standard library are allowed to be arbitrary strings, for better or + /// worse. + Symbol(Symbol), +} - /// Whether to treat the since attribute as being a Rust version identifier - /// (rather than an opaque string). - pub is_since_rustc_version: bool, +impl Display for DeprecatedSince { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + DeprecatedSince::RustcVersion(since) => Display::fmt(since, formatter), + DeprecatedSince::Future => formatter.write_str("TBD"), + DeprecatedSince::Symbol(since) => Display::fmt(since, formatter), + } + } } /// Finds the deprecation attribute. `None` if none exists. @@ -839,22 +860,30 @@ pub fn find_deprecation( } } - if is_rustc { - if since.is_none() { - sess.emit_err(session_diagnostics::MissingSince { span: attr.span }); - continue; + let since = if let Some(since) = since { + if since.as_str() == "TBD" { + Some(DeprecatedSince::Future) + } else if !is_rustc { + Some(DeprecatedSince::Symbol(since)) + } else if let Some(version) = parse_version(since) { + Some(DeprecatedSince::RustcVersion(version)) + } else { + sess.emit_err(session_diagnostics::InvalidSince { span: attr.span }); + Some(DeprecatedSince::Symbol(since)) } + } else if is_rustc { + sess.emit_err(session_diagnostics::MissingSince { span: attr.span }); + continue; + } else { + None + }; - if note.is_none() { - sess.emit_err(session_diagnostics::MissingNote { span: attr.span }); - continue; - } + if is_rustc && note.is_none() { + sess.emit_err(session_diagnostics::MissingNote { span: attr.span }); + continue; } - depr = Some(( - Deprecation { since, note, suggestion, is_since_rustc_version: is_rustc }, - attr.span, - )); + depr = Some((Deprecation { since, note, suggestion }, attr.span)); } depr |
