]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #14158 : nikomatsakis/rust/issue-5527-refactor-foldable, r=pcwalton
authorbors <bors@rust-lang.org>
Tue, 13 May 2014 15:57:33 +0000 (08:57 -0700)
committerbors <bors@rust-lang.org>
Tue, 13 May 2014 15:57:33 +0000 (08:57 -0700)
Factor out foldable better to reduce code duplication.

r? @pcwalton (probably want to let travis run...)

1  2 
src/librustc/middle/ty.rs
src/librustc/middle/typeck/check/mod.rs

index b6f8f33b719cc3d572ef758bd1f70bd5aa63cce9,7ef61a2361d3968b544c9a321dd4c3f3b9e61f6a..2ae925caab56395c1d6028d0dd3dd45e8541fad5
@@@ -26,7 -26,7 +26,7 @@@ use middle::subst::Subst
  use middle::typeck;
  use middle::typeck::MethodCall;
  use middle::ty_fold;
- use middle::ty_fold::TypeFolder;
+ use middle::ty_fold::{TypeFoldable,TypeFolder};
  use middle;
  use util::ppaux::{note_and_explain_region, bound_region_ptr_to_str};
  use util::ppaux::{trait_store_to_str, ty_to_str};
@@@ -278,7 -278,7 +278,7 @@@ pub struct ctxt 
      pub freevars: RefCell<freevars::freevar_map>,
      pub tcache: type_cache,
      pub rcache: creader_cache,
 -    pub short_names_cache: RefCell<HashMap<t, ~str>>,
 +    pub short_names_cache: RefCell<HashMap<t, StrBuf>>,
      pub needs_unwind_cleanup_cache: RefCell<HashMap<t, bool>>,
      pub tc_cache: RefCell<HashMap<uint, TypeContents>>,
      pub ast_ty_to_ty_cache: RefCell<NodeMap<ast_ty_to_ty_cache_entry>>,
@@@ -1034,7 -1034,7 +1034,7 @@@ pub struct ParameterEnvironment 
      pub self_param_bound: Option<Rc<TraitRef>>,
  
      /// Bounds on each numbered type parameter
-     pub type_param_bounds: Vec<ParamBounds> ,
+     pub type_param_bounds: Vec<ParamBounds>,
  }
  
  /// A polytype.
