From a5e5ea1646367b82864af3a2a508993d76b792af Mon Sep 17 00:00:00 2001 From: cgswords Date: Fri, 15 Jul 2016 13:13:17 -0700 Subject: [PATCH 1/2] General MetaItem encapsulation rewrites. --- src/librustc/lint/context.rs | 22 ++--- src/librustc_driver/lib.rs | 36 ++++---- src/librustc_incremental/assert_dep_graph.rs | 33 ++++--- src/librustc_incremental/calculate_svh.rs | 3 +- src/librustc_lint/builtin.rs | 15 ++-- src/librustc_metadata/decoder.rs | 10 +-- src/librustc_metadata/encoder.rs | 37 ++++---- src/librustc_metadata/macro_import.rs | 12 +-- src/librustdoc/clean/mod.rs | 79 ++++++++++------ src/libsyntax/attr.rs | 94 +++++++++++++++++--- src/libsyntax/ext/build.rs | 23 ++--- src/libsyntax/ext/expand.rs | 5 +- src/libsyntax/feature_gate.rs | 15 ++-- src/libsyntax_ext/deriving/mod.rs | 19 ++-- 14 files changed, 232 insertions(+), 171 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index ce3d72de9ae99..0a1e7005f9fb9 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -366,19 +366,19 @@ pub fn gather_attr(attr: &ast::Attribute) attr::mark_used(attr); let meta = &attr.node.value; - let metas = match meta.node { - ast::MetaItemKind::List(_, ref metas) => metas, - _ => { - out.push(Err(meta.span)); - return out; - } - }; + let metas = if let Some(metas) = meta.meta_item_list() { + metas + } else { + out.push(Err(meta.span)); + return out; + }; for meta in metas { - out.push(match meta.node { - ast::MetaItemKind::Word(ref lint_name) => Ok((lint_name.clone(), level, meta.span)), - _ => Err(meta.span), - }); + out.push(if meta.is_word() { + Ok((meta.name().clone(), level, meta.span)) + } else { + Err(meta.span) + }); } out diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 0a8df923b846b..9df1dea45671f 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -95,6 +95,7 @@ use std::thread; use rustc::session::early_error; use syntax::{ast, json}; +use syntax::attr::AttrMetaMethods; use syntax::codemap::{CodeMap, FileLoader, RealFileLoader}; use syntax::feature_gate::{GatedCfg, UnstableFeatures}; use syntax::parse::{self, PResult}; @@ -392,15 +393,13 @@ fn check_cfg(sopts: &config::Options, let mut saw_invalid_predicate = false; for item in sopts.cfg.iter() { - match item.node { - ast::MetaItemKind::List(ref pred, _) => { - saw_invalid_predicate = true; - handler.emit(&MultiSpan::new(), - &format!("invalid predicate in --cfg command line argument: `{}`", - pred), - errors::Level::Fatal); - } - _ => {}, + if item.is_meta_item_list() { + saw_invalid_predicate = true; + saw_invalid_predicate = true; + handler.emit(&MultiSpan::new(), + &format!("invalid predicate in --cfg command line argument: `{}`", + pred), + errors::Level::Fatal); } } @@ -649,20 +648,19 @@ impl RustcDefaultCalls { if !allow_unstable_cfg && GatedCfg::gate(&*cfg).is_some() { continue; } - match cfg.node { - ast::MetaItemKind::Word(ref word) => println!("{}", word), - ast::MetaItemKind::NameValue(ref name, ref value) => { - println!("{}=\"{}\"", name, match value.node { - ast::LitKind::Str(ref s, _) => s, - _ => continue, - }); + if cfg.is_word() { + println!("{}", cfg.name()); + } else if cfg.is_value_str() { + let rhs = cfg.value_str(); + match rhs { + Some(s) => println!("{}=\"{}\"", cfg.name(), s), + None => continue, } + } else if cfg.is_meta_item_list() { // Right now there are not and should not be any // MetaItemKind::List items in the configuration returned by // `build_configuration`. - ast::MetaItemKind::List(..) => { - panic!("MetaItemKind::List encountered in default cfg") - } + panic!("MetaItemKind::List encountered in default cfg") } } } diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index d38f979e33c5a..0d327414c8fc5 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -110,13 +110,13 @@ impl<'a, 'tcx> IfThisChanged<'a, 'tcx> { if attr.check_name(IF_THIS_CHANGED) { let mut id = None; for meta_item in attr.meta_item_list().unwrap_or_default() { - match meta_item.node { - ast::MetaItemKind::Word(ref s) if id.is_none() => id = Some(s.clone()), - _ => { - self.tcx.sess.span_err( - meta_item.span, - &format!("unexpected meta-item {:?}", meta_item.node)); - } + if meta_item.is_word() && id.is_none() { + id = Some(meta_item.name().clone()); + } else { + // FIXME better-encapsulate meta_item (don't directly access `node`) + self.tcx.sess.span_err( + meta_item.span(), + &format!("unexpected meta-item {:?}", meta_item.node)); } } let id = id.unwrap_or(InternedString::new(ID)); @@ -127,16 +127,15 @@ impl<'a, 'tcx> IfThisChanged<'a, 'tcx> { let mut dep_node_interned = None; let mut id = None; for meta_item in attr.meta_item_list().unwrap_or_default() { - match meta_item.node { - ast::MetaItemKind::Word(ref s) if dep_node_interned.is_none() => - dep_node_interned = Some(s.clone()), - ast::MetaItemKind::Word(ref s) if id.is_none() => - id = Some(s.clone()), - _ => { - self.tcx.sess.span_err( - meta_item.span, - &format!("unexpected meta-item {:?}", meta_item.node)); - } + if meta_item.is_word() && dep_node_interned.is_none() { + dep_node_interned = Some(meta_item.name().clone()); + } else if meta_item.is_word() && id.is_none() { + id = Some(meta_item.name().clone()); + } else { + // FIXME better-encapsulate meta_item (don't directly access `node`) + self.tcx.sess.span_err( + meta_item.span(), + &format!("unexpected meta-item {:?}", meta_item.node)); } } let dep_node = match dep_node_interned { diff --git a/src/librustc_incremental/calculate_svh.rs b/src/librustc_incremental/calculate_svh.rs index cbc246ac2a11b..5d26bcd48a3bc 100644 --- a/src/librustc_incremental/calculate_svh.rs +++ b/src/librustc_incremental/calculate_svh.rs @@ -11,6 +11,7 @@ //! Calculation of a Strict Version Hash for crates. For a length //! comment explaining the general idea, see `librustc/middle/svh.rs`. +use syntax::attr::AttributeMethods; use std::hash::{Hash, SipHasher, Hasher}; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use rustc::hir::svh::Svh; @@ -69,7 +70,7 @@ impl<'a, 'tcx> SvhCalculate for TyCtxt<'a, 'tcx, 'tcx> { // to avoid hashing the AttrId for attr in &krate.attrs { debug!("krate attr {:?}", attr); - attr.node.value.hash(&mut state); + attr.meta().hash(&mut state); } Svh::new(state.finish()) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 18f9733040e0f..a498004b390a4 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -44,7 +44,7 @@ use lint::{LintPass, LateLintPass}; use std::collections::HashSet; use syntax::{ast}; -use syntax::attr::{self, AttrMetaMethods}; +use syntax::attr::{self, AttrMetaMethods, AttributeMethods}; use syntax_pos::{self, Span}; use rustc::hir::{self, PatKind}; @@ -299,9 +299,10 @@ impl MissingDoc { } let has_doc = attrs.iter().any(|a| { - match a.node.value.node { - ast::MetaItemKind::NameValue(ref name, _) if *name == "doc" => true, - _ => false + if a.is_value_str() && a.name() == "doc" { + true + } else { + false } }); if !has_doc { @@ -1094,10 +1095,10 @@ impl LintPass for UnstableFeatures { impl LateLintPass for UnstableFeatures { fn check_attribute(&mut self, ctx: &LateContext, attr: &ast::Attribute) { - if attr::contains_name(&[attr.node.value.clone()], "feature") { - if let Some(items) = attr.node.value.meta_item_list() { + if attr::contains_name(&[attr.meta().clone()], "feature") { + if let Some(items) = attr.meta().meta_item_list() { for item in items { - ctx.span_lint(UNSTABLE_FEATURES, item.span, "unstable feature"); + ctx.span_lint(UNSTABLE_FEATURES, item.span(), "unstable feature"); } } } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 409cec282bce9..63345a15e6a9b 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -1160,15 +1160,7 @@ fn get_attributes(md: rbml::Doc) -> Vec { // an attribute assert_eq!(meta_items.len(), 1); let meta_item = meta_items.into_iter().nth(0).unwrap(); - codemap::Spanned { - node: ast::Attribute_ { - id: attr::mk_attr_id(), - style: ast::AttrStyle::Outer, - value: meta_item, - is_sugared_doc: is_sugared_doc, - }, - span: syntax_pos::DUMMY_SP - } + attr::mk_doc_attr_outer(attr::mk_attr_id(), meta_item, is_sugared_doc) }).collect() }, None => vec![], diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 7314259423592..91b1b82211a16 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -44,7 +44,7 @@ use std::rc::Rc; use std::u32; use syntax::abi::Abi; use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID, CrateNum}; -use syntax::attr; +use syntax::attr::{self,AttrMetaMethods,AttributeMethods}; use errors::Handler; use syntax; use syntax_pos::BytePos; @@ -1431,31 +1431,28 @@ fn encode_item_index(rbml_w: &mut Encoder, index: IndexData) { } fn encode_meta_item(rbml_w: &mut Encoder, mi: &ast::MetaItem) { - match mi.node { - ast::MetaItemKind::Word(ref name) => { + if mi.is_word() { + let name = mi.name(); rbml_w.start_tag(tag_meta_item_word); - rbml_w.wr_tagged_str(tag_meta_item_name, name); + rbml_w.wr_tagged_str(tag_meta_item_name, &name); rbml_w.end_tag(); - } - ast::MetaItemKind::NameValue(ref name, ref value) => { - match value.node { - ast::LitKind::Str(ref value, _) => { - rbml_w.start_tag(tag_meta_item_name_value); - rbml_w.wr_tagged_str(tag_meta_item_name, name); - rbml_w.wr_tagged_str(tag_meta_item_value, value); - rbml_w.end_tag(); - } - _ => {/* FIXME (#623): encode other variants */ } - } - } - ast::MetaItemKind::List(ref name, ref items) => { + } else if mi.is_value_str() { + let name = mi.name(); + /* FIXME (#623): support other literal kinds */ + let value = mi.value_str().unwrap(); + rbml_w.start_tag(tag_meta_item_name_value); + rbml_w.wr_tagged_str(tag_meta_item_name, &name); + rbml_w.wr_tagged_str(tag_meta_item_value, &value); + rbml_w.end_tag(); + } else { // it must be a list + let name = mi.name(); + let items = mi.meta_item_list().unwrap(); rbml_w.start_tag(tag_meta_item_list); - rbml_w.wr_tagged_str(tag_meta_item_name, name); + rbml_w.wr_tagged_str(tag_meta_item_name, &name); for inner_item in items { encode_meta_item(rbml_w, &inner_item); } rbml_w.end_tag(); - } } } @@ -1464,7 +1461,7 @@ fn encode_attributes(rbml_w: &mut Encoder, attrs: &[ast::Attribute]) { for attr in attrs { rbml_w.start_tag(tag_attribute); rbml_w.wr_tagged_u8(tag_attribute_is_sugared_doc, attr.node.is_sugared_doc as u8); - encode_meta_item(rbml_w, &attr.node.value); + encode_meta_item(rbml_w, attr.meta()); rbml_w.end_tag(); } rbml_w.end_tag(); diff --git a/src/librustc_metadata/macro_import.rs b/src/librustc_metadata/macro_import.rs index 7dadf8d108a71..4be044c1df307 100644 --- a/src/librustc_metadata/macro_import.rs +++ b/src/librustc_metadata/macro_import.rs @@ -60,10 +60,10 @@ impl<'a> ext::base::MacroLoader for MacroLoader<'a> { } if let (Some(sel), Some(names)) = (import.as_mut(), names) { for attr in names { - if let ast::MetaItemKind::Word(ref name) = attr.node { - sel.insert(name.clone(), attr.span); + if attr.is_word() { + sel.insert(attr.name().clone(), attr.span()); } else { - span_err!(self.sess, attr.span, E0466, "bad macro import"); + span_err!(self.sess, attr.span(), E0466, "bad macro import"); } } } @@ -78,10 +78,10 @@ impl<'a> ext::base::MacroLoader for MacroLoader<'a> { }; for attr in names { - if let ast::MetaItemKind::Word(ref name) = attr.node { - reexport.insert(name.clone(), attr.span); + if attr.is_word() { + reexport.insert(attr.name().clone(), attr.span()); } else { - call_bad_macro_reexport(self.sess, attr.span); + call_bad_macro_reexport(self.sess, attr.span()); } } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0211b2c9bc7ba..8d69c55ecf124 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -498,21 +498,20 @@ pub enum Attribute { impl Clean for ast::MetaItem { fn clean(&self, cx: &DocContext) -> Attribute { - match self.node { - ast::MetaItemKind::Word(ref s) => Word(s.to_string()), - ast::MetaItemKind::List(ref s, ref l) => { - List(s.to_string(), l.clean(cx)) - } - ast::MetaItemKind::NameValue(ref s, ref v) => { - NameValue(s.to_string(), lit_to_string(v)) - } - } + if self.is_word() { + Word(self.name().to_string()) + } else if let Some(v) = self.value_str() { + NameValue(self.name().to_string(), v.to_string()) + } else { // must be a list + let l = self.meta_item_list().unwrap(); + List(self.name().to_string(), l.clean(cx)) + } } } impl Clean for ast::Attribute { fn clean(&self, cx: &DocContext) -> Attribute { - self.with_desugared_doc(|a| a.node.value.clean(cx)) + self.with_desugared_doc(|a| a.meta().clean(cx)) } } @@ -535,6 +534,28 @@ impl attr::AttrMetaMethods for Attribute { } } fn meta_item_list<'a>(&'a self) -> Option<&'a [P]> { None } + + fn is_word(&self) -> bool { + match *self { + Word(_) => true, + _ => false, + } + } + + fn is_value_str(&self) -> bool { + match *self { + NameValue(..) => true, + _ => false, + } + } + + fn is_meta_item_list(&self) -> bool { + match *self { + List(..) => true, + _ => false, + } + } + fn span(&self) -> syntax_pos::Span { unimplemented!() } } @@ -2568,25 +2589,25 @@ impl ToSource for syntax_pos::Span { } } -fn lit_to_string(lit: &ast::Lit) -> String { - match lit.node { - ast::LitKind::Str(ref st, _) => st.to_string(), - ast::LitKind::ByteStr(ref data) => format!("{:?}", data), - ast::LitKind::Byte(b) => { - let mut res = String::from("b'"); - for c in (b as char).escape_default() { - res.push(c); - } - res.push('\''); - res - }, - ast::LitKind::Char(c) => format!("'{}'", c), - ast::LitKind::Int(i, _t) => i.to_string(), - ast::LitKind::Float(ref f, _t) => f.to_string(), - ast::LitKind::FloatUnsuffixed(ref f) => f.to_string(), - ast::LitKind::Bool(b) => b.to_string(), - } -} +// fn lit_to_string(lit: &ast::Lit) -> String { +// match lit.node { +// ast::LitKind::Str(ref st, _) => st.to_string(), +// ast::LitKind::ByteStr(ref data) => format!("{:?}", data), +// ast::LitKind::Byte(b) => { +// let mut res = String::from("b'"); +// for c in (b as char).escape_default() { +// res.push(c); +// } +// res.push('\''); +// res +// }, +// ast::LitKind::Char(c) => format!("'{}'", c), +// ast::LitKind::Int(i, _t) => i.to_string(), +// ast::LitKind::Float(ref f, _t) => f.to_string(), +// ast::LitKind::FloatUnsuffixed(ref f) => f.to_string(), +// ast::LitKind::Bool(b) => b.to_string(), +// } +// } fn name_from_pat(p: &hir::Pat) -> String { use rustc::hir::*; diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 67f73d4dd4f71..8bd3f5195ccd8 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -17,8 +17,8 @@ pub use self::IntType::*; use ast; use ast::{AttrId, Attribute, Attribute_, MetaItem, MetaItemKind}; use ast::{Expr, Item, Local, Stmt, StmtKind}; -use codemap::{spanned, dummy_spanned, Spanned}; -use syntax_pos::{Span, BytePos}; +use codemap::{respan, spanned, dummy_spanned, Spanned}; +use syntax_pos::{Span, BytePos, DUMMY_SP}; use errors::Handler; use feature_gate::{Features, GatedCfg}; use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; @@ -92,6 +92,13 @@ pub trait AttrMetaMethods { /// Gets a list of inner meta items from a list MetaItem type. fn meta_item_list(&self) -> Option<&[P]>; + /// Indicates if the attribute is a Word. + fn is_word(&self) -> bool; + /// Indicates if the attribute is a Value String. + fn is_value_str(&self) -> bool; + /// Indicates if the attribute is a Meta-Item List. + fn is_meta_item_list(&self) -> bool; + fn span(&self) -> Span; } @@ -108,8 +115,14 @@ impl AttrMetaMethods for Attribute { self.meta().value_str() } fn meta_item_list(&self) -> Option<&[P]> { - self.node.value.meta_item_list() + self.meta().meta_item_list() } + + fn is_word(&self) -> bool { self.meta().is_word() } + fn is_value_str(&self) -> bool { self.meta().is_value_str() } + + fn is_meta_item_list(&self) -> bool { self.meta().is_meta_item_list() } + fn span(&self) -> Span { self.meta().span } } @@ -140,6 +153,18 @@ impl AttrMetaMethods for MetaItem { _ => None } } + + fn is_word(&self) -> bool { + match self.node { + MetaItemKind::Word(_) => true, + _ => false, + } + } + + fn is_value_str(&self) -> bool { self.value_str().is_some() } + + fn is_meta_item_list(&self) -> bool { self.meta_item_list().is_some() } + fn span(&self) -> Span { self.span } } @@ -150,6 +175,9 @@ impl AttrMetaMethods for P { fn meta_item_list(&self) -> Option<&[P]> { (**self).meta_item_list() } + fn is_word(&self) -> bool { (**self).is_word() } + fn is_value_str(&self) -> bool { (**self).is_value_str() } + fn is_meta_item_list(&self) -> bool { (**self).is_meta_item_list() } fn span(&self) -> Span { (**self).span() } } @@ -194,22 +222,38 @@ impl AttributeMethods for Attribute { pub fn mk_name_value_item_str(name: InternedString, value: InternedString) -> P { let value_lit = dummy_spanned(ast::LitKind::Str(value, ast::StrStyle::Cooked)); - mk_name_value_item(name, value_lit) + mk_spanned_name_value_item(DUMMY_SP, name, value_lit) } pub fn mk_name_value_item(name: InternedString, value: ast::Lit) -> P { - P(dummy_spanned(MetaItemKind::NameValue(name, value))) + mk_spanned_name_value_item(DUMMY_SP, name, value) } pub fn mk_list_item(name: InternedString, items: Vec>) -> P { - P(dummy_spanned(MetaItemKind::List(name, items))) + mk_spanned_list_item(DUMMY_SP, name, items) } pub fn mk_word_item(name: InternedString) -> P { - P(dummy_spanned(MetaItemKind::Word(name))) + mk_spanned_word_item(DUMMY_SP, name) +} + +pub fn mk_spanned_name_value_item(sp: Span, name: InternedString, value: ast::Lit) + -> P { + P(respan(sp,MetaItemKind::NameValue(name, value))) +} + +pub fn mk_spanned_list_item(sp: Span, name: InternedString, items: Vec>) + -> P { + P(respan(sp, MetaItemKind::List(name, items))) } +pub fn mk_spanned_word_item(sp: Span, name: InternedString) -> P { + P(respan(sp,MetaItemKind::Word(name))) +} + + + thread_local! { static NEXT_ATTR_ID: Cell = Cell::new(0) } pub fn mk_attr_id() -> AttrId { @@ -223,21 +267,43 @@ pub fn mk_attr_id() -> AttrId { /// Returns an inner attribute with the given value. pub fn mk_attr_inner(id: AttrId, item: P) -> Attribute { - dummy_spanned(Attribute_ { - id: id, - style: ast::AttrStyle::Inner, - value: item, - is_sugared_doc: false, - }) + mk_spanned_attr_inner(DUMMY_SP, id, item) } +/// Returns an innter attribute with the given value and span. +pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: P) -> Attribute { + respan(sp, + Attribute_ { + id: id, + style: ast::AttrStyle::Inner, + value: item, + is_sugared_doc: false, + }) +} + + /// Returns an outer attribute with the given value. pub fn mk_attr_outer(id: AttrId, item: P) -> Attribute { + mk_spanned_attr_outer(DUMMY_SP, id, item) +} + +/// Returns an outer attribute with the given value and span. +pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: P) -> Attribute { + respan(sp, + Attribute_ { + id: id, + style: ast::AttrStyle::Outer, + value: item, + is_sugared_doc: false, + }) +} + +pub fn mk_doc_attr_outer(id: AttrId, item: P, is_sugared_doc: bool) -> Attribute { dummy_spanned(Attribute_ { id: id, style: ast::AttrStyle::Outer, value: item, - is_sugared_doc: false, + is_sugared_doc: is_sugared_doc, }) } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 435241f426ec6..5d6429f7bdfff 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -1135,30 +1135,19 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn attribute(&self, sp: Span, mi: P) -> ast::Attribute { - respan(sp, ast::Attribute_ { - id: attr::mk_attr_id(), - style: ast::AttrStyle::Outer, - value: mi, - is_sugared_doc: false, - }) + attr::mk_spanned_attr_outer(sp, attr::mk_attr_id(), mi) } fn meta_word(&self, sp: Span, w: InternedString) -> P { - P(respan(sp, ast::MetaItemKind::Word(w))) + attr::mk_spanned_word_item(sp, w) } - fn meta_list(&self, - sp: Span, - name: InternedString, - mis: Vec> ) + fn meta_list(&self, sp: Span, name: InternedString, mis: Vec>) -> P { - P(respan(sp, ast::MetaItemKind::List(name, mis))) + attr::mk_spanned_list_item(sp, name, mis) } - fn meta_name_value(&self, - sp: Span, - name: InternedString, - value: ast::LitKind) + fn meta_name_value(&self, sp: Span, name: InternedString, value: ast::LitKind) -> P { - P(respan(sp, ast::MetaItemKind::NameValue(name, respan(sp, value)))) + attr::mk_spanned_name_value_item(sp, name, respan(sp, value)) } fn item_use(&self, sp: Span, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 18342f2e38c1b..5293d2ab0001a 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -302,9 +302,8 @@ fn contains_macro_use(fld: &mut MacroExpander, attrs: &[ast::Attribute]) -> bool }; if is_use { - match attr.node.value.node { - ast::MetaItemKind::Word(..) => (), - _ => fld.cx.span_err(attr.span, "arguments to macro_use are not allowed here"), + if !attr.is_word() { + fld.cx.span_err(attr.span, "arguments to macro_use are not allowed here"); } return true; } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 27485ee65fcc0..5a718dd48e374 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1108,14 +1108,13 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute]) -> F } Some(list) => { for mi in list { - let name = match mi.node { - ast::MetaItemKind::Word(ref word) => (*word).clone(), - _ => { - span_err!(span_handler, mi.span, E0556, - "malformed feature, expected just one word"); - continue - } - }; + let name = if mi.is_word() { + mi.name() + } else { + span_err!(span_handler, mi.span, E0556, + "malformed feature, expected just one word"); + continue + }; if let Some(&(_, _, _, setter)) = ACTIVE_FEATURES.iter() .find(|& &(n, _, _, _)| name == n) { *(setter(&mut features)) = true; diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index 80e2a923e5569..e09a64e73449b 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -10,7 +10,7 @@ //! The compiler code necessary to implement the `#[derive]` extensions. -use syntax::ast::{self, MetaItem, MetaItemKind}; +use syntax::ast::{MetaItem, self}; use syntax::attr::AttrMetaMethods; use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxEnv}; use syntax::ext::base::{MultiDecorator, MultiItemDecorator, MultiModifier}; @@ -98,15 +98,14 @@ fn expand_derive(cx: &mut ExtCtxt, let mut eq_span = None; for titem in traits.iter().rev() { - let tname = match titem.node { - MetaItemKind::Word(ref tname) => tname, - _ => { - cx.span_err(titem.span, "malformed `derive` entry"); - continue; - } - }; - - if !(is_builtin_trait(tname) || cx.ecfg.enable_custom_derive()) { + let tname = if titem.is_word() { + titem.name() } + else { + cx.span_err(titem.span, "malformed `derive` entry"); + continue; + }; + + if !(is_builtin_trait(&tname) || cx.ecfg.enable_custom_derive()) { feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic, "custom_derive", titem.span, From 5553901146fa80c652abdc514b38360a0ae7418d Mon Sep 17 00:00:00 2001 From: cgswords Date: Sun, 17 Jul 2016 21:45:06 -0700 Subject: [PATCH 2/2] Adressed PR comments. --- src/librustc/lint/context.rs | 18 ++++++++-------- src/librustc_driver/lib.rs | 9 +++----- src/librustc_incremental/assert_dep_graph.rs | 8 ++----- src/librustc_lint/builtin.rs | 8 +------ src/librustdoc/clean/mod.rs | 22 +------------------- src/libsyntax/attr.rs | 21 +++++++++---------- src/libsyntax_pos/lib.rs | 4 ++++ 7 files changed, 30 insertions(+), 60 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 0a1e7005f9fb9..27e1d0520dc9a 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -367,18 +367,18 @@ pub fn gather_attr(attr: &ast::Attribute) let meta = &attr.node.value; let metas = if let Some(metas) = meta.meta_item_list() { - metas - } else { - out.push(Err(meta.span)); - return out; - }; + metas + } else { + out.push(Err(meta.span)); + return out; + }; for meta in metas { out.push(if meta.is_word() { - Ok((meta.name().clone(), level, meta.span)) - } else { - Err(meta.span) - }); + Ok((meta.name().clone(), level, meta.span)) + } else { + Err(meta.span) + }); } out diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 9df1dea45671f..07a2605026abe 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -394,11 +394,10 @@ fn check_cfg(sopts: &config::Options, let mut saw_invalid_predicate = false; for item in sopts.cfg.iter() { if item.is_meta_item_list() { - saw_invalid_predicate = true; saw_invalid_predicate = true; handler.emit(&MultiSpan::new(), &format!("invalid predicate in --cfg command line argument: `{}`", - pred), + item.name()), errors::Level::Fatal); } } @@ -651,10 +650,8 @@ impl RustcDefaultCalls { if cfg.is_word() { println!("{}", cfg.name()); } else if cfg.is_value_str() { - let rhs = cfg.value_str(); - match rhs { - Some(s) => println!("{}=\"{}\"", cfg.name(), s), - None => continue, + if let Some(s) = cfg.value_str() { + println!("{}=\"{}\"", cfg.name(), s); } } else if cfg.is_meta_item_list() { // Right now there are not and should not be any diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index 0d327414c8fc5..774c5ca6d6b23 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -114,9 +114,7 @@ impl<'a, 'tcx> IfThisChanged<'a, 'tcx> { id = Some(meta_item.name().clone()); } else { // FIXME better-encapsulate meta_item (don't directly access `node`) - self.tcx.sess.span_err( - meta_item.span(), - &format!("unexpected meta-item {:?}", meta_item.node)); + span_bug!(meta_item.span(), "unexpected meta-item {:?}", meta_item.node) } } let id = id.unwrap_or(InternedString::new(ID)); @@ -133,9 +131,7 @@ impl<'a, 'tcx> IfThisChanged<'a, 'tcx> { id = Some(meta_item.name().clone()); } else { // FIXME better-encapsulate meta_item (don't directly access `node`) - self.tcx.sess.span_err( - meta_item.span(), - &format!("unexpected meta-item {:?}", meta_item.node)); + span_bug!(meta_item.span(), "unexpected meta-item {:?}", meta_item.node) } } let dep_node = match dep_node_interned { diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index a498004b390a4..7547e28625c18 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -298,13 +298,7 @@ impl MissingDoc { } } - let has_doc = attrs.iter().any(|a| { - if a.is_value_str() && a.name() == "doc" { - true - } else { - false - } - }); + let has_doc = attrs.iter().any(|a| a.is_value_str() && a.name() == "doc"); if !has_doc { cx.span_lint(MISSING_DOCS, sp, &format!("missing documentation for {}", desc)); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8d69c55ecf124..6883c22d67525 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -504,7 +504,7 @@ impl Clean for ast::MetaItem { NameValue(self.name().to_string(), v.to_string()) } else { // must be a list let l = self.meta_item_list().unwrap(); - List(self.name().to_string(), l.clean(cx)) + List(self.name().to_string(), l.clean(cx)) } } } @@ -2589,26 +2589,6 @@ impl ToSource for syntax_pos::Span { } } -// fn lit_to_string(lit: &ast::Lit) -> String { -// match lit.node { -// ast::LitKind::Str(ref st, _) => st.to_string(), -// ast::LitKind::ByteStr(ref data) => format!("{:?}", data), -// ast::LitKind::Byte(b) => { -// let mut res = String::from("b'"); -// for c in (b as char).escape_default() { -// res.push(c); -// } -// res.push('\''); -// res -// }, -// ast::LitKind::Char(c) => format!("'{}'", c), -// ast::LitKind::Int(i, _t) => i.to_string(), -// ast::LitKind::Float(ref f, _t) => f.to_string(), -// ast::LitKind::FloatUnsuffixed(ref f) => f.to_string(), -// ast::LitKind::Bool(b) => b.to_string(), -// } -// } - fn name_from_pat(p: &hir::Pat) -> String { use rustc::hir::*; debug!("Trying to get a name from pattern: {:?}", p); diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 8bd3f5195ccd8..b622f6861b383 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -94,10 +94,16 @@ pub trait AttrMetaMethods { /// Indicates if the attribute is a Word. fn is_word(&self) -> bool; + /// Indicates if the attribute is a Value String. - fn is_value_str(&self) -> bool; + fn is_value_str(&self) -> bool { + self.value_str().is_some() + } + /// Indicates if the attribute is a Meta-Item List. - fn is_meta_item_list(&self) -> bool; + fn is_meta_item_list(&self) -> bool { + self.meta_item_list().is_some() + } fn span(&self) -> Span; } @@ -119,9 +125,6 @@ impl AttrMetaMethods for Attribute { } fn is_word(&self) -> bool { self.meta().is_word() } - fn is_value_str(&self) -> bool { self.meta().is_value_str() } - - fn is_meta_item_list(&self) -> bool { self.meta().is_meta_item_list() } fn span(&self) -> Span { self.meta().span } } @@ -161,10 +164,6 @@ impl AttrMetaMethods for MetaItem { } } - fn is_value_str(&self) -> bool { self.value_str().is_some() } - - fn is_meta_item_list(&self) -> bool { self.meta_item_list().is_some() } - fn span(&self) -> Span { self.span } } @@ -240,7 +239,7 @@ pub fn mk_word_item(name: InternedString) -> P { pub fn mk_spanned_name_value_item(sp: Span, name: InternedString, value: ast::Lit) -> P { - P(respan(sp,MetaItemKind::NameValue(name, value))) + P(respan(sp, MetaItemKind::NameValue(name, value))) } pub fn mk_spanned_list_item(sp: Span, name: InternedString, items: Vec>) @@ -249,7 +248,7 @@ pub fn mk_spanned_list_item(sp: Span, name: InternedString, items: Vec P { - P(respan(sp,MetaItemKind::Word(name))) + P(respan(sp, MetaItemKind::Word(name))) } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index c96be8fec2b02..b1ec7fd0ab896 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -254,6 +254,10 @@ pub const NO_EXPANSION: ExpnId = ExpnId(!0); // For code appearing from the command line pub const COMMAND_LINE_EXPN: ExpnId = ExpnId(!1); +// For code generated by a procedural macro, without knowing which +// Used in `qquote!` +pub const PROC_EXPN: ExpnId = ExpnId(!2); + impl ExpnId { pub fn from_u32(id: u32) -> ExpnId { ExpnId(id)