summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-02-28 23:17:38 -0800
committerAlex Crichton <alex@alexcrichton.com>2014-03-06 18:11:02 -0800
commit0a8413292845f527b8cf6bb2d02c9923f782ff37 (patch)
tree6c4877cab523a54019eb8e15820c8531913139cc /src/libsyntax/ext
parentbec7b766fbbc9b56a1608e2573390e3894519840 (diff)
downloadrust-0a8413292845f527b8cf6bb2d02c9923f782ff37.tar.gz
rust-0a8413292845f527b8cf6bb2d02c9923f782ff37.zip
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.
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/base.rs6
-rw-r--r--src/libsyntax/ext/deriving/hash.rs20
-rw-r--r--src/libsyntax/ext/expand.rs39
3 files changed, 49 insertions, 16 deletions
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<ast::Ident> ,
     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 {