mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-11 19:46:49 +00:00
Instantiate all bound vars existentially
This commit is contained in:
parent
79b6c41bc2
commit
afa884c03a
src
librustc
librustc_mir/borrow_check/nll/type_check
librustc_traits/chalk_context
librustc_typeck/check
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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<T>(
|
||||
pub fn replace_bound_vars_with_fresh_vars<T>(
|
||||
&self,
|
||||
span: Span,
|
||||
lbrct: LateBoundRegionConversionTime,
|
||||
value: &ty::Binder<T>,
|
||||
value: &ty::Binder<T>
|
||||
) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
|
||||
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:
|
||||
|
@ -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,
|
||||
|
@ -520,22 +520,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn replace_late_bound_regions<T, F>(
|
||||
self,
|
||||
value: &Binder<T>,
|
||||
mut fld_r: F
|
||||
fld_r: F
|
||||
) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
|
||||
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<ty::BoundRegion, ty::Region<'tcx>>)
|
||||
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<T>,
|
||||
fld_r: F,
|
||||
fld_t: G
|
||||
) -> T
|
||||
) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
|
||||
where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>,
|
||||
G: FnMut(ty::BoundTy) -> ty::Ty<'tcx>,
|
||||
T: TypeFoldable<'tcx>
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -347,12 +347,11 @@ impl context::UnificationOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
|
||||
&mut self,
|
||||
arg: &ty::Binder<Goal<'tcx>>,
|
||||
) -> 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<dyn Debug + 'v> {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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(),
|
||||
|
@ -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,
|
||||
|
@ -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<T>(&self, value: &ty::Binder<T>) -> T
|
||||
fn replace_bound_vars_with_fresh_vars<T>(&self, value: &ty::Binder<T>) -> 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
|
||||
}
|
||||
}
|
||||
|
@ -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 } => {
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user