From 92f94765ec2202ccda84a7da97c4d415ffb9b070 Mon Sep 17 00:00:00 2001 From: Niko Matsakis <niko@alum.mit.edu> Date: Sat, 31 Jan 2015 06:33:41 -0500 Subject: [PATCH] Adjust the handling of trait obligations and defaults to account for upvar inference. Upvar inference can cause some obligations to be deferred, notably things like `F : Sized` where `F` is a closure type, or `F : FnMut`. Adjust the ordering therefore so that we process all traits and apply fallback, do upvar inference, and only then start reporting errors for outstanding obligations. --- src/librustc_typeck/check/mod.rs | 3 ++- src/librustc_typeck/check/vtable.rs | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 285b4fdf2e8..c58377fc87b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -493,8 +493,9 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let fcx = check_fn(ccx, fn_ty.unsafety, id, &fn_sig, decl, id, body, &inh); - vtable::select_all_fcx_obligations_or_error(&fcx); + vtable::select_all_fcx_obligations_and_apply_defaults(&fcx); upvar::closure_analyze_fn(&fcx, id, decl, body); + vtable::select_all_fcx_obligations_or_error(&fcx); regionck::regionck_fn(&fcx, id, decl, body); writeback::resolve_type_vars_in_fn(&fcx, decl, body); } diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs index 9d8eaf98569..9921a331fa4 100644 --- a/src/librustc_typeck/check/vtable.rs +++ b/src/librustc_typeck/check/vtable.rs @@ -277,15 +277,20 @@ fn check_object_type_binds_all_associated_types<'tcx>(tcx: &ty::ctxt<'tcx>, } } -pub fn select_all_fcx_obligations_or_error(fcx: &FnCtxt) { +pub fn select_all_fcx_obligations_and_apply_defaults(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(); + select_fcx_obligations_where_possible(fcx); +} +pub fn select_all_fcx_obligations_or_error(fcx: &FnCtxt) { + debug!("select_all_fcx_obligations_or_error"); + + select_all_fcx_obligations_and_apply_defaults(fcx); let mut fulfillment_cx = fcx.inh.fulfillment_cx.borrow_mut(); let r = fulfillment_cx.select_all_or_error(fcx.infcx(), fcx); match r {