Skip to content

Commit

Permalink
Migrate rustc_depr uses to use deprecation attribute
Browse files Browse the repository at this point in the history
This should not be a change in behavior.
  • Loading branch information
Mark-Simulacrum committed Jul 21, 2020
1 parent 21a3d29 commit 8454ee8
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 181 deletions.
54 changes: 2 additions & 52 deletions src/librustc_attr/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Op
pub struct Stability {
pub level: StabilityLevel,
pub feature: Symbol,
pub rustc_depr: Option<RustcDeprecation>,
}

/// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes.
Expand Down Expand Up @@ -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)]`.
/// This will not perform any "sanity checks" on the form of the attributes.
pub fn contains_feature_attr(attrs: &[Attribute], feature_name: Symbol) -> bool {
Expand Down Expand Up @@ -204,7 +194,6 @@ where
use StabilityLevel::*;

let mut stab: Option<Stability> = None;
let mut rustc_depr: Option<RustcDeprecation> = None;
let mut const_stab: Option<ConstStability> = None;
let mut promotable = false;
let mut allow_const_fn_ptr = false;
Expand Down Expand Up @@ -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();
match meta_name {
sym::rustc_const_unstable | sym::unstable => {
Expand Down Expand Up @@ -398,7 +348,7 @@ where
(Some(feature), reason, Some(_)) => {
let level = Unstable { reason, issue: issue_num, is_soft };
if sym::unstable == meta_name {
stab = Some(Stability { level, feature, rustc_depr: None });
stab = Some(Stability { level, feature });
} else {
const_stab = Some(ConstStability {
level,
Expand Down Expand Up @@ -470,7 +420,7 @@ where
(Some(feature), Some(since)) => {
let level = Stable { since };
if sym::stable == meta_name {
stab = Some(Stability { level, feature, rustc_depr: None });
stab = Some(Stability { level, feature });
} else {
const_stab = Some(ConstStability {
level,
Expand Down
71 changes: 41 additions & 30 deletions src/librustc_middle/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub use self::StabilityLevel::*;

use crate::ty::{self, TyCtxt};
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_errors::{Applicability, DiagnosticBuilder};
use rustc_feature::GateIssue;
Expand Down Expand Up @@ -130,14 +130,26 @@ 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(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> {
// We ignore non-integer components of the version (e.g., "nightly").
ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect()
}

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);
// We simply treat invalid `since` attributes as relating to a previous
// Rust version, thus always displaying the warning.
Expand Down Expand Up @@ -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) {
let message = format!("use of deprecated item '{}'", path);
(deprecation_message_common(message, depr.note), DEPRECATED)
}

pub fn rustc_deprecation_message(depr: &RustcDeprecation, path: &str) -> (String, &'static Lint) {
let (message, lint) = if deprecation_in_effect(&depr.since.as_str()) {
let (message, lint) = if deprecation_in_effect(
depr.is_since_rustc_version,
depr.since.map(Symbol::as_str).as_deref(),
) {
(format!("use of deprecated item '{}'", path), DEPRECATED)
} else {
(
format!(
"use of item '{}' that will be deprecated in future version {}",
path, depr.since
path,
depr.since.unwrap()
),
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(
Expand Down Expand Up @@ -289,10 +297,23 @@ impl<'tcx> TyCtxt<'tcx> {
.lookup_deprecation_entry(parent_def_id.to_def_id())
.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) =
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,
);
}
};
}
Expand All @@ -310,16 +331,6 @@ impl<'tcx> TyCtxt<'tcx> {
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
let cross_crate = !def_id.is_local();
if !cross_crate {
Expand Down
Loading

0 comments on commit 8454ee8

Please sign in to comment.