]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/middle/typeck/check/mod.rs
auto merge of #15421 : catharsis/rust/doc-ffi-minor-fixes, r=alexcrichton
[rust.git] / src / librustc / middle / typeck / check / mod.rs
index b68991aed70963c53c341788689c4f11e1652a7a..fb29baeea73f2c592d5ad99303d1e3865863b82d 100644 (file)
@@ -397,8 +397,8 @@ fn visit_local(&mut self, local: &ast::Local, _: ()) {
         };
         self.assign(local.id, o_ty);
         debug!("Local variable {} is assigned type {}",
-               self.fcx.pat_to_str(&*local.pat),
-               self.fcx.infcx().ty_to_str(
+               self.fcx.pat_to_string(&*local.pat),
+               self.fcx.infcx().ty_to_string(
                    self.fcx.inh.locals.borrow().get_copy(&local.id)));
         visit::walk_local(self, local, ());
     }
@@ -411,7 +411,7 @@ fn visit_pat(&mut self, p: &ast::Pat, _: ()) {
                 self.assign(p.id, None);
                 debug!("Pattern binding {} is assigned to {}",
                        token::get_ident(path1.node),
-                       self.fcx.infcx().ty_to_str(
+                       self.fcx.infcx().ty_to_string(
                            self.fcx.inh.locals.borrow().get_copy(&p.id)));
               }
               _ => {}
@@ -534,7 +534,7 @@ fn span_for_field(tcx: &ty::ctxt, field: &ty::field_ty, struct_id: ast::DefId) -
     let item = match tcx.map.find(struct_id.node) {
         Some(ast_map::NodeItem(item)) => item,
         None => fail!("node not in ast map: {}", struct_id.node),
-        _ => fail!("expected item, found {}", tcx.map.node_to_str(struct_id.node))
+        _ => fail!("expected item, found {}", tcx.map.node_to_string(struct_id.node))
     };
 
     match item.node {
@@ -757,14 +757,16 @@ fn check_method_body(ccx: &CrateCtxt,
     let method_def_id = local_def(method.id);
     let method_ty = ty::method(ccx.tcx, method_def_id);
     let method_generics = &method_ty.generics;
+    let m_body = ast_util::method_body(&*method);
 
     let param_env = ty::construct_parameter_environment(ccx.tcx,
                                                         method_generics,
-                                                        method.body.id);
+                                                        m_body.id);
 
     let fty = ty::node_id_to_type(ccx.tcx, method.id);
 
-    check_bare_fn(ccx, &*method.decl, &*method.body, method.id, fty, param_env);
+    check_bare_fn(ccx, ast_util::method_fn_decl(&*method),
+                  m_body, method.id, fty, param_env);
 }
 
 fn check_impl_methods_against_trait(ccx: &CrateCtxt,
@@ -792,7 +794,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
                 compare_impl_method(ccx.tcx,
                                     &*impl_method_ty,
                                     impl_method.span,
-                                    impl_method.body.id,
+                                    ast_util::method_body(&**impl_method).id,
                                     &**trait_method_ty,
                                     &impl_trait_ref.substs);
             }
@@ -803,7 +805,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
                     format!(
                         "method `{}` is not a member of trait `{}`",
                         token::get_ident(impl_method_ty.ident),
-                        pprust::path_to_str(&ast_trait_ref.path)).as_slice());
+                        pprust::path_to_string(&ast_trait_ref.path)).as_slice());
             }
         }
     }
@@ -815,7 +817,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
     for trait_method in trait_methods.iter() {
         let is_implemented =
             impl_methods.iter().any(
-                |m| m.ident.name == trait_method.ident.name);
+                |m| ast_util::method_ident(&**m).name == trait_method.ident.name);
         let is_provided =
             provided_methods.iter().any(
                 |m| m.ident.name == trait_method.ident.name);
@@ -870,7 +872,7 @@ fn compare_impl_method(tcx: &ty::ctxt,
                 format!("method `{}` has a `{}` declaration in the impl, \
                         but not in the trait",
                         token::get_ident(trait_m.ident),
-                        pprust::explicit_self_to_str(
+                        pprust::explicit_self_to_string(
                             impl_m.explicit_self)).as_slice());
             return;
         }
