about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-12-05 00:03:03 -0500
committerNiko Matsakis <niko@alum.mit.edu>2014-12-12 20:24:34 -0500
commit4efaddf7c96743c087861ba15bd9b48a2200ddfd (patch)
tree6381e7829ecb5fb7b9ff617b671e99f49200fd69 /src
parentffc111889e93bcd38222d9d74a70fdc26a78fcb5 (diff)
downloadrust-4efaddf7c96743c087861ba15bd9b48a2200ddfd.tar.gz
rust-4efaddf7c96743c087861ba15bd9b48a2200ddfd.zip
Start restructuring to support generalized where clauses etc.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/metadata/csearch.rs6
-rw-r--r--src/librustc/middle/astencode.rs2
-rw-r--r--src/librustc/middle/traits/fulfill.rs8
-rw-r--r--src/librustc/middle/traits/mod.rs41
-rw-r--r--src/librustc/middle/traits/select.rs102
-rw-r--r--src/librustc/middle/traits/util.rs10
-rw-r--r--src/librustc/middle/ty.rs8
-rw-r--r--src/librustc/middle/ty_fold.rs28
-rw-r--r--src/librustc_typeck/check/mod.rs2
-rw-r--r--src/librustc_typeck/check/vtable.rs12
-rw-r--r--src/librustc_typeck/lib.rs6
11 files changed, 112 insertions, 113 deletions
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index b864dc39603..7ce9893afc8 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -21,7 +21,6 @@ use middle::def;
 use middle::lang_items;
 use middle::resolve;
 use middle::ty;
-use middle::subst::VecPerParamSpace;
 
 use rbml;
 use rbml::reader;
@@ -250,9 +249,8 @@ pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId,
         });
     let ty = decoder::item_type(def, the_field, tcx, &*cdata);
     ty::Polytype {
-        generics: ty::Generics {types: VecPerParamSpace::empty(),
-                                regions: VecPerParamSpace::empty()},
-        ty: ty
+        generics: ty::Generics::empty(),
+        ty: ty,
     }
 }
 
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 113d127503f..8c2fbc078e2 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -1553,7 +1553,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
                             this.read_struct_field("regions", 1, |this| {
                                 Ok(this.read_vec_per_param_space(
                                     |this| Decodable::decode(this).unwrap()))
-                            }).unwrap()
+                            }).unwrap(),
                         })
                     })
                 }).unwrap(),
diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs
index 653c686ab19..f6428efc4e4 100644
--- a/src/librustc/middle/traits/fulfill.rs
+++ b/src/librustc/middle/traits/fulfill.rs
@@ -16,7 +16,7 @@ use std::rc::Rc;
 use util::ppaux::Repr;
 
 use super::CodeAmbiguity;
-use super::Obligation;
+use super::TraitObligation;
 use super::FulfillmentError;
 use super::CodeSelectionError;
 use super::select::SelectionContext;
@@ -41,7 +41,7 @@ pub struct FulfillmentContext<'tcx> {
 
     // A list of all obligations that have been registered with this
     // fulfillment context.
-    trait_obligations: Vec<Obligation<'tcx>>,
+    trait_obligations: Vec<TraitObligation<'tcx>>,
 
     // Remembers the count of trait obligations that we have already
     // attempted to select. This is used to avoid repeating work
