Skip to content

Commit

Permalink
syntax: Conditionally deriving(Hash) with Writers
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
alexcrichton committed Mar 7, 2014
1 parent bec7b76 commit 0a84132
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 97 deletions.
6 changes: 5 additions & 1 deletion src/librustc/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 6 additions & 1 deletion src/librustc/front/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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),
Expand Down
21 changes: 19 additions & 2 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<W:Writer> Hash<W> for intern_key {
fn hash(&self, s: &mut W) {
unsafe { (*self.sty).hash(s) }
Expand Down Expand Up @@ -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<HashMap<intern_key, ~t_box_>>,
#[cfg(not(stage0))]
interner: RefCell<HashMap<intern_key, ~t_box_, ::util::nodemap::FnvHasher>>,
next_id: Cell<uint>,
cstore: @metadata::cstore::CStore,
Expand Down Expand Up @@ -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<intern_key, ~t_box_> {
HashMap::new()
}
#[cfg(not(stage0))]
fn hasher() -> HashMap<intern_key, ~t_box_, ::util::nodemap::FnvHasher> {
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,
Expand Down
49 changes: 48 additions & 1 deletion src/librustc/util/nodemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,84 @@ use std::hash::{Hasher, Hash};
use std::io;
use syntax::ast;

#[cfg(not(stage0))]
pub type NodeMap<T> = HashMap<ast::NodeId, T, FnvHasher>;
#[cfg(not(stage0))]
pub type DefIdMap<T> = HashMap<ast::DefId, T, FnvHasher>;
#[cfg(not(stage0))]
pub type NodeSet = HashSet<ast::NodeId, FnvHasher>;
#[cfg(not(stage0))]
pub type DefIdSet = HashSet<ast::DefId, FnvHasher>;

// Hacks to get good names
#[cfg(not(stage0))]
pub mod NodeMap {
use collections::HashMap;
pub fn new<T>() -> super::NodeMap<T> {
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<T>() -> super::DefIdMap<T> {
HashMap::with_hasher(super::FnvHasher)
}
}
#[cfg(not(stage0))]
pub mod DefIdSet {
use collections::HashSet;
pub fn new() -> super::DefIdSet {
HashSet::with_hasher(super::FnvHasher)
}
}

#[cfg(stage0)]
pub type NodeMap<T> = HashMap<ast::NodeId, T>;
#[cfg(stage0)]
pub type DefIdMap<T> = HashMap<ast::DefId, T>;
#[cfg(stage0)]
pub type NodeSet = HashSet<ast::NodeId>;
#[cfg(stage0)]
pub type DefIdSet = HashSet<ast::DefId>;

// Hacks to get good names
#[cfg(stage0)]
pub mod NodeMap {
use collections::HashMap;
pub fn new<T>() -> super::NodeMap<T> {
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<T>() -> super::DefIdMap<T> {
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
Expand All @@ -56,7 +103,7 @@ pub mod DefIdSet {
#[deriving(Clone)]
pub struct FnvHasher;

struct FnvState(u64);
pub struct FnvState(u64);

impl Hasher<FnvState> for FnvHasher {
fn hash<T: Hash<FnvState>>(&self, t: &T) -> u64 {
Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,21 +283,21 @@ 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<ast::Ident> ,
trace_mac: bool
}

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
}
}
Expand Down
20 changes: 16 additions & 4 deletions src/libsyntax/ext/deriving/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
39 changes: 30 additions & 9 deletions src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,15 +443,15 @@ 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,
_ => unreachable!()
};
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(),
Expand All @@ -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
};
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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 (){
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)];

Expand Down
Loading

5 comments on commit 0a84132

@bors
Copy link
Contributor

@bors bors commented on 0a84132 Mar 7, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from brson
at alexcrichton@0a84132

@bors
Copy link
Contributor

@bors bors commented on 0a84132 Mar 7, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging alexcrichton/rust/speedy-hash = 0a84132 into auto

@bors
Copy link
Contributor

@bors bors commented on 0a84132 Mar 7, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alexcrichton/rust/speedy-hash = 0a84132 merged ok, testing candidate = 5862c0c

@bors
Copy link
Contributor

@bors bors commented on 0a84132 Mar 7, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 0a84132 Mar 7, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 5862c0c

Please sign in to comment.