@@ -880,7 +882,7 @@ fn compare_impl_method(tcx: &ty::ctxt,
                 format!("method `{}` has a `{}` declaration in the trait, \
                         but not in the impl",
                         token::get_ident(trait_m.ident),
-                        pprust::explicit_self_to_str(
+                        pprust::explicit_self_to_string(
                             trait_m.explicit_self)).as_slice());
             return;
         }
@@ -917,8 +919,8 @@ fn compare_impl_method(tcx: &ty::ctxt,
         return;
     }
 
-    let it = trait_m.generics.types.get_vec(subst::FnSpace).iter()
-        .zip(impl_m.generics.types.get_vec(subst::FnSpace).iter());
+    let it = trait_m.generics.types.get_slice(subst::FnSpace).iter()
+        .zip(impl_m.generics.types.get_slice(subst::FnSpace).iter());
 
     // This code is best explained by example. Consider a trait:
     //
@@ -989,8 +991,8 @@ fn compare_impl_method(tcx: &ty::ctxt,
     let trait_to_skol_substs =
         trait_to_impl_substs
         .subst(tcx, &impl_to_skol_substs)
-        .with_method(skol_tps.get_vec(subst::FnSpace).clone(),
-                     skol_regions.get_vec(subst::FnSpace).clone());
+        .with_method(Vec::from_slice(skol_tps.get_slice(subst::FnSpace)),
+                     Vec::from_slice(skol_regions.get_slice(subst::FnSpace)));
     let trait_fty = ty::mk_bare_fn(tcx, trait_m.fty.clone());
     let trait_fty = trait_fty.subst(tcx, &trait_to_skol_substs);
 
@@ -1051,7 +1053,7 @@ fn compare_impl_method(tcx: &ty::ctxt,
                                            declaration",
                                           token::get_ident(trait_m.ident),
                                           i,
-                                          ppaux::trait_ref_to_str(
+                                          ppaux::trait_ref_to_string(
                                               tcx,
                                               &*impl_trait_bound)).as_slice())
             }
@@ -1101,8 +1103,8 @@ fn check_cast(fcx: &FnCtxt,
 
     let t_e = fcx.expr_ty(e);
 
-    debug!("t_1={}", fcx.infcx().ty_to_str(t_1));
-    debug!("t_e={}", fcx.infcx().ty_to_str(t_e));
+    debug!("t_1={}", fcx.infcx().ty_to_string(t_1));
+    debug!("t_e={}", fcx.infcx().ty_to_string(t_e));
 
     if ty::type_is_error(t_e) {
         fcx.write_error(id);
@@ -1126,13 +1128,13 @@ fn check_cast(fcx: &FnCtxt,
         fcx.type_error_message(span, |actual| {
             format!("cast from nil: `{}` as `{}`",
                     actual,
-                    fcx.infcx().ty_to_str(t_1))
+                    fcx.infcx().ty_to_string(t_1))
         }, t_e, None);
     } else if ty::type_is_nil(t_1) {
         fcx.type_error_message(span, |actual| {
             format!("cast to nil: `{}` as `{}`",
                     actual,
-                    fcx.infcx().ty_to_str(t_1))
+                    fcx.infcx().ty_to_string(t_1))
         }, t_e, None);
     }
 
@@ -1149,7 +1151,7 @@ fn check_cast(fcx: &FnCtxt,
                 format!("illegal cast; cast through an \
                          integer first: `{}` as `{}`",
                         actual,
-                        fcx.infcx().ty_to_str(t_1))
+                        fcx.infcx().ty_to_string(t_1))
             }, t_e, None);
         }
         // casts from C-like enums are allowed
