]> git.lizzy.rs Git - rust.git/commitdiff
Introduce the notion of deferred resolutions and use it to hold off on
authorNiko Matsakis <niko@alum.mit.edu>
Sat, 24 Jan 2015 22:32:10 +0000 (17:32 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Sun, 1 Feb 2015 11:13:05 +0000 (06:13 -0500)
doing the final checking for closure calls until after trait inference
is performed. This isn't important now, but it's essential if we are to
delay inferring the closure kind.

src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/callee.rs
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/method/mod.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/vtable.rs

index cb4c880717bc86b5ea47d8cd2c96f030a41be199..c4b7ffb87296e8a79a1277f7284d6180b0f84f61 100644 (file)
@@ -30,7 +30,7 @@
 use syntax::ptr::P;
 
 pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
-                           pat: &ast::Pat,
+                           pat: &'tcx ast::Pat,
                            expected: Ty<'tcx>)
 {
     let fcx = pcx.fcx;
@@ -157,9 +157,10 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
         }
         ast::PatIdent(_, ref path, _) => {
             let path = ast_util::ident_to_path(path.span, path.node);
-            check_pat_enum(pcx, pat, &path, &Some(vec![]), expected);
+            check_pat_enum(pcx, pat, &path, Some(&[]), expected);
         }
         ast::PatEnum(ref path, ref subpats) => {
+            let subpats = subpats.as_ref().map(|v| &v[]);
             check_pat_enum(pcx, pat, path, subpats, expected);
         }
         ast::PatStruct(ref path, ref fields, etc) => {
@@ -335,9 +336,9 @@ pub fn check_dereferencable<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
 }
 
 pub fn check_match<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                             expr: &ast::Expr,
-                             discrim: &ast::Expr,
-                             arms: &[ast::Arm],
+                             expr: &'tcx ast::Expr,
+                             discrim: &'tcx ast::Expr,
+                             arms: &'tcx [ast::Arm],
                              expected: Expectation<'tcx>,
                              match_src: ast::MatchSource) {
     let tcx = fcx.ccx.tcx;
@@ -424,8 +425,8 @@ pub struct pat_ctxt<'a, 'tcx: 'a> {
     pub map: PatIdMap,
 }
 
-pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &ast::Pat,
-                                  path: &ast::Path, fields: &[Spanned<ast::FieldPat>],
+pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat,
+                                  path: &ast::Path, fields: &'tcx [Spanned<ast::FieldPat>],
                                   etc: bool, expected: Ty<'tcx>) {
     let fcx = pcx.fcx;
     let tcx = pcx.fcx.ccx.tcx;
@@ -483,10 +484,12 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &ast::Pat,
                             variant_def_id, etc);
 }
 
-pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &ast::Pat,
-                                path: &ast::Path, subpats: &Option<Vec<P<ast::Pat>>>,
-                                expected: Ty<'tcx>) {
-
+pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
+                                pat: &ast::Pat,
+                                path: &ast::Path,
+                                subpats: Option<&'tcx [P<ast::Pat>]>,
+                                expected: Ty<'tcx>)
+{
     // Typecheck the path.
     let fcx = pcx.fcx;
     let tcx = pcx.fcx.ccx.tcx;
@@ -536,7 +539,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &ast::Pat,
                 "`{}` does not name a non-struct variant or a tuple struct", name);
             fcx.write_error(pat.id);
 
-            if let Some(ref subpats) = *subpats {
+            if let Some(subpats) = subpats {
                 for pat in subpats.iter() {
                     check_pat(pcx, &**pat, tcx.types.err);
                 }
@@ -545,7 +548,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &ast::Pat,
         }
     };
 
