Split Bound into Canonical and Bound
This commit is contained in:
@@ -278,7 +278,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
|
||||
mut map: impl FnMut(ty::RegionVid) -> ty::Region<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
fold_regions(tcx, self.inner, |r, depth| match r.kind() {
|
||||
ty::ReBound(debruijn, br) => {
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br) => {
|
||||
debug_assert_eq!(debruijn, depth);
|
||||
map(ty::RegionVid::from_usize(br.var.index()))
|
||||
}
|
||||
|
||||
@@ -174,21 +174,25 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>(
|
||||
for (param, var) in std::iter::zip(&generics.own_params, gat_vars) {
|
||||
let existing = match var.kind() {
|
||||
ty::GenericArgKind::Lifetime(re) => {
|
||||
if let ty::RegionKind::ReBound(ty::INNERMOST, bv) = re.kind() {
|
||||
if let ty::RegionKind::ReBound(ty::BoundVarIndexKind::Bound(ty::INNERMOST), bv) =
|
||||
re.kind()
|
||||
{
|
||||
mapping.insert(bv.var, tcx.mk_param_from_def(param))
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
ty::GenericArgKind::Type(ty) => {
|
||||
if let ty::Bound(ty::INNERMOST, bv) = *ty.kind() {
|
||||
if let ty::Bound(ty::BoundVarIndexKind::Bound(ty::INNERMOST), bv) = *ty.kind() {
|
||||
mapping.insert(bv.var, tcx.mk_param_from_def(param))
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
ty::GenericArgKind::Const(ct) => {
|
||||
if let ty::ConstKind::Bound(ty::INNERMOST, bv) = ct.kind() {
|
||||
if let ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(ty::INNERMOST), bv) =
|
||||
ct.kind()
|
||||
{
|
||||
mapping.insert(bv.var, tcx.mk_param_from_def(param))
|
||||
} else {
|
||||
return None;
|
||||
@@ -253,7 +257,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
|
||||
return ty;
|
||||
}
|
||||
|
||||
if let ty::Bound(binder, old_bound) = *ty.kind()
|
||||
if let ty::Bound(ty::BoundVarIndexKind::Bound(binder), old_bound) = *ty.kind()
|
||||
&& self.binder == binder
|
||||
{
|
||||
let mapped = if let Some(mapped) = self.mapping.get(&old_bound.var) {
|
||||
@@ -279,7 +283,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, re: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
if let ty::ReBound(binder, old_bound) = re.kind()
|
||||
if let ty::ReBound(ty::BoundVarIndexKind::Bound(binder), old_bound) = re.kind()
|
||||
&& self.binder == binder
|
||||
{
|
||||
let mapped = if let Some(mapped) = self.mapping.get(&old_bound.var) {
|
||||
@@ -307,7 +311,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
|
||||
return ct;
|
||||
}
|
||||
|
||||
if let ty::ConstKind::Bound(binder, old_bound) = ct.kind()
|
||||
if let ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(binder), old_bound) = ct.kind()
|
||||
&& self.binder == binder
|
||||
{
|
||||
let mapped = if let Some(mapped) = self.mapping.get(&old_bound.var) {
|
||||
|
||||
@@ -915,7 +915,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 't
|
||||
ty::Param(param) => {
|
||||
self.params.insert(param.index);
|
||||
}
|
||||
ty::Bound(db, bt) if *db >= self.depth => {
|
||||
ty::Bound(ty::BoundVarIndexKind::Bound(db), bt) if *db >= self.depth => {
|
||||
self.vars.insert(match bt.kind {
|
||||
ty::BoundTyKind::Param(def_id) => def_id,
|
||||
ty::BoundTyKind::Anon => {
|
||||
@@ -938,7 +938,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 't
|
||||
ty::ReEarlyParam(param) => {
|
||||
self.params.insert(param.index);
|
||||
}
|
||||
ty::ReBound(db, br) if db >= self.depth => {
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(db), br) if db >= self.depth => {
|
||||
self.vars.insert(match br.kind {
|
||||
ty::BoundRegionKind::Named(def_id) => def_id,
|
||||
ty::BoundRegionKind::Anon | ty::BoundRegionKind::ClosureEnv => {
|
||||
@@ -961,7 +961,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 't
|
||||
ty::ConstKind::Param(param) => {
|
||||
self.params.insert(param.index);
|
||||
}
|
||||
ty::ConstKind::Bound(db, _) if db >= self.depth => {
|
||||
ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(db), _) if db >= self.depth => {
|
||||
let guar = self.cx.dcx().delayed_bug("unexpected escaping late-bound const var");
|
||||
return ControlFlow::Break(guar);
|
||||
}
|
||||
|
||||
@@ -303,8 +303,6 @@ struct Canonicalizer<'cx, 'tcx> {
|
||||
sub_root_lookup_table: SsoHashMap<ty::TyVid, usize>,
|
||||
canonicalize_mode: &'cx dyn CanonicalizeMode,
|
||||
needs_canonical_flags: TypeFlags,
|
||||
|
||||
binder_index: ty::DebruijnIndex,
|
||||
}
|
||||
|
||||
impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
||||
@@ -312,24 +310,12 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
|
||||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
self.binder_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.binder_index.shift_out(1);
|
||||
t
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
match r.kind() {
|
||||
ty::ReBound(index, ..) => {
|
||||
if index >= self.binder_index {
|
||||
bug!("escaping late-bound region during canonicalization");
|
||||
} else {
|
||||
r
|
||||
}
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(_), ..) => r,
|
||||
|
||||
ty::ReBound(ty::BoundVarIndexKind::Canonical, _) => {
|
||||
bug!("canonicalized bound var found during canonicalization");
|
||||
}
|
||||
|
||||
ty::ReStatic
|
||||
@@ -403,12 +389,10 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
||||
self.canonicalize_ty_var(CanonicalVarKind::PlaceholderTy(placeholder), t)
|
||||
}
|
||||
|
||||
ty::Bound(debruijn, _) => {
|
||||
if debruijn >= self.binder_index {
|
||||
bug!("escaping bound type during canonicalization")
|
||||
} else {
|
||||
t
|
||||
}
|
||||
ty::Bound(ty::BoundVarIndexKind::Bound(_), _) => t,
|
||||
|
||||
ty::Bound(ty::BoundVarIndexKind::Canonical, _) => {
|
||||
bug!("canonicalized bound var found during canonicalization");
|
||||
}
|
||||
|
||||
ty::Closure(..)
|
||||
@@ -479,12 +463,11 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
||||
ty::ConstKind::Infer(InferConst::Fresh(_)) => {
|
||||
bug!("encountered a fresh const during canonicalization")
|
||||
}
|
||||
ty::ConstKind::Bound(debruijn, _) => {
|
||||
if debruijn >= self.binder_index {
|
||||
bug!("escaping bound const during canonicalization")
|
||||
} else {
|
||||
ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(_), _) => {
|
||||
return ct;
|
||||
}
|
||||
ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, _) => {
|
||||
bug!("canonicalized bound var found during canonicalization");
|
||||
}
|
||||
ty::ConstKind::Placeholder(placeholder) => {
|
||||
return self
|
||||
@@ -569,7 +552,6 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||
query_state,
|
||||
indices: FxHashMap::default(),
|
||||
sub_root_lookup_table: Default::default(),
|
||||
binder_index: ty::INNERMOST,
|
||||
};
|
||||
if canonicalizer.query_state.var_values.spilled() {
|
||||
canonicalizer.indices = canonicalizer
|
||||
@@ -751,8 +733,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||
r: ty::Region<'tcx>,
|
||||
) -> ty::Region<'tcx> {
|
||||
let var = self.canonical_var(var_kind, r.into());
|
||||
let br = ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon };
|
||||
ty::Region::new_bound(self.cx(), self.binder_index, br)
|
||||
ty::Region::new_canonical_bound(self.cx(), var)
|
||||
}
|
||||
|
||||
/// Given a type variable `ty_var` of the given kind, first check
|
||||
@@ -766,8 +747,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||
) -> Ty<'tcx> {
|
||||
debug_assert!(!self.infcx.is_some_and(|infcx| ty_var != infcx.shallow_resolve(ty_var)));
|
||||
let var = self.canonical_var(var_kind, ty_var.into());
|
||||
let bt = ty::BoundTy { var, kind: ty::BoundTyKind::Anon };
|
||||
Ty::new_bound(self.tcx, self.binder_index, bt)
|
||||
Ty::new_canonical_bound(self.tcx, var)
|
||||
}
|
||||
|
||||
/// Given a type variable `const_var` of the given kind, first check
|
||||
@@ -783,7 +763,6 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||
!self.infcx.is_some_and(|infcx| ct_var != infcx.shallow_resolve_const(ct_var))
|
||||
);
|
||||
let var = self.canonical_var(var_kind, ct_var.into());
|
||||
let bc = ty::BoundConst { var };
|
||||
ty::Const::new_bound(self.tcx, self.binder_index, bc)
|
||||
ty::Const::new_canonical_bound(self.tcx, var)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use rustc_middle::ty::{
|
||||
self, DelayedMap, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable,
|
||||
TypeVisitableExt, TypeVisitor,
|
||||
};
|
||||
use rustc_type_ir::TypeVisitable;
|
||||
use rustc_type_ir::{TypeFlags, TypeVisitable};
|
||||
|
||||
use crate::infer::canonical::{Canonical, CanonicalVarValues};
|
||||
|
||||
@@ -66,7 +66,6 @@ where
|
||||
|
||||
value.fold_with(&mut CanonicalInstantiator {
|
||||
tcx,
|
||||
current_index: ty::INNERMOST,
|
||||
var_values: var_values.var_values,
|
||||
cache: Default::default(),
|
||||
})
|
||||
@@ -79,12 +78,9 @@ struct CanonicalInstantiator<'tcx> {
|
||||
// The values that the bound vars are are being instantiated with.
|
||||
var_values: ty::GenericArgsRef<'tcx>,
|
||||
|
||||
/// As with `BoundVarReplacer`, represents the index of a binder *just outside*
|
||||
/// the ones we have visited.
|
||||
current_index: ty::DebruijnIndex,
|
||||
|
||||
// Instantiation is a pure function of `DebruijnIndex` and `Ty`.
|
||||
cache: DelayedMap<(ty::DebruijnIndex, Ty<'tcx>), Ty<'tcx>>,
|
||||
// Because we use `ty::BoundVarIndexKind::Canonical`, we can cache
|
||||
// based only on the entire ty, not worrying about a `DebruijnIndex`
|
||||
cache: DelayedMap<Ty<'tcx>, Ty<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for CanonicalInstantiator<'tcx> {
|
||||
@@ -92,29 +88,19 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for CanonicalInstantiator<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
t
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match *t.kind() {
|
||||
ty::Bound(debruijn, bound_ty) if debruijn == self.current_index => {
|
||||
ty::Bound(ty::BoundVarIndexKind::Canonical, bound_ty) => {
|
||||
self.var_values[bound_ty.var.as_usize()].expect_ty()
|
||||
}
|
||||
_ => {
|
||||
if !t.has_vars_bound_at_or_above(self.current_index) {
|
||||
if !t.has_type_flags(TypeFlags::HAS_CANONICAL_BOUND) {
|
||||
t
|
||||
} else if let Some(&t) = self.cache.get(&(self.current_index, t)) {
|
||||
} else if let Some(&t) = self.cache.get(&t) {
|
||||
t
|
||||
} else {
|
||||
let res = t.super_fold_with(self);
|
||||
assert!(self.cache.insert((self.current_index, t), res));
|
||||
assert!(self.cache.insert(t, res));
|
||||
res
|
||||
}
|
||||
}
|
||||
@@ -123,7 +109,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for CanonicalInstantiator<'tcx> {
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
match r.kind() {
|
||||
ty::ReBound(debruijn, br) if debruijn == self.current_index => {
|
||||
ty::ReBound(ty::BoundVarIndexKind::Canonical, br) => {
|
||||
self.var_values[br.var.as_usize()].expect_region()
|
||||
}
|
||||
_ => r,
|
||||
@@ -132,7 +118,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for CanonicalInstantiator<'tcx> {
|
||||
|
||||
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||
match ct.kind() {
|
||||
ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.current_index => {
|
||||
ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, bound_const) => {
|
||||
self.var_values[bound_const.var.as_usize()].expect_const()
|
||||
}
|
||||
_ => ct.super_fold_with(self),
|
||||
@@ -140,22 +126,14 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for CanonicalInstantiator<'tcx> {
|
||||
}
|
||||
|
||||
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
|
||||
if p.has_vars_bound_at_or_above(self.current_index) { p.super_fold_with(self) } else { p }
|
||||
if p.has_type_flags(TypeFlags::HAS_CANONICAL_BOUND) { p.super_fold_with(self) } else { p }
|
||||
}
|
||||
|
||||
fn fold_clauses(&mut self, c: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> {
|
||||
if !c.has_vars_bound_at_or_above(self.current_index) {
|
||||
if !c.has_type_flags(TypeFlags::HAS_CANONICAL_BOUND) {
|
||||
return c;
|
||||
}
|
||||
|
||||
// Since instantiation is a function of `DebruijnIndex`, we don't want
|
||||
// to have to cache more copies of clauses when we're inside of binders.
|
||||
// Since we currently expect to only have clauses in the outermost
|
||||
// debruijn index, we just fold if we're inside of a binder.
|
||||
if self.current_index > ty::INNERMOST {
|
||||
return c.super_fold_with(self);
|
||||
}
|
||||
|
||||
// Our cache key is `(clauses, var_values)`, but we also don't care about
|
||||
// var values that aren't named in the clauses, since they can change without
|
||||
// affecting the output. Since `ParamEnv`s are cached first, we compute the
|
||||
@@ -185,45 +163,29 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for CanonicalInstantiator<'tcx> {
|
||||
fn highest_var_in_clauses<'tcx>(c: ty::Clauses<'tcx>) -> usize {
|
||||
struct HighestVarInClauses {
|
||||
max_var: usize,
|
||||
current_index: ty::DebruijnIndex,
|
||||
}
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HighestVarInClauses {
|
||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
|
||||
&mut self,
|
||||
t: &ty::Binder<'tcx, T>,
|
||||
) -> Self::Result {
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_visit_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
t
|
||||
}
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
||||
if let ty::Bound(debruijn, bound_ty) = *t.kind()
|
||||
&& debruijn == self.current_index
|
||||
{
|
||||
if let ty::Bound(ty::BoundVarIndexKind::Canonical, bound_ty) = *t.kind() {
|
||||
self.max_var = self.max_var.max(bound_ty.var.as_usize());
|
||||
} else if t.has_vars_bound_at_or_above(self.current_index) {
|
||||
} else if t.has_type_flags(TypeFlags::HAS_CANONICAL_BOUND) {
|
||||
t.super_visit_with(self);
|
||||
}
|
||||
}
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||
if let ty::ReBound(debruijn, bound_region) = r.kind()
|
||||
&& debruijn == self.current_index
|
||||
{
|
||||
if let ty::ReBound(ty::BoundVarIndexKind::Canonical, bound_region) = r.kind() {
|
||||
self.max_var = self.max_var.max(bound_region.var.as_usize());
|
||||
}
|
||||
}
|
||||
fn visit_const(&mut self, ct: ty::Const<'tcx>) {
|
||||
if let ty::ConstKind::Bound(debruijn, bound_const) = ct.kind()
|
||||
&& debruijn == self.current_index
|
||||
{
|
||||
if let ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, bound_const) = ct.kind() {
|
||||
self.max_var = self.max_var.max(bound_const.var.as_usize());
|
||||
} else if ct.has_vars_bound_at_or_above(self.current_index) {
|
||||
} else if ct.has_type_flags(TypeFlags::HAS_CANONICAL_BOUND) {
|
||||
ct.super_visit_with(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut visitor = HighestVarInClauses { max_var: 0, current_index: ty::INNERMOST };
|
||||
let mut visitor = HighestVarInClauses { max_var: 0 };
|
||||
c.visit_with(&mut visitor);
|
||||
visitor.max_var
|
||||
}
|
||||
|
||||
@@ -422,28 +422,28 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
// and only use it for placeholders. We need to handle the
|
||||
// `sub_root` of type inference variables which would make this
|
||||
// more involved. They are also a lot rarer than region variables.
|
||||
if let ty::Bound(debruijn, b) = *result_value.kind()
|
||||
if let ty::Bound(index_kind, b) = *result_value.kind()
|
||||
&& !matches!(
|
||||
query_response.variables[b.var.as_usize()],
|
||||
CanonicalVarKind::Ty { .. }
|
||||
)
|
||||
{
|
||||
// We only allow a `ty::INNERMOST` index in generic parameters.
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
// We only allow a `Canonical` index in generic parameters.
|
||||
assert!(matches!(index_kind, ty::BoundVarIndexKind::Canonical));
|
||||
opt_values[b.var] = Some(*original_value);
|
||||
}
|
||||
}
|
||||
GenericArgKind::Lifetime(result_value) => {
|
||||
if let ty::ReBound(debruijn, b) = result_value.kind() {
|
||||
// We only allow a `ty::INNERMOST` index in generic parameters.
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
if let ty::ReBound(index_kind, b) = result_value.kind() {
|
||||
// We only allow a `Canonical` index in generic parameters.
|
||||
assert!(matches!(index_kind, ty::BoundVarIndexKind::Canonical));
|
||||
opt_values[b.var] = Some(*original_value);
|
||||
}
|
||||
}
|
||||
GenericArgKind::Const(result_value) => {
|
||||
if let ty::ConstKind::Bound(debruijn, b) = result_value.kind() {
|
||||
// We only allow a `ty::INNERMOST` index in generic parameters.
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
if let ty::ConstKind::Bound(index_kind, b) = result_value.kind() {
|
||||
// We only allow a `Canonical` index in generic parameters.
|
||||
assert!(matches!(index_kind, ty::BoundVarIndexKind::Canonical));
|
||||
opt_values[b.var] = Some(*original_value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ pub fn extract_verify_if_eq<'tcx>(
|
||||
let verify_if_eq = verify_if_eq_b.skip_binder();
|
||||
m.relate(verify_if_eq.ty, test_ty).ok()?;
|
||||
|
||||
if let ty::RegionKind::ReBound(depth, br) = verify_if_eq.bound.kind() {
|
||||
assert!(depth == ty::INNERMOST);
|
||||
if let ty::RegionKind::ReBound(index_kind, br) = verify_if_eq.bound.kind() {
|
||||
assert!(matches!(index_kind, ty::BoundVarIndexKind::Bound(ty::INNERMOST)));
|
||||
match m.map.get(&br) {
|
||||
Some(&r) => Some(r),
|
||||
None => {
|
||||
@@ -156,7 +156,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for MatchAgainstHigherRankedOutlives<'tcx>
|
||||
pattern: ty::Region<'tcx>,
|
||||
value: ty::Region<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||
if let ty::RegionKind::ReBound(depth, br) = pattern.kind()
|
||||
if let ty::RegionKind::ReBound(ty::BoundVarIndexKind::Bound(depth), br) = pattern.kind()
|
||||
&& depth == self.pattern_depth
|
||||
{
|
||||
self.bind(br, value)
|
||||
|
||||
@@ -95,7 +95,15 @@ impl<'tcx> Const<'tcx> {
|
||||
debruijn: ty::DebruijnIndex,
|
||||
bound_const: ty::BoundConst,
|
||||
) -> Const<'tcx> {
|
||||
Const::new(tcx, ty::ConstKind::Bound(debruijn, bound_const))
|
||||
Const::new(tcx, ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_const))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: ty::BoundVar) -> Const<'tcx> {
|
||||
Const::new(
|
||||
tcx,
|
||||
ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, ty::BoundConst { var }),
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -180,6 +188,10 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
|
||||
Const::new_bound(tcx, debruijn, ty::BoundConst { var })
|
||||
}
|
||||
|
||||
fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: rustc_type_ir::BoundVar) -> Self {
|
||||
Const::new_canonical_bound(tcx, var)
|
||||
}
|
||||
|
||||
fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderConst) -> Self {
|
||||
Const::new_placeholder(tcx, placeholder)
|
||||
}
|
||||
|
||||
@@ -1110,6 +1110,15 @@ const NUM_PREINTERNED_FRESH_TYS: u32 = 20;
|
||||
const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3;
|
||||
const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3;
|
||||
const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3;
|
||||
|
||||
// From general profiling of the *max vars during canonicalization* of a value:
|
||||
// - about 90% of the time, there are no canonical vars
|
||||
// - about 9% of the time, there is only one canonical var
|
||||
// - there are rarely more than 3-5 canonical vars (with exceptions in particularly pathological cases)
|
||||
// This may not match the number of bound vars found in `for`s.
|
||||
// Given that this is all heap interned, it seems likely that interning fewer
|
||||
// vars here won't make an appreciable difference. Though, if we were to inline the data (in an array),
|
||||
// we may want to consider reducing the number for canonicalized vars down to 4 or so.
|
||||
const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20;
|
||||
|
||||
// This number may seem high, but it is reached in all but the smallest crates.
|
||||
@@ -1160,9 +1169,14 @@ pub struct CommonTypes<'tcx> {
|
||||
pub fresh_float_tys: Vec<Ty<'tcx>>,
|
||||
|
||||
/// Pre-interned values of the form:
|
||||
/// `Bound(DebruijnIndex(i), BoundTy { var: v, kind: BoundTyKind::Anon})`
|
||||
/// `Bound(BoundVarIndexKind::Bound(DebruijnIndex(i)), BoundTy { var: v, kind: BoundTyKind::Anon})`
|
||||
/// for small values of `i` and `v`.
|
||||
pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>,
|
||||
|
||||
// Pre-interned values of the form:
|
||||
// `Bound(BoundVarIndexKind::Canonical, BoundTy { var: v, kind: BoundTyKind::Anon })`
|
||||
// for small values of `v`.
|
||||
pub anon_canonical_bound_tys: Vec<Ty<'tcx>>,
|
||||
}
|
||||
|
||||
pub struct CommonLifetimes<'tcx> {
|
||||
@@ -1176,9 +1190,14 @@ pub struct CommonLifetimes<'tcx> {
|
||||
pub re_vars: Vec<Region<'tcx>>,
|
||||
|
||||
/// Pre-interned values of the form:
|
||||
/// `ReBound(DebruijnIndex(i), BoundRegion { var: v, kind: BoundRegionKind::Anon })`
|
||||
/// `ReBound(BoundVarIndexKind::Bound(DebruijnIndex(i)), BoundRegion { var: v, kind: BoundRegionKind::Anon })`
|
||||
/// for small values of `i` and `v`.
|
||||
pub anon_re_bounds: Vec<Vec<Region<'tcx>>>,
|
||||
|
||||
// Pre-interned values of the form:
|
||||
// `ReBound(BoundVarIndexKind::Canonical, BoundRegion { var: v, kind: BoundRegionKind::Anon })`
|
||||
// for small values of `v`.
|
||||
pub anon_re_canonical_bounds: Vec<Region<'tcx>>,
|
||||
}
|
||||
|
||||
pub struct CommonConsts<'tcx> {
|
||||
@@ -1211,7 +1230,7 @@ impl<'tcx> CommonTypes<'tcx> {
|
||||
(0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
|
||||
.map(|v| {
|
||||
mk(ty::Bound(
|
||||
ty::DebruijnIndex::from(i),
|
||||
ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
|
||||
ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
|
||||
))
|
||||
})
|
||||
@@ -1219,6 +1238,15 @@ impl<'tcx> CommonTypes<'tcx> {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let anon_canonical_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_V)
|
||||
.map(|v| {
|
||||
mk(ty::Bound(
|
||||
ty::BoundVarIndexKind::Canonical,
|
||||
ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon },
|
||||
))
|
||||
})
|
||||
.collect();
|
||||
|
||||
CommonTypes {
|
||||
unit: mk(Tuple(List::empty())),
|
||||
bool: mk(Bool),
|
||||
@@ -1250,6 +1278,7 @@ impl<'tcx> CommonTypes<'tcx> {
|
||||
fresh_int_tys,
|
||||
fresh_float_tys,
|
||||
anon_bound_tys,
|
||||
anon_canonical_bound_tys,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1270,7 +1299,7 @@ impl<'tcx> CommonLifetimes<'tcx> {
|
||||
(0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
|
||||
.map(|v| {
|
||||
mk(ty::ReBound(
|
||||
ty::DebruijnIndex::from(i),
|
||||
ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)),
|
||||
ty::BoundRegion {
|
||||
var: ty::BoundVar::from(v),
|
||||
kind: ty::BoundRegionKind::Anon,
|
||||
@@ -1281,11 +1310,21 @@ impl<'tcx> CommonLifetimes<'tcx> {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let anon_re_canonical_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V)
|
||||
.map(|v| {
|
||||
mk(ty::ReBound(
|
||||
ty::BoundVarIndexKind::Canonical,
|
||||
ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BoundRegionKind::Anon },
|
||||
))
|
||||
})
|
||||
.collect();
|
||||
|
||||
CommonLifetimes {
|
||||
re_static: mk(ty::ReStatic),
|
||||
re_erased: mk(ty::ReErased),
|
||||
re_vars,
|
||||
anon_re_bounds,
|
||||
anon_re_canonical_bounds,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,9 @@ where
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match *t.kind() {
|
||||
ty::Bound(debruijn, bound_ty) if debruijn == self.current_index => {
|
||||
ty::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_ty)
|
||||
if debruijn == self.current_index =>
|
||||
{
|
||||
let ty = self.delegate.replace_ty(bound_ty);
|
||||
debug_assert!(!ty.has_vars_bound_above(ty::INNERMOST));
|
||||
ty::shift_vars(self.tcx, ty, self.current_index.as_u32())
|
||||
@@ -146,9 +148,11 @@ where
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
match r.kind() {
|
||||
ty::ReBound(debruijn, br) if debruijn == self.current_index => {
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br)
|
||||
if debruijn == self.current_index =>
|
||||
{
|
||||
let region = self.delegate.replace_region(br);
|
||||
if let ty::ReBound(debruijn1, br) = region.kind() {
|
||||
if let ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn1), br) = region.kind() {
|
||||
// If the callback returns a bound region,
|
||||
// that region should always use the INNERMOST
|
||||
// debruijn index. Then we adjust it to the
|
||||
@@ -165,7 +169,9 @@ where
|
||||
|
||||
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||
match ct.kind() {
|
||||
ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.current_index => {
|
||||
ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_const)
|
||||
if debruijn == self.current_index =>
|
||||
{
|
||||
let ct = self.delegate.replace_const(bound_const);
|
||||
debug_assert!(!ct.has_vars_bound_above(ty::INNERMOST));
|
||||
ty::shift_vars(self.tcx, ct, self.current_index.as_u32())
|
||||
|
||||
@@ -2664,7 +2664,7 @@ impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
let name = &mut self.name;
|
||||
let region = match r.kind() {
|
||||
ty::ReBound(db, br) if db >= self.current_index => {
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(db), br) if db >= self.current_index => {
|
||||
*self.region_map.entry(br).or_insert_with(|| name(Some(db), self.current_index, br))
|
||||
}
|
||||
ty::RePlaceholder(ty::PlaceholderRegion {
|
||||
@@ -2687,7 +2687,7 @@ impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
|
||||
}
|
||||
_ => return r,
|
||||
};
|
||||
if let ty::ReBound(debruijn1, br) = region.kind() {
|
||||
if let ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn1), br) = region.kind() {
|
||||
assert_eq!(debruijn1, ty::INNERMOST);
|
||||
ty::Region::new_bound(self.tcx, self.current_index, br)
|
||||
} else {
|
||||
|
||||
@@ -31,7 +31,7 @@ impl<'tcx> rustc_type_ir::Flags for Region<'tcx> {
|
||||
|
||||
fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
|
||||
match self.kind() {
|
||||
ty::ReBound(debruijn, _) => debruijn.shifted_in(1),
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) => debruijn.shifted_in(1),
|
||||
_ => ty::INNERMOST,
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,20 @@ impl<'tcx> Region<'tcx> {
|
||||
{
|
||||
re
|
||||
} else {
|
||||
tcx.intern_region(ty::ReBound(debruijn, bound_region))
|
||||
tcx.intern_region(ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), bound_region))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: ty::BoundVar) -> Region<'tcx> {
|
||||
// Use a pre-interned one when possible.
|
||||
if let Some(re) = tcx.lifetimes.anon_re_canonical_bounds.get(var.as_usize()).copied() {
|
||||
re
|
||||
} else {
|
||||
tcx.intern_region(ty::ReBound(
|
||||
ty::BoundVarIndexKind::Canonical,
|
||||
ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon },
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +135,12 @@ impl<'tcx> Region<'tcx> {
|
||||
pub fn new_from_kind(tcx: TyCtxt<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> {
|
||||
match kind {
|
||||
ty::ReEarlyParam(region) => Region::new_early_param(tcx, region),
|
||||
ty::ReBound(debruijn, region) => Region::new_bound(tcx, debruijn, region),
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), region) => {
|
||||
Region::new_bound(tcx, debruijn, region)
|
||||
}
|
||||
ty::ReBound(ty::BoundVarIndexKind::Canonical, region) => {
|
||||
Region::new_canonical_bound(tcx, region.var)
|
||||
}
|
||||
ty::ReLateParam(ty::LateParamRegion { scope, kind }) => {
|
||||
Region::new_late_param(tcx, scope, kind)
|
||||
}
|
||||
@@ -148,6 +166,10 @@ impl<'tcx> rustc_type_ir::inherent::Region<TyCtxt<'tcx>> for Region<'tcx> {
|
||||
Region::new_bound(tcx, debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon })
|
||||
}
|
||||
|
||||
fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: rustc_type_ir::BoundVar) -> Self {
|
||||
Region::new_canonical_bound(tcx, var)
|
||||
}
|
||||
|
||||
fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderRegion) -> Self {
|
||||
Region::new_placeholder(tcx, placeholder)
|
||||
}
|
||||
@@ -223,7 +245,7 @@ impl<'tcx> Region<'tcx> {
|
||||
#[inline]
|
||||
pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool {
|
||||
match self.kind() {
|
||||
ty::ReBound(debruijn, _) => debruijn >= index,
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) => debruijn >= index,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@@ -254,7 +276,11 @@ impl<'tcx> Region<'tcx> {
|
||||
ty::ReStatic => {
|
||||
flags = flags | TypeFlags::HAS_FREE_REGIONS;
|
||||
}
|
||||
ty::ReBound(..) => {
|
||||
ty::ReBound(ty::BoundVarIndexKind::Canonical, _) => {
|
||||
flags = flags | TypeFlags::HAS_RE_BOUND;
|
||||
flags = flags | TypeFlags::HAS_CANONICAL_BOUND;
|
||||
}
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(..), _) => {
|
||||
flags = flags | TypeFlags::HAS_RE_BOUND;
|
||||
}
|
||||
ty::ReErased => {
|
||||
|
||||
@@ -487,7 +487,23 @@ impl<'tcx> Ty<'tcx> {
|
||||
{
|
||||
ty
|
||||
} else {
|
||||
Ty::new(tcx, Bound(index, bound_ty))
|
||||
Ty::new(tcx, Bound(ty::BoundVarIndexKind::Bound(index), bound_ty))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: BoundVar) -> Ty<'tcx> {
|
||||
// Use a pre-interned one when possible.
|
||||
if let Some(ty) = tcx.types.anon_canonical_bound_tys.get(var.as_usize()).copied() {
|
||||
ty
|
||||
} else {
|
||||
Ty::new(
|
||||
tcx,
|
||||
Bound(
|
||||
ty::BoundVarIndexKind::Canonical,
|
||||
ty::BoundTy { var, kind: ty::BoundTyKind::Anon },
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -952,6 +968,10 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
|
||||
Ty::new_bound(tcx, debruijn, ty::BoundTy { var, kind: ty::BoundTyKind::Anon })
|
||||
}
|
||||
|
||||
fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: ty::BoundVar) -> Self {
|
||||
Ty::new_canonical_bound(tcx, var)
|
||||
}
|
||||
|
||||
fn new_alias(
|
||||
interner: TyCtxt<'tcx>,
|
||||
kind: ty::AliasTyKind,
|
||||
|
||||
@@ -798,8 +798,8 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
|
||||
match arg.kind() {
|
||||
GenericArgKind::Type(ty) => match ty.kind() {
|
||||
ty::Bound(debruijn, b) => {
|
||||
// We only allow a `ty::INNERMOST` index in generic parameters.
|
||||
assert_eq!(*debruijn, ty::INNERMOST);
|
||||
// We only allow a `ty::BoundVarIndexKind::Canonical` index in generic parameters.
|
||||
assert_eq!(*debruijn, ty::BoundVarIndexKind::Canonical);
|
||||
cvar == b.var
|
||||
}
|
||||
_ => false,
|
||||
@@ -807,8 +807,8 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
|
||||
|
||||
GenericArgKind::Lifetime(r) => match r.kind() {
|
||||
ty::ReBound(debruijn, b) => {
|
||||
// We only allow a `ty::INNERMOST` index in generic parameters.
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
// We only allow a `ty::BoundVarIndexKind::Canonical` index in generic parameters.
|
||||
assert_eq!(debruijn, ty::BoundVarIndexKind::Canonical);
|
||||
cvar == b.var
|
||||
}
|
||||
_ => false,
|
||||
@@ -816,8 +816,8 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
|
||||
|
||||
GenericArgKind::Const(ct) => match ct.kind() {
|
||||
ty::ConstKind::Bound(debruijn, b) => {
|
||||
// We only allow a `ty::INNERMOST` index in generic parameters.
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
// We only allow a `ty::BoundVarIndexKind::Canonical` index in generic parameters.
|
||||
assert_eq!(debruijn, ty::BoundVarIndexKind::Canonical);
|
||||
cvar == b.var
|
||||
}
|
||||
_ => false,
|
||||
|
||||
@@ -78,7 +78,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result {
|
||||
match r.kind() {
|
||||
ty::ReBound(debruijn, _) if debruijn < self.outer_index => {
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _)
|
||||
if debruijn < self.outer_index =>
|
||||
{
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
_ => {
|
||||
@@ -205,7 +207,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for LateBoundRegionsCollector {
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||
if let ty::ReBound(debruijn, br) = r.kind() {
|
||||
if let ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br) = r.kind() {
|
||||
if debruijn == self.current_index {
|
||||
self.regions.insert(br.kind);
|
||||
}
|
||||
|
||||
@@ -74,12 +74,10 @@ pub(super) struct Canonicalizer<'a, D: SolverDelegate<Interner = I>, I: Interner
|
||||
/// we set the `sub_root` of the second variable to the position of the first.
|
||||
/// Otherwise the `sub_root` of each type variable is just its own position.
|
||||
sub_root_lookup_table: HashMap<ty::TyVid, usize>,
|
||||
binder_index: ty::DebruijnIndex,
|
||||
|
||||
/// We only use the debruijn index during lookup. We don't need to
|
||||
/// track the `variables` as each generic arg only results in a single
|
||||
/// bound variable regardless of how many times it is encountered.
|
||||
cache: HashMap<(ty::DebruijnIndex, I::Ty), I::Ty>,
|
||||
/// We can simply cache based on the ty itself, because we use
|
||||
/// `ty::BoundVarIndexKind::Canonical`.
|
||||
cache: HashMap<I::Ty, I::Ty>,
|
||||
}
|
||||
|
||||
impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
||||
@@ -97,7 +95,6 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
||||
variable_lookup_table: Default::default(),
|
||||
sub_root_lookup_table: Default::default(),
|
||||
var_kinds: Vec::new(),
|
||||
binder_index: ty::INNERMOST,
|
||||
|
||||
cache: Default::default(),
|
||||
};
|
||||
@@ -141,12 +138,10 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
||||
variable_lookup_table: Default::default(),
|
||||
sub_root_lookup_table: Default::default(),
|
||||
var_kinds: Vec::new(),
|
||||
binder_index: ty::INNERMOST,
|
||||
|
||||
cache: Default::default(),
|
||||
};
|
||||
let param_env = param_env.fold_with(&mut env_canonicalizer);
|
||||
debug_assert_eq!(env_canonicalizer.binder_index, ty::INNERMOST);
|
||||
debug_assert!(env_canonicalizer.sub_root_lookup_table.is_empty());
|
||||
CanonicalParamEnvCacheEntry {
|
||||
param_env,
|
||||
@@ -175,12 +170,10 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
||||
variable_lookup_table: Default::default(),
|
||||
sub_root_lookup_table: Default::default(),
|
||||
var_kinds: Vec::new(),
|
||||
binder_index: ty::INNERMOST,
|
||||
|
||||
cache: Default::default(),
|
||||
};
|
||||
let param_env = param_env.fold_with(&mut env_canonicalizer);
|
||||
debug_assert_eq!(env_canonicalizer.binder_index, ty::INNERMOST);
|
||||
debug_assert!(env_canonicalizer.sub_root_lookup_table.is_empty());
|
||||
(param_env, env_canonicalizer.variable_lookup_table, env_canonicalizer.var_kinds)
|
||||
}
|
||||
@@ -212,7 +205,6 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
||||
variable_lookup_table,
|
||||
sub_root_lookup_table: Default::default(),
|
||||
var_kinds,
|
||||
binder_index: ty::INNERMOST,
|
||||
|
||||
// We do not reuse the cache as it may contain entries whose canonicalized
|
||||
// value contains `'static`. While we could alternatively handle this by
|
||||
@@ -409,7 +401,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
|
||||
|
||||
let var = self.get_or_insert_bound_var(t, kind);
|
||||
|
||||
Ty::new_anon_bound(self.cx(), self.binder_index, var)
|
||||
Ty::new_canonical_bound(self.cx(), var)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,16 +410,6 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
|
||||
self.delegate.cx()
|
||||
}
|
||||
|
||||
fn fold_binder<T>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T>
|
||||
where
|
||||
T: TypeFoldable<I>,
|
||||
{
|
||||
self.binder_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.binder_index.shift_out(1);
|
||||
t
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: I::Region) -> I::Region {
|
||||
let kind = match r.kind() {
|
||||
ty::ReBound(..) => return r,
|
||||
@@ -491,15 +473,15 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
|
||||
|
||||
let var = self.get_or_insert_bound_var(r, kind);
|
||||
|
||||
Region::new_anon_bound(self.cx(), self.binder_index, var)
|
||||
Region::new_canonical_bound(self.cx(), var)
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
|
||||
if let Some(&ty) = self.cache.get(&(self.binder_index, t)) {
|
||||
if let Some(&ty) = self.cache.get(&t) {
|
||||
ty
|
||||
} else {
|
||||
let res = self.inner_fold_ty(t);
|
||||
let old = self.cache.insert((self.binder_index, t), res);
|
||||
let old = self.cache.insert(t, res);
|
||||
assert_eq!(old, None);
|
||||
res
|
||||
}
|
||||
@@ -552,7 +534,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
|
||||
|
||||
let var = self.get_or_insert_bound_var(c, kind);
|
||||
|
||||
Const::new_anon_bound(self.cx(), self.binder_index, var)
|
||||
Const::new_canonical_bound(self.cx(), var)
|
||||
}
|
||||
|
||||
fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
|
||||
|
||||
@@ -167,25 +167,25 @@ where
|
||||
// and only use it for placeholders. We need to handle the
|
||||
// `sub_root` of type inference variables which would make this
|
||||
// more involved. They are also a lot rarer than region variables.
|
||||
if let ty::Bound(debruijn, b) = t.kind()
|
||||
if let ty::Bound(index_kind, b) = t.kind()
|
||||
&& !matches!(
|
||||
response.variables.get(b.var().as_usize()).unwrap(),
|
||||
CanonicalVarKind::Ty { .. }
|
||||
)
|
||||
{
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
assert!(matches!(index_kind, ty::BoundVarIndexKind::Canonical));
|
||||
opt_values[b.var()] = Some(*original_value);
|
||||
}
|
||||
}
|
||||
ty::GenericArgKind::Lifetime(r) => {
|
||||
if let ty::ReBound(debruijn, br) = r.kind() {
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
if let ty::ReBound(index_kind, br) = r.kind() {
|
||||
assert!(matches!(index_kind, ty::BoundVarIndexKind::Canonical));
|
||||
opt_values[br.var()] = Some(*original_value);
|
||||
}
|
||||
}
|
||||
ty::GenericArgKind::Const(c) => {
|
||||
if let ty::ConstKind::Bound(debruijn, bv) = c.kind() {
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
if let ty::ConstKind::Bound(index_kind, bv) = c.kind() {
|
||||
assert!(matches!(index_kind, ty::BoundVarIndexKind::Canonical));
|
||||
opt_values[bv.var()] = Some(*original_value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ where
|
||||
|
||||
fn fold_region(&mut self, r: I::Region) -> I::Region {
|
||||
match r.kind() {
|
||||
ty::ReBound(debruijn, _)
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _)
|
||||
if debruijn.as_usize()
|
||||
>= self.current_index.as_usize() + self.universe_indices.len() =>
|
||||
{
|
||||
@@ -99,7 +99,9 @@ where
|
||||
self.universe_indices
|
||||
);
|
||||
}
|
||||
ty::ReBound(debruijn, br) if debruijn >= self.current_index => {
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br)
|
||||
if debruijn >= self.current_index =>
|
||||
{
|
||||
let universe = self.universe_for(debruijn);
|
||||
let p = PlaceholderLike::new(universe, br);
|
||||
self.mapped_regions.insert(p, br);
|
||||
@@ -111,7 +113,7 @@ where
|
||||
|
||||
fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
|
||||
match t.kind() {
|
||||
ty::Bound(debruijn, _)
|
||||
ty::Bound(ty::BoundVarIndexKind::Bound(debruijn), _)
|
||||
if debruijn.as_usize() + 1
|
||||
> self.current_index.as_usize() + self.universe_indices.len() =>
|
||||
{
|
||||
@@ -120,7 +122,9 @@ where
|
||||
self.universe_indices
|
||||
);
|
||||
}
|
||||
ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => {
|
||||
ty::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_ty)
|
||||
if debruijn >= self.current_index =>
|
||||
{
|
||||
let universe = self.universe_for(debruijn);
|
||||
let p = PlaceholderLike::new(universe, bound_ty);
|
||||
self.mapped_types.insert(p, bound_ty);
|
||||
@@ -133,7 +137,7 @@ where
|
||||
|
||||
fn fold_const(&mut self, ct: I::Const) -> I::Const {
|
||||
match ct.kind() {
|
||||
ty::ConstKind::Bound(debruijn, _)
|
||||
ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), _)
|
||||
if debruijn.as_usize() + 1
|
||||
> self.current_index.as_usize() + self.universe_indices.len() =>
|
||||
{
|
||||
@@ -142,7 +146,9 @@ where
|
||||
self.universe_indices
|
||||
);
|
||||
}
|
||||
ty::ConstKind::Bound(debruijn, bound_const) if debruijn >= self.current_index => {
|
||||
ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_const)
|
||||
if debruijn >= self.current_index =>
|
||||
{
|
||||
let universe = self.universe_for(debruijn);
|
||||
let p = PlaceholderLike::new(universe, bound_const);
|
||||
self.mapped_consts.insert(p, bound_const);
|
||||
|
||||
@@ -453,7 +453,10 @@ impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> {
|
||||
TyKind::Alias(alias_kind.stable(tables, cx), alias_ty.stable(tables, cx))
|
||||
}
|
||||
ty::Param(param_ty) => TyKind::Param(param_ty.stable(tables, cx)),
|
||||
ty::Bound(debruijn_idx, bound_ty) => {
|
||||
ty::Bound(ty::BoundVarIndexKind::Canonical, _) => {
|
||||
unreachable!()
|
||||
}
|
||||
ty::Bound(ty::BoundVarIndexKind::Bound(debruijn_idx), bound_ty) => {
|
||||
TyKind::Bound(debruijn_idx.as_usize(), bound_ty.stable(tables, cx))
|
||||
}
|
||||
ty::CoroutineWitness(def_id, args) => TyKind::RigidTy(RigidTy::CoroutineWitness(
|
||||
@@ -907,7 +910,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
|
||||
index: early_reg.index,
|
||||
name: early_reg.name.to_string(),
|
||||
}),
|
||||
ty::ReBound(db_index, bound_reg) => RegionKind::ReBound(
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(db_index), bound_reg) => RegionKind::ReBound(
|
||||
db_index.as_u32(),
|
||||
BoundRegion {
|
||||
var: bound_reg.var.as_u32(),
|
||||
|
||||
@@ -287,7 +287,7 @@ fn encode_region<'tcx>(region: Region<'tcx>, dict: &mut FxHashMap<DictKey<'tcx>,
|
||||
// u6region[I[<region-disambiguator>][<region-index>]E] as vendor extended type
|
||||
let mut s = String::new();
|
||||
match region.kind() {
|
||||
RegionKind::ReBound(debruijn, r) => {
|
||||
RegionKind::ReBound(ty::BoundVarIndexKind::Bound(debruijn), r) => {
|
||||
s.push_str("u6regionI");
|
||||
// Debruijn index, which identifies the binder, as region disambiguator
|
||||
let num = debruijn.index() as u64;
|
||||
@@ -303,7 +303,8 @@ fn encode_region<'tcx>(region: Region<'tcx>, dict: &mut FxHashMap<DictKey<'tcx>,
|
||||
s.push_str("u6region");
|
||||
compress(dict, DictKey::Region(region), &mut s);
|
||||
}
|
||||
RegionKind::ReEarlyParam(..)
|
||||
RegionKind::ReBound(ty::BoundVarIndexKind::Canonical, _)
|
||||
| RegionKind::ReEarlyParam(..)
|
||||
| RegionKind::ReLateParam(..)
|
||||
| RegionKind::ReStatic
|
||||
| RegionKind::ReError(_)
|
||||
|
||||
@@ -412,7 +412,10 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> {
|
||||
|
||||
// Bound lifetimes use indices starting at 1,
|
||||
// see `BinderLevel` for more details.
|
||||
ty::ReBound(debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon }) => {
|
||||
ty::ReBound(
|
||||
ty::BoundVarIndexKind::Bound(debruijn),
|
||||
ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon },
|
||||
) => {
|
||||
let binder = &self.binders[self.binders.len() - 1 - debruijn.index()];
|
||||
let depth = binder.lifetime_depths.start + var.as_u32();
|
||||
|
||||
|
||||
@@ -830,7 +830,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EraseEscapingBoundRegions<'tcx> {
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
if let ty::ReBound(debruijn, _) = r.kind()
|
||||
if let ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) = r.kind()
|
||||
&& debruijn < self.binder
|
||||
{
|
||||
r
|
||||
|
||||
@@ -145,7 +145,9 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxEscapingBoundVarVisitor {
|
||||
#[inline]
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||
match r.kind() {
|
||||
ty::ReBound(debruijn, _) if debruijn > self.outer_index => {
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _)
|
||||
if debruijn > self.outer_index =>
|
||||
{
|
||||
self.escaping =
|
||||
self.escaping.max(debruijn.as_usize() - self.outer_index.as_usize());
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
|
||||
// bounds of the RPITIT. Shift these binders back out when
|
||||
// constructing the top-level projection predicate.
|
||||
let shifted_alias_ty = fold_regions(self.tcx, unshifted_alias_ty, |re, depth| {
|
||||
if let ty::ReBound(index, bv) = re.kind() {
|
||||
if let ty::ReBound(ty::BoundVarIndexKind::Bound(index), bv) = re.kind() {
|
||||
if depth != ty::INNERMOST {
|
||||
return ty::Region::new_error_with_message(
|
||||
self.tcx,
|
||||
|
||||
@@ -4,6 +4,7 @@ use std::ops::{ControlFlow, Deref};
|
||||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
|
||||
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::data_structures::SsoHashSet;
|
||||
@@ -11,7 +12,7 @@ use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldabl
|
||||
use crate::inherent::*;
|
||||
use crate::lift::Lift;
|
||||
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||
use crate::{self as ty, Interner};
|
||||
use crate::{self as ty, DebruijnIndex, Interner};
|
||||
|
||||
/// `Binder` is a binder for higher-ranked lifetimes or types. It is part of the
|
||||
/// compiler's representation for things like `for<'a> Fn(&'a isize)`
|
||||
@@ -299,7 +300,9 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
|
||||
return ControlFlow::Break(());
|
||||
}
|
||||
match t.kind() {
|
||||
ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
|
||||
ty::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_ty)
|
||||
if debruijn == self.binder_index =>
|
||||
{
|
||||
let idx = bound_ty.var().as_usize();
|
||||
if self.bound_vars.len() <= idx {
|
||||
panic!("Not enough bound vars: {:?} not found in {:?}", t, self.bound_vars);
|
||||
@@ -317,7 +320,9 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
|
||||
return ControlFlow::Break(());
|
||||
}
|
||||
match c.kind() {
|
||||
ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.binder_index => {
|
||||
ty::ConstKind::Bound(debruijn, bound_const)
|
||||
if debruijn == ty::BoundVarIndexKind::Bound(self.binder_index) =>
|
||||
{
|
||||
let idx = bound_const.var().as_usize();
|
||||
if self.bound_vars.len() <= idx {
|
||||
panic!("Not enough bound vars: {:?} not found in {:?}", c, self.bound_vars);
|
||||
@@ -332,7 +337,7 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
|
||||
|
||||
fn visit_region(&mut self, r: I::Region) -> Self::Result {
|
||||
match r.kind() {
|
||||
ty::ReBound(index, br) if index == self.binder_index => {
|
||||
ty::ReBound(index, br) if index == ty::BoundVarIndexKind::Bound(self.binder_index) => {
|
||||
let idx = br.var().as_usize();
|
||||
if self.bound_vars.len() <= idx {
|
||||
panic!("Not enough bound vars: {:?} not found in {:?}", r, self.bound_vars);
|
||||
@@ -913,3 +918,33 @@ impl<'a, I: Interner> ArgFolder<'a, I> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Okay, we do something fun for `Bound` types/regions/consts:
|
||||
/// Specifically, we distinguish between *canonically* bound things and
|
||||
/// `for<>` bound things. And, really, it comes down to caching during
|
||||
/// canonicalization and instantiation.
|
||||
///
|
||||
/// To understand why we do this, imagine we have a type `(T, for<> fn(T))`.
|
||||
/// If we just tracked canonically bound types with a `DebruijnIndex` (as we
|
||||
/// used to), then the canonicalized type would be something like
|
||||
/// `for<0> (^0.0, for<> fn(^1.0))` and so we can't cache `T -> ^0.0`,
|
||||
/// we have to also factor in binder level. (Of course, we don't cache that
|
||||
/// exactly, but rather the entire enclosing type, but the point stands.)
|
||||
///
|
||||
/// Of course, this is okay because we don't ever nest canonicalization, so
|
||||
/// `BoundVarIndexKind::Canonical` is unambiguous. We, alternatively, could
|
||||
/// have some sentinel `DebruijinIndex`, but that just seems too scary.
|
||||
///
|
||||
/// This doesn't seem to have a huge perf swing either way, but in the next
|
||||
/// solver, canonicalization is hot and there are some pathological cases where
|
||||
/// this is needed (`post-mono-higher-ranked-hang`).
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
pub enum BoundVarIndexKind {
|
||||
Bound(DebruijnIndex),
|
||||
Canonical,
|
||||
}
|
||||
|
||||
@@ -230,13 +230,13 @@ impl<I: Interner> CanonicalVarValues<I> {
|
||||
pub fn is_identity(&self) -> bool {
|
||||
self.var_values.iter().enumerate().all(|(bv, arg)| match arg.kind() {
|
||||
ty::GenericArgKind::Lifetime(r) => {
|
||||
matches!(r.kind(), ty::ReBound(ty::INNERMOST, br) if br.var().as_usize() == bv)
|
||||
matches!(r.kind(), ty::ReBound(ty::BoundVarIndexKind::Canonical, br) if br.var().as_usize() == bv)
|
||||
}
|
||||
ty::GenericArgKind::Type(ty) => {
|
||||
matches!(ty.kind(), ty::Bound(ty::INNERMOST, bt) if bt.var().as_usize() == bv)
|
||||
matches!(ty.kind(), ty::Bound(ty::BoundVarIndexKind::Canonical, bt) if bt.var().as_usize() == bv)
|
||||
}
|
||||
ty::GenericArgKind::Const(ct) => {
|
||||
matches!(ct.kind(), ty::ConstKind::Bound(ty::INNERMOST, bc) if bc.var().as_usize() == bv)
|
||||
matches!(ct.kind(), ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, bc) if bc.var().as_usize() == bv)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -246,21 +246,23 @@ impl<I: Interner> CanonicalVarValues<I> {
|
||||
for arg in self.var_values.iter() {
|
||||
match arg.kind() {
|
||||
ty::GenericArgKind::Lifetime(r) => {
|
||||
if matches!(r.kind(), ty::ReBound(ty::INNERMOST, br) if var == br.var()) {
|
||||
if matches!(r.kind(), ty::ReBound(ty::BoundVarIndexKind::Canonical, br) if var == br.var())
|
||||
{
|
||||
var = var + 1;
|
||||
} else {
|
||||
// It's ok if this region var isn't an identity variable
|
||||
}
|
||||
}
|
||||
ty::GenericArgKind::Type(ty) => {
|
||||
if matches!(ty.kind(), ty::Bound(ty::INNERMOST, bt) if var == bt.var()) {
|
||||
if matches!(ty.kind(), ty::Bound(ty::BoundVarIndexKind::Canonical, bt) if var == bt.var())
|
||||
{
|
||||
var = var + 1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ty::GenericArgKind::Const(ct) => {
|
||||
if matches!(ct.kind(), ty::ConstKind::Bound(ty::INNERMOST, bc) if var == bc.var())
|
||||
if matches!(ct.kind(), ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, bc) if var == bc.var())
|
||||
{
|
||||
var = var + 1;
|
||||
} else {
|
||||
@@ -284,16 +286,13 @@ impl<I: Interner> CanonicalVarValues<I> {
|
||||
| CanonicalVarKind::Int
|
||||
| CanonicalVarKind::Float
|
||||
| CanonicalVarKind::PlaceholderTy(_) => {
|
||||
Ty::new_anon_bound(cx, ty::INNERMOST, ty::BoundVar::from_usize(i))
|
||||
.into()
|
||||
Ty::new_canonical_bound(cx, ty::BoundVar::from_usize(i)).into()
|
||||
}
|
||||
CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => {
|
||||
Region::new_anon_bound(cx, ty::INNERMOST, ty::BoundVar::from_usize(i))
|
||||
.into()
|
||||
Region::new_canonical_bound(cx, ty::BoundVar::from_usize(i)).into()
|
||||
}
|
||||
CanonicalVarKind::Const(_) | CanonicalVarKind::PlaceholderConst(_) => {
|
||||
Const::new_anon_bound(cx, ty::INNERMOST, ty::BoundVar::from_usize(i))
|
||||
.into()
|
||||
Const::new_canonical_bound(cx, ty::BoundVar::from_usize(i)).into()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -7,7 +7,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
|
||||
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
|
||||
use crate::{self as ty, DebruijnIndex, Interner};
|
||||
use crate::{self as ty, BoundVarIndexKind, Interner};
|
||||
|
||||
/// Represents a constant in Rust.
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
|
||||
@@ -23,7 +23,7 @@ pub enum ConstKind<I: Interner> {
|
||||
Infer(InferConst),
|
||||
|
||||
/// Bound const variable, used only when preparing a trait query.
|
||||
Bound(DebruijnIndex, I::BoundConst),
|
||||
Bound(BoundVarIndexKind, I::BoundConst),
|
||||
|
||||
/// A placeholder const - universally quantified higher-ranked const.
|
||||
Placeholder(I::PlaceholderConst),
|
||||
|
||||
@@ -133,6 +133,9 @@ bitflags::bitflags! {
|
||||
|
||||
/// Does this type have any coroutines in it?
|
||||
const HAS_TY_CORO = 1 << 24;
|
||||
|
||||
/// Does this have have a `Bound(BoundVarIndexKind::Canonical, _)`?
|
||||
const HAS_CANONICAL_BOUND = 1 << 25;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +257,12 @@ impl<I: Interner> FlagComputation<I> {
|
||||
self.add_args(args.as_slice());
|
||||
}
|
||||
|
||||
ty::Bound(debruijn, _) => {
|
||||
ty::Bound(ty::BoundVarIndexKind::Canonical, _) => {
|
||||
self.add_flags(TypeFlags::HAS_TY_BOUND);
|
||||
self.add_flags(TypeFlags::HAS_CANONICAL_BOUND);
|
||||
}
|
||||
|
||||
ty::Bound(ty::BoundVarIndexKind::Bound(debruijn), _) => {
|
||||
self.add_bound_var(debruijn);
|
||||
self.add_flags(TypeFlags::HAS_TY_BOUND);
|
||||
}
|
||||
@@ -434,7 +442,7 @@ impl<I: Interner> FlagComputation<I> {
|
||||
|
||||
fn add_region(&mut self, r: I::Region) {
|
||||
self.add_flags(r.flags());
|
||||
if let ty::ReBound(debruijn, _) = r.kind() {
|
||||
if let ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) = r.kind() {
|
||||
self.add_bound_var(debruijn);
|
||||
}
|
||||
}
|
||||
@@ -454,10 +462,14 @@ impl<I: Interner> FlagComputation<I> {
|
||||
ty::InferConst::Fresh(_) => self.add_flags(TypeFlags::HAS_CT_FRESH),
|
||||
ty::InferConst::Var(_) => self.add_flags(TypeFlags::HAS_CT_INFER),
|
||||
},
|
||||
ty::ConstKind::Bound(debruijn, _) => {
|
||||
ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), _) => {
|
||||
self.add_bound_var(debruijn);
|
||||
self.add_flags(TypeFlags::HAS_CT_BOUND);
|
||||
}
|
||||
ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, _) => {
|
||||
self.add_flags(TypeFlags::HAS_CT_BOUND);
|
||||
self.add_flags(TypeFlags::HAS_CANONICAL_BOUND);
|
||||
}
|
||||
ty::ConstKind::Param(_) => {
|
||||
self.add_flags(TypeFlags::HAS_CT_PARAM);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ use tracing::{debug, instrument};
|
||||
|
||||
use crate::inherent::*;
|
||||
use crate::visit::{TypeVisitable, TypeVisitableExt as _};
|
||||
use crate::{self as ty, Interner, TypeFlags};
|
||||
use crate::{self as ty, BoundVarIndexKind, Interner, TypeFlags};
|
||||
|
||||
/// This trait is implemented for every type that can be folded,
|
||||
/// providing the skeleton of the traversal.
|
||||
@@ -398,7 +398,9 @@ impl<I: Interner> TypeFolder<I> for Shifter<I> {
|
||||
|
||||
fn fold_region(&mut self, r: I::Region) -> I::Region {
|
||||
match r.kind() {
|
||||
ty::ReBound(debruijn, br) if debruijn >= self.current_index => {
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br)
|
||||
if debruijn >= self.current_index =>
|
||||
{
|
||||
let debruijn = debruijn.shifted_in(self.amount);
|
||||
Region::new_bound(self.cx, debruijn, br)
|
||||
}
|
||||
@@ -408,7 +410,9 @@ impl<I: Interner> TypeFolder<I> for Shifter<I> {
|
||||
|
||||
fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
|
||||
match ty.kind() {
|
||||
ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => {
|
||||
ty::Bound(BoundVarIndexKind::Bound(debruijn), bound_ty)
|
||||
if debruijn >= self.current_index =>
|
||||
{
|
||||
let debruijn = debruijn.shifted_in(self.amount);
|
||||
Ty::new_bound(self.cx, debruijn, bound_ty)
|
||||
}
|
||||
@@ -420,7 +424,9 @@ impl<I: Interner> TypeFolder<I> for Shifter<I> {
|
||||
|
||||
fn fold_const(&mut self, ct: I::Const) -> I::Const {
|
||||
match ct.kind() {
|
||||
ty::ConstKind::Bound(debruijn, bound_ct) if debruijn >= self.current_index => {
|
||||
ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_ct)
|
||||
if debruijn >= self.current_index =>
|
||||
{
|
||||
let debruijn = debruijn.shifted_in(self.amount);
|
||||
Const::new_bound(self.cx, debruijn, bound_ct)
|
||||
}
|
||||
@@ -435,7 +441,7 @@ impl<I: Interner> TypeFolder<I> for Shifter<I> {
|
||||
|
||||
pub fn shift_region<I: Interner>(cx: I, region: I::Region, amount: u32) -> I::Region {
|
||||
match region.kind() {
|
||||
ty::ReBound(debruijn, br) if amount > 0 => {
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br) if amount > 0 => {
|
||||
Region::new_bound(cx, debruijn.shifted_in(amount), br)
|
||||
}
|
||||
_ => region,
|
||||
@@ -515,7 +521,13 @@ where
|
||||
#[instrument(skip(self), level = "debug", ret)]
|
||||
fn fold_region(&mut self, r: I::Region) -> I::Region {
|
||||
match r.kind() {
|
||||
ty::ReBound(debruijn, _) if debruijn < self.current_index => {
|
||||
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _)
|
||||
if debruijn < self.current_index =>
|
||||
{
|
||||
debug!(?self.current_index, "skipped bound region");
|
||||
r
|
||||
}
|
||||
ty::ReBound(ty::BoundVarIndexKind::Canonical, _) => {
|
||||
debug!(?self.current_index, "skipped bound region");
|
||||
r
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ pub trait Ty<I: Interner<Ty = Self>>:
|
||||
|
||||
fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;
|
||||
|
||||
fn new_canonical_bound(interner: I, var: ty::BoundVar) -> Self;
|
||||
|
||||
fn new_alias(interner: I, kind: ty::AliasTyKind, alias_ty: ty::AliasTy<I>) -> Self;
|
||||
|
||||
fn new_projection_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> Self {
|
||||
@@ -230,6 +232,8 @@ pub trait Region<I: Interner<Region = Self>>:
|
||||
|
||||
fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;
|
||||
|
||||
fn new_canonical_bound(interner: I, var: ty::BoundVar) -> Self;
|
||||
|
||||
fn new_static(interner: I) -> Self;
|
||||
|
||||
fn new_placeholder(interner: I, var: I::PlaceholderRegion) -> Self;
|
||||
@@ -260,6 +264,8 @@ pub trait Const<I: Interner<Const = Self>>:
|
||||
|
||||
fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;
|
||||
|
||||
fn new_canonical_bound(interner: I, var: ty::BoundVar) -> Self;
|
||||
|
||||
fn new_placeholder(interner: I, param: I::PlaceholderConst) -> Self;
|
||||
|
||||
fn new_unevaluated(interner: I, uv: ty::UnevaluatedConst<I>) -> Self;
|
||||
|
||||
@@ -196,14 +196,21 @@ impl DebruijnIndex {
|
||||
|
||||
pub fn debug_bound_var<T: std::fmt::Write>(
|
||||
fmt: &mut T,
|
||||
debruijn: DebruijnIndex,
|
||||
bound_index: BoundVarIndexKind,
|
||||
var: impl std::fmt::Debug,
|
||||
) -> Result<(), std::fmt::Error> {
|
||||
match bound_index {
|
||||
BoundVarIndexKind::Bound(debruijn) => {
|
||||
if debruijn == INNERMOST {
|
||||
write!(fmt, "^{var:?}")
|
||||
} else {
|
||||
write!(fmt, "^{}_{:?}", debruijn.index(), var)
|
||||
}
|
||||
}
|
||||
BoundVarIndexKind::Canonical => {
|
||||
write!(fmt, "^c_{:?}", var)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
|
||||
@@ -7,7 +7,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
|
||||
|
||||
use self::RegionKind::*;
|
||||
use crate::{DebruijnIndex, Interner};
|
||||
use crate::{BoundVarIndexKind, Interner};
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
/// A **region** **v**ariable **ID**.
|
||||
@@ -147,7 +147,7 @@ pub enum RegionKind<I: Interner> {
|
||||
/// Bound regions inside of types **must not** be erased, as they impact trait
|
||||
/// selection and the `TypeId` of that type. `for<'a> fn(&'a ())` and
|
||||
/// `fn(&'static ())` are different types and have to be treated as such.
|
||||
ReBound(DebruijnIndex, I::BoundRegion),
|
||||
ReBound(BoundVarIndexKind, I::BoundRegion),
|
||||
|
||||
/// Late-bound function parameters are represented using a `ReBound`. When
|
||||
/// inside of a function, we convert these bound variables to placeholder
|
||||
|
||||
@@ -15,7 +15,7 @@ pub use self::closure::*;
|
||||
use crate::inherent::*;
|
||||
#[cfg(feature = "nightly")]
|
||||
use crate::visit::TypeVisitable;
|
||||
use crate::{self as ty, DebruijnIndex, FloatTy, IntTy, Interner, UintTy};
|
||||
use crate::{self as ty, BoundVarIndexKind, FloatTy, IntTy, Interner, UintTy};
|
||||
|
||||
mod closure;
|
||||
|
||||
@@ -229,7 +229,7 @@ pub enum TyKind<I: Interner> {
|
||||
///
|
||||
/// [1]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
|
||||
/// [2]: https://rustc-dev-guide.rust-lang.org/traits/canonical-queries.html
|
||||
Bound(DebruijnIndex, I::BoundTy),
|
||||
Bound(BoundVarIndexKind, I::BoundTy),
|
||||
|
||||
/// A placeholder type, used during higher ranked subtyping to instantiate
|
||||
/// bound variables.
|
||||
|
||||
@@ -344,7 +344,8 @@ impl<I: Interner> TypeVisitor<I> for HasRegionsBoundAt {
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, r: I::Region) -> Self::Result {
|
||||
if matches!(r.kind(), ty::ReBound(binder, _) if self.binder == binder) {
|
||||
if matches!(r.kind(), ty::ReBound(ty::BoundVarIndexKind::Bound(binder), _) if self.binder == binder)
|
||||
{
|
||||
ControlFlow::Break(())
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
@@ -531,7 +532,7 @@ impl<I: Interner> TypeFolder<I> for FoldEscapingRegions<I> {
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: <I as Interner>::Region) -> <I as Interner>::Region {
|
||||
if let ty::ReBound(debruijn, _) = r.kind() {
|
||||
if let ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) = r.kind() {
|
||||
assert!(
|
||||
debruijn <= self.debruijn,
|
||||
"cannot instantiate binder with escaping bound vars"
|
||||
|
||||
@@ -14,7 +14,7 @@ use rustc_hir::{BindingMode, Body, FnDecl, Impl, ItemKind, MutTy, Mutability, No
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::adjustment::{Adjust, PointerCoercion};
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::{self, RegionKind, TyCtxt};
|
||||
use rustc_middle::ty::{self, BoundVarIndexKind, RegionKind, TyCtxt};
|
||||
use rustc_session::impl_lint_pass;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::{Span, sym};
|
||||
@@ -151,7 +151,7 @@ impl PassByRefOrValue {
|
||||
match *ty.skip_binder().kind() {
|
||||
ty::Ref(lt, ty, Mutability::Not) => {
|
||||
match lt.kind() {
|
||||
RegionKind::ReBound(index, region)
|
||||
RegionKind::ReBound(BoundVarIndexKind::Bound(index), region)
|
||||
if index.as_u32() == 0 && output_regions.contains(®ion) =>
|
||||
{
|
||||
continue;
|
||||
|
||||
@@ -21,7 +21,7 @@ use rustc_middle::traits::EvaluationResult;
|
||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment};
|
||||
use rustc_middle::ty::layout::ValidityRequirement;
|
||||
use rustc_middle::ty::{
|
||||
self, AdtDef, AliasTy, AssocItem, AssocTag, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind, GenericArgsRef,
|
||||
self, AdtDef, AliasTy, AssocItem, AssocTag, Binder, BoundRegion, BoundVarIndexKind, FnSig, GenericArg, GenericArgKind, GenericArgsRef,
|
||||
GenericParamDefKind, IntTy, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
|
||||
TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr,
|
||||
};
|
||||
@@ -826,7 +826,7 @@ pub fn for_each_top_level_late_bound_region<B>(
|
||||
impl<'tcx, B, F: FnMut(BoundRegion) -> ControlFlow<B>> TypeVisitor<TyCtxt<'tcx>> for V<F> {
|
||||
type Result = ControlFlow<B>;
|
||||
fn visit_region(&mut self, r: Region<'tcx>) -> Self::Result {
|
||||
if let RegionKind::ReBound(idx, bound) = r.kind()
|
||||
if let RegionKind::ReBound(BoundVarIndexKind::Bound(idx), bound) = r.kind()
|
||||
&& idx.as_u32() == self.index
|
||||
{
|
||||
(self.f)(bound)
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
// MIR for `address_of_reborrow` after SimplifyCfg-initial
|
||||
|
||||
| User Type Annotations
|
||||
| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:8:10: 8:18, inferred_ty: *const [i32; 10]
|
||||
| 0: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:8:10: 8:18, inferred_ty: *const [i32; 10]
|
||||
| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:10:10: 10:25, inferred_ty: *const dyn std::marker::Send
|
||||
| 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
|
||||
| 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
|
||||
| 2: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
|
||||
| 3: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
|
||||
| 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10]
|
||||
| 5: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10]
|
||||
| 6: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
|
||||
| 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
|
||||
| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:19:10: 19:18, inferred_ty: *const [i32; 10]
|
||||
| 10: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:19:10: 19:18, inferred_ty: *const [i32; 10]
|
||||
| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:21:10: 21:25, inferred_ty: *const dyn std::marker::Send
|
||||
| 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
|
||||
| 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
|
||||
| 12: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
|
||||
| 13: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
|
||||
| 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10]
|
||||
| 15: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10]
|
||||
| 16: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
|
||||
| 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
|
||||
| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:29:10: 29:16, inferred_ty: *mut [i32; 10]
|
||||
| 20: user_ty: Canonical { value: Ty(*mut ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:29:10: 29:16, inferred_ty: *mut [i32; 10]
|
||||
| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:31:10: 31:23, inferred_ty: *mut dyn std::marker::Send
|
||||
| 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
|
||||
| 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
|
||||
| 22: user_ty: Canonical { value: Ty(*mut ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
|
||||
| 23: user_ty: Canonical { value: Ty(*mut ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
|
||||
| 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10]
|
||||
| 25: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10]
|
||||
| 26: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error: reached the recursion limit while instantiating `ToChain::<'_, '_>::perm_pairs::<{async closure@$DIR/post-mono-higher-ranked-hang.rs:43:45: 43:67}>`
|
||||
--> $DIR/post-mono-higher-ranked-hang.rs:43:21
|
||||
error: reached the recursion limit while instantiating `ToChain::<'_, '_>::perm_pairs::<{async closure@$DIR/post-mono-higher-ranked-hang.rs:47:45: 47:67}>`
|
||||
--> $DIR/post-mono-higher-ranked-hang.rs:47:21
|
||||
|
|
||||
LL | / self.perm_pairs(l, &mut async move |left_pair| {
|
||||
LL | |
|
||||
@@ -8,7 +8,7 @@ LL | | })
|
||||
| |______________________^
|
||||
|
|
||||
note: `ToChain::<'env, 'db>::perm_pairs` defined here
|
||||
--> $DIR/post-mono-higher-ranked-hang.rs:34:5
|
||||
--> $DIR/post-mono-higher-ranked-hang.rs:38:5
|
||||
|
|
||||
LL | / fn perm_pairs<'l>(
|
||||
LL | | &'l self,
|
||||
@@ -0,0 +1,21 @@
|
||||
error: reached the recursion limit while instantiating `ToChain::<'_, '_>::perm_pairs::<{async closure@$DIR/post-mono-higher-ranked-hang.rs:47:45: 47:67}>`
|
||||
--> $DIR/post-mono-higher-ranked-hang.rs:47:21
|
||||
|
|
||||
LL | / self.perm_pairs(l, &mut async move |left_pair| {
|
||||
LL | |
|
||||
LL | | self.perm_pairs(r, yield_chain).await
|
||||
LL | | })
|
||||
| |______________________^
|
||||
|
|
||||
note: `ToChain::<'env, 'db>::perm_pairs` defined here
|
||||
--> $DIR/post-mono-higher-ranked-hang.rs:38:5
|
||||
|
|
||||
LL | / fn perm_pairs<'l>(
|
||||
LL | | &'l self,
|
||||
LL | | perm: &'l SymPerm<'db>,
|
||||
LL | | yield_chain: &'l mut impl AsyncFnMut(&SymPerm<'db>),
|
||||
LL | | ) -> Pin<Box<dyn std::future::Future<Output = ()> + 'l>> {
|
||||
| |____________________________________________________________^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
//@ aux-build:block-on.rs
|
||||
//@ edition:2021
|
||||
|
||||
//@ revisions: current next
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
// Regression test for <https://github.com/rust-lang/rust/issues/135780>.
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
@@ -37,7 +37,7 @@ error: higher-ranked lifetime error
|
||||
LL | v.t(|| {});
|
||||
| ^^^^^
|
||||
|
|
||||
= note: could not prove `for<'a> &'a V: 'b`
|
||||
= note: could not prove `for<'a> &'a V: '_`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ error: higher-ranked lifetime error
|
||||
LL | || {};
|
||||
| ^^^^^
|
||||
|
|
||||
= note: could not prove `for<'a> &'a (): 'b`
|
||||
= note: could not prove `for<'a> &'a (): '_`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ error: higher-ranked lifetime error
|
||||
LL | foo(&10);
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: could not prove `for<'b> &'b (): 'a`
|
||||
= note: could not prove `for<'b> &'b (): '_`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ fn main() {
|
||||
// Here: we only want the `T` to be given, the rest should be variables.
|
||||
//
|
||||
// (`T` refers to the declaration of `Bazoom`)
|
||||
let x = <_ as Bazoom<u32>>::method::<_>; //~ ERROR [^0, u32, ^1]
|
||||
let x = <_ as Bazoom<u32>>::method::<_>; //~ ERROR [^c_0, u32, ^c_1]
|
||||
x(&22, 44, 66);
|
||||
|
||||
// Here: all are given and definitely contain no lifetimes, so we
|
||||
@@ -48,7 +48,7 @@ fn main() {
|
||||
//
|
||||
// (`U` refers to the declaration of `Bazoom`)
|
||||
let y = 22_u32;
|
||||
y.method::<u32>(44, 66); //~ ERROR [^0, ^1, u32]
|
||||
y.method::<u32>(44, 66); //~ ERROR [^c_0, ^c_1, u32]
|
||||
|
||||
// Here: nothing is given, so we don't have any annotation.
|
||||
let y = 22_u32;
|
||||
|
||||
@@ -4,7 +4,7 @@ error: user args: UserArgs { args: [&'static u32], user_self_ty: None }
|
||||
LL | let x = foo::<&'static u32>;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: user args: UserArgs { args: [^0, u32, ^1], user_self_ty: None }
|
||||
error: user args: UserArgs { args: [^c_0, u32, ^c_1], user_self_ty: None }
|
||||
--> $DIR/dump-fn-method.rs:34:13
|
||||
|
|
||||
LL | let x = <_ as Bazoom<u32>>::method::<_>;
|
||||
@@ -16,7 +16,7 @@ error: user args: UserArgs { args: [u8, &'static u16, u32], user_self_ty: None }
|
||||
LL | let x = <u8 as Bazoom<&'static u16>>::method::<u32>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: user args: UserArgs { args: [^0, ^1, u32], user_self_ty: None }
|
||||
error: user args: UserArgs { args: [^c_0, ^c_1, u32], user_self_ty: None }
|
||||
--> $DIR/dump-fn-method.rs:51:5
|
||||
|
|
||||
LL | y.method::<u32>(44, 66);
|
||||
|
||||
Reference in New Issue
Block a user