From d9bc86032d0aa20db522e04a550deb1034005784 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 2 Nov 2016 11:50:16 -0400 Subject: [PATCH] normalize trait-ref in context of impl The `specializes()` function was trying to normalize the impl trait in an empty environment. This could lead to inexplicable failures. --- src/librustc/traits/specialize/mod.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index e37425901c8c..6a27558b0b77 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -148,6 +148,8 @@ pub fn find_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl1_def_id: DefId, impl2_def_id: DefId) -> bool { + debug!("specializes({:?}, {:?})", impl1_def_id, impl2_def_id); + if let Some(r) = tcx.specializes_cache.borrow().check(impl1_def_id, impl2_def_id) { return r; } @@ -177,21 +179,22 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } // create a parameter environment corresponding to a (skolemized) instantiation of impl1 - let mut penv = tcx.construct_parameter_environment(DUMMY_SP, - impl1_def_id, - region::DUMMY_CODE_EXTENT); + let penv = tcx.construct_parameter_environment(DUMMY_SP, + impl1_def_id, + region::DUMMY_CODE_EXTENT); let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id) .unwrap() .subst(tcx, &penv.free_substs); - let result = tcx.infer_ctxt(None, None, Reveal::ExactMatch).enter(|mut infcx| { + // Create a infcx, taking the predicates of impl1 as assumptions: + let result = tcx.infer_ctxt(None, Some(penv), Reveal::ExactMatch).enter(|mut infcx| { // Normalize the trait reference, adding any obligations // that arise into the impl1 assumptions. let Normalized { value: impl1_trait_ref, obligations: normalization_obligations } = { let selcx = &mut SelectionContext::new(&infcx); traits::normalize(selcx, ObligationCause::dummy(), &impl1_trait_ref) }; - penv.caller_bounds.extend(normalization_obligations.into_iter().map(|o| { + infcx.parameter_environment.caller_bounds.extend(normalization_obligations.into_iter().map(|o| { match tcx.lift_to_global(&o.predicate) { Some(predicate) => predicate, None => { @@ -200,9 +203,6 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } })); - // Install the parameter environment, taking the predicates of impl1 as assumptions: - infcx.parameter_environment = penv; - // Attempt to prove that impl2 applies, given all of the above. fulfill_implication(&infcx, impl1_trait_ref, impl2_def_id).is_ok() });