-    if let Some(ref subpats) = *subpats {
+    if let Some(subpats) = subpats {
         if subpats.len() == arg_tys.len() {
             for (subpat, arg_ty) in subpats.iter().zip(arg_tys.iter()) {
                 check_pat(pcx, &**subpat, *arg_ty);
@@ -579,7 +582,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &ast::Pat,
 /// `etc` is true if the pattern said '...' and false otherwise.
 pub fn check_struct_pat_fields<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
                                          span: Span,
-                                         fields: &[Spanned<ast::FieldPat>],
+                                         fields: &'tcx [Spanned<ast::FieldPat>],
                                          struct_fields: &[ty::field<'tcx>],
                                          struct_id: ast::DefId,
                                          etc: bool) {
index e37c1ab7f0cb7d77ce722276bc0d13bd12d7b5b8..dc8bde9f84d6dfaf9502141329e132364d8a3ad6 100644 (file)
@@ -13,6 +13,8 @@
 use super::check_argument_types;
 use super::check_expr;
 use super::check_method_argument_types;
+use super::demand;
+use super::DeferredResolution;
 use super::err_args;
 use super::Expectation;
 use super::expected_types_for_fn_args;
 use super::UnresolvedTypeAction;
 use super::write_call;
 
+use CrateCtxt;
 use middle::infer;
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, ClosureTyper};
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::ptr::P;
-use CrateCtxt;
+use util::ppaux::Repr;
 
 /// Check that it is legal to call methods of the trait corresponding
 /// to `trait_id` (this only cares about the trait, not the specific
@@ -66,9 +69,9 @@ pub fn check_legal_trait_for_method_call(ccx: &CrateCtxt, span: Span, trait_id:
 }
 
 pub fn check_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                            call_expr: &ast::Expr,
-                            callee_expr: &ast::Expr,
-                            arg_exprs: &[P<ast::Expr>],
+                            call_expr: &'tcx ast::Expr,
+                            callee_expr: &'tcx ast::Expr,
+                            arg_exprs: &'tcx [P<ast::Expr>],
                             expected: Expectation<'tcx>)
 {
     check_expr(fcx, callee_expr);
@@ -96,24 +99,35 @@ pub fn check_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             confirm_builtin_call(fcx, call_expr, callee_ty, arg_exprs, expected);
         }
 
+        Some(CallStep::Closure(fn_sig)) => {
+            confirm_closure_call(fcx, call_expr, arg_exprs, expected, fn_sig);
+        }
+
         Some(CallStep::Overloaded(method_callee)) => {
-            confirm_overloaded_call(fcx, call_expr, arg_exprs, method_callee, expected);
+            confirm_overloaded_call(fcx, call_expr, callee_expr,
+                                    arg_exprs, expected, method_callee);
         }
     }
 }
 
 enum CallStep<'tcx> {
     Builtin,
+    Closure(ty::FnSig<'tcx>),
     Overloaded(ty::MethodCallee<'tcx>)
 }
 
 fn try_overloaded_call_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                      call_expr: &ast::Expr,
-                                      callee_expr: &ast::Expr,
+                                      call_expr: &'tcx ast::Expr,
+                                      callee_expr: &'tcx ast::Expr,
                                       adjusted_ty: Ty<'tcx>,
                                       autoderefref: ty::AutoDerefRef<'tcx>)
                                       -> Option<CallStep<'tcx>>
 {
+    debug!("try_overloaded_call_step(call_expr={}, adjusted_ty={}, autoderefref={})",
+           call_expr.repr(fcx.tcx()),
+           adjusted_ty.repr(fcx.tcx()),
+           autoderefref.repr(fcx.tcx()));
+
     // If the callee is a bare function or a closure, then we're all set.
     match structurally_resolved_type(fcx, callee_expr.span, adjusted_ty).sty {
         ty::ty_bare_fn(..) => {
@@ -123,9 +137,37 @@ fn try_overloaded_call_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             return Some(CallStep::Builtin);
         }
 
+        ty::ty_closure(def_id, _, substs) => {
+            let closure_ty =
+                fcx.closure_type(def_id, substs);
+            let fn_sig =
+                fcx.infcx().replace_late_bound_regions_with_fresh_var(call_expr.span,
+                                                                      infer::FnCall,
+                                                                      &closure_ty.sig).0;
+            fcx.record_deferred_resolution(box CallResolution {
+                call_expr: call_expr,
+                callee_expr: callee_expr,
+                adjusted_ty: adjusted_ty,
+                autoderefref: autoderefref,
+                fn_sig: fn_sig.clone(),
+            });
+            return Some(CallStep::Closure(fn_sig));
+        }
+
         _ => {}
     }
 
+    try_overloaded_call_traits(fcx, call_expr, callee_expr, adjusted_ty, autoderefref)
+        .map(|method_callee| CallStep::Overloaded(method_callee))
+}
+
+fn try_overloaded_call_traits<'a,'tcx>(fcx: &FnCtxt<'a, 'tcx>,
+                                       call_expr: &ast::Expr,
+                                       callee_expr: &ast::Expr,
+                                       adjusted_ty: Ty<'tcx>,
+                                       autoderefref: ty::AutoDerefRef<'tcx>)
+                                       -> Option<ty::MethodCallee<'tcx>>
+{
     // Try the options that are least restrictive on the caller first.
     for &(opt_trait_def_id, method_name) in [
         (fcx.tcx().lang_items.fn_trait(), token::intern("call")),
@@ -147,7 +189,7 @@ fn try_overloaded_call_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                                None) {
             None => continue,
             Some(method_callee) => {
-                return Some(CallStep::Overloaded(method_callee));
+                return Some(method_callee);
             }
         }
     }
@@ -158,7 +200,7 @@ fn try_overloaded_call_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                                  call_expr: &ast::Expr,
                                  callee_ty: Ty<'tcx>,
-                                 arg_exprs: &[P<ast::Expr>],
+                                 arg_exprs: &'tcx [P<ast::Expr>],
                                  expected: Expectation<'tcx>)
 {
     let error_fn_sig;
@@ -215,22 +257,124 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
     write_call(fcx, call_expr, fn_sig.output);
 }
 
+fn confirm_closure_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
+                                 call_expr: &ast::Expr,
+                                 arg_exprs: &'tcx [P<ast::Expr>],
+                                 expected: Expectation<'tcx>,
+                                 fn_sig: ty::FnSig<'tcx>)
+{
+    // `fn_sig` is the *signature* of the cosure being called. We
+    // don't know the full details yet (`Fn` vs `FnMut` etc), but we
+    // do know the types expected for each argument and the return
+    // type.
+
+    let expected_arg_tys =
+        expected_types_for_fn_args(fcx,
+                                   call_expr.span,
+                                   expected,
+                                   fn_sig.output.clone(),
+                                   &*fn_sig.inputs);
+
+    check_argument_types(fcx,
+                         call_expr.span,
+                         &*fn_sig.inputs,
+                         &*expected_arg_tys,
+                         arg_exprs,
+                         AutorefArgs::No,
+                         fn_sig.variadic,
+                         TupleArgumentsFlag::TupleArguments);
+
+    write_call(fcx, call_expr, fn_sig.output);
+}
+
 fn confirm_overloaded_call<'a,'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                     call_expr: &ast::Expr,
-                                    arg_exprs: &[P<ast::Expr>],
-                                    method_callee: ty::MethodCallee<'tcx>,
-                                    expected: Expectation<'tcx>)
+                                    callee_expr: &'tcx ast::Expr,
+                                    arg_exprs: &'tcx [P<ast::Expr>],
+                                    expected: Expectation<'tcx>,
+                                    method_callee: ty::MethodCallee<'tcx>)
 {
-    let output_type = check_method_argument_types(fcx,
-                                                  call_expr.span,
-                                                  method_callee.ty,
-                                                  call_expr,
-                                                  arg_exprs,
-                                                  AutorefArgs::No,
-                                                  TupleArgumentsFlag::TupleArguments,
-                                                  expected);
+    let output_type =
+        check_method_argument_types(fcx,
+                                    call_expr.span,
+                                    method_callee.ty,
+                                    callee_expr,
+                                    arg_exprs,
+                                    AutorefArgs::No,
+                                    TupleArgumentsFlag::TupleArguments,
+                                    expected);
+    write_call(fcx, call_expr, output_type);
+
+    write_overloaded_call_method_map(fcx, call_expr, method_callee);
+}
+
+fn write_overloaded_call_method_map<'a,'tcx>(fcx: &FnCtxt<'a, 'tcx>,
+                                             call_expr: &ast::Expr,
+                                             method_callee: ty::MethodCallee<'tcx>) {
     let method_call = ty::MethodCall::expr(call_expr.id);
     fcx.inh.method_map.borrow_mut().insert(method_call, method_callee);
-    write_call(fcx, call_expr, output_type);
 }
 
+struct CallResolution<'tcx> {
+    call_expr: &'tcx ast::Expr,
+    callee_expr: &'tcx ast::Expr,
+    adjusted_ty: Ty<'tcx>,
+    autoderefref: ty::AutoDerefRef<'tcx>,
+    fn_sig: ty::FnSig<'tcx>,
+}
+
+impl<'tcx> Repr<'tcx> for CallResolution<'tcx> {
+    fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
+        format!("CallResolution(call_expr={}, callee_expr={}, adjusted_ty={}, \
+                autoderefref={}, fn_sig={})",
+                self.call_expr.repr(tcx),
+                self.callee_expr.repr(tcx),
+                self.adjusted_ty.repr(tcx),
+                self.autoderefref.repr(tcx),
+                self.fn_sig.repr(tcx))
+    }
+}
+
+impl<'tcx> DeferredResolution<'tcx> for CallResolution<'tcx> {
+    fn attempt_resolution<'a>(&self, fcx: &FnCtxt<'a,'tcx>) -> bool {
+        debug!("attempt_resolution() {}",
+               self.repr(fcx.tcx()));
+
+        // We may now know enough to figure out fn vs fnmut etc.
+        match try_overloaded_call_traits(fcx, self.call_expr, self.callee_expr,
+                                         self.adjusted_ty, self.autoderefref.clone()) {
+            None => false,
+            Some(method_callee) => {
+                // One problem is that when we get here, we are going
+                // to have a newly instantiated function signature
+                // from the call trait. This has to be reconciled with
+                // the older function signature we had before. In
+                // principle we *should* be able to fn_sigs(), but we
+                // can't because of the annoying need for a TypeTrace.
+                // (This always bites me, should find a way to
+                // refactor it.)
+                let method_sig =
+                    ty::assert_no_late_bound_regions(fcx.tcx(),
+                                                     ty::ty_fn_sig(method_callee.ty));
+
+                debug!("attempt_resolution: method_callee={}",
+                       method_callee.repr(fcx.tcx()));
+
+                for (&method_arg_ty, &self_arg_ty) in
+                    method_sig.inputs[1..].iter().zip(self.fn_sig.inputs.iter())
+                {
+                    demand::eqtype(fcx, self.call_expr.span, self_arg_ty, method_arg_ty);
+                }
+
+                demand::eqtype(fcx,
+                               self.call_expr.span,
+                               method_sig.output.unwrap(),
+                               self.fn_sig.output.unwrap());
+
+                write_overloaded_call_method_map(fcx, self.call_expr, method_callee);
+
+                true
+            }
+        }
+    }
+}
index bdae34e7878504e5709d59f1288cbef36455b131..906a8a33314cc4070398bd948f8250111a855182 100644 (file)
@@ -26,8 +26,8 @@ pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                                    expr: &ast::Expr,
                                    _capture: ast::CaptureClause,
                                    opt_kind: Option<ast::ClosureKind>,
