diff options
Diffstat (limited to 'src/librustc/traits/mod.rs')
| -rw-r--r-- | src/librustc/traits/mod.rs | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 55b1a913f0d..a3a5c26ec18 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -431,7 +431,10 @@ pub fn type_known_to_meet_bound<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx // this function's result remains infallible, we must confirm // that guess. While imperfect, I believe this is sound. - let mut fulfill_cx = FulfillmentContext::new(); + // The handling of regions in this area of the code is terrible, + // see issue #29149. We should be able to improve on this with + // NLL. + let mut fulfill_cx = FulfillmentContext::new_ignoring_regions(); // We can use a dummy node-id here because we won't pay any mind // to region obligations that arise (there shouldn't really be any @@ -511,8 +514,24 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, unnormalized_env.reveal); tcx.infer_ctxt().enter(|infcx| { - let predicates = match fully_normalize( + // FIXME. We should really... do something with these region + // obligations. But this call just continues the older + // behavior (i.e., doesn't cause any new bugs), and it would + // take some further refactoring to actually solve them. In + // particular, we would have to handle implied bounds + // properly, and that code is currently largely confined to + // regionck (though I made some efforts to extract it + // out). -nmatsakis + // + // @arielby: In any case, these obligations are checked + // by wfcheck anyway, so I'm not sure we have to check + // them here too, and we will remove this function when + // we move over to lazy normalization *anyway*. + let fulfill_cx = FulfillmentContext::new_ignoring_regions(); + + let predicates = match fully_normalize_with_fulfillcx( &infcx, + fulfill_cx, cause, elaborated_env, // You would really want to pass infcx.param_env.caller_bounds here, @@ -537,16 +556,6 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let region_scope_tree = region::ScopeTree::default(); let free_regions = FreeRegionMap::new(); - // FIXME. We should really... do something with these region - // obligations. But this call just continues the older - // behavior (i.e., doesn't cause any new bugs), and it would - // take some further refactoring to actually solve them. In - // particular, we would have to handle implied bounds - // properly, and that code is currently largely confined to - // regionck (though I made some efforts to extract it - // out). -nmatsakis - let _ = infcx.ignore_region_obligations(); - infcx.resolve_regions_and_report_errors(region_context, ®ion_scope_tree, &free_regions); let predicates = match infcx.fully_resolve(&predicates) { Ok(predicates) => predicates, @@ -583,9 +592,6 @@ pub fn fully_normalize<'a, 'gcx, 'tcx, T>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, -> Result<T, Vec<FulfillmentError<'tcx>>> where T : TypeFoldable<'tcx> { - debug!("fully_normalize(value={:?})", value); - - let selcx = &mut SelectionContext::new(infcx); // FIXME (@jroesch) ISSUE 26721 // I'm not sure if this is a bug or not, needs further investigation. // It appears that by reusing the fulfillment_cx here we incur more @@ -599,8 +605,21 @@ pub fn fully_normalize<'a, 'gcx, 'tcx, T>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, // // I think we should probably land this refactor and then come // back to this is a follow-up patch. - let mut fulfill_cx = FulfillmentContext::new(); + let fulfillcx = FulfillmentContext::new(); + fully_normalize_with_fulfillcx(infcx, fulfillcx, cause, param_env, value) +} +pub fn fully_normalize_with_fulfillcx<'a, 'gcx, 'tcx, T>( + infcx: &InferCtxt<'a, 'gcx, 'tcx>, + mut fulfill_cx: FulfillmentContext<'tcx>, + cause: ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + value: &T) + -> Result<T, Vec<FulfillmentError<'tcx>>> + where T : TypeFoldable<'tcx> +{ + debug!("fully_normalize_with_fulfillcx(value={:?})", value); + let selcx = &mut SelectionContext::new(infcx); let Normalized { value: normalized_value, obligations } = project::normalize(selcx, param_env, cause, value); debug!("fully_normalize: normalized_value={:?} obligations={:?}", |
