Skip to content

Commit 4b9b0d3

Browse files
committed
Refactor CrateConfig.
1 parent a262641 commit 4b9b0d3

File tree

8 files changed

+64
-141
lines changed

8 files changed

+64
-141
lines changed

src/librustc/session/config.rs

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use lint;
2525
use middle::cstore;
2626

2727
use syntax::ast::{self, IntTy, UintTy};
28-
use syntax::attr;
2928
use syntax::parse::{self, token};
3029
use syntax::parse::token::InternedString;
3130
use syntax::feature_gate::UnstableFeatures;
@@ -41,6 +40,7 @@ use std::collections::btree_map::Values as BTreeMapValuesIter;
4140
use std::fmt;
4241
use std::hash::Hasher;
4342
use std::collections::hash_map::DefaultHasher;
43+
use std::collections::HashSet;
4444
use std::iter::FromIterator;
4545
use std::path::PathBuf;
4646

@@ -945,47 +945,39 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
945945
InternedString::new("unix")
946946
};
947947

948-
let mk = attr::mk_name_value_item_str;
949-
let mut ret = vec![ // Target bindings.
950-
mk(token::intern("target_os"), intern(os)),
951-
mk(token::intern("target_family"), fam.clone()),
952-
mk(token::intern("target_arch"), intern(arch)),
953-
mk(token::intern("target_endian"), intern(end)),
954-
mk(token::intern("target_pointer_width"), intern(wordsz)),
955-
mk(token::intern("target_env"), intern(env)),
956-
mk(token::intern("target_vendor"), intern(vendor)),
957-
];
958-
match &fam[..] {
959-
"windows" | "unix" => ret.push(attr::mk_word_item(token::intern(&fam))),
960-
_ => (),
948+
let mut ret = HashSet::new();
949+
// Target bindings.
950+
ret.insert((token::intern("target_os"), Some(intern(os))));
951+
ret.insert((token::intern("target_family"), Some(fam.clone())));
952+
ret.insert((token::intern("target_arch"), Some(intern(arch))));
953+
ret.insert((token::intern("target_endian"), Some(intern(end))));
954+
ret.insert((token::intern("target_pointer_width"), Some(intern(wordsz))));
955+
ret.insert((token::intern("target_env"), Some(intern(env))));
956+
ret.insert((token::intern("target_vendor"), Some(intern(vendor))));
957+
if &fam == "windows" || &fam == "unix" {
958+
ret.insert((token::intern(&fam), None));
961959
}
962960
if sess.target.target.options.has_elf_tls {
963-
ret.push(attr::mk_word_item(token::intern("target_thread_local")));
961+
ret.insert((token::intern("target_thread_local"), None));
964962
}
965963
for &i in &[8, 16, 32, 64, 128] {
966964
if i <= max_atomic_width {
967965
let s = i.to_string();
968-
ret.push(mk(token::intern("target_has_atomic"), intern(&s)));
966+
ret.insert((token::intern("target_has_atomic"), Some(intern(&s))));
969967
if &s == wordsz {
970-
ret.push(mk(token::intern("target_has_atomic"), intern("ptr")));
968+
ret.insert((token::intern("target_has_atomic"), Some(intern("ptr"))));
971969
}
972970
}
973971
}
974972
if sess.opts.debug_assertions {
975-
ret.push(attr::mk_word_item(token::intern("debug_assertions")));
973+
ret.insert((token::intern("debug_assertions"), None));
976974
}
977975
if sess.opts.crate_types.contains(&CrateTypeProcMacro) {
978-
ret.push(attr::mk_word_item(token::intern("proc_macro")));
976+
ret.insert((token::intern("proc_macro"), None));
979977
}
980978
return ret;
981979
}
982980