-                                   decl: &ast::FnDecl,
-                                   body: &ast::Block,
+                                   decl: &'tcx ast::FnDecl,
+                                   body: &'tcx ast::Block,
                                    expected: Expectation<'tcx>) {
     debug!("check_expr_closure(expr={},expected={})",
            expr.repr(fcx.tcx()),
@@ -76,8 +76,8 @@ pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
 fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                           expr: &ast::Expr,
                           kind: ty::ClosureKind,
-                          decl: &ast::FnDecl,
-                          body: &ast::Block,
+                          decl: &'tcx ast::FnDecl,
+                          body: &'tcx ast::Block,
                           expected_sig: Option<ty::FnSig<'tcx>>) {
     let expr_def_id = ast_util::local_def(expr.id);
 
index 56a32186c9eac2040ad9c910ef275fb2e013cba7..c326116cbd5449b3fbbf8709212af0a69039d67b 100644 (file)
@@ -31,8 +31,8 @@
 struct ConfirmContext<'a, 'tcx:'a> {
     fcx: &'a FnCtxt<'a, 'tcx>,
     span: Span,
-    self_expr: &'a ast::Expr,
-    call_expr: &'a ast::Expr,
+    self_expr: &'tcx ast::Expr,
+    call_expr: &'tcx ast::Expr,
 }
 
 struct InstantiatedMethodSig<'tcx> {
