mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-17 09:23:05 +00:00
WIP partial apply fix
This commit is contained in:
parent
c63f1fe92b
commit
a9f1e1c440
@ -298,6 +298,7 @@ struct AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||||||
cause: ObligationCause<'tcx>,
|
cause: ObligationCause<'tcx>,
|
||||||
obligations: &'a mut Vec<PredicateObligation<'tcx>>,
|
obligations: &'a mut Vec<PredicateObligation<'tcx>>,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
|
universes: Vec<Option<ty::UniverseIndex>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
|
impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||||
@ -308,12 +309,16 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||||||
depth: usize,
|
depth: usize,
|
||||||
obligations: &'a mut Vec<PredicateObligation<'tcx>>,
|
obligations: &'a mut Vec<PredicateObligation<'tcx>>,
|
||||||
) -> AssocTypeNormalizer<'a, 'b, 'tcx> {
|
) -> AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||||
AssocTypeNormalizer { selcx, param_env, cause, obligations, depth }
|
AssocTypeNormalizer { selcx, param_env, cause, obligations, depth, universes: vec![] }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T {
|
fn fold<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T {
|
||||||
let value = self.selcx.infcx().resolve_vars_if_possible(value);
|
let value = self.selcx.infcx().resolve_vars_if_possible(value);
|
||||||
|
|
||||||
|
if value.has_escaping_bound_vars() {
|
||||||
|
bug!("Normalizing without wrapping in a `Binder`");
|
||||||
|
}
|
||||||
|
|
||||||
if !value.has_projections() { value } else { value.fold_with(self) }
|
if !value.has_projections() { value } else { value.fold_with(self) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -323,6 +328,16 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||||||
self.selcx.tcx()
|
self.selcx.tcx()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||||
|
&mut self,
|
||||||
|
t: ty::Binder<'tcx, T>,
|
||||||
|
) -> ty::Binder<'tcx, T> {
|
||||||
|
self.universes.push(None);
|
||||||
|
let t = t.super_fold_with(self);
|
||||||
|
self.universes.pop();
|
||||||
|
t
|
||||||
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
if !ty.has_projections() {
|
if !ty.has_projections() {
|
||||||
return ty;
|
return ty;
|
||||||
@ -412,37 +427,40 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||||||
// give up and fall back to pretending like we never tried!
|
// give up and fall back to pretending like we never tried!
|
||||||
|
|
||||||
let infcx = self.selcx.infcx();
|
let infcx = self.selcx.infcx();
|
||||||
let (data, mapped_regions, mapped_types, mapped_consts, universe_map) =
|
let replaced =
|
||||||
BoundVarReplacer::replace_bound_vars(infcx, data);
|
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
|
||||||
|
if let Some((data, mapped_regions, mapped_types, mapped_consts)) = replaced {
|
||||||
|
let normalized_ty = opt_normalize_projection_type(
|
||||||
|
self.selcx,
|
||||||
|
self.param_env,
|
||||||
|
data,
|
||||||
|
self.cause.clone(),
|
||||||
|
self.depth,
|
||||||
|
&mut self.obligations,
|
||||||
|
)
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
.unwrap_or_else(|| ty);
|
||||||
|
|
||||||
let normalized_ty = opt_normalize_projection_type(
|
let normalized_ty = PlaceholderReplacer::replace_placeholders(
|
||||||
self.selcx,
|
infcx,
|
||||||
self.param_env,
|
mapped_regions,
|
||||||
data,
|
mapped_types,
|
||||||
self.cause.clone(),
|
mapped_consts,
|
||||||
self.depth,
|
&self.universes,
|
||||||
&mut self.obligations,
|
normalized_ty,
|
||||||
)
|
);
|
||||||
.ok()
|
debug!(
|
||||||
.flatten()
|
?self.depth,
|
||||||
.unwrap_or_else(|| ty);
|
?ty,
|
||||||
|
?normalized_ty,
|
||||||
let normalized_ty = PlaceholderReplacer::replace_placeholders(
|
obligations.len = ?self.obligations.len(),
|
||||||
infcx,
|
"AssocTypeNormalizer: normalized type"
|
||||||
mapped_regions,
|
);
|
||||||
mapped_types,
|
normalized_ty
|
||||||
mapped_consts,
|
} else {
|
||||||
universe_map,
|
ty
|
||||||
normalized_ty,
|
}
|
||||||
);
|
|
||||||
debug!(
|
|
||||||
?self.depth,
|
|
||||||
?ty,
|
|
||||||
?normalized_ty,
|
|
||||||
obligations.len = ?self.obligations.len(),
|
|
||||||
"AssocTypeNormalizer: normalized type"
|
|
||||||
);
|
|
||||||
normalized_ty
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => ty,
|
_ => ty,
|
||||||
@ -460,26 +478,42 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct BoundVarReplacer<'me, 'tcx> {
|
pub struct BoundVarReplacer<'me, 'tcx> {
|
||||||
pub infcx: &'me InferCtxt<'me, 'tcx>,
|
infcx: &'me InferCtxt<'me, 'tcx>,
|
||||||
pub mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
|
// These three maps track the bound variable that were replaced by placeholders. It might be
|
||||||
pub mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy>,
|
// nice to remove these since we already have the `kind` in the placeholder; we really just need
|
||||||
pub mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
|
// the `var` (but we *could* bring that into scope if we were to track them as we pass them).
|
||||||
pub universes: BTreeMap<ty::DebruijnIndex, ty::UniverseIndex>,
|
mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
|
||||||
pub universes_inverse: BTreeMap<ty::UniverseIndex, ty::DebruijnIndex>,
|
mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy>,
|
||||||
pub current_index: ty::DebruijnIndex,
|
mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
|
||||||
|
// The current depth relative to *this* folding, *not* the entire normalization. In other words,
|
||||||
|
// the depth of binders we've passed here.
|
||||||
|
current_index: ty::DebruijnIndex,
|
||||||
|
// The `UniverseIndex` of the binding levels above us. These are optional, since we are lazy:
|
||||||
|
// we don't actually create a universe until we see a bound var we have to replace.
|
||||||
|
universe_indices: &'me mut Vec<Option<ty::UniverseIndex>>,
|
||||||
|
// FIXME: So, this is a less-than-ideal solution to a problem we want to solve eventually. Ideally, we
|
||||||
|
// shouldn't need to worry about bound vars for which we haven't passed (`self.current_index`)
|
||||||
|
// or that we don't explicitly know about (`self.universe_indices`). This is true for
|
||||||
|
// `AssocTypeNormalizer` but not `QueryNormalizer` currently. When we can always know about
|
||||||
|
// any binding levels above us, we can remove this. (The alternative would be
|
||||||
|
// `outer_exclusive_binder`, but that only exists on `Ty`. Otherwise, we would have to visit
|
||||||
|
// through the `T`, which we specifically want to avoid not being lazy.)
|
||||||
|
failed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> {
|
impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> {
|
||||||
|
/// Returns `Some` if we *were* able to replace bound vars. If there are any bound vars that
|
||||||
|
/// use a binding level above `universe_indices.len()`, we fail.
|
||||||
pub fn replace_bound_vars<T: TypeFoldable<'tcx>>(
|
pub fn replace_bound_vars<T: TypeFoldable<'tcx>>(
|
||||||
infcx: &'me InferCtxt<'me, 'tcx>,
|
infcx: &'me InferCtxt<'me, 'tcx>,
|
||||||
|
universe_indices: &'me mut Vec<Option<ty::UniverseIndex>>,
|
||||||
value: T,
|
value: T,
|
||||||
) -> (
|
) -> Option<(
|
||||||
T,
|
T,
|
||||||
BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
|
BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
|
||||||
BTreeMap<ty::PlaceholderType, ty::BoundTy>,
|
BTreeMap<ty::PlaceholderType, ty::BoundTy>,
|
||||||
BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
|
BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
|
||||||
BTreeMap<ty::UniverseIndex, ty::DebruijnIndex>,
|
)> {
|
||||||
) {
|
|
||||||
let mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion> = BTreeMap::new();
|
let mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion> = BTreeMap::new();
|
||||||
let mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy> = BTreeMap::new();
|
let mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy> = BTreeMap::new();
|
||||||
let mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar> = BTreeMap::new();
|
let mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar> = BTreeMap::new();
|
||||||
@ -489,20 +523,16 @@ impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> {
|
|||||||
mapped_regions,
|
mapped_regions,
|
||||||
mapped_types,
|
mapped_types,
|
||||||
mapped_consts,
|
mapped_consts,
|
||||||
universes: BTreeMap::new(),
|
|
||||||
universes_inverse: BTreeMap::new(),
|
|
||||||
current_index: ty::INNERMOST,
|
current_index: ty::INNERMOST,
|
||||||
|
universe_indices,
|
||||||
|
failed: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let value = value.super_fold_with(&mut replacer);
|
let value = value.super_fold_with(&mut replacer);
|
||||||
|
|
||||||
(
|
(!replacer.failed).then(|| {
|
||||||
value,
|
(value, replacer.mapped_regions, replacer.mapped_types, replacer.mapped_consts)
|
||||||
replacer.mapped_regions,
|
})
|
||||||
replacer.mapped_types,
|
|
||||||
replacer.mapped_consts,
|
|
||||||
replacer.universes_inverse,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,15 +553,24 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
|||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReLateBound(debruijn, br) => {
|
ty::ReLateBound(debruijn, _)
|
||||||
|
if debruijn.as_usize() + 1
|
||||||
|
> self.current_index.as_usize() + self.universe_indices.len() =>
|
||||||
|
{
|
||||||
|
self.failed = true;
|
||||||
|
r
|
||||||
|
}
|
||||||
|
ty::ReLateBound(debruijn, br) if debruijn >= self.current_index => {
|
||||||
let infcx = self.infcx;
|
let infcx = self.infcx;
|
||||||
let placeholder_db_index =
|
let index = self.universe_indices.len() - debruijn.as_usize()
|
||||||
ty::DebruijnIndex::from_u32(self.current_index.as_u32() - debruijn.as_u32());
|
+ self.current_index.as_usize()
|
||||||
let universe = *self
|
- 1;
|
||||||
.universes
|
let universe = self.universe_indices[index].unwrap_or_else(|| {
|
||||||
.entry(placeholder_db_index)
|
for i in self.universe_indices.iter_mut().take(index + 1) {
|
||||||
.or_insert_with(|| infcx.create_next_universe());
|
*i = i.or_else(|| Some(infcx.create_next_universe()))
|
||||||
self.universes_inverse.insert(universe, placeholder_db_index);
|
}
|
||||||
|
self.universe_indices[index].unwrap()
|
||||||
|
});
|
||||||
let p = ty::PlaceholderRegion { universe, name: br.kind };
|
let p = ty::PlaceholderRegion { universe, name: br.kind };
|
||||||
self.mapped_regions.insert(p.clone(), br);
|
self.mapped_regions.insert(p.clone(), br);
|
||||||
self.infcx.tcx.mk_region(ty::RePlaceholder(p))
|
self.infcx.tcx.mk_region(ty::RePlaceholder(p))
|
||||||
@ -542,15 +581,24 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
|||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match *t.kind() {
|
match *t.kind() {
|
||||||
ty::Bound(debruijn, bound_ty) => {
|
ty::Bound(debruijn, _)
|
||||||
|
if debruijn.as_usize() + 1
|
||||||
|
> self.current_index.as_usize() + self.universe_indices.len() =>
|
||||||
|
{
|
||||||
|
self.failed = true;
|
||||||
|
t
|
||||||
|
}
|
||||||
|
ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => {
|
||||||
let infcx = self.infcx;
|
let infcx = self.infcx;
|
||||||
let placeholder_db_index =
|
let index = self.universe_indices.len() - debruijn.as_usize()
|
||||||
ty::DebruijnIndex::from_u32(self.current_index.as_u32() - debruijn.as_u32());
|
+ self.current_index.as_usize()
|
||||||
let universe = *self
|
- 1;
|
||||||
.universes
|
let universe = self.universe_indices[index].unwrap_or_else(|| {
|
||||||
.entry(placeholder_db_index)
|
for i in self.universe_indices.iter_mut().take(index + 1) {
|
||||||
.or_insert_with(|| infcx.create_next_universe());
|
*i = i.or_else(|| Some(infcx.create_next_universe()))
|
||||||
self.universes_inverse.insert(universe, placeholder_db_index);
|
}
|
||||||
|
self.universe_indices[index].unwrap()
|
||||||
|
});
|
||||||
let p = ty::PlaceholderType { universe, name: bound_ty.var };
|
let p = ty::PlaceholderType { universe, name: bound_ty.var };
|
||||||
self.mapped_types.insert(p.clone(), bound_ty);
|
self.mapped_types.insert(p.clone(), bound_ty);
|
||||||
self.infcx.tcx.mk_ty(ty::Placeholder(p))
|
self.infcx.tcx.mk_ty(ty::Placeholder(p))
|
||||||
@ -562,15 +610,26 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
|||||||
|
|
||||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
match *ct {
|
match *ct {
|
||||||
ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty } => {
|
ty::Const { val: ty::ConstKind::Bound(debruijn, _), ty: _ }
|
||||||
|
if debruijn.as_usize() + 1
|
||||||
|
> self.current_index.as_usize() + self.universe_indices.len() =>
|
||||||
|
{
|
||||||
|
self.failed = true;
|
||||||
|
ct
|
||||||
|
}
|
||||||
|
ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty }
|
||||||
|
if debruijn >= self.current_index =>
|
||||||
|
{
|
||||||
let infcx = self.infcx;
|
let infcx = self.infcx;
|
||||||
let placeholder_db_index =
|
let index = self.universe_indices.len() - debruijn.as_usize()
|
||||||
ty::DebruijnIndex::from_u32(self.current_index.as_u32() - debruijn.as_u32());
|
+ self.current_index.as_usize()
|
||||||
let universe = *self
|
- 1;
|
||||||
.universes
|
let universe = self.universe_indices[index].unwrap_or_else(|| {
|
||||||
.entry(placeholder_db_index)
|
for i in self.universe_indices.iter_mut().take(index + 1) {
|
||||||
.or_insert_with(|| infcx.create_next_universe());
|
*i = i.or_else(|| Some(infcx.create_next_universe()))
|
||||||
self.universes_inverse.insert(universe, placeholder_db_index);
|
}
|
||||||
|
self.universe_indices[index].unwrap()
|
||||||
|
});
|
||||||
let p = ty::PlaceholderConst {
|
let p = ty::PlaceholderConst {
|
||||||
universe,
|
universe,
|
||||||
name: ty::BoundConst { var: bound_const, ty },
|
name: ty::BoundConst { var: bound_const, ty },
|
||||||
@ -584,13 +643,14 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The inverse of `BoundVarReplacer`: replaces placeholders with the bound vars from which they came.
|
||||||
pub struct PlaceholderReplacer<'me, 'tcx> {
|
pub struct PlaceholderReplacer<'me, 'tcx> {
|
||||||
pub infcx: &'me InferCtxt<'me, 'tcx>,
|
infcx: &'me InferCtxt<'me, 'tcx>,
|
||||||
pub mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
|
mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
|
||||||
pub mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy>,
|
mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy>,
|
||||||
pub mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
|
mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
|
||||||
pub universes_inverse: BTreeMap<ty::UniverseIndex, ty::DebruijnIndex>,
|
universe_indices: &'me Vec<Option<ty::UniverseIndex>>,
|
||||||
pub current_index: ty::DebruijnIndex,
|
current_index: ty::DebruijnIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> {
|
impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> {
|
||||||
@ -599,7 +659,7 @@ impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> {
|
|||||||
mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
|
mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>,
|
||||||
mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy>,
|
mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy>,
|
||||||
mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
|
mapped_consts: BTreeMap<ty::PlaceholderConst<'tcx>, ty::BoundVar>,
|
||||||
universes_inverse: BTreeMap<ty::UniverseIndex, ty::DebruijnIndex>,
|
universe_indices: &'me Vec<Option<ty::UniverseIndex>>,
|
||||||
value: T,
|
value: T,
|
||||||
) -> T {
|
) -> T {
|
||||||
let mut replacer = PlaceholderReplacer {
|
let mut replacer = PlaceholderReplacer {
|
||||||
@ -607,7 +667,7 @@ impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> {
|
|||||||
mapped_regions,
|
mapped_regions,
|
||||||
mapped_types,
|
mapped_types,
|
||||||
mapped_consts,
|
mapped_consts,
|
||||||
universes_inverse,
|
universe_indices,
|
||||||
current_index: ty::INNERMOST,
|
current_index: ty::INNERMOST,
|
||||||
};
|
};
|
||||||
value.super_fold_with(&mut replacer)
|
value.super_fold_with(&mut replacer)
|
||||||
@ -648,13 +708,15 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
|||||||
let replace_var = self.mapped_regions.get(&p);
|
let replace_var = self.mapped_regions.get(&p);
|
||||||
match replace_var {
|
match replace_var {
|
||||||
Some(replace_var) => {
|
Some(replace_var) => {
|
||||||
let db = self
|
let index = self
|
||||||
.universes_inverse
|
.universe_indices
|
||||||
.get(&p.universe)
|
.iter()
|
||||||
|
.position(|u| matches!(u, Some(pu) if *pu == p.universe))
|
||||||
.unwrap_or_else(|| bug!("Unexpected placeholder universe."));
|
.unwrap_or_else(|| bug!("Unexpected placeholder universe."));
|
||||||
let index =
|
let db = ty::DebruijnIndex::from_usize(
|
||||||
ty::DebruijnIndex::from_u32(db.as_u32() + self.current_index.as_u32());
|
self.universe_indices.len() - index + self.current_index.as_usize() - 1,
|
||||||
self.tcx().mk_region(ty::ReLateBound(index, *replace_var))
|
);
|
||||||
|
self.tcx().mk_region(ty::ReLateBound(db, *replace_var))
|
||||||
}
|
}
|
||||||
None => r1,
|
None => r1,
|
||||||
}
|
}
|
||||||
@ -673,13 +735,15 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
|||||||
let replace_var = self.mapped_types.get(&p);
|
let replace_var = self.mapped_types.get(&p);
|
||||||
match replace_var {
|
match replace_var {
|
||||||
Some(replace_var) => {
|
Some(replace_var) => {
|
||||||
let db = self
|
let index = self
|
||||||
.universes_inverse
|
.universe_indices
|
||||||
.get(&p.universe)
|
.iter()
|
||||||
|
.position(|u| matches!(u, Some(pu) if *pu == p.universe))
|
||||||
.unwrap_or_else(|| bug!("Unexpected placeholder universe."));
|
.unwrap_or_else(|| bug!("Unexpected placeholder universe."));
|
||||||
let index =
|
let db = ty::DebruijnIndex::from_usize(
|
||||||
ty::DebruijnIndex::from_u32(db.as_u32() + self.current_index.as_u32());
|
self.universe_indices.len() - index + self.current_index.as_usize() - 1,
|
||||||
self.tcx().mk_ty(ty::Bound(index, *replace_var))
|
);
|
||||||
|
self.tcx().mk_ty(ty::Bound(db, *replace_var))
|
||||||
}
|
}
|
||||||
None => ty,
|
None => ty,
|
||||||
}
|
}
|
||||||
@ -695,14 +759,16 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
|||||||
let replace_var = self.mapped_consts.get(&p);
|
let replace_var = self.mapped_consts.get(&p);
|
||||||
match replace_var {
|
match replace_var {
|
||||||
Some(replace_var) => {
|
Some(replace_var) => {
|
||||||
let db = self
|
let index = self
|
||||||
.universes_inverse
|
.universe_indices
|
||||||
.get(&p.universe)
|
.iter()
|
||||||
|
.position(|u| matches!(u, Some(pu) if *pu == p.universe))
|
||||||
.unwrap_or_else(|| bug!("Unexpected placeholder universe."));
|
.unwrap_or_else(|| bug!("Unexpected placeholder universe."));
|
||||||
let index =
|
let db = ty::DebruijnIndex::from_usize(
|
||||||
ty::DebruijnIndex::from_u32(db.as_u32() + self.current_index.as_u32());
|
self.universe_indices.len() - index + self.current_index.as_usize() - 1,
|
||||||
|
);
|
||||||
self.tcx()
|
self.tcx()
|
||||||
.mk_const(ty::Const { val: ty::ConstKind::Bound(index, *replace_var), ty })
|
.mk_const(ty::Const { val: ty::ConstKind::Bound(db, *replace_var), ty })
|
||||||
}
|
}
|
||||||
None => ct,
|
None => ct,
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,7 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
|
|||||||
error: false,
|
error: false,
|
||||||
cache: SsoHashMap::new(),
|
cache: SsoHashMap::new(),
|
||||||
anon_depth: 0,
|
anon_depth: 0,
|
||||||
|
universes: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = value.fold_with(&mut normalizer);
|
let result = value.fold_with(&mut normalizer);
|
||||||
@ -91,6 +92,7 @@ struct QueryNormalizer<'cx, 'tcx> {
|
|||||||
cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>,
|
cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>,
|
||||||
error: bool,
|
error: bool,
|
||||||
anon_depth: usize,
|
anon_depth: usize,
|
||||||
|
universes: Vec<Option<ty::UniverseIndex>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||||
@ -98,6 +100,16 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||||
|
&mut self,
|
||||||
|
t: ty::Binder<'tcx, T>,
|
||||||
|
) -> ty::Binder<'tcx, T> {
|
||||||
|
self.universes.push(None);
|
||||||
|
let t = t.super_fold_with(self);
|
||||||
|
self.universes.pop();
|
||||||
|
t
|
||||||
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
if !ty.has_projections() {
|
if !ty.has_projections() {
|
||||||
@ -216,8 +228,19 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||||||
|
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
let infcx = self.infcx;
|
let infcx = self.infcx;
|
||||||
let (data, mapped_regions, mapped_types, mapped_consts, universe_map) =
|
let replaced = crate::traits::project::BoundVarReplacer::replace_bound_vars(
|
||||||
crate::traits::project::BoundVarReplacer::replace_bound_vars(infcx, data);
|
infcx,
|
||||||
|
&mut self.universes,
|
||||||
|
data,
|
||||||
|
);
|
||||||
|
let (data, mapped_regions, mapped_types, mapped_consts) = match replaced {
|
||||||
|
Some(r) => r,
|
||||||
|
None => {
|
||||||
|
bug!("{:?} {:?}", data, self.universes);
|
||||||
|
//self.error = true;
|
||||||
|
//return ty.super_fold_with(self);
|
||||||
|
}
|
||||||
|
};
|
||||||
let data = data.super_fold_with(self);
|
let data = data.super_fold_with(self);
|
||||||
|
|
||||||
let mut orig_values = OriginalQueryValues::default();
|
let mut orig_values = OriginalQueryValues::default();
|
||||||
@ -263,7 +286,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||||||
mapped_regions,
|
mapped_regions,
|
||||||
mapped_types,
|
mapped_types,
|
||||||
mapped_consts,
|
mapped_consts,
|
||||||
universe_map,
|
&self.universes,
|
||||||
normalized_ty,
|
normalized_ty,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user