983-
pub fn append_configuration(cfg: &mut ast::CrateConfig, name: ast::Name) {
984-
if !cfg.iter().any(|mi| mi.name() == name) {
985-
cfg.push(attr::mk_word_item(name))
986-
}
987-
}
988-
989981
pub fn build_configuration(sess: &Session,
990982
mut user_cfg: ast::CrateConfig)
991983
-> ast::CrateConfig {
@@ -994,11 +986,10 @@ pub fn build_configuration(sess: &Session,
994986
let default_cfg = default_configuration(sess);
995987
// If the user wants a test runner, then add the test cfg
996988
if sess.opts.test {
997-
append_configuration(&mut user_cfg, token::intern("test"))
989+
user_cfg.insert((token::intern("test"), None));
998990
}
999-
let mut v = user_cfg.into_iter().collect::<Vec<_>>();
1000-
v.extend_from_slice(&default_cfg[..]);
1001-
v
991+
user_cfg.extend(default_cfg.iter().cloned());
992+
user_cfg
1002993
}
1003994

1004995
pub fn build_target_config(opts: &Options, sp: &Handler) -> Config {
@@ -1244,11 +1235,14 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String> ) -> ast::CrateConfig {
12441235
let meta_item = panictry!(parser.parse_meta_item());
12451236

12461237
if !parser.reader.is_eof() {
1247-
early_error(ErrorOutputType::default(), &format!("invalid --cfg argument: {}",
1248-
s))
1238+
early_error(ErrorOutputType::default(), &format!("invalid --cfg argument: {}", s))
1239+
} else if meta_item.is_meta_item_list() {
1240+
let msg =
1241+
format!("invalid predicate in --cfg command line argument: `{}`", meta_item.name());
1242+
early_error(ErrorOutputType::default(), &msg)
12491243
}
12501244

1251-
meta_item
1245+
(meta_item.name(), meta_item.value_str())
12521246
}).collect::<ast::CrateConfig>()
12531247
}
12541248

src/librustc_driver/lib.rs

Lines changed: 19 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,11 @@ use std::str;
9595
use std::sync::{Arc, Mutex};
9696
use std::thread;
9797

98-
use syntax::{ast, json};
98+
use syntax::ast;
9999
use syntax::codemap::{CodeMap, FileLoader, RealFileLoader};
100100
use syntax::feature_gate::{GatedCfg, UnstableFeatures};
101101
use syntax::parse::{self, PResult};
102-
use syntax_pos::MultiSpan;
103-
use errors::emitter::Emitter;
102+
use syntax_pos::{DUMMY_SP, MultiSpan};
104103

105104
#[cfg(test)]
106105
pub mod test;
@@ -374,37 +373,11 @@ fn handle_explain(code: &str,
374373
}
375374
}
376375

377-
fn check_cfg(cfg: &ast::CrateConfig,
378-
output: ErrorOutputType) {
379-
let emitter: Box<Emitter> = match output {
380-
config::ErrorOutputType::HumanReadable(color_config) => {
381-
Box::new(errors::emitter::EmitterWriter::stderr(color_config, None))
382-
}
383-
config::ErrorOutputType::Json => Box::new(json::JsonEmitter::basic()),
384-
};
385-
let handler = errors::Handler::with_emitter(true, false, emitter);
386-
387-
let mut saw_invalid_predicate = false;
388-
for item in cfg.iter() {
389-
if item.is_meta_item_list() {
390-
saw_invalid_predicate = true;
391-
handler.emit(&MultiSpan::new(),
392-
&format!("invalid predicate in --cfg command line argument: `{}`",
393-
item.name()),
394-
errors::Level::Fatal);
395-
}
396-
}
397-
398-
if saw_invalid_predicate {
399-
panic!(errors::FatalError);
400-
}
401-
}
402-
403376
impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
404377
fn early_callback(&mut self,
405378
matches: &getopts::Matches,
406379
_: &config::Options,
407-
cfg: &ast::CrateConfig,
380+
_: &ast::CrateConfig,
408381
descriptions: &errors::registry::Registry,
409382
output: ErrorOutputType)
410383
-> Compilation {
@@ -413,7 +386,6 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
413386
return Compilation::Stop;
414387
}
415388

416-
check_cfg(cfg, output);
417389
Compilation::Continue
418390
}
419391