@@ -1217,7 +1219,14 @@ fn types_compatible(fcx: &FnCtxt, sp: Span,
         fcx.type_error_message(span, |actual| {
             format!("non-scalar cast: `{}` as `{}`",
                     actual,
-                    fcx.infcx().ty_to_str(t_1))
+                    fcx.infcx().ty_to_string(t_1))
+        }, t_e, None);
+    } else if ty::type_is_unsafe_ptr(t_e) && t_1_is_float {
+        fcx.type_error_message(span, |actual| {
+            format!("cannot cast from pointer to float directly: `{}` as `{}`; cast through an \
+                     integer first",
+                    actual,
+                    fcx.infcx().ty_to_string(t_1))
         }, t_e, None);
     }
 
@@ -1286,7 +1295,7 @@ pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> ty::t {
     #[inline]
     pub fn write_ty(&self, node_id: ast::NodeId, ty: ty::t) {
         debug!("write_ty({}, {}) in fcx {}",
-               node_id, ppaux::ty_to_str(self.tcx(), ty), self.tag());
+               node_id, ppaux::ty_to_string(self.tcx(), ty), self.tag());
         self.inh.node_types.borrow_mut().insert(node_id, ty);
     }
 
@@ -1343,7 +1352,7 @@ pub fn to_ty(&self, ast_t: &ast::Ty) -> ty::t {
         ast_ty_to_ty(self, self.infcx(), ast_t)
     }
 
-    pub fn pat_to_str(&self, pat: &ast::Pat) -> String {
+    pub fn pat_to_string(&self, pat: &ast::Pat) -> String {
         pat.repr(self.tcx())
     }
 
@@ -1363,7 +1372,7 @@ pub fn node_ty(&self, id: ast::NodeId) -> ty::t {
             None => {
                 self.tcx().sess.bug(
                     format!("no type for node {}: {} in fcx {}",
-                            id, self.tcx().map.node_to_str(id),
+                            id, self.tcx().map.node_to_string(id),
                             self.tag()).as_slice());
             }
         }
@@ -1375,7 +1384,7 @@ pub fn method_ty_substs(&self, id: ast::NodeId) -> subst::Substs {
             None => {
                 self.tcx().sess.bug(
                     format!("no method entry for node {}: {} in fcx {}",
-                            id, self.tcx().map.node_to_str(id),
+                            id, self.tcx().map.node_to_string(id),
                             self.tag()).as_slice());
             }
         }
@@ -1629,6 +1638,76 @@ fn try_overloaded_deref(fcx: &FnCtxt,
     }
 }
 
