From afa884c03a90f4d773e28faaad4bc7845d677332 Mon Sep 17 00:00:00 2001 From: scalexm Date: Thu, 1 Nov 2018 15:30:37 +0100 Subject: [PATCH] Instantiate all bound vars existentially --- src/librustc/infer/canonical/substitute.rs | 2 +- src/librustc/infer/higher_ranked/mod.rs | 10 +++---- src/librustc/infer/mod.rs | 12 ++++---- src/librustc/traits/error_reporting.rs | 5 ++-- src/librustc/ty/fold.rs | 30 +++++++++---------- .../nll/type_check/input_output.rs | 2 +- .../borrow_check/nll/type_check/mod.rs | 2 +- src/librustc_traits/chalk_context/mod.rs | 7 ++--- src/librustc_typeck/check/callee.rs | 11 +++---- src/librustc_typeck/check/closure.rs | 4 +-- src/librustc_typeck/check/compare_method.rs | 11 +++---- src/librustc_typeck/check/method/confirm.rs | 12 ++++---- src/librustc_typeck/check/method/mod.rs | 8 +++-- src/librustc_typeck/check/method/probe.rs | 7 +++-- src/librustc_typeck/check/mod.rs | 10 +++---- 15 files changed, 68 insertions(+), 65 deletions(-) diff --git a/src/librustc/infer/canonical/substitute.rs b/src/librustc/infer/canonical/substitute.rs index b8c1ed236c0..70ce5d0d8dc 100644 --- a/src/librustc/infer/canonical/substitute.rs +++ b/src/librustc/infer/canonical/substitute.rs @@ -80,6 +80,6 @@ where } }; - tcx.replace_escaping_bound_vars(value, fld_r, fld_t) + tcx.replace_escaping_bound_vars(value, fld_r, fld_t).0 } } diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index 3e08a4e021a..642382bcf0f 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -59,11 +59,11 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { // with a fresh region variable. These region variables -- // but no other pre-existing region variables -- can name // the placeholders. - let (a_prime, _) = - self.infcx.replace_late_bound_regions_with_fresh_var( - span, - HigherRankedType, - a); + let (a_prime, _) = self.infcx.replace_bound_vars_with_fresh_vars( + span, + HigherRankedType, + a + ); debug!("a_prime={:?}", a_prime); debug!("b_prime={:?}", b_prime); diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index f5513acecf9..4ddf47c88dd 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -1328,18 +1328,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.report_and_explain_type_error(trace, &err) } - pub fn replace_late_bound_regions_with_fresh_var( + pub fn replace_bound_vars_with_fresh_vars( &self, span: Span, lbrct: LateBoundRegionConversionTime, - value: &ty::Binder, + value: &ty::Binder ) -> (T, BTreeMap>) where - T: TypeFoldable<'tcx>, + T: TypeFoldable<'tcx> { - self.tcx.replace_late_bound_regions(value, |br| { - self.next_region_var(LateBoundRegion(span, br, lbrct)) - }) + let fld_r = |br| self.next_region_var(LateBoundRegion(span, br, lbrct)); + let fld_t = |_| self.next_ty_var(TypeVariableOrigin::MiscVariable(span)); + self.tcx.replace_bound_vars(value, fld_r, fld_t) } /// Given a higher-ranked projection predicate like: diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index fbada789956..2761a954cea 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -212,10 +212,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // cause I have no idea for a good error message. if let ty::Predicate::Projection(ref data) = predicate { let mut selcx = SelectionContext::new(self); - let (data, _) = self.replace_late_bound_regions_with_fresh_var( + let (data, _) = self.replace_bound_vars_with_fresh_vars( obligation.cause.span, infer::LateBoundRegionConversionTime::HigherRankedType, - data); + data + ); let mut obligations = vec![]; let normalized_ty = super::normalize_projection_type( &mut selcx, diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index ffa4380a5d6..a897afa0ca6 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -520,22 +520,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn replace_late_bound_regions( self, value: &Binder, - mut fld_r: F + fld_r: F ) -> (T, BTreeMap>) where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, T: TypeFoldable<'tcx> { - let mut map = BTreeMap::new(); - let mut real_fldr = |br| { - *map.entry(br).or_insert_with(|| fld_r(br)) - }; - // identity for bound types - let mut fld_t = |bound_ty| self.mk_ty(ty::Bound(bound_ty)); - - let mut replacer = BoundVarReplacer::new(self, &mut real_fldr, &mut fld_t); - let result = value.skip_binder().fold_with(&mut replacer); - (result, map) + let fld_t = |bound_ty| self.mk_ty(ty::Bound(bound_ty)); + self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t) } /// Replace all escaping bound vars. The `fld_r` closure replaces escaping @@ -545,17 +537,23 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { value: &T, mut fld_r: F, mut fld_t: G - ) -> T + ) -> (T, BTreeMap>) where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, G: FnMut(ty::BoundTy) -> ty::Ty<'tcx>, T: TypeFoldable<'tcx> { + let mut map = BTreeMap::new(); + if !value.has_escaping_bound_vars() { - value.clone() + (value.clone(), map) } else { - let mut replacer = BoundVarReplacer::new(self, &mut fld_r, &mut fld_t); + let mut real_fld_r = |br| { + *map.entry(br).or_insert_with(|| fld_r(br)) + }; + + let mut replacer = BoundVarReplacer::new(self, &mut real_fld_r, &mut fld_t); let result = value.fold_with(&mut replacer); - result + (result, map) } } @@ -567,7 +565,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { value: &Binder, fld_r: F, fld_t: G - ) -> T + ) -> (T, BTreeMap>) where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, G: FnMut(ty::BoundTy) -> ty::Ty<'tcx>, T: TypeFoldable<'tcx> diff --git a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs index ab4ee3a4ad0..85ea39e538f 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs @@ -62,7 +62,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { // "inside" the closure. Some( self.infcx - .replace_late_bound_regions_with_fresh_var( + .replace_bound_vars_with_fresh_vars( mir.span, LateBoundRegionConversionTime::FnCall, &poly_sig, diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index c8d2bcd8b93..2193dba9fca 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -1406,7 +1406,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { return; } }; - let (sig, map) = self.infcx.replace_late_bound_regions_with_fresh_var( + let (sig, map) = self.infcx.replace_bound_vars_with_fresh_vars( term.source_info.span, LateBoundRegionConversionTime::FnCall, &sig, diff --git a/src/librustc_traits/chalk_context/mod.rs b/src/librustc_traits/chalk_context/mod.rs index 611cace45df..0fd9f607a54 100644 --- a/src/librustc_traits/chalk_context/mod.rs +++ b/src/librustc_traits/chalk_context/mod.rs @@ -347,12 +347,11 @@ impl context::UnificationOps, ChalkArenas<'tcx>> &mut self, arg: &ty::Binder>, ) -> Goal<'tcx> { - let (value, _map) = self.infcx.replace_late_bound_regions_with_fresh_var( + self.infcx.replace_bound_vars_with_fresh_vars( DUMMY_SP, LateBoundRegionConversionTime::HigherRankedType, - arg, - ); - value + arg + ).0 } fn debug_ex_clause(&mut self, value: &'v ChalkExClause<'tcx>) -> Box { diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index de4293aaaea..411583b36b9 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -110,10 +110,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // fnmut vs fnonce. If so, we have to defer further processing. if self.closure_kind(def_id, substs).is_none() { let closure_ty = self.closure_sig(def_id, substs); - let fn_sig = self.replace_late_bound_regions_with_fresh_var(call_expr.span, - infer::FnCall, - &closure_ty) - .0; + let fn_sig = self.replace_bound_vars_with_fresh_vars( + call_expr.span, + infer::FnCall, + &closure_ty + ).0; let adjustments = autoderef.adjust_steps(Needs::None); self.record_deferred_call_resolution(def_id, DeferredCallResolution { call_expr, @@ -284,7 +285,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // previously appeared within a `Binder<>` and hence would not // have been normalized before. let fn_sig = - self.replace_late_bound_regions_with_fresh_var(call_expr.span, infer::FnCall, &fn_sig) + self.replace_bound_vars_with_fresh_vars(call_expr.span, infer::FnCall, &fn_sig) .0; let fn_sig = self.normalize_associated_types_in(call_expr.span, &fn_sig); diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 010561d1001..10ac2448d00 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -564,7 +564,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // `liberated_sig` is E'. { // Instantiate (this part of..) S to S', i.e., with fresh variables. - let (supplied_ty, _) = self.infcx.replace_late_bound_regions_with_fresh_var( + let (supplied_ty, _) = self.infcx.replace_bound_vars_with_fresh_vars( hir_ty.span, LateBoundRegionConversionTime::FnCall, &ty::Binder::bind(supplied_ty), @@ -605,7 +605,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); } - let (supplied_output_ty, _) = self.infcx.replace_late_bound_regions_with_fresh_var( + let (supplied_output_ty, _) = self.infcx.replace_bound_vars_with_fresh_vars( decl.output.span(), LateBoundRegionConversionTime::FnCall, &supplied_sig.output(), diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 45c5457c9e1..e30ebe07e54 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -233,7 +233,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut selcx = traits::SelectionContext::new(&infcx); let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_skol_substs); - let (impl_m_own_bounds, _) = infcx.replace_late_bound_regions_with_fresh_var( + let (impl_m_own_bounds, _) = infcx.replace_bound_vars_with_fresh_vars( impl_m_span, infer::HigherRankedType, &ty::Binder::bind(impl_m_own_bounds.predicates) @@ -262,10 +262,11 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Compute placeholder form of impl and trait method tys. let tcx = infcx.tcx; - let (impl_sig, _) = - infcx.replace_late_bound_regions_with_fresh_var(impl_m_span, - infer::HigherRankedType, - &tcx.fn_sig(impl_m.def_id)); + let (impl_sig, _) = infcx.replace_bound_vars_with_fresh_vars( + impl_m_span, + infer::HigherRankedType, + &tcx.fn_sig(impl_m.def_id) + ); let impl_sig = inh.normalize_associated_types_in(impl_m_span, impl_m_node_id, diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 75f5bf74c6a..5144f3e41d4 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -245,7 +245,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { let original_poly_trait_ref = principal.with_self_ty(this.tcx, object_ty); let upcast_poly_trait_ref = this.upcast(original_poly_trait_ref, trait_def_id); let upcast_trait_ref = - this.replace_late_bound_regions_with_fresh_var(&upcast_poly_trait_ref); + this.replace_bound_vars_with_fresh_vars(&upcast_poly_trait_ref); debug!("original_poly_trait_ref={:?} upcast_trait_ref={:?} target_trait={:?}", original_poly_trait_ref, upcast_trait_ref, @@ -268,7 +268,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { probe::WhereClausePick(ref poly_trait_ref) => { // Where clauses can have bound regions in them. We need to instantiate // those to convert from a poly-trait-ref to a trait-ref. - self.replace_late_bound_regions_with_fresh_var(&poly_trait_ref).substs + self.replace_bound_vars_with_fresh_vars(&poly_trait_ref).substs } } } @@ -398,7 +398,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // NB: Instantiate late-bound regions first so that // `instantiate_type_scheme` can normalize associated types that // may reference those regions. - let method_sig = self.replace_late_bound_regions_with_fresh_var(&sig); + let method_sig = self.replace_bound_vars_with_fresh_vars(&sig); debug!("late-bound lifetimes from method instantiated, method_sig={:?}", method_sig); @@ -633,11 +633,9 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { upcast_trait_refs.into_iter().next().unwrap() } - fn replace_late_bound_regions_with_fresh_var(&self, value: &ty::Binder) -> T + fn replace_bound_vars_with_fresh_vars(&self, value: &ty::Binder) -> T where T: TypeFoldable<'tcx> { - self.fcx - .replace_late_bound_regions_with_fresh_var(self.span, infer::FnCall, value) - .0 + self.fcx.replace_bound_vars_with_fresh_vars(self.span, infer::FnCall, value).0 } } diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 637f3eaae9a..ac338ba6678 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -311,9 +311,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // `instantiate_type_scheme` can normalize associated types that // may reference those regions. let fn_sig = tcx.fn_sig(def_id); - let fn_sig = self.replace_late_bound_regions_with_fresh_var(span, - infer::FnCall, - &fn_sig).0; + let fn_sig = self.replace_bound_vars_with_fresh_vars( + span, + infer::FnCall, + &fn_sig + ).0; let fn_sig = fn_sig.subst(self.tcx, substs); let fn_sig = match self.normalize_associated_types_in_as_infer_ok(span, &fn_sig) { InferOk { value, obligations: o } => { diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 305efd0d75a..4c06cae1d07 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -755,8 +755,11 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { self.probe(|_| { let substs = self.fresh_substs_for_item(self.span, method.def_id); let fty = fty.subst(self.tcx, substs); - let (fty, _) = self.replace_late_bound_regions_with_fresh_var( - self.span, infer::FnCall, &fty); + let (fty, _) = self.replace_bound_vars_with_fresh_vars( + self.span, + infer::FnCall, + &fty + ); if let Some(self_ty) = self_ty { if self.at(&ObligationCause::dummy(), self.param_env) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 2e6797ef23a..41e0c6c0a19 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1921,11 +1921,11 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { poly_trait_ref: ty::PolyTraitRef<'tcx>) -> Ty<'tcx> { - let (trait_ref, _) = - self.replace_late_bound_regions_with_fresh_var( - span, - infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id), - &poly_trait_ref); + let (trait_ref, _) = self.replace_bound_vars_with_fresh_vars( + span, + infer::LateBoundRegionConversionTime::AssocTypeProjection(item_def_id), + &poly_trait_ref + ); self.tcx().mk_projection(item_def_id, trait_ref.substs) }