From e24a4b4690f73dc834c2f3d5c7b454c1943d0e3a Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Wed, 28 Oct 2020 01:11:03 +0000
Subject: [PATCH] Add type to `ConstKind::Placeholder`

---
 .../src/infer/canonical/canonicalizer.rs      | 10 ++++-----
 .../rustc_infer/src/infer/canonical/mod.rs    |  6 ++---
 .../src/infer/higher_ranked/mod.rs            |  2 +-
 compiler/rustc_middle/src/infer/canonical.rs  | 22 ++++++++++---------
 compiler/rustc_middle/src/ty/codec.rs         |  2 +-
 compiler/rustc_middle/src/ty/consts/kind.rs   |  2 +-
 compiler/rustc_middle/src/ty/context.rs       | 11 ++++++----
 compiler/rustc_middle/src/ty/mod.rs           | 17 +++++++++-----
 8 files changed, 41 insertions(+), 31 deletions(-)

diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 871fc4fafe269..f554b51800a72 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -277,7 +277,7 @@ impl CanonicalizeRegionMode for CanonicalizeFreeRegionsOtherThanStatic {
 struct Canonicalizer<'cx, 'tcx> {
     infcx: Option<&'cx InferCtxt<'cx, 'tcx>>,
     tcx: TyCtxt<'tcx>,
-    variables: SmallVec<[CanonicalVarInfo; 8]>,
+    variables: SmallVec<[CanonicalVarInfo<'tcx>; 8]>,
     query_state: &'cx mut OriginalQueryValues<'tcx>,
     // Note that indices is only used once `var_values` is big enough to be
     // heap-allocated.
@@ -542,7 +542,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
     /// or returns an existing variable if `kind` has already been
     /// seen. `kind` is expected to be an unbound variable (or
     /// potentially a free region).
-    fn canonical_var(&mut self, info: CanonicalVarInfo, kind: GenericArg<'tcx>) -> BoundVar {
+    fn canonical_var(&mut self, info: CanonicalVarInfo<'tcx>, kind: GenericArg<'tcx>) -> BoundVar {
         let Canonicalizer { variables, query_state, indices, .. } = self;
 
         let var_values = &mut query_state.var_values;
@@ -621,7 +621,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
     /// representing the region `r`; return a region referencing it.
     fn canonical_var_for_region(
         &mut self,
-        info: CanonicalVarInfo,
+        info: CanonicalVarInfo<'tcx>,
         r: ty::Region<'tcx>,
     ) -> ty::Region<'tcx> {
         let var = self.canonical_var(info, r.into());
@@ -633,7 +633,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
     /// if `ty_var` is bound to anything; if so, canonicalize
     /// *that*. Otherwise, create a new canonical variable for
     /// `ty_var`.
-    fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo, ty_var: Ty<'tcx>) -> Ty<'tcx> {
+    fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo<'tcx>, ty_var: Ty<'tcx>) -> Ty<'tcx> {
         let infcx = self.infcx.expect("encountered ty-var without infcx");
         let bound_to = infcx.shallow_resolve(ty_var);
         if bound_to != ty_var {
@@ -650,7 +650,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
     /// `const_var`.
     fn canonicalize_const_var(
         &mut self,
-        info: CanonicalVarInfo,
+        info: CanonicalVarInfo<'tcx>,
         const_var: &'tcx ty::Const<'tcx>,
     ) -> &'tcx ty::Const<'tcx> {
         let infcx = self.infcx.expect("encountered const-var without infcx");
diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs
index 2b8c46f1de42d..0c26639e9b0fe 100644
--- a/compiler/rustc_infer/src/infer/canonical/mod.rs
+++ b/compiler/rustc_infer/src/infer/canonical/mod.rs
@@ -82,7 +82,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
     fn instantiate_canonical_vars(
         &self,
         span: Span,
-        variables: &List<CanonicalVarInfo>,
+        variables: &List<CanonicalVarInfo<'tcx>>,
         universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
     ) -> CanonicalVarValues<'tcx> {
         let var_values: IndexVec<BoundVar, GenericArg<'tcx>> = variables
@@ -100,7 +100,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
     fn instantiate_canonical_var(
         &self,
         span: Span,
-        cv_info: CanonicalVarInfo,
+        cv_info: CanonicalVarInfo<'tcx>,
         universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
     ) -> GenericArg<'tcx> {
         match cv_info.kind {
@@ -154,7 +154,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
                 self.tcx
                     .mk_const(ty::Const {
                         val: ty::ConstKind::Placeholder(placeholder_mapped),
-                        ty: self.tcx.ty_error(), // FIXME(const_generics)
+                        ty: name.ty,
                     })
                     .into()
             }
diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
index e3365e8590b5e..4a5fd4b2aa5c8 100644
--- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
+++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
@@ -95,7 +95,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             self.tcx.mk_const(ty::Const {
                 val: ty::ConstKind::Placeholder(ty::PlaceholderConst {
                     universe: next_universe,
-                    name: bound_var,
+                    name: ty::BoundConst { var: bound_var, ty },
                 }),
                 ty,
             })
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index 1e15ae49a0c38..947b016a1fc93 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -40,7 +40,7 @@ pub struct Canonical<'tcx, V> {
     pub value: V,
 }
 
-pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo>;
+pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo<'tcx>>;
 
 /// A set of values corresponding to the canonical variables from some
 /// `Canonical`. You can give these values to
@@ -88,11 +88,11 @@ impl Default for OriginalQueryValues<'tcx> {
 /// a copy of the canonical value in some other inference context,
 /// with fresh inference variables replacing the canonical values.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)]
-pub struct CanonicalVarInfo {
-    pub kind: CanonicalVarKind,
+pub struct CanonicalVarInfo<'tcx> {
+    pub kind: CanonicalVarKind<'tcx>,
 }
 
-impl CanonicalVarInfo {
+impl<'tcx> CanonicalVarInfo<'tcx> {
     pub fn universe(&self) -> ty::UniverseIndex {
         self.kind.universe()
     }
@@ -113,7 +113,7 @@ impl CanonicalVarInfo {
 /// in the type-theory sense of the term -- i.e., a "meta" type system
 /// that analyzes type-like values.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)]
-pub enum CanonicalVarKind {
+pub enum CanonicalVarKind<'tcx> {
     /// Some kind of type inference variable.
     Ty(CanonicalTyVarKind),
 
@@ -132,10 +132,10 @@ pub enum CanonicalVarKind {
     Const(ty::UniverseIndex),
 
     /// A "placeholder" that represents "any const".
-    PlaceholderConst(ty::PlaceholderConst),
+    PlaceholderConst(ty::PlaceholderConst<'tcx>),
 }
 
-impl CanonicalVarKind {
+impl<'tcx> CanonicalVarKind<'tcx> {
     pub fn universe(self) -> ty::UniverseIndex {
         match self {
             CanonicalVarKind::Ty(kind) => match kind {
@@ -287,9 +287,11 @@ pub type QueryOutlivesConstraint<'tcx> =
     ty::Binder<ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>>;
 
 CloneTypeFoldableAndLiftImpls! {
-    crate::infer::canonical::Certainty,
-    crate::infer::canonical::CanonicalVarInfo,
-    crate::infer::canonical::CanonicalVarKind,
+    for <'tcx> {
+        crate::infer::canonical::Certainty,
+        crate::infer::canonical::CanonicalVarInfo<'tcx>,
+        crate::infer::canonical::CanonicalVarKind<'tcx>,
+    }
 }
 
 CloneTypeFoldableImpls! {
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index aaf6a8570437c..1def4936860f1 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -278,7 +278,7 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Region<'tcx> {
 impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for CanonicalVarInfos<'tcx> {
     fn decode(decoder: &mut D) -> Result<Self, D::Error> {
         let len = decoder.read_usize()?;
-        let interned: Result<Vec<CanonicalVarInfo>, _> =
+        let interned: Result<Vec<CanonicalVarInfo<'tcx>>, _> =
             (0..len).map(|_| Decodable::decode(decoder)).collect();
         Ok(decoder.tcx().intern_canonical_var_infos(interned?.as_slice()))
     }
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index ede28522000af..ca51f2a941174 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -23,7 +23,7 @@ pub enum ConstKind<'tcx> {
     Bound(ty::DebruijnIndex, ty::BoundVar),
 
     /// A placeholder const - universally quantified higher-ranked const.
-    Placeholder(ty::PlaceholderConst),
+    Placeholder(ty::PlaceholderConst<'tcx>),
 
     /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other
     /// variants when the code is monomorphic enough for that.
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index f6ea6743a0e04..4b7d6148fd39a 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -83,7 +83,7 @@ pub struct CtxtInterners<'tcx> {
     type_: InternedSet<'tcx, TyS<'tcx>>,
     type_list: InternedSet<'tcx, List<Ty<'tcx>>>,
     substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
-    canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo>>,
+    canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
     region: InternedSet<'tcx, RegionKind>,
     existential_predicates: InternedSet<'tcx, List<ExistentialPredicate<'tcx>>>,
     predicate: InternedSet<'tcx, PredicateInner<'tcx>>,
@@ -1613,7 +1613,7 @@ nop_lift! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>}
 nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
 nop_list_lift! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
 nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
-nop_list_lift! {canonical_var_infos; CanonicalVarInfo => CanonicalVarInfo}
+nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>}
 nop_list_lift! {projs; ProjectionKind => ProjectionKind}
 
 // This is the impl for `&'a InternalSubsts<'a>`.
@@ -2049,7 +2049,7 @@ macro_rules! slice_interners {
 slice_interners!(
     type_list: _intern_type_list(Ty<'tcx>),
     substs: _intern_substs(GenericArg<'tcx>),
-    canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo),
+    canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>),
     existential_predicates: _intern_existential_predicates(ExistentialPredicate<'tcx>),
     predicates: _intern_predicates(Predicate<'tcx>),
     projs: _intern_projs(ProjectionKind),
@@ -2448,7 +2448,10 @@ impl<'tcx> TyCtxt<'tcx> {
         if ts.is_empty() { List::empty() } else { self._intern_place_elems(ts) }
     }
 
-    pub fn intern_canonical_var_infos(self, ts: &[CanonicalVarInfo]) -> CanonicalVarInfos<'tcx> {
+    pub fn intern_canonical_var_infos(
+        self,
+        ts: &[CanonicalVarInfo<'tcx>],
+    ) -> CanonicalVarInfos<'tcx> {
         if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
     }
 
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 845fa8a47ae2c..1f0164562ec84 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1576,11 +1576,9 @@ impl UniverseIndex {
     }
 }
 
-/// The "placeholder index" fully defines a placeholder region.
-/// Placeholder regions are identified by both a **universe** as well
-/// as a "bound-region" within that universe. The `bound_region` is
-/// basically a name -- distinct bound regions within the same
-/// universe are just two regions with an unknown relationship to one
+/// The "placeholder index" fully defines a placeholder region, type, or const. Placeholders are
+/// identified by both a universe, as well as a name residing within that universe. Distinct bound
+/// regions/types/consts within the same universe simply have an unknown relationship to one
 /// another.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)]
 pub struct Placeholder<T> {
@@ -1602,7 +1600,14 @@ pub type PlaceholderRegion = Placeholder<BoundRegion>;
 
 pub type PlaceholderType = Placeholder<BoundVar>;
 
-pub type PlaceholderConst = Placeholder<BoundVar>;
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
+#[derive(TyEncodable, TyDecodable, PartialOrd, Ord)]
+pub struct BoundConst<'tcx> {
+    pub var: BoundVar,
+    pub ty: Ty<'tcx>,
+}
+
+pub type PlaceholderConst<'tcx> = Placeholder<BoundConst<'tcx>>;
 
 /// A `DefId` which is potentially bundled with its corresponding generic parameter
 /// in case `did` is a const argument.