about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs1
-rw-r--r--src/libsyntax/diagnostic.rs5
-rw-r--r--src/libsyntax/ext/deriving/cmp/ord.rs104
-rw-r--r--src/libsyntax/ext/expand.rs232
-rw-r--r--src/libsyntax/ext/mtwt.rs3
-rw-r--r--src/libsyntax/fold.rs150
-rw-r--r--src/libsyntax/owned_slice.rs4
-rw-r--r--src/libsyntax/parse/lexer/mod.rs4
-rw-r--r--src/libsyntax/parse/parser.rs6
-rw-r--r--src/libsyntax/parse/token.rs1
-rw-r--r--src/libsyntax/print/pprust.rs10
-rw-r--r--src/libsyntax/util/small_vector.rs6
12 files changed, 353 insertions, 173 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index d24c2be5a74..529b460adcd 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -401,6 +401,7 @@ pub enum Decl_ {
     DeclItem(Gc<Item>),
 }
 
+/// represents one arm of a 'match'
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct Arm {
     pub attrs: Vec<Attribute>,
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index 16c463f0c96..dfaa9fb5fcb 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -18,6 +18,7 @@ use std::fmt;
 use std::io;
 use std::iter::range;
 use std::string::String;
+use term::WriterWrapper;
 use term;
 
 // maximum number of lines we will print for each error; arbitrary.
@@ -281,7 +282,7 @@ pub struct EmitterWriter {
 }
 
 enum Destination {
-    Terminal(Box<term::Terminal<Box<Writer + Send>> + Send>),
+    Terminal(Box<term::Terminal<WriterWrapper> + Send>),
     Raw(Box<Writer + Send>),
 }
 
@@ -414,7 +415,7 @@ fn highlight_lines(err: &mut EmitterWriter,
         }
         let orig = fm.get_line(*lines.lines.get(0) as int);
         for pos in range(0u, left-skip) {
-            let cur_char = orig.as_slice()[pos] as char;
+            let cur_char = orig.as_bytes()[pos] as char;
             // Whenever a tab occurs on the previous line, we insert one on
             // the error-point-squiggly-line as well (instead of a space).
             // That way the squiggly line will usually appear in the correct
diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs
index 88ebe8a60fa..59cdec1ea88 100644
--- a/src/libsyntax/ext/deriving/cmp/ord.rs
+++ b/src/libsyntax/ext/deriving/cmp/ord.rs
@@ -43,22 +43,116 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
         } }
     );
 
+    let ordering_ty = Literal(Path::new(vec!["std", "cmp", "Ordering"]));
+    let ret_ty = Literal(Path::new_(vec!["std", "option", "Option"],
+                                    None,
+                                    vec![box ordering_ty],
+                                    true));
+
+    let inline = cx.meta_word(span, InternedString::new("inline"));
+    let attrs = vec!(cx.attribute(span, inline));
+
+    let partial_cmp_def = MethodDef {
+        name: "partial_cmp",
+        generics: LifetimeBounds::empty(),
+        explicit_self: borrowed_explicit_self(),
+        args: vec![borrowed_self()],
+        ret_ty: ret_ty,
+        attributes: attrs,
+        const_nonmatching: false,
+        combine_substructure: combine_substructure(|cx, span, substr| {
+            cs_partial_cmp(cx, span, substr)
+        })
+    };
+
     let trait_def = TraitDef {
         span: span,
-        attributes: Vec::new(),
-        path: Path::new(vec!("std", "cmp", "PartialOrd")),
-        additional_bounds: Vec::new(),
+        attributes: vec![],
+        path: Path::new(vec!["std", "cmp", "PartialOrd"]),
+        additional_bounds: vec![],
         generics: LifetimeBounds::empty(),
-        methods: vec!(
+        methods: vec![
+            partial_cmp_def,
             md!("lt", true, false),
             md!("le", true, true),
             md!("gt", false, false),
             md!("ge", false, true)
-        )
+        ]
     };
     trait_def.expand(cx, mitem, item, push)
 }
 
