about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLindsey Kuper <lindsey@composition.al>2013-08-21 03:10:16 -0400
committerLindsey Kuper <lindsey@composition.al>2013-08-21 13:33:30 -0400
commit3613c22c8cb9ee37955352c1fde79457c0a211f6 (patch)
treebfe5eb1d24c0fb88e155a5636743c16a8c885ac8
parentbf90634087e8f4015176d8e6be53794768d5c6ec (diff)
downloadrust-3613c22c8cb9ee37955352c1fde79457c0a211f6.tar.gz
rust-3613c22c8cb9ee37955352c1fde79457c0a211f6.zip
Refactor type combining to use default methods. Woohoo!
This commit removes the "super_*" functions from
typeck::infer::combine, and adds them as default methods on the
Combine trait instead, making it possible to remove a lot of
boilerplate from the various impls of Combine.

I've been wanting to do this for over a year.  In fact, it was my
original motivation for default methods!

It might be possible to tighten things up even more, but this is the
bulk of it.
-rw-r--r--src/librustc/middle/typeck/infer/combine.rs528
-rw-r--r--src/librustc/middle/typeck/infer/glb.rs63
-rw-r--r--src/librustc/middle/typeck/infer/lub.rs64
-rw-r--r--src/librustc/middle/typeck/infer/sub.rs62
4 files changed, 250 insertions, 467 deletions
diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs
index 161d96d828b..2dd7a4e88b1 100644
--- a/src/librustc/middle/typeck/infer/combine.rs
+++ b/src/librustc/middle/typeck/infer/combine.rs
@@ -12,20 +12,12 @@
 // Type combining
 //
 // There are three type combiners: sub, lub, and glb.  Each implements
-// the trait `combine` and contains methods for combining two
+// the trait `Combine` and contains methods for combining two
 // instances of various things and yielding a new instance.  These
 // combiner methods always yield a `result<T>`---failure is propagated
-// upward using `chain()` methods.
-//
-// There is a lot of common code for these operations, which is
-// abstracted out into functions named `super_X()` which take a combiner
-// instance as the first parameter.  This would be better implemented
-// using traits.  For this system to work properly, you should not
-// call the `super_X(foo, ...)` functions directly, but rather call
-// `foo.X(...)`.  The implementation of `X()` can then choose to delegate
-// to the `super` routine or to do other things.
-// (FIXME (#2794): revise this paragraph once default methods in traits
-// are working.)
+// upward using `chain()` methods.  There is a lot of common code for
+// these operations, implemented as default methods on the `Combine`
+// trait.
 //
 // In reality, the sub operation is rather different from lub/glb, but
 // they are combined into one trait to avoid duplication (they used to