+fn try_overloaded_index(fcx: &FnCtxt,
+                        method_call: Option<MethodCall>,
+                        expr: &ast::Expr,
+                        base_expr: Gc<ast::Expr>,
+                        base_ty: ty::t,
+                        index_expr: Gc<ast::Expr>,
+                        lvalue_pref: LvaluePreference)
+                        -> Option<ty::mt> {
+    // Try `IndexMut` first, if preferred.
+    let method = match (lvalue_pref, fcx.tcx().lang_items.index_mut_trait()) {
+        (PreferMutLvalue, Some(trait_did)) => {
+            method::lookup_in_trait(fcx,
+                                    expr.span,
+                                    Some(&*base_expr),
+                                    token::intern("index_mut"),
+                                    trait_did,
+                                    base_ty,
+                                    [],
+                                    DontAutoderefReceiver,
+                                    IgnoreStaticMethods)
+        }
+        _ => None,
+    };
+
+    // Otherwise, fall back to `Index`.
+    let method = match (method, fcx.tcx().lang_items.index_trait()) {
+        (None, Some(trait_did)) => {
+            method::lookup_in_trait(fcx,
+                                    expr.span,
+                                    Some(&*base_expr),
+                                    token::intern("index"),
+                                    trait_did,
+                                    base_ty,
+                                    [],
+                                    DontAutoderefReceiver,
+                                    IgnoreStaticMethods)
+        }
+        (method, _) => method,
+    };
+
+    // Regardless of whether the lookup succeeds, check the method arguments
+    // so that we have *some* type for each argument.
+    let method_type = match method {
+        Some(ref method) => method.ty,
+        None => ty::mk_err()
+    };
+    check_method_argument_types(fcx,
+                                expr.span,
+                                method_type,
+                                expr,
+                                [base_expr, index_expr],
+                                DoDerefArgs,
+                                DontTupleArguments);
+
+    match method {
+        Some(method) => {
+            let ref_ty = ty::ty_fn_ret(method.ty);
+            match method_call {
+                Some(method_call) => {
+                    fcx.inh.method_map.borrow_mut().insert(method_call,
+                                                           method);
+                }
+                None => {}
+            }
+            ty::deref(ref_ty, true)
+        }
+        None => None,
+    }
+}
+
 fn check_method_argument_types(fcx: &FnCtxt,
                                sp: Span,
                                method_fn_ty: ty::t,
@@ -1772,7 +1851,7 @@ fn check_argument_types(fcx: &FnCtxt,
     };
 
     debug!("check_argument_types: formal_tys={:?}",
-           formal_tys.iter().map(|t| fcx.infcx().ty_to_str(*t)).collect::<Vec<String>>());
+           formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
 
     // Check the arguments.
     // We do this in a pretty awful way: first we typecheck any arguments
@@ -2002,7 +2081,7 @@ pub fn impl_self_ty(vcx: &VtableContext,
     let ity = ty::lookup_item_type(tcx, did);
     let (n_tps, rps, raw_ty) =
         (ity.generics.types.len(subst::TypeSpace),
-         ity.generics.regions.get_vec(subst::TypeSpace),
+         ity.generics.regions.get_slice(subst::TypeSpace),
          ity.ty);
 
     let rps = vcx.infcx.region_vars_for_defs(span, rps);
@@ -2340,7 +2419,7 @@ fn check_binop(fcx: &FnCtxt,
                                              operation `{}` not \
                                              supported for floating \
                                              point SIMD vector `{}`",
-                                            ast_util::binop_to_str(op),
+                                            ast_util::binop_to_string(op),
                                             actual)
                                 },
                                 lhs_t,
@@ -2370,7 +2449,7 @@ fn check_binop(fcx: &FnCtxt,
                                    |actual| {
                     format!("binary operation `{}` cannot be applied \
                              to type `{}`",
-                            ast_util::binop_to_str(op),
+                            ast_util::binop_to_string(op),
                             actual)
                 },
                 lhs_t,
@@ -2387,7 +2466,7 @@ fn check_binop(fcx: &FnCtxt,
                                                  operation `{}=` \
                                                  cannot be applied to \
                                                  type `{}`",
-                                                ast_util::binop_to_str(op),
+                                                ast_util::binop_to_string(op),
                                                 actual)
                                    },
                                    lhs_t,
@@ -2436,7 +2515,7 @@ fn check_user_binop(fcx: &FnCtxt,
                          trait_did, [lhs_expr, rhs], DontAutoderefReceiver, || {
             fcx.type_error_message(ex.span, |actual| {
                 format!("binary operation `{}` cannot be applied to type `{}`",
-                        ast_util::binop_to_str(op),
+                        ast_util::binop_to_string(op),
                         actual)
             }, lhs_resolved_t, None)
         })
@@ -2524,7 +2603,7 @@ fn check_expr_fn(fcx: &FnCtxt,
                                            expected_sig);
         let fty_sig = fn_ty.sig.clone();
         let fty = ty::mk_closure(tcx, fn_ty);
-        debug!("check_expr_fn fty={}", fcx.infcx().ty_to_str(fty));
+        debug!("check_expr_fn fty={}", fcx.infcx().ty_to_string(fty));
 
         fcx.write_ty(expr.id, fty);
 
@@ -2558,7 +2637,7 @@ fn check_field(fcx: &FnCtxt,
             autoderef(fcx, expr.span, expr_t, Some(base.id), lvalue_pref, |base_t, _| {
                 match ty::get(base_t).sty {
                     ty::ty_struct(base_id, ref substs) => {
-                        debug!("struct named {}", ppaux::ty_to_str(tcx, base_t));
+                        debug!("struct named {}", ppaux::ty_to_string(tcx, base_t));
                         let fields = ty::lookup_struct_fields(tcx, base_id);
                         lookup_field_ty(tcx, base_id, fields.as_slice(),
                                         field.node.name, &(*substs))
@@ -3296,17 +3375,34 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
         // Resolve the path.
         let def = tcx.def_map.borrow().find(&id).map(|i| *i);
         match def {
-            Some(def::DefStruct(type_def_id)) => {
-                check_struct_constructor(fcx, id, expr.span, type_def_id,
-                                         fields.as_slice(), base_expr);
-            }
             Some(def::DefVariant(enum_id, variant_id, _)) => {
                 check_struct_enum_variant(fcx, id, expr.span, enum_id,
                                           variant_id, fields.as_slice());
             }
+            Some(def) => {
+                // Verify that this was actually a struct.
+                let typ = ty::lookup_item_type(fcx.ccx.tcx, def.def_id());
+                match ty::get(typ.ty).sty {
+                    ty::ty_struct(struct_did, _) => {
+                        check_struct_constructor(fcx,
+                                                 id,
+                                                 expr.span,
+                                                 struct_did,
+                                                 fields.as_slice(),
+                                                 base_expr);
+                    }
+                    _ => {
+                        tcx.sess
+                           .span_err(path.span,
+                                     format!("`{}` does not name a structure",
+                                             pprust::path_to_string(
+                                                 path)).as_slice())
+                    }
+                }
+            }
             _ => {
                 tcx.sess.span_bug(path.span,
-                                  "structure constructor does not name a structure type");
+                                  "structure constructor wasn't resolved")
             }
         }
       }
@@ -3323,7 +3419,7 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
           } else if ty::type_is_error(idx_t) || ty::type_is_bot(idx_t) {
               fcx.write_ty(id, idx_t);
           } else {
-              let (base_t, autoderefs, field_ty) =
+              let (_, autoderefs, field_ty) =
                 autoderef(fcx, expr.span, raw_base_t, Some(base.id),
                           lvalue_pref, |base_t, _| ty::index(base_t));
               match field_ty {
@@ -3333,27 +3429,33 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
                       fcx.write_autoderef_adjustment(base.id, autoderefs);
                   }
                   None => {
-                      let resolved = structurally_resolved_type(fcx,
-                                                                expr.span,
-                                                                raw_base_t);
-                      let ret_ty = lookup_op_method(fcx,
-                                                    expr,
-                                                    resolved,
-                                                    token::intern("index"),
-                                                    tcx.lang_items.index_trait(),
-                                                    [base.clone(), idx.clone()],
-                                                    AutoderefReceiver,
-                                                    || {
-                        fcx.type_error_message(expr.span,
-                                               |actual| {
-                                                    format!("cannot index a \
-                                                             value of type \
-                                                             `{}`", actual)
-                                               },
-                                               base_t,
-                                               None);
-                      });
-                      fcx.write_ty(id, ret_ty);
+                      // This is an overloaded method.
+                      let base_t = structurally_resolved_type(fcx,
+                                                              expr.span,
+                                                              raw_base_t);
+                      let method_call = MethodCall::expr(expr.id);
+                      match try_overloaded_index(fcx,
+                                                 Some(method_call),
+                                                 expr,
+                                                 *base,
+                                                 base_t,
+                                                 *idx,
+                                                 lvalue_pref) {
+                          Some(mt) => fcx.write_ty(id, mt.ty),
+                          None => {
+                                fcx.type_error_message(expr.span,
+                                                       |actual| {
+                                                        format!("cannot \
+                                                                 index a \
+                                                                 value of \
+                                                                 type `{}`",
+                                                                actual)
+                                                       },
+                                                       base_t,
+                                                       None);
+                                fcx.write_ty(id, ty::mk_err())
+                          }
+                      }
                   }
               }
           }
@@ -3361,10 +3463,10 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
     }
 
     debug!("type of expr({}) {} is...", expr.id,
-           syntax::print::pprust::expr_to_str(expr));
+           syntax::print::pprust::expr_to_string(expr));
     debug!("... {}, expected is {}",
-           ppaux::ty_to_str(tcx, fcx.expr_ty(expr)),
-           expected.repr(tcx))
+           ppaux::ty_to_string(tcx, fcx.expr_ty(expr)),
+           expected.repr(tcx));
 
     unifier();
 }