@@ -51,8 +51,8 @@ struct InstantiatedMethodSig<'tcx> {
 
 pub fn confirm<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                          span: Span,
-                         self_expr: &ast::Expr,
-                         call_expr: &ast::Expr,
+                         self_expr: &'tcx ast::Expr,
+                         call_expr: &'tcx ast::Expr,
                          unadjusted_self_ty: Ty<'tcx>,
                          pick: probe::Pick<'tcx>,
                          supplied_method_types: Vec<Ty<'tcx>>)
@@ -70,8 +70,8 @@ pub fn confirm<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 impl<'a,'tcx> ConfirmContext<'a,'tcx> {
     fn new(fcx: &'a FnCtxt<'a, 'tcx>,
            span: Span,
-           self_expr: &'a ast::Expr,
-           call_expr: &'a ast::Expr)
+           self_expr: &'tcx ast::Expr,
+           call_expr: &'tcx ast::Expr)
            -> ConfirmContext<'a, 'tcx>
     {
         ConfirmContext { fcx: fcx, span: span, self_expr: self_expr, call_expr: call_expr }
index d92cc1dfc1e95f4af178b5bc176a0e49e76db449..24e9f1c8720eef68e5ecca9b24bd04b6e10faf18 100644 (file)
@@ -90,8 +90,8 @@ pub fn lookup<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                         method_name: ast::Name,
                         self_ty: Ty<'tcx>,
                         supplied_method_types: Vec<Ty<'tcx>>,
-                        call_expr: &ast::Expr,
-                        self_expr: &ast::Expr)
+                        call_expr: &'tcx ast::Expr,
+                        self_expr: &'tcx ast::Expr)
                         -> Result<MethodCallee<'tcx>, MethodError>
 {
     debug!("lookup(method_name={}, self_ty={}, call_expr={}, self_expr={})",
index 9dcde1c2a0a50cc9cb4ed5438d2bec8526b6b6e5..565e96483b9a2b841d2f05236759eefadc5f9513 100644 (file)
@@ -170,8 +170,17 @@ pub struct Inherited<'a, 'tcx: 'a> {
 
     // Tracks trait obligations incurred during this function body.
     fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
+
+    //
+    deferred_resolutions: RefCell<Vec<DeferredResolutionHandler<'tcx>>>,
+}
+
+trait DeferredResolution<'tcx> {
+    fn attempt_resolution<'a>(&self, fcx: &FnCtxt<'a,'tcx>) -> bool;
 }
 
+type DeferredResolutionHandler<'tcx> = Box<DeferredResolution<'tcx>+'tcx>;
+
 /// When type-checking an expression, we propagate downward
 /// whatever type hint we are able in the form of an `Expectation`.
 #[derive(Copy)]
@@ -377,6 +386,7 @@ fn new(tcx: &'a ty::ctxt<'tcx>,
             closures: RefCell::new(DefIdMap()),
             fn_sig_map: RefCell::new(NodeMap()),
             fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
+            deferred_resolutions: RefCell::new(Vec::new()),
         }
     }
 
@@ -425,13 +435,13 @@ fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>)
 
 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
 
-impl<'a, 'tcx, 'v> Visitor<'v> for CheckItemTypesVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, i: &ast::Item) {
+impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, i: &'tcx ast::Item) {
         check_item(self.ccx, i);
         visit::walk_item(self, i);
     }
 