@@ -60,7 +60,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
 
     pub fn register_obligation(&mut self,
                                tcx: &ty::ctxt<'tcx>,
-                               obligation: Obligation<'tcx>)
+                               obligation: TraitObligation<'tcx>)
     {
         if self.duplicate_set.insert(obligation.trait_ref.clone()) {
             debug!("register_obligation({})", obligation.repr(tcx));
@@ -117,7 +117,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
         self.select(&mut selcx, false)
     }
 
-    pub fn pending_trait_obligations(&self) -> &[Obligation<'tcx>] {
+    pub fn pending_trait_obligations(&self) -> &[TraitObligation<'tcx>] {
         self.trait_obligations[]
     }
 
diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs
index d410a456dc9..1505fe7561b 100644
--- a/src/librustc/middle/traits/mod.rs
+++ b/src/librustc/middle/traits/mod.rs
@@ -47,22 +47,22 @@ mod util;
 /// provides the required vtable, or else finding a bound that is in
 /// scope. The eventual result is usually a `Selection` (defined below).
 #[deriving(Clone)]
-pub struct Obligation<'tcx> {
+pub struct Obligation<'tcx, T> {
     pub cause: ObligationCause<'tcx>,
     pub recursion_depth: uint,
-    pub trait_ref: Rc<ty::TraitRef<'tcx>>,
+    pub trait_ref: T,
 }
 
+pub type TraitObligation<'tcx> = Obligation<'tcx, Rc<ty::TraitRef<'tcx>>>;
+
 /// Why did we incur this obligation? Used for error reporting.
-#[deriving(Clone)]
+#[deriving(Copy, Clone)]
 pub struct ObligationCause<'tcx> {
     pub span: Span,
     pub code: ObligationCauseCode<'tcx>
 }
 
-impl<'tcx> Copy for ObligationCause<'tcx> {}
-
-#[deriving(Clone)]
+#[deriving(Copy, Clone)]
 pub enum ObligationCauseCode<'tcx> {
     /// Not well classified or should be obvious from span.
     MiscObligation,
@@ -95,11 +95,11 @@ pub enum ObligationCauseCode<'tcx> {
     ObjectSized,
 }
 
-pub type Obligations<'tcx> = subst::VecPerParamSpace<Obligation<'tcx>>;
+pub type Obligations<'tcx, O> = subst::VecPerParamSpace<Obligation<'tcx, O>>;
 
-impl<'tcx> Copy for ObligationCauseCode<'tcx> {}
+pub type TraitObligations<'tcx> = subst::VecPerParamSpace<TraitObligation<'tcx>>;
 
-pub type Selection<'tcx> = Vtable<'tcx, Obligation<'tcx>>;
+pub type Selection<'tcx> = Vtable<'tcx, TraitObligation<'tcx>>;
 
 #[deriving(Clone,Show)]
 pub enum SelectionError<'tcx> {
@@ -109,7 +109,7 @@ pub enum SelectionError<'tcx> {
 }
 
 pub struct FulfillmentError<'tcx> {
-    pub obligation: Obligation<'tcx>,
+    pub obligation: TraitObligation<'tcx>,
     pub code: FulfillmentErrorCode<'tcx>
 }
 
@@ -230,7 +230,7 @@ pub fn select_inherent_impl<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
                                      impl_def_id: ast::DefId,
                                      self_ty: Ty<'tcx>)
                                      -> SelectionResult<'tcx,
-                                            VtableImplData<'tcx, Obligation<'tcx>>>
+                                            VtableImplData<'tcx, TraitObligation<'tcx>>>
 {
     // This routine is only suitable for inherent impls. This is
     // because it does not attempt to unify the output type parameters
@@ -279,7 +279,7 @@ pub fn obligations_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
                                       cause: ObligationCause<'tcx>,
                                       generic_bounds: &ty::GenericBounds<'tcx>,
                                       type_substs: &subst::VecPerParamSpace<Ty<'tcx>>)
-                                      -> subst::VecPerParamSpace<Obligation<'tcx>>
+                                      -> subst::VecPerParamSpace<TraitObligation<'tcx>>
 {
     util::obligations_for_generics(tcx, cause, 0, generic_bounds, type_substs)
 }
@@ -288,23 +288,27 @@ pub fn obligation_for_builtin_bound<'tcx>(tcx: &ty::ctxt<'tcx>,
                                           cause: ObligationCause<'tcx>,
                                           source_ty: Ty<'tcx>,
                                           builtin_bound: ty::BuiltinBound)
-                                          -> Result<Obligation<'tcx>, ErrorReported>
+                                          -> Result<TraitObligation<'tcx>, ErrorReported>
 {
     util::obligation_for_builtin_bound(tcx, cause, builtin_bound, 0, source_ty)
 }
 