@@ -3699,7 +3801,7 @@ pub fn check_instantiable(tcx: &ty::ctxt,
                      format!("this type cannot be instantiated without an \
                               instance of itself; consider using \
                               `Option<{}>`",
-                             ppaux::ty_to_str(tcx, item_ty)).as_slice());
+                             ppaux::ty_to_string(tcx, item_ty)).as_slice());
         false
     } else {
         true
@@ -3760,7 +3862,7 @@ pub fn check_enum_variants_sized(ccx: &CrateCtxt,
                                         dynamically sized types may only \
                                         appear as the final type in a \
                                         variant",
-                                       ppaux::ty_to_str(ccx.tcx,
+                                       ppaux::ty_to_string(ccx.tcx,
                                                         *t)).as_slice());
                     }
                 }
@@ -3825,7 +3927,7 @@ fn do_check(ccx: &CrateCtxt,
 
             match v.node.disr_expr {
                 Some(e) => {
-                    debug!("disr expr, checking {}", pprust::expr_to_str(&*e));
+                    debug!("disr expr, checking {}", pprust::expr_to_string(&*e));
 
                     let inh = blank_inherited_fields(ccx);
                     let fcx = blank_fn_ctxt(ccx, &inh, rty, e.id);
@@ -4126,12 +4228,10 @@ pub fn instantiate_path(fcx: &FnCtxt,
     // a problem.
     for &space in ParamSpace::all().iter() {
         adjust_type_parameters(fcx, span, space, type_defs, &mut substs);
-        assert_eq!(substs.types.get_vec(space).len(),
-                   type_defs.get_vec(space).len());
+        assert_eq!(substs.types.len(space), type_defs.len(space));
 
         adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
-        assert_eq!(substs.regions().get_vec(space).len(),
-                   region_defs.get_vec(space).len());
+        assert_eq!(substs.regions().len(space), region_defs.len(space));
     }
 
     fcx.write_ty_substs(node_id, polytype.ty, ty::ItemSubsts {
@@ -4183,8 +4283,8 @@ fn push_explicit_parameters_from_segment_to_substs(
          */
 
         {
-            let type_count = type_defs.get_vec(space).len();
-            assert_eq!(substs.types.get_vec(space).len(), 0);
+            let type_count = type_defs.len(space);
+            assert_eq!(substs.types.len(space), 0);
             for (i, &typ) in segment.types.iter().enumerate() {
                 let t = fcx.to_ty(&*typ);
                 if i < type_count {
@@ -4198,14 +4298,14 @@ fn push_explicit_parameters_from_segment_to_substs(
                              but found {} parameter(s)",
                             type_count,
                             segment.types.len()).as_slice());
-                    substs.types.get_mut_vec(space).truncate(0);
+                    substs.types.truncate(space, 0);
                 }
             }
         }
 
         {
-            let region_count = region_defs.get_vec(space).len();
-            assert_eq!(substs.regions().get_vec(space).len(), 0);
+            let region_count = region_defs.len(space);
+            assert_eq!(substs.regions().len(space), 0);
             for (i, lifetime) in segment.lifetimes.iter().enumerate() {
                 let r = ast_region_to_region(fcx.tcx(), lifetime);
                 if i < region_count {
@@ -4218,7 +4318,7 @@ fn push_explicit_parameters_from_segment_to_substs(
                              expected {} parameter(s) but found {} parameter(s)",
                             region_count,
                             segment.lifetimes.len()).as_slice());
-                    substs.mut_regions().get_mut_vec(space).truncate(0);
+                    substs.mut_regions().truncate(space, 0);
                 }
             }
         }
@@ -4231,8 +4331,8 @@ fn adjust_type_parameters(
         defs: &VecPerParamSpace<ty::TypeParameterDef>,
         substs: &mut Substs)
     {
-        let provided_len = substs.types.get_vec(space).len();
-        let desired = defs.get_vec(space).as_slice();
+        let provided_len = substs.types.len(space);
+        let desired = defs.get_slice(space);
         let required_len = desired.iter()
                               .take_while(|d| d.default.is_none())
                               .count();
@@ -4252,8 +4352,8 @@ fn adjust_type_parameters(
         // Nothing specified at all: supply inference variables for
         // everything.
         if provided_len == 0 {
-            let provided = substs.types.get_mut_vec(space);
-            *provided = fcx.infcx().next_ty_vars(desired.len());
+            substs.types.replace(space,
+                                 fcx.infcx().next_ty_vars(desired.len()));
             return;
         }
 
@@ -4270,8 +4370,8 @@ fn adjust_type_parameters(
                             qualifier,
                             required_len,
                             provided_len).as_slice());
-            let provided = substs.types.get_mut_vec(space);
-            *provided = Vec::from_elem(desired.len(), ty::mk_err());
+            substs.types.replace(space,
+                                 Vec::from_elem(desired.len(), ty::mk_err()));
             return;
         }
 
@@ -4287,7 +4387,7 @@ fn adjust_type_parameters(
             let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
             substs.types.push(space, default);
         }
-        assert_eq!(substs.types.get_vec(space).len(), desired.len());
+        assert_eq!(substs.types.len(space), desired.len());
 
         debug!("Final substs: {}", substs.repr(fcx.tcx()));
     }
@@ -4299,20 +4399,22 @@ fn adjust_region_parameters(
         defs: &VecPerParamSpace<ty::RegionParameterDef>,
         substs: &mut Substs)
     {
-        let provided = substs.mut_regions().get_mut_vec(space);
-        let desired = defs.get_vec(space);
+        let provided_len = substs.mut_regions().len(space);
+        let desired = defs.get_slice(space);
 
         // Enforced by `push_explicit_parameters_from_segment_to_substs()`.
-        assert!(provided.len() <= desired.len());
+        assert!(provided_len <= desired.len());
 
         // If nothing was provided, just use inference variables.
-        if provided.len() == 0 {
-            *provided = fcx.infcx().region_vars_for_defs(span, desired);
+        if provided_len == 0 {
+            substs.mut_regions().replace(
+                space,
+                fcx.infcx().region_vars_for_defs(span, desired));
             return;
         }
 
         // If just the right number were provided, everybody is happy.
-        if provided.len() == desired.len() {
+        if provided_len == desired.len() {
             return;
         }
 
@@ -4325,9 +4427,11 @@ fn adjust_region_parameters(
                          expected {} parameter(s) \
                          but found {} parameter(s)",
                 desired.len(),
-                provided.len()).as_slice());
+                provided_len).as_slice());
 
-        *provided = fcx.infcx().region_vars_for_defs(span, desired);
+        substs.mut_regions().replace(
+            space,
+            fcx.infcx().region_vars_for_defs(span, desired));
     }
 }
 
@@ -4427,7 +4531,7 @@ pub fn check_bounds_are_used(ccx: &CrateCtxt,
                              tps: &OwnedSlice<ast::TyParam>,
                              ty: ty::t) {
     debug!("check_bounds_are_used(n_tps={}, ty={})",
-           tps.len(), ppaux::ty_to_str(ccx.tcx, ty));
+           tps.len(), ppaux::ty_to_string(ccx.tcx, ty));
 
     // make a vector of booleans initially false, set to true when used
     if tps.len() == 0u { return; }
@@ -4745,7 +4849,7 @@ fn param(ccx: &CrateCtxt, n: uint) -> ty::t {
                            fty,
                            || {
                 format!("intrinsic has wrong type: expected `{}`",
-                        ppaux::ty_to_str(ccx.tcx, fty))
+                        ppaux::ty_to_string(ccx.tcx, fty))
             });
     }
 }