diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 58eb2119c6a..5b335d163d8 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -224,8 +224,12 @@ pub fn phase_2_configure_and_expand(sess: Session, front::config::strip_unconfigured_items(krate)); krate = time(time_passes, "expansion", krate, |krate| { + let cfg = syntax::ext::expand::ExpansionConfig { + loader: loader, + deriving_hash_type_parameter: sess.features.default_type_params.get() + }; syntax::ext::expand::expand_crate(sess.parse_sess, - loader, + cfg, krate) }); // dump the syntax-time crates diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index 493fd3522d5..ecbb704684b 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -28,6 +28,7 @@ use syntax::attr; use syntax::codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute}; use syntax::codemap; use syntax::ext::base::ExtCtxt; +use syntax::ext::expand::ExpansionConfig; use syntax::fold::Folder; use syntax::fold; use syntax::opt_vec; @@ -165,7 +166,11 @@ fn generate_test_harness(sess: session::Session, krate: ast::Crate) let loader = &mut Loader::new(sess); let mut cx: TestCtxt = TestCtxt { sess: sess, - ext_cx: ExtCtxt::new(sess.parse_sess, sess.opts.cfg.clone(), loader), + ext_cx: ExtCtxt::new(sess.parse_sess, sess.opts.cfg.clone(), + ExpansionConfig { + loader: loader, + deriving_hash_type_parameter: false, + }), path: RefCell::new(~[]), testfns: RefCell::new(~[]), is_test_crate: is_test_crate(&krate), diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index a83a03c9838..9442a2144bd 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -179,6 +179,13 @@ impl cmp::Eq for intern_key { } } +#[cfg(stage0)] +impl Hash for intern_key { + fn hash(&self, s: &mut sip::SipState) { + unsafe { (*self.sty).hash(s) } + } +} +#[cfg(not(stage0))] impl Hash for intern_key { fn hash(&self, s: &mut W) { unsafe { (*self.sty).hash(s) } @@ -251,6 +258,9 @@ pub struct ctxt_ { diag: @syntax::diagnostic::SpanHandler, // Specifically use a speedy hash algorithm for this hash map, it's used // quite often. + #[cfg(stage0)] + interner: RefCell>, + #[cfg(not(stage0))] interner: RefCell>, next_id: Cell, cstore: @metadata::cstore::CStore, @@ -1081,12 +1091,19 @@ pub fn mk_ctxt(s: session::Session, region_maps: middle::region::RegionMaps, lang_items: @middle::lang_items::LanguageItems) -> ctxt { - + #[cfg(stage0)] + fn hasher() -> HashMap { + HashMap::new() + } + #[cfg(not(stage0))] + fn hasher() -> HashMap { + HashMap::with_hasher(::util::nodemap::FnvHasher) + } @ctxt_ { named_region_map: named_region_map, item_variance_map: RefCell::new(DefIdMap::new()), diag: s.diagnostic(), - interner: RefCell::new(HashMap::with_hasher(::util::nodemap::FnvHasher)), + interner: RefCell::new(hasher()), next_id: Cell::new(primitives::LAST_PRIMITIVE_ID), cstore: s.cstore, sess: s, diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs index 84b579a1fb0..fe24733aba2 100644 --- a/src/librustc/util/nodemap.rs +++ b/src/librustc/util/nodemap.rs @@ -15,30 +15,38 @@ use std::hash::{Hasher, Hash}; use std::io; use syntax::ast; +#[cfg(not(stage0))] pub type NodeMap = HashMap; +#[cfg(not(stage0))] pub type DefIdMap = HashMap; +#[cfg(not(stage0))] pub type NodeSet = HashSet; +#[cfg(not(stage0))] pub type DefIdSet = HashSet; // Hacks to get good names +#[cfg(not(stage0))] pub mod NodeMap { use collections::HashMap; pub fn new() -> super::NodeMap { HashMap::with_hasher(super::FnvHasher) } } +#[cfg(not(stage0))] pub mod NodeSet { use collections::HashSet; pub fn new() -> super::NodeSet { HashSet::with_hasher(super::FnvHasher) } } +#[cfg(not(stage0))] pub mod DefIdMap { use collections::HashMap; pub fn new() -> super::DefIdMap { HashMap::with_hasher(super::FnvHasher) } } +#[cfg(not(stage0))] pub mod DefIdSet { use collections::HashSet; pub fn new() -> super::DefIdSet { @@ -46,6 +54,45 @@ pub mod DefIdSet { } } +#[cfg(stage0)] +pub type NodeMap = HashMap; +#[cfg(stage0)] +pub type DefIdMap = HashMap; +#[cfg(stage0)] +pub type NodeSet = HashSet; +#[cfg(stage0)] +pub type DefIdSet = HashSet; + +// Hacks to get good names +#[cfg(stage0)] +pub mod NodeMap { + use collections::HashMap; + pub fn new() -> super::NodeMap { + HashMap::new() + } +} +#[cfg(stage0)] +pub mod NodeSet { + use collections::HashSet; + pub fn new() -> super::NodeSet { + HashSet::new() + } +} +#[cfg(stage0)] +pub mod DefIdMap { + use collections::HashMap; + pub fn new() -> super::DefIdMap { + HashMap::new() + } +} +#[cfg(stage0)] +pub mod DefIdSet { + use collections::HashSet; + pub fn new() -> super::DefIdSet { + HashSet::new() + } +} + /// A speedy hash algorithm for node ids and def ids. The hashmap in /// libcollections by default uses SipHash which isn't quite as speedy as we /// want. In the compiler we're not really worried about DOS attempts, so we @@ -56,7 +103,7 @@ pub mod DefIdSet { #[deriving(Clone)] pub struct FnvHasher; -struct FnvState(u64); +pub struct FnvState(u64); impl Hasher for FnvHasher { fn hash>(&self, t: &T) -> u64 { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 79068d40469..459c0d1d0e3 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -283,7 +283,7 @@ pub struct ExtCtxt<'a> { parse_sess: @parse::ParseSess, cfg: ast::CrateConfig, backtrace: Option<@ExpnInfo>, - loader: &'a mut CrateLoader, + ecfg: expand::ExpansionConfig<'a>, mod_path: Vec , trace_mac: bool @@ -291,13 +291,13 @@ pub struct ExtCtxt<'a> { impl<'a> ExtCtxt<'a> { pub fn new<'a>(parse_sess: @parse::ParseSess, cfg: ast::CrateConfig, - loader: &'a mut CrateLoader) -> ExtCtxt<'a> { + ecfg: expand::ExpansionConfig<'a>) -> ExtCtxt<'a> { ExtCtxt { parse_sess: parse_sess, cfg: cfg, backtrace: None, - loader: loader, mod_path: Vec::new(), + ecfg: ecfg, trace_mac: false } } diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs index 1d6cfab120d..299989d5fe6 100644 --- a/src/libsyntax/ext/deriving/hash.rs +++ b/src/libsyntax/ext/deriving/hash.rs @@ -22,19 +22,31 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt, item: @Item, push: |@Item|) { + let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter { + (Path::new_(vec!("std", "hash", "Hash"), None, + vec!(~Literal(Path::new_local("__H"))), true), + LifetimeBounds { + lifetimes: Vec::new(), + bounds: vec!(("__H", vec!(Path::new(vec!("std", "io", "Writer"))))), + }, + Path::new_local("__H")) + } else { + (Path::new(vec!("std", "hash", "Hash")), + LifetimeBounds::empty(), + Path::new(vec!("std", "hash", "sip", "SipState"))) + }; let hash_trait_def = TraitDef { span: span, attributes: Vec::new(), - path: Path::new(vec!("std", "hash", "Hash")), + path: path, additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), + generics: generics, methods: vec!( MethodDef { name: "hash", generics: LifetimeBounds::empty(), explicit_self: borrowed_explicit_self(), - args: vec!(Ptr(~Literal(Path::new(vec!("std", "hash", "sip", "SipState"))), - Borrowed(None, MutMutable))), + args: vec!(Ptr(~Literal(args), Borrowed(None, MutMutable))), ret_ty: nil_ty(), inline: true, const_nonmatching: false, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 8b23de235b8..12eaa759ede 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -443,7 +443,7 @@ pub fn expand_view_item(vi: &ast::ViewItem, } fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) { - let MacroCrate { lib, cnum } = fld.cx.loader.load_crate(krate); + let MacroCrate { lib, cnum } = fld.cx.ecfg.loader.load_crate(krate); let crate_name = match krate.node { ast::ViewItemExternMod(name, _, _) => name, @@ -451,7 +451,7 @@ fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) { }; let name = format!("<{} macros>", token::get_ident(crate_name)); - let exported_macros = fld.cx.loader.get_exported_macros(cnum); + let exported_macros = fld.cx.ecfg.loader.get_exported_macros(cnum); for source in exported_macros.iter() { let item = parse::parse_item_from_source_str(name.clone(), (*source).clone(), @@ -468,7 +468,7 @@ fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) { // Make sure the path contains a / or the linker will search for it. let path = os::make_absolute(&path); - let registrar = match fld.cx.loader.get_registrar_symbol(cnum) { + let registrar = match fld.cx.ecfg.loader.get_registrar_symbol(cnum) { Some(registrar) => registrar, None => return }; @@ -823,10 +823,15 @@ impl<'a> Folder for MacroExpander<'a> { } } +pub struct ExpansionConfig<'a> { + loader: &'a mut CrateLoader, + deriving_hash_type_parameter: bool, +} + pub fn expand_crate(parse_sess: @parse::ParseSess, - loader: &mut CrateLoader, + cfg: ExpansionConfig, c: Crate) -> Crate { - let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), loader); + let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg); let mut expander = MacroExpander { extsbox: syntax_expander_table(), cx: &mut cx, @@ -995,7 +1000,11 @@ mod test { Vec::new(),sess); // should fail: let mut loader = ErrLoader; - expand_crate(sess,&mut loader,crate_ast); + let cfg = ::syntax::ext::expand::ExpansionConfig { + loader: &mut loader, + deriving_hash_type_parameter: false, + }; + expand_crate(sess,cfg,crate_ast); } // make sure that macros can leave scope for modules @@ -1010,7 +1019,11 @@ mod test { Vec::new(),sess); // should fail: let mut loader = ErrLoader; - expand_crate(sess,&mut loader,crate_ast); + let cfg = ::syntax::ext::expand::ExpansionConfig { + loader: &mut loader, + deriving_hash_type_parameter: false, + }; + expand_crate(sess,cfg,crate_ast); } // macro_escape modules shouldn't cause macros to leave scope @@ -1024,7 +1037,11 @@ mod test { Vec::new(), sess); // should fail: let mut loader = ErrLoader; - expand_crate(sess, &mut loader, crate_ast); + let cfg = ::syntax::ext::expand::ExpansionConfig { + loader: &mut loader, + deriving_hash_type_parameter: false, + }; + expand_crate(sess, cfg, crate_ast); } #[test] fn test_contains_flatten (){ @@ -1062,7 +1079,11 @@ mod test { let (crate_ast,ps) = string_to_crate_and_sess(crate_str); // the cfg argument actually does matter, here... let mut loader = ErrLoader; - expand_crate(ps,&mut loader,crate_ast) + let cfg = ::syntax::ext::expand::ExpansionConfig { + loader: &mut loader, + deriving_hash_type_parameter: false, + }; + expand_crate(ps,cfg,crate_ast) } //fn expand_and_resolve(crate_str: @str) -> ast::crate { diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 0d7e54bb69d..0d465e8475c 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -26,7 +26,7 @@ This API is completely unstable and subject to change. html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://static.rust-lang.org/doc/master")]; -#[feature(macro_rules, globs, managed_boxes)]; +#[feature(macro_rules, globs, managed_boxes, default_type_params)]; #[allow(unknown_features)];// Note: remove it after a snapshot. #[feature(quote)]; diff --git a/src/libsyntax/util/nodemap.rs b/src/libsyntax/util/nodemap.rs deleted file mode 100644 index e9ace61eb95..00000000000 --- a/src/libsyntax/util/nodemap.rs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! An efficient hash map for node IDs - -use collections::hashmap; -use collections::{HashMap, HashSet}; -use std::hash::{Hasher, Hash}; -use std::iter; -use ast; - -pub type NodeMap = HashMap; -pub type DefIdMap = HashMap; -pub type NodeSet = HashSet; -pub type DefIdSet = HashSet; - -#[deriving(Clone)] -struct NodeHasher; - -impl Hasher for NodeHasher { - fn hash>(&self, t: &T) -> u64 { - let mut last = 0; - t.hash(&mut last); - return last - } -} - -impl Hash for ast::NodeId { - fn hash(&self, state: &mut u64) { - *state = self.get() as u64; - } -} - -impl Hash for ast::DefId { - fn hash(&self, state: &mut u64) { - let ast::DefId { krate, node } = *self; - // assert that these two types are each 32 bits - let krate: u32 = krate; - let node: u32 = node; - *state = (krate << 32) as u64 | (node as u64); - } -} - -// Hacks to get good names -pub mod NodeMap { - use collections::HashMap; - pub fn new() -> super::NodeMap { - HashMap::with_hasher(super::NodeHasher) - } -} -pub mod NodeSet { - use collections::HashSet; - pub fn new() -> super::NodeSet { - HashSet::with_hasher(super::NodeHasher) - } -} -pub mod DefIdMap { - use collections::HashMap; - pub fn new() -> super::DefIdMap { - HashMap::with_hasher(super::NodeHasher) - } -} -pub mod DefIdSet { - use collections::HashSet; - pub fn new() -> super::DefIdSet { - HashSet::with_hasher(super::NodeHasher) - } -}