Add a DeprecatedSince::Err variant for versions that fail to parse

This commit is contained in:
David Tolnay 2023-10-30 08:53:21 -07:00
parent 1e10fe9eb6
commit b106167673
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
4 changed files with 36 additions and 38 deletions

View File

@ -13,7 +13,6 @@
use rustc_session::{RustcVersion, Session}; use rustc_session::{RustcVersion, Session};
use rustc_span::hygiene::Transparency; use rustc_span::hygiene::Transparency;
use rustc_span::{symbol::sym, symbol::Symbol, Span}; use rustc_span::{symbol::sym, symbol::Symbol, Span};
use std::fmt::{self, Display};
use std::num::NonZeroU32; use std::num::NonZeroU32;
use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause}; use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause};
@ -736,12 +735,12 @@ pub enum DeprecatedSince {
RustcVersion(RustcVersion), RustcVersion(RustcVersion),
/// Deprecated in the future ("to be determined"). /// Deprecated in the future ("to be determined").
Future, Future,
/// `feature(staged_api)` is off, or it's on but the deprecation version /// `feature(staged_api)` is off. Deprecation versions outside the standard
/// cannot be parsed as a RustcVersion. In the latter case, an error has /// library are allowed to be arbitrary strings, for better or worse.
/// 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), Symbol(Symbol),
/// Failed to parse a deprecation version. An error has already been
/// emitted.
Err,
} }
impl Deprecation { impl Deprecation {
@ -754,18 +753,8 @@ pub fn is_in_effect(&self) -> bool {
Some(DeprecatedSince::Future) => false, Some(DeprecatedSince::Future) => false,
// The `since` field doesn't have semantic purpose without `#![staged_api]`. // The `since` field doesn't have semantic purpose without `#![staged_api]`.
Some(DeprecatedSince::Symbol(_)) => true, Some(DeprecatedSince::Symbol(_)) => true,
// Assume deprecation is in effect if "since" field is missing. // Assume deprecation is in effect if "since" field is absent or invalid.
None => true, None | Some(DeprecatedSince::Err) => true,
}
}
}
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),
} }
} }
} }
@ -885,7 +874,7 @@ pub fn find_deprecation(
Some(DeprecatedSince::RustcVersion(version)) Some(DeprecatedSince::RustcVersion(version))
} else { } else {
sess.emit_err(session_diagnostics::InvalidSince { span: attr.span }); sess.emit_err(session_diagnostics::InvalidSince { span: attr.span });
Some(DeprecatedSince::Symbol(since)) Some(DeprecatedSince::Err)
} }
} else if is_rustc { } else if is_rustc {
sess.emit_err(session_diagnostics::MissingSince { span: attr.span }); sess.emit_err(session_diagnostics::MissingSince { span: attr.span });

View File

@ -155,15 +155,16 @@ fn deprecation_message(
let message = if is_in_effect { let message = if is_in_effect {
format!("use of deprecated {kind} `{path}`") format!("use of deprecated {kind} `{path}`")
} else { } else {
if let Some(DeprecatedSince::Future) = since { match since {
format!("use of {kind} `{path}` that will be deprecated in a future Rust version") Some(DeprecatedSince::RustcVersion(version)) => format!(
} else { "use of {kind} `{path}` that will be deprecated in future version {version}"
format!( ),
"use of {} `{}` that will be deprecated in future version {}", Some(DeprecatedSince::Future) => {
kind, format!("use of {kind} `{path}` that will be deprecated in a future Rust version")
path, }
since.unwrap() Some(DeprecatedSince::Symbol(_)) | Some(DeprecatedSince::Err) | None => {
) unreachable!("this deprecation is always in effect; {since:?}")
}
} }
}; };

View File

@ -619,18 +619,19 @@ fn short_item_info(
if let Some(depr @ Deprecation { note, since, suggestion: _ }) = item.deprecation(cx.tcx()) { if let Some(depr @ Deprecation { note, since, suggestion: _ }) = item.deprecation(cx.tcx()) {
// We display deprecation messages for #[deprecated], but only display // We display deprecation messages for #[deprecated], but only display
// the future-deprecation messages for rustc versions. // the future-deprecation messages for rustc versions.
let mut message = if let Some(since) = since { let mut message = match since {
if !depr.is_in_effect() { Some(DeprecatedSince::RustcVersion(version)) => {
if let DeprecatedSince::Future = since { if depr.is_in_effect() {
String::from("Deprecating in a future Rust version") format!("Deprecated since {version}")
} else { } else {
format!("Deprecating in {}", Escape(&since.to_string())) format!("Deprecating in {version}")
} }
} else {
format!("Deprecated since {}", Escape(&since.to_string()))
} }
} else { Some(DeprecatedSince::Future) => String::from("Deprecating in a future Rust version"),
String::from("Deprecated") Some(DeprecatedSince::Symbol(since)) => {
format!("Deprecated since {}", Escape(since.as_str()))
}
Some(DeprecatedSince::Err) | None => String::from("Deprecated"),
}; };
if let Some(note) = note { if let Some(note) = note {

View File

@ -7,6 +7,7 @@
use std::fmt; use std::fmt;
use rustc_ast::ast; use rustc_ast::ast;
use rustc_attr::DeprecatedSince;
use rustc_hir::{def::CtorKind, def::DefKind, def_id::DefId}; use rustc_hir::{def::CtorKind, def::DefKind, def_id::DefId};
use rustc_metadata::rendered_const; use rustc_metadata::rendered_const;
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
@ -139,7 +140,13 @@ fn from_tcx(f: I, tcx: TyCtxt<'_>) -> Vec<U> {
pub(crate) fn from_deprecation(deprecation: rustc_attr::Deprecation) -> Deprecation { pub(crate) fn from_deprecation(deprecation: rustc_attr::Deprecation) -> Deprecation {
let rustc_attr::Deprecation { since, note, suggestion: _ } = deprecation; let rustc_attr::Deprecation { since, note, suggestion: _ } = deprecation;
Deprecation { since: since.map(|s| s.to_string()), note: note.map(|s| s.to_string()) } let since = match since {
Some(DeprecatedSince::RustcVersion(version)) => Some(version.to_string()),
Some(DeprecatedSince::Future) => Some("TBD".to_owned()),
Some(DeprecatedSince::Symbol(since)) => Some(since.to_string()),
Some(DeprecatedSince::Err) | None => None,
};
Deprecation { since, note: note.map(|s| s.to_string()) }
} }
impl FromWithTcx<clean::GenericArgs> for GenericArgs { impl FromWithTcx<clean::GenericArgs> for GenericArgs {