about summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/build.rs31
-rw-r--r--src/libsyntax/ext/deriving/rand.rs27
2 files changed, 49 insertions, 9 deletions
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index a62a1d121e2..21d67493cbf 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -74,6 +74,13 @@ pub trait AstBuilder {
     // statements
     fn stmt_expr(&self, expr: @ast::expr) -> @ast::stmt;
     fn stmt_let(&self, sp: span, mutbl: bool, ident: ast::ident, ex: @ast::expr) -> @ast::stmt;
+    fn stmt_let_typed(&self,
+                      sp: span,
+                      mutbl: bool,
+                      ident: ast::ident,
+                      typ: ast::Ty,
+                      ex: @ast::expr)
+                      -> @ast::stmt;
 
     // blocks
     fn block(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> ast::Block;
@@ -241,8 +248,8 @@ impl AstBuilder for @ExtCtxt {
                 types: ~[ast::Ty])
                 -> ast::Path {
         let last_identifier = idents.pop();
-        let mut segments: ~[ast::PathSegment] = idents.consume_iter()
-                                                      .transform(|ident| {
+        let mut segments: ~[ast::PathSegment] = idents.move_iter()
+                                                      .map(|ident| {
             ast::PathSegment {
                 identifier: ident,
                 lifetime: None,
@@ -400,6 +407,26 @@ impl AstBuilder for @ExtCtxt {
         @respan(sp, ast::stmt_decl(@decl, self.next_id()))
     }
 
+    fn stmt_let_typed(&self,
+                      sp: span,
+                      mutbl: bool,
+                      ident: ast::ident,
+                      typ: ast::Ty,
+                      ex: @ast::expr)
+                      -> @ast::stmt {
+        let pat = self.pat_ident(sp, ident);
+        let local = @ast::Local {
+            is_mutbl: mutbl,
+            ty: typ,
+            pat: pat,
+            init: Some(ex),
+            id: self.next_id(),
+            span: sp,
+        };
+        let decl = respan(sp, ast::decl_local(local));
+        @respan(sp, ast::stmt_decl(@decl, self.next_id()))
+    }
+
     fn block(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@expr>) -> ast::Block {
         self.block_all(span, ~[], stmts, expr)
     }
diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs
index e55a96f77ff..9f86fe7d7f2 100644
--- a/src/libsyntax/ext/deriving/rand.rs
+++ b/src/libsyntax/ext/deriving/rand.rs
@@ -76,24 +76,34 @@ fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
 
             let variant_count = cx.expr_uint(span, variants.len());
 
-            // need to specify the uint-ness of the random number
-            let uint_ty = cx.ty_ident(span, cx.ident_of("uint"));
             let r_ty = cx.ty_ident(span, cx.ident_of("R"));
             let rand_name = cx.path_all(span,
                                         true,
                                         rand_ident.clone(),
                                         None,
-                                        ~[ uint_ty, r_ty ]);
+                                        ~[]);
             let rand_name = cx.expr_path(rand_name);
 
-            // ::std::rand::Rand::rand::<uint>(rng)
+            // ::std::rand::Rand::rand(rng)
             let rv_call = cx.expr_call(span,
                                        rand_name,
                                        ~[ rng[0].duplicate(cx) ]);
 
+            // need to specify the uint-ness of the random number
+            let uint_ty = cx.ty_ident(span, cx.ident_of("uint"));
+            let value_ident = cx.ident_of("__value");
+            let let_statement = cx.stmt_let_typed(span,
+                                                  false,
+                                                  value_ident,
+                                                  uint_ty,
+                                                  rv_call);
+
             // rand() % variants.len()
-            let rand_variant = cx.expr_binary(span, ast::rem,
-                                              rv_call, variant_count);
+            let value_ref = cx.expr_ident(span, value_ident);
+            let rand_variant = cx.expr_binary(span,
+                                              ast::rem,
+                                              value_ref,
+                                              variant_count);
 
             let mut arms = do variants.iter().enumerate().map |(i, id_sum)| {
                 let i_expr = cx.expr_uint(span, i);
@@ -111,7 +121,10 @@ fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
             // _ => {} at the end. Should never occur
             arms.push(cx.arm_unreachable(span));
 
-            cx.expr_match(span, rand_variant, arms)
+            let match_expr = cx.expr_match(span, rand_variant, arms);
+
+            let block = cx.block(span, ~[ let_statement ], Some(match_expr));
+            cx.expr_block(block)
         }
         _ => cx.bug("Non-static method in `deriving(Rand)`")
     };