Skip to content

Commit f164cf5

Browse files
authored
Auto merge of #34842 - cgswords:attr_enc, r=nrc
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
2 parents 5a7773a + 5553901 commit f164cf5

File tree

15 files changed

+204
-173
lines changed

15 files changed

+204
-173
lines changed

src/librustc/lint/context.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -366,18 +366,18 @@ pub fn gather_attr(attr: &ast::Attribute)
366366
attr::mark_used(attr);
367367

368368
let meta = &attr.node.value;
369-
let metas = match meta.node {
370-
ast::MetaItemKind::List(_, ref metas) => metas,
371-
_ => {
372-
out.push(Err(meta.span));
373-
return out;
374-
}
369+
let metas = if let Some(metas) = meta.meta_item_list() {
370+
metas
371+
} else {
372+
out.push(Err(meta.span));
373+
return out;
375374
};
376375

377376
for meta in metas {
378-
out.push(match meta.node {
379-
ast::MetaItemKind::Word(ref lint_name) => Ok((lint_name.clone(), level, meta.span)),
380-
_ => Err(meta.span),
377+
out.push(if meta.is_word() {
378+
Ok((meta.name().clone(), level, meta.span))
379+
} else {
380+
Err(meta.span)
381381
});
382382
}
383383

src/librustc_driver/lib.rs

+14-19
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ use std::thread;
9595
use rustc::session::early_error;
9696

9797
use syntax::{ast, json};
98+
use syntax::attr::AttrMetaMethods;
9899
use syntax::codemap::{CodeMap, FileLoader, RealFileLoader};
99100
use syntax::feature_gate::{GatedCfg, UnstableFeatures};
100101
use syntax::parse::{self, PResult};
@@ -392,15 +393,12 @@ fn check_cfg(sopts: &config::Options,
392393

393394
let mut saw_invalid_predicate = false;
394395
for item in sopts.cfg.iter() {
395-
match item.node {
396-
ast::MetaItemKind::List(ref pred, _) => {
397-
saw_invalid_predicate = true;
398-
handler.emit(&MultiSpan::new(),
399-
&format!("invalid predicate in --cfg command line argument: `{}`",
400-
pred),
401-
errors::Level::Fatal);
402-
}
403-
_ => {},
396+
if item.is_meta_item_list() {
397+
saw_invalid_predicate = true;
398+
handler.emit(&MultiSpan::new(),
399+
&format!("invalid predicate in --cfg command line argument: `{}`",
400+
item.name()),
401+
errors::Level::Fatal);
404402
}
405403
}
406404

@@ -649,20 +647,17 @@ impl RustcDefaultCalls {
649647
if !allow_unstable_cfg && GatedCfg::gate(&*cfg).is_some() {
650648
continue;
651649
}
652-
match cfg.node {
653-
ast::MetaItemKind::Word(ref word) => println!("{}", word),
654-
ast::MetaItemKind::NameValue(ref name, ref value) => {
655-
println!("{}=\"{}\"", name, match value.node {
656-
ast::LitKind::Str(ref s, _) => s,
657-
_ => continue,
658-
});
650+
if cfg.is_word() {
651+
println!("{}", cfg.name());
652+
} else if cfg.is_value_str() {
653+
if let Some(s) = cfg.value_str() {
654+
println!("{}=\"{}\"", cfg.name(), s);
659655
}
656+
} else if cfg.is_meta_item_list() {
660657
// Right now there are not and should not be any
661658
// MetaItemKind::List items in the configuration returned by
662659
// `build_configuration`.
663-
ast::MetaItemKind::List(..) => {
664-
panic!("MetaItemKind::List encountered in default cfg")
665-
}
660+
panic!("MetaItemKind::List encountered in default cfg")
666661
}
667662
}
668663
}

src/librustc_incremental/assert_dep_graph.rs

+12-17
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,11 @@ impl<'a, 'tcx> IfThisChanged<'a, 'tcx> {
110110
if attr.check_name(IF_THIS_CHANGED) {
111111
let mut id = None;
112112
for meta_item in attr.meta_item_list().unwrap_or_default() {
113-
match meta_item.node {
114-
ast::MetaItemKind::Word(ref s) if id.is_none() => id = Some(s.clone()),
115-
_ => {
116-
self.tcx.sess.span_err(
117-
meta_item.span,
118-
&format!("unexpected meta-item {:?}", meta_item.node));
119-
}
113+
if meta_item.is_word() && id.is_none() {
114+
id = Some(meta_item.name().clone());
115+
} else {
116+
// FIXME better-encapsulate meta_item (don't directly access `node`)
117+
span_bug!(meta_item.span(), "unexpected meta-item {:?}", meta_item.node)
120118
}
121119
}
122120
let id = id.unwrap_or(InternedString::new(ID));
@@ -127,16 +125,13 @@ impl<'a, 'tcx> IfThisChanged<'a, 'tcx> {
127125
let mut dep_node_interned = None;
128126
let mut id = None;
129127
for meta_item in attr.meta_item_list().unwrap_or_default() {
130-
match meta_item.node {
131-
ast::MetaItemKind::Word(ref s) if dep_node_interned.is_none() =>
132-
dep_node_interned = Some(s.clone()),
133-
ast::MetaItemKind::Word(ref s) if id.is_none() =>
134-
id = Some(s.clone()),
135-
_ => {
136-
self.tcx.sess.span_err(
137-
meta_item.span,
138-
&format!("unexpected meta-item {:?}", meta_item.node));
139-
}
128+
if meta_item.is_word() && dep_node_interned.is_none() {
129+
dep_node_interned = Some(meta_item.name().clone());
130+
} else if meta_item.is_word() && id.is_none() {
131+
id = Some(meta_item.name().clone());
132+
} else {
133+
// FIXME better-encapsulate meta_item (don't directly access `node`)
134+
span_bug!(meta_item.span(), "unexpected meta-item {:?}", meta_item.node)
140135
}
141136
}
142137
let dep_node = match dep_node_interned {

src/librustc_incremental/calculate_svh.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//! Calculation of a Strict Version Hash for crates. For a length
1212
//! comment explaining the general idea, see `librustc/middle/svh.rs`.
1313
14+
use syntax::attr::AttributeMethods;
1415
use std::hash::{Hash, SipHasher, Hasher};
1516
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
1617
use rustc::hir::svh::Svh;
@@ -69,7 +70,7 @@ impl<'a, 'tcx> SvhCalculate for TyCtxt<'a, 'tcx, 'tcx> {
6970
// to avoid hashing the AttrId
7071
for attr in &krate.attrs {
7172
debug!("krate attr {:?}", attr);
72-
attr.node.value.hash(&mut state);
73+
attr.meta().hash(&mut state);
7374
}
7475

7576
Svh::new(state.finish())

src/librustc_lint/builtin.rs

+5-10
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use lint::{LintPass, LateLintPass};
4444
use std::collections::HashSet;
4545

4646
use syntax::{ast};
47-
use syntax::attr::{self, AttrMetaMethods};
47+
use syntax::attr::{self, AttrMetaMethods, AttributeMethods};
4848
use syntax_pos::{self, Span};
4949

5050
use rustc::hir::{self, PatKind};
@@ -298,12 +298,7 @@ impl MissingDoc {
298298
}
299299
}
300300

301-
let has_doc = attrs.iter().any(|a| {
302-
match a.node.value.node {
303-
ast::MetaItemKind::NameValue(ref name, _) if *name == "doc" => true,
304-
_ => false
305-
}
306-
});
301+
let has_doc = attrs.iter().any(|a| a.is_value_str() && a.name() == "doc");
307302
if !has_doc {
308303
cx.span_lint(MISSING_DOCS, sp,
309304
&format!("missing documentation for {}", desc));
@@ -1094,10 +1089,10 @@ impl LintPass for UnstableFeatures {
10941089

10951090
impl LateLintPass for UnstableFeatures {
10961091
fn check_attribute(&mut self, ctx: &LateContext, attr: &ast::Attribute) {
1097-
if attr::contains_name(&[attr.node.value.clone()], "feature") {
1098-
if let Some(items) = attr.node.value.meta_item_list() {
1092+
if attr::contains_name(&[attr.meta().clone()], "feature") {
1093+
if let Some(items) = attr.meta().meta_item_list() {
10991094
for item in items {
1100-
ctx.span_lint(UNSTABLE_FEATURES, item.span, "unstable feature");
1095+
ctx.span_lint(UNSTABLE_FEATURES, item.span(), "unstable feature");
11011096
}
11021097
}
11031098
}

src/librustc_metadata/decoder.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -1160,15 +1160,7 @@ fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
11601160
// an attribute
11611161
assert_eq!(meta_items.len(), 1);
11621162
let meta_item = meta_items.into_iter().nth(0).unwrap();
1163-
codemap::Spanned {
1164-
node: ast::Attribute_ {
1165-
id: attr::mk_attr_id(),
1166-
style: ast::AttrStyle::Outer,
1167-
value: meta_item,
1168-
is_sugared_doc: is_sugared_doc,
1169-
},
1170-
span: syntax_pos::DUMMY_SP
1171-
}
1163+
attr::mk_doc_attr_outer(attr::mk_attr_id(), meta_item, is_sugared_doc)
11721164
}).collect()
11731165
},
11741166
None => vec![],

src/librustc_metadata/encoder.rs

+17-20
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use std::rc::Rc;
4444
use std::u32;
4545
use syntax::abi::Abi;
4646
use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID, CrateNum};
47-
use syntax::attr;
47+
use syntax::attr::{self,AttrMetaMethods,AttributeMethods};
4848
use errors::Handler;
4949
use syntax;
5050
use syntax_pos::BytePos;
@@ -1431,31 +1431,28 @@ fn encode_item_index(rbml_w: &mut Encoder, index: IndexData) {
14311431
}
14321432

14331433
fn encode_meta_item(rbml_w: &mut Encoder, mi: &ast::MetaItem) {
1434-
match mi.node {
1435-
ast::MetaItemKind::Word(ref name) => {
1434+
if mi.is_word() {
1435+
let name = mi.name();
14361436
rbml_w.start_tag(tag_meta_item_word);
1437-
rbml_w.wr_tagged_str(tag_meta_item_name, name);
1437+
rbml_w.wr_tagged_str(tag_meta_item_name, &name);
14381438
rbml_w.end_tag();
1439-
}
1440-
ast::MetaItemKind::NameValue(ref name, ref value) => {
1441-
match value.node {
1442-
ast::LitKind::Str(ref value, _) => {
1443-
rbml_w.start_tag(tag_meta_item_name_value);
1444-
rbml_w.wr_tagged_str(tag_meta_item_name, name);
1445-
rbml_w.wr_tagged_str(tag_meta_item_value, value);
1446-
rbml_w.end_tag();
1447-
}
1448-
_ => {/* FIXME (#623): encode other variants */ }
1449-
}
1450-
}
1451-
ast::MetaItemKind::List(ref name, ref items) => {
1439+
} else if mi.is_value_str() {
1440+
let name = mi.name();
1441+
/* FIXME (#623): support other literal kinds */
1442+
let value = mi.value_str().unwrap();
1443+
rbml_w.start_tag(tag_meta_item_name_value);
1444+
rbml_w.wr_tagged_str(tag_meta_item_name, &name);
1445+
rbml_w.wr_tagged_str(tag_meta_item_value, &value);
1446+
rbml_w.end_tag();
1447+
} else { // it must be a list
1448+
let name = mi.name();
1449+
let items = mi.meta_item_list().unwrap();
14521450
rbml_w.start_tag(tag_meta_item_list);
1453-
rbml_w.wr_tagged_str(tag_meta_item_name, name);
1451+
rbml_w.wr_tagged_str(tag_meta_item_name, &name);
14541452
for inner_item in items {
14551453
encode_meta_item(rbml_w, &inner_item);
14561454
}
14571455
rbml_w.end_tag();
1458-
}
14591456
}
14601457
}
14611458

@@ -1464,7 +1461,7 @@ fn encode_attributes(rbml_w: &mut Encoder, attrs: &[ast::Attribute]) {
14641461
for attr in attrs {
14651462
rbml_w.start_tag(tag_attribute);
14661463
rbml_w.wr_tagged_u8(tag_attribute_is_sugared_doc, attr.node.is_sugared_doc as u8);
1467-
encode_meta_item(rbml_w, &attr.node.value);
1464+
encode_meta_item(rbml_w, attr.meta());
14681465
rbml_w.end_tag();
14691466
}
14701467
rbml_w.end_tag();

src/librustc_metadata/macro_import.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ impl<'a> ext::base::MacroLoader for MacroLoader<'a> {
6060
}
6161
if let (Some(sel), Some(names)) = (import.as_mut(), names) {
6262
for attr in names {
63-
if let ast::MetaItemKind::Word(ref name) = attr.node {
64-
sel.insert(name.clone(), attr.span);
63+
if attr.is_word() {
64+
sel.insert(attr.name().clone(), attr.span());
6565
} else {
66-
span_err!(self.sess, attr.span, E0466, "bad macro import");
66+
span_err!(self.sess, attr.span(), E0466, "bad macro import");
6767
}
6868
}
6969
}
@@ -78,10 +78,10 @@ impl<'a> ext::base::MacroLoader for MacroLoader<'a> {
7878
};
7979

8080
for attr in names {
81-
if let ast::MetaItemKind::Word(ref name) = attr.node {
82-
reexport.insert(name.clone(), attr.span);
81+
if attr.is_word() {
82+
reexport.insert(attr.name().clone(), attr.span());
8383
} else {
84-
call_bad_macro_reexport(self.sess, attr.span);
84+
call_bad_macro_reexport(self.sess, attr.span());
8585
}
8686
}
8787
}

src/librustdoc/clean/mod.rs

+31-30
Original file line numberDiff line numberDiff line change
@@ -498,21 +498,20 @@ pub enum Attribute {
498498

499499
impl Clean<Attribute> for ast::MetaItem {
500500
fn clean(&self, cx: &DocContext) -> Attribute {
501-
match self.node {
502-
ast::MetaItemKind::Word(ref s) => Word(s.to_string()),
503-
ast::MetaItemKind::List(ref s, ref l) => {
504-
List(s.to_string(), l.clean(cx))
505-
}
506-
ast::MetaItemKind::NameValue(ref s, ref v) => {
507-
NameValue(s.to_string(), lit_to_string(v))
508-
}
509-
}
501+
if self.is_word() {
502+
Word(self.name().to_string())
503+
} else if let Some(v) = self.value_str() {
504+
NameValue(self.name().to_string(), v.to_string())
505+
} else { // must be a list
506+
let l = self.meta_item_list().unwrap();
507+
List(self.name().to_string(), l.clean(cx))
508+
}
510509
}
511510
}
512511

513512
impl Clean<Attribute> for ast::Attribute {
514513
fn clean(&self, cx: &DocContext) -> Attribute {
515-
self.with_desugared_doc(|a| a.node.value.clean(cx))
514+
self.with_desugared_doc(|a| a.meta().clean(cx))
516515
}
517516
}
518517

@@ -535,6 +534,28 @@ impl attr::AttrMetaMethods for Attribute {
535534
}
536535
}
537536
fn meta_item_list<'a>(&'a self) -> Option<&'a [P<ast::MetaItem>]> { None }
537+
538+
fn is_word(&self) -> bool {
539+
match *self {
540+
Word(_) => true,
541+
_ => false,
542+
}
543+
}
544+
545+
fn is_value_str(&self) -> bool {
546+
match *self {
547+
NameValue(..) => true,
548+
_ => false,
549+
}
550+
}
551+
552+
fn is_meta_item_list(&self) -> bool {
553+
match *self {
554+
List(..) => true,
555+
_ => false,
556+
}
557+
}
558+
538559
fn span(&self) -> syntax_pos::Span { unimplemented!() }
539560
}
540561

@@ -2568,26 +2589,6 @@ impl ToSource for syntax_pos::Span {
25682589
}
25692590
}
25702591

2571-
fn lit_to_string(lit: &ast::Lit) -> String {
2572-
match lit.node {
2573-
ast::LitKind::Str(ref st, _) => st.to_string(),
2574-
ast::LitKind::ByteStr(ref data) => format!("{:?}", data),
2575-
ast::LitKind::Byte(b) => {
2576-
let mut res = String::from("b'");
2577-
for c in (b as char).escape_default() {
2578-
res.push(c);
2579-
}
2580-
res.push('\'');
2581-
res
2582-
},
2583-
ast::LitKind::Char(c) => format!("'{}'", c),
2584-
ast::LitKind::Int(i, _t) => i.to_string(),
2585-
ast::LitKind::Float(ref f, _t) => f.to_string(),
2586-
ast::LitKind::FloatUnsuffixed(ref f) => f.to_string(),
2587-
ast::LitKind::Bool(b) => b.to_string(),
2588-
}
2589-
}
2590-
25912592
fn name_from_pat(p: &hir::Pat) -> String {
25922593
use rustc::hir::*;
25932594
debug!("Trying to get a name from pattern: {:?}", p);

0 commit comments

Comments
 (0)