@@ -88,34 +80,264 @@ pub trait Combine {
     fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt>;
     fn contratys(&self, a: ty::t, b: ty::t) -> cres<ty::t>;
     fn tys(&self, a: ty::t, b: ty::t) -> cres<ty::t>;
-    fn tps(&self, as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]>;
+
+    fn tps(&self, as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> {
+
+        // Note: type parameters are always treated as *invariant*
+        // (otherwise the type system would be unsound).  In the
+        // future we could allow type parameters to declare a
+        // variance.
+
+        if vec::same_length(as_, bs) {
+            result::fold_(as_.iter().zip(bs.iter())
+                          .map(|(a, b)| eq_tys(self, *a, *b)))
+                .then(|| Ok(as_.to_owned()))
+        } else {
+            Err(ty::terr_ty_param_size(expected_found(self,
+                                                      as_.len(),
+                                                      bs.len())))
+        }
+    }
+
     fn self_tys(&self, a: Option<ty::t>, b: Option<ty::t>)
-               -> cres<Option<ty::t>>;
+               -> cres<Option<ty::t>> {
+
+        match (a, b) {
+            (None, None) => {
+                Ok(None)
+            }
+            (Some(a), Some(b)) => {
+                // FIXME(#5781) this should be eq_tys
+                // eq_tys(self, a, b).then(|| Ok(Some(a)) )
+                self.contratys(a, b).chain(|t| Ok(Some(t)))
+            }
+            (None, Some(_)) |
+                (Some(_), None) => {
+                // I think it should never happen that we unify two
+                // substs and one of them has a self_ty and one
+                // doesn't...? I could be wrong about this.
+                self.infcx().tcx.sess.bug(
+                                          fmt!("substitution a had a self_ty \
+                                               and substitution b didn't, \
+                                               or vice versa"));
+            }
+        }
+    }
+
     fn substs(&self, generics: &ty::Generics, as_: &ty::substs,
-              bs: &ty::substs) -> cres<ty::substs>;
+              bs: &ty::substs) -> cres<ty::substs> {
+
+        fn relate_region_params<C:Combine>(
+                                           this: &C,
+                                           generics: &ty::Generics,
+                                           a: &ty::RegionSubsts,
+                                           b: &ty::RegionSubsts)
+            -> cres<ty::RegionSubsts>
+            {
+            match (a, b) {
+                (&ty::ErasedRegions, _) |
+                    (_, &ty::ErasedRegions) => {
+                    Ok(ty::ErasedRegions)
+                }
+
+                (&ty::NonerasedRegions(ref a_rs),
+                 &ty::NonerasedRegions(ref b_rs)) => {
+                    match generics.region_param {
+                        None => {
+                            assert!(a_rs.is_empty());
+                            assert!(b_rs.is_empty());
+                            Ok(ty::NonerasedRegions(opt_vec::Empty))
+                        }
+
+                        Some(variance) => {
+                            assert_eq!(a_rs.len(), 1);
+                            assert_eq!(b_rs.len(), 1);
+                            let a_r = *a_rs.get(0);
+                            let b_r = *b_rs.get(0);
+
+                            match variance {
+                                ty::rv_invariant => {
+                                    do eq_regions(this, a_r, b_r).then {
+                                        Ok(ty::NonerasedRegions(opt_vec::with(a_r)))
+                                    }
+                                }
+
+                                ty::rv_covariant => {
+                                    do this.regions(a_r, b_r).chain |r| {
+                                        Ok(ty::NonerasedRegions(opt_vec::with(r)))
+                                    }
+                                }
+
+                                ty::rv_contravariant => {
+                                    do this.contraregions(a_r, b_r).chain |r| {
+                                        Ok(ty::NonerasedRegions(opt_vec::with(r)))
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        do self.tps(as_.tps, bs.tps).chain |tps| {
+            do self.self_tys(as_.self_ty, bs.self_ty).chain |self_ty| {
+                do relate_region_params(self,
+                                        generics,
+                                        &as_.regions,
+                                        &bs.regions).chain |regions| {
+                    Ok(substs {
+                            regions: regions,
+                            self_ty: self_ty,
+                            tps: tps.clone()
+                        })
+                }
+            }
+        }
+    }
+
     fn bare_fn_tys(&self, a: &ty::BareFnTy,
-                   b: &ty::BareFnTy) -> cres<ty::BareFnTy>;
+                   b: &ty::BareFnTy) -> cres<ty::BareFnTy> {
+        let purity = if_ok!(self.purities(a.purity, b.purity));
+        let abi = if_ok!(self.abis(a.abis, b.abis));
+        let sig = if_ok!(self.fn_sigs(&a.sig, &b.sig));
+        Ok(ty::BareFnTy {purity: purity,
+                abis: abi,
+                sig: sig})
+    }
+
     fn closure_tys(&self, a: &ty::ClosureTy,
-                   b: &ty::ClosureTy) -> cres<ty::ClosureTy>;
+                   b: &ty::ClosureTy) -> cres<ty::ClosureTy> {
+
+        let p = if_ok!(self.sigils(a.sigil, b.sigil));
+        let r = if_ok!(self.contraregions(a.region, b.region));
+        let purity = if_ok!(self.purities(a.purity, b.purity));
+        let onceness = if_ok!(self.oncenesses(a.onceness, b.onceness));
+        let bounds = if_ok!(self.bounds(a.bounds, b.bounds));
+        let sig = if_ok!(self.fn_sigs(&a.sig, &b.sig));
+        Ok(ty::ClosureTy {purity: purity,
+                sigil: p,
+                onceness: onceness,
+                region: r,
+                bounds: bounds,
+                sig: sig})
+    }
+
     fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig>;
-    fn flds(&self, a: ty::field, b: ty::field) -> cres<ty::field>;
-    fn args(&self, a: ty::t, b: ty::t) -> cres<ty::t>;
-    fn sigils(&self, p1: ast::Sigil, p2: ast::Sigil) -> cres<ast::Sigil>;
+
+    fn flds(&self, a: ty::field, b: ty::field) -> cres<ty::field> {
+        if a.ident == b.ident {
+            self.mts(&a.mt, &b.mt)
+                .chain(|mt| Ok(ty::field {ident: a.ident, mt: mt}) )
+                .chain_err(|e| Err(ty::terr_in_field(@e, a.ident)) )
+        } else {
+            Err(ty::terr_record_fields(
+                                       expected_found(self,
+                                                      a.ident,
+                                                      b.ident)))
+        }
+    }
+
+    fn args(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
+        do self.contratys(a, b).chain |t| {
+            Ok(t)
+        }
+    }
+
+    fn sigils(&self, p1: ast::Sigil, p2: ast::Sigil) -> cres<ast::Sigil> {
+        if p1 == p2 {
+            Ok(p1)
+        } else {
+            Err(ty::terr_sigil_mismatch(expected_found(self, p1, p2)))
+        }
+    }
+
     fn purities(&self, a: purity, b: purity) -> cres<purity>;
-    fn abis(&self, a: AbiSet, b: AbiSet) -> cres<AbiSet>;
+
+    fn abis(&self, a: AbiSet, b: AbiSet) -> cres<AbiSet> {
+        if a == b {
+            Ok(a)
+        } else {
+            Err(ty::terr_abi_mismatch(expected_found(self, a, b)))
+        }
+    }
+
     fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<Onceness>;
     fn bounds(&self, a: BuiltinBounds, b: BuiltinBounds) -> cres<BuiltinBounds>;
     fn contraregions(&self, a: ty::Region, b: ty::Region)
                   -> cres<ty::Region>;
     fn regions(&self, a: ty::Region, b: ty::Region) -> cres<ty::Region>;
+
     fn vstores(&self, vk: ty::terr_vstore_kind,
-               a: ty::vstore, b: ty::vstore) -> cres<ty::vstore>;
+               a: ty::vstore, b: ty::vstore) -> cres<ty::vstore> {
+
+        debug!("%s.vstores(a=%?, b=%?)", self.tag(), a, b);
+
+        match (a, b) {
+            (ty::vstore_slice(a_r), ty::vstore_slice(b_r)) => {
+                do self.contraregions(a_r, b_r).chain |r| {
+                    Ok(ty::vstore_slice(r))
+                }
+            }
+
+            _ if a == b => {
+                Ok(a)
+            }
+
+            _ => {
+                Err(ty::terr_vstores_differ(vk, expected_found(self, a, b)))
+            }
+        }
+    }
+
     fn trait_stores(&self,
                     vk: ty::terr_vstore_kind,
                     a: ty::TraitStore,
                     b: ty::TraitStore)
-                 -> cres<ty::TraitStore>;
-    fn trait_refs(&self, a: &ty::TraitRef, b: &ty::TraitRef) -> cres<ty::TraitRef>;
+                 -> cres<ty::TraitStore> {
+
+        debug!("%s.trait_stores(a=%?, b=%?)", self.tag(), a, b);
+
+        match (a, b) {
+            (ty::RegionTraitStore(a_r), ty::RegionTraitStore(b_r)) => {
+                do self.contraregions(a_r, b_r).chain |r| {
+                    Ok(ty::RegionTraitStore(r))
+                }
+            }
+
+            _ if a == b => {
+                Ok(a)
+            }
+
+            _ => {
+                Err(ty::terr_trait_stores_differ(vk, expected_found(self, a, b)))
+            }
+        }
+
+    }
+
+    fn trait_refs(&self,
+                  a: &ty::TraitRef,
+                  b: &ty::TraitRef) -> cres<ty::TraitRef> {
+        // Different traits cannot be related
+
+        // - NOTE in the future, expand out subtraits!
+
+        if a.def_id != b.def_id {
+            Err(ty::terr_traits(
+                                expected_found(self, a.def_id, b.def_id)))
+        } else {
+            let tcx = self.infcx().tcx;
+            let trait_def = ty::lookup_trait_def(tcx, a.def_id);
+            let substs = if_ok!(self.substs(&trait_def.generics,
+                                            &a.substs,
+                                            &b.substs));
+            Ok(ty::TraitRef {
+                    def_id: a.def_id,
+                    substs: substs
+                })
+        }
+    }
 }
 
 pub struct CombineFields {
@@ -193,238 +415,9 @@ pub fn eq_opt_regions<C:Combine>(
     }
 }
 
-pub fn super_substs<C:Combine>(
-    this: &C, generics: &ty::Generics,
-    a: &ty::substs, b: &ty::substs) -> cres<ty::substs> {
-
-    fn relate_region_params<C:Combine>(
-        this: &C,
-        generics: &ty::Generics,
-        a: &ty::RegionSubsts,
-        b: &ty::RegionSubsts)
-        -> cres<ty::RegionSubsts>
-    {
-        match (a, b) {
-            (&ty::ErasedRegions, _) |
-            (_, &ty::ErasedRegions) => {
-                Ok(ty::ErasedRegions)
-            }
-
-            (&ty::NonerasedRegions(ref a_rs),
-             &ty::NonerasedRegions(ref b_rs)) => {
-                match generics.region_param {
-                    None => {
-                        assert!(a_rs.is_empty());
-                        assert!(b_rs.is_empty());
-                        Ok(ty::NonerasedRegions(opt_vec::Empty))
-                    }
-
-                    Some(variance) => {
-                        assert_eq!(a_rs.len(), 1);
-                        assert_eq!(b_rs.len(), 1);
-                        let a_r = *a_rs.get(0);
-                        let b_r = *b_rs.get(0);
-
-                        match variance {
-                            ty::rv_invariant => {
-                                do eq_regions(this, a_r, b_r).then {
-                                    Ok(ty::NonerasedRegions(opt_vec::with(a_r)))
-                                }
-                            }
-
-                            ty::rv_covariant => {
-                                do this.regions(a_r, b_r).chain |r| {
-                                    Ok(ty::NonerasedRegions(opt_vec::with(r)))
-                                }
-                            }
-
-                            ty::rv_contravariant => {
-                                do this.contraregions(a_r, b_r).chain |r| {
-                                    Ok(ty::NonerasedRegions(opt_vec::with(r)))
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    do this.tps(a.tps, b.tps).chain |tps| {
-        do this.self_tys(a.self_ty, b.self_ty).chain |self_ty| {
-            do relate_region_params(this,
-                                    generics,
-                                    &a.regions,
-                                    &b.regions).chain |regions| {
-                Ok(substs {
-                    regions: regions,
-                    self_ty: self_ty,
-                    tps: tps.clone()
-                })
-            }
-        }
-    }
-}
-
-pub fn super_tps<C:Combine>(
-    this: &C, as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> {
-
-    // Note: type parameters are always treated as *invariant*
-    // (otherwise the type system would be unsound).  In the
-    // future we could allow type parameters to declare a
-    // variance.
-
-    if vec::same_length(as_, bs) {
-        result::fold_(as_.iter().zip(bs.iter())
-                      .map(|(a, b)| eq_tys(this, *a, *b)))
-            .then(|| Ok(as_.to_owned()))
-    } else {
-        Err(ty::terr_ty_param_size(
-            expected_found(this, as_.len(), bs.len())))
-    }
-}
-
-pub fn super_self_tys<C:Combine>(
-    this: &C, a: Option<ty::t>, b: Option<ty::t>) -> cres<Option<ty::t>> {
-
-    match (a, b) {
-      (None, None) => {
-        Ok(None)
-      }
-      (Some(a), Some(b)) => {
-          // FIXME(#5781) this should be eq_tys
-          // eq_tys(this, a, b).then(|| Ok(Some(a)) )
-          this.contratys(a, b).chain(|t| Ok(Some(t)))
-      }
-      (None, Some(_)) |
-      (Some(_), None) => {
-        // I think it should never happen that we unify two substs and
-        // one of them has a self_ty and one doesn't...? I could be
-        // wrong about this.
-          this.infcx().tcx.sess.bug(
-              fmt!("substitution a had a self_ty and substitution b didn't, \
-                    or vice versa"));
-      }
-    }
-}
-
-pub fn super_sigils<C:Combine>(
-    this: &C, p1: ast::Sigil, p2: ast::Sigil) -> cres<ast::Sigil> {
-    if p1 == p2 {
-        Ok(p1)
-    } else {
-        Err(ty::terr_sigil_mismatch(expected_found(this, p1, p2)))
-    }
-}
-
-pub fn super_flds<C:Combine>(
-    this: &C, a: ty::field, b: ty::field) -> cres<ty::field> {
-
-    if a.ident == b.ident {
-        this.mts(&a.mt, &b.mt)
-            .chain(|mt| Ok(ty::field {ident: a.ident, mt: mt}) )
-            .chain_err(|e| Err(ty::terr_in_field(@e, a.ident)) )
-    } else {
-        Err(ty::terr_record_fields(
-            expected_found(this, a.ident, b.ident)))
-    }
-}
-
-pub fn super_args<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
-    do this.contratys(a, b).chain |t| {
-        Ok(t)
-    }
-}
-
-pub fn super_vstores<C:Combine>(this: &C,
-                                vk: ty::terr_vstore_kind,
-                                a: ty::vstore,
-                                b: ty::vstore)
-                                -> cres<ty::vstore> {
-    debug!("%s.super_vstores(a=%?, b=%?)", this.tag(), a, b);
-
-    match (a, b) {
-      (ty::vstore_slice(a_r), ty::vstore_slice(b_r)) => {
-        do this.contraregions(a_r, b_r).chain |r| {
-            Ok(ty::vstore_slice(r))
-        }
-      }
-
-      _ if a == b => {
-        Ok(a)
-      }
-
-      _ => {
-        Err(ty::terr_vstores_differ(vk, expected_found(this, a, b)))
-      }
-    }
-}
-
-pub fn super_trait_stores<C:Combine>(this: &C,
-                                     vk: ty::terr_vstore_kind,
-                                     a: ty::TraitStore,
-                                     b: ty::TraitStore)
-                                  -> cres<ty::TraitStore> {
-    debug!("%s.super_vstores(a=%?, b=%?)", this.tag(), a, b);
-
-    match (a, b) {
-      (ty::RegionTraitStore(a_r), ty::RegionTraitStore(b_r)) => {
-        do this.contraregions(a_r, b_r).chain |r| {
-            Ok(ty::RegionTraitStore(r))
-        }
-      }
-
-      _ if a == b => {
-        Ok(a)
-      }
-
-      _ => {
-        Err(ty::terr_trait_stores_differ(vk, expected_found(this, a, b)))
-      }
-    }
-}
-
-pub fn super_closure_tys<C:Combine>(
-    this: &C, a_f: &ty::ClosureTy, b_f: &ty::ClosureTy) -> cres<ty::ClosureTy>
-{
-    let p = if_ok!(this.sigils(a_f.sigil, b_f.sigil));
-    let r = if_ok!(this.contraregions(a_f.region, b_f.region));
-    let purity = if_ok!(this.purities(a_f.purity, b_f.purity));
-    let onceness = if_ok!(this.oncenesses(a_f.onceness, b_f.onceness));
-    let bounds = if_ok!(this.bounds(a_f.bounds, b_f.bounds));
-    let sig = if_ok!(this.fn_sigs(&a_f.sig, &b_f.sig));
-    Ok(ty::ClosureTy {purity: purity,
-                      sigil: p,
-                      onceness: onceness,
-                      region: r,
-                      bounds: bounds,
-                      sig: sig})
-}
-
-pub fn super_abis<C:Combine>(
-    this: &C, a: AbiSet, b: AbiSet) -> cres<AbiSet>
-{
-    if a == b {
-        Ok(a)
-    } else {
-        Err(ty::terr_abi_mismatch(expected_found(this, a, b)))
-    }
-}
-
-pub fn super_bare_fn_tys<C:Combine>(
-    this: &C, a_f: &ty::BareFnTy, b_f: &ty::BareFnTy) -> cres<ty::BareFnTy>
-{
-    let purity = if_ok!(this.purities(a_f.purity, b_f.purity));
-    let abi = if_ok!(this.abis(a_f.abis, b_f.abis));
-    let sig = if_ok!(this.fn_sigs(&a_f.sig, &b_f.sig));
-    Ok(ty::BareFnTy {purity: purity,
-                     abis: abi,
-                     sig: sig})
-}
-
 pub fn super_fn_sigs<C:Combine>(
-    this: &C, a_f: &ty::FnSig, b_f: &ty::FnSig) -> cres<ty::FnSig>
-{
+    this: &C, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
+
     fn argvecs<C:Combine>(this: &C, a_args: &[ty::t], b_args: &[ty::t]) -> cres<~[ty::t]> {
         if vec::same_length(a_args, b_args) {
             result::collect(a_args.iter().zip(b_args.iter())
@@ -434,9 +427,9 @@ pub fn super_fn_sigs<C:Combine>(
         }
     }
 
-    do argvecs(this, a_f.inputs, b_f.inputs)
+    do argvecs(this, a.inputs, b.inputs)
             .chain |inputs| {
-        do this.tys(a_f.output, b_f.output).chain |output| {
+        do this.tys(a.output, b.output).chain |output| {
             Ok(FnSig {bound_lifetime_names: opt_vec::Empty, // FIXME(#4846)
                       inputs: inputs.clone(),
                       output: output})
@@ -638,24 +631,3 @@ pub fn super_tys<C:Combine>(
         Ok(ty::mk_mach_float(val))
     }
 }
-
-pub fn super_trait_refs<C:Combine>(
-    this: &C, a: &ty::TraitRef, b: &ty::TraitRef) -> cres<ty::TraitRef>
-{
-    // Different traits cannot be related
-
-    // - NOTE in the future, expand out subtraits!
-
-    if a.def_id != b.def_id {
-        Err(ty::terr_traits(
-            expected_found(this, a.def_id, b.def_id)))
-    } else {
-        let tcx = this.infcx().tcx;
-        let trait_def = ty::lookup_trait_def(tcx, a.def_id);
-        let substs = if_ok!(this.substs(&trait_def.generics, &a.substs, &b.substs));
-        Ok(ty::TraitRef {
-            def_id: a.def_id,
-            substs: substs
-        })
-    }
-}
diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs
index f05388344bc..2e337f5f57b 100644
--- a/src/librustc/middle/typeck/infer/glb.rs
+++ b/src/librustc/middle/typeck/infer/glb.rs
@@ -21,11 +21,9 @@ use middle::typeck::infer::{cres, InferCtxt};
 use middle::typeck::infer::{TypeTrace, Subtype};
 use middle::typeck::infer::fold_regions_in_sig;
 use middle::typeck::isr_alist;
-use syntax::ast;
 use syntax::ast::{Many, Once, extern_fn, impure_fn, m_const, m_imm, m_mutbl};
 use syntax::ast::{unsafe_fn};
 use syntax::ast::{Onceness, purity};
-use syntax::abi::AbiSet;
 use util::common::{indenter};
 use util::ppaux::mt_to_str;
 
@@ -139,29 +137,6 @@ impl Combine for Glb {
         super_lattice_tys(self, a, b)
     }
 
-    // Traits please (FIXME: #2794):
-
-    fn flds(&self, a: ty::field, b: ty::field) -> cres<ty::field> {
-        super_flds(self, a, b)
-    }
-
-    fn vstores(&self, vk: ty::terr_vstore_kind,
-               a: ty::vstore, b: ty::vstore) -> cres<ty::vstore> {
-        super_vstores(self, vk, a, b)
-    }
-
-    fn trait_stores(&self,
-                    vk: ty::terr_vstore_kind,
-                    a: ty::TraitStore,
-                    b: ty::TraitStore)
-                 -> cres<ty::TraitStore> {
-        super_trait_stores(self, vk, a, b)
-    }
-
-    fn args(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
-        super_args(self, a, b)
-    }
-
     fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
         // Note: this is a subtle algorithm.  For a full explanation,
         // please see the large comment in `region_inference.rs`.
@@ -290,42 +265,4 @@ impl Combine for Glb {
             this.infcx.region_vars.new_bound()
         }
     }
-
-    fn sigils(&self, p1: ast::Sigil, p2: ast::Sigil) -> cres<ast::Sigil> {
-        super_sigils(self, p1, p2)
-    }
-
-    fn abis(&self, p1: AbiSet, p2: AbiSet) -> cres<AbiSet> {
-        super_abis(self, p1, p2)
-    }
-
-    fn bare_fn_tys(&self, a: &ty::BareFnTy,
-                   b: &ty::BareFnTy) -> cres<ty::BareFnTy> {
-        super_bare_fn_tys(self, a, b)
-    }
-
-    fn closure_tys(&self, a: &ty::ClosureTy,
-                   b: &ty::ClosureTy) -> cres<ty::ClosureTy> {
-        super_closure_tys(self, a, b)
-    }
-
-    fn substs(&self,
-              generics: &ty::Generics,
-              as_: &ty::substs,
-              bs: &ty::substs) -> cres<ty::substs> {
-        super_substs(self, generics, as_, bs)
-    }
-
-    fn tps(&self, as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> {
-        super_tps(self, as_, bs)
-    }
-
-    fn self_tys(&self, a: Option<ty::t>, b: Option<ty::t>)
-               -> cres<Option<ty::t>> {
-        super_self_tys(self, a, b)
-    }
-
-    fn trait_refs(&self, a: &ty::TraitRef, b: &ty::TraitRef) -> cres<ty::TraitRef> {
-        super_trait_refs(self, a, b)
-    }
 }
diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs
index 8afb5a18d4f..4f38e2aaac6 100644
--- a/src/librustc/middle/typeck/infer/lub.rs
+++ b/src/librustc/middle/typeck/infer/lub.rs
@@ -24,8 +24,6 @@ use middle::typeck::isr_alist;
 use util::ppaux::mt_to_str;
 
 use extra::list;
-use syntax::abi::AbiSet;
-use syntax::ast;
 use syntax::ast::{Many, Once, extern_fn, m_const, impure_fn};
 use syntax::ast::{unsafe_fn};
 use syntax::ast::{Onceness, purity};
@@ -206,69 +204,7 @@ impl Combine for Lub {
         }
     }
 
-    fn bare_fn_tys(&self, a: &ty::BareFnTy,
-                   b: &ty::BareFnTy) -> cres<ty::BareFnTy> {
-        super_bare_fn_tys(self, a, b)
-    }
-
-    fn closure_tys(&self, a: &ty::ClosureTy,
-                   b: &ty::ClosureTy) -> cres<ty::ClosureTy> {
-        super_closure_tys(self, a, b)
-    }
-
-    // Traits please (FIXME: #2794):
-
-    fn sigils(&self, p1: ast::Sigil, p2: ast::Sigil)
-             -> cres<ast::Sigil> {
-        super_sigils(self, p1, p2)
-    }
-
-    fn abis(&self, p1: AbiSet, p2: AbiSet) -> cres<AbiSet> {
-        super_abis(self, p1, p2)
-    }
-
     fn tys(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
         super_lattice_tys(self, a, b)
     }
-
-    fn flds(&self, a: ty::field, b: ty::field) -> cres<ty::field> {
-        super_flds(self, a, b)
-    }
-
-    fn vstores(&self, vk: ty::terr_vstore_kind,
-               a: ty::vstore, b: ty::vstore) -> cres<ty::vstore> {
-        super_vstores(self, vk, a, b)
-    }
-
-    fn trait_stores(&self,
-                    vk: ty::terr_vstore_kind,
-                    a: ty::TraitStore,
-                    b: ty::TraitStore)
-                 -> cres<ty::TraitStore> {
-        super_trait_stores(self, vk, a, b)
-    }
-
-    fn args(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
-        super_args(self, a, b)
-    }
-
-    fn substs(&self,
-              generics: &ty::Generics,
-              as_: &ty::substs,
-              bs: &ty::substs) -> cres<ty::substs> {
-        super_substs(self, generics, as_, bs)
-    }
-
-    fn tps(&self, as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> {
-        super_tps(self, as_, bs)
-    }
-
-    fn self_tys(&self, a: Option<ty::t>, b: Option<ty::t>)
-               -> cres<Option<ty::t>> {
-        super_self_tys(self, a, b)
-    }
-
-    fn trait_refs(&self, a: &ty::TraitRef, b: &ty::TraitRef) -> cres<ty::TraitRef> {
-        super_trait_refs(self, a, b)
-    }
 }
diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs
index 441e71d4722..5a4ea1c9f1f 100644
--- a/src/librustc/middle/typeck/infer/sub.rs
+++ b/src/librustc/middle/typeck/infer/sub.rs
@@ -26,8 +26,6 @@ use util::ppaux::bound_region_to_str;
 
 use extra::list::Nil;
 use extra::list;
-use syntax::abi::AbiSet;
-use syntax::ast;
 use syntax::ast::{Onceness, m_const, purity};
 
 pub struct Sub(CombineFields);  // "subtype", "subregion" etc
@@ -225,64 +223,4 @@ impl Combine for Sub {
         ret
     }
 
-    // Traits please (FIXME: #2794):
-
-    fn sigils(&self, p1: ast::Sigil, p2: ast::Sigil) -> cres<ast::Sigil> {
-        super_sigils(self, p1, p2)
-    }
-
-    fn abis(&self, p1: AbiSet, p2: AbiSet) -> cres<AbiSet> {
-        super_abis(self, p1, p2)
-    }
-
-    fn flds(&self, a: ty::field, b: ty::field) -> cres<ty::field> {
-        super_flds(self, a, b)
-    }
-
-    fn bare_fn_tys(&self, a: &ty::BareFnTy,
-                   b: &ty::BareFnTy) -> cres<ty::BareFnTy> {
-        super_bare_fn_tys(self, a, b)
-    }
-
-    fn closure_tys(&self, a: &ty::ClosureTy,
-                   b: &ty::ClosureTy) -> cres<ty::ClosureTy> {
-        super_closure_tys(self, a, b)
-    }
-
-    fn vstores(&self, vk: ty::terr_vstore_kind,
-               a: ty::vstore, b: ty::vstore) -> cres<ty::vstore> {
-        super_vstores(self, vk, a, b)
-    }
-
-    fn trait_stores(&self,
-                    vk: ty::terr_vstore_kind,
-                    a: ty::TraitStore,
-                    b: ty::TraitStore)
-                    -> cres<ty::TraitStore> {
-        super_trait_stores(self, vk, a, b)
-    }
-
-    fn args(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
-        super_args(self, a, b)
-    }
-
-    fn substs(&self,
-              generics: &ty::Generics,
-              as_: &ty::substs,
-              bs: &ty::substs) -> cres<ty::substs> {
-        super_substs(self, generics, as_, bs)
-    }
-
-    fn tps(&self, as_: &[ty::t], bs: &[ty::t]) -> cres<~[ty::t]> {
-        super_tps(self, as_, bs)
-    }
-
-    fn self_tys(&self, a: Option<ty::t>, b: Option<ty::t>)
-               -> cres<Option<ty::t>> {
-        super_self_tys(self, a, b)
-    }
-
-    fn trait_refs(&self, a: &ty::TraitRef, b: &ty::TraitRef) -> cres<ty::TraitRef> {
-        super_trait_refs(self, a, b)
-    }
 }