Migrate rustc_depr uses to use deprecation attribute
This should not be a change in behavior.
This commit is contained in:
parent
21a3d294dc
commit
8454ee89b2
7 changed files with 138 additions and 181 deletions
|
@ -129,7 +129,6 @@ pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Op
|
||||||
pub struct Stability {
|
pub struct Stability {
|
||||||
pub level: StabilityLevel,
|
pub level: StabilityLevel,
|
||||||
pub feature: Symbol,
|
pub feature: Symbol,
|
||||||
pub rustc_depr: Option<RustcDeprecation>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes.
|
/// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes.
|
||||||
|
@ -162,15 +161,6 @@ impl StabilityLevel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)]
|
|
||||||
#[derive(HashStable_Generic)]
|
|
||||||
pub struct RustcDeprecation {
|
|
||||||
pub since: Symbol,
|
|
||||||
pub reason: Symbol,
|
|
||||||
/// A text snippet used to completely replace any use of the deprecated item in an expression.
|
|
||||||
pub suggestion: Option<Symbol>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks if `attrs` contains an attribute like `#![feature(feature_name)]`.
|
/// Checks if `attrs` contains an attribute like `#![feature(feature_name)]`.
|
||||||
/// This will not perform any "sanity checks" on the form of the attributes.
|
/// This will not perform any "sanity checks" on the form of the attributes.
|
||||||
pub fn contains_feature_attr(attrs: &[Attribute], feature_name: Symbol) -> bool {
|
pub fn contains_feature_attr(attrs: &[Attribute], feature_name: Symbol) -> bool {
|
||||||
|
@ -204,7 +194,6 @@ where
|
||||||
use StabilityLevel::*;
|
use StabilityLevel::*;
|
||||||
|
|
||||||
let mut stab: Option<Stability> = None;
|
let mut stab: Option<Stability> = None;
|
||||||
let mut rustc_depr: Option<RustcDeprecation> = None;
|
|
||||||
let mut const_stab: Option<ConstStability> = None;
|
let mut const_stab: Option<ConstStability> = None;
|
||||||
let mut promotable = false;
|
let mut promotable = false;
|
||||||
let mut allow_const_fn_ptr = false;
|
let mut allow_const_fn_ptr = false;
|
||||||
|
@ -256,45 +245,6 @@ where
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! get_meta {
|
|
||||||
($($name:ident),+) => {
|
|
||||||
$(
|
|
||||||
let mut $name = None;
|
|
||||||
)+
|
|
||||||
for meta in metas {
|
|
||||||
if let Some(mi) = meta.meta_item() {
|
|
||||||
match mi.name_or_empty() {
|
|
||||||
$(
|
|
||||||
sym::$name => if !get(mi, &mut $name) { continue 'outer },
|
|
||||||
)+
|
|
||||||
_ => {
|
|
||||||
let expected = &[ $( stringify!($name) ),+ ];
|
|
||||||
handle_errors(
|
|
||||||
sess,
|
|
||||||
mi.span,
|
|
||||||
AttrError::UnknownMetaItem(
|
|
||||||
pprust::path_to_string(&mi.path),
|
|
||||||
expected,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
continue 'outer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
handle_errors(
|
|
||||||
sess,
|
|
||||||
meta.span(),
|
|
||||||
AttrError::UnsupportedLiteral(
|
|
||||||
"unsupported literal",
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
continue 'outer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let meta_name = meta.name_or_empty();
|
let meta_name = meta.name_or_empty();
|
||||||
match meta_name {
|
match meta_name {
|
||||||
sym::rustc_const_unstable | sym::unstable => {
|
sym::rustc_const_unstable | sym::unstable => {
|
||||||
|
@ -398,7 +348,7 @@ where
|
||||||
(Some(feature), reason, Some(_)) => {
|
(Some(feature), reason, Some(_)) => {
|
||||||
let level = Unstable { reason, issue: issue_num, is_soft };
|
let level = Unstable { reason, issue: issue_num, is_soft };
|
||||||
if sym::unstable == meta_name {
|
if sym::unstable == meta_name {
|
||||||
stab = Some(Stability { level, feature, rustc_depr: None });
|
stab = Some(Stability { level, feature });
|
||||||
} else {
|
} else {
|
||||||
const_stab = Some(ConstStability {
|
const_stab = Some(ConstStability {
|
||||||
level,
|
level,
|
||||||
|
@ -470,7 +420,7 @@ where
|
||||||
(Some(feature), Some(since)) => {
|
(Some(feature), Some(since)) => {
|
||||||
let level = Stable { since };
|
let level = Stable { since };
|
||||||
if sym::stable == meta_name {
|
if sym::stable == meta_name {
|
||||||
stab = Some(Stability { level, feature, rustc_depr: None });
|
stab = Some(Stability { level, feature });
|
||||||
} else {
|
} else {
|
||||||
const_stab = Some(ConstStability {
|
const_stab = Some(ConstStability {
|
||||||
level,
|
level,
|
||||||
|
|
|
@ -5,7 +5,7 @@ pub use self::StabilityLevel::*;
|
||||||
|
|
||||||
use crate::ty::{self, TyCtxt};
|
use crate::ty::{self, TyCtxt};
|
||||||
use rustc_ast::ast::CRATE_NODE_ID;
|
use rustc_ast::ast::CRATE_NODE_ID;
|
||||||
use rustc_attr::{self as attr, ConstStability, Deprecation, RustcDeprecation, Stability};
|
use rustc_attr::{self as attr, ConstStability, Deprecation, Stability};
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_errors::{Applicability, DiagnosticBuilder};
|
use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||||
use rustc_feature::GateIssue;
|
use rustc_feature::GateIssue;
|
||||||
|
@ -130,14 +130,26 @@ pub fn report_unstable(
|
||||||
|
|
||||||
/// Checks whether an item marked with `deprecated(since="X")` is currently
|
/// Checks whether an item marked with `deprecated(since="X")` is currently
|
||||||
/// deprecated (i.e., whether X is not greater than the current rustc version).
|
/// deprecated (i.e., whether X is not greater than the current rustc version).
|
||||||
pub fn deprecation_in_effect(since: &str) -> bool {
|
pub fn deprecation_in_effect(is_since_rustc_version: bool, since: Option<&str>) -> bool {
|
||||||
|
let since = if let Some(since) = since {
|
||||||
|
if is_since_rustc_version {
|
||||||
|
since
|
||||||
|
} else {
|
||||||
|
// We assume that the deprecation is in effect if it's not a
|
||||||
|
// rustc version.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If since attribute is not set, then we're definitely in effect.
|
||||||
|
return true;
|
||||||
|
};
|
||||||
fn parse_version(ver: &str) -> Vec<u32> {
|
fn parse_version(ver: &str) -> Vec<u32> {
|
||||||
// We ignore non-integer components of the version (e.g., "nightly").
|
// We ignore non-integer components of the version (e.g., "nightly").
|
||||||
ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect()
|
ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(rustc) = option_env!("CFG_RELEASE") {
|
if let Some(rustc) = option_env!("CFG_RELEASE") {
|
||||||
let since: Vec<u32> = parse_version(since);
|
let since: Vec<u32> = parse_version(&since);
|
||||||
let rustc: Vec<u32> = parse_version(rustc);
|
let rustc: Vec<u32> = parse_version(rustc);
|
||||||
// We simply treat invalid `since` attributes as relating to a previous
|
// We simply treat invalid `since` attributes as relating to a previous
|
||||||
// Rust version, thus always displaying the warning.
|
// Rust version, thus always displaying the warning.
|
||||||
|
@ -167,31 +179,27 @@ pub fn deprecation_suggestion(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deprecation_message_common(message: String, reason: Option<Symbol>) -> String {
|
|
||||||
match reason {
|
|
||||||
Some(reason) => format!("{}: {}", message, reason),
|
|
||||||
None => message,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deprecation_message(depr: &Deprecation, path: &str) -> (String, &'static Lint) {
|
pub fn deprecation_message(depr: &Deprecation, path: &str) -> (String, &'static Lint) {
|
||||||
let message = format!("use of deprecated item '{}'", path);
|
let (message, lint) = if deprecation_in_effect(
|
||||||
(deprecation_message_common(message, depr.note), DEPRECATED)
|
depr.is_since_rustc_version,
|
||||||
}
|
depr.since.map(Symbol::as_str).as_deref(),
|
||||||
|
) {
|
||||||
pub fn rustc_deprecation_message(depr: &RustcDeprecation, path: &str) -> (String, &'static Lint) {
|
|
||||||
let (message, lint) = if deprecation_in_effect(&depr.since.as_str()) {
|
|
||||||
(format!("use of deprecated item '{}'", path), DEPRECATED)
|
(format!("use of deprecated item '{}'", path), DEPRECATED)
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
format!(
|
format!(
|
||||||
"use of item '{}' that will be deprecated in future version {}",
|
"use of item '{}' that will be deprecated in future version {}",
|
||||||
path, depr.since
|
path,
|
||||||
|
depr.since.unwrap()
|
||||||
),
|
),
|
||||||
DEPRECATED_IN_FUTURE,
|
DEPRECATED_IN_FUTURE,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
(deprecation_message_common(message, Some(depr.reason)), lint)
|
let message = match depr.note {
|
||||||
|
Some(reason) => format!("{}: {}", message, reason),
|
||||||
|
None => message,
|
||||||
|
};
|
||||||
|
(message, lint)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn early_report_deprecation(
|
pub fn early_report_deprecation(
|
||||||
|
@ -289,10 +297,23 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
.lookup_deprecation_entry(parent_def_id.to_def_id())
|
.lookup_deprecation_entry(parent_def_id.to_def_id())
|
||||||
.map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
|
.map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
|
||||||
|
|
||||||
if !skip {
|
// #[deprecated] doesn't emit a notice if we're not on the
|
||||||
|
// topmost deprecation. For example, if a struct is deprecated,
|
||||||
|
// the use of a field won't be linted.
|
||||||
|
//
|
||||||
|
// #[rustc_deprecated] however wants to emit down the whole
|
||||||
|
// hierarchy.
|
||||||
|
if !skip || depr_entry.attr.is_since_rustc_version {
|
||||||
let (message, lint) =
|
let (message, lint) =
|
||||||
deprecation_message(&depr_entry.attr, &self.def_path_str(def_id));
|
deprecation_message(&depr_entry.attr, &self.def_path_str(def_id));
|
||||||
late_report_deprecation(self, &message, None, lint, span, id);
|
late_report_deprecation(
|
||||||
|
self,
|
||||||
|
&message,
|
||||||
|
depr_entry.attr.suggestion,
|
||||||
|
lint,
|
||||||
|
span,
|
||||||
|
id,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -310,16 +331,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
def_id, span, stability
|
def_id, span, stability
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(id) = id {
|
|
||||||
if let Some(stability) = stability {
|
|
||||||
if let Some(depr) = &stability.rustc_depr {
|
|
||||||
let (message, lint) =
|
|
||||||
rustc_deprecation_message(depr, &self.def_path_str(def_id));
|
|
||||||
late_report_deprecation(self, &message, depr.suggestion, lint, span, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only the cross-crate scenario matters when checking unstable APIs
|
// Only the cross-crate scenario matters when checking unstable APIs
|
||||||
let cross_crate = !def_id.is_local();
|
let cross_crate = !def_id.is_local();
|
||||||
if !cross_crate {
|
if !cross_crate {
|
||||||
|
|
|
@ -59,21 +59,51 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||||
) where
|
) where
|
||||||
F: FnOnce(&mut Self),
|
F: FnOnce(&mut Self),
|
||||||
{
|
{
|
||||||
|
debug!("annotate(id = {:?}, attrs = {:?})", hir_id, attrs);
|
||||||
|
let mut did_error = false;
|
||||||
if !self.tcx.features().staged_api {
|
if !self.tcx.features().staged_api {
|
||||||
self.forbid_staged_api_attrs(hir_id, attrs, item_sp, kind, visit_children);
|
did_error = self.forbid_staged_api_attrs(hir_id, attrs);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This crate explicitly wants staged API.
|
let depr = if did_error {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
attr::find_deprecation(&self.tcx.sess.parse_sess, attrs, item_sp)
|
||||||
|
};
|
||||||
|
let mut is_deprecated = false;
|
||||||
|
if let Some(depr) = &depr {
|
||||||
|
is_deprecated = true;
|
||||||
|
|
||||||
debug!("annotate(id = {:?}, attrs = {:?})", hir_id, attrs);
|
if kind == AnnotationKind::Prohibited {
|
||||||
if let Some(..) = attr::find_deprecation(&self.tcx.sess.parse_sess, attrs, item_sp) {
|
self.tcx.sess.span_err(item_sp, "This deprecation annotation is useless");
|
||||||
|
}
|
||||||
|
|
||||||
|
// `Deprecation` is just two pointers, no need to intern it
|
||||||
|
let depr_entry = DeprecationEntry::local(depr.clone(), hir_id);
|
||||||
|
self.index.depr_map.insert(hir_id, depr_entry);
|
||||||
|
} else if let Some(parent_depr) = self.parent_depr.clone() {
|
||||||
|
is_deprecated = true;
|
||||||
|
info!("tagging child {:?} as deprecated from parent", hir_id);
|
||||||
|
self.index.depr_map.insert(hir_id, parent_depr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.tcx.features().staged_api {
|
||||||
|
if let Some(..) = attrs.iter().find(|a| a.check_name(sym::deprecated)) {
|
||||||
self.tcx.sess.span_err(
|
self.tcx.sess.span_err(
|
||||||
item_sp,
|
item_sp,
|
||||||
"`#[deprecated]` cannot be used in staged API; \
|
"`#[deprecated]` cannot be used in staged API; \
|
||||||
use `#[rustc_deprecated]` instead",
|
use `#[rustc_deprecated]` instead",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
self.recurse_with_stability_attrs(
|
||||||
|
depr.map(|d| DeprecationEntry::local(d, hir_id)),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
visit_children,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let (stab, const_stab) = attr::find_stability(&self.tcx.sess.parse_sess, attrs, item_sp);
|
let (stab, const_stab) = attr::find_stability(&self.tcx.sess.parse_sess, attrs, item_sp);
|
||||||
|
|
||||||
|
@ -92,33 +122,34 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let stab = stab.map(|mut stab| {
|
if depr.as_ref().map_or(false, |d| d.is_since_rustc_version) {
|
||||||
|
if stab.is_none() {
|
||||||
|
struct_span_err!(
|
||||||
|
self.tcx.sess,
|
||||||
|
item_sp,
|
||||||
|
E0549,
|
||||||
|
"rustc_deprecated attribute must be paired with \
|
||||||
|
either stable or unstable attribute"
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let stab = stab.map(|stab| {
|
||||||
// Error if prohibited, or can't inherit anything from a container.
|
// Error if prohibited, or can't inherit anything from a container.
|
||||||
if kind == AnnotationKind::Prohibited
|
if kind == AnnotationKind::Prohibited
|
||||||
|| (kind == AnnotationKind::Container
|
|| (kind == AnnotationKind::Container && stab.level.is_stable() && is_deprecated)
|
||||||
&& stab.level.is_stable()
|
|
||||||
&& stab.rustc_depr.is_none())
|
|
||||||
{
|
{
|
||||||
self.tcx.sess.span_err(item_sp, "This stability annotation is useless");
|
self.tcx.sess.span_err(item_sp, "This stability annotation is useless");
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("annotate: found {:?}", stab);
|
debug!("annotate: found {:?}", stab);
|
||||||
// If parent is deprecated and we're not, inherit this by merging
|
|
||||||
// deprecated_since and its reason.
|
|
||||||
if let Some(parent_stab) = self.parent_stab {
|
|
||||||
if parent_stab.rustc_depr.is_some() && stab.rustc_depr.is_none() {
|
|
||||||
stab.rustc_depr = parent_stab.rustc_depr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let stab = self.tcx.intern_stability(stab);
|
let stab = self.tcx.intern_stability(stab);
|
||||||
|
|
||||||
// Check if deprecated_since < stable_since. If it is,
|
// Check if deprecated_since < stable_since. If it is,
|
||||||
// this is *almost surely* an accident.
|
// this is *almost surely* an accident.
|
||||||
if let (
|
if let (&Some(dep_since), &attr::Stable { since: stab_since }) =
|
||||||
&Some(attr::RustcDeprecation { since: dep_since, .. }),
|
(&depr.as_ref().and_then(|d| d.since), &stab.level)
|
||||||
&attr::Stable { since: stab_since },
|
|
||||||
) = (&stab.rustc_depr, &stab.level)
|
|
||||||
{
|
{
|
||||||
// Explicit version of iter::order::lt to handle parse errors properly
|
// Explicit version of iter::order::lt to handle parse errors properly
|
||||||
for (dep_v, stab_v) in
|
for (dep_v, stab_v) in
|
||||||
|
@ -163,19 +194,29 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.recurse_with_stability_attrs(stab, const_stab, visit_children);
|
self.recurse_with_stability_attrs(
|
||||||
|
depr.map(|d| DeprecationEntry::local(d, hir_id)),
|
||||||
|
stab,
|
||||||
|
const_stab,
|
||||||
|
visit_children,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recurse_with_stability_attrs(
|
fn recurse_with_stability_attrs(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
depr: Option<DeprecationEntry>,
|
||||||
stab: Option<&'tcx Stability>,
|
stab: Option<&'tcx Stability>,
|
||||||
const_stab: Option<&'tcx ConstStability>,
|
const_stab: Option<&'tcx ConstStability>,
|
||||||
f: impl FnOnce(&mut Self),
|
f: impl FnOnce(&mut Self),
|
||||||
) {
|
) {
|
||||||
// These will be `Some` if this item changes the corresponding stability attribute.
|
// These will be `Some` if this item changes the corresponding stability attribute.
|
||||||
|
let mut replaced_parent_depr = None;
|
||||||
let mut replaced_parent_stab = None;
|
let mut replaced_parent_stab = None;
|
||||||
let mut replaced_parent_const_stab = None;
|
let mut replaced_parent_const_stab = None;
|
||||||
|
|
||||||
|
if let Some(depr) = depr {
|
||||||
|
replaced_parent_depr = Some(replace(&mut self.parent_depr, Some(depr)));
|
||||||
|
}
|
||||||
if let Some(stab) = stab {
|
if let Some(stab) = stab {
|
||||||
replaced_parent_stab = Some(replace(&mut self.parent_stab, Some(stab)));
|
replaced_parent_stab = Some(replace(&mut self.parent_stab, Some(stab)));
|
||||||
}
|
}
|
||||||
|
@ -186,6 +227,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||||
|
|
||||||
f(self);
|
f(self);
|
||||||
|
|
||||||
|
if let Some(orig_parent_depr) = replaced_parent_depr {
|
||||||
|
self.parent_depr = orig_parent_depr;
|
||||||
|
}
|
||||||
if let Some(orig_parent_stab) = replaced_parent_stab {
|
if let Some(orig_parent_stab) = replaced_parent_stab {
|
||||||
self.parent_stab = orig_parent_stab;
|
self.parent_stab = orig_parent_stab;
|
||||||
}
|
}
|
||||||
|
@ -194,14 +238,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn forbid_staged_api_attrs(
|
// returns true if an error occurred, used to suppress some spurious errors
|
||||||
&mut self,
|
fn forbid_staged_api_attrs(&mut self, hir_id: HirId, attrs: &[Attribute]) -> bool {
|
||||||
hir_id: HirId,
|
|
||||||
attrs: &[Attribute],
|
|
||||||
item_sp: Span,
|
|
||||||
kind: AnnotationKind,
|
|
||||||
visit_children: impl FnOnce(&mut Self),
|
|
||||||
) {
|
|
||||||
// Emit errors for non-staged-api crates.
|
// Emit errors for non-staged-api crates.
|
||||||
let unstable_attrs = [
|
let unstable_attrs = [
|
||||||
sym::unstable,
|
sym::unstable,
|
||||||
|
@ -210,6 +248,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||||
sym::rustc_const_unstable,
|
sym::rustc_const_unstable,
|
||||||
sym::rustc_const_stable,
|
sym::rustc_const_stable,
|
||||||
];
|
];
|
||||||
|
let mut has_error = false;
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
let name = attr.name_or_empty();
|
let name = attr.name_or_empty();
|
||||||
if unstable_attrs.contains(&name) {
|
if unstable_attrs.contains(&name) {
|
||||||
|
@ -221,6 +260,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||||
"stability attributes may not be used outside of the standard library",
|
"stability attributes may not be used outside of the standard library",
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
|
has_error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,24 +272,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(depr) = attr::find_deprecation(&self.tcx.sess.parse_sess, attrs, item_sp) {
|
has_error
|
||||||
if kind == AnnotationKind::Prohibited {
|
|
||||||
self.tcx.sess.span_err(item_sp, "This deprecation annotation is useless");
|
|
||||||
}
|
|
||||||
|
|
||||||
// `Deprecation` is just two pointers, no need to intern it
|
|
||||||
let depr_entry = DeprecationEntry::local(depr, hir_id);
|
|
||||||
self.index.depr_map.insert(hir_id, depr_entry.clone());
|
|
||||||
|
|
||||||
let orig_parent_depr = replace(&mut self.parent_depr, Some(depr_entry));
|
|
||||||
visit_children(self);
|
|
||||||
self.parent_depr = orig_parent_depr;
|
|
||||||
} else if let Some(parent_depr) = self.parent_depr.clone() {
|
|
||||||
self.index.depr_map.insert(hir_id, parent_depr);
|
|
||||||
visit_children(self);
|
|
||||||
} else {
|
|
||||||
visit_children(self);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,7 +477,6 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
|
||||||
is_soft: false,
|
is_soft: false,
|
||||||
},
|
},
|
||||||
feature: sym::rustc_private,
|
feature: sym::rustc_private,
|
||||||
rustc_depr: None,
|
|
||||||
});
|
});
|
||||||
annotator.parent_stab = Some(stability);
|
annotator.parent_stab = Some(stability);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1017,9 +1017,10 @@ impl<'a> Resolver<'a> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(depr) = &stability.rustc_depr {
|
}
|
||||||
let path = pprust::path_to_string(path);
|
if let Some(depr) = &ext.deprecation {
|
||||||
let (message, lint) = stability::rustc_deprecation_message(depr, &path);
|
let path = pprust::path_to_string(&path);
|
||||||
|
let (message, lint) = stability::deprecation_message(depr, &path);
|
||||||
stability::early_report_deprecation(
|
stability::early_report_deprecation(
|
||||||
&mut self.lint_buffer,
|
&mut self.lint_buffer,
|
||||||
&message,
|
&message,
|
||||||
|
@ -1029,12 +1030,6 @@ impl<'a> Resolver<'a> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(depr) = &ext.deprecation {
|
|
||||||
let path = pprust::path_to_string(&path);
|
|
||||||
let (message, lint) = stability::deprecation_message(depr, &path);
|
|
||||||
stability::early_report_deprecation(&mut self.lint_buffer, &message, None, lint, span);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn prohibit_imported_non_macro_attrs(
|
fn prohibit_imported_non_macro_attrs(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -2353,10 +2353,6 @@ impl Clean<Stability> for attr::Stability {
|
||||||
attr::Stable { ref since } => since.to_string(),
|
attr::Stable { ref since } => since.to_string(),
|
||||||
_ => String::new(),
|
_ => String::new(),
|
||||||
},
|
},
|
||||||
deprecation: self.rustc_depr.as_ref().map(|d| Deprecation {
|
|
||||||
note: Some(d.reason.to_string()).filter(|r| !r.is_empty()),
|
|
||||||
since: Some(d.since.to_string()).filter(|d| !d.is_empty()),
|
|
||||||
}),
|
|
||||||
unstable_reason: match self.level {
|
unstable_reason: match self.level {
|
||||||
attr::Unstable { reason: Some(ref reason), .. } => Some(reason.to_string()),
|
attr::Unstable { reason: Some(ref reason), .. } => Some(reason.to_string()),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -2374,6 +2370,7 @@ impl Clean<Deprecation> for attr::Deprecation {
|
||||||
Deprecation {
|
Deprecation {
|
||||||
since: self.since.map(|s| s.to_string()).filter(|s| !s.is_empty()),
|
since: self.since.map(|s| s.to_string()).filter(|s| !s.is_empty()),
|
||||||
note: self.note.map(|n| n.to_string()).filter(|n| !n.is_empty()),
|
note: self.note.map(|n| n.to_string()).filter(|n| !n.is_empty()),
|
||||||
|
is_since_rustc_version: self.is_since_rustc_version,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,7 +195,8 @@ impl Item {
|
||||||
classes.push("unstable");
|
classes.push("unstable");
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.deprecation.is_some() {
|
// FIXME: what about non-staged API items that are deprecated?
|
||||||
|
if self.deprecation.is_some() {
|
||||||
classes.push("deprecated");
|
classes.push("deprecated");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,14 +217,6 @@ impl Item {
|
||||||
ItemType::from(self)
|
ItemType::from(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the info in the item's `#[deprecated]` or `#[rustc_deprecated]` attributes.
|
|
||||||
///
|
|
||||||
/// If the item is not deprecated, returns `None`.
|
|
||||||
pub fn deprecation(&self) -> Option<&Deprecation> {
|
|
||||||
self.deprecation
|
|
||||||
.as_ref()
|
|
||||||
.or_else(|| self.stability.as_ref().and_then(|s| s.deprecation.as_ref()))
|
|
||||||
}
|
|
||||||
pub fn is_default(&self) -> bool {
|
pub fn is_default(&self) -> bool {
|
||||||
match self.inner {
|
match self.inner {
|
||||||
ItemEnum::MethodItem(ref meth) => {
|
ItemEnum::MethodItem(ref meth) => {
|
||||||
|
@ -1528,7 +1521,6 @@ pub struct Stability {
|
||||||
pub level: stability::StabilityLevel,
|
pub level: stability::StabilityLevel,
|
||||||
pub feature: Option<String>,
|
pub feature: Option<String>,
|
||||||
pub since: String,
|
pub since: String,
|
||||||
pub deprecation: Option<Deprecation>,
|
|
||||||
pub unstable_reason: Option<String>,
|
pub unstable_reason: Option<String>,
|
||||||
pub issue: Option<NonZeroU32>,
|
pub issue: Option<NonZeroU32>,
|
||||||
}
|
}
|
||||||
|
@ -1537,6 +1529,7 @@ pub struct Stability {
|
||||||
pub struct Deprecation {
|
pub struct Deprecation {
|
||||||
pub since: Option<String>,
|
pub since: Option<String>,
|
||||||
pub note: Option<String>,
|
pub note: Option<String>,
|
||||||
|
pub is_since_rustc_version: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
|
/// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
|
||||||
|
|
|
@ -2216,17 +2216,11 @@ fn stability_tags(item: &clean::Item) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The trailing space after each tag is to space it properly against the rest of the docs.
|
// The trailing space after each tag is to space it properly against the rest of the docs.
|
||||||
if item.deprecation().is_some() {
|
if let Some(depr) = &item.deprecation {
|
||||||
let mut message = "Deprecated";
|
let mut message = "Deprecated";
|
||||||
if let Some(ref stab) = item.stability {
|
if !stability::deprecation_in_effect(depr.is_since_rustc_version, depr.since.as_deref()) {
|
||||||
if let Some(ref depr) = stab.deprecation {
|
|
||||||
if let Some(ref since) = depr.since {
|
|
||||||
if !stability::deprecation_in_effect(&since) {
|
|
||||||
message = "Deprecation planned";
|
message = "Deprecation planned";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tags += &tag_html("deprecated", message);
|
tags += &tag_html("deprecated", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2254,23 +2248,18 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
|
||||||
let mut stability = vec![];
|
let mut stability = vec![];
|
||||||
let error_codes = cx.shared.codes;
|
let error_codes = cx.shared.codes;
|
||||||
|
|
||||||
if let Some(Deprecation { note, since }) = &item.deprecation() {
|
if let Some(Deprecation { ref note, ref since, is_since_rustc_version }) = item.deprecation {
|
||||||
// We display deprecation messages for #[deprecated] and #[rustc_deprecated]
|
// We display deprecation messages for #[deprecated] and #[rustc_deprecated]
|
||||||
// but only display the future-deprecation messages for #[rustc_deprecated].
|
// but only display the future-deprecation messages for #[rustc_deprecated].
|
||||||
let mut message = if let Some(since) = since {
|
let mut message = if let Some(since) = since {
|
||||||
format!("Deprecated since {}", Escape(since))
|
if !stability::deprecation_in_effect(is_since_rustc_version, Some(since)) {
|
||||||
|
format!("Deprecating in {}", Escape(&since))
|
||||||
|
} else {
|
||||||
|
format!("Deprecated since {}", Escape(&since))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
String::from("Deprecated")
|
String::from("Deprecated")
|
||||||
};
|
};
|
||||||
if let Some(ref stab) = item.stability {
|
|
||||||
if let Some(ref depr) = stab.deprecation {
|
|
||||||
if let Some(ref since) = depr.since {
|
|
||||||
if !stability::deprecation_in_effect(&since) {
|
|
||||||
message = format!("Deprecating in {}", Escape(&since));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(note) = note {
|
if let Some(note) = note {
|
||||||
let mut ids = cx.id_map.borrow_mut();
|
let mut ids = cx.id_map.borrow_mut();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue