about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2014-12-16 18:38:06 +0200
committerEduard Burtescu <edy.burt@gmail.com>2014-12-20 07:04:42 +0200
commite0d44386d334e13677e2d43ad9365d6b24350780 (patch)
tree0c30cf4850f5965275b812441198b3ca3cd2bb0a
parent1c2df5cc3cfc0c9e80adf9fa6504d55056741c5a (diff)
downloadrust-e0d44386d334e13677e2d43ad9365d6b24350780.tar.gz
rust-e0d44386d334e13677e2d43ad9365d6b24350780.zip
rustc: use Ty instead of passing ty::sty around.
-rw-r--r--src/librustc/metadata/tyencode.rs197
-rw-r--r--src/librustc/middle/infer/coercion.rs110
-rw-r--r--src/librustc/middle/ty_fold.rs112
-rw-r--r--src/librustc_typeck/check/closure.rs75
-rw-r--r--src/librustc_typeck/check/mod.rs51
-rw-r--r--src/librustc_typeck/check/wf.rs6
6 files changed, 259 insertions, 292 deletions
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index 5d7d85d4679..ce63c467822 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -55,7 +55,103 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t
         None => {}
     }
     let pos = w.tell().unwrap();
-    enc_sty(w, cx, &t.sty);
+
+    match t.sty {
+        ty::ty_bool => mywrite!(w, "b"),
+        ty::ty_char => mywrite!(w, "c"),
+        ty::ty_int(t) => {
+            match t {
+                ast::TyI => mywrite!(w, "i"),
+                ast::TyI8 => mywrite!(w, "MB"),
+                ast::TyI16 => mywrite!(w, "MW"),
+                ast::TyI32 => mywrite!(w, "ML"),
+                ast::TyI64 => mywrite!(w, "MD")
+            }
+        }
+        ty::ty_uint(t) => {
+            match t {
+                ast::TyU => mywrite!(w, "u"),
+                ast::TyU8 => mywrite!(w, "Mb"),
+                ast::TyU16 => mywrite!(w, "Mw"),
+                ast::TyU32 => mywrite!(w, "Ml"),
+                ast::TyU64 => mywrite!(w, "Md")
+            }
+        }
+        ty::ty_float(t) => {
+            match t {
+                ast::TyF32 => mywrite!(w, "Mf"),
+                ast::TyF64 => mywrite!(w, "MF"),
+            }
+        }
+        ty::ty_enum(def, ref substs) => {
+            mywrite!(w, "t[{}|", (cx.ds)(def));
+            enc_substs(w, cx, substs);
+            mywrite!(w, "]");
+        }
+        ty::ty_trait(box ty::TyTrait { ref principal,
+                                       ref bounds }) => {
+            mywrite!(w, "x[");
+            enc_trait_ref(w, cx, &principal.0);
+            enc_existential_bounds(w, cx, bounds);
+            mywrite!(w, "]");
+        }
+        ty::ty_tup(ref ts) => {
+            mywrite!(w, "T[");
+            for t in ts.iter() { enc_ty(w, cx, *t); }
+            mywrite!(w, "]");
+        }
+        ty::ty_uniq(typ) => { mywrite!(w, "~"); enc_ty(w, cx, typ); }
+        ty::ty_ptr(mt) => { mywrite!(w, "*"); enc_mt(w, cx, mt); }
+        ty::ty_rptr(r, mt) => {
+            mywrite!(w, "&");
+            enc_region(w, cx, r);
+            enc_mt(w, cx, mt);
+        }
+        ty::ty_vec(t, sz) => {
+            mywrite!(w, "V");
+            enc_ty(w, cx, t);
+            mywrite!(w, "/");
+            match sz {
+                Some(n) => mywrite!(w, "{}|", n),
+                None => mywrite!(w, "|"),
+            }
+        }
+        ty::ty_str => {
+            mywrite!(w, "v");
+        }
+        ty::ty_closure(ref f) => {
+            mywrite!(w, "f");
+            enc_closure_ty(w, cx, &**f);
+        }
+        ty::ty_bare_fn(ref f) => {
+            mywrite!(w, "F");
+            enc_bare_fn_ty(w, cx, f);
+        }
+        ty::ty_infer(_) => {
+            cx.diag.handler().bug("cannot encode inference variable types");
+        }
+        ty::ty_param(ParamTy {space, idx: id, def_id: did}) => {
+            mywrite!(w, "p{}|{}|{}|", (cx.ds)(did), id, space.to_uint())
+        }
+        ty::ty_struct(def, ref substs) => {
+            mywrite!(w, "a[{}|", (cx.ds)(def));
+            enc_substs(w, cx, substs);
+            mywrite!(w, "]");
+        }
+        ty::ty_unboxed_closure(def, region, ref substs) => {
+            mywrite!(w, "k[{}|", (cx.ds)(def));
+            enc_region(w, cx, region);
+            enc_substs(w, cx, substs);
+            mywrite!(w, "]");
+        }
+        ty::ty_err => {
+            mywrite!(w, "e");
+        }
+        ty::ty_open(_) => {
+            cx.diag.handler().bug("unexpected type in enc_sty (ty_open)");
+        }
+    }
+
     let end = w.tell().unwrap();
     let len = end - pos;
     fn estimate_sz(u: u64) -> u64 {
@@ -214,105 +310,6 @@ pub fn enc_trait_store(w: &mut SeekableMemWriter, cx: &ctxt, s: ty::TraitStore)
     }
 }
 