+pub fn some_ordering_const(cx: &mut ExtCtxt, span: Span, cnst: Ordering) -> Gc<ast::Expr> {
+    let cnst = match cnst {
+        Less => "Less",
+        Equal => "Equal",
+        Greater => "Greater"
+    };
+    let ordering = cx.path_global(span,
+                                  vec!(cx.ident_of("std"),
+                                       cx.ident_of("cmp"),
+                                       cx.ident_of(cnst)));
+    let ordering = cx.expr_path(ordering);
+    cx.expr_some(span, ordering)
+}
+
+pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
+              substr: &Substructure) -> Gc<Expr> {
+    let test_id = cx.ident_of("__test");
+    let equals_expr = some_ordering_const(cx, span, Equal);
+
+    /*
+    Builds:
+
+    let __test = self_field1.partial_cmp(&other_field2);
+    if __test == ::std::option::Some(::std::cmp::Equal) {
+        let __test = self_field2.partial_cmp(&other_field2);
+        if __test == ::std::option::Some(::std::cmp::Equal) {
+            ...
+        } else {
+            __test
+        }
+    } else {
+        __test
+    }
+
+    FIXME #6449: These `if`s could/should be `match`es.
+    */
+    cs_same_method_fold(
+        // foldr nests the if-elses correctly, leaving the first field
+        // as the outermost one, and the last as the innermost.
+        false,
+        |cx, span, old, new| {
+            // let __test = new;
+            // if __test == Some(::std::cmp::Equal) {
+            //    old
+            // } else {
+            //    __test
+            // }
+
+            let assign = cx.stmt_let(span, false, test_id, new);
+
+            let cond = cx.expr_binary(span, ast::BiEq,
+                                      cx.expr_ident(span, test_id),
+                                      equals_expr.clone());
+            let if_ = cx.expr_if(span,
+                                 cond,
+                                 old, Some(cx.expr_ident(span, test_id)));
+            cx.expr_block(cx.block(span, vec!(assign), Some(if_)))
+        },
+        equals_expr.clone(),
+        |cx, span, list, _| {
+            match list {
+                // an earlier nonmatching variant is Less than a
+                // later one.
+                [(self_var, _, _), (other_var, _, _)] =>
+                     some_ordering_const(cx, span, self_var.cmp(&other_var)),
+                _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
+            }
+        },
+        cx, span, substr)
+}
+
 /// Strict inequality.
 fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span,
          substr: &Substructure) -> Gc<Expr> {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 321c56d4bbf..b9cedb7a779 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -31,6 +31,7 @@ use util::small_vector::SmallVector;
 
 use std::gc::{Gc, GC};
 
+
 pub fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> {
     match e.node {
         // expr_mac should really be expr_ext or something; it's the
@@ -53,7 +54,6 @@ pub fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> {
                     }
                     let extname = pth.segments.get(0).identifier;
                     let extnamestr = token::get_ident(extname);
-                    // leaving explicit deref here to highlight unbox op:
                     let marked_after = match fld.extsbox.find(&extname.name) {
                         None => {
                             fld.cx.span_err(
@@ -130,8 +130,6 @@ pub fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> {
         // From: `['<ident>:] for <src_pat> in <src_expr> <src_loop_block>`
         // FIXME #6993: change type of opt_ident to Option<Name>
         ast::ExprForLoop(src_pat, src_expr, src_loop_block, opt_ident) => {
-            // Expand any interior macros etc.
-            // NB: we don't fold pats yet. Curious.
 
             let span = e.span;
 
@@ -252,7 +250,7 @@ fn expand_loop_block(loop_block: P<Block>,
             // the same context will pick that up in the deferred renaming pass
             // and be renamed incorrectly.
             let mut rename_list = vec!(rename);
-            let mut rename_fld = renames_to_fold(&mut rename_list);
+            let mut rename_fld = IdentRenamer{renames: &mut rename_list};
             let renamed_ident = rename_fld.fold_ident(label);
 
             // The rename *must* be added to the enclosed syntax context for
@@ -281,7 +279,7 @@ macro_rules! with_exts_frame (
 )
 
 // When we enter a module, record it, for the sake of `module!`
-pub fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
+fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
                    -> SmallVector<Gc<ast::Item>> {
     let it = expand_item_modifiers(it, fld);
 
@@ -386,13 +384,13 @@ fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
 }
 
 // does this attribute list contain "macro_escape" ?
-pub fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
+fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
     attr::contains_name(attrs, "macro_escape")
 }
 
 // Support for item-position macro invocations, exactly the same
 // logic as for expression-position macro invocations.
-pub fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
+fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
                        -> SmallVector<Gc<ast::Item>> {
     let (pth, tts) = match it.node {
         ItemMac(codemap::Spanned {
@@ -498,7 +496,7 @@ pub fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
 }
 
 // expand a stmt
-pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<Gc<Stmt>> {
+fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<Gc<Stmt>> {
     // why the copying here and not in expand_expr?
     // looks like classic changed-in-only-one-place
     let (pth, tts, semi) = match s.node {
@@ -609,25 +607,21 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
                         span: span,
                         source: source,
                     } = **local;
-                    // expand the pat (it might contain exprs... #:(o)>
+                    // expand the pat (it might contain macro uses):
                     let expanded_pat = fld.fold_pat(pat);
                     // find the pat_idents in the pattern:
                     // oh dear heaven... this is going to include the enum
                     // names, as well... but that should be okay, as long as
                     // the new names are gensyms for the old ones.
-                    let mut name_finder = new_name_finder(Vec::new());
-                    name_finder.visit_pat(&*expanded_pat,());
                     // generate fresh names, push them to a new pending list
-                    let mut new_pending_renames = Vec::new();
-                    for ident in name_finder.ident_accumulator.iter() {
-                        let new_name = fresh_name(ident);
-                        new_pending_renames.push((*ident,new_name));
-                    }
+                    let idents = pattern_bindings(expanded_pat);
+                    let mut new_pending_renames =
+                        idents.iter().map(|ident| (*ident, fresh_name(ident))).collect();
+                    // rewrite the pattern using the new names (the old
+                    // ones have already been applied):
                     let rewritten_pat = {
-                        let mut rename_fld =
-                            renames_to_fold(&mut new_pending_renames);
-                        // rewrite the pattern using the new names (the old
-                        // ones have already been applied):
+                        // nested binding to allow borrow to expire:
+                        let mut rename_fld = IdentRenamer{renames: &mut new_pending_renames};
                         rename_fld.fold_pat(expanded_pat)
                     };
                     // add them to the existing pending renames:
@@ -659,9 +653,47 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
     }
 }
 
+fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
+    // expand pats... they might contain macro uses:
+    let expanded_pats : Vec<Gc<ast::Pat>> = arm.pats.iter().map(|pat| fld.fold_pat(*pat)).collect();
+    if expanded_pats.len() == 0 {
+        fail!("encountered match arm with 0 patterns");
+    }
+    // all of the pats must have the same set of bindings, so use the
+    // first one to extract them and generate new names:
+    let first_pat = expanded_pats.get(0);
+    // code duplicated from 'let', above. Perhaps this can be lifted
+    // into a separate function:
+    let idents = pattern_bindings(*first_pat);
+    let mut new_pending_renames =
+        idents.iter().map(|id| (*id,fresh_name(id))).collect();
+    // rewrite all of the patterns using the new names (the old
+    // ones have already been applied). Note that we depend here
+    // on the guarantee that after expansion, there can't be any
+    // Path expressions (a.k.a. varrefs) left in the pattern. If
+    // this were false, we'd need to apply this renaming only to
+    // the bindings, and not to the varrefs, using a more targeted
+    // fold-er.
+    let mut rename_fld = IdentRenamer{renames:&mut new_pending_renames};
+    let rewritten_pats =
+        expanded_pats.iter().map(|pat| rename_fld.fold_pat(*pat)).collect();
+    // apply renaming and then expansion to the guard and the body:
+    let rewritten_guard =
+        arm.guard.map(|g| fld.fold_expr(rename_fld.fold_expr(g)));
+    let rewritten_body = fld.fold_expr(rename_fld.fold_expr(arm.body));
+    ast::Arm {
+        attrs: arm.attrs.iter().map(|x| fld.fold_attribute(*x)).collect(),
+        pats: rewritten_pats,
+        guard: rewritten_guard,
+        body: rewritten_body,
+    }
+}
+
+
+
 // a visitor that extracts the pat_ident (binding) paths
 // from a given thingy and puts them in a mutable
-// array (passed in to the traversal).
+// array
 #[deriving(Clone)]
 struct NameFinderContext {
     ident_accumulator: Vec<ast::Ident> ,
@@ -701,38 +733,38 @@ impl Visitor<()> for NameFinderContext {
 
 }
 
-// return a visitor that extracts the pat_ident paths
-// from a given thingy and puts them in a mutable
-// array (passed in to the traversal)
-fn new_name_finder(idents: Vec<ast::Ident> ) -> NameFinderContext {
-    NameFinderContext {
-        ident_accumulator: idents,
-    }
+// find the pat_ident paths in a pattern
+fn pattern_bindings(pat : &ast::Pat) -> Vec<ast::Ident> {
+    let mut name_finder = NameFinderContext{ident_accumulator:Vec::new()};
+    name_finder.visit_pat(pat,());
+    name_finder.ident_accumulator
 }
 
 // expand a block. pushes a new exts_frame, then calls expand_block_elts
-pub fn expand_block(blk: &Block, fld: &mut MacroExpander) -> P<Block> {
+fn expand_block(blk: &Block, fld: &mut MacroExpander) -> P<Block> {
     // see note below about treatment of exts table
     with_exts_frame!(fld.extsbox,false,
                      expand_block_elts(blk, fld))
 }
 
 // expand the elements of a block.
-pub fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P<Block> {
+fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P<Block> {
     let new_view_items = b.view_items.iter().map(|x| fld.fold_view_item(x)).collect();
     let new_stmts =
         b.stmts.iter().flat_map(|x| {
+            // perform all pending renames
             let renamed_stmt = {
                 let pending_renames = &mut fld.extsbox.info().pending_renames;
-                let mut rename_fld = renames_to_fold(pending_renames);
+                let mut rename_fld = IdentRenamer{renames:pending_renames};
                 rename_fld.fold_stmt(&**x).expect_one("rename_fold didn't return one value")
             };
+            // expand macros in the statement
             fld.fold_stmt(&*renamed_stmt).move_iter()
         }).collect();
     let new_expr = b.expr.map(|x| {
         let expr = {
             let pending_renames = &mut fld.extsbox.info().pending_renames;
-            let mut rename_fld = renames_to_fold(pending_renames);
+            let mut rename_fld = IdentRenamer{renames:pending_renames};
             rename_fld.fold_expr(x)
         };
         fld.fold_expr(expr)
@@ -747,7 +779,7 @@ pub fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P<Block> {
     })
 }
 
-pub fn expand_pat(p: Gc<ast::Pat>, fld: &mut MacroExpander) -> Gc<ast::Pat> {
+fn expand_pat(p: Gc<ast::Pat>, fld: &mut MacroExpander) -> Gc<ast::Pat> {
     let (pth, tts) = match p.node {
         PatMac(ref mac) => {
             match mac.node {
@@ -824,6 +856,9 @@ pub fn expand_pat(p: Gc<ast::Pat>, fld: &mut MacroExpander) -> Gc<ast::Pat> {
     }
 }
 
+// a tree-folder that applies every rename in its (mutable) list
+// to every identifier, including both bindings and varrefs
+// (and lots of things that will turn out to be neither)
 pub struct IdentRenamer<'a> {
     renames: &'a mut RenameList,
 }
@@ -840,15 +875,7 @@ impl<'a> Folder for IdentRenamer<'a> {
     }
 }
 
-// given a mutable list of renames, return a tree-folder that applies those
-// renames.
-pub fn renames_to_fold<'a>(renames: &'a mut RenameList) -> IdentRenamer<'a> {
-    IdentRenamer {
-        renames: renames,
-    }
-}
-
-pub fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
+fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
     /* this discards information in the case of macro-defining macros */
     Span {
         lo: sp.lo,
@@ -883,6 +910,10 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
         expand_block(&*block, self)
     }
 
+    fn fold_arm(&mut self, arm: &ast::Arm) -> ast::Arm {
+        expand_arm(arm, self)
+    }
+
     fn new_span(&mut self, span: Span) -> Span {
         new_span(self.cx, span)
     }
@@ -965,35 +996,30 @@ impl Folder for Marker {
     }
 }
 
-// just a convenience:
-fn new_mark_folder(m: Mrk) -> Marker {
-    Marker {mark: m}
-}
-
 // apply a given mark to the given token trees. Used prior to expansion of a macro.
 fn mark_tts(tts: &[TokenTree], m: Mrk) -> Vec<TokenTree> {
-    fold_tts(tts, &mut new_mark_folder(m))
+    fold_tts(tts, &mut Marker{mark:m})
 }
 
 // apply a given mark to the given expr. Used following the expansion of a macro.
 fn mark_expr(expr: Gc<ast::Expr>, m: Mrk) -> Gc<ast::Expr> {
-    new_mark_folder(m).fold_expr(expr)
+    Marker{mark:m}.fold_expr(expr)
 }
 
 // apply a given mark to the given pattern. Used following the expansion of a macro.
 fn mark_pat(pat: Gc<ast::Pat>, m: Mrk) -> Gc<ast::Pat> {
-    new_mark_folder(m).fold_pat(pat)
+    Marker{mark:m}.fold_pat(pat)
 }
 
 // apply a given mark to the given stmt. Used following the expansion of a macro.
 fn mark_stmt(expr: &ast::Stmt, m: Mrk) -> Gc<ast::Stmt> {
-    new_mark_folder(m).fold_stmt(expr)
+    Marker{mark:m}.fold_stmt(expr)
             .expect_one("marking a stmt didn't return a stmt")
 }
 
 // apply a given mark to the given item. Used following the expansion of a macro.
 fn mark_item(expr: Gc<ast::Item>, m: Mrk) -> SmallVector<Gc<ast::Item>> {
-    new_mark_folder(m).fold_item(expr)
+    Marker{mark:m}.fold_item(expr)
 }
 
 fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> {
@@ -1013,7 +1039,8 @@ fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> {
 
 #[cfg(test)]
 mod test {
-    use super::{new_name_finder, expand_crate, contains_macro_escape};
+    use super::{pattern_bindings, expand_crate, contains_macro_escape};
+    use super::{NameFinderContext};
     use ast;
     use ast::{Attribute_, AttrOuter, MetaWord};
     use attr;
@@ -1043,22 +1070,22 @@ mod test {
             match *expr {
                 ast::Expr{id:_,span:_,node:ast::ExprPath(ref p)} => {
                     self.path_accumulator.push(p.clone());
-                    // not calling visit_path, should be fine.
+                    // not calling visit_path, but it should be fine.
                 }
                 _ => visit::walk_expr(self,expr,())
             }
         }
     }
 
-    // return a visitor that extracts the paths
-    // from a given thingy and puts them in a mutable
-    // array (passed in to the traversal)
-    fn new_path_finder(paths: Vec<ast::Path> ) -> PathExprFinderContext {
-        PathExprFinderContext {
-            path_accumulator: paths
-        }
+    // find the variable references in a crate
+    fn crate_varrefs(the_crate : &ast::Crate) -> Vec<ast::Path> {
+        let mut path_finder = PathExprFinderContext{path_accumulator:Vec::new()};
+        visit::walk_crate(&mut path_finder, the_crate, ());
+        path_finder.path_accumulator
     }
 
+
+
     // these following tests are quite fragile, in that they don't test what
     // *kind* of failure occurs.
 
@@ -1150,6 +1177,14 @@ mod test {
         expand_crate(&ps,cfg,vec!(),vec!(),crate_ast)
     }
 
+    // find the pat_ident paths in a crate
+    fn crate_bindings(the_crate : &ast::Crate) -> Vec<ast::Ident> {
+        let mut name_finder = NameFinderContext{ident_accumulator:Vec::new()};
+        visit::walk_crate(&mut name_finder, the_crate, ());
+        name_finder.ident_accumulator
+    }
+
+
     //fn expand_and_resolve(crate_str: @str) -> ast::crate {
         //let expanded_ast = expand_crate_str(crate_str);
         // println!("expanded: {:?}\n",expanded_ast);
@@ -1246,15 +1281,27 @@ mod test {
             0)
     }
 
-    // FIXME #9384, match variable hygiene. Should expand into
-    // fn z() {match 8 {x_1 => {match 9 {x_2 | x_2 => x_2 + x_1}}}}
-    #[ignore]
+    // match variable hygiene. Should expand into
+    // fn z() {match 8 {x_1 => {match 9 {x_2 | x_2 if x_2 == x_1 => x_2 + x_1}}}}
     #[test] fn issue_9384(){
         run_renaming_test(
-            &("macro_rules! bad_macro (($ex:expr) => ({match 9 {x | x => x + $ex}}))
-              fn z() {match 8 {x => bad_macro!(_x)}}",
+            &("macro_rules! bad_macro (($ex:expr) => ({match 9 {x | x if x == $ex => x + $ex}}))
+              fn z() {match 8 {x => bad_macro!(x)}}",
               // NB: the third "binding" is the repeat of the second one.
-              vec!(vec!(1),vec!(0),vec!(0)),
+              vec!(vec!(1,3),vec!(0,2),vec!(0,2)),
+              true),
+            0)
+    }
+
+    // interpolated nodes weren't getting labeled.
+    // should expand into
+    // fn main(){let g1_1 = 13; g1_1}}
+    #[test] fn pat_expand_issue_15221(){
+        run_renaming_test(
+            &("macro_rules! inner ( ($e:pat ) => ($e))
+              macro_rules! outer ( ($e:pat ) => (inner!($e)))
+              fn main() { let outer!(g) = 13; g;}",
+              vec!(vec!(0)),
               true),
             0)
     }
@@ -1283,15 +1330,8 @@ mod test {
             (ref str,ref conns, bic) => (str.to_owned(), conns.clone(), bic)
         };
         let cr = expand_crate_str(teststr.to_string());
-        // find the bindings:
-        let mut name_finder = new_name_finder(Vec::new());
-        visit::walk_crate(&mut name_finder,&cr,());
-        let bindings = name_finder.ident_accumulator;
-
-        // find the varrefs:
-        let mut path_finder = new_path_finder(Vec::new());
-        visit::walk_crate(&mut path_finder,&cr,());
-        let varrefs = path_finder.path_accumulator;
+        let bindings = crate_bindings(&cr);
+        let varrefs = crate_varrefs(&cr);
 
         // must be one check clause for each binding:
         assert_eq!(bindings.len(),bound_connections.len());
@@ -1315,9 +1355,13 @@ mod test {
                                                            .ctxt,
                                                      invalid_name);
                     if !(varref_name==binding_name) {
+                        let varref_idents : Vec<ast::Ident>
+                            = varref.segments.iter().map(|s|
+                                                         s.identifier)
+                            .collect();
                         println!("uh oh, should match but doesn't:");
-                        println!("varref: {:?}",varref);
-                        println!("binding: {:?}", *bindings.get(binding_idx));
+                        println!("varref #{}: {}",idx, varref_idents);
+                        println!("binding #{}: {}", binding_idx, *bindings.get(binding_idx));
                         mtwt::with_sctable(|x| mtwt::display_sctable(x));
                     }
                     assert_eq!(varref_name,binding_name);
@@ -1332,11 +1376,15 @@ mod test {
                             == binding_name);
                     // temp debugging:
                     if fail {
+                        let varref_idents : Vec<ast::Ident>
+                            = varref.segments.iter().map(|s|
+                                                         s.identifier)
+                            .collect();
                         println!("failure on test {}",test_idx);
                         println!("text of test case: \"{}\"", teststr);
                         println!("");
                         println!("uh oh, matches but shouldn't:");
-                        println!("varref: {:?}",varref);
+                        println!("varref: {}",varref_idents);
                         // good lord, you can't make a path with 0 segments, can you?
                         let string = token::get_ident(varref.segments
                                                             .get(0)
@@ -1344,7 +1392,7 @@ mod test {
                         println!("varref's first segment's uint: {}, and string: \"{}\"",
                                  varref.segments.get(0).identifier.name,
                                  string.get());
-                        println!("binding: {:?}", *bindings.get(binding_idx));
+                        println!("binding: {}", *bindings.get(binding_idx));
                         mtwt::with_sctable(|x| mtwt::display_sctable(x));
                     }
                     assert!(!fail);
@@ -1360,10 +1408,7 @@ foo_module!()
 ".to_string();
         let cr = expand_crate_str(crate_str);
         // find the xx binding
-        let mut name_finder = new_name_finder(Vec::new());
-        visit::walk_crate(&mut name_finder, &cr, ());
-        let bindings = name_finder.ident_accumulator;
-
+        let bindings = crate_bindings(&cr);
         let cxbinds: Vec<&ast::Ident> =
             bindings.iter().filter(|b| {
                 let ident = token::get_ident(**b);
@@ -1376,10 +1421,7 @@ foo_module!()
             _ => fail!("expected just one binding for ext_cx")
         };
         let resolved_binding = mtwt::resolve(*cxbind);
-        // find all the xx varrefs:
-        let mut path_finder = new_path_finder(Vec::new());
-        visit::walk_crate(&mut path_finder, &cr, ());
-        let varrefs = path_finder.path_accumulator;
+        let varrefs = crate_varrefs(&cr);
 
         // the xx binding should bind all of the xx varrefs:
         for (idx,v) in varrefs.iter().filter(|p| {
@@ -1405,10 +1447,8 @@ foo_module!()
     fn pat_idents(){
         let pat = string_to_pat(
             "(a,Foo{x:c @ (b,9),y:Bar(4,d)})".to_string());
-        let mut pat_idents = new_name_finder(Vec::new());
-        pat_idents.visit_pat(pat, ());
-        assert_eq!(pat_idents.ident_accumulator,
-                   strs_to_idents(vec!("a","c","b","d")));
+        let idents = pattern_bindings(pat);
+        assert_eq!(idents, strs_to_idents(vec!("a","c","b","d")));
     }
 
     // test the list of identifier patterns gathered by the visitor. Note that
@@ -1418,12 +1458,10 @@ foo_module!()
     fn crate_idents(){
         let the_crate = string_to_crate("fn main (a : int) -> int {|b| {
         match 34 {None => 3, Some(i) | i => j, Foo{k:z,l:y} => \"banana\"}} }".to_string());
-        let mut idents = new_name_finder(Vec::new());
-        //visit::walk_crate(&mut idents, &the_crate, ());
-        idents.visit_mod(&the_crate.module, the_crate.span, ast::CRATE_NODE_ID, ());
-        assert_eq!(idents.ident_accumulator,
-                   strs_to_idents(vec!("a","b","None","i","i","z","y")));
+        let idents = crate_bindings(&the_crate);
+        assert_eq!(idents, strs_to_idents(vec!("a","b","None","i","i","z","y")));
     }
 
+    //
 
 }
diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs
index 6c97a8aed1f..48895d34022 100644
--- a/src/libsyntax/ext/mtwt.rs
+++ b/src/libsyntax/ext/mtwt.rs
@@ -30,6 +30,7 @@ use std::collections::HashMap;
 // change the semantics--everything here is immutable--but
 // it should cut down on memory use *a lot*; applying a mark
 // to a tree containing 50 identifiers would otherwise generate
+// 50 new contexts
 pub struct SCTable {
     table: RefCell<Vec<SyntaxContext_>>,
     mark_memo: RefCell<HashMap<(SyntaxContext,Mrk),SyntaxContext>>,
@@ -160,7 +161,7 @@ fn with_resolve_table_mut<T>(op: |&mut ResolveTable| -> T) -> T {
 }
 
 // Resolve a syntax object to a name, per MTWT.
-// adding memorization to possibly resolve 500+ seconds in resolve for librustc (!)
+// adding memoization to resolve 500+ seconds in resolve for librustc (!)
 fn resolve_internal(id: Ident,
                     table: &SCTable,
                     resolve_table: &mut ResolveTable) -> Name {
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 6d2b0ceed8b..c6177ce31f5 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -86,7 +86,7 @@ pub trait Folder {
                 kind: sf.node.kind,
                 id: id,
                 ty: self.fold_ty(sf.node.ty),
-                attrs: sf.node.attrs.iter().map(|e| fold_attribute_(*e, self)).collect()
+                attrs: sf.node.attrs.iter().map(|e| self.fold_attribute(*e)).collect()
             },
             span: self.new_span(sf.span)
         }
@@ -118,7 +118,7 @@ pub trait Folder {
 
     fn fold_arm(&mut self, a: &Arm) -> Arm {
         Arm {
-            attrs: a.attrs.iter().map(|x| fold_attribute_(*x, self)).collect(),
+            attrs: a.attrs.iter().map(|x| self.fold_attribute(*x)).collect(),
             pats: a.pats.iter().map(|x| self.fold_pat(*x)).collect(),
             guard: a.guard.map(|x| self.fold_expr(x)),
             body: self.fold_expr(a.body),
@@ -251,7 +251,7 @@ pub trait Folder {
             }
         }
 
-        let attrs = v.node.attrs.iter().map(|x| fold_attribute_(*x, self)).collect();
+        let attrs = v.node.attrs.iter().map(|x| self.fold_attribute(*x)).collect();
 
         let de = match v.node.disr_expr {
           Some(e) => Some(self.fold_expr(e)),
@@ -344,6 +344,21 @@ pub trait Folder {
     fn fold_lifetime(&mut self, l: &Lifetime) -> Lifetime {
         noop_fold_lifetime(l, self)
     }
+
+    //used in noop_fold_item and noop_fold_crate
+    fn fold_attribute(&mut self, at: Attribute) -> Attribute {
+        Spanned {
+            span: self.new_span(at.span),
+            node: ast::Attribute_ {
+                id: at.node.id,
+                style: at.node.style,
+                value: fold_meta_item_(at.node.value, self),
+                is_sugared_doc: at.node.is_sugared_doc
+            }
+        }
+    }
+
+
 }
 
 /* some little folds that probably aren't useful to have in Folder itself*/
@@ -364,19 +379,6 @@ fn fold_meta_item_<T: Folder>(mi: Gc<MetaItem>, fld: &mut T) -> Gc<MetaItem> {
         span: fld.new_span(mi.span) }
 }
 
-//used in noop_fold_item and noop_fold_crate
-fn fold_attribute_<T: Folder>(at: Attribute, fld: &mut T) -> Attribute {
-    Spanned {
-        span: fld.new_span(at.span),
-        node: ast::Attribute_ {
-            id: at.node.id,
-            style: at.node.style,
-            value: fold_meta_item_(at.node.value, fld),
-            is_sugared_doc: at.node.is_sugared_doc
-        }
-    }
-}
-
 //used in noop_fold_foreign_item and noop_fold_fn_decl
 fn fold_arg_<T: Folder>(a: &Arg, fld: &mut T) -> Arg {
     let id = fld.new_id(a.id); // Needs to be first, for ast_map.
@@ -387,53 +389,80 @@ fn fold_arg_<T: Folder>(a: &Arg, fld: &mut T) -> Arg {
     }
 }
 
-// build a new vector of tts by appling the Folder's fold_ident to
-// all of the identifiers in the token trees.
-//
-// This is part of hygiene magic. As far as hygiene is concerned, there
-// are three types of let pattern bindings or loop labels:
-//      - those defined and used in non-macro part of the program
-//      - those used as part of macro invocation arguments
-//      - those defined and used inside macro definitions
-// Lexically, type 1 and 2 are in one group and type 3 the other. If they
-// clash, in order for let and loop label to work hygienically, one group
-// or the other needs to be renamed. The problem is that type 2 and 3 are
-// parsed together (inside the macro expand function). After being parsed and
-// AST being constructed, they can no longer be distinguished from each other.
-//
-// For that reason, type 2 let bindings and loop labels are actually renamed
-// in the form of tokens instead of AST nodes, here. There are wasted effort
-// since many token::IDENT are not necessary part of let bindings and most
-// token::LIFETIME are certainly not loop labels. But we can't tell in their
-// token form. So this is less ideal and hacky but it works.
-pub fn fold_tts<T: Folder>(tts: &[TokenTree], fld: &mut T) -> Vec<TokenTree> {
-    tts.iter().map(|tt| {
-        match *tt {
-            TTTok(span, ref tok) =>
-            TTTok(span,maybe_fold_ident(tok,fld)),
-            TTDelim(ref tts) => TTDelim(Rc::new(fold_tts(tts.as_slice(), fld))),
-            TTSeq(span, ref pattern, ref sep, is_optional) =>
+pub fn fold_tt<T: Folder>(tt: &TokenTree, fld: &mut T) -> TokenTree {
+    match *tt {
+        TTTok(span, ref tok) =>
+            TTTok(span, fold_token(tok,fld)),
+        TTDelim(ref tts) => TTDelim(Rc::new(fold_tts(tts.as_slice(), fld))),
+        TTSeq(span, ref pattern, ref sep, is_optional) =>
             TTSeq(span,
                   Rc::new(fold_tts(pattern.as_slice(), fld)),
-                  sep.as_ref().map(|tok|maybe_fold_ident(tok,fld)),
+                  sep.as_ref().map(|tok| fold_token(tok,fld)),
                   is_optional),
-            TTNonterminal(sp,ref ident) =>
+        TTNonterminal(sp,ref ident) =>
             TTNonterminal(sp,fld.fold_ident(*ident))
-        }
-    }).collect()
+    }
+}
+
+pub fn fold_tts<T: Folder>(tts: &[TokenTree], fld: &mut T) -> Vec<TokenTree> {
+    tts.iter().map(|tt| fold_tt(tt,fld)).collect()
 }
 
-// apply ident folder if it's an ident, otherwise leave it alone
-fn maybe_fold_ident<T: Folder>(t: &token::Token, fld: &mut T) -> token::Token {
+
+// apply ident folder if it's an ident, apply other folds to interpolated nodes
+fn fold_token<T: Folder>(t: &token::Token, fld: &mut T) -> token::Token {
     match *t {
         token::IDENT(id, followed_by_colons) => {
             token::IDENT(fld.fold_ident(id), followed_by_colons)
         }
         token::LIFETIME(id) => token::LIFETIME(fld.fold_ident(id)),
+        token::INTERPOLATED(ref nt) => token::INTERPOLATED(fold_interpolated(nt,fld)),
         _ => (*t).clone()
     }
 }
 
+// apply folder to elements of interpolated nodes
+//
+// NB: this can occur only when applying a fold to partially expanded code, where
+// parsed pieces have gotten implanted ito *other* macro invocations. This is relevant
+// for macro hygiene, but possibly not elsewhere.
+//
+// One problem here occurs because the types for fold_item, fold_stmt, etc. allow the
+// folder to return *multiple* items; this is a problem for the nodes here, because
+// they insist on having exactly one piece. One solution would be to mangle the fold
+// trait to include one-to-many and one-to-one versions of these entry points, but that
+// would probably confuse a lot of people and help very few. Instead, I'm just going
+// to put in dynamic checks. I think the performance impact of this will be pretty much
+// nonexistent. The danger is that someone will apply a fold to a partially expanded
+// node, and will be confused by the fact that their "fold_item" or "fold_stmt" isn't
+// getting called on NtItem or NtStmt nodes. Hopefully they'll wind up reading this
+// comment, and doing something appropriate.
+//
+// BTW, design choice: I considered just changing the type of, e.g., NtItem to contain
+// multiple items, but decided against it when I looked at parse_item_or_view_item and
+// tried to figure out what I would do with multiple items there....
+fn fold_interpolated<T: Folder>(nt : &token::Nonterminal, fld: &mut T) -> token::Nonterminal {
+    match *nt {
+        token::NtItem(item) =>
+            token::NtItem(fld.fold_item(item)
+                          .expect_one("expected fold to produce exactly one item")),
+        token::NtBlock(block) => token::NtBlock(fld.fold_block(block)),
+        token::NtStmt(stmt) =>
+            token::NtStmt(fld.fold_stmt(stmt)
+                          .expect_one("expected fold to produce exactly one statement")),
+        token::NtPat(pat) => token::NtPat(fld.fold_pat(pat)),
+        token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)),
+        token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)),
+        token::NtIdent(ref id, is_mod_name) =>
+            token::NtIdent(box fld.fold_ident(**id),is_mod_name),
+        token::NtMeta(meta_item) => token::NtMeta(fold_meta_item_(meta_item,fld)),
+        token::NtPath(ref path) => token::NtPath(box fld.fold_path(*path)),
+        token::NtTT(tt) => token::NtTT(box (GC) fold_tt(tt,fld)),
+        // it looks to me like we can leave out the matchers: token::NtMatchers(matchers)
+        _ => (*nt).clone()
+    }
+}
+
 pub fn noop_fold_fn_decl<T: Folder>(decl: &FnDecl, fld: &mut T) -> P<FnDecl> {
     P(FnDecl {
         inputs: decl.inputs.iter().map(|x| fold_arg_(x, fld)).collect(), // bad copy
@@ -526,7 +555,7 @@ fn fold_struct_field<T: Folder>(f: &StructField, fld: &mut T) -> StructField {
             kind: f.node.kind,
             id: id,
             ty: fld.fold_ty(f.node.ty),
-            attrs: f.node.attrs.iter().map(|a| fold_attribute_(*a, fld)).collect(),
+            attrs: f.node.attrs.iter().map(|a| fld.fold_attribute(*a)).collect(),
         },
         span: fld.new_span(f.span),
     }
@@ -578,7 +607,7 @@ pub fn noop_fold_view_item<T: Folder>(vi: &ViewItem, folder: &mut T)
     };
     ViewItem {
         node: inner_view_item,
-        attrs: vi.attrs.iter().map(|a| fold_attribute_(*a, folder)).collect(),
+        attrs: vi.attrs.iter().map(|a| folder.fold_attribute(*a)).collect(),
         vis: vi.vis,
         span: folder.new_span(vi.span),
     }
@@ -658,7 +687,7 @@ pub fn noop_fold_type_method<T: Folder>(m: &TypeMethod, fld: &mut T) -> TypeMeth
     TypeMethod {
         id: id,
         ident: fld.fold_ident(m.ident),
-        attrs: m.attrs.iter().map(|a| fold_attribute_(*a, fld)).collect(),
+        attrs: m.attrs.iter().map(|a| fld.fold_attribute(*a)).collect(),
         fn_style: m.fn_style,
         decl: fld.fold_fn_decl(&*m.decl),
         generics: fold_generics(&m.generics, fld),
@@ -681,14 +710,21 @@ pub fn noop_fold_mod<T: Folder>(m: &Mod, folder: &mut T) -> Mod {
 pub fn noop_fold_crate<T: Folder>(c: Crate, folder: &mut T) -> Crate {
     Crate {
         module: folder.fold_mod(&c.module),
-        attrs: c.attrs.iter().map(|x| fold_attribute_(*x, folder)).collect(),
+        attrs: c.attrs.iter().map(|x| folder.fold_attribute(*x)).collect(),
         config: c.config.iter().map(|x| fold_meta_item_(*x, folder)).collect(),
         span: folder.new_span(c.span),
     }
 }
 
+// fold one item into possibly many items
 pub fn noop_fold_item<T: Folder>(i: &Item,
                                  folder: &mut T) -> SmallVector<Gc<Item>> {
+    SmallVector::one(box(GC) noop_fold_item_(i,folder))
+}
+
+
+// fold one item into exactly one item
+pub fn noop_fold_item_<T: Folder>(i: &Item, folder: &mut T) -> Item {
     let id = folder.new_id(i.id); // Needs to be first, for ast_map.
     let node = folder.fold_item_underscore(&i.node);
     let ident = match node {
@@ -699,14 +735,14 @@ pub fn noop_fold_item<T: Folder>(i: &Item,
         _ => i.ident
     };
 
-    SmallVector::one(box(GC) Item {
+    Item {
         id: id,
         ident: folder.fold_ident(ident),
-        attrs: i.attrs.iter().map(|e| fold_attribute_(*e, folder)).collect(),
+        attrs: i.attrs.iter().map(|e| folder.fold_attribute(*e)).collect(),
         node: node,
         vis: i.vis,
         span: folder.new_span(i.span)
-    })
+    }
 }
 
 pub fn noop_fold_foreign_item<T: Folder>(ni: &ForeignItem,
@@ -715,7 +751,7 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: &ForeignItem,
     box(GC) ForeignItem {
         id: id,
         ident: folder.fold_ident(ni.ident),
-        attrs: ni.attrs.iter().map(|x| fold_attribute_(*x, folder)).collect(),
+        attrs: ni.attrs.iter().map(|x| folder.fold_attribute(*x)).collect(),
         node: match ni.node {
             ForeignItemFn(ref fdec, ref generics) => {
                 ForeignItemFn(P(FnDecl {
@@ -739,7 +775,7 @@ pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> Gc<Method> {
     box(GC) Method {
         id: id,
         ident: folder.fold_ident(m.ident),
-        attrs: m.attrs.iter().map(|a| fold_attribute_(*a, folder)).collect(),
+        attrs: m.attrs.iter().map(|a| folder.fold_attribute(*a)).collect(),
         generics: fold_generics(&m.generics, folder),
         explicit_self: folder.fold_explicit_self(&m.explicit_self),
         fn_style: m.fn_style,
diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs
index 016dd879dcd..530ea013112 100644
--- a/src/libsyntax/owned_slice.rs
+++ b/src/libsyntax/owned_slice.rs
@@ -69,9 +69,9 @@ impl<T> OwnedSlice<T> {
         static PTR_MARKER: u8 = 0;
         let ptr = if self.data.is_null() {
             // length zero, i.e. this will never be read as a T.
-            &PTR_MARKER as *u8 as *T
+            &PTR_MARKER as *const u8 as *const T
         } else {
-            self.data as *T
+            self.data as *const T
         };
 
         let slice: &[T] = unsafe {mem::transmute(raw::Slice {
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index ac570c88837..0f188fdf18a 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -1203,8 +1203,8 @@ impl<'a> StringReader<'a> {
 
     fn read_one_line_comment(&mut self) -> String {
         let val = self.read_to_eol();
-        assert!((val.as_slice()[0] == '/' as u8 && val.as_slice()[1] == '/' as u8)
-             || (val.as_slice()[0] == '#' as u8 && val.as_slice()[1] == '!' as u8));
+        assert!((val.as_bytes()[0] == '/' as u8 && val.as_bytes()[1] == '/' as u8)
+             || (val.as_bytes()[0] == '#' as u8 && val.as_bytes()[1] == '!' as u8));
         return val;
     }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 1cb09bb8d89..0fd5a7086b7 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1448,7 +1448,11 @@ impl<'a> Parser<'a> {
         } else if self.eat_keyword(keywords::Const) {
             MutImmutable
         } else {
-            // NOTE: after a stage0 snap this should turn into a span_err.
+            let span = self.last_span;
+            self.span_err(span,
+                          "bare raw pointers are no longer allowed, you should \
+                           likely use `*mut T`, but otherwise `*T` is now \
+                           known as `*const T`");
             MutImmutable
         };
         let t = self.parse_ty(true);
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 9549d5b8389..a93e8270d98 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -114,6 +114,7 @@ pub enum Nonterminal {
     NtPat( Gc<ast::Pat>),
     NtExpr(Gc<ast::Expr>),
     NtTy(  P<ast::Ty>),
+    // see IDENT, above, for meaning of bool in NtIdent:
     NtIdent(Box<ast::Ident>, bool),
     NtMeta(Gc<ast::MetaItem>), // stuff inside brackets for attributes
     NtPath(Box<ast::Path>),
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 87ed2076d61..a9cf4fbd9f0 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -479,7 +479,11 @@ impl<'a> State<'a> {
             }
             ast::TyPtr(ref mt) => {
                 try!(word(&mut self.s, "*"));
-                try!(self.print_mt(mt));
+                match mt.mutbl {
+                    ast::MutMutable => try!(self.word_nbsp("mut")),
+                    ast::MutImmutable => try!(self.word_nbsp("const")),
+                }
+                try!(self.print_type(&*mt.ty));
             }
             ast::TyRptr(ref lifetime, ref mt) => {
                 try!(word(&mut self.s, "&"));
@@ -994,7 +998,7 @@ impl<'a> State<'a> {
 
     pub fn print_outer_attributes(&mut self,
                                   attrs: &[ast::Attribute]) -> IoResult<()> {
-        let mut count = 0;
+        let mut count = 0u;
         for attr in attrs.iter() {
             match attr.node.style {
                 ast::AttrOuter => {
@@ -1012,7 +1016,7 @@ impl<'a> State<'a> {
 
     pub fn print_inner_attributes(&mut self,
                                   attrs: &[ast::Attribute]) -> IoResult<()> {
-        let mut count = 0;
+        let mut count = 0u;
         for attr in attrs.iter() {
             match attr.node.style {
                 ast::AttrInner => {
diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs
index d5cc2c7f304..43367611ab2 100644
--- a/src/libsyntax/util/small_vector.rs
+++ b/src/libsyntax/util/small_vector.rs
@@ -166,8 +166,8 @@ mod test {
         let v: SmallVector<int> = SmallVector::zero();
         assert_eq!(0, v.len());
 
-        assert_eq!(1, SmallVector::one(1).len());
-        assert_eq!(5, SmallVector::many(vec!(1, 2, 3, 4, 5)).len());
+        assert_eq!(1, SmallVector::one(1i).len());
+        assert_eq!(5, SmallVector::many(vec!(1i, 2, 3, 4, 5)).len());
     }
 
     #[test]
@@ -215,7 +215,7 @@ mod test {
     #[test]
     #[should_fail]
     fn test_expect_one_many() {
-        SmallVector::many(vec!(1, 2)).expect_one("");
+        SmallVector::many(vec!(1i, 2)).expect_one("");
     }
 
     #[test]