@@@ -1519,7 -1519,9 +1519,9 @@@ pub fn walk_regions_and_ty(cx: &ctxt, t
  
  impl ItemSubsts {
      pub fn empty() -> ItemSubsts {
-         ItemSubsts { substs: substs::empty() }
+         ItemSubsts {
+             substs: substs::empty(),
+         }
      }
  
      pub fn is_noop(&self) -> bool {
@@@ -1538,7 -1540,7 +1540,7 @@@ pub fn substs_is_noop(substs: &substs) 
          substs.self_ty.is_none()
  }
  
 -pub fn substs_to_str(cx: &ctxt, substs: &substs) -> ~str {
 +pub fn substs_to_str(cx: &ctxt, substs: &substs) -> StrBuf {
      substs.repr(cx)
  }
  
@@@ -3189,9 -3191,7 +3191,9 @@@ pub fn field_idx_strict(tcx: &ctxt, nam
      tcx.sess.bug(format!(
          "no field named `{}` found in the list of fields `{:?}`",
          token::get_name(name),
 -        fields.iter().map(|f| token::get_ident(f.ident).get().to_str()).collect::<Vec<~str>>()));
 +        fields.iter()
 +              .map(|f| token::get_ident(f.ident).get().to_strbuf())
 +              .collect::<Vec<StrBuf>>()));
  }
  
  pub fn method_idx(id: ast::Ident, meths: &[Rc<Method>]) -> Option<uint> {
@@@ -3214,38 -3214,34 +3216,38 @@@ pub fn param_tys_in_type(ty: t) -> Vec<
      rslt
  }
  
 -pub fn ty_sort_str(cx: &ctxt, t: t) -> ~str {
 +pub fn ty_sort_str(cx: &ctxt, t: t) -> StrBuf {
      match get(t).sty {
          ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) |
          ty_uint(_) | ty_float(_) | ty_str => {
              ::util::ppaux::ty_to_str(cx, t)
          }
  
 -        ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)),
 -        ty_box(_) => "@-ptr".to_owned(),
 -        ty_uniq(_) => "box".to_owned(),
 -        ty_vec(_, _) => "vector".to_owned(),
 -        ty_ptr(_) => "*-ptr".to_owned(),
 -        ty_rptr(_, _) => "&-ptr".to_owned(),
 -        ty_bare_fn(_) => "extern fn".to_owned(),
 -        ty_closure(_) => "fn".to_owned(),
 -        ty_trait(ref inner) => format!("trait {}", item_path_str(cx, inner.def_id)),
 -        ty_struct(id, _) => format!("struct {}", item_path_str(cx, id)),
 -        ty_tup(_) => "tuple".to_owned(),
 -        ty_infer(TyVar(_)) => "inferred type".to_owned(),
 -        ty_infer(IntVar(_)) => "integral variable".to_owned(),
 -        ty_infer(FloatVar(_)) => "floating-point variable".to_owned(),
 -        ty_param(_) => "type parameter".to_owned(),
 -        ty_self(_) => "self".to_owned(),
 -        ty_err => "type error".to_owned()
 -    }
 -}
 -
 -pub fn type_err_to_str(cx: &ctxt, err: &type_err) -> ~str {
 +        ty_enum(id, _) => format_strbuf!("enum {}", item_path_str(cx, id)),
 +        ty_box(_) => "@-ptr".to_strbuf(),
 +        ty_uniq(_) => "box".to_strbuf(),
 +        ty_vec(_, _) => "vector".to_strbuf(),
 +        ty_ptr(_) => "*-ptr".to_strbuf(),
 +        ty_rptr(_, _) => "&-ptr".to_strbuf(),
 +        ty_bare_fn(_) => "extern fn".to_strbuf(),
 +        ty_closure(_) => "fn".to_strbuf(),
 +        ty_trait(ref inner) => {
 +            format_strbuf!("trait {}", item_path_str(cx, inner.def_id))
 +        }
 +        ty_struct(id, _) => {
 +            format_strbuf!("struct {}", item_path_str(cx, id))
 +        }
 +        ty_tup(_) => "tuple".to_strbuf(),
 +        ty_infer(TyVar(_)) => "inferred type".to_strbuf(),
 +        ty_infer(IntVar(_)) => "integral variable".to_strbuf(),
 +        ty_infer(FloatVar(_)) => "floating-point variable".to_strbuf(),
 +        ty_param(_) => "type parameter".to_strbuf(),
 +        ty_self(_) => "self".to_strbuf(),
 +        ty_err => "type error".to_strbuf(),
 +    }
 +}
 +
 +pub fn type_err_to_str(cx: &ctxt, err: &type_err) -> StrBuf {
      /*!
       *
       * Explains the source of a type err in a short,
       * to present additional details, particularly when
       * it comes to lifetime-related errors. */
  
 -    fn tstore_to_closure(s: &TraitStore) -> ~str {
 +    fn tstore_to_closure(s: &TraitStore) -> StrBuf {
          match s {
 -            &UniqTraitStore => "proc".to_owned(),
 -            &RegionTraitStore(..) => "closure".to_owned()
 +            &UniqTraitStore => "proc".to_strbuf(),
 +            &RegionTraitStore(..) => "closure".to_strbuf()
          }
      }
  
      match *err {
 -        terr_mismatch => "types differ".to_owned(),
 +        terr_mismatch => "types differ".to_strbuf(),
          terr_fn_style_mismatch(values) => {
 -            format!("expected {} fn but found {} fn",
 -                 values.expected.to_str(), values.found.to_str())
 +            format_strbuf!("expected {} fn but found {} fn",
 +                           values.expected.to_str(),
 +                           values.found.to_str())
          }
          terr_abi_mismatch(values) => {
 -            format!("expected {} fn but found {} fn",
 -                 values.expected.to_str(), values.found.to_str())
 +            format_strbuf!("expected {} fn but found {} fn",
 +                           values.expected.to_str(),
 +                           values.found.to_str())
          }
          terr_onceness_mismatch(values) => {
 -            format!("expected {} fn but found {} fn",
 -                 values.expected.to_str(), values.found.to_str())
 +            format_strbuf!("expected {} fn but found {} fn",
 +                           values.expected.to_str(),
 +                           values.found.to_str())
          }
          terr_sigil_mismatch(values) => {
 -            format!("expected {}, found {}",
 -                    tstore_to_closure(&values.expected),
 -                    tstore_to_closure(&values.found))
 +            format_strbuf!("expected {}, found {}",
 +                           tstore_to_closure(&values.expected),
 +                           tstore_to_closure(&values.found))
 +        }
 +        terr_mutability => "values differ in mutability".to_strbuf(),
 +        terr_box_mutability => {
 +            "boxed values differ in mutability".to_strbuf()
          }
 -        terr_mutability => "values differ in mutability".to_owned(),
 -        terr_box_mutability => "boxed values differ in mutability".to_owned(),
 -        terr_vec_mutability => "vectors differ in mutability".to_owned(),
 -        terr_ptr_mutability => "pointers differ in mutability".to_owned(),
 -        terr_ref_mutability => "references differ in mutability".to_owned(),
 +        terr_vec_mutability => "vectors differ in mutability".to_strbuf(),
 +        terr_ptr_mutability => "pointers differ in mutability".to_strbuf(),
 +        terr_ref_mutability => "references differ in mutability".to_strbuf(),
          terr_ty_param_size(values) => {
 -            format!("expected a type with {} type params \
 -                  but found one with {} type params",
 -                 values.expected, values.found)
 +            format_strbuf!("expected a type with {} type params \
 +                            but found one with {} type params",
 +                           values.expected,
 +                           values.found)
          }
          terr_tuple_size(values) => {
 -            format!("expected a tuple with {} elements \
 -                  but found one with {} elements",
 -                 values.expected, values.found)
 +            format_strbuf!("expected a tuple with {} elements \
 +                            but found one with {} elements",
 +                           values.expected,
 +                           values.found)
          }
          terr_record_size(values) => {
 -            format!("expected a record with {} fields \
 -                  but found one with {} fields",
 -                 values.expected, values.found)
 +            format_strbuf!("expected a record with {} fields \
 +                            but found one with {} fields",
 +                           values.expected,
 +                           values.found)
          }
          terr_record_mutability => {
 -            "record elements differ in mutability".to_owned()
 +            "record elements differ in mutability".to_strbuf()
          }
          terr_record_fields(values) => {
 -            format!("expected a record with field `{}` but found one with field \
 -                  `{}`",
 -                 token::get_ident(values.expected),
 -                 token::get_ident(values.found))
 +            format_strbuf!("expected a record with field `{}` but found one \
 +                            with field `{}`",
 +                           token::get_ident(values.expected),
 +                           token::get_ident(values.found))
 +        }
 +        terr_arg_count => {
 +            "incorrect number of function parameters".to_strbuf()
          }
 -        terr_arg_count => "incorrect number of function parameters".to_owned(),
          terr_regions_does_not_outlive(..) => {
 -            format!("lifetime mismatch")
 +            "lifetime mismatch".to_strbuf()
          }
          terr_regions_not_same(..) => {
 -            format!("lifetimes are not the same")
 +            "lifetimes are not the same".to_strbuf()
          }
          terr_regions_no_overlap(..) => {
 -            format!("lifetimes do not intersect")
 +            "lifetimes do not intersect".to_strbuf()
          }
          terr_regions_insufficiently_polymorphic(br, _) => {
 -            format!("expected bound lifetime parameter {}, \
 -                  but found concrete lifetime",
 -                 bound_region_ptr_to_str(cx, br))
 +            format_strbuf!("expected bound lifetime parameter {}, \
 +                            but found concrete lifetime",
 +                           bound_region_ptr_to_str(cx, br))
          }
          terr_regions_overly_polymorphic(br, _) => {
 -            format!("expected concrete lifetime, \
 -                  but found bound lifetime parameter {}",
 -                 bound_region_ptr_to_str(cx, br))
 +            format_strbuf!("expected concrete lifetime, \
 +                            but found bound lifetime parameter {}",
 +                           bound_region_ptr_to_str(cx, br))
          }
          terr_trait_stores_differ(_, ref values) => {
 -            format!("trait storage differs: expected `{}` but found `{}`",
 -                 trait_store_to_str(cx, (*values).expected),
 -                 trait_store_to_str(cx, (*values).found))
 +            format_strbuf!("trait storage differs: expected `{}` but found \
 +                            `{}`",
 +                           trait_store_to_str(cx, (*values).expected),
 +                           trait_store_to_str(cx, (*values).found))
          }
          terr_sorts(values) => {
 -            format!("expected {} but found {}",
 -                 ty_sort_str(cx, values.expected),
 -                 ty_sort_str(cx, values.found))
 +            format_strbuf!("expected {} but found {}",
 +                           ty_sort_str(cx, values.expected),
 +                           ty_sort_str(cx, values.found))
          }
          terr_traits(values) => {
 -            format!("expected trait `{}` but found trait `{}`",
 -                 item_path_str(cx, values.expected),
 -                 item_path_str(cx, values.found))
 +            format_strbuf!("expected trait `{}` but found trait `{}`",
 +                           item_path_str(cx, values.expected),
 +                           item_path_str(cx, values.found))
          }
          terr_builtin_bounds(values) => {
              if values.expected.is_empty() {
 -                format!("expected no bounds but found `{}`",
 -                     values.found.user_string(cx))
 +                format_strbuf!("expected no bounds but found `{}`",
 +                               values.found.user_string(cx))
              } else if values.found.is_empty() {
 -                format!("expected bounds `{}` but found no bounds",
 -                     values.expected.user_string(cx))
 +                format_strbuf!("expected bounds `{}` but found no bounds",
 +                               values.expected.user_string(cx))
              } else {
 -                format!("expected bounds `{}` but found bounds `{}`",
 -                     values.expected.user_string(cx),
 -                     values.found.user_string(cx))
 +                format_strbuf!("expected bounds `{}` but found bounds `{}`",
 +                               values.expected.user_string(cx),
 +                               values.found.user_string(cx))
              }
          }
          terr_integer_as_char => {
 -            format!("expected an integral type but found `char`")
 +            "expected an integral type but found `char`".to_strbuf()
          }
          terr_int_mismatch(ref values) => {
 -            format!("expected `{}` but found `{}`",
 -                 values.expected.to_str(),
 -                 values.found.to_str())
 +            format_strbuf!("expected `{}` but found `{}`",
 +                           values.expected.to_str(),
 +                           values.found.to_str())
          }
          terr_float_mismatch(ref values) => {
 -            format!("expected `{}` but found `{}`",
 -                 values.expected.to_str(),
 -                 values.found.to_str())
 +            format_strbuf!("expected `{}` but found `{}`",
 +                           values.expected.to_str(),
 +                           values.found.to_str())
          }
          terr_variadic_mismatch(ref values) => {
 -            format!("expected {} fn but found {} function",
 -                    if values.expected { "variadic" } else { "non-variadic" },
 -                    if values.found { "variadic" } else { "non-variadic" })
 +            format_strbuf!("expected {} fn but found {} function",
 +                           if values.expected {
 +                                "variadic"
 +                           } else {
 +                                "non-variadic"
 +                           },
 +                           if values.found {
 +                               "variadic"
 +                           } else {
 +                               "non-variadic"
 +                           })
          }
      }
  }
@@@ -3690,8 -3667,8 +3692,8 @@@ pub fn substd_enum_variants(cx: &ctxt
      }).collect()
  }
  
 -pub fn item_path_str(cx: &ctxt, id: ast::DefId) -> ~str {
 -    with_path(cx, id, |path| ast_map::path_to_str(path)).to_owned()
 +pub fn item_path_str(cx: &ctxt, id: ast::DefId) -> StrBuf {
 +    with_path(cx, id, |path| ast_map::path_to_str(path)).to_strbuf()
  }
  
  pub enum DtorKind {
@@@ -4127,8 -4104,8 +4129,8 @@@ pub fn normalize_ty(cx: &ctxt, t: t) -
                         substs: &substs)
                         -> substs {
              substs { regions: ErasedRegions,
-                      self_ty: ty_fold::fold_opt_ty(self, substs.self_ty),
-                      tps: ty_fold::fold_ty_vec(self, substs.tps.as_slice()) }
+                      self_ty: substs.self_ty.fold_with(self),
+                      tps: substs.tps.fold_with(self) }
          }
  
          fn fold_sig(&mut self,
              // are erased at trans time.
              ty::FnSig {
                  binder_id: ast::DUMMY_NODE_ID,
-                 inputs: ty_fold::fold_ty_vec(self, sig.inputs.as_slice()),
-                 output: self.fold_ty(sig.output),
+                 inputs: sig.inputs.fold_with(self),
+                 output: sig.output.fold_with(self),
                  variadic: sig.variadic,
              }
          }