-fn enc_sty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
-                     st: &ty::sty<'tcx>) {
-    match *st {
-        ty::ty_bool => mywrite!(w, "b"),
-        ty::ty_char => mywrite!(w, "c"),
-        ty::ty_int(t) => {
-            match t {
-                ast::TyI => mywrite!(w, "i"),
-                ast::TyI8 => mywrite!(w, "MB"),
-                ast::TyI16 => mywrite!(w, "MW"),
-                ast::TyI32 => mywrite!(w, "ML"),
-                ast::TyI64 => mywrite!(w, "MD")
-            }
-        }
-        ty::ty_uint(t) => {
-            match t {
-                ast::TyU => mywrite!(w, "u"),
-                ast::TyU8 => mywrite!(w, "Mb"),
-                ast::TyU16 => mywrite!(w, "Mw"),
-                ast::TyU32 => mywrite!(w, "Ml"),
-                ast::TyU64 => mywrite!(w, "Md")
-            }
-        }
-        ty::ty_float(t) => {
-            match t {
-                ast::TyF32 => mywrite!(w, "Mf"),
-                ast::TyF64 => mywrite!(w, "MF"),
-            }
-        }
-        ty::ty_enum(def, ref substs) => {
-            mywrite!(w, "t[{}|", (cx.ds)(def));
-            enc_substs(w, cx, substs);
-            mywrite!(w, "]");
-        }
-        ty::ty_trait(box ty::TyTrait { ref principal,
-                                       ref bounds }) => {
-            mywrite!(w, "x[");
-            enc_trait_ref(w, cx, &principal.0);
-            enc_existential_bounds(w, cx, bounds);
-            mywrite!(w, "]");
-        }
-        ty::ty_tup(ref ts) => {
-            mywrite!(w, "T[");
-            for t in ts.iter() { enc_ty(w, cx, *t); }
-            mywrite!(w, "]");
-        }
-        ty::ty_uniq(typ) => { mywrite!(w, "~"); enc_ty(w, cx, typ); }
-        ty::ty_ptr(mt) => { mywrite!(w, "*"); enc_mt(w, cx, mt); }
-        ty::ty_rptr(r, mt) => {
-            mywrite!(w, "&");
-            enc_region(w, cx, r);
-            enc_mt(w, cx, mt);
-        }
-        ty::ty_vec(t, sz) => {
-            mywrite!(w, "V");
-            enc_ty(w, cx, t);
-            mywrite!(w, "/");
-            match sz {
-                Some(n) => mywrite!(w, "{}|", n),
-                None => mywrite!(w, "|"),
-            }
-        }
-        ty::ty_str => {
-            mywrite!(w, "v");
-        }
-        ty::ty_closure(ref f) => {
-            mywrite!(w, "f");
-            enc_closure_ty(w, cx, &**f);
-        }
-        ty::ty_bare_fn(ref f) => {
-            mywrite!(w, "F");
-            enc_bare_fn_ty(w, cx, f);
-        }
-        ty::ty_infer(_) => {
-            cx.diag.handler().bug("cannot encode inference variable types");
-        }
-        ty::ty_param(ParamTy {space, idx: id, def_id: did}) => {
-            mywrite!(w, "p{}|{}|{}|", (cx.ds)(did), id, space.to_uint())
-        }
-        ty::ty_struct(def, ref substs) => {
-            mywrite!(w, "a[{}|", (cx.ds)(def));
-            enc_substs(w, cx, substs);
-            mywrite!(w, "]");
-        }
-        ty::ty_unboxed_closure(def, region, ref substs) => {
-            mywrite!(w, "k[{}|", (cx.ds)(def));
-            enc_region(w, cx, region);
-            enc_substs(w, cx, substs);
-            mywrite!(w, "]");
-        }
-        ty::ty_err => {
-            mywrite!(w, "e");
-        }
-        ty::ty_open(_) => {
-            cx.diag.handler().bug("unexpected type in enc_sty (ty_open)");
-        }
-    }
-}
-
 fn enc_unsafety(w: &mut SeekableMemWriter, p: ast::Unsafety) {
     match p {
         ast::Unsafety::Normal => mywrite!(w, "n"),
diff --git a/src/librustc/middle/infer/coercion.rs b/src/librustc/middle/infer/coercion.rs
index 805d4532aa1..64bfd138802 100644
--- a/src/librustc/middle/infer/coercion.rs
+++ b/src/librustc/middle/infer/coercion.rs
@@ -90,8 +90,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                b.repr(self.get_ref().infcx.tcx));
 
         // Consider coercing the subtype to a DST
-        let unsize = self.unpack_actual_value(a, |sty_a| {
-            self.coerce_unsized(a, sty_a, b)
+        let unsize = self.unpack_actual_value(a, |a| {
+            self.coerce_unsized(a, b)
         });
         if unsize.is_ok() {
             return unsize;
@@ -105,14 +105,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             ty::ty_ptr(mt_b) => {
                 match mt_b.ty.sty {
                     ty::ty_str => {
-                        return self.unpack_actual_value(a, |sty_a| {
-                            self.coerce_unsafe_ptr(a, sty_a, b, ast::MutImmutable)
+                        return self.unpack_actual_value(a, |a| {
+                            self.coerce_unsafe_ptr(a, b, ast::MutImmutable)
                         });
                     }
 
                     ty::ty_trait(..) => {
-                        let result = self.unpack_actual_value(a, |sty_a| {
-                            self.coerce_unsafe_object(a, sty_a, b, mt_b.mutbl)
+                        let result = self.unpack_actual_value(a, |a| {
+                            self.coerce_unsafe_object(a, b, mt_b.mutbl)
                         });
 
                         match result {
@@ -122,8 +122,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                     }
 
                     _ => {
-                        return self.unpack_actual_value(a, |sty_a| {
-                            self.coerce_unsafe_ptr(a, sty_a, b, mt_b.mutbl)
+                        return self.unpack_actual_value(a, |a| {
+                            self.coerce_unsafe_ptr(a, b, mt_b.mutbl)
                         });
                     }
                 };
@@ -132,14 +132,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             ty::ty_rptr(_, mt_b) => {
                 match mt_b.ty.sty {
                     ty::ty_str => {
-                        return self.unpack_actual_value(a, |sty_a| {
-                            self.coerce_borrowed_pointer(a, sty_a, b, ast::MutImmutable)
+                        return self.unpack_actual_value(a, |a| {
+                            self.coerce_borrowed_pointer(a, b, ast::MutImmutable)
                         });
                     }
 
                     ty::ty_trait(..) => {
-                        let result = self.unpack_actual_value(a, |sty_a| {
-                            self.coerce_borrowed_object(a, sty_a, b, mt_b.mutbl)
+                        let result = self.unpack_actual_value(a, |a| {
+                            self.coerce_borrowed_object(a, b, mt_b.mutbl)
                         });
 
                         match result {
@@ -149,8 +149,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                     }
 
                     _ => {
-                        return self.unpack_actual_value(a, |sty_a| {
-                            self.coerce_borrowed_pointer(a, sty_a, b, mt_b.mutbl)
+                        return self.unpack_actual_value(a, |a| {
+                            self.coerce_borrowed_pointer(a, b, mt_b.mutbl)
                         });
                     }
                 };
@@ -160,16 +160,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                     store: ty::RegionTraitStore(..),
                     ..
                 }) => {
-                return self.unpack_actual_value(a, |sty_a| {
-                    self.coerce_borrowed_fn(a, sty_a, b)
+                return self.unpack_actual_value(a, |a| {
+                    self.coerce_borrowed_fn(a, b)
                 });
             }
 
             _ => {}
         }
 
-        self.unpack_actual_value(a, |sty_a| {
-            match *sty_a {
+        self.unpack_actual_value(a, |a| {
+            match a.sty {
                 ty::ty_bare_fn(ref a_f) => {
                     // Bare functions are coercible to any closure type.
                     //
@@ -194,20 +194,19 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
     }
 
     pub fn unpack_actual_value<T, F>(&self, a: Ty<'tcx>, f: F) -> T where
-        F: FnOnce(&ty::sty<'tcx>) -> T,
+        F: FnOnce(Ty<'tcx>) -> T,
     {
-        f(&self.get_ref().infcx.shallow_resolve(a).sty)
+        f(self.get_ref().infcx.shallow_resolve(a))
     }
 
     // ~T -> &T or &mut T -> &T (including where T = [U] or str)
     pub fn coerce_borrowed_pointer(&self,
                                    a: Ty<'tcx>,
-                                   sty_a: &ty::sty<'tcx>,
                                    b: Ty<'tcx>,
                                    mutbl_b: ast::Mutability)
                                    -> CoerceResult<'tcx> {
-        debug!("coerce_borrowed_pointer(a={}, sty_a={}, b={})",
-               a.repr(self.get_ref().infcx.tcx), sty_a,
+        debug!("coerce_borrowed_pointer(a={}, b={})",
+               a.repr(self.get_ref().infcx.tcx),
                b.repr(self.get_ref().infcx.tcx));
 
         // If we have a parameter of type `&M T_a` and the value
@@ -220,7 +219,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         let coercion = Coercion(self.get_ref().trace.clone());
         let r_borrow = self.get_ref().infcx.next_region_var(coercion);
 
-        let inner_ty = match *sty_a {
+        let inner_ty = match a.sty {
             ty::ty_uniq(_) => return Err(ty::terr_mismatch),
             ty::ty_rptr(_, mt_a) => mt_a.ty,
             _ => {
@@ -245,11 +244,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
     // or &Concrete -> &Trait, etc.
     fn coerce_unsized(&self,
                       a: Ty<'tcx>,
-                      sty_a: &ty::sty<'tcx>,
                       b: Ty<'tcx>)
                       -> CoerceResult<'tcx> {
-        debug!("coerce_unsized(a={}, sty_a={}, b={})",
-               a.repr(self.get_ref().infcx.tcx), sty_a,
+        debug!("coerce_unsized(a={}, b={})",
+               a.repr(self.get_ref().infcx.tcx),
                b.repr(self.get_ref().infcx.tcx));
 
         // Note, we want to avoid unnecessary unsizing. We don't want to coerce to
@@ -259,11 +257,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
         let sub = Sub(self.get_ref().clone());
 
-        let sty_b = &b.sty;
-        match (sty_a, sty_b) {
+        match (&a.sty, &b.sty) {
             (&ty::ty_rptr(_, ty::mt{ty: t_a, mutbl: mutbl_a}), &ty::ty_rptr(_, mt_b)) => {
-                self.unpack_actual_value(t_a, |sty_a| {
-                    match self.unsize_ty(t_a, sty_a, mt_b.ty) {
+                self.unpack_actual_value(t_a, |a| {
+                    match self.unsize_ty(t_a, a, mt_b.ty) {
                         Some((ty, kind)) => {
                             if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) {
                                 return Err(ty::terr_mutability);
@@ -288,8 +285,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 })
             }
             (&ty::ty_rptr(_, ty::mt{ty: t_a, mutbl: mutbl_a}), &ty::ty_ptr(mt_b)) => {
-                self.unpack_actual_value(t_a, |sty_a| {
-                    match self.unsize_ty(t_a, sty_a, mt_b.ty) {
+                self.unpack_actual_value(t_a, |a| {
+                    match self.unsize_ty(t_a, a, mt_b.ty) {
                         Some((ty, kind)) => {
                             if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) {
                                 return Err(ty::terr_mutability);
@@ -311,8 +308,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 })
             }
             (&ty::ty_uniq(t_a), &ty::ty_uniq(t_b)) => {
-                self.unpack_actual_value(t_a, |sty_a| {
-                    match self.unsize_ty(t_a, sty_a, t_b) {
+                self.unpack_actual_value(t_a, |a| {
+                    match self.unsize_ty(t_a, a, t_b) {
                         Some((ty, kind)) => {
                             let ty = ty::mk_uniq(self.get_ref().infcx.tcx, ty);
                             try!(self.get_ref().infcx.try(|_| sub.tys(ty, b)));
@@ -336,15 +333,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
     // E.g., `[T, ..n]` -> `([T], UnsizeLength(n))`
     fn unsize_ty(&self,
                  ty_a: Ty<'tcx>,
-                 sty_a: &ty::sty<'tcx>,
+                 a: Ty<'tcx>,
                  ty_b: Ty<'tcx>)
                  -> Option<(Ty<'tcx>, ty::UnsizeKind<'tcx>)> {
-        debug!("unsize_ty(sty_a={}, ty_b={})", sty_a, ty_b.repr(self.get_ref().infcx.tcx));
+        debug!("unsize_ty(a={}, ty_b={})", a, ty_b.repr(self.get_ref().infcx.tcx));
 
         let tcx = self.get_ref().infcx.tcx;
 
-        self.unpack_actual_value(ty_b, |sty_b|
-            match (sty_a, sty_b) {
+        self.unpack_actual_value(ty_b, |b|
+            match (&a.sty, &b.sty) {
                 (&ty::ty_vec(t_a, Some(len)), &ty::ty_vec(_, None)) => {
                     let ty = ty::mk_vec(tcx, t_a, None);
                     Some((ty, ty::UnsizeLength(len)))
@@ -412,44 +409,41 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
     fn coerce_borrowed_object(&self,
                               a: Ty<'tcx>,
-                              sty_a: &ty::sty<'tcx>,
                               b: Ty<'tcx>,
                               b_mutbl: ast::Mutability) -> CoerceResult<'tcx>
     {
         let tcx = self.get_ref().infcx.tcx;
 
-        debug!("coerce_borrowed_object(a={}, sty_a={}, b={}, b_mutbl={})",
-               a.repr(tcx), sty_a,
+        debug!("coerce_borrowed_object(a={}, b={}, b_mutbl={})",
+               a.repr(tcx),
                b.repr(tcx), b_mutbl);
 
         let coercion = Coercion(self.get_ref().trace.clone());
         let r_a = self.get_ref().infcx.next_region_var(coercion);
 
-        self.coerce_object(a, sty_a, b, b_mutbl,
+        self.coerce_object(a, b, b_mutbl,
                            |tr| ty::mk_rptr(tcx, r_a, ty::mt{ mutbl: b_mutbl, ty: tr }),
                            || AutoPtr(r_a, b_mutbl, None))
     }
 
     fn coerce_unsafe_object(&self,
                             a: Ty<'tcx>,
-                            sty_a: &ty::sty<'tcx>,
                             b: Ty<'tcx>,
                             b_mutbl: ast::Mutability) -> CoerceResult<'tcx>
     {
         let tcx = self.get_ref().infcx.tcx;
 
-        debug!("coerce_unsafe_object(a={}, sty_a={}, b={}, b_mutbl={})",
-               a.repr(tcx), sty_a,
+        debug!("coerce_unsafe_object(a={}, b={}, b_mutbl={})",
+               a.repr(tcx),
                b.repr(tcx), b_mutbl);
 
-        self.coerce_object(a, sty_a, b, b_mutbl,
+        self.coerce_object(a, b, b_mutbl,
                            |tr| ty::mk_ptr(tcx, ty::mt{ mutbl: b_mutbl, ty: tr }),
                            || AutoUnsafe(b_mutbl, None))
     }
 
     fn coerce_object<F, G>(&self,
                            a: Ty<'tcx>,
-                           sty_a: &ty::sty<'tcx>,
                            b: Ty<'tcx>,
                            b_mutbl: ast::Mutability,
                            mk_ty: F,
@@ -459,7 +453,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
     {
         let tcx = self.get_ref().infcx.tcx;
 
-        match *sty_a {
+        match a.sty {
             ty::ty_rptr(_, ty::mt{ty, mutbl}) => match ty.sty {
                 ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
                     debug!("mutbl={} b_mutbl={}", mutbl, b_mutbl);
@@ -483,14 +477,13 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
     pub fn coerce_borrowed_fn(&self,
                               a: Ty<'tcx>,
-                              sty_a: &ty::sty<'tcx>,
                               b: Ty<'tcx>)
                               -> CoerceResult<'tcx> {
-        debug!("coerce_borrowed_fn(a={}, sty_a={}, b={})",
-               a.repr(self.get_ref().infcx.tcx), sty_a,
+        debug!("coerce_borrowed_fn(a={}, b={})",
+               a.repr(self.get_ref().infcx.tcx),
                b.repr(self.get_ref().infcx.tcx));
 
-        match *sty_a {
+        match a.sty {
             ty::ty_bare_fn(ref f) => {
                 self.coerce_from_bare_fn(a, f, b)
             }
@@ -504,7 +497,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
     ///  `proc`.
     fn coerce_from_bare_fn(&self, a: Ty<'tcx>, fn_ty_a: &ty::BareFnTy<'tcx>, b: Ty<'tcx>)
                            -> CoerceResult<'tcx> {
-        self.unpack_actual_value(b, |sty_b| {
+        self.unpack_actual_value(b, |b| {
 
             debug!("coerce_from_bare_fn(a={}, b={})",
                    a.repr(self.get_ref().infcx.tcx), b.repr(self.get_ref().infcx.tcx));
@@ -513,7 +506,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 return self.subtype(a, b);
             }
 
-            let fn_ty_b = match *sty_b {
+            let fn_ty_b = match b.sty {
                 ty::ty_closure(ref f) => (*f).clone(),
                 _ => return self.subtype(a, b)
             };
@@ -531,15 +524,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
     pub fn coerce_unsafe_ptr(&self,
                              a: Ty<'tcx>,
-                             sty_a: &ty::sty<'tcx>,
                              b: Ty<'tcx>,
                              mutbl_b: ast::Mutability)
                              -> CoerceResult<'tcx> {
-        debug!("coerce_unsafe_ptr(a={}, sty_a={}, b={})",
-               a.repr(self.get_ref().infcx.tcx), sty_a,
+        debug!("coerce_unsafe_ptr(a={}, b={})",
+               a.repr(self.get_ref().infcx.tcx),
                b.repr(self.get_ref().infcx.tcx));
 
-        let mt_a = match *sty_a {
+        let mt_a = match a.sty {
             ty::ty_rptr(_, mt) | ty::ty_ptr(mt) => mt,
             _ => {
                 return self.subtype(a, b);
diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs
index 71e42a9dbb3..d69ae96d07e 100644
--- a/src/librustc/middle/ty_fold.rs
+++ b/src/librustc/middle/ty_fold.rs
@@ -82,10 +82,6 @@ pub trait TypeFolder<'tcx> {
         super_fold_trait_ref(self, t)
     }
 
-    fn fold_sty(&mut self, sty: &ty::sty<'tcx>) -> ty::sty<'tcx> {
-        super_fold_sty(self, sty)
-    }
-
     fn fold_substs(&mut self,
                    substs: &subst::Substs<'tcx>)
                    -> subst::Substs<'tcx> {
@@ -260,12 +256,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for ty::sty<'tcx> {
-    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::sty<'tcx> {
-        folder.fold_sty(self)
-    }
-}
-
 impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> {
     fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::TraitRef<'tcx> {
         folder.fold_trait_ref(self)
@@ -521,9 +511,55 @@ impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U>
 // They should invoke `foo.fold_with()` to do recursive folding.
 
 pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
-                                                t: Ty<'tcx>)
+                                                ty: Ty<'tcx>)
                                                 -> Ty<'tcx> {
-    let sty = t.sty.fold_with(this);
+    let sty = match ty.sty {
+        ty::ty_uniq(typ) => {
+            ty::ty_uniq(typ.fold_with(this))
+        }
+        ty::ty_ptr(ref tm) => {
+            ty::ty_ptr(tm.fold_with(this))
+        }
+        ty::ty_vec(typ, sz) => {
+            ty::ty_vec(typ.fold_with(this), sz)
+        }
+        ty::ty_open(typ) => {
+            ty::ty_open(typ.fold_with(this))
+        }
+        ty::ty_enum(tid, ref substs) => {
+            ty::ty_enum(tid, substs.fold_with(this))
+        }
+        ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
+            ty::ty_trait(box ty::TyTrait {
+                principal: (*principal).fold_with(this),
+                bounds: bounds.fold_with(this),
+            })
+        }
+        ty::ty_tup(ref ts) => {
+            ty::ty_tup(ts.fold_with(this))
+        }
+        ty::ty_bare_fn(ref f) => {
+            ty::ty_bare_fn(f.fold_with(this))
+        }
+        ty::ty_closure(ref f) => {
+            ty::ty_closure(box f.fold_with(this))
+        }
+        ty::ty_rptr(r, ref tm) => {
+            ty::ty_rptr(r.fold_with(this), tm.fold_with(this))
+        }
+        ty::ty_struct(did, ref substs) => {
+            ty::ty_struct(did, substs.fold_with(this))
+        }
+        ty::ty_unboxed_closure(did, ref region, ref substs) => {
+            ty::ty_unboxed_closure(did, region.fold_with(this), substs.fold_with(this))
+        }
+        ty::ty_bool | ty::ty_char | ty::ty_str |
+        ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) |
+        ty::ty_err | ty::ty_infer(_) |
+        ty::ty_param(..) => {
+            ty.sty.clone()
+        }
+    };
     ty::mk_t(this.tcx(), sty)
 }
 
@@ -601,58 +637,6 @@ pub fn super_fold_mt<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
             mutbl: mt.mutbl}
 }
 
-pub fn super_fold_sty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
-                                                 sty: &ty::sty<'tcx>)
-                                                 -> ty::sty<'tcx> {
-    match *sty {
-        ty::ty_uniq(typ) => {
-            ty::ty_uniq(typ.fold_with(this))
-        }
-        ty::ty_ptr(ref tm) => {
-            ty::ty_ptr(tm.fold_with(this))
-        }
-        ty::ty_vec(typ, sz) => {
-            ty::ty_vec(typ.fold_with(this), sz)
-        }
-        ty::ty_open(typ) => {
-            ty::ty_open(typ.fold_with(this))
-        }
-        ty::ty_enum(tid, ref substs) => {
-            ty::ty_enum(tid, substs.fold_with(this))
-        }
-        ty::ty_trait(box ty::TyTrait { ref principal, bounds }) => {
-            ty::ty_trait(box ty::TyTrait {
-                principal: (*principal).fold_with(this),
-                bounds: bounds.fold_with(this),
-            })
-        }
-        ty::ty_tup(ref ts) => {
-            ty::ty_tup(ts.fold_with(this))
-        }
-        ty::ty_bare_fn(ref f) => {
-            ty::ty_bare_fn(f.fold_with(this))
-        }
-        ty::ty_closure(ref f) => {
-            ty::ty_closure(box f.fold_with(this))
-        }
-        ty::ty_rptr(r, ref tm) => {
-            ty::ty_rptr(r.fold_with(this), tm.fold_with(this))
-        }
-        ty::ty_struct(did, ref substs) => {
-            ty::ty_struct(did, substs.fold_with(this))
-        }
-        ty::ty_unboxed_closure(did, ref region, ref substs) => {
-            ty::ty_unboxed_closure(did, region.fold_with(this), substs.fold_with(this))
-        }
-        ty::ty_bool | ty::ty_char | ty::ty_str |
-        ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) |
-        ty::ty_err | ty::ty_infer(_) |
-        ty::ty_param(..) => {
-            (*sty).clone()
-        }
-    }
-}
-
 pub fn super_fold_trait_store<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
                                                          trait_store: ty::TraitStore)
                                                          -> ty::TraitStore {
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 2ade3040d6c..09226052367 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -261,44 +261,43 @@ fn check_boxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
     // Find the expected input/output types (if any). Substitute
     // fresh bound regions for any bound regions we find in the
     // expected types so as to avoid capture.
-    let expected_sty = expected.map_to_option(fcx, |x| Some((*x).clone()));
-    let (expected_sig,
-         expected_onceness,
-         expected_bounds) = {
-        match expected_sty {
-            Some(ty::ty_closure(ref cenv)) => {
-                let (sig, _) =
-                    ty::replace_late_bound_regions(
-                        tcx,
-                        &cenv.sig,
-                        |_, debruijn| fcx.inh.infcx.fresh_bound_region(debruijn));
-                let onceness = match (&store, &cenv.store) {
-                    // As the closure type and onceness go, only three
-                    // combinations are legit:
-                    //      once closure
-                    //      many closure
-                    //      once proc
-                    // If the actual and expected closure type disagree with
-                    // each other, set expected onceness to be always Once or
-                    // Many according to the actual type. Otherwise, it will
-                    // yield either an illegal "many proc" or a less known
-                    // "once closure" in the error message.
-                    (&ty::UniqTraitStore, &ty::UniqTraitStore) |
-                    (&ty::RegionTraitStore(..), &ty::RegionTraitStore(..)) =>
-                        cenv.onceness,
-                    (&ty::UniqTraitStore, _) => ast::Once,
-                    (&ty::RegionTraitStore(..), _) => ast::Many,
-                };
-                (Some(sig), onceness, cenv.bounds)
-            }
-            _ => {
-                // Not an error! Means we're inferring the closure type
-                let region = fcx.infcx().next_region_var(
-                    infer::AddrOfRegion(expr.span));
-                let bounds = ty::region_existential_bound(region);
-                let onceness = ast::Many;
-                (None, onceness, bounds)
-            }
+    let expected_cenv = expected.map_to_option(fcx, |ty| match ty.sty {
+        ty::ty_closure(ref cenv) => Some(cenv),
+        _ => None
+    });
+    let (expected_sig, expected_onceness, expected_bounds) = match expected_cenv {
+        Some(cenv) => {
+            let (sig, _) =
+                ty::replace_late_bound_regions(
+                    tcx,
+                    &cenv.sig,
+                    |_, debruijn| fcx.inh.infcx.fresh_bound_region(debruijn));
+            let onceness = match (&store, &cenv.store) {
+                // As the closure type and onceness go, only three
+                // combinations are legit:
+                //      once closure
+                //      many closure
+                //      once proc
+                // If the actual and expected closure type disagree with
+                // each other, set expected onceness to be always Once or
+                // Many according to the actual type. Otherwise, it will
+                // yield either an illegal "many proc" or a less known
+                // "once closure" in the error message.
+                (&ty::UniqTraitStore, &ty::UniqTraitStore) |
+                (&ty::RegionTraitStore(..), &ty::RegionTraitStore(..)) =>
+                    cenv.onceness,
+                (&ty::UniqTraitStore, _) => ast::Once,
+                (&ty::RegionTraitStore(..), _) => ast::Many,
+            };
+            (Some(sig), onceness, cenv.bounds)
+        }
+        _ => {
+            // Not an error! Means we're inferring the closure type
+            let region = fcx.infcx().next_region_var(
+                infer::AddrOfRegion(expr.span));
+            let bounds = ty::region_existential_bound(region);
+            let onceness = ast::Many;
+            (None, onceness, bounds)
         }
     };
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index bbc33826f35..1e624dfaaa4 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2042,7 +2042,7 @@ fn try_overloaded_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                  -> bool {
     // Bail out if the callee is a bare function or a closure. We check those
     // manually.
-    match *structure_of(fcx, callee.span, callee_type) {
+    match structurally_resolved_type(fcx, callee.span, callee_type).sty {
         ty::ty_bare_fn(_) | ty::ty_closure(_) => return false,
         _ => {}
     }
@@ -2717,10 +2717,9 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         ast::LitInt(_, ast::SignedIntLit(t, _)) => ty::mk_mach_int(t),
         ast::LitInt(_, ast::UnsignedIntLit(t)) => ty::mk_mach_uint(t),
         ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
-            let opt_ty = expected.map_to_option(fcx, |sty| {
-                match *sty {
-                    ty::ty_int(i) => Some(ty::mk_mach_int(i)),
-                    ty::ty_uint(i) => Some(ty::mk_mach_uint(i)),
+            let opt_ty = expected.map_to_option(fcx, |ty| {
+                match ty.sty {
+                    ty::ty_int(_) | ty::ty_uint(_) => Some(ty),
                     ty::ty_char => Some(ty::mk_mach_uint(ast::TyU8)),
                     ty::ty_ptr(..) => Some(ty::mk_mach_uint(ast::TyU)),
                     ty::ty_bare_fn(..) => Some(ty::mk_mach_uint(ast::TyU)),
@@ -2732,9 +2731,9 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         }
         ast::LitFloat(_, t) => ty::mk_mach_float(t),
         ast::LitFloatUnsuffixed(_) => {
-            let opt_ty = expected.map_to_option(fcx, |sty| {
-                match *sty {
-                    ty::ty_float(i) => Some(ty::mk_mach_float(i)),
+            let opt_ty = expected.map_to_option(fcx, |ty| {
+                match ty.sty {
+                    ty::ty_float(_) => Some(ty),
                     _ => None
                 }
             });
@@ -2910,7 +2909,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
         let fn_ty = fcx.expr_ty(f);
 
         // Extract the function signature from `in_fty`.
-        let fn_sty = structure_of(fcx, f.span, fn_ty);
+        let fn_ty = structurally_resolved_type(fcx, f.span, fn_ty);
 
         // This is the "default" function signature, used in case of error.
         // In that case, we check each argument against "error" in order to
@@ -2921,7 +2920,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
             variadic: false
         });
 
-        let fn_sig = match *fn_sty {
+        let fn_sig = match fn_ty.sty {
             ty::ty_bare_fn(ty::BareFnTy {ref sig, ..}) |
             ty::ty_closure(box ty::ClosureTy {ref sig, ..}) => sig,
             _ => {
@@ -3655,9 +3654,9 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
         }
       }
       ast::ExprUnary(unop, ref oprnd) => {
-        let expected_inner = expected.map(fcx, |sty| {
+        let expected_inner = expected.map(fcx, |ty| {
             match unop {
-                ast::UnUniq => match *sty {
+                ast::UnUniq => match ty.sty {
                     ty::ty_uniq(ty) => {
                         ExpectHasType(ty)
                     }
@@ -3746,9 +3745,11 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
       }
       ast::ExprAddrOf(mutbl, ref oprnd) => {
         let expected = expected.only_has_type();
-        let hint = expected.map(fcx, |sty| {
-            match *sty { ty::ty_rptr(_, ref mt) | ty::ty_ptr(ref mt) => ExpectHasType(mt.ty),
-                         _ => NoExpectation }
+        let hint = expected.map(fcx, |ty| {
+            match ty.sty {
+                ty::ty_rptr(_, ref mt) | ty::ty_ptr(ref mt) => ExpectHasType(mt.ty),
+                _ => NoExpectation
+            }
         });
         let lvalue_pref = match mutbl {
             ast::MutMutable => PreferMutLvalue,
@@ -4037,9 +4038,9 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
       }
       ast::ExprTup(ref elts) => {
         let expected = expected.only_has_type();
-        let flds = expected.map_to_option(fcx, |sty| {
-            match *sty {
-                ty::ty_tup(ref flds) => Some((*flds).clone()),
+        let flds = expected.map_to_option(fcx, |ty| {
+            match ty.sty {
+                ty::ty_tup(ref flds) => Some(flds[]),
                 _ => None
             }
         });
@@ -4304,20 +4305,20 @@ impl<'tcx> Expectation<'tcx> {
     }
 
     fn map<'a, F>(self, fcx: &FnCtxt<'a, 'tcx>, unpack: F) -> Expectation<'tcx> where
-        F: FnOnce(&ty::sty<'tcx>) -> Expectation<'tcx>
+        F: FnOnce(Ty<'tcx>) -> Expectation<'tcx>
     {
         match self.resolve(fcx) {
             NoExpectation => NoExpectation,
-            ExpectCastableToType(t) | ExpectHasType(t) => unpack(&t.sty),
+            ExpectCastableToType(ty) | ExpectHasType(ty) => unpack(ty),
         }
     }
 
     fn map_to_option<'a, O, F>(self, fcx: &FnCtxt<'a, 'tcx>, unpack: F) -> Option<O> where
-        F: FnOnce(&ty::sty<'tcx>) -> Option<O>,
+        F: FnOnce(Ty<'tcx>) -> Option<O>,
     {
         match self.resolve(fcx) {
             NoExpectation => None,
-            ExpectCastableToType(t) | ExpectHasType(t) => unpack(&t.sty),
+            ExpectCastableToType(ty) | ExpectHasType(ty) => unpack(ty),
         }
     }
 }
@@ -5320,12 +5321,6 @@ pub fn structurally_resolved_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
     ty
 }
 
-// Returns the one-level-deep structure of the given type.
-pub fn structure_of<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, typ: Ty<'tcx>)
-                        -> &'tcx ty::sty<'tcx> {
-    &structurally_resolved_type(fcx, sp, typ).sty
-}
-
 // Returns true if b contains a break that can exit from b
 pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool {
     // First: is there an unlabeled break immediately
diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs
index c09ce3db6dd..24d7bf5031e 100644
--- a/src/librustc_typeck/check/wf.rs
+++ b/src/librustc_typeck/check/wf.rs
@@ -17,7 +17,7 @@ use middle::subst::{Subst};
 use middle::traits;
 use middle::ty::{mod, Ty};
 use middle::ty::liberate_late_bound_regions;
-use middle::ty_fold::{TypeFolder, TypeFoldable};
+use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty};
 use util::ppaux::Repr;
 
 use std::collections::HashSet;
@@ -368,8 +368,8 @@ impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> {
 
                 self.binding_count -= 1;
             }
-            ref sty => {
-                self.fold_sty(sty);
+            _ => {
+                super_fold_ty(self, t);
             }
         }