mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 22:41:50 +00:00
Auto merge of #117377 - dtolnay:deprecatedsince, r=cjgillot
Store #[deprecated] attribute's `since` value in parsed form This PR implements the first followup bullet listed in https://github.com/rust-lang/rust/pull/117148#issue-1960240108. We centralize error handling to the attribute parsing code in `compiler/rustc_attr/src/builtin.rs`, and thereby remove some awkward error codepaths from later phases of compilation that had to make sense of these #\[deprecated\] attributes, namely `compiler/rustc_passes/src/stability.rs` and `compiler/rustc_middle/src/middle/stability.rs`.
This commit is contained in:
commit
22b27120b9
@ -139,7 +139,7 @@ pub enum StabilityLevel {
|
||||
/// `#[stable]`
|
||||
Stable {
|
||||
/// Rust release which stabilized this feature.
|
||||
since: Since,
|
||||
since: StableSince,
|
||||
/// Is this item allowed to be referred to on stable, despite being contained in unstable
|
||||
/// modules?
|
||||
allowed_through_unstable_modules: bool,
|
||||
@ -149,7 +149,7 @@ pub enum StabilityLevel {
|
||||
/// Rust release in which a feature is stabilized.
|
||||
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
|
||||
#[derive(HashStable_Generic)]
|
||||
pub enum Since {
|
||||
pub enum StableSince {
|
||||
Version(RustcVersion),
|
||||
/// Stabilized in the upcoming version, whatever number that is.
|
||||
Current,
|
||||
@ -378,16 +378,16 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
|
||||
|
||||
let since = if let Some(since) = since {
|
||||
if since.as_str() == VERSION_PLACEHOLDER {
|
||||
Since::Current
|
||||
StableSince::Current
|
||||
} else if let Some(version) = parse_version(since) {
|
||||
Since::Version(version)
|
||||
StableSince::Version(version)
|
||||
} else {
|
||||
sess.emit_err(session_diagnostics::InvalidSince { span: attr.span });
|
||||
Since::Err
|
||||
StableSince::Err
|
||||
}
|
||||
} else {
|
||||
sess.emit_err(session_diagnostics::MissingSince { span: attr.span });
|
||||
Since::Err
|
||||
StableSince::Err
|
||||
};
|
||||
|
||||
match feature {
|
||||
@ -720,17 +720,49 @@ pub fn eval_condition(
|
||||
|
||||
#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)]
|
||||
pub struct Deprecation {
|
||||
pub since: Option<Symbol>,
|
||||
pub since: 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>,
|
||||
}
|
||||
|
||||
/// Whether to treat the since attribute as being a Rust version identifier
|
||||
/// (rather than an opaque string).
|
||||
pub is_since_rustc_version: bool,
|
||||
/// 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. Deprecation versions outside the standard
|
||||
/// library are allowed to be arbitrary strings, for better or worse.
|
||||
NonStandard(Symbol),
|
||||
/// Deprecation version is unspecified but optional.
|
||||
Unspecified,
|
||||
/// Failed to parse a deprecation version, or the deprecation version is
|
||||
/// unspecified and required. An error has already been emitted.
|
||||
Err,
|
||||
}
|
||||
|
||||
impl Deprecation {
|
||||
/// Whether an item marked with #[deprecated(since = "X")] is currently
|
||||
/// deprecated (i.e., whether X is not greater than the current rustc
|
||||
/// version).
|
||||
pub fn is_in_effect(&self) -> bool {
|
||||
match self.since {
|
||||
DeprecatedSince::RustcVersion(since) => since <= RustcVersion::CURRENT,
|
||||
DeprecatedSince::Future => false,
|
||||
// The `since` field doesn't have semantic purpose without `#![staged_api]`.
|
||||
DeprecatedSince::NonStandard(_) => true,
|
||||
// Assume deprecation is in effect if "since" field is absent or invalid.
|
||||
DeprecatedSince::Unspecified | DeprecatedSince::Err => true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_since_rustc_version(&self) -> bool {
|
||||
matches!(self.since, DeprecatedSince::RustcVersion(_))
|
||||
}
|
||||
}
|
||||
|
||||
/// Finds the deprecation attribute. `None` if none exists.
|
||||
@ -839,22 +871,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" {
|
||||
DeprecatedSince::Future
|
||||
} else if !is_rustc {
|
||||
DeprecatedSince::NonStandard(since)
|
||||
} else if let Some(version) = parse_version(since) {
|
||||
DeprecatedSince::RustcVersion(version)
|
||||
} else {
|
||||
sess.emit_err(session_diagnostics::InvalidSince { span: attr.span });
|
||||
DeprecatedSince::Err
|
||||
}
|
||||
} else if is_rustc {
|
||||
sess.emit_err(session_diagnostics::MissingSince { span: attr.span });
|
||||
DeprecatedSince::Err
|
||||
} else {
|
||||
DeprecatedSince::Unspecified
|
||||
};
|
||||
|
||||
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
|
||||
|
@ -5,7 +5,9 @@ pub use self::StabilityLevel::*;
|
||||
|
||||
use crate::ty::{self, TyCtxt};
|
||||
use rustc_ast::NodeId;
|
||||
use rustc_attr::{self as attr, ConstStability, DefaultBodyStability, Deprecation, Stability};
|
||||
use rustc_attr::{
|
||||
self as attr, ConstStability, DefaultBodyStability, DeprecatedSince, Deprecation, Stability,
|
||||
};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{Applicability, Diagnostic};
|
||||
use rustc_feature::GateIssue;
|
||||
@ -16,7 +18,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE};
|
||||
use rustc_session::lint::{BuiltinLintDiagnostics, Level, Lint, LintBuffer};
|
||||
use rustc_session::parse::feature_err_issue;
|
||||
use rustc_session::{RustcVersion, Session};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::Span;
|
||||
use std::num::NonZeroU32;
|
||||
@ -123,41 +125,6 @@ pub fn report_unstable(
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks whether an item marked with `deprecated(since="X")` is currently
|
||||
/// deprecated (i.e., whether X is not greater than the current rustc version).
|
||||
pub fn deprecation_in_effect(depr: &Deprecation) -> bool {
|
||||
let is_since_rustc_version = depr.is_since_rustc_version;
|
||||
let since = depr.since.as_ref().map(Symbol::as_str);
|
||||
|
||||
if !is_since_rustc_version {
|
||||
// The `since` field doesn't have semantic purpose without `#![staged_api]`.
|
||||
return true;
|
||||
}
|
||||
|
||||
if let Some(since) = since {
|
||||
if since == "TBD" {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We ignore non-integer components of the version (e.g., "nightly").
|
||||
let since: Vec<u16> =
|
||||
since.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect();
|
||||
|
||||
// We simply treat invalid `since` attributes as relating to a previous
|
||||
// Rust version, thus always displaying the warning.
|
||||
if since.len() != 3 {
|
||||
return true;
|
||||
}
|
||||
|
||||
let rustc = RustcVersion::CURRENT;
|
||||
return since.as_slice() <= &[rustc.major, rustc.minor, rustc.patch];
|
||||
};
|
||||
|
||||
// Assume deprecation is in effect if "since" field is missing
|
||||
// or if we can't determine the current Rust version.
|
||||
true
|
||||
}
|
||||
|
||||
pub fn deprecation_suggestion(
|
||||
diag: &mut Diagnostic,
|
||||
kind: &str,
|
||||
@ -180,7 +147,7 @@ fn deprecation_lint(is_in_effect: bool) -> &'static Lint {
|
||||
|
||||
fn deprecation_message(
|
||||
is_in_effect: bool,
|
||||
since: Option<Symbol>,
|
||||
since: DeprecatedSince,
|
||||
note: Option<Symbol>,
|
||||
kind: &str,
|
||||
path: &str,
|
||||
@ -188,17 +155,18 @@ fn deprecation_message(
|
||||
let message = if is_in_effect {
|
||||
format!("use of deprecated {kind} `{path}`")
|
||||
} else {
|
||||
let since = since.as_ref().map(Symbol::as_str);
|
||||
|
||||
if since == Some("TBD") {
|
||||
format!("use of {kind} `{path}` that will be deprecated in a future Rust version")
|
||||
} else {
|
||||
format!(
|
||||
"use of {} `{}` that will be deprecated in future version {}",
|
||||
kind,
|
||||
path,
|
||||
since.unwrap()
|
||||
)
|
||||
match since {
|
||||
DeprecatedSince::RustcVersion(version) => format!(
|
||||
"use of {kind} `{path}` that will be deprecated in future version {version}"
|
||||
),
|
||||
DeprecatedSince::Future => {
|
||||
format!("use of {kind} `{path}` that will be deprecated in a future Rust version")
|
||||
}
|
||||
DeprecatedSince::NonStandard(_)
|
||||
| DeprecatedSince::Unspecified
|
||||
| DeprecatedSince::Err => {
|
||||
unreachable!("this deprecation is always in effect; {since:?}")
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -213,7 +181,7 @@ pub fn deprecation_message_and_lint(
|
||||
kind: &str,
|
||||
path: &str,
|
||||
) -> (String, &'static Lint) {
|
||||
let is_in_effect = deprecation_in_effect(depr);
|
||||
let is_in_effect = depr.is_in_effect();
|
||||
(
|
||||
deprecation_message(is_in_effect, depr.since, depr.note, kind, path),
|
||||
deprecation_lint(is_in_effect),
|
||||
@ -381,11 +349,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
// With #![staged_api], we want to emit down the whole
|
||||
// hierarchy.
|
||||
let depr_attr = &depr_entry.attr;
|
||||
if !skip || depr_attr.is_since_rustc_version {
|
||||
if !skip || depr_attr.is_since_rustc_version() {
|
||||
// Calculating message for lint involves calling `self.def_path_str`.
|
||||
// Which by default to calculate visible path will invoke expensive `visible_parent_map` query.
|
||||
// So we skip message calculation altogether, if lint is allowed.
|
||||
let is_in_effect = deprecation_in_effect(depr_attr);
|
||||
let is_in_effect = depr_attr.is_in_effect();
|
||||
let lint = deprecation_lint(is_in_effect);
|
||||
if self.lint_level_at_node(lint, id).0 != Level::Allow {
|
||||
let def_path = with_no_trimmed_paths!(self.def_path_str(def_id));
|
||||
|
@ -396,11 +396,6 @@ passes_invalid_attr_at_crate_level =
|
||||
passes_invalid_attr_at_crate_level_item =
|
||||
the inner attribute doesn't annotate this {$kind}
|
||||
|
||||
passes_invalid_deprecation_version =
|
||||
invalid deprecation version found
|
||||
.label = invalid deprecation version
|
||||
.item = the stability attribute annotates this item
|
||||
|
||||
passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]` argument
|
||||
|
||||
passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments
|
||||
|
@ -1524,16 +1524,6 @@ pub struct CannotStabilizeDeprecated {
|
||||
pub item_sp: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_invalid_deprecation_version)]
|
||||
pub struct InvalidDeprecationVersion {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[label(passes_item)]
|
||||
pub item_sp: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_missing_stability_attr)]
|
||||
pub struct MissingStabilityAttr<'a> {
|
||||
|
@ -3,8 +3,8 @@
|
||||
|
||||
use crate::errors;
|
||||
use rustc_attr::{
|
||||
self as attr, ConstStability, Since, Stability, StabilityLevel, Unstable, UnstableReason,
|
||||
VERSION_PLACEHOLDER,
|
||||
self as attr, ConstStability, DeprecatedSince, Stability, StabilityLevel, StableSince,
|
||||
Unstable, UnstableReason, VERSION_PLACEHOLDER,
|
||||
};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
||||
use rustc_hir as hir;
|
||||
@ -24,8 +24,6 @@ use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::iter;
|
||||
use std::mem::replace;
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
@ -198,10 +196,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((rustc_attr::Deprecation { is_since_rustc_version: true, .. }, span)) = &depr {
|
||||
if stab.is_none() {
|
||||
self.tcx.sess.emit_err(errors::DeprecatedAttribute { span: *span });
|
||||
}
|
||||
if let Some((depr, span)) = &depr && depr.is_since_rustc_version() && stab.is_none() {
|
||||
self.tcx.sess.emit_err(errors::DeprecatedAttribute { span: *span });
|
||||
}
|
||||
|
||||
if let Some((body_stab, _span)) = body_stab {
|
||||
@ -223,44 +219,23 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||
|
||||
// Check if deprecated_since < stable_since. If it is,
|
||||
// this is *almost surely* an accident.
|
||||
if let (&Some(dep_since), &attr::Stable { since: stab_since, .. }) =
|
||||
(&depr.as_ref().and_then(|(d, _)| d.since), &stab.level)
|
||||
if let (
|
||||
&Some(DeprecatedSince::RustcVersion(dep_since)),
|
||||
&attr::Stable { since: stab_since, .. },
|
||||
) = (&depr.as_ref().map(|(d, _)| d.since), &stab.level)
|
||||
{
|
||||
match stab_since {
|
||||
Since::Current => {
|
||||
StableSince::Current => {
|
||||
self.tcx.sess.emit_err(errors::CannotStabilizeDeprecated { span, item_sp });
|
||||
}
|
||||
Since::Version(stab_since) => {
|
||||
// Explicit version of iter::order::lt to handle parse errors properly
|
||||
for (dep_v, stab_v) in iter::zip(
|
||||
dep_since.as_str().split('.'),
|
||||
[stab_since.major, stab_since.minor, stab_since.patch],
|
||||
) {
|
||||
match dep_v.parse::<u64>() {
|
||||
Ok(dep_vp) => match dep_vp.cmp(&u64::from(stab_v)) {
|
||||
Ordering::Less => {
|
||||
self.tcx.sess.emit_err(errors::CannotStabilizeDeprecated {
|
||||
span,
|
||||
item_sp,
|
||||
});
|
||||
break;
|
||||
}
|
||||
Ordering::Equal => continue,
|
||||
Ordering::Greater => break,
|
||||
},
|
||||
Err(_) => {
|
||||
if dep_v != "TBD" {
|
||||
self.tcx.sess.emit_err(errors::InvalidDeprecationVersion {
|
||||
span,
|
||||
item_sp,
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
StableSince::Version(stab_since) => {
|
||||
if dep_since < stab_since {
|
||||
self.tcx
|
||||
.sess
|
||||
.emit_err(errors::CannotStabilizeDeprecated { span, item_sp });
|
||||
}
|
||||
}
|
||||
Since::Err => {
|
||||
StableSince::Err => {
|
||||
// An error already reported. Assume the unparseable stabilization
|
||||
// version is older than the deprecation version.
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ use thin_vec::ThinVec;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_attr::{ConstStability, Deprecation, Since, Stability, StabilityLevel};
|
||||
use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel, StableSince};
|
||||
use rustc_const_eval::const_eval::is_unstable_const_fn;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_hir as hir;
|
||||
@ -585,14 +585,14 @@ impl Item {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn stable_since(&self, tcx: TyCtxt<'_>) -> Option<Since> {
|
||||
pub(crate) fn stable_since(&self, tcx: TyCtxt<'_>) -> Option<StableSince> {
|
||||
match self.stability(tcx)?.level {
|
||||
StabilityLevel::Stable { since, .. } => Some(since),
|
||||
StabilityLevel::Unstable { .. } => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn const_stable_since(&self, tcx: TyCtxt<'_>) -> Option<Since> {
|
||||
pub(crate) fn const_stable_since(&self, tcx: TyCtxt<'_>) -> Option<StableSince> {
|
||||
match self.const_stability(tcx)?.level {
|
||||
StabilityLevel::Stable { since, .. } => Some(since),
|
||||
StabilityLevel::Unstable { .. } => None,
|
||||
|
@ -48,12 +48,11 @@ use std::str;
|
||||
use std::string::ToString;
|
||||
|
||||
use askama::Template;
|
||||
use rustc_attr::{ConstStability, Deprecation, Since, StabilityLevel};
|
||||
use rustc_attr::{ConstStability, DeprecatedSince, Deprecation, StabilityLevel, StableSince};
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_hir::def_id::{DefId, DefIdSet};
|
||||
use rustc_hir::Mutability;
|
||||
use rustc_middle::middle::stability;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_session::RustcVersion;
|
||||
use rustc_span::{
|
||||
@ -617,24 +616,22 @@ fn short_item_info(
|
||||
) -> Vec<ShortItemInfo> {
|
||||
let mut extra_info = vec![];
|
||||
|
||||
if let Some(depr @ Deprecation { note, since, is_since_rustc_version: _, 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
|
||||
// the future-deprecation messages for rustc versions.
|
||||
let mut message = if let Some(since) = since {
|
||||
let since = since.as_str();
|
||||
if !stability::deprecation_in_effect(&depr) {
|
||||
if since == "TBD" {
|
||||
String::from("Deprecating in a future Rust version")
|
||||
let mut message = match since {
|
||||
DeprecatedSince::RustcVersion(version) => {
|
||||
if depr.is_in_effect() {
|
||||
format!("Deprecated since {version}")
|
||||
} else {
|
||||
format!("Deprecating in {}", Escape(since))
|
||||
format!("Deprecating in {version}")
|
||||
}
|
||||
} else {
|
||||
format!("Deprecated since {}", Escape(since))
|
||||
}
|
||||
} else {
|
||||
String::from("Deprecated")
|
||||
DeprecatedSince::Future => String::from("Deprecating in a future Rust version"),
|
||||
DeprecatedSince::NonStandard(since) => {
|
||||
format!("Deprecated since {}", Escape(since.as_str()))
|
||||
}
|
||||
DeprecatedSince::Unspecified | DeprecatedSince::Err => String::from("Deprecated"),
|
||||
};
|
||||
|
||||
if let Some(note) = note {
|
||||
@ -912,10 +909,10 @@ fn assoc_method(
|
||||
/// consequence of the above rules.
|
||||
fn render_stability_since_raw_with_extra(
|
||||
w: &mut Buffer,
|
||||
ver: Option<Since>,
|
||||
ver: Option<StableSince>,
|
||||
const_stability: Option<ConstStability>,
|
||||
containing_ver: Option<Since>,
|
||||
containing_const_ver: Option<Since>,
|
||||
containing_ver: Option<StableSince>,
|
||||
containing_const_ver: Option<StableSince>,
|
||||
extra_class: &str,
|
||||
) -> bool {
|
||||
let stable_version = if ver != containing_ver && let Some(ver) = &ver {
|
||||
@ -977,21 +974,21 @@ fn render_stability_since_raw_with_extra(
|
||||
!stability.is_empty()
|
||||
}
|
||||
|
||||
fn since_to_string(since: &Since) -> Option<String> {
|
||||
fn since_to_string(since: &StableSince) -> Option<String> {
|
||||
match since {
|
||||
Since::Version(since) => Some(since.to_string()),
|
||||
Since::Current => Some(RustcVersion::CURRENT.to_string()),
|
||||
Since::Err => None,
|
||||
StableSince::Version(since) => Some(since.to_string()),
|
||||
StableSince::Current => Some(RustcVersion::CURRENT.to_string()),
|
||||
StableSince::Err => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn render_stability_since_raw(
|
||||
w: &mut Buffer,
|
||||
ver: Option<Since>,
|
||||
ver: Option<StableSince>,
|
||||
const_stability: Option<ConstStability>,
|
||||
containing_ver: Option<Since>,
|
||||
containing_const_ver: Option<Since>,
|
||||
containing_ver: Option<StableSince>,
|
||||
containing_const_ver: Option<StableSince>,
|
||||
) -> bool {
|
||||
render_stability_since_raw_with_extra(
|
||||
w,
|
||||
|
@ -6,7 +6,6 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def::CtorKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::middle::stability;
|
||||
use rustc_middle::query::Key;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
@ -591,11 +590,7 @@ fn extra_info_tags<'a, 'tcx: 'a>(
|
||||
|
||||
// The trailing space after each tag is to space it properly against the rest of the docs.
|
||||
if let Some(depr) = &item.deprecation(tcx) {
|
||||
let message = if stability::deprecation_in_effect(depr) {
|
||||
"Deprecated"
|
||||
} else {
|
||||
"Deprecation planned"
|
||||
};
|
||||
let message = if depr.is_in_effect() { "Deprecated" } else { "Deprecation planned" };
|
||||
write!(f, "{}", tag_html("deprecated", "", message))?;
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
use std::fmt;
|
||||
|
||||
use rustc_ast::ast;
|
||||
use rustc_attr::DeprecatedSince;
|
||||
use rustc_hir::{def::CtorKind, def::DefKind, def_id::DefId};
|
||||
use rustc_metadata::rendered_const;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
@ -138,9 +139,14 @@ where
|
||||
}
|
||||
|
||||
pub(crate) fn from_deprecation(deprecation: rustc_attr::Deprecation) -> Deprecation {
|
||||
#[rustfmt::skip]
|
||||
let rustc_attr::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ } = deprecation;
|
||||
Deprecation { since: since.map(|s| s.to_string()), note: note.map(|s| s.to_string()) }
|
||||
let rustc_attr::Deprecation { since, note, suggestion: _ } = deprecation;
|
||||
let since = match since {
|
||||
DeprecatedSince::RustcVersion(version) => Some(version.to_string()),
|
||||
DeprecatedSince::Future => Some("TBD".to_owned()),
|
||||
DeprecatedSince::NonStandard(since) => Some(since.to_string()),
|
||||
DeprecatedSince::Unspecified | DeprecatedSince::Err => None,
|
||||
};
|
||||
Deprecation { since, note: note.map(|s| s.to_string()) }
|
||||
}
|
||||
|
||||
impl FromWithTcx<clean::GenericArgs> for GenericArgs {
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
use crate::msrvs::Msrv;
|
||||
use hir::LangItem;
|
||||
use rustc_attr::Since;
|
||||
use rustc_attr::StableSince;
|
||||
use rustc_const_eval::transform::check_consts::ConstCx;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
@ -372,9 +372,9 @@ fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
|
||||
// as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.
|
||||
|
||||
let const_stab_rust_version = match since {
|
||||
Since::Version(version) => version,
|
||||
Since::Current => rustc_session::RustcVersion::CURRENT,
|
||||
Since::Err => return false,
|
||||
StableSince::Version(version) => version,
|
||||
StableSince::Current => rustc_session::RustcVersion::CURRENT,
|
||||
StableSince::Err => return false,
|
||||
};
|
||||
|
||||
msrv.meets(RustcVersion::new(
|
||||
|
@ -19,6 +19,7 @@ mod bogus_attribute_types_2 {
|
||||
|
||||
#[stable(feature = "a", since = "3.3.3")]
|
||||
#[deprecated] //~ ERROR missing 'since'
|
||||
//~^ ERROR missing 'note'
|
||||
fn f5() { }
|
||||
|
||||
#[stable(feature = "a", since = "3.3.3")]
|
||||
|
@ -28,12 +28,19 @@ error[E0542]: missing 'since'
|
||||
LL | #[deprecated]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error[E0543]: missing 'note'
|
||||
--> $DIR/stability-attribute-sanity-4.rs:21:5
|
||||
|
|
||||
LL | #[deprecated]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error[E0542]: missing 'since'
|
||||
--> $DIR/stability-attribute-sanity-4.rs:25:5
|
||||
--> $DIR/stability-attribute-sanity-4.rs:26:5
|
||||
|
|
||||
LL | #[deprecated = "a"]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0542`.
|
||||
Some errors have detailed explanations: E0542, E0543.
|
||||
For more information about an error, try `rustc --explain E0542`.
|
||||
|
@ -41,7 +41,7 @@ mod missing_version {
|
||||
fn f2() { }
|
||||
|
||||
#[stable(feature = "a", since = "4.4.4")]
|
||||
#[deprecated(since = "a")] //~ ERROR missing 'note' [E0543]
|
||||
#[deprecated(since = "5.5.5")] //~ ERROR missing 'note' [E0543]
|
||||
fn f3() { }
|
||||
}
|
||||
|
||||
@ -58,18 +58,17 @@ fn multiple2() { }
|
||||
fn multiple3() { }
|
||||
|
||||
#[stable(feature = "e", since = "b")] //~ ERROR 'since' must be a Rust version number, such as "1.31.0"
|
||||
#[deprecated(since = "b", note = "text")]
|
||||
#[deprecated(since = "b", note = "text")] //~ ERROR multiple `deprecated` attributes
|
||||
#[deprecated(since = "5.5.5", note = "text")]
|
||||
#[deprecated(since = "5.5.5", note = "text")] //~ ERROR multiple `deprecated` attributes
|
||||
#[rustc_const_unstable(feature = "c", issue = "none")]
|
||||
#[rustc_const_unstable(feature = "d", issue = "none")] //~ ERROR multiple stability levels
|
||||
pub const fn multiple4() { }
|
||||
|
||||
#[stable(feature = "a", since = "1.0.0")] //~ ERROR invalid deprecation version found
|
||||
//~^ ERROR feature `a` is declared stable since 1.0.0
|
||||
#[deprecated(since = "invalid", note = "text")]
|
||||
#[stable(feature = "a", since = "1.0.0")] //~ ERROR feature `a` is declared stable since 1.0.0
|
||||
#[deprecated(since = "invalid", note = "text")] //~ ERROR 'since' must be a Rust version number, such as "1.31.0"
|
||||
fn invalid_deprecation_version() {}
|
||||
|
||||
#[deprecated(since = "a", note = "text")]
|
||||
#[deprecated(since = "5.5.5", note = "text")]
|
||||
fn deprecated_without_unstable_or_stable() { }
|
||||
//~^^ ERROR deprecated attribute must be paired with either stable or unstable attribute
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
error: multiple `deprecated` attributes
|
||||
--> $DIR/stability-attribute-sanity.rs:62:1
|
||||
|
|
||||
LL | #[deprecated(since = "b", note = "text")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
|
||||
LL | #[deprecated(since = "5.5.5", note = "text")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
|
||||
|
|
||||
note: attribute also specified here
|
||||
--> $DIR/stability-attribute-sanity.rs:61:1
|
||||
|
|
||||
LL | #[deprecated(since = "b", note = "text")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[deprecated(since = "5.5.5", note = "text")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0541]: unknown meta item 'reason'
|
||||
--> $DIR/stability-attribute-sanity.rs:8:46
|
||||
@ -73,8 +73,8 @@ LL | #[deprecated(note = "a")]
|
||||
error[E0543]: missing 'note'
|
||||
--> $DIR/stability-attribute-sanity.rs:44:5
|
||||
|
|
||||
LL | #[deprecated(since = "a")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[deprecated(since = "5.5.5")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0544]: multiple stability levels
|
||||
--> $DIR/stability-attribute-sanity.rs:49:1
|
||||
@ -106,20 +106,17 @@ error[E0544]: multiple stability levels
|
||||
LL | #[rustc_const_unstable(feature = "d", issue = "none")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: invalid deprecation version found
|
||||
--> $DIR/stability-attribute-sanity.rs:67:1
|
||||
error: 'since' must be a Rust version number, such as "1.31.0"
|
||||
--> $DIR/stability-attribute-sanity.rs:68:1
|
||||
|
|
||||
LL | #[stable(feature = "a", since = "1.0.0")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid deprecation version
|
||||
...
|
||||
LL | fn invalid_deprecation_version() {}
|
||||
| ----------------------------------- the stability attribute annotates this item
|
||||
LL | #[deprecated(since = "invalid", note = "text")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0549]: deprecated attribute must be paired with either stable or unstable attribute
|
||||
--> $DIR/stability-attribute-sanity.rs:72:1
|
||||
--> $DIR/stability-attribute-sanity.rs:71:1
|
||||
|
|
||||
LL | #[deprecated(since = "a", note = "text")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[deprecated(since = "5.5.5", note = "text")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0711]: feature `a` is declared stable since 1.0.0, but was previously declared stable since 4.4.4
|
||||
--> $DIR/stability-attribute-sanity.rs:67:1
|
||||
|
Loading…
Reference in New Issue
Block a user