Skip to content

Commit d029ebf

Browse files
committed
auto merge of #7902 : huonw/rust/attr++, r=cmr,pcwalton
This does a number of things, but especially dramatically reduce the number of allocations performed for operations involving attributes/ meta items: - Converts ast::meta_item & ast::attribute and other associated enums to CamelCase. - Converts several standalone functions in syntax::attr into methods, defined on two traits AttrMetaMethods & AttributeMethods. The former is common to both MetaItem and Attribute since the latter is a thin wrapper around the former. - Deletes functions that are unnecessary due to iterators. - Converts other standalone functions to use iterators and the generic AttrMetaMethods rather than allocating a lot of new vectors (e.g. the old code would have to allocate a new vector to use functions that operated on &[meta_item] on &[attribute].) - Moves the core algorithm of the #[cfg] matching to syntax::attr, similar to find_inline_attr and find_linkage_metas. This doesn't have much of an effect on the speed of #[cfg] stripping, despite hugely reducing the number of allocations performed; presumably most of the time is spent in the ast folder rather than doing attribute checks. Also fixes the Eq instance of MetaItem_ to correctly ignore spans, so that `rustc --cfg 'foo(bar)'` now works.
2 parents 8476419 + cc760a6 commit d029ebf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+728
-811
lines changed

src/librustc/back/link.rs

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use std::vec;
3636
use syntax::ast;
3737
use syntax::ast_map::{path, path_mod, path_name};
3838
use syntax::attr;
39+
use syntax::attr::{AttrMetaMethods};
3940
use syntax::print::pprust;
4041
use syntax::parse::token;
4142

