about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-08-08 11:38:10 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-08-27 18:47:57 -0700
commit8693943676487c01fa09f5f3daf0df6a1f71e24d (patch)
tree5aa978e4144d51f320d069d88fe0fad4ed40705e /src/libsyntax
parent3b6314c39bfc13b5a41c53f13c3fafa7ad91e062 (diff)
downloadrust-8693943676487c01fa09f5f3daf0df6a1f71e24d.tar.gz
rust-8693943676487c01fa09f5f3daf0df6a1f71e24d.zip
librustc: Ensure that type parameters are in the right positions in paths.
This removes the stacking of type parameters that occurs when invoking
trait methods, and fixes all places in the standard library that were
relying on it. It is somewhat awkward in places; I think we'll probably
want something like the `Foo::<for T>::new()` syntax.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs12
-rw-r--r--src/libsyntax/ext/build.rs31
-rw-r--r--src/libsyntax/ext/deriving/rand.rs27
-rw-r--r--src/libsyntax/parse/mod.rs4
-rw-r--r--src/libsyntax/parse/parser.rs12
-rw-r--r--src/libsyntax/visit.rs2
6 files changed, 66 insertions, 22 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 0a13f1a8a5e..44015a8b443 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -175,11 +175,15 @@ impl Generics {
 }
 
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
+pub enum MethodProvenance {
+    FromTrait(def_id),
+    FromImpl(def_id),
+}
+
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum def {
     def_fn(def_id, purity),
-    def_static_method(/* method */ def_id,
-                      /* trait */  Option<def_id>,
-                      purity),
+    def_static_method(/* method */ def_id, MethodProvenance, purity),
     def_self(NodeId),
     def_self_ty(/* trait id */ NodeId),
     def_mod(def_id),
@@ -716,7 +720,7 @@ impl ToStr for float_ty {
 }
 
 // NB Eq method appears below.
-#[deriving(Clone, Eq, Encodable, Decodable,IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct Ty {
     id: NodeId,
     node: ty_,
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)`")
     };
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 73e17f551c9..1a7fc558dcd 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -399,8 +399,8 @@ mod test {
                                     types: ~[],
                                 }
                             ]
-                        },
-                        span: sp(0, 6))
+                        }),
+                    span: sp(0, 6)
                    })
     }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 0882a5e3143..8ca858b7935 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1374,7 +1374,7 @@ impl Parser {
             _ => None,
         };
         match found {
-            Some(INTERPOLATED(token::nt_path(path))) => {
+            Some(INTERPOLATED(token::nt_path(~path))) => {
                 return PathAndBounds {
                     path: path,
                     bounds: None,
@@ -1483,7 +1483,7 @@ impl Parser {
         let mut path_segments = ~[];
         let mut bounds = None;
         let last_segment_index = segments.len() - 1;
-        for (i, segment_and_bounds) in segments.consume_iter().enumerate() {
+        for (i, segment_and_bounds) in segments.move_iter().enumerate() {
             let PathSegmentAndBoundSet {
                 segment: segment,
                 bound_set: bound_set
@@ -4840,7 +4840,7 @@ impl Parser {
             let path = ast::Path {
                 span: mk_sp(lo, self.span.hi),
                 global: false,
-                segments: path.consume_iter().transform(|identifier| {
+                segments: path.move_iter().map(|identifier| {
                     ast::PathSegment {
                         identifier: identifier,
                         lifetime: None,
@@ -4876,7 +4876,7 @@ impl Parser {
                     let path = ast::Path {
                         span: mk_sp(lo, self.span.hi),
                         global: false,
-                        segments: path.consume_iter().transform(|identifier| {
+                        segments: path.move_iter().map(|identifier| {
                             ast::PathSegment {
                                 identifier: identifier,
                                 lifetime: None,
@@ -4894,7 +4894,7 @@ impl Parser {
                     let path = ast::Path {
                         span: mk_sp(lo, self.span.hi),
                         global: false,
-                        segments: path.consume_iter().transform(|identifier| {
+                        segments: path.move_iter().map(|identifier| {
                             ast::PathSegment {
                                 identifier: identifier,
                                 lifetime: None,
@@ -4916,7 +4916,7 @@ impl Parser {
         let path = ast::Path {
             span: mk_sp(lo, self.span.hi),
             global: false,
-            segments: path.consume_iter().transform(|identifier| {
+            segments: path.move_iter().map(|identifier| {
                 ast::PathSegment {
                     identifier: identifier,
                     lifetime: None,
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index ef44a368ab5..e5b7823ae44 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -320,7 +320,7 @@ pub fn walk_ty<E:Clone, V:Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
 
 pub fn walk_path<E:Clone, V:Visitor<E>>(visitor: &mut V, path: &Path, env: E) {
     for segment in path.segments.iter() {
-        for typ in path.types.iter() {
+        for typ in segment.types.iter() {
             visitor.visit_ty(typ, env.clone())
         }
     }