-    fn visit_ty(&mut self, t: &ast::Ty) {
+    fn visit_ty(&mut self, t: &'tcx ast::Ty) {
         match t.node {
             ast::TyFixedLengthVec(_, ref expr) => {
                 check_const_in_type(self.ccx, &**expr, self.ccx.tcx.types.uint);
@@ -459,8 +469,8 @@ pub fn check_item_types(ccx: &CrateCtxt) {
 }
 
 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
-                           decl: &ast::FnDecl,
-                           body: &ast::Block,
+                           decl: &'tcx ast::FnDecl,
+                           body: &'tcx ast::Block,
                            id: ast::NodeId,
                            raw_fty: Ty<'tcx>,
                            param_env: ty::ParameterEnvironment<'a, 'tcx>)
@@ -512,9 +522,9 @@ fn assign(&mut self, _span: Span, nid: ast::NodeId, ty_opt: Option<Ty<'tcx>>) ->
     }
 }
 
-impl<'a, 'tcx, 'v> Visitor<'v> for GatherLocalsVisitor<'a, 'tcx> {
+impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
     // Add explicitly-declared locals.
-    fn visit_local(&mut self, local: &ast::Local) {
+    fn visit_local(&mut self, local: &'tcx ast::Local) {
         let o_ty = match local.ty {
             Some(ref ty) => Some(self.fcx.to_ty(&**ty)),
             None => None
@@ -528,7 +538,7 @@ fn visit_local(&mut self, local: &ast::Local) {
     }
 
     // Add pattern bindings.
-    fn visit_pat(&mut self, p: &ast::Pat) {
+    fn visit_pat(&mut self, p: &'tcx ast::Pat) {
         if let ast::PatIdent(_, ref path1, _) = p.node {
             if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map, p) {
                 let var_ty = self.assign(p.span, p.id, None);
@@ -546,7 +556,7 @@ fn visit_pat(&mut self, p: &ast::Pat) {
         visit::walk_pat(self, p);
     }
 
-    fn visit_block(&mut self, b: &ast::Block) {
+    fn visit_block(&mut self, b: &'tcx ast::Block) {
         // non-obvious: the `blk` variable maps to region lb, so
         // we have to keep this up-to-date.  This
         // is... unfortunate.  It'd be nice to not need this.
@@ -555,7 +565,7 @@ fn visit_block(&mut self, b: &ast::Block) {
 
     // Since an expr occurs as part of the type fixed size arrays we
     // need to record the type for that node
-    fn visit_ty(&mut self, t: &ast::Ty) {
+    fn visit_ty(&mut self, t: &'tcx ast::Ty) {
         match t.node {
             ast::TyFixedLengthVec(ref ty, ref count_expr) => {
                 self.visit_ty(&**ty);
@@ -566,8 +576,8 @@ fn visit_ty(&mut self, t: &ast::Ty) {
     }
 
     // Don't descend into fns and items
-    fn visit_fn(&mut self, _: visit::FnKind<'v>, _: &'v ast::FnDecl,
-                _: &'v ast::Block, _: Span, _: ast::NodeId) { }
+    fn visit_fn(&mut self, _: visit::FnKind<'tcx>, _: &'tcx ast::FnDecl,
+                _: &'tcx ast::Block, _: Span, _: ast::NodeId) { }
     fn visit_item(&mut self, _: &ast::Item) { }
 
 }
@@ -582,9 +592,9 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
                       unsafety: ast::Unsafety,
                       unsafety_id: ast::NodeId,
                       fn_sig: &ty::FnSig<'tcx>,
-                      decl: &ast::FnDecl,
+                      decl: &'tcx ast::FnDecl,
                       fn_id: ast::NodeId,
-                      body: &ast::Block,
+                      body: &'tcx ast::Block,
                       inherited: &'a Inherited<'a, 'tcx>)
                       -> FnCtxt<'a, 'tcx>
 {
@@ -677,7 +687,7 @@ pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
     }
 }
 
-pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
+pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
     debug!("check_item(it.id={}, it.ident={})",
            it.id,
            ty::item_path_str(ccx.tcx, local_def(it.id)));
@@ -829,7 +839,7 @@ fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 /// * `method`: the method definition
 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                item_generics: &ty::Generics<'tcx>,
-                               method: &ast::Method) {
+                               method: &'tcx ast::Method) {
     debug!("check_method_body(item_generics={}, method.id={})",
             item_generics.repr(ccx.tcx),
             method.id);
@@ -1133,10 +1143,10 @@ fn types_compatible<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
     }
 }
 
-fn check_cast(fcx: &FnCtxt,
-              cast_expr: &ast::Expr,
-              e: &ast::Expr,
-              t: &ast::Ty) {
+fn check_cast<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
+                       cast_expr: &ast::Expr,
+                       e: &'tcx ast::Expr,
+                       t: &ast::Ty) {
     let id = cast_expr.id;
     let span = cast_expr.span;
 
@@ -1279,6 +1289,10 @@ fn resolve_type_vars_or_error(&self, t: &Ty<'tcx>) -> mc::McResult<Ty<'tcx>> {
         if ty::type_has_ty_infer(t) || ty::type_is_error(t) { Err(()) } else { Ok(t) }
     }
 
+    fn record_deferred_resolution(&self, r: DeferredResolutionHandler<'tcx>) {
+        self.inh.deferred_resolutions.borrow_mut().push(r);
+    }
+
     pub fn tag(&self) -> String {
         format!("{:?}", self as *const FnCtxt)
     }
@@ -2068,7 +2082,7 @@ fn autoderef_for_index<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
 fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                             method_call: MethodCall,
                             expr: &ast::Expr,
-                            base_expr: &ast::Expr,
+                            base_expr: &'tcx ast::Expr,
                             adjusted_ty: Ty<'tcx>,
                             adjustment: ty::AutoDerefRef<'tcx>,
                             lvalue_pref: LvaluePreference,
@@ -2138,8 +2152,8 @@ fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                          sp: Span,
                                          method_fn_ty: Ty<'tcx>,
-                                         callee_expr: &ast::Expr,
-                                         args_no_rcvr: &[P<ast::Expr>],
+                                         callee_expr: &'tcx ast::Expr,
+                                         args_no_rcvr: &'tcx [P<ast::Expr>],
                                          autoref_args: AutorefArgs,
                                          tuple_arguments: TupleArgumentsFlag,
                                          expected: Expectation<'tcx>)
@@ -2194,7 +2208,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                   sp: Span,
                                   fn_inputs: &[Ty<'tcx>],
                                   expected_arg_tys: &[Ty<'tcx>],
-                                  args: &[P<ast::Expr>],
+                                  args: &'tcx [P<ast::Expr>],
                                   autoref_args: AutorefArgs,
                                   variadic: bool,
                                   tuple_arguments: TupleArgumentsFlag) {
@@ -2462,7 +2476,7 @@ pub fn valid_range_bounds(ccx: &CrateCtxt,
 }
 
 pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                     expr: &ast::Expr,
+                                     expr: &'tcx ast::Expr,
                                      expected: Ty<'tcx>) {
     check_expr_with_unifier(
         fcx, expr, ExpectHasType(expected), NoPreference,
@@ -2470,14 +2484,14 @@ pub fn check_expr_has_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 }
 
 fn check_expr_coercable_to_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                          expr: &ast::Expr,
+                                          expr: &'tcx ast::Expr,
                                           expected: Ty<'tcx>) {
     check_expr_with_unifier(
         fcx, expr, ExpectHasType(expected), NoPreference,
         || demand::coerce(fcx, expr.span, expected, expr));
 }
 
-fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &ast::Expr,
+fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &'tcx ast::Expr,
                                   expected: Ty<'tcx>) {
     check_expr_with_unifier(
         fcx, expr, ExpectHasType(expected), NoPreference,
@@ -2485,7 +2499,7 @@ fn check_expr_with_hint<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, expr: &ast::Expr,
 }
 
 fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                         expr: &ast::Expr,
+                                         expr: &'tcx ast::Expr,
                                          expected: Expectation<'tcx>) {
     check_expr_with_unifier(
         fcx, expr, expected, NoPreference,
@@ -2493,19 +2507,19 @@ fn check_expr_with_expectation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 }
 
 fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                                         expr: &ast::Expr,
+                                                         expr: &'tcx ast::Expr,
                                                          expected: Expectation<'tcx>,
                                                          lvalue_pref: LvaluePreference)
 {
     check_expr_with_unifier(fcx, expr, expected, lvalue_pref, || ())
 }
 
-fn check_expr(fcx: &FnCtxt, expr: &ast::Expr)  {
+fn check_expr<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx ast::Expr)  {
     check_expr_with_unifier(fcx, expr, NoExpectation, NoPreference, || ())
 }
 
-fn check_expr_with_lvalue_pref(fcx: &FnCtxt, expr: &ast::Expr,
-                               lvalue_pref: LvaluePreference)  {
+fn check_expr_with_lvalue_pref<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &'tcx ast::Expr,
+                                        lvalue_pref: LvaluePreference)  {
     check_expr_with_unifier(fcx, expr, NoExpectation, lvalue_pref, || ())
 }
 
@@ -2613,7 +2627,7 @@ fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 /// that there are actually multiple representations for `ty_err`, so avoid
 /// that when err needs to be handled differently.
 fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
-                                        expr: &ast::Expr,
+                                        expr: &'tcx ast::Expr,
                                         expected: Expectation<'tcx>,
                                         lvalue_pref: LvaluePreference,
                                         unifier: F) where
@@ -2624,9 +2638,9 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
 
     // Checks a method call.
     fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                   expr: &ast::Expr,
+                                   expr: &'tcx ast::Expr,
                                    method_name: ast::SpannedIdent,
-                                   args: &[P<ast::Expr>],
+                                   args: &'tcx [P<ast::Expr>],
                                    tps: &[P<ast::Ty>],
                                    expected: Expectation<'tcx>,
                                    lvalue_pref: LvaluePreference) {
@@ -2675,9 +2689,9 @@ fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     // A generic function for checking the then and else in an if
     // or if-else.
     fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                 cond_expr: &ast::Expr,
-                                 then_blk: &ast::Block,
-                                 opt_else_expr: Option<&ast::Expr>,
+                                 cond_expr: &'tcx ast::Expr,
+                                 then_blk: &'tcx ast::Block,
+                                 opt_else_expr: Option<&'tcx ast::Expr>,
                                  id: ast::NodeId,
                                  sp: Span,
                                  expected: Expectation<'tcx>) {
@@ -2717,12 +2731,12 @@ fn check_then_else<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     }
 
     fn lookup_op_method<'a, 'tcx, F>(fcx: &'a FnCtxt<'a, 'tcx>,
-                                     op_ex: &ast::Expr,
+                                     op_ex: &'tcx ast::Expr,
                                      lhs_ty: Ty<'tcx>,
                                      opname: ast::Name,
                                      trait_did: Option<ast::DefId>,
                                      lhs: &'a ast::Expr,
-                                     rhs: Option<&P<ast::Expr>>,
+                                     rhs: Option<&'tcx P<ast::Expr>>,
                                      unbound_method: F,
                                      autoref_args: AutorefArgs) -> Ty<'tcx> where
         F: FnOnce(),
@@ -2803,12 +2817,12 @@ fn lookup_op_method<'a, 'tcx, F>(fcx: &'a FnCtxt<'a, 'tcx>,
     }
 
     // could be either an expr_binop or an expr_assign_binop
-    fn check_binop(fcx: &FnCtxt,
-                   expr: &ast::Expr,
-                   op: ast::BinOp,
-                   lhs: &ast::Expr,
-                   rhs: &P<ast::Expr>,
-                   is_binop_assignment: IsBinopAssignment) {
+    fn check_binop<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
+                            expr: &'tcx ast::Expr,
+                            op: ast::BinOp,
+                            lhs: &'tcx ast::Expr,
+                            rhs: &'tcx P<ast::Expr>,
+                            is_binop_assignment: IsBinopAssignment) {
         let tcx = fcx.ccx.tcx;
 
         let lvalue_pref = match is_binop_assignment {
@@ -2923,11 +2937,11 @@ fn check_binop(fcx: &FnCtxt,
     }
 
     fn check_user_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                  ex: &ast::Expr,
-                                  lhs_expr: &ast::Expr,
+                                  ex: &'tcx ast::Expr,
+                                  lhs_expr: &'tcx ast::Expr,
                                   lhs_resolved_t: Ty<'tcx>,
                                   op: ast::BinOp,
-                                  rhs: &P<ast::Expr>) -> Ty<'tcx> {
+                                  rhs: &'tcx P<ast::Expr>) -> Ty<'tcx> {
         let tcx = fcx.ccx.tcx;
         let lang = &tcx.lang_items;
         let (name, trait_did) = match op.node {
@@ -2966,8 +2980,8 @@ fn check_user_unop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                  op_str: &str,
                                  mname: &str,
                                  trait_did: Option<ast::DefId>,
-                                 ex: &ast::Expr,
-                                 rhs_expr: &ast::Expr,
+                                 ex: &'tcx ast::Expr,
+                                 rhs_expr: &'tcx ast::Expr,
                                  rhs_t: Ty<'tcx>,
                                  op: ast::UnOp) -> Ty<'tcx> {
        lookup_op_method(fcx, ex, rhs_t, token::intern(mname),
@@ -2980,11 +2994,11 @@ fn check_user_unop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     }
 
     // Check field access expressions
-    fn check_field(fcx: &FnCtxt,
-                   expr: &ast::Expr,
-                   lvalue_pref: LvaluePreference,
-                   base: &ast::Expr,
-                   field: &ast::SpannedIdent) {
+    fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
+                            expr: &'tcx ast::Expr,
+                            lvalue_pref: LvaluePreference,
+                            base: &'tcx ast::Expr,
+                            field: &ast::SpannedIdent) {
         let tcx = fcx.ccx.tcx;
         check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
         let expr_t = structurally_resolved_type(fcx, expr.span,
@@ -3077,11 +3091,11 @@ fn suggest_field_names<'tcx>(id : DefId,
     }
 
     // Check tuple index expressions
-    fn check_tup_field(fcx: &FnCtxt,
-                       expr: &ast::Expr,
-                       lvalue_pref: LvaluePreference,
-                       base: &ast::Expr,
-                       idx: codemap::Spanned<uint>) {
+    fn check_tup_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
+                                expr: &'tcx ast::Expr,
+                                lvalue_pref: LvaluePreference,
+                                base: &'tcx ast::Expr,
+                                idx: codemap::Spanned<uint>) {
         let tcx = fcx.ccx.tcx;
         check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
         let expr_t = structurally_resolved_type(fcx, expr.span,
@@ -3149,7 +3163,7 @@ fn check_struct_or_variant_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                                 node_id: ast::NodeId,
                                                 substitutions: &'tcx subst::Substs<'tcx>,
                                                 field_types: &[ty::field_ty],
-                                                ast_fields: &[ast::Field],
+                                                ast_fields: &'tcx [ast::Field],
                                                 check_completeness: bool,
                                                 enum_id_opt: Option<ast::DefId>)  {
         let tcx = fcx.ccx.tcx;
@@ -3252,12 +3266,12 @@ fn check_struct_or_variant_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         }
     }
 
-    fn check_struct_constructor(fcx: &FnCtxt,
-                                id: ast::NodeId,
-                                span: codemap::Span,
-                                class_id: ast::DefId,
-                                fields: &[ast::Field],
-                                base_expr: Option<&ast::Expr>) {
+    fn check_struct_constructor<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
+                                         id: ast::NodeId,
+                                         span: codemap::Span,
+                                         class_id: ast::DefId,
+                                         fields: &'tcx [ast::Field],
+                                         base_expr: Option<&'tcx ast::Expr>) {
         let tcx = fcx.ccx.tcx;
 
         // Generate the struct type.
@@ -3294,12 +3308,12 @@ fn check_struct_constructor(fcx: &FnCtxt,
         fcx.write_ty(id, struct_type);
     }
 
-    fn check_struct_enum_variant(fcx: &FnCtxt,
-                                 id: ast::NodeId,
-                                 span: codemap::Span,
-                                 enum_id: ast::DefId,
-                                 variant_id: ast::DefId,
-                                 fields: &[ast::Field]) {
+    fn check_struct_enum_variant<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
+                                          id: ast::NodeId,
+                                          span: codemap::Span,
+                                          enum_id: ast::DefId,
+                                          variant_id: ast::DefId,
+                                          fields: &'tcx [ast::Field]) {
         let tcx = fcx.ccx.tcx;
 
         // Look up the number of type parameters and the raw type, and
@@ -3324,10 +3338,10 @@ fn check_struct_enum_variant(fcx: &FnCtxt,
         fcx.write_ty(id, enum_type);
     }
 
-    fn check_struct_fields_on_error(fcx: &FnCtxt,
-                                    id: ast::NodeId,
-                                    fields: &[ast::Field],
-                                    base_expr: &Option<P<ast::Expr>>) {
+    fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
+                                             id: ast::NodeId,
+                                             fields: &'tcx [ast::Field],
+                                             base_expr: &'tcx Option<P<ast::Expr>>) {
         // Make sure to still write the types
         // otherwise we might ICE
         fcx.write_error(id);
@@ -4126,15 +4140,15 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
     }
 }
 
-pub fn check_decl_initializer(fcx: &FnCtxt,
-                              nid: ast::NodeId,
-                              init: &ast::Expr)
+pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
+                                       nid: ast::NodeId,
+                                       init: &'tcx ast::Expr)
 {
     let local_ty = fcx.local_ty(init.span, nid);
     check_expr_coercable_to_type(fcx, init, local_ty)
 }
 
-pub fn check_decl_local(fcx: &FnCtxt, local: &ast::Local)  {
+pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx ast::Local)  {
     let tcx = fcx.ccx.tcx;
 
     let t = fcx.local_ty(local.span, local.id);
@@ -4159,7 +4173,7 @@ pub fn check_decl_local(fcx: &FnCtxt, local: &ast::Local)  {
     }
 }
 
-pub fn check_stmt(fcx: &FnCtxt, stmt: &ast::Stmt)  {
+pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx ast::Stmt)  {
     let node_id;
     let mut saw_bot = false;
     let mut saw_err = false;
@@ -4204,7 +4218,7 @@ pub fn check_stmt(fcx: &FnCtxt, stmt: &ast::Stmt)  {
     }
 }
 
-pub fn check_block_no_value(fcx: &FnCtxt, blk: &ast::Block)  {
+pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx ast::Block)  {
     check_block_with_expected(fcx, blk, ExpectHasType(ty::mk_nil(fcx.tcx())));
     let blkty = fcx.node_ty(blk.id);
     if ty::type_is_error(blkty) {
@@ -4216,7 +4230,7 @@ pub fn check_block_no_value(fcx: &FnCtxt, blk: &ast::Block)  {
 }
 
 fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                       blk: &ast::Block,
+                                       blk: &'tcx ast::Block,
                                        expected: Expectation<'tcx>) {
     let prev = {
         let mut fcx_ps = fcx.ps.borrow_mut();
@@ -4299,17 +4313,17 @@ fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 /// length expression in a fixed-length vector, but someday it might be
 /// extended to type-level numeric literals.
 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
-                                expr: &ast::Expr,
+                                expr: &'tcx ast::Expr,
                                 expected_type: Ty<'tcx>) {
     let inh = static_inherited_fields(ccx);
     let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
     check_const_with_ty(&fcx, expr.span, expr, expected_type);
 }
 
-fn check_const(ccx: &CrateCtxt,
-               sp: Span,
-               e: &ast::Expr,
-               id: ast::NodeId) {
+fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
+                        sp: Span,
+                        e: &'tcx ast::Expr,
+                        id: ast::NodeId) {
     let inh = static_inherited_fields(ccx);
     let rty = ty::node_id_to_type(ccx.tcx, id);
     let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
@@ -4319,7 +4333,7 @@ fn check_const(ccx: &CrateCtxt,
 
 fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                  _: Span,
-                                 e: &ast::Expr,
+                                 e: &'tcx ast::Expr,
                                  declty: Ty<'tcx>) {
     // Gather locals in statics (because of block expressions).
     // This is technically unnecessary because locals in static items are forbidden,
@@ -4420,10 +4434,10 @@ pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
     }
 }
 
-pub fn check_enum_variants(ccx: &CrateCtxt,
-                           sp: Span,
-                           vs: &[P<ast::Variant>],
-                           id: ast::NodeId) {
+pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
+                                    sp: Span,
+                                    vs: &'tcx [P<ast::Variant>],
+                                    id: ast::NodeId) {
 
     fn disr_in_range(ccx: &CrateCtxt,
                      ty: attr::IntType,
@@ -4453,7 +4467,7 @@ fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
     }
 
     fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
-                          vs: &[P<ast::Variant>],
+                          vs: &'tcx [P<ast::Variant>],
                           id: ast::NodeId,
                           hint: attr::ReprAttr)
                           -> Vec<Rc<ty::VariantInfo<'tcx>>> {
index 41b63830279a8f1b8109d993f0c49a9019771758..9d8eaf98569fa10882f0a9e46e30adc58e3c25b6 100644 (file)
@@ -280,6 +280,9 @@ fn check_object_type_binds_all_associated_types<'tcx>(tcx: &ty::ctxt<'tcx>,
 pub fn select_all_fcx_obligations_or_error(fcx: &FnCtxt) {
     debug!("select_all_fcx_obligations_or_error");
 
+    fcx.inh.deferred_resolutions.borrow_mut()
+                                .retain(|r| !r.attempt_resolution(fcx));
+
     select_fcx_obligations_where_possible(fcx);
     fcx.default_type_parameters();