Skip to content

Commit 0a84132

Browse files
committed
syntax: Conditionally deriving(Hash) with Writers
If #[feature(default_type_parameters)] is enabled for a crate, then deriving(Hash) will expand with Hash<W: Writer> instead of Hash<SipState> so more hash algorithms can be used.
1 parent bec7b76 commit 0a84132

File tree

9 files changed

+128
-97
lines changed

9 files changed

+128
-97
lines changed

src/librustc/driver/driver.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,12 @@ pub fn phase_2_configure_and_expand(sess: Session,
224224
front::config::strip_unconfigured_items(krate));
225225

226226
krate = time(time_passes, "expansion", krate, |krate| {
227+
let cfg = syntax::ext::expand::ExpansionConfig {
228+
loader: loader,
229+
deriving_hash_type_parameter: sess.features.default_type_params.get()
230+
};
227231
syntax::ext::expand::expand_crate(sess.parse_sess,
228-
loader,
232+
cfg,
229233
krate)
230234
});
231235
// dump the syntax-time crates

src/librustc/front/test.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use syntax::attr;
2828
use syntax::codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute};
2929
use syntax::codemap;
3030
use syntax::ext::base::ExtCtxt;
31+
use syntax::ext::expand::ExpansionConfig;
3132
use syntax::fold::Folder;
3233
use syntax::fold;
3334
use syntax::opt_vec;
@@ -165,7 +166,11 @@ fn generate_test_harness(sess: session::Session, krate: ast::Crate)
165166
let loader = &mut Loader::new(sess);
166167
let mut cx: TestCtxt = TestCtxt {
167168
sess: sess,
168-
ext_cx: ExtCtxt::new(sess.parse_sess, sess.opts.cfg.clone(), loader),
169+
ext_cx: ExtCtxt::new(sess.parse_sess, sess.opts.cfg.clone(),
170+
ExpansionConfig {
171+
loader: loader,
172+
deriving_hash_type_parameter: false,
173+
}),
169174
path: RefCell::new(~[]),
170175
testfns: RefCell::new(~[]),
171176
is_test_crate: is_test_crate(&krate),

src/librustc/middle/ty.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,13 @@ impl cmp::Eq for intern_key {
179179
}
180180
}
181181

