From 113b7f7be15c49fcd0854ca53486e92f1badfdd6 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Mon, 4 Feb 2019 12:41:01 -0500 Subject: allow shorthand syntax for deprecation reason --- src/libsyntax/attr/builtin.rs | 125 ++++++++++++++++++++++-------------------- src/libsyntax/attr/mod.rs | 4 ++ 2 files changed, 69 insertions(+), 60 deletions(-) (limited to 'src/libsyntax/attr') diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 08c7c617a7b..7230a2922c4 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -592,81 +592,86 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess, let diagnostic = &sess.span_diagnostic; 'outer: for attr in attrs_iter { - if attr.path != "deprecated" { - continue + if !attr.check_name("deprecated") { + continue; } - mark_used(attr); - if depr.is_some() { span_err!(diagnostic, item_sp, E0550, "multiple deprecated attributes"); break } - depr = if let Some(metas) = attr.meta_item_list() { - let get = |meta: &MetaItem, item: &mut Option| { - if item.is_some() { - handle_errors(sess, meta.span, AttrError::MultipleItem(meta.name())); - return false - } - if let Some(v) = meta.value_str() { - *item = Some(v); - true - } else { - if let Some(lit) = meta.name_value_literal() { - handle_errors( - sess, - lit.span, - AttrError::UnsupportedLiteral( - "literal in `deprecated` \ - value must be a string", - lit.node.is_bytestr() - ), - ); - } else { - span_err!(diagnostic, meta.span, E0551, "incorrect meta item"); + let meta = attr.meta().unwrap(); + depr = match &meta.node { + MetaItemKind::Word => Some(Deprecation { since: None, note: None }), + MetaItemKind::NameValue(..) => { + meta.value_str().map(|note| { + Deprecation { since: None, note: Some(note) } + }) + } + MetaItemKind::List(list) => { + let get = |meta: &MetaItem, item: &mut Option| { + if item.is_some() { + handle_errors(sess, meta.span, AttrError::MultipleItem(meta.name())); + return false } + if let Some(v) = meta.value_str() { + *item = Some(v); + true + } else { + if let Some(lit) = meta.name_value_literal() { + handle_errors( + sess, + lit.span, + AttrError::UnsupportedLiteral( + "literal in `deprecated` \ + value must be a string", + lit.node.is_bytestr() + ), + ); + } else { + span_err!(diagnostic, meta.span, E0551, "incorrect meta item"); + } - false - } - }; + false + } + }; - let mut since = None; - let mut note = None; - for meta in metas { - match &meta.node { - NestedMetaItemKind::MetaItem(mi) => { - match &*mi.name().as_str() { - "since" => if !get(mi, &mut since) { continue 'outer }, - "note" => if !get(mi, &mut note) { continue 'outer }, - _ => { - handle_errors( - sess, - meta.span, - AttrError::UnknownMetaItem(mi.name(), &["since", "note"]), - ); - continue 'outer + let mut since = None; + let mut note = None; + for meta in list { + match &meta.node { + NestedMetaItemKind::MetaItem(mi) => { + match &*mi.name().as_str() { + "since" => if !get(mi, &mut since) { continue 'outer }, + "note" => if !get(mi, &mut note) { continue 'outer }, + _ => { + handle_errors( + sess, + meta.span, + AttrError::UnknownMetaItem(mi.name(), &["since", "note"]), + ); + continue 'outer + } } } - } - NestedMetaItemKind::Literal(lit) => { - handle_errors( - sess, - lit.span, - AttrError::UnsupportedLiteral( - "item in `deprecated` must be a key/value pair", - false, - ), - ); - continue 'outer + NestedMetaItemKind::Literal(lit) => { + handle_errors( + sess, + lit.span, + AttrError::UnsupportedLiteral( + "item in `deprecated` must be a key/value pair", + false, + ), + ); + continue 'outer + } } } - } - Some(Deprecation {since: since, note: note}) - } else { - Some(Deprecation{since: None, note: None}) - } + Some(Deprecation { since, note }) + } + }; } depr diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 58be7c3e085..7e0342e1cba 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -161,6 +161,10 @@ fn name_from_path(path: &Path) -> Name { } impl Attribute { + /// Returns `true` if the attribute's path matches the argument. If it matches, then the + /// attribute is marked as used. + /// + /// To check the attribute name without marking it used, use the `path` field directly. pub fn check_name(&self, name: &str) -> bool { let matches = self.path == name; if matches { -- cgit 1.4.1-3-g733a5