@@@ -4256,14 -4233,14 +4258,14 @@@ pub fn each_bound_trait_and_supertraits
      return true;
  }
  
 -pub fn get_tydesc_ty(tcx: &ctxt) -> Result<t, ~str> {
 +pub fn get_tydesc_ty(tcx: &ctxt) -> Result<t, StrBuf> {
      tcx.lang_items.require(TyDescStructLangItem).map(|tydesc_lang_item| {
          tcx.intrinsic_defs.borrow().find_copy(&tydesc_lang_item)
              .expect("Failed to resolve TyDesc")
      })
  }
  
 -pub fn get_opaque_ty(tcx: &ctxt) -> Result<t, ~str> {
 +pub fn get_opaque_ty(tcx: &ctxt) -> Result<t, StrBuf> {
      tcx.lang_items.require(OpaqueStructLangItem).map(|opaque_lang_item| {
          tcx.intrinsic_defs.borrow().find_copy(&opaque_lang_item)
              .expect("Failed to resolve Opaque")
  }
  
  pub fn visitor_object_ty(tcx: &ctxt,
 -                         region: ty::Region) -> Result<(Rc<TraitRef>, t), ~str> {
 +                         region: ty::Region) -> Result<(Rc<TraitRef>, t), StrBuf> {
      let trait_lang_item = match tcx.lang_items.require(TyVisitorTraitLangItem) {
          Ok(id) => id,
          Err(s) => { return Err(s); }
index 94f08b28fed2518934e9adb11f95ec13c1d8810e,22a8168ecaad112b79d9244590ac4f3573044475..6be96a408b86f5b99d7ae0f942ed35ac6b8f7747
@@@ -468,7 -468,7 +468,7 @@@ fn check_fn<'a>(ccx: &'a CrateCtxt<'a>
      let ret_ty = fn_sig.output;
  
      debug!("check_fn(arg_tys={:?}, ret_ty={:?})",
 -           arg_tys.iter().map(|&a| ppaux::ty_to_str(tcx, a)).collect::<Vec<~str>>(),
 +           arg_tys.iter().map(|&a| ppaux::ty_to_str(tcx, a)).collect::<Vec<StrBuf>>(),
             ppaux::ty_to_str(tcx, ret_ty));
  
      // Create the function context.  This is either derived from scratch or,
@@@ -1089,8 -1089,8 +1089,8 @@@ impl<'a> RegionScope for infer::InferCt
  }
  
  impl<'a> FnCtxt<'a> {
 -    pub fn tag(&self) -> ~str {
 -        format!("{}", self as *FnCtxt)
 +    pub fn tag(&self) -> StrBuf {
 +        format_strbuf!("{}", self as *FnCtxt)
      }
  
      pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> ty::t {
          ast_ty_to_ty(self, self.infcx(), ast_t)
      }
  
 -    pub fn pat_to_str(&self, pat: &ast::Pat) -> ~str {
 +    pub fn pat_to_str(&self, pat: &ast::Pat) -> StrBuf {
          pat.repr(self.tcx())
      }
  
  
      pub fn type_error_message(&self,
                                sp: Span,
 -                              mk_msg: |~str| -> ~str,
 +                              mk_msg: |StrBuf| -> StrBuf,
                                actual_ty: ty::t,
                                err: Option<&ty::type_err>) {
          self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
@@@ -1787,7 -1787,7 +1787,7 @@@ fn check_expr_with_unifier(fcx: &FnCtxt
          };
  
          debug!("check_argument_types: formal_tys={:?}",
 -               formal_tys.iter().map(|t| fcx.infcx().ty_to_str(*t)).collect::<Vec<~str>>());
 +               formal_tys.iter().map(|t| fcx.infcx().ty_to_str(*t)).collect::<Vec<StrBuf>>());
  
          // Check the arguments.
          // We do this in a pretty awful way: first we typecheck any arguments
                  match ty::get(arg_ty).sty {
                      ty::ty_float(ast::TyF32) => {
                          fcx.type_error_message(arg.span,
 -                                |t| format!("can't pass an {} to variadic function, \
 -                                             cast to c_double", t), arg_ty, None);
 +                                               |t| {
 +                            format_strbuf!("can't pass an {} to variadic \
 +                                            function, cast to c_double", t)
 +                        }, arg_ty, None);
                      }
                      ty::ty_int(ast::TyI8) | ty::ty_int(ast::TyI16) | ty::ty_bool => {
 -                        fcx.type_error_message(arg.span,
 -                                |t| format!("can't pass {} to variadic function, cast to c_int",
 -                                            t), arg_ty, None);
 +                        fcx.type_error_message(arg.span, |t| {
 +                            format_strbuf!("can't pass {} to variadic \
 +                                            function, cast to c_int",
 +                                           t)
 +                        }, arg_ty, None);
                      }
                      ty::ty_uint(ast::TyU8) | ty::ty_uint(ast::TyU16) => {
 -                        fcx.type_error_message(arg.span,
 -                                |t| format!("can't pass {} to variadic function, cast to c_uint",
 -                                            t), arg_ty, None);
 +                        fcx.type_error_message(arg.span, |t| {
 +                            format_strbuf!("can't pass {} to variadic \
 +                                            function, cast to c_uint",
 +                                           t)
 +                        }, arg_ty, None);
                      }
                      _ => {}
                  }
              ty::ty_closure(box ty::ClosureTy {sig: ref sig, ..}) => sig,
              _ => {
                  fcx.type_error_message(call_expr.span, |actual| {
 -                    format!("expected function but \
 -                          found `{}`", actual) }, fn_ty, None);
 +                    format_strbuf!("expected function but found `{}`", actual)
 +                }, fn_ty, None);
                  &error_fn_sig
              }
          };
  
                  fcx.type_error_message(method_name.span,
                    |actual| {
 -                      format!("type `{}` does not implement any method in scope named `{}`",
 -                              actual, token::get_ident(method_name.node))
 +                      format_strbuf!("type `{}` does not implement any \
 +                                      method in scope named `{}`",
 +                                     actual,
 +                                     token::get_ident(method_name.node))
                    },
                    expr_t,
                    None);
                  fcx.write_error(expr.id);
  
                  // Check for potential static matches (missing self parameters)
 -                method::lookup(fcx, expr, rcvr,
 -                                    method_name.node.name,
 -                                    expr_t, tps.as_slice(),
 -                                    DontDerefArgs,
 -                                    CheckTraitsAndInherentMethods,
 -                                    DontAutoderefReceiver, ReportStaticMethods);
 +                method::lookup(fcx,
 +                               expr,
 +                               rcvr,
 +                               method_name.node.name,
 +                               expr_t,
 +                               tps.as_slice(),
 +                               DontDerefArgs,
 +                               CheckTraitsAndInherentMethods,
 +                               DontAutoderefReceiver,
 +                               ReportStaticMethods);
  
                  ty::mk_err()
              }
                          if ty::type_is_fp(ty::simd_type(tcx, lhs_t)) {
                              fcx.type_error_message(expr.span,
                                  |actual| {
 -                                    format!("binary comparison operation `{}` not supported \
 -                                            for floating point SIMD vector `{}`",
 -                                            ast_util::binop_to_str(op), actual)
 +                                    format_strbuf!("binary comparison \
 +                                                    operation `{}` not \
 +                                                    supported for floating \
 +                                                    point SIMD vector `{}`",
 +                                                   ast_util::binop_to_str(op),
 +                                                   actual)
                                  },
                                  lhs_t,
                                  None
              // type
              fcx.write_error(expr.id);
              fcx.write_error(rhs.id);
 -            fcx.type_error_message(expr.span, |actual| {
 -                format!("binary operation `{}` cannot be applied \
 -                      to type `{}`",
 -                     ast_util::binop_to_str(op), actual)},
 -                                   lhs_t, None)
 -
 +            fcx.type_error_message(expr.span,
 +                                   |actual| {
 +                    format_strbuf!("binary operation `{}` cannot be applied \
 +                                   to type `{}`",
 +                                   ast_util::binop_to_str(op),
 +                                   actual)
 +                },
 +                lhs_t,
 +                None)
          }
  
          // Check for overloaded operators if not an assignment.
          } else {
              fcx.type_error_message(expr.span,
                                     |actual| {
 -                                        format!("binary assignment operation \
 -                                                `{}=` cannot be applied to type `{}`",
 -                                                ast_util::binop_to_str(op),
 -                                                actual)
 +                                        format_strbuf!("binary assignment \
 +                                                        operation `{}=` \
 +                                                        cannot be applied to \
 +                                                        type `{}`",
 +                                                 ast_util::binop_to_str(op),
 +                                                 actual)
                                     },
                                     lhs_t,
                                     None);
          lookup_op_method(fcx, ex, lhs_resolved_t, token::intern(name),
                           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), actual)
 +                format_strbuf!("binary operation `{}` cannot be applied to \
 +                                type `{}`",
 +                               ast_util::binop_to_str(op),
 +                               actual)
              }, lhs_resolved_t, None)
          })
      }
         lookup_op_method(fcx, ex, rhs_t, token::intern(mname),
                          trait_did, [rhs_expr], DontAutoderefReceiver, || {
              fcx.type_error_message(ex.span, |actual| {
 -                format!("cannot apply unary operator `{}` to type `{}`", op_str, actual)
 +                format_strbuf!("cannot apply unary operator `{}` to type \
 +                                `{}`",
 +                               op_str,
 +                               actual)
              }, rhs_t, None);
          })
      }
                  fcx.type_error_message(
                      expr.span,
                      |actual| {
 -                        format!("attempted to take value of method `{}` on type `{}`",
 -                                token::get_name(field), actual)
 +                        format_strbuf!("attempted to take value of method \
 +                                        `{}` on type `{}`",
 +                                       token::get_name(field),
 +                                       actual)
                      },
                      expr_t, None);
  
                  fcx.type_error_message(
                      expr.span,
                      |actual| {
 -                        format!("attempted access of field `{}` on type `{}`, \
 -                                 but no field with that name was found",
 -                                token::get_name(field), actual)
 +                        format_strbuf!("attempted access of field `{}` on \
 +                                        type `{}`, but no field with that \
 +                                        name was found",
 +                                       token::get_name(field),
 +                                       actual)
                      },
                      expr_t, None);
              }
                      fcx.type_error_message(
                        field.ident.span,
                        |actual| {
 -                          format!("structure `{}` has no field named `{}`",
 -                                  actual, token::get_ident(field.ident.node))
 -                    }, struct_ty, None);
 +                          format_strbuf!("structure `{}` has no field named \
 +                                          `{}`",
 +                                         actual,
 +                                         token::get_ident(field.ident.node))
 +                      },
 +                      struct_ty,
 +                      None);
                      error_happened = true;
                  }
                  Some((_, true)) => {
                                             .require(GcLangItem) {
                                        Ok(id) => id,
                                        Err(msg) => {
 -                                          tcx.sess.span_err(expr.span, msg);
 +                                          tcx.sess.span_err(expr.span,
 +                                                            msg.as_slice());
                                            ast::DefId {
                                                krate: ast::CRATE_NODE_ID,
                                                node: ast::DUMMY_NODE_ID,
                                           no longer be dereferenced");
                                  } else {
                                      fcx.type_error_message(expr.span, |actual| {
 -                                        format!("type `{}` cannot be dereferenced", actual)
 +                                        format_strbuf!("type `{}` cannot be \
 +                                                        dereferenced",
 +                                                       actual)
                                      }, oprnd_t, None);
                                  }
                                  ty::mk_err()
                  _ => {
                      if ty::type_is_nil(t_e) {
                          fcx.type_error_message(expr.span, |actual| {
 -                            format!("cast from nil: `{}` as `{}`", actual,
 -                                 fcx.infcx().ty_to_str(t_1))
 +                            format_strbuf!("cast from nil: `{}` as `{}`",
 +                                           actual,
 +                                           fcx.infcx().ty_to_str(t_1))
                          }, t_e, None);
                      } else if ty::type_is_nil(t_1) {
                          fcx.type_error_message(expr.span, |actual| {
 -                            format!("cast to nil: `{}` as `{}`", actual,
 -                                 fcx.infcx().ty_to_str(t_1))
 +                            format_strbuf!("cast to nil: `{}` as `{}`",
 +                                           actual,
 +                                           fcx.infcx().ty_to_str(t_1))
                          }, t_e, None);
                      }
  
                          let te = fcx.infcx().resolve_type_vars_if_possible(te);
                          if ty::get(te).sty != ty::ty_uint(ast::TyU8) {
                              fcx.type_error_message(expr.span, |actual| {
 -                                format!("only `u8` can be cast as `char`, not `{}`", actual)
 +                                format_strbuf!("only `u8` can be cast as \
 +                                                `char`, not `{}`",
 +                                               actual)
                              }, t_e, None);
                          }
                      } else if ty::get(t1).sty == ty::ty_bool {
 -                        fcx.tcx().sess.span_err(expr.span,
 -                                                "cannot cast as `bool`, compare with zero instead");
 +                        fcx.tcx()
 +                           .sess
 +                           .span_err(expr.span,
 +                                     "cannot cast as `bool`, compare with \
 +                                      zero instead");
                      } else if type_is_region_ptr(fcx, expr.span, t_e) &&
                          type_is_unsafe_ptr(fcx, expr.span, t_1) {
  
                          record the issue number in this comment.
                          */
                          fcx.type_error_message(expr.span, |actual| {
 -                            format!("non-scalar cast: `{}` as `{}`", actual,
 -                                 fcx.infcx().ty_to_str(t_1))
 +                            format_strbuf!("non-scalar cast: `{}` as `{}`",
 +                                           actual,
 +                                           fcx.infcx().ty_to_str(t_1))
                          }, t_e, None);
                      }
                  }
                                                      || {
                          fcx.type_error_message(expr.span,
                                                 |actual| {
 -                                                format!("cannot index a value \
 -                                                      of type `{}`",
 -                                                     actual)
 +                                                    format_strbuf!("cannot \
 +                                                                    index a \
 +                                                                    value of \
 +                                                                    type \
 +                                                                    `{}`",
 +                                                                    actual)
                                                 },
                                                 base_t,
                                                 None);
             ppaux::ty_to_str(tcx, fcx.expr_ty(expr)),
             match expected {
                 Some(t) => ppaux::ty_to_str(tcx, t),
 -               _ => "empty".to_owned()
 +               _ => "empty".to_strbuf()
             });
  
      unifier();
  pub fn require_uint(fcx: &FnCtxt, sp: Span, t: ty::t) {
      if !type_is_uint(fcx, sp, t) {
          fcx.type_error_message(sp, |actual| {
 -            format!("mismatched types: expected `uint` type but found `{}`",
 -                 actual)
 +            format_strbuf!("mismatched types: expected `uint` type but found \
 +                           `{}`",
 +                           actual)
          }, t, None);
      }
  }
  pub fn require_integral(fcx: &FnCtxt, sp: Span, t: ty::t) {
      if !type_is_integral(fcx, sp, t) {
          fcx.type_error_message(sp, |actual| {
 -            format!("mismatched types: expected integral type but found `{}`",
 -                 actual)
 +            format_strbuf!("mismatched types: expected integral type but \
 +                            found `{}`",
 +                           actual)
          }, t, None);
      }
  }
@@@ -3488,13 -3439,8 +3488,13 @@@ pub fn check_block_with_expected(fcx: &
                    ast::StmtExpr(_, _) | ast::StmtSemi(_, _) => true,
                    _ => false
                  } {
 -                fcx.ccx.tcx.sess.add_lint(UnreachableCode, s_id, s.span,
 -                                          "unreachable statement".to_owned());
 +                fcx.ccx
 +                   .tcx
 +                   .sess
 +                   .add_lint(UnreachableCode,
 +                             s_id,
 +                             s.span,
 +                             "unreachable statement".to_strbuf());
                  warned = true;
              }
              if ty::type_is_bot(s_ty) {
              },
            Some(e) => {
              if any_bot && !warned {
 -                fcx.ccx.tcx.sess.add_lint(UnreachableCode, e.id, e.span,
 -                                          "unreachable expression".to_owned());
 +                fcx.ccx
 +                   .tcx
 +                   .sess
 +                   .add_lint(UnreachableCode,
 +                             e.id,
 +                             e.span,
 +                             "unreachable expression".to_strbuf());
              }
              check_expr_with_opt_hint(fcx, e, expected);
                let ety = fcx.expr_ty(e);
@@@ -4022,10 -3963,12 +4022,12 @@@ pub fn instantiate_path(fcx: &FnCtxt
          (tps, regions)
      };
  
+     let substs = substs { regions: regions,
+                           self_ty: None,
+                           tps: tps };
      fcx.write_ty_substs(node_id, tpt.ty, ty::ItemSubsts {
-         substs: substs { regions: regions,
-                          self_ty: None,
-                          tps: tps }
+         substs: substs,
      });
  
      debug!("<<<");
@@@ -4038,8 -3981,7 +4040,8 @@@ pub fn structurally_resolved_type(fcx: 
          Ok(t_s) if !ty::type_is_ty_var(t_s) => t_s,
          _ => {
              fcx.type_error_message(sp, |_actual| {
 -                "the type of this value must be known in this context".to_owned()
 +                "the type of this value must be known in this \
 +                 context".to_strbuf()
              }, tp, None);
              demand::suptype(fcx, sp, ty::mk_err(), tp);
              tp
@@@ -4243,7 -4185,7 +4245,7 @@@ pub fn check_intrinsic_type(ccx: &Crate
              "get_tydesc" => {
                let tydesc_ty = match ty::get_tydesc_ty(ccx.tcx) {
                    Ok(t) => t,
 -                  Err(s) => { tcx.sess.span_fatal(it.span, s); }
 +                  Err(s) => { tcx.sess.span_fatal(it.span, s.as_slice()); }
                };
                let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
                    ty: tydesc_ty,
                                                   tps: Vec::new(),
                                                   regions: ty::NonerasedRegions(OwnedSlice::empty())
                                                   }) ),
 -                    Err(msg) => { tcx.sess.span_fatal(it.span, msg); }
 +                    Err(msg) => {
 +                        tcx.sess.span_fatal(it.span, msg.as_slice());
 +                    }
                  }
              },
              "visit_tydesc" => {
                let tydesc_ty = match ty::get_tydesc_ty(ccx.tcx) {
                    Ok(t) => t,
 -                  Err(s) => { tcx.sess.span_fatal(it.span, s); }
 +                  Err(s) => { tcx.sess.span_fatal(it.span, s.as_slice()); }
                };
                let region = ty::ReLateBound(it.id, ty::BrAnon(0));
                let visitor_object_ty = match ty::visitor_object_ty(tcx, region) {
                    Ok((_, vot)) => vot,
 -                  Err(s) => { tcx.sess.span_fatal(it.span, s); }
 +                  Err(s) => { tcx.sess.span_fatal(it.span, s.as_slice()); }
                };
  
                let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
      let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
          fn_style: ast::UnsafeFn,
          abi: abi::RustIntrinsic,
 -        sig: FnSig {binder_id: it.id,
 -                    inputs: inputs,
 -                    output: output,
 -                    variadic: false}
 +        sig: FnSig {
 +            binder_id: it.id,
 +            inputs: inputs,
 +            output: output,
 +            variadic: false,
 +        }
      });
      let i_ty = ty::lookup_item_type(ccx.tcx, local_def(it.id));
      let i_n_tps = i_ty.generics.type_param_defs().len();
                                           of type parameters: found {}, \
                                           expected {}", i_n_tps, n_tps));
      } else {
 -        require_same_types(
 -            tcx, None, false, it.span, i_ty.ty, fty,
 -            || format!("intrinsic has wrong type: \
 -                      expected `{}`",
 -                     ppaux::ty_to_str(ccx.tcx, fty)));
 +        require_same_types(tcx,
 +                           None,
 +                           false,
 +                           it.span,
 +                           i_ty.ty,
 +                           fty,
 +                           || {
 +                format_strbuf!("intrinsic has wrong type: expected `{}`",
 +                               ppaux::ty_to_str(ccx.tcx, fty))
 +            });
      }
  }