]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_front/lowering.rs
Auto merge of #31052 - bluss:split-at-mut-str, r=alexcrichton
[rust.git] / src / librustc_front / lowering.rs
index c0b10fb89124a9ba07a173a3ff8c80548f3afb8e..f6342831143256ce0709603d945a7cddc07986cb 100644 (file)
@@ -70,7 +70,6 @@
 use syntax::ext::mtwt;
 use syntax::ptr::P;
 use syntax::codemap::{respan, Spanned, Span};
-use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token;
 use syntax::std_inject;
 use syntax::visit::{self, Visitor};
@@ -88,7 +87,8 @@ pub struct LoweringContext<'a> {
     cached_id: Cell<u32>,
     // Keep track of gensym'ed idents.
     gensym_cache: RefCell<HashMap<(NodeId, &'static str), hir::Ident>>,
-    // A copy of cached_id, but is also set to an id while it is being cached.
+    // A copy of cached_id, but is also set to an id while a node is lowered for
+    // the first time.
     gensym_key: Cell<u32>,
 }
 
@@ -115,32 +115,79 @@ pub fn new(id_assigner: &'a NodeIdAssigner, c: Option<&Crate>) -> LoweringContex
     }
 
     fn next_id(&self) -> NodeId {
-        let cached = self.cached_id.get();
-        if cached == 0 {
+        let cached_id = self.cached_id.get();
+        if cached_id == 0 {
             return self.id_assigner.next_node_id();
         }
 
-        self.cached_id.set(cached + 1);
-        cached
+        self.cached_id.set(cached_id + 1);
+        cached_id
     }
 
     fn str_to_ident(&self, s: &'static str) -> hir::Ident {
-        let cached_id = self.gensym_key.get();
-        if cached_id == 0 {
+        let gensym_key = self.gensym_key.get();
+        if gensym_key == 0 {
             return hir::Ident::from_name(token::gensym(s));
         }
 
-        let cached = self.gensym_cache.borrow().contains_key(&(cached_id, s));
+        let cached = self.gensym_cache.borrow().contains_key(&(gensym_key, s));
         if cached {
-            self.gensym_cache.borrow()[&(cached_id, s)]
+            self.gensym_cache.borrow()[&(gensym_key, s)]
         } else {
             let result = hir::Ident::from_name(token::gensym(s));
-            self.gensym_cache.borrow_mut().insert((cached_id, s), result);
+            self.gensym_cache.borrow_mut().insert((gensym_key, s), result);
             result
         }
     }
 }
 
+// Utility fn for setting and unsetting the cached id.
+fn cache_ids<'a, OP, R>(lctx: &LoweringContext, expr_id: NodeId, op: OP) -> R
+    where OP: FnOnce(&LoweringContext) -> R
+{
+    // Only reset the id if it was previously 0, i.e., was not cached.
+    // If it was cached, we are in a nested node, but our id count will
+    // still count towards the parent's count.
+    let reset_cached_id = lctx.cached_id.get() == 0;
+    // We always reset gensym_key so that if we use the same name in a nested
+    // node and after that node, they get different values.
+    let old_gensym_key = lctx.gensym_key.get();
+
+    {
+        let id_cache: &mut HashMap<_, _> = &mut lctx.id_cache.borrow_mut();
+
+        if id_cache.contains_key(&expr_id) {
+            let cached_id = lctx.cached_id.get();
+            if cached_id == 0 {
+                // We're entering a node where we need to track ids, but are not
+                // yet tracking.
+                lctx.cached_id.set(id_cache[&expr_id]);
+            } else {
+                // We're already tracking - check that the tracked id is the same
+                // as the expected id.
+                assert!(cached_id == id_cache[&expr_id], "id mismatch");
+            }
+            lctx.gensym_key.set(id_cache[&expr_id]);
+        } else {
+            // We've never lowered this node before, remember it for next time.
+            let next_id = lctx.id_assigner.peek_node_id();
+            id_cache.insert(expr_id, next_id);
+            lctx.gensym_key.set(next_id);
+            // self.cached_id is not set when we lower a node for the first time,
+            // only on re-lowering.
+        }
+    }
+
+    let result = op(lctx);
+
+    if reset_cached_id {
+        lctx.cached_id.set(0);
+    }
+    lctx.gensym_key.set(old_gensym_key);
+
+    result
+}
+
 pub fn lower_ident(_lctx: &LoweringContext, ident: Ident) -> hir::Ident {
     hir::Ident {
         name: mtwt::resolve(ident),
@@ -148,6 +195,10 @@ pub fn lower_ident(_lctx: &LoweringContext, ident: Ident) -> hir::Ident {
     }
 }
 
+pub fn lower_attrs(_lctx: &LoweringContext, attrs: &Vec<Attribute>) -> hir::HirVec<Attribute> {
+    attrs.clone().into()
+}
+
 pub fn lower_view_path(lctx: &LoweringContext, view_path: &ViewPath) -> P<hir::ViewPath> {
     P(Spanned {
         node: match view_path.node {
@@ -187,7 +238,7 @@ pub fn lower_view_path(lctx: &LoweringContext, view_path: &ViewPath) -> P<hir::V
 
 pub fn lower_arm(lctx: &LoweringContext, arm: &Arm) -> hir::Arm {
     hir::Arm {
-        attrs: arm.attrs.clone(),
+        attrs: lower_attrs(lctx, &arm.attrs),
         pats: arm.pats.iter().map(|x| lower_pat(lctx, x)).collect(),
         guard: arm.guard.as_ref().map(|ref x| lower_expr(lctx, x)),
         body: lower_expr(lctx, &arm.body),
@@ -276,7 +327,7 @@ pub fn lower_variant(lctx: &LoweringContext, v: &Variant) -> hir::Variant {
     Spanned {
         node: hir::Variant_ {
             name: v.node.name.name,
-            attrs: v.node.attrs.clone(),
+            attrs: lower_attrs(lctx, &v.node.attrs),
             data: lower_variant_data(lctx, &v.node.data),
             disr_expr: v.node.disr_expr.as_ref().map(|e| lower_expr(lctx, e)),
         },
@@ -316,9 +367,9 @@ pub fn lower_path_parameters(lctx: &LoweringContext,
                              path_parameters: &PathParameters)
                              -> hir::PathParameters {
     match *path_parameters {
-        AngleBracketedParameters(ref data) =>
+        PathParameters::AngleBracketed(ref data) =>
             hir::AngleBracketedParameters(lower_angle_bracketed_parameter_data(lctx, data)),
-        ParenthesizedParameters(ref data) =>
+        PathParameters::Parenthesized(ref data) =>
             hir::ParenthesizedParameters(lower_parenthesized_parameter_data(lctx, data)),
     }
 }
@@ -430,8 +481,8 @@ pub fn lower_ty_param(lctx: &LoweringContext, tp: &TyParam) -> hir::TyParam {
 }
 
 pub fn lower_ty_params(lctx: &LoweringContext,
-                       tps: &OwnedSlice<TyParam>)
-                       -> OwnedSlice<hir::TyParam> {
+                       tps: &P<[TyParam]>)
+                       -> hir::HirVec<hir::TyParam> {
     tps.iter().map(|tp| lower_ty_param(lctx, tp)).collect()
 }
 
@@ -450,13 +501,13 @@ pub fn lower_lifetime_def(lctx: &LoweringContext, l: &LifetimeDef) -> hir::Lifet
     }
 }
 
-pub fn lower_lifetimes(lctx: &LoweringContext, lts: &Vec<Lifetime>) -> Vec<hir::Lifetime> {
+pub fn lower_lifetimes(lctx: &LoweringContext, lts: &Vec<Lifetime>) -> hir::HirVec<hir::Lifetime> {
     lts.iter().map(|l| lower_lifetime(lctx, l)).collect()
 }
 
 pub fn lower_lifetime_defs(lctx: &LoweringContext,
                            lts: &Vec<LifetimeDef>)
-                           -> Vec<hir::LifetimeDef> {
+                           -> hir::HirVec<hir::LifetimeDef> {
     lts.iter().map(|l| lower_lifetime_def(lctx, l)).collect()
 }
 
@@ -561,7 +612,7 @@ pub fn lower_struct_field(lctx: &LoweringContext, f: &StructField) -> hir::Struc
             id: f.node.id,
             kind: lower_struct_field_kind(lctx, &f.node.kind),
             ty: lower_ty(lctx, &f.node.ty),
-            attrs: f.node.attrs.clone(),
+            attrs: lower_attrs(lctx, &f.node.attrs),
         },
         span: f.span,
     }
@@ -583,8 +634,8 @@ pub fn lower_mt(lctx: &LoweringContext, mt: &MutTy) -> hir::MutTy {
 }
 
 pub fn lower_opt_bounds(lctx: &LoweringContext,
-                        b: &Option<OwnedSlice<TyParamBound>>)
-                        -> Option<OwnedSlice<hir::TyParamBound>> {
+                        b: &Option<TyParamBounds>)
+                        -> Option<hir::TyParamBounds> {
     b.as_ref().map(|ref bounds| lower_bounds(lctx, bounds))
 }
 
@@ -674,7 +725,7 @@ pub fn lower_trait_item(lctx: &LoweringContext, i: &TraitItem) -> hir::TraitItem
     hir::TraitItem {
         id: i.id,
         name: i.ident.name,
-        attrs: i.attrs.clone(),
+        attrs: lower_attrs(lctx, &i.attrs),
         node: match i.node {
             ConstTraitItem(ref ty, ref default) => {
                 hir::ConstTraitItem(lower_ty(lctx, ty),
@@ -697,7 +748,7 @@ pub fn lower_impl_item(lctx: &LoweringContext, i: &ImplItem) -> hir::ImplItem {
     hir::ImplItem {
         id: i.id,
         name: i.ident.name,
-        attrs: i.attrs.clone(),
+        attrs: lower_attrs(lctx, &i.attrs),
         vis: lower_visibility(lctx, i.vis),
         node: match i.node {
             ImplItemKind::Const(ref ty, ref expr) => {
@@ -741,25 +792,25 @@ pub fn lower_crate(lctx: &LoweringContext, c: &Crate) -> hir::Crate {
 
     hir::Crate {
         module: lower_mod(lctx, &c.module),
-        attrs: c.attrs.clone(),
-        config: c.config.clone(),
+        attrs: lower_attrs(lctx, &c.attrs),
+        config: c.config.clone().into(),
         span: c.span,
         exported_macros: c.exported_macros.iter().map(|m| lower_macro_def(lctx, m)).collect(),
         items: items,
     }
 }
 
-pub fn lower_macro_def(_lctx: &LoweringContext, m: &MacroDef) -> hir::MacroDef {
+pub fn lower_macro_def(lctx: &LoweringContext, m: &MacroDef) -> hir::MacroDef {
     hir::MacroDef {
         name: m.ident.name,
-        attrs: m.attrs.clone(),
+        attrs: lower_attrs(lctx, &m.attrs),
         id: m.id,
         span: m.span,
         imported_from: m.imported_from.map(|x| x.name),
         export: m.export,
         use_locally: m.use_locally,
         allow_internal_unstable: m.allow_internal_unstable,
-        body: m.body.clone(),
+        body: m.body.clone().into(),
     }
 }
 
@@ -773,7 +824,7 @@ pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item {
     hir::Item {
         id: i.id,
         name: i.ident.name,
-        attrs: i.attrs.clone(),
+        attrs: lower_attrs(lctx, &i.attrs),
         node: node,
         vis: lower_visibility(lctx, i.vis),
         span: i.span,
@@ -784,7 +835,7 @@ pub fn lower_foreign_item(lctx: &LoweringContext, i: &ForeignItem) -> hir::Forei
     hir::ForeignItem {
         id: i.id,
         name: i.ident.name,
-        attrs: i.attrs.clone(),
+        attrs: lower_attrs(lctx, &i.attrs),
         node: match i.node {
             ForeignItemFn(ref fdec, ref generics) => {
                 hir::ForeignItemFn(lower_fn_decl(lctx, fdec), lower_generics(lctx, generics))
@@ -915,47 +966,6 @@ pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P<hir::Pat> {
     })
 }
 
-// Utility fn for setting and unsetting the cached id.
-fn cache_ids<'a, OP, R>(lctx: &LoweringContext, expr_id: NodeId, op: OP) -> R
-    where OP: FnOnce(&LoweringContext) -> R
-{
-    // Only reset the id if it was previously 0, i.e., was not cached.
-    // If it was cached, we are in a nested node, but our id count will
-    // still count towards the parent's count.
-    let reset_cached_id = lctx.cached_id.get() == 0;
-
-    {
-        let id_cache: &mut HashMap<_, _> = &mut lctx.id_cache.borrow_mut();
-
-        if id_cache.contains_key(&expr_id) {
-            let cached_id = lctx.cached_id.get();
-            if cached_id == 0 {
-                // We're entering a node where we need to track ids, but are not
-                // yet tracking.
-                lctx.cached_id.set(id_cache[&expr_id]);
-                lctx.gensym_key.set(id_cache[&expr_id]);
-            } else {
-                // We're already tracking - check that the tracked id is the same
-                // as the expected id.
-                assert!(cached_id == id_cache[&expr_id], "id mismatch");
-            }
-        } else {
-            let next_id = lctx.id_assigner.peek_node_id();
-            id_cache.insert(expr_id, next_id);
-            lctx.gensym_key.set(next_id);
-        }
-    }
-
-    let result = op(lctx);
-
-    if reset_cached_id {
-        lctx.cached_id.set(0);
-        lctx.gensym_key.set(0);
-    }
-
-    result
-}
-
 pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
     P(hir::Expr {
         id: e.id,
@@ -1021,7 +1031,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                     // let placer = <placer_expr> ;
                     let s1 = {
                         let placer_expr = signal_block_expr(lctx,
-                                                            vec![],
+                                                            hir_vec![],
                                                             placer_expr,
                                                             e.span,
                                                             hir::PopUnstableBlock,
@@ -1032,14 +1042,14 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                     // let mut place = Placer::make_place(placer);
                     let s2 = {
                         let placer = expr_ident(lctx, e.span, placer_ident, None);
-                        let call = make_call(lctx, &make_place, vec![placer]);
+                        let call = make_call(lctx, &make_place, hir_vec![placer]);
                         mk_stmt_let_mut(lctx, place_ident, call)
                     };
 
                     // let p_ptr = Place::pointer(&mut place);
                     let s3 = {
                         let agent = expr_ident(lctx, e.span, place_ident, None);
-                        let args = vec![expr_mut_addr_of(lctx, e.span, agent, None)];
+                        let args = hir_vec![expr_mut_addr_of(lctx, e.span, agent, None)];
                         let call = make_call(lctx, &place_pointer, args);
                         mk_stmt_let(lctx, p_ptr_ident, call)
                     };
@@ -1047,13 +1057,13 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                     // pop_unsafe!(EXPR));
                     let pop_unsafe_expr = {
                         let value_expr = signal_block_expr(lctx,
-                                                           vec![],
+                                                           hir_vec![],
                                                            value_expr,
                                                            e.span,
                                                            hir::PopUnstableBlock,
                                                            None);
                         signal_block_expr(lctx,
-                                          vec![],
+                                          hir_vec![],
                                           value_expr,
                                           e.span,
                                           hir::PopUnsafeBlock(hir::CompilerGenerated), None)
@@ -1067,21 +1077,21 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                         let ptr = expr_ident(lctx, e.span, p_ptr_ident, None);
                         let call_move_val_init =
                             hir::StmtSemi(
-                                make_call(lctx, &move_val_init, vec![ptr, pop_unsafe_expr]),
+                                make_call(lctx, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
                                 lctx.next_id());
                         let call_move_val_init = respan(e.span, call_move_val_init);
 
                         let place = expr_ident(lctx, e.span, place_ident, None);
-                        let call = make_call(lctx, &inplace_finalize, vec![place]);
+                        let call = make_call(lctx, &inplace_finalize, hir_vec![place]);
                         signal_block_expr(lctx,
-                                          vec![call_move_val_init],
+                                          hir_vec![call_move_val_init],
                                           call,
                                           e.span,
                                           hir::PushUnsafeBlock(hir::CompilerGenerated), None)
                     };
 
                     signal_block_expr(lctx,
-                                      vec![s1, s2, s3],
+                                      hir_vec![s1, s2, s3],
                                       expr,
                                       e.span,
                                       hir::PushUnstableBlock,
@@ -1125,6 +1135,10 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                 let expr = lower_expr(lctx, expr);
                 hir::ExprCast(expr, lower_ty(lctx, ty))
             }
+            ExprType(ref expr, ref ty) => {
+                let expr = lower_expr(lctx, expr);
+                hir::ExprType(expr, lower_ty(lctx, ty))
+            }
             ExprAddrOf(m, ref ohs) => {
                 let m = lower_mutability(lctx, m);
                 let ohs = lower_expr(lctx, ohs);
@@ -1142,7 +1156,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                                 let els = lower_expr(lctx, els);
                                 let id = lctx.next_id();
                                 let blk = P(hir::Block {
-                                    stmts: vec![],
+                                    stmts: hir_vec![],
                                     expr: Some(els),
                                     id: id,
                                     rules: hir::DefaultBlock,
@@ -1239,7 +1253,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                                 .collect(),
                 asm: asm.clone(),
                 asm_str_style: asm_str_style,
-                clobbers: clobbers.clone(),
+                clobbers: clobbers.clone().into(),
                 volatile: volatile,
                 alignstack: alignstack,
                 dialect: dialect,
@@ -1276,7 +1290,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                     let pat_arm = {
                         let body = lower_block(lctx, body);
                         let body_expr = expr_block(lctx, body, None);
-                        arm(vec![lower_pat(lctx, pat)], body_expr)
+                        arm(hir_vec![lower_pat(lctx, pat)], body_expr)
                     };
 
                     // `[_ if <else_opt_if_cond> => <else_opt_if_body>,]`
@@ -1291,8 +1305,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                                         hir::ExprIf(cond, then, else_opt) => {
                                             let pat_under = pat_wild(lctx, e.span);
                                             arms.push(hir::Arm {
-                                                attrs: vec![],
-                                                pats: vec![pat_under],
+                                                attrs: hir_vec![],
+                                                pats: hir_vec![pat_under],
                                                 guard: Some(cond),
                                                 body: expr_block(lctx, then, None),
                                             });
@@ -1326,8 +1340,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                         let pat_under = pat_wild(lctx, e.span);
                         let else_expr =
                             else_opt.unwrap_or_else(
-                                || expr_tuple(lctx, e.span, vec![], None));
-                        arm(vec![pat_under], else_expr)
+                                || expr_tuple(lctx, e.span, hir_vec![], None));
+                        arm(hir_vec![pat_under], else_expr)
                     };
 
                     let mut arms = Vec::with_capacity(else_if_arms.len() + 2);
@@ -1340,7 +1354,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                     expr(lctx,
                          e.span,
                          hir::ExprMatch(sub_expr,
-                                        arms,
+                                        arms.into(),
                                         hir::MatchSource::IfLetDesugar {
                                             contains_else_clause: contains_else_clause,
                                         }),
@@ -1365,18 +1379,18 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                     let pat_arm = {
                         let body = lower_block(lctx, body);
                         let body_expr = expr_block(lctx, body, None);
-                        arm(vec![lower_pat(lctx, pat)], body_expr)
+                        arm(hir_vec![lower_pat(lctx, pat)], body_expr)
                     };
 
                     // `_ => break`
                     let break_arm = {
                         let pat_under = pat_wild(lctx, e.span);
                         let break_expr = expr_break(lctx, e.span, None);
-                        arm(vec![pat_under], break_expr)
+                        arm(hir_vec![pat_under], break_expr)
                     };
 
                     // `match <sub_expr> { ... }`
-                    let arms = vec![pat_arm, break_arm];
+                    let arms = hir_vec![pat_arm, break_arm];
                     let sub_expr = lower_expr(lctx, sub_expr);
                     let match_expr = expr(lctx,
                                           e.span,
@@ -1432,14 +1446,14 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                         let pat = lower_pat(lctx, pat);
                         let some_pat = pat_some(lctx, e.span, pat);
 
-                        arm(vec![some_pat], body_expr)
+                        arm(hir_vec![some_pat], body_expr)
                     };
 
                     // `::std::option::Option::None => break`
                     let break_arm = {
                         let break_expr = expr_break(lctx, e.span, None);
 
-                        arm(vec![pat_none(lctx, e.span)], break_expr)
+                        arm(hir_vec![pat_none(lctx, e.span)], break_expr)
                     };
 
                     // `match ::std::iter::Iterator::next(&mut iter) { ... }`
@@ -1455,9 +1469,9 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                         let next_expr = expr_call(lctx,
                                                   e.span,
                                                   next_path,
-                                                  vec![ref_mut_iter],
+                                                  hir_vec![ref_mut_iter],
                                                   None);
-                        let arms = vec![pat_arm, break_arm];
+                        let arms = hir_vec![pat_arm, break_arm];
 
                         expr(lctx,
                              e.span,
@@ -1477,7 +1491,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                                                               e.span,
                                                               iter,
                                                               hir::BindByValue(hir::MutMutable));
-                        arm(vec![iter_pat], loop_expr)
+                        arm(hir_vec![iter_pat], loop_expr)
                     };
 
                     // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
@@ -1489,21 +1503,22 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                         };
 
                         let into_iter = expr_path(lctx, into_iter_path, None);
-                        expr_call(lctx, e.span, into_iter, vec![head], None)
+                        expr_call(lctx, e.span, into_iter, hir_vec![head], None)
                     };
 
                     let match_expr = expr_match(lctx,
                                                 e.span,
                                                 into_iter_expr,
-                                                vec![iter_arm],
+                                                hir_vec![iter_arm],
                                                 hir::MatchSource::ForLoopDesugar,
                                                 None);
 
-                    // `{ let result = ...; result }`
-                    let result_ident = lctx.str_to_ident("result");
+                    // `{ let _result = ...; _result }`
+                    // underscore prevents an unused_variables lint if the head diverges
+                    let result_ident = lctx.str_to_ident("_result");
                     let let_stmt = stmt_let(lctx, e.span, false, result_ident, match_expr, None);
                     let result = expr_ident(lctx, e.span, result_ident, None);
-                    let block = block_all(lctx, e.span, vec![let_stmt], Some(result));
+                    let block = block_all(lctx, e.span, hir_vec![let_stmt], Some(result));
                     // add the attributes to the outer returned expr node
                     expr_block(lctx, block, e.attrs.clone())
                 });
@@ -1563,8 +1578,8 @@ pub fn lower_block_check_mode(lctx: &LoweringContext, b: &BlockCheckMode) -> hir
 
 pub fn lower_binding_mode(lctx: &LoweringContext, b: &BindingMode) -> hir::BindingMode {
     match *b {
-        BindByRef(m) => hir::BindByRef(lower_mutability(lctx, m)),
-        BindByValue(m) => hir::BindByValue(lower_mutability(lctx, m)),
+        BindingMode::ByRef(m) => hir::BindByRef(lower_mutability(lctx, m)),
+        BindingMode::ByValue(m) => hir::BindByValue(lower_mutability(lctx, m)),
     }
 }
 
@@ -1602,9 +1617,9 @@ pub fn lower_trait_bound_modifier(_lctx: &LoweringContext,
 
 // Helper methods for building HIR.
 
-fn arm(pats: Vec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
+fn arm(pats: hir::HirVec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
     hir::Arm {
-        attrs: vec![],
+        attrs: hir_vec![],
         pats: pats,
         guard: None,
         body: expr,
@@ -1619,7 +1634,7 @@ fn expr_break(lctx: &LoweringContext, span: Span,
 fn expr_call(lctx: &LoweringContext,
              span: Span,
              e: P<hir::Expr>,
-             args: Vec<P<hir::Expr>>,
+             args: hir::HirVec<P<hir::Expr>>,
              attrs: ThinAttributes)
              -> P<hir::Expr> {
     expr(lctx, span, hir::ExprCall(e, args), attrs)
@@ -1643,7 +1658,7 @@ fn expr_path(lctx: &LoweringContext, path: hir::Path,
 fn expr_match(lctx: &LoweringContext,
               span: Span,
               arg: P<hir::Expr>,
-              arms: Vec<hir::Arm>,
+              arms: hir::HirVec<hir::Arm>,
               source: hir::MatchSource,
               attrs: ThinAttributes)
               -> P<hir::Expr> {
@@ -1655,7 +1670,7 @@ fn expr_block(lctx: &LoweringContext, b: P<hir::Block>,
     expr(lctx, b.span, hir::ExprBlock(b), attrs)
 }
 
-fn expr_tuple(lctx: &LoweringContext, sp: Span, exprs: Vec<P<hir::Expr>>,
+fn expr_tuple(lctx: &LoweringContext, sp: Span, exprs: hir::HirVec<P<hir::Expr>>,
               attrs: ThinAttributes) -> P<hir::Expr> {
     expr(lctx, sp, hir::ExprTup(exprs), attrs)
 }
@@ -1695,12 +1710,12 @@ fn stmt_let(lctx: &LoweringContext,
 }
 
 fn block_expr(lctx: &LoweringContext, expr: P<hir::Expr>) -> P<hir::Block> {
-    block_all(lctx, expr.span, Vec::new(), Some(expr))
+    block_all(lctx, expr.span, hir::HirVec::new(), Some(expr))
 }
 
 fn block_all(lctx: &LoweringContext,
              span: Span,
-             stmts: Vec<hir::Stmt>,
+             stmts: hir::HirVec<hir::Stmt>,
              expr: Option<P<hir::Expr>>)
              -> P<hir::Block> {
     P(hir::Block {
@@ -1715,19 +1730,19 @@ fn block_all(lctx: &LoweringContext,
 fn pat_some(lctx: &LoweringContext, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
     let some = std_path(lctx, &["option", "Option", "Some"]);
     let path = path_global(span, some);
-    pat_enum(lctx, span, path, vec![pat])
+    pat_enum(lctx, span, path, hir_vec![pat])
 }
 
 fn pat_none(lctx: &LoweringContext, span: Span) -> P<hir::Pat> {
     let none = std_path(lctx, &["option", "Option", "None"]);
     let path = path_global(span, none);
-    pat_enum(lctx, span, path, vec![])
+    pat_enum(lctx, span, path, hir_vec![])
 }
 
 fn pat_enum(lctx: &LoweringContext,
             span: Span,
             path: hir::Path,
-            subpats: Vec<P<hir::Pat>>)
+            subpats: hir::HirVec<P<hir::Pat>>)
             -> P<hir::Pat> {
     let pt = hir::PatEnum(path, Some(subpats));
     pat(lctx, span, pt)
@@ -1768,19 +1783,19 @@ fn path_ident(span: Span, id: hir::Ident) -> hir::Path {
 }
 
 fn path(span: Span, strs: Vec<hir::Ident>) -> hir::Path {
-    path_all(span, false, strs, Vec::new(), Vec::new(), Vec::new())
+    path_all(span, false, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new())
 }
 
 fn path_global(span: Span, strs: Vec<hir::Ident>) -> hir::Path {
-    path_all(span, true, strs, Vec::new(), Vec::new(), Vec::new())
+    path_all(span, true, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new())
 }
 
 fn path_all(sp: Span,
             global: bool,
             mut idents: Vec<hir::Ident>,
-            lifetimes: Vec<hir::Lifetime>,
-            types: Vec<P<hir::Ty>>,
-            bindings: Vec<hir::TypeBinding>)
+            lifetimes: hir::HirVec<hir::Lifetime>,
+            types: hir::HirVec<P<hir::Ty>>,
+            bindings: hir::HirVec<hir::TypeBinding>)
             -> hir::Path {
     let last_identifier = idents.pop().unwrap();
     let mut segments: Vec<hir::PathSegment> = idents.into_iter()
@@ -1795,14 +1810,14 @@ fn path_all(sp: Span,
         identifier: last_identifier,
         parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData {
             lifetimes: lifetimes,
-            types: OwnedSlice::from_vec(types),
-            bindings: OwnedSlice::from_vec(bindings),
+            types: types,
+            bindings: bindings,
         }),
     });
     hir::Path {
         span: sp,
         global: global,
-        segments: segments,
+        segments: segments.into(),
     }
 }
 
@@ -1823,7 +1838,7 @@ fn core_path(lctx: &LoweringContext, span: Span, components: &[&str]) -> hir::Pa
 }
 
 fn signal_block_expr(lctx: &LoweringContext,
-                     stmts: Vec<hir::Stmt>,
+                     stmts: hir::HirVec<hir::Stmt>,
                      expr: P<hir::Expr>,
                      span: Span,
                      rule: hir::BlockCheckMode,
@@ -1927,7 +1942,9 @@ fn test_preserves_ids() {
         let ast_while_let = assigner.fold_expr(ast_while_let);
         let ast_for = quote_expr!(&cx,
                                   for i in 0..10 {
-                                      foo(i);
+                                      for j in 0..10 {
+                                          foo(i, j);
+                                      }
                                   });
         let ast_for = assigner.fold_expr(ast_for);
         let ast_in = quote_expr!(&cx, in HEAP { foo() });