182+
#[cfg(stage0)]
183+
impl Hash for intern_key {
184+
fn hash(&self, s: &mut sip::SipState) {
185+
unsafe { (*self.sty).hash(s) }
186+
}
187+
}
188+
#[cfg(not(stage0))]
182189
impl<W:Writer> Hash<W> for intern_key {
183190
fn hash(&self, s: &mut W) {
184191
unsafe { (*self.sty).hash(s) }
@@ -251,6 +258,9 @@ pub struct ctxt_ {
251258
diag: @syntax::diagnostic::SpanHandler,
252259
// Specifically use a speedy hash algorithm for this hash map, it's used
253260
// quite often.
261+
#[cfg(stage0)]
262+
interner: RefCell<HashMap<intern_key, ~t_box_>>,
263+
#[cfg(not(stage0))]
254264
interner: RefCell<HashMap<intern_key, ~t_box_, ::util::nodemap::FnvHasher>>,
255265
next_id: Cell<uint>,
256266
cstore: @metadata::cstore::CStore,
@@ -1081,12 +1091,19 @@ pub fn mk_ctxt(s: session::Session,
10811091
region_maps: middle::region::RegionMaps,
10821092
lang_items: @middle::lang_items::LanguageItems)
10831093
-> ctxt {
1084-
1094+
#[cfg(stage0)]
1095+
fn hasher() -> HashMap<intern_key, ~t_box_> {
1096+
HashMap::new()
1097+
}
1098+
#[cfg(not(stage0))]
1099+
fn hasher() -> HashMap<intern_key, ~t_box_, ::util::nodemap::FnvHasher> {
1100+
HashMap::with_hasher(::util::nodemap::FnvHasher)
1101+
}
10851102
@ctxt_ {
10861103
named_region_map: named_region_map,
10871104
item_variance_map: RefCell::new(DefIdMap::new()),
10881105
diag: s.diagnostic(),
1089-
interner: RefCell::new(HashMap::with_hasher(::util::nodemap::FnvHasher)),
1106+
interner: RefCell::new(hasher()),
10901107
next_id: Cell::new(primitives::LAST_PRIMITIVE_ID),
10911108
cstore: s.cstore,
10921109
sess: s,

src/librustc/util/nodemap.rs

+48-1
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,84 @@ use std::hash::{Hasher, Hash};
1515
use std::io;
1616
use syntax::ast;
1717

18+
#[cfg(not(stage0))]
1819
pub type NodeMap<T> = HashMap<ast::NodeId, T, FnvHasher>;
20+
#[cfg(not(stage0))]
1921
pub type DefIdMap<T> = HashMap<ast::DefId, T, FnvHasher>;
22+
#[cfg(not(stage0))]
2023
pub type NodeSet = HashSet<ast::NodeId, FnvHasher>;
24+
#[cfg(not(stage0))]
2125
pub type DefIdSet = HashSet<ast::DefId, FnvHasher>;
2226

2327
// Hacks to get good names
28+
#[cfg(not(stage0))]
2429
pub mod NodeMap {
2530
use collections::HashMap;
2631
pub fn new<T>() -> super::NodeMap<T> {
2732
HashMap::with_hasher(super::FnvHasher)
2833
}
2934
}
35+
#[cfg(not(stage0))]
3036
pub mod NodeSet {
3137
use collections::HashSet;
3238
pub fn new() -> super::NodeSet {
3339
HashSet::with_hasher(super::FnvHasher)
3440
}
3541
}
42+
#[cfg(not(stage0))]
3643
pub mod DefIdMap {
3744
use collections::HashMap;
3845
pub fn new<T>() -> super::DefIdMap<T> {
3946
HashMap::with_hasher(super::FnvHasher)
4047
}
4148
}
49+
#[cfg(not(stage0))]
4250
pub mod DefIdSet {
4351
use collections::HashSet;
4452
pub fn new() -> super::DefIdSet {
4553
HashSet::with_hasher(super::FnvHasher)
4654
}
4755
}
4856

57+
#[cfg(stage0)]
58+
pub type NodeMap<T> = HashMap<ast::NodeId, T>;
59+
#[cfg(stage0)]
60+
pub type DefIdMap<T> = HashMap<ast::DefId, T>;
61+
#[cfg(stage0)]
62+
pub type NodeSet = HashSet<ast::NodeId>;
63+
#[cfg(stage0)]
64+
pub type DefIdSet = HashSet<ast::DefId>;
65+
66+
// Hacks to get good names
67+
#[cfg(stage0)]
68+
pub mod NodeMap {
69+
use collections::HashMap;
70+
pub fn new<T>() -> super::NodeMap<T> {
71+
HashMap::new()
72+
}
73+
}
74+
#[cfg(stage0)]
75+
pub mod NodeSet {
76+
use collections::HashSet;
77+
pub fn new() -> super::NodeSet {
78+
HashSet::new()
79+
}
80+
}
81+
#[cfg(stage0)]
82+
pub mod DefIdMap {
83+
use collections::HashMap;
84+
pub fn new<T>() -> super::DefIdMap<T> {
85+
HashMap::new()
86+
}
87+
}
88+
#[cfg(stage0)]
89+
pub mod DefIdSet {
90+
use collections::HashSet;
91+
pub fn new() -> super::DefIdSet {
92+
HashSet::new()
93+
}
94+
}
95+
4996
/// A speedy hash algorithm for node ids and def ids. The hashmap in
5097
/// libcollections by default uses SipHash which isn't quite as speedy as we
5198
/// want. In the compiler we're not really worried about DOS attempts, so we
@@ -56,7 +103,7 @@ pub mod DefIdSet {
56103
#[deriving(Clone)]
57104
pub struct FnvHasher;
58105

59-
struct FnvState(u64);
106+
pub struct FnvState(u64);
60107

61108
impl Hasher<FnvState> for FnvHasher {
62109
fn hash<T: Hash<FnvState>>(&self, t: &T) -> u64 {

src/libsyntax/ext/base.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -283,21 +283,21 @@ pub struct ExtCtxt<'a> {
283283
parse_sess: @parse::ParseSess,
284284
cfg: ast::CrateConfig,
285285
backtrace: Option<@ExpnInfo>,
286-
loader: &'a mut CrateLoader,
286+
ecfg: expand::ExpansionConfig<'a>,
287287

288288
mod_path: Vec<ast::Ident> ,
289289
trace_mac: bool
290290
}
291291

292292
impl<'a> ExtCtxt<'a> {
293293
pub fn new<'a>(parse_sess: @parse::ParseSess, cfg: ast::CrateConfig,
294-
loader: &'a mut CrateLoader) -> ExtCtxt<'a> {
294+
ecfg: expand::ExpansionConfig<'a>) -> ExtCtxt<'a> {
295295
ExtCtxt {
296296
parse_sess: parse_sess,
297297
cfg: cfg,
298298
backtrace: None,
299-
loader: loader,
300299
mod_path: Vec::new(),
300+
ecfg: ecfg,
301301
trace_mac: false
302302
}
303303
}

src/libsyntax/ext/deriving/hash.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,31 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
2222
item: @Item,
2323
push: |@Item|) {
2424

25+
let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter {
26+
(Path::new_(vec!("std", "hash", "Hash"), None,
27+
vec!(~Literal(Path::new_local("__H"))), true),
28+
LifetimeBounds {
29+
lifetimes: Vec::new(),
30+
bounds: vec!(("__H", vec!(Path::new(vec!("std", "io", "Writer"))))),
31+
},
32+
Path::new_local("__H"))
33+
} else {
34+
(Path::new(vec!("std", "hash", "Hash")),
35+
LifetimeBounds::empty(),
36+
Path::new(vec!("std", "hash", "sip", "SipState")))
37+
};
2538
let hash_trait_def = TraitDef {
2639
span: span,
2740
attributes: Vec::new(),
28-
path: Path::new(vec!("std", "hash", "Hash")),
41+
path: path,
2942
additional_bounds: Vec::new(),
30-
generics: LifetimeBounds::empty(),
43+
generics: generics,
3144
methods: vec!(
3245
MethodDef {
3346
name: "hash",
3447
generics: LifetimeBounds::empty(),
3548
explicit_self: borrowed_explicit_self(),
36-
args: vec!(Ptr(~Literal(Path::new(vec!("std", "hash", "sip", "SipState"))),
37-
Borrowed(None, MutMutable))),
49+
args: vec!(Ptr(~Literal(args), Borrowed(None, MutMutable))),
3850
ret_ty: nil_ty(),
3951
inline: true,
4052
const_nonmatching: false,

src/libsyntax/ext/expand.rs

+30-9
Original file line numberDiff line numberDiff line change
@@ -443,15 +443,15 @@ pub fn expand_view_item(vi: &ast::ViewItem,
443443
}
444444

445445
fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
446-
let MacroCrate { lib, cnum } = fld.cx.loader.load_crate(krate);
446+
let MacroCrate { lib, cnum } = fld.cx.ecfg.loader.load_crate(krate);
447447

448448
let crate_name = match krate.node {
449449
ast::ViewItemExternMod(name, _, _) => name,
450450
_ => unreachable!()
451451
};
452452
let name = format!("<{} macros>", token::get_ident(crate_name));
453453

454-
let exported_macros = fld.cx.loader.get_exported_macros(cnum);
454+
let exported_macros = fld.cx.ecfg.loader.get_exported_macros(cnum);
455455
for source in exported_macros.iter() {
456456
let item = parse::parse_item_from_source_str(name.clone(),
457457
(*source).clone(),
@@ -468,7 +468,7 @@ fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
468468
// Make sure the path contains a / or the linker will search for it.
469469
let path = os::make_absolute(&path);
470470

471-
let registrar = match fld.cx.loader.get_registrar_symbol(cnum) {
471+
let registrar = match fld.cx.ecfg.loader.get_registrar_symbol(cnum) {
472472
Some(registrar) => registrar,
473473
None => return
474474
};
@@ -823,10 +823,15 @@ impl<'a> Folder for MacroExpander<'a> {
823823
}
824824
}
825825

826+
pub struct ExpansionConfig<'a> {
827+
loader: &'a mut CrateLoader,
828+
deriving_hash_type_parameter: bool,
829+
}
830+
826831
pub fn expand_crate(parse_sess: @parse::ParseSess,
827-
loader: &mut CrateLoader,
832+
cfg: ExpansionConfig,
828833
c: Crate) -> Crate {
829-
let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), loader);
834+
let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
830835
let mut expander = MacroExpander {
831836
extsbox: syntax_expander_table(),
832837
cx: &mut cx,
@@ -995,7 +1000,11 @@ mod test {
9951000
Vec::new(),sess);
9961001
// should fail:
9971002
let mut loader = ErrLoader;
998-
expand_crate(sess,&mut loader,crate_ast);
1003+
let cfg = ::syntax::ext::expand::ExpansionConfig {
1004+
loader: &mut loader,
1005+
deriving_hash_type_parameter: false,
1006+
};
1007+
expand_crate(sess,cfg,crate_ast);
9991008
}
10001009
10011010
// make sure that macros can leave scope for modules
@@ -1010,7 +1019,11 @@ mod test {
10101019
Vec::new(),sess);
10111020
// should fail:
10121021
let mut loader = ErrLoader;
1013-
expand_crate(sess,&mut loader,crate_ast);
1022+
let cfg = ::syntax::ext::expand::ExpansionConfig {
1023+
loader: &mut loader,
1024+
deriving_hash_type_parameter: false,
1025+
};
1026+
expand_crate(sess,cfg,crate_ast);
10141027
}
10151028
10161029
// macro_escape modules shouldn't cause macros to leave scope
@@ -1024,7 +1037,11 @@ mod test {
10241037
Vec::new(), sess);
10251038
// should fail:
10261039
let mut loader = ErrLoader;
1027-
expand_crate(sess, &mut loader, crate_ast);
1040+
let cfg = ::syntax::ext::expand::ExpansionConfig {
1041+
loader: &mut loader,
1042+
deriving_hash_type_parameter: false,
1043+
};
1044+
expand_crate(sess, cfg, crate_ast);
10281045
}
10291046
10301047
#[test] fn test_contains_flatten (){
@@ -1062,7 +1079,11 @@ mod test {
10621079
let (crate_ast,ps) = string_to_crate_and_sess(crate_str);
10631080
// the cfg argument actually does matter, here...
10641081
let mut loader = ErrLoader;
1065-
expand_crate(ps,&mut loader,crate_ast)
1082+
let cfg = ::syntax::ext::expand::ExpansionConfig {
1083+
loader: &mut loader,
1084+
deriving_hash_type_parameter: false,
1085+
};
1086+
expand_crate(ps,cfg,crate_ast)
10661087
}
10671088

10681089
//fn expand_and_resolve(crate_str: @str) -> ast::crate {

src/libsyntax/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ This API is completely unstable and subject to change.
2626
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
2727
html_root_url = "http://static.rust-lang.org/doc/master")];
2828

29-
#[feature(macro_rules, globs, managed_boxes)];
29+
#[feature(macro_rules, globs, managed_boxes, default_type_params)];
3030
#[allow(unknown_features)];// Note: remove it after a snapshot.
3131
#[feature(quote)];
3232

0 commit comments

Comments
 (0)