1 use rustc::session::Session;
2 use rustc_errors::Applicability;
6 /// Deprecation status of attributes known by Clippy.
8 pub enum DeprecationStatus {
9 /// Attribute is deprecated
11 /// Attribute is deprecated and was replaced by the named attribute
12 Replaced(&'static str),
16 pub const BUILTIN_ATTRIBUTES: &[(&str, DeprecationStatus)] = &[
17 ("author", DeprecationStatus::None),
18 ("cognitive_complexity", DeprecationStatus::None),
20 "cyclomatic_complexity",
21 DeprecationStatus::Replaced("cognitive_complexity"),
23 ("dump", DeprecationStatus::None),
26 pub struct LimitStack {
30 impl Drop for LimitStack {
32 assert_eq!(self.stack.len(), 1);
37 pub fn new(limit: u64) -> Self {
38 Self { stack: vec![limit] }
40 pub fn limit(&self) -> u64 {
41 *self.stack.last().expect("there should always be a value in the stack")
43 pub fn push_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) {
44 let stack = &mut self.stack;
45 parse_attrs(sess, attrs, name, |val| stack.push(val));
47 pub fn pop_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) {
48 let stack = &mut self.stack;
49 parse_attrs(sess, attrs, name, |val| assert_eq!(stack.pop(), Some(val)));
55 attrs: &'a [ast::Attribute],
57 ) -> impl Iterator<Item = &'a ast::Attribute> {
58 attrs.iter().filter(move |attr| {
59 let attr_segments = &attr.path.segments;
60 if attr_segments.len() == 2 && attr_segments[0].ident.to_string() == "clippy" {
61 if let Some(deprecation_status) =
64 .find_map(|(builtin_name, deprecation_status)| {
65 if *builtin_name == attr_segments[1].ident.to_string() {
66 Some(deprecation_status)
72 let mut db = sess.struct_span_err(attr_segments[1].ident.span, "Usage of deprecated attribute");
73 match deprecation_status {
74 DeprecationStatus::Deprecated => {
78 DeprecationStatus::Replaced(new_name) => {
80 attr_segments[1].ident.span,
83 Applicability::MachineApplicable,
88 DeprecationStatus::None => {
90 attr_segments[1].ident.to_string() == name
94 sess.span_err(attr_segments[1].ident.span, "Usage of unknown attribute");
103 fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) {
104 for attr in get_attr(sess, attrs, name) {
105 if let Some(ref value) = attr.value_str() {
106 if let Ok(value) = FromStr::from_str(&value.as_str()) {
109 sess.span_err(attr.span, "not a number");
112 sess.span_err(attr.span, "bad clippy attribute");