@@ -640,24 +612,26 @@ impl RustcDefaultCalls {
640612
let allow_unstable_cfg = UnstableFeatures::from_environment()
641613
.is_nightly_build();
642614

643-
for cfg in &sess.parse_sess.config {
644-
if !allow_unstable_cfg && GatedCfg::gate(cfg).is_some() {
615+
let mut cfgs = Vec::new();
616+
for &(name, ref value) in sess.parse_sess.config.iter() {
617+
let gated_cfg = GatedCfg::gate(&ast::MetaItem {
618+
node: ast::MetaItemKind::Word(name),
619+
span: DUMMY_SP,
620+
});
621+
if !allow_unstable_cfg && gated_cfg.is_some() {
645622
continue;
646623
}
647624

648-
if cfg.is_word() {
649-
println!("{}", cfg.name());
650-
} else if let Some(s) = cfg.value_str() {
651-
println!("{}=\"{}\"", cfg.name(), s);
652-
} else if cfg.is_meta_item_list() {
653-
// Right now there are not and should not be any
654-
// MetaItemKind::List items in the configuration returned by
655-
// `build_configuration`.
656-
panic!("Found an unexpected list in cfg attribute '{}'!", cfg.name())
625+
cfgs.push(if let &Some(ref value) = value {
626+
format!("{}=\"{}\"", name, value)
657627
} else {
658-
// There also shouldn't be literals.
659-
panic!("Found an unexpected literal in cfg attribute '{}'!", cfg.name())
660-
}
628+
format!("{}", name)
629+
});
630+
}
631+
632+
cfgs.sort();
633+
for cfg in cfgs {
634+
println!("{}", cfg);
661635
}
662636
}
663637
PrintRequest::TargetCPUs => {

src/librustc_driver/target_features.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use syntax::{ast, attr};
11+
use syntax::ast;
1212
use llvm::LLVMRustHasFeature;
1313
use rustc::session::Session;
1414
use rustc_trans::back::write::create_target_machine;
@@ -44,7 +44,7 @@ pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) {
4444
for feat in whitelist {
4545
assert_eq!(feat.chars().last(), Some('\0'));
4646
if unsafe { LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } {
47-
cfg.push(attr::mk_name_value_item_str(tf, intern(&feat[..feat.len() - 1])))
47+
cfg.insert((tf, Some(intern(&feat[..feat.len() - 1]))));
4848
}
4949
}
5050

@@ -73,6 +73,6 @@ pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) {
7373
}
7474

7575
if crt_static {
76-
cfg.push(attr::mk_name_value_item_str(tf.clone(), intern("crt-static")));
76+
cfg.insert((tf, Some(intern("crt-static"))));
7777
}
7878
}

src/librustc_incremental/persist/dirty_clean.rs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use rustc::hir::def_id::DefId;
4848
use rustc::hir::itemlikevisit::ItemLikeVisitor;
4949
use syntax::ast::{self, Attribute, NestedMetaItem};
5050
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
51-
use syntax::parse::token::InternedString;
51+
use syntax::parse::token;
5252
use syntax_pos::Span;
5353
use rustc::ty::TyCtxt;
5454
use ich::Fingerprint;
@@ -88,12 +88,11 @@ pub struct DirtyCleanVisitor<'a, 'tcx:'a> {
8888
}
8989

