Skip to content

Commit

Permalink
Auto merge of #34842 - cgswords:attr_enc, r=nrc
Browse files Browse the repository at this point in the history
Better attribute and metaitem encapsulation throughout the compiler

This PR refactors most (hopefully all?) of the `MetaItem` interactions outside of `libsyntax` (and a few inside) to interact with MetaItems through the provided traits instead of directly creating / destruct / matching against them. This is a necessary first step to eventually converting `MetaItem`s to internally use `TokenStream` representations (which will make `MetaItem` interactions much nicer for macro writers once the new macro system is in place).

r? @nrc
  • Loading branch information
bors authored Jul 29, 2016
2 parents 5a7773a + 5553901 commit f164cf5
Show file tree
Hide file tree
Showing 15 changed files with 204 additions and 173 deletions.
18 changes: 9 additions & 9 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,18 +366,18 @@ 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)
});
}

Expand Down
33 changes: 14 additions & 19 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -392,15 +393,12 @@ 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;
handler.emit(&MultiSpan::new(),
&format!("invalid predicate in --cfg command line argument: `{}`",
item.name()),
errors::Level::Fatal);
}
}

Expand Down Expand Up @@ -649,20 +647,17 @@ 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() {
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
// 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")
}
}
}
Expand Down
29 changes: 12 additions & 17 deletions src/librustc_incremental/assert_dep_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,11 @@ 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`)
span_bug!(meta_item.span(), "unexpected meta-item {:?}", meta_item.node)
}
}
let id = id.unwrap_or(InternedString::new(ID));
Expand All @@ -127,16 +125,13 @@ 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`)
span_bug!(meta_item.span(), "unexpected meta-item {:?}", meta_item.node)
}
}
let dep_node = match dep_node_interned {
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_incremental/calculate_svh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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())
Expand Down
15 changes: 5 additions & 10 deletions src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -298,12 +298,7 @@ impl MissingDoc {
}
}

let has_doc = attrs.iter().any(|a| {
match a.node.value.node {
ast::MetaItemKind::NameValue(ref name, _) if *name == "doc" => true,
_ => 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));
Expand Down Expand Up @@ -1094,10 +1089,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");
}
}
}
Expand Down
10 changes: 1 addition & 9 deletions src/librustc_metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1160,15 +1160,7 @@ fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
// 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![],
Expand Down
37 changes: 17 additions & 20 deletions src/librustc_metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
}
}

Expand All @@ -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();
Expand Down
12 changes: 6 additions & 6 deletions src/librustc_metadata/macro_import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}
}
Expand All @@ -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());
}
}
}
Expand Down
61 changes: 31 additions & 30 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -498,21 +498,20 @@ pub enum Attribute {

impl Clean<Attribute> 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<Attribute> 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))
}
}

Expand All @@ -535,6 +534,28 @@ impl attr::AttrMetaMethods for Attribute {
}
}
fn meta_item_list<'a>(&'a self) -> Option<&'a [P<ast::MetaItem>]> { 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!() }
}

Expand Down Expand Up @@ -2568,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);
Expand Down
Loading

0 comments on commit f164cf5

Please sign in to comment.