@@ -502,7 +503,7 @@ pub fn build_link_meta(sess: Session,
502503
struct ProvidedMetas {
503504
name: Option<@str>,
504505
vers: Option<@str>,
505-
cmh_items: ~[@ast::meta_item]
506+
cmh_items: ~[@ast::MetaItem]
506507
}
507508

508509
fn provided_link_metas(sess: Session, c: &ast::crate) ->
@@ -513,18 +514,10 @@ pub fn build_link_meta(sess: Session,
513514
let linkage_metas = attr::find_linkage_metas(c.node.attrs);
514515
attr::require_unique_names(sess.diagnostic(), linkage_metas);
515516
for linkage_metas.iter().advance |meta| {
516-
match attr::get_meta_item_value_str(*meta) {
517-
Some(value) => {
518-
let item_name : &str = attr::get_meta_item_name(*meta);
519-
match item_name {
520-
// Changing attr would avoid the need for the copy
521-
// here
522-
"name" => name = Some(value),
523-
"vers" => vers = Some(value),
524-
_ => cmh_items.push(*meta)
525-
}
526-
},
527-
None => cmh_items.push(*meta)
517+
match meta.name_str_pair() {
518+
Some((n, value)) if "name" == n => name = Some(value),
519+
Some((n, value)) if "vers" == n => vers = Some(value),
520+
_ => cmh_items.push(*meta)
528521
}
529522
}
530523

@@ -537,7 +530,7 @@ pub fn build_link_meta(sess: Session,
537530

538531
// This calculates CMH as defined above
539532
fn crate_meta_extras_hash(symbol_hasher: &mut hash::State,
540-
cmh_items: ~[@ast::meta_item],
533+
cmh_items: ~[@ast::MetaItem],
541534
dep_hashes: ~[@str]) -> @str {
542535
fn len_and_str(s: &str) -> ~str {
543536
fmt!("%u_%s", s.len(), s)
@@ -549,16 +542,16 @@ pub fn build_link_meta(sess: Session,
549542

550543
let cmh_items = attr::sort_meta_items(cmh_items);
551544

552-
fn hash(symbol_hasher: &mut hash::State, m: &@ast::meta_item) {
545+
fn hash(symbol_hasher: &mut hash::State, m: &@ast::MetaItem) {
553546
match m.node {
554-
ast::meta_name_value(key, value) => {
547+
ast::MetaNameValue(key, value) => {
555548
write_string(symbol_hasher, len_and_str(key));
556549
write_string(symbol_hasher, len_and_str_lit(value));
557550
}
558-
ast::meta_word(name) => {
551+
ast::MetaWord(name) => {
559552
write_string(symbol_hasher, len_and_str(name));
560553
}
561-
ast::meta_list(name, ref mis) => {
554+
ast::MetaList(name, ref mis) => {
562555
write_string(symbol_hasher, len_and_str(name));
563556
for mis.iter().advance |m_| {
564557
hash(symbol_hasher, m_);

src/librustc/driver/driver.rs

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use extra::getopts;
3434
use syntax::ast;
3535
use syntax::abi;
3636
use syntax::attr;
37+
use syntax::attr::{AttrMetaMethods};
3738
use syntax::codemap;
3839
use syntax::diagnostic;
3940
use syntax::parse;
@@ -95,12 +96,9 @@ pub fn default_configuration(sess: Session, argv0: @str, input: &input) ->
9596
mk(@"build_input", source_name(input))];
9697
}
9798

98-
pub fn append_configuration(cfg: ast::crate_cfg, name: @str)
99-
-> ast::crate_cfg {
100-
if attr::contains_name(cfg, name) {
101-
cfg
102-
} else {
103-
vec::append_one(cfg, attr::mk_word_item(name))
99+
pub fn append_configuration(cfg: &mut ast::crate_cfg, name: @str) {
100+
if !cfg.iter().any(|mi| mi.name() == name) {
101+
cfg.push(attr::mk_word_item(name))
104102
}
105103
}
106104

@@ -109,18 +107,11 @@ pub fn build_configuration(sess: Session, argv0: @str, input: &input) ->
109107
// Combine the configuration requested by the session (command line) with
110108
// some default and generated configuration items
111109
let default_cfg = default_configuration(sess, argv0, input);
112-
let user_cfg = sess.opts.cfg.clone();
110+
let mut user_cfg = sess.opts.cfg.clone();
113111
// If the user wants a test runner, then add the test cfg
114-
let user_cfg = if sess.opts.test {
115-
append_configuration(user_cfg, @"test")
116-
} else {
117-
user_cfg
118-
};
119-
112+
if sess.opts.test { append_configuration(&mut user_cfg, @"test") }
120113
// If the user requested GC, then add the GC cfg
121-
let user_cfg = append_configuration(
122-
user_cfg,
123-
if sess.opts.gc { @"gc" } else { @"nogc" });
114+
append_configuration(&mut user_cfg, if sess.opts.gc { @"gc" } else { @"nogc" });
124115
return vec::append(user_cfg, default_cfg);
125116
}
126117

@@ -130,7 +121,7 @@ fn parse_cfgspecs(cfgspecs: ~[~str],
130121
do cfgspecs.consume_iter().transform |s| {
131122
let sess = parse::new_parse_sess(Some(demitter));
132123
parse::parse_meta_from_source_str(@"cfgspec", s.to_managed(), ~[], sess)
133-
}.collect()
124+
}.collect::<ast::crate_cfg>()
134125
}
135126

136127
pub enum input {
@@ -215,6 +206,7 @@ pub fn compile_rest(sess: Session,
215206
crate = time(time_passes, ~"configuration 2", ||
216207
front::config::strip_unconfigured_items(crate));
217208

209+
218210
crate = time(time_passes, ~"maybe building test harness", ||
219211
front::test::modify_for_testing(sess, crate));
220212
}
@@ -870,7 +862,7 @@ pub struct OutputFilenames {
870862
pub fn build_output_filenames(input: &input,
871863
odir: &Option<Path>,
872864
ofile: &Option<Path>,
873-
attrs: &[ast::attribute],
865+
attrs: &[ast::Attribute],
874866
sess: Session)
875867
-> @OutputFilenames {
876868
let obj_path;
@@ -912,12 +904,10 @@ pub fn build_output_filenames(input: &input,
912904
let linkage_metas = attr::find_linkage_metas(attrs);
913905
if !linkage_metas.is_empty() {
914906
// But if a linkage meta is present, that overrides
915-
let maybe_matches = attr::find_meta_items_by_name(linkage_metas, "name");
916-
if !maybe_matches.is_empty() {
917-
match attr::get_meta_item_value_str(maybe_matches[0]) {
918-
Some(s) => stem = s,
919-
_ => ()
920-
}
907+
let maybe_name = linkage_metas.iter().find_(|m| "name" == m.name());
908+
match maybe_name.chain(|m| m.value_str()) {
909+
Some(s) => stem = s,
910+
_ => ()
921911
}
922912
// If the name is missing, we just default to the filename
923913
// version
@@ -1011,7 +1001,8 @@ mod test {
10111001
@"rustc", matches, diagnostic::emit);
10121002
let sess = build_session(sessopts, diagnostic::emit);
10131003
let cfg = build_configuration(sess, @"whatever", &str_input(@""));
1014-
let test_items = attr::find_meta_items_by_name(cfg, "test");
1015-
assert_eq!(test_items.len(), 1u);
1004+
let mut test_items = cfg.iter().filter(|m| "test" == m.name());
1005+
assert!(test_items.next().is_some());
1006+
assert!(test_items.next().is_none());
10161007
}
10171008
}

src/librustc/driver/session.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ pub fn building_library(req_crate_type: crate_type,
369369
match syntax::attr::first_attr_value_str_by_name(
370370
crate.node.attrs,
371371
"crate_type") {
372-
Some(s) if "lib" == s => true,
372+
Some(s) => "lib" == s,
373373
_ => false
374374
}
375375
}
@@ -395,18 +395,11 @@ mod test {
395395
use driver::session::{unknown_crate};
396396

397397
use syntax::ast;
398+
use syntax::attr;
398399
use syntax::codemap;
399400

400-
fn make_crate_type_attr(t: @str) -> ast::attribute {
401-
codemap::respan(codemap::dummy_sp(), ast::attribute_ {
402-
style: ast::attr_outer,
403-
value: @codemap::respan(codemap::dummy_sp(),
404-
ast::meta_name_value(
405-
@"crate_type",
406-
codemap::respan(codemap::dummy_sp(),
407-
ast::lit_str(t)))),
408-
is_sugared_doc: false
409-
})
401+
fn make_crate_type_attr(t: @str) -> ast::Attribute {
402+
attr::mk_attr(attr::mk_name_value_item_str(@"crate_type", t))
410403
}
411404

412405
fn make_crate(with_bin: bool, with_lib: bool) -> @ast::crate {

src/librustc/front/config.rs

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
use std::option;
1313
use syntax::{ast, fold, attr};
1414

15-
type in_cfg_pred = @fn(attrs: &[ast::attribute]) -> bool;
15+
type in_cfg_pred = @fn(attrs: &[ast::Attribute]) -> bool;
1616

1717
struct Context {
1818
in_cfg: in_cfg_pred
@@ -175,31 +175,6 @@ fn trait_method_in_cfg(cx: @Context, meth: &ast::trait_method) -> bool {
175175

176176
// Determine if an item should be translated in the current crate
177177
// configuration based on the item's attributes
178-
fn in_cfg(cfg: &[@ast::meta_item], attrs: &[ast::attribute]) -> bool {
179-
metas_in_cfg(cfg, attr::attr_metas(attrs))
180-
}
181-
182-
pub fn metas_in_cfg(cfg: &[@ast::meta_item],
183-
metas: &[@ast::meta_item]) -> bool {
184-
// The "cfg" attributes on the item
185-
let cfg_metas = attr::find_meta_items_by_name(metas, "cfg");
186-
187-
// Pull the inner meta_items from the #[cfg(meta_item, ...)] attributes,
188-
// so we can match against them. This is the list of configurations for
189-
// which the item is valid
190-
let cfg_metas = cfg_metas.consume_iter()
191-
.filter_map(|i| attr::get_meta_item_list(i))
192-
.collect::<~[~[@ast::meta_item]]>();
193-
194-
if cfg_metas.iter().all(|c| c.is_empty()) { return true; }
195-
196-
cfg_metas.iter().any(|cfg_meta| {
197-
cfg_meta.iter().all(|cfg_mi| {
198-
match cfg_mi.node {
199-
ast::meta_list(s, ref it) if "not" == s
200-
=> it.iter().all(|mi| !attr::contains(cfg, *mi)),
201-
_ => attr::contains(cfg, *cfg_mi)
202-
}
203-
})
204-
})
178+
fn in_cfg(cfg: &[@ast::MetaItem], attrs: &[ast::Attribute]) -> bool {
179+
attr::test_cfg(cfg, attrs.iter().transform(|x| *x))
205180
}

src/librustc/front/std_inject.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ pub fn maybe_inject_libstd_ref(sess: Session, crate: @ast::crate)
3030
}
3131

3232
fn use_std(crate: &ast::crate) -> bool {
33-
!attr::attrs_contains_name(crate.node.attrs, "no_std")
33+
!attr::contains_name(crate.node.attrs, "no_std")
3434
}
35-
fn no_prelude(attrs: &[ast::attribute]) -> bool {
36-
attr::attrs_contains_name(attrs, "no_implicit_prelude")
35+
fn no_prelude(attrs: &[ast::Attribute]) -> bool {
36+
attr::contains_name(attrs, "no_implicit_prelude")
3737
}
3838

3939
fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate {
@@ -48,14 +48,8 @@ fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate {
4848
node: ast::view_item_extern_mod(
4949
sess.ident_of("std"), ~[], n1),
5050
attrs: ~[
51-
spanned(ast::attribute_ {
52-
style: ast::attr_inner,
53-
value: @spanned(ast::meta_name_value(
54-
@"vers",
55-
spanned(ast::lit_str(STD_VERSION.to_managed()))
56-
)),
57-
is_sugared_doc: false
58-
})
51+
attr::mk_attr(
52+
attr::mk_name_value_item_str(@"vers", STD_VERSION.to_managed()))
5953
],
6054
vis: ast::private,
6155
span: dummy_sp()

0 commit comments

Comments
 (0)