-impl<'tcx> Obligation<'tcx> {
-    pub fn new(cause: ObligationCause<'tcx>, trait_ref: Rc<ty::TraitRef<'tcx>>)
-               -> Obligation<'tcx> {
+impl<'tcx,O> Obligation<'tcx,O> {
+    pub fn new(cause: ObligationCause<'tcx>,
+               trait_ref: O)
+               -> Obligation<'tcx, O>
+    {
         Obligation { cause: cause,
                      recursion_depth: 0,
                      trait_ref: trait_ref }
     }
 
-    pub fn misc(span: Span, trait_ref: Rc<ty::TraitRef<'tcx>>) -> Obligation<'tcx> {
+    pub fn misc(span: Span, trait_ref: O) -> Obligation<'tcx, O> {
         Obligation::new(ObligationCause::misc(span), trait_ref)
     }
+}
 
+impl<'tcx> Obligation<'tcx,Rc<ty::TraitRef<'tcx>>> {
     pub fn self_ty(&self) -> Ty<'tcx> {
         self.trait_ref.self_ty()
     }
@@ -406,7 +410,8 @@ impl<N> VtableBuiltinData<N> {
 }
 
 impl<'tcx> FulfillmentError<'tcx> {
-    fn new(obligation: Obligation<'tcx>, code: FulfillmentErrorCode<'tcx>)
+    fn new(obligation: TraitObligation<'tcx>,
+           code: FulfillmentErrorCode<'tcx>)
            -> FulfillmentError<'tcx>
     {
         FulfillmentError { obligation: obligation, code: code }
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index 06f8cbf1a6a..90fc663e829 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -17,7 +17,7 @@ use self::Candidate::*;
 use self::BuiltinBoundConditions::*;
 use self::EvaluationResult::*;
 
-use super::{Obligation, ObligationCause};
+use super::{TraitObligation, ObligationCause};
 use super::{SelectionError, Unimplemented, Overflow,
             OutputTypeParameterMismatch};
 use super::{Selection};
@@ -70,14 +70,14 @@ pub struct SelectionContext<'cx, 'tcx:'cx> {
 }
 
 // A stack that walks back up the stack frame.
-struct ObligationStack<'prev, 'tcx: 'prev> {
-    obligation: &'prev Obligation<'tcx>,
+struct TraitObligationStack<'prev, 'tcx: 'prev> {
+    obligation: &'prev TraitObligation<'tcx>,
 
     /// Trait ref from `obligation` but skolemized with the
     /// selection-context's skolemizer. Used to check for recursion.
     skol_trait_ref: Rc<ty::TraitRef<'tcx>>,
 
-    previous: Option<&'prev ObligationStack<'prev, 'tcx>>
+    previous: Option<&'prev TraitObligationStack<'prev, 'tcx>>
 }
 
 #[deriving(Clone)]
@@ -213,7 +213,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     /// Evaluates whether the obligation can be satisfied. Returns an indication of whether the
     /// obligation can be satisfied and, if so, by what means. Never affects surrounding typing
     /// environment.
-    pub fn select(&mut self, obligation: &Obligation<'tcx>)
+    pub fn select(&mut self, obligation: &TraitObligation<'tcx>)
                   -> SelectionResult<'tcx, Selection<'tcx>> {
         debug!("select({})", obligation.repr(self.tcx()));
         assert!(!obligation.trait_ref.has_escaping_regions());
@@ -229,7 +229,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                 impl_def_id: ast::DefId,
                                 obligation_cause: ObligationCause<'tcx>,
                                 obligation_self_ty: Ty<'tcx>)
-                                -> SelectionResult<'tcx, VtableImplData<'tcx, Obligation<'tcx>>>
+                                -> SelectionResult<'tcx, VtableImplData<'tcx, TraitObligation<'tcx>>>
     {
         debug!("select_inherent_impl(impl_def_id={}, obligation_self_ty={})",
                impl_def_id.repr(self.tcx()),
@@ -260,7 +260,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
     /// Evaluates whether the obligation `obligation` can be satisfied (by any means).
     pub fn evaluate_obligation(&mut self,
-                               obligation: &Obligation<'tcx>)
+                               obligation: &TraitObligation<'tcx>)
                                -> bool
     {
         debug!("evaluate_obligation({})",
@@ -273,7 +273,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
     fn evaluate_builtin_bound_recursively<'o>(&mut self,
                                               bound: ty::BuiltinBound,
-                                              previous_stack: &ObligationStack<'o, 'tcx>,
+                                              previous_stack: &TraitObligationStack<'o, 'tcx>,
                                               ty: Ty<'tcx>)
                                               -> EvaluationResult<'tcx>
     {
@@ -296,8 +296,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn evaluate_obligation_recursively<'o>(&mut self,
-                                           previous_stack: Option<&ObligationStack<'o, 'tcx>>,
-                                           obligation: &Obligation<'tcx>)
+                                           previous_stack: Option<&TraitObligationStack<'o, 'tcx>>,
+                                           obligation: &TraitObligation<'tcx>)
                                            -> EvaluationResult<'tcx>
     {
         debug!("evaluate_obligation_recursively({})",
@@ -312,7 +312,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn evaluate_stack<'o>(&mut self,
-                          stack: &ObligationStack<'o, 'tcx>)
+                          stack: &TraitObligationStack<'o, 'tcx>)
                           -> EvaluationResult<'tcx>
     {
         // In intercrate mode, whenever any of the types are unbound,
@@ -392,7 +392,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     /// `obligation_self_ty`. This can be used either for trait or inherent impls.
     pub fn evaluate_impl(&mut self,
                          impl_def_id: ast::DefId,
-                         obligation: &Obligation<'tcx>)
+                         obligation: &TraitObligation<'tcx>)
                          -> bool
     {
         debug!("evaluate_impl(impl_def_id={}, obligation={})",
@@ -423,7 +423,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     // candidates. See `doc.rs` and the `Candidate` type for more details.
 
     fn candidate_from_obligation<'o>(&mut self,
-                                     stack: &ObligationStack<'o, 'tcx>)
+                                     stack: &TraitObligationStack<'o, 'tcx>)
                                      -> SelectionResult<'tcx, Candidate<'tcx>>
     {
         // Watch out for overflow. This intentionally bypasses (and does
@@ -466,7 +466,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn candidate_from_obligation_no_cache<'o>(&mut self,
-                                              stack: &ObligationStack<'o, 'tcx>)
+                                              stack: &TraitObligationStack<'o, 'tcx>)
                                               -> SelectionResult<'tcx, Candidate<'tcx>>
     {
         if ty::type_is_error(stack.obligation.self_ty()) {
@@ -626,12 +626,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn assemble_candidates<'o>(&mut self,
-                               stack: &ObligationStack<'o, 'tcx>)
+                               stack: &TraitObligationStack<'o, 'tcx>)
                                -> Result<CandidateSet<'tcx>, SelectionError<'tcx>>
     {
         // Check for overflow.
 
-        let ObligationStack { obligation, .. } = *stack;
+        let TraitObligationStack { obligation, .. } = *stack;
 
         let mut candidates = CandidateSet {
             vec: Vec::new(),
@@ -682,7 +682,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     ///
     /// Never affects inference environment.
     fn assemble_candidates_from_caller_bounds(&mut self,
-                                              obligation: &Obligation<'tcx>,
+                                              obligation: &TraitObligation<'tcx>,
                                               candidates: &mut CandidateSet<'tcx>)
                                               -> Result<(),SelectionError<'tcx>>
     {
@@ -720,7 +720,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     /// parameters and hence do not affect whether this trait is a match or not. They will be
     /// unified during the confirmation step.
     fn assemble_unboxed_closure_candidates(&mut self,
-                                           obligation: &Obligation<'tcx>,
+                                           obligation: &TraitObligation<'tcx>,
                                            candidates: &mut CandidateSet<'tcx>)
                                            -> Result<(),SelectionError<'tcx>>
     {
@@ -762,7 +762,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
     /// Implement one of the `Fn()` family for a fn pointer.
     fn assemble_fn_pointer_candidates(&mut self,
-                                      obligation: &Obligation<'tcx>,
+                                      obligation: &TraitObligation<'tcx>,
                                       candidates: &mut CandidateSet<'tcx>)
                                       -> Result<(),SelectionError<'tcx>>
     {
@@ -800,7 +800,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
     /// Search for impls that might apply to `obligation`.
     fn assemble_candidates_from_impls(&mut self,
-                                      obligation: &Obligation<'tcx>,
+                                      obligation: &TraitObligation<'tcx>,
                                       candidates: &mut CandidateSet<'tcx>)
                                       -> Result<(), SelectionError<'tcx>>
     {
@@ -831,7 +831,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     /// obligations are met. Returns true if `candidate` remains viable after this further
     /// scrutiny.
     fn winnow_candidate<'o>(&mut self,
-                            stack: &ObligationStack<'o, 'tcx>,
+                            stack: &TraitObligationStack<'o, 'tcx>,
                             candidate: &Candidate<'tcx>)
                             -> EvaluationResult<'tcx>
     {
@@ -846,7 +846,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn winnow_selection<'o>(&mut self,
-                            stack: Option<&ObligationStack<'o, 'tcx>>,
+                            stack: Option<&TraitObligationStack<'o, 'tcx>>,
                             selection: Selection<'tcx>)
                             -> EvaluationResult<'tcx>
     {
@@ -885,7 +885,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     /// essentially harmless.  See issue #18453 for more details of
     /// a case where doing the opposite caused us harm.
     fn candidate_should_be_dropped_in_favor_of<'o>(&mut self,
-                                                   stack: &ObligationStack<'o, 'tcx>,
+                                                   stack: &TraitObligationStack<'o, 'tcx>,
                                                    candidate_i: &Candidate<'tcx>,
                                                    candidate_j: &Candidate<'tcx>)
                                                    -> bool
@@ -928,7 +928,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
     fn assemble_builtin_bound_candidates<'o>(&mut self,
                                              bound: ty::BuiltinBound,
-                                             stack: &ObligationStack<'o, 'tcx>,
+                                             stack: &TraitObligationStack<'o, 'tcx>,
                                              candidates: &mut CandidateSet<'tcx>)
                                              -> Result<(),SelectionError<'tcx>>
     {
@@ -1300,7 +1300,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     // type error.  See `doc.rs` for more details.
 
     fn confirm_candidate(&mut self,
-                         obligation: &Obligation<'tcx>,
+                         obligation: &TraitObligation<'tcx>,
                          candidate: Candidate<'tcx>)
                          -> Result<Selection<'tcx>,SelectionError<'tcx>>
     {
@@ -1343,7 +1343,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn confirm_param_candidate(&mut self,
-                               obligation: &Obligation<'tcx>,
+                               obligation: &TraitObligation<'tcx>,
                                param: VtableParamData<'tcx>)
                                -> Result<VtableParamData<'tcx>,
                                          SelectionError<'tcx>>
@@ -1359,9 +1359,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn confirm_builtin_candidate(&mut self,
-                                 obligation: &Obligation<'tcx>,
+                                 obligation: &TraitObligation<'tcx>,
                                  bound: ty::BuiltinBound)
-                                 -> Result<VtableBuiltinData<Obligation<'tcx>>,
+                                 -> Result<VtableBuiltinData<TraitObligation<'tcx>>,
                                            SelectionError<'tcx>>
     {
         debug!("confirm_builtin_candidate({})",
@@ -1379,10 +1379,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn vtable_builtin_data(&mut self,
-                           obligation: &Obligation<'tcx>,
+                           obligation: &TraitObligation<'tcx>,
                            bound: ty::BuiltinBound,
                            nested: Vec<Ty<'tcx>>)
-                           -> VtableBuiltinData<Obligation<'tcx>>
+                           -> VtableBuiltinData<TraitObligation<'tcx>>
     {
         let obligations = nested.iter().map(|&t| {
             util::obligation_for_builtin_bound(
@@ -1402,9 +1402,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn confirm_impl_candidate(&mut self,
-                              obligation: &Obligation<'tcx>,
+                              obligation: &TraitObligation<'tcx>,
                               impl_def_id: ast::DefId)
-                              -> Result<VtableImplData<'tcx, Obligation<'tcx>>,
+                              -> Result<VtableImplData<'tcx, TraitObligation<'tcx>>,
                                         SelectionError<'tcx>>
     {
         debug!("confirm_impl_candidate({},{})",
@@ -1422,7 +1422,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                    substs: Substs<'tcx>,
                    cause: ObligationCause<'tcx>,
                    recursion_depth: uint)
-                   -> VtableImplData<'tcx, Obligation<'tcx>>
+                   -> VtableImplData<'tcx, TraitObligation<'tcx>>
     {
         let impl_obligations =
             self.impl_obligations(cause,
@@ -1435,7 +1435,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn confirm_fn_pointer_candidate(&mut self,
-                                    obligation: &Obligation<'tcx>)
+                                    obligation: &TraitObligation<'tcx>)
                                     -> Result<ty::Ty<'tcx>,SelectionError<'tcx>>
     {
         debug!("confirm_fn_pointer_candidate({})",
@@ -1480,7 +1480,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn confirm_unboxed_closure_candidate(&mut self,
-                                         obligation: &Obligation<'tcx>,
+                                         obligation: &TraitObligation<'tcx>,
                                          closure_def_id: ast::DefId,
                                          substs: &Substs<'tcx>)
                                          -> Result<(),SelectionError<'tcx>>
@@ -1531,7 +1531,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
     fn rematch_impl(&mut self,
                     impl_def_id: ast::DefId,
-                    obligation: &Obligation<'tcx>)
+                    obligation: &TraitObligation<'tcx>)
                     -> Substs<'tcx>
     {
         match self.match_impl(impl_def_id, obligation) {
@@ -1550,7 +1550,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
     fn match_impl(&mut self,
                   impl_def_id: ast::DefId,
-                  obligation: &Obligation<'tcx>)
+                  obligation: &TraitObligation<'tcx>)
                   -> Result<Substs<'tcx>, ()>
     {
         let impl_trait_ref = ty::impl_trait_ref(self.tcx(),
@@ -1577,7 +1577,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn fast_reject_trait_refs(&mut self,
-                              obligation: &Obligation,
+                              obligation: &TraitObligation,
                               impl_trait_ref: &ty::TraitRef)
                               -> bool
     {
@@ -1600,7 +1600,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn match_trait_refs(&mut self,
-                        obligation: &Obligation<'tcx>,
+                        obligation: &TraitObligation<'tcx>,
                         trait_ref: Rc<ty::TraitRef<'tcx>>)
                         -> Result<(),()>
     {
@@ -1762,13 +1762,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     // Miscellany
 
     fn push_stack<'o,'s:'o>(&mut self,
-                            previous_stack: Option<&'s ObligationStack<'s, 'tcx>>,
-                            obligation: &'o Obligation<'tcx>)
-                            -> ObligationStack<'o, 'tcx>
+                            previous_stack: Option<&'s TraitObligationStack<'s, 'tcx>>,
+                            obligation: &'o TraitObligation<'tcx>)
+                            -> TraitObligationStack<'o, 'tcx>
     {
         let skol_trait_ref = obligation.trait_ref.fold_with(&mut self.skolemizer);
 
-        ObligationStack {
+        TraitObligationStack {
             obligation: obligation,
             skol_trait_ref: skol_trait_ref,
             previous: previous_stack.map(|p| p), // FIXME variance
@@ -1790,7 +1790,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         recursion_depth: uint,
                         impl_def_id: ast::DefId,
                         impl_substs: &Substs<'tcx>)
-                        -> VecPerParamSpace<Obligation<'tcx>>
+                        -> VecPerParamSpace<TraitObligation<'tcx>>
     {
         let impl_generics = ty::lookup_item_type(self.tcx(), impl_def_id).generics;
         let bounds = impl_generics.to_bounds(self.tcx(), impl_substs);
@@ -1840,14 +1840,16 @@ impl<'tcx> SelectionCache<'tcx> {
     }
 }
 
-impl<'o, 'tcx> ObligationStack<'o, 'tcx> {
-    fn iter(&self) -> Option<&ObligationStack<'o, 'tcx>> {
+impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> {
+    fn iter(&self) -> Option<&TraitObligationStack<'o, 'tcx>> {
         Some(self)
     }
 }
 
-impl<'o, 'tcx> Iterator<&'o ObligationStack<'o, 'tcx>> for Option<&'o ObligationStack<'o, 'tcx>> {
-    fn next(&mut self) -> Option<&'o ObligationStack<'o, 'tcx>> {
+impl<'o, 'tcx> Iterator<&'o TraitObligationStack<'o,'tcx>>
+           for Option<&'o TraitObligationStack<'o, 'tcx>>
+{
+    fn next(&mut self) -> Option<&'o TraitObligationStack<'o, 'tcx>> {
         match *self {
             Some(o) => {
                 *self = o.previous;
@@ -1860,9 +1862,9 @@ impl<'o, 'tcx> Iterator<&'o ObligationStack<'o, 'tcx>> for Option<&'o Obligation
     }
 }
 
-impl<'o, 'tcx> Repr<'tcx> for ObligationStack<'o, 'tcx> {
+impl<'o, 'tcx> Repr<'tcx> for TraitObligationStack<'o, 'tcx> {
     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
-        format!("ObligationStack({})",
+        format!("TraitObligationStack({})",
                 self.obligation.repr(tcx))
     }
 }
diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs
index 159b6961782..9ffa5b76a99 100644
--- a/src/librustc/middle/traits/util.rs
+++ b/src/librustc/middle/traits/util.rs
@@ -21,7 +21,7 @@ use syntax::codemap::Span;
 use util::common::ErrorReported;
 use util::ppaux::Repr;
 
-use super::{Obligation, ObligationCause, VtableImpl,
+use super::{Obligation, ObligationCause, TraitObligation, VtableImpl,
             VtableParam, VtableParamData, VtableImplData};
 
 ///////////////////////////////////////////////////////////////////////////
@@ -181,7 +181,7 @@ pub fn obligations_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
                                       recursion_depth: uint,
                                       generic_bounds: &ty::GenericBounds<'tcx>,
                                       type_substs: &VecPerParamSpace<Ty<'tcx>>)
-                                      -> VecPerParamSpace<Obligation<'tcx>>
+                                      -> VecPerParamSpace<TraitObligation<'tcx>>
 {
 
     debug!("obligations_for_generics(generic_bounds={}, type_substs={})",
@@ -213,7 +213,7 @@ fn push_obligations_for_param_bounds<'tcx>(
     index: uint,
     param_bounds: &ty::ParamBounds<'tcx>,
     param_type_substs: &VecPerParamSpace<Ty<'tcx>>,
-    obligations: &mut VecPerParamSpace<Obligation<'tcx>>)
+    obligations: &mut VecPerParamSpace<TraitObligation<'tcx>>)
 {
     let param_ty = *param_type_substs.get(space, index);
     for builtin_bound in param_bounds.builtin_bounds.iter() {
@@ -262,7 +262,7 @@ pub fn obligation_for_builtin_bound<'tcx>(
     builtin_bound: ty::BuiltinBound,
     recursion_depth: uint,
     param_ty: Ty<'tcx>)
-    -> Result<Obligation<'tcx>, ErrorReported>
+    -> Result<TraitObligation<'tcx>, ErrorReported>
 {
     let trait_ref = trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty);
     match trait_ref {
@@ -294,7 +294,7 @@ pub fn search_trait_and_supertraits_from_bound<'tcx>(tcx: &ty::ctxt<'tcx>,
     return None;
 }
 
-impl<'tcx> Repr<'tcx> for super::Obligation<'tcx> {
+impl<'tcx,O:Repr<'tcx>> Repr<'tcx> for super::Obligation<'tcx, O> {
     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
         format!("Obligation(trait_ref={},depth={})",
                 self.trait_ref.repr(tcx),
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 3f555ec5c4c..5f5709f87f7 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -1623,8 +1623,10 @@ pub struct Generics<'tcx> {
 
 impl<'tcx> Generics<'tcx> {
     pub fn empty() -> Generics<'tcx> {
-        Generics { types: VecPerParamSpace::empty(),
-                   regions: VecPerParamSpace::empty() }
+        Generics {
+            types: VecPerParamSpace::empty(),
+            regions: VecPerParamSpace::empty(),
+        }
     }
 
     pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
@@ -1743,7 +1745,7 @@ pub struct ParameterEnvironment<'tcx> {
     ///
     /// Note: This effectively *duplicates* the `bounds` array for
     /// now.
-    pub caller_obligations: VecPerParamSpace<traits::Obligation<'tcx>>,
+    pub caller_obligations: VecPerParamSpace<traits::TraitObligation<'tcx>>,
 
     /// Caches the results of trait selection. This cache is used
     /// for things that have to do with the parameters in scope.
diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs
index 77092025349..543d2bdd957 100644
--- a/src/librustc/middle/ty_fold.rs
+++ b/src/librustc/middle/ty_fold.rs
@@ -137,11 +137,6 @@ pub trait TypeFolder<'tcx> {
     fn fold_item_substs(&mut self, i: ty::ItemSubsts<'tcx>) -> ty::ItemSubsts<'tcx> {
         super_fold_item_substs(self, i)
     }
-
-    fn fold_obligation(&mut self, o: &traits::Obligation<'tcx>)
-                       -> traits::Obligation<'tcx> {
-        super_fold_obligation(self, o)
-    }
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -434,9 +429,15 @@ impl<'tcx> TypeFoldable<'tcx> for ty::UnsizeKind<'tcx> {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for traits::Obligation<'tcx> {
-    fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::Obligation<'tcx> {
-        folder.fold_obligation(self)
+impl<'tcx,O> TypeFoldable<'tcx> for traits::Obligation<'tcx,O>
+    where O : TypeFoldable<'tcx>
+{
+    fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::Obligation<'tcx, O> {
+        traits::Obligation {
+            cause: self.cause,
+            recursion_depth: self.recursion_depth,
+            trait_ref: self.trait_ref.fold_with(folder),
+        }
     }
 }
 
@@ -687,17 +688,6 @@ pub fn super_fold_item_substs<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
     }
 }
 
-pub fn super_fold_obligation<'tcx, T:TypeFolder<'tcx>>(this: &mut T,
-                                                       obligation: &traits::Obligation<'tcx>)
-                                                       -> traits::Obligation<'tcx>
-{
-    traits::Obligation {
-        cause: obligation.cause,
-        recursion_depth: obligation.recursion_depth,
-        trait_ref: obligation.trait_ref.fold_with(this),
-    }
-}
-
 ///////////////////////////////////////////////////////////////////////////
 // Higher-ranked things
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 7e29e7078d4..7270e66ab53 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1841,7 +1841,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     pub fn register_obligation(&self,
-                               obligation: traits::Obligation<'tcx>)
+                               obligation: traits::TraitObligation<'tcx>)
     {
         debug!("register_obligation({})",
                obligation.repr(self.tcx()));
diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs
index 80363055a4b..1f0a486edd3 100644
--- a/src/librustc_typeck/check/vtable.rs
+++ b/src/librustc_typeck/check/vtable.rs
@@ -12,9 +12,9 @@ use check::{FnCtxt, structurally_resolved_type};
 use middle::subst::{SelfSpace, FnSpace};
 use middle::traits;
 use middle::traits::{SelectionError, OutputTypeParameterMismatch, Overflow, Unimplemented};
-use middle::traits::{Obligation, obligation_for_builtin_bound};
+use middle::traits::{Obligation, ObligationCause, obligation_for_builtin_bound};
 use middle::traits::{FulfillmentError, CodeSelectionError, CodeAmbiguity};
-use middle::traits::{ObligationCause};
+use middle::traits::{TraitObligation};
 use middle::ty::{mod, Ty};
 use middle::infer;
 use std::rc::Rc;
@@ -323,7 +323,7 @@ pub fn select_all_fcx_obligations_or_error(fcx: &FnCtxt) {
     }
 }
 
-fn resolve_trait_ref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, obligation: &Obligation<'tcx>)
+fn resolve_trait_ref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, obligation: &TraitObligation<'tcx>)
                                -> (Rc<ty::TraitRef<'tcx>>, Ty<'tcx>)
 {
     let trait_ref =
@@ -354,7 +354,7 @@ pub fn report_fulfillment_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 }
 
 pub fn report_selection_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                        obligation: &Obligation<'tcx>,
+                                        obligation: &TraitObligation<'tcx>,
                                         error: &SelectionError<'tcx>)
 {
     match *error {
@@ -411,7 +411,7 @@ pub fn report_selection_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 }
 
 pub fn maybe_report_ambiguity<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                        obligation: &Obligation<'tcx>) {
+                                        obligation: &TraitObligation<'tcx>) {
     // Unable to successfully determine, probably means
     // insufficient type information, but could mean
     // ambiguous impls. The latter *ought* to be a
@@ -500,7 +500,7 @@ pub fn select_new_fcx_obligations(fcx: &FnCtxt) {
 }
 
 fn note_obligation_cause<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                   obligation: &Obligation<'tcx>) {
+                                   obligation: &TraitObligation<'tcx>) {
     let tcx = fcx.tcx();
     let trait_name = ty::item_path_str(tcx, obligation.trait_ref.def_id);
     match obligation.cause.code {
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index b83bbd6b4c0..d29e5a9f430 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -160,8 +160,10 @@ fn lookup_def_ccx(ccx: &CrateCtxt, sp: Span, id: ast::NodeId)
 
 fn no_params<'tcx>(t: Ty<'tcx>) -> ty::Polytype<'tcx> {
     ty::Polytype {
-        generics: ty::Generics {types: VecPerParamSpace::empty(),
-                                regions: VecPerParamSpace::empty()},
+        generics: ty::Generics {
+            types: VecPerParamSpace::empty(),
+            regions: VecPerParamSpace::empty(),
+        },
         ty: t
     }
 }