summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/infer
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/infer')
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs36
1 files changed, 33 insertions, 3 deletions
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index 0331d764b..43583b572 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -68,6 +68,22 @@ pub struct CanonicalVarValues<'tcx> {
pub var_values: IndexVec<BoundVar, GenericArg<'tcx>>,
}
+impl CanonicalVarValues<'_> {
+ pub fn is_identity(&self) -> bool {
+ self.var_values.iter_enumerated().all(|(bv, arg)| match arg.unpack() {
+ ty::GenericArgKind::Lifetime(r) => {
+ matches!(*r, ty::ReLateBound(ty::INNERMOST, br) if br.var == bv)
+ }
+ ty::GenericArgKind::Type(ty) => {
+ matches!(*ty.kind(), ty::Bound(ty::INNERMOST, bt) if bt.var == bv)
+ }
+ ty::GenericArgKind::Const(ct) => {
+ matches!(ct.kind(), ty::ConstKind::Bound(ty::INNERMOST, bc) if bc == bv)
+ }
+ })
+ }
+}
+
/// When we canonicalize a value to form a query, we wind up replacing
/// various parts of it with canonical variables. This struct stores
/// those replaced bits to remember for when we process the query
@@ -213,9 +229,7 @@ impl QueryRegionConstraints<'_> {
}
}
-pub type Canonicalized<'tcx, V> = Canonical<'tcx, V>;
-
-pub type CanonicalizedQueryResponse<'tcx, T> = &'tcx Canonical<'tcx, QueryResponse<'tcx, T>>;
+pub type CanonicalQueryResponse<'tcx, T> = &'tcx Canonical<'tcx, QueryResponse<'tcx, T>>;
/// Indicates whether or not we were able to prove the query to be
/// true.
@@ -300,6 +314,16 @@ impl<'tcx, V> Canonical<'tcx, V> {
let Canonical { max_universe, variables, value } = self;
Canonical { max_universe, variables, value: map_op(value) }
}
+
+ /// Allows you to map the `value` of a canonical while keeping the same set of
+ /// bound variables.
+ ///
+ /// **WARNING:** This function is very easy to mis-use, hence the name! See
+ /// the comment of [Canonical::unchecked_map] for more details.
+ pub fn unchecked_rebind<W>(self, value: W) -> Canonical<'tcx, W> {
+ let Canonical { max_universe, variables, value: _ } = self;
+ Canonical { max_universe, variables, value }
+ }
}
pub type QueryOutlivesConstraint<'tcx> = (
@@ -315,6 +339,12 @@ TrivialTypeTraversalAndLiftImpls! {
}
impl<'tcx> CanonicalVarValues<'tcx> {
+ /// Creates dummy var values which should not be used in a
+ /// canonical response.
+ pub fn dummy() -> CanonicalVarValues<'tcx> {
+ CanonicalVarValues { var_values: Default::default() }
+ }
+
#[inline]
pub fn len(&self) -> usize {
self.var_values.len()