9090
impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
91-
9291
fn dep_node(&self, attr: &Attribute, def_id: DefId) -> DepNode<DefId> {
9392
for item in attr.meta_item_list().unwrap_or(&[]) {
9493
if item.check_name(LABEL) {
9594
let value = expect_associated_value(self.tcx, item);
96-
match DepNode::from_label_string(&value[..], def_id) {
95+
match DepNode::from_label_string(&value.as_str(), def_id) {
9796
Ok(def_id) => return def_id,
9897
Err(()) => {
9998
self.tcx.sess.span_fatal(
@@ -276,13 +275,7 @@ fn check_config(tcx: TyCtxt, attr: &ast::Attribute) -> bool {
276275
if item.check_name(CFG) {
277276
let value = expect_associated_value(tcx, item);
278277
debug!("check_config: searching for cfg {:?}", value);
279-
for cfg in &config[..] {
280-
if cfg.check_name(&value[..]) {
281-
debug!("check_config: matched {:?}", cfg);
282-
return true;
283-
}
284-
}
285-
return false;
278+
return config.contains(&(value, None));
286279
}
287280
}
288281

@@ -291,9 +284,9 @@ fn check_config(tcx: TyCtxt, attr: &ast::Attribute) -> bool {
291284
&format!("no cfg attribute"));
292285
}
293286

294-
fn expect_associated_value(tcx: TyCtxt, item: &NestedMetaItem) -> InternedString {
287+
fn expect_associated_value(tcx: TyCtxt, item: &NestedMetaItem) -> ast::Name {
295288
if let Some(value) = item.value_str() {
296-
value
289+
token::intern(&value)
297290
} else {
298291
let msg = if let Some(name) = item.name() {
299292
format!("associated value expected for `{}`", name)

src/librustc_trans/assert_module_sources.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
3030
use rustc::ty::TyCtxt;
3131
use syntax::ast;
32-
use syntax::parse::token::InternedString;
32+
use syntax::parse::token;
3333

3434
use {ModuleSource, ModuleTranslation};
3535

@@ -77,7 +77,7 @@ impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> {
7777
}
7878

7979
let mname = self.field(attr, MODULE);
80-
let mtrans = self.modules.iter().find(|mtrans| &mtrans.name[..] == &mname[..]);
80+
let mtrans = self.modules.iter().find(|mtrans| *mtrans.name == *mname.as_str());
8181
let mtrans = match mtrans {
8282
Some(m) => m,
8383
None => {
@@ -113,11 +113,11 @@ impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> {
113113
}
114114
}
115115

116-
fn field(&self, attr: &ast::Attribute, name: &str) -> InternedString {
116+
fn field(&self, attr: &ast::Attribute, name: &str) -> ast::Name {
117117
for item in attr.meta_item_list().unwrap_or(&[]) {
118118
if item.check_name(name) {
119119
if let Some(value) = item.value_str() {
120-
return value;
120+
return token::intern(&value);
121121
} else {
122122
self.tcx.sess.span_fatal(
123123
item.span,
@@ -137,7 +137,7 @@ impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> {
137137
let config = &self.tcx.sess.parse_sess.config;
138138
let value = self.field(attr, CFG);
139139
debug!("check_config(config={:?}, value={:?})", config, value);
140-
if config.iter().any(|c| c.check_name(&value[..])) {
140+
if config.iter().any(|&(name, _)| name == value) {
141141
debug!("check_config: matched");
142142
return true;
143143
}

src/libsyntax/ast.rs

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use print::pprust;
2525
use ptr::P;
2626
use tokenstream::{TokenTree};
2727

28+
use std::collections::HashSet;
2829
use std::fmt;
2930
use std::rc::Rc;
3031
use std::u32;
@@ -485,7 +486,7 @@ pub struct WhereEqPredicate {
485486

486487
/// The set of MetaItems that define the compilation environment of the crate,
487488
/// used to drive conditional compilation
488-
pub type CrateConfig = Vec<P<MetaItem>>;
489+
pub type CrateConfig = HashSet<(Name, Option<InternedString>)>;
489490

490491
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
491492
pub struct Crate {
@@ -519,7 +520,7 @@ pub type MetaItem = Spanned<MetaItemKind>;
519520
/// A compile-time attribute item.
520521
///
521522
/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
522-
#[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
523+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
523524
pub enum MetaItemKind {
524525
/// Word meta item.
525526
///
@@ -535,34 +536,6 @@ pub enum MetaItemKind {
535536
NameValue(Name, Lit),
536537
}
537538

538-
// can't be derived because the MetaItemKind::List requires an unordered comparison
539-
impl PartialEq for MetaItemKind {
540-
fn eq(&self, other: &MetaItemKind) -> bool {
541-
use self::MetaItemKind::*;
542-
match *self {
543-
Word(ref ns) => match *other {
544-
Word(ref no) => (*ns) == (*no),
545-
_ => false
546-
},
547-
List(ref ns, ref miss) => match *other {
548-
List(ref no, ref miso) => {
549-
ns == no &&
550-
miss.iter().all(|mi| {
551-
miso.iter().any(|x| x.node == mi.node)
552-
})
553-
}
554-
_ => false
555-
},
556-
NameValue(ref ns, ref vs) => match *other {
557-
NameValue(ref no, ref vo) => {
558-
(*ns) == (*no) && vs.node == vo.node
559-
}
560-
_ => false
561-
},
562-
}
563-
}
564-
}
565-
566539
/// A Block (`{ .. }`).
567540
///
568541
/// E.g. `{ .. }` as in `fn foo() { .. }`

0 commit comments

Comments
 (0)