Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit cfa901b

Browse files
committedNov 17, 2023
Uplift CanonicalVarInfo and friends
1 parent 6eddff4 commit cfa901b

File tree

4 files changed

+313
-158
lines changed

4 files changed

+313
-158
lines changed
 

‎compiler/rustc_middle/src/infer/canonical.rs

Lines changed: 4 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
2424
use rustc_macros::HashStable;
2525
use rustc_type_ir::Canonical as IrCanonical;
26+
use rustc_type_ir::CanonicalVarInfo as IrCanonicalVarInfo;
27+
pub use rustc_type_ir::{CanonicalTyVarKind, CanonicalVarKind};
2628
use smallvec::SmallVec;
2729
use std::ops::Index;
2830

@@ -33,6 +35,8 @@ use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt};
3335

3436
pub type Canonical<'tcx, V> = IrCanonical<TyCtxt<'tcx>, V>;
3537

38+
pub type CanonicalVarInfo<'tcx> = IrCanonicalVarInfo<TyCtxt<'tcx>>;
39+
3640
pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo<'tcx>>;
3741

3842
impl<'tcx> ty::TypeFoldable<TyCtxt<'tcx>> for CanonicalVarInfos<'tcx> {
@@ -138,158 +142,6 @@ impl<'tcx> Default for OriginalQueryValues<'tcx> {
138142
}
139143
}
140144

141-
/// Information about a canonical variable that is included with the
142-
/// canonical value. This is sufficient information for code to create
143-
/// a copy of the canonical value in some other inference context,
144-
/// with fresh inference variables replacing the canonical values.
145-
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)]
146-
#[derive(TypeFoldable, TypeVisitable)]
147-
pub struct CanonicalVarInfo<'tcx> {
148-
pub kind: CanonicalVarKind<'tcx>,
149-
}
150-
151-
impl<'tcx> CanonicalVarInfo<'tcx> {
152-
pub fn universe(&self) -> ty::UniverseIndex {
153-
self.kind.universe()
154-
}
155-
156-
#[must_use]
157-
pub fn with_updated_universe(self, ui: ty::UniverseIndex) -> CanonicalVarInfo<'tcx> {
158-
CanonicalVarInfo { kind: self.kind.with_updated_universe(ui) }
159-
}
160-
161-
pub fn is_existential(&self) -> bool {
162-
match self.kind {
163-
CanonicalVarKind::Ty(_) => true,
164-
CanonicalVarKind::PlaceholderTy(_) => false,
165-
CanonicalVarKind::Region(_) => true,
166-
CanonicalVarKind::PlaceholderRegion(..) => false,
167-
CanonicalVarKind::Const(..) => true,
168-
CanonicalVarKind::PlaceholderConst(_, _) => false,
169-
CanonicalVarKind::Effect => true,
170-
}
171-
}
172-
173-
pub fn is_region(&self) -> bool {
174-
match self.kind {
175-
CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => true,
176-
CanonicalVarKind::Ty(_)
177-
| CanonicalVarKind::PlaceholderTy(_)
178-
| CanonicalVarKind::Const(_, _)
179-
| CanonicalVarKind::PlaceholderConst(_, _)
180-
| CanonicalVarKind::Effect => false,
181-
}
182-
}
183-
184-
pub fn expect_placeholder_index(self) -> usize {
185-
match self.kind {
186-
CanonicalVarKind::Ty(_)
187-
| CanonicalVarKind::Region(_)
188-
| CanonicalVarKind::Const(_, _)
189-
| CanonicalVarKind::Effect => bug!("expected placeholder: {self:?}"),
190-
191-
CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.bound.var.as_usize(),
192-
CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.bound.var.as_usize(),
193-
CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.bound.as_usize(),
194-
}
195-
}
196-
}
197-
198-
/// Describes the "kind" of the canonical variable. This is a "kind"
199-
/// in the type-theory sense of the term -- i.e., a "meta" type system
200-
/// that analyzes type-like values.
201-
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)]
202-
#[derive(TypeFoldable, TypeVisitable)]
203-
pub enum CanonicalVarKind<'tcx> {
204-
/// Some kind of type inference variable.
205-
Ty(CanonicalTyVarKind),
206-
207-
/// A "placeholder" that represents "any type".
208-
PlaceholderTy(ty::PlaceholderType),
209-
210-
/// Region variable `'?R`.
211-
Region(ty::UniverseIndex),
212-
213-
/// A "placeholder" that represents "any region". Created when you
214-
/// are solving a goal like `for<'a> T: Foo<'a>` to represent the
215-
/// bound region `'a`.
216-
PlaceholderRegion(ty::PlaceholderRegion),
217-
218-
/// Some kind of const inference variable.
219-
Const(ty::UniverseIndex, Ty<'tcx>),
220-
221-
/// Effect variable `'?E`.
222-
Effect,
223-
224-
/// A "placeholder" that represents "any const".
225-
PlaceholderConst(ty::PlaceholderConst, Ty<'tcx>),
226-
}
227-
228-
impl<'tcx> CanonicalVarKind<'tcx> {
229-
pub fn universe(self) -> ty::UniverseIndex {
230-
match self {
231-
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) => ui,
232-
CanonicalVarKind::Ty(CanonicalTyVarKind::Float | CanonicalTyVarKind::Int) => {
233-
ty::UniverseIndex::ROOT
234-
}
235-
CanonicalVarKind::Effect => ty::UniverseIndex::ROOT,
236-
CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe,
237-
CanonicalVarKind::Region(ui) => ui,
238-
CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe,
239-
CanonicalVarKind::Const(ui, _) => ui,
240-
CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.universe,
241-
}
242-
}
243-
244-
/// Replaces the universe of this canonical variable with `ui`.
245-
///
246-
/// In case this is a float or int variable, this causes an ICE if
247-
/// the updated universe is not the root.
248-
pub fn with_updated_universe(self, ui: ty::UniverseIndex) -> CanonicalVarKind<'tcx> {
249-
match self {
250-
CanonicalVarKind::Ty(CanonicalTyVarKind::General(_)) => {
251-
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui))
252-
}
253-
CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float)
254-
| CanonicalVarKind::Effect => {
255-
assert_eq!(ui, ty::UniverseIndex::ROOT);
256-
self
257-
}
258-
CanonicalVarKind::PlaceholderTy(placeholder) => {
259-
CanonicalVarKind::PlaceholderTy(ty::Placeholder { universe: ui, ..placeholder })
260-
}
261-
CanonicalVarKind::Region(_) => CanonicalVarKind::Region(ui),
262-
CanonicalVarKind::PlaceholderRegion(placeholder) => {
263-
CanonicalVarKind::PlaceholderRegion(ty::Placeholder { universe: ui, ..placeholder })
264-
}
265-
CanonicalVarKind::Const(_, ty) => CanonicalVarKind::Const(ui, ty),
266-
CanonicalVarKind::PlaceholderConst(placeholder, ty) => {
267-
CanonicalVarKind::PlaceholderConst(
268-
ty::Placeholder { universe: ui, ..placeholder },
269-
ty,
270-
)
271-
}
272-
}
273-
}
274-
}
275-
276-
/// Rust actually has more than one category of type variables;
277-
/// notably, the type variables we create for literals (e.g., 22 or
278-
/// 22.) can only be instantiated with integral/float types (e.g.,
279-
/// usize or f32). In order to faithfully reproduce a type, we need to
280-
/// know what set of types a given type variable can be unified with.
281-
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)]
282-
pub enum CanonicalTyVarKind {
283-
/// General type variable `?T` that can be unified with arbitrary types.
284-
General(ty::UniverseIndex),
285-
286-
/// Integral type variable `?I` (that can only be unified with integral types).
287-
Int,
288-
289-
/// Floating-point type variable `?F` (that can only be unified with float types).
290-
Float,
291-
}
292-
293145
/// After we execute a query with a canonicalized key, we get back a
294146
/// `Canonical<QueryResponse<..>>`. You can use
295147
/// `instantiate_query_result` to access the data in this result.
@@ -366,7 +218,6 @@ pub type QueryOutlivesConstraint<'tcx> =
366218

367219
TrivialTypeTraversalImpls! {
368220
crate::infer::canonical::Certainty,
369-
crate::infer::canonical::CanonicalTyVarKind,
370221
}
371222

372223
impl<'tcx> CanonicalVarValues<'tcx> {

‎compiler/rustc_middle/src/ty/mod.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1519,8 +1519,36 @@ pub struct Placeholder<T> {
15191519

15201520
pub type PlaceholderRegion = Placeholder<BoundRegion>;
15211521

1522+
impl rustc_type_ir::Placeholder for PlaceholderRegion {
1523+
fn universe(&self) -> UniverseIndex {
1524+
self.universe
1525+
}
1526+
1527+
fn var(&self) -> BoundVar {
1528+
self.bound.var
1529+
}
1530+
1531+
fn with_updated_universe(self, ui: UniverseIndex) -> Self {
1532+
Placeholder { universe: ui, ..self }
1533+
}
1534+
}
1535+
15221536
pub type PlaceholderType = Placeholder<BoundTy>;
15231537

1538+
impl rustc_type_ir::Placeholder for PlaceholderType {
1539+
fn universe(&self) -> UniverseIndex {
1540+
self.universe
1541+
}
1542+
1543+
fn var(&self) -> BoundVar {
1544+
self.bound.var
1545+
}
1546+
1547+
fn with_updated_universe(self, ui: UniverseIndex) -> Self {
1548+
Placeholder { universe: ui, ..self }
1549+
}
1550+
}
1551+
15241552
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
15251553
#[derive(TyEncodable, TyDecodable, PartialOrd, Ord)]
15261554
pub struct BoundConst<'tcx> {
@@ -1530,6 +1558,20 @@ pub struct BoundConst<'tcx> {
15301558

15311559
pub type PlaceholderConst = Placeholder<BoundVar>;
15321560

1561+
impl rustc_type_ir::Placeholder for PlaceholderConst {
1562+
fn universe(&self) -> UniverseIndex {
1563+
self.universe
1564+
}
1565+
1566+
fn var(&self) -> BoundVar {
1567+
self.bound
1568+
}
1569+
1570+
fn with_updated_universe(self, ui: UniverseIndex) -> Self {
1571+
Placeholder { universe: ui, ..self }
1572+
}
1573+
}
1574+
15331575
/// When type checking, we use the `ParamEnv` to track
15341576
/// details about the set of where-clauses that are in scope at this
15351577
/// particular point.

‎compiler/rustc_type_ir/src/canonical.rs

Lines changed: 255 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::ops::ControlFlow;
44

55
use crate::fold::{FallibleTypeFolder, TypeFoldable};
66
use crate::visit::{TypeVisitable, TypeVisitor};
7-
use crate::{Interner, UniverseIndex};
7+
use crate::{Interner, Placeholder, UniverseIndex};
88

99
/// A "canonicalized" type `V` is one where all free inference
1010
/// variables have been rewritten to "canonical vars". These are
@@ -113,3 +113,257 @@ where
113113
self.variables.visit_with(folder)
114114
}
115115
}
116+
117+
/// Information about a canonical variable that is included with the
118+
/// canonical value. This is sufficient information for code to create
119+
/// a copy of the canonical value in some other inference context,
120+
/// with fresh inference variables replacing the canonical values.
121+
#[derive(derivative::Derivative)]
122+
#[derivative(
123+
Clone(bound = ""),
124+
Hash(bound = ""),
125+
Copy(bound = "CanonicalVarKind<I>: Copy"),
126+
Debug(bound = "")
127+
)]
128+
#[derive(TyDecodable, TyEncodable, HashStable_NoContext)]
129+
pub struct CanonicalVarInfo<I: Interner> {
130+
pub kind: CanonicalVarKind<I>,
131+
}
132+
133+
impl<I: Interner> PartialEq for CanonicalVarInfo<I> {
134+
fn eq(&self, other: &Self) -> bool {
135+
self.kind == other.kind
136+
}
137+
}
138+
139+
impl<I: Interner> Eq for CanonicalVarInfo<I> {}
140+
141+
impl<I: Interner> TypeVisitable<I> for CanonicalVarInfo<I>
142+
where
143+
I::Ty: TypeVisitable<I>,
144+
{
145+
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
146+
self.kind.visit_with(visitor)
147+
}
148+
}
149+
150+
impl<I: Interner> TypeFoldable<I> for CanonicalVarInfo<I>
151+
where
152+
I::Ty: TypeFoldable<I>,
153+
{
154+
fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
155+
Ok(CanonicalVarInfo { kind: self.kind.try_fold_with(folder)? })
156+
}
157+
}
158+
159+
impl<I: Interner> CanonicalVarInfo<I> {
160+
pub fn universe(&self) -> UniverseIndex {
161+
self.kind.universe()
162+
}
163+
164+
#[must_use]
165+
pub fn with_updated_universe(self, ui: UniverseIndex) -> CanonicalVarInfo<I> {
166+
CanonicalVarInfo { kind: self.kind.with_updated_universe(ui) }
167+
}
168+
169+
pub fn is_existential(&self) -> bool {
170+
match self.kind {
171+
CanonicalVarKind::Ty(_) => true,
172+
CanonicalVarKind::PlaceholderTy(_) => false,
173+
CanonicalVarKind::Region(_) => true,
174+
CanonicalVarKind::PlaceholderRegion(..) => false,
175+
CanonicalVarKind::Const(..) => true,
176+
CanonicalVarKind::PlaceholderConst(_, _) => false,
177+
CanonicalVarKind::Effect => true,
178+
}
179+
}
180+
181+
pub fn is_region(&self) -> bool {
182+
match self.kind {
183+
CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => true,
184+
CanonicalVarKind::Ty(_)
185+
| CanonicalVarKind::PlaceholderTy(_)
186+
| CanonicalVarKind::Const(_, _)
187+
| CanonicalVarKind::PlaceholderConst(_, _)
188+
| CanonicalVarKind::Effect => false,
189+
}
190+
}
191+
192+
pub fn expect_placeholder_index(self) -> usize {
193+
match self.kind {
194+
CanonicalVarKind::Ty(_)
195+
| CanonicalVarKind::Region(_)
196+
| CanonicalVarKind::Const(_, _)
197+
| CanonicalVarKind::Effect => panic!("expected placeholder: {self:?}"),
198+
199+
CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.var().as_usize(),
200+
CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.var().as_usize(),
201+
CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.var().as_usize(),
202+
}
203+
}
204+
}
205+
206+
/// Describes the "kind" of the canonical variable. This is a "kind"
207+
/// in the type-theory sense of the term -- i.e., a "meta" type system
208+
/// that analyzes type-like values.
209+
#[derive(derivative::Derivative)]
210+
#[derivative(Clone(bound = ""), Hash(bound = ""), Debug(bound = ""))]
211+
#[derive(TyDecodable, TyEncodable, HashStable_NoContext)]
212+
pub enum CanonicalVarKind<I: Interner> {
213+
/// Some kind of type inference variable.
214+
Ty(CanonicalTyVarKind),
215+
216+
/// A "placeholder" that represents "any type".
217+
PlaceholderTy(I::PlaceholderTy),
218+
219+
/// Region variable `'?R`.
220+
Region(UniverseIndex),
221+
222+
/// A "placeholder" that represents "any region". Created when you
223+
/// are solving a goal like `for<'a> T: Foo<'a>` to represent the
224+
/// bound region `'a`.
225+
PlaceholderRegion(I::PlaceholderRegion),
226+
227+
/// Some kind of const inference variable.
228+
Const(UniverseIndex, I::Ty),
229+
230+
/// Effect variable `'?E`.
231+
Effect,
232+
233+
/// A "placeholder" that represents "any const".
234+
PlaceholderConst(I::PlaceholderConst, I::Ty),
235+
}
236+
237+
impl<I: Interner> Copy for CanonicalVarKind<I>
238+
where
239+
I::PlaceholderTy: Copy,
240+
I::PlaceholderRegion: Copy,
241+
I::PlaceholderConst: Copy,
242+
I::Ty: Copy,
243+
{
244+
}
245+
246+
impl<I: Interner> PartialEq for CanonicalVarKind<I> {
247+
fn eq(&self, other: &Self) -> bool {
248+
match (self, other) {
249+
(Self::Ty(l0), Self::Ty(r0)) => l0 == r0,
250+
(Self::PlaceholderTy(l0), Self::PlaceholderTy(r0)) => l0 == r0,
251+
(Self::Region(l0), Self::Region(r0)) => l0 == r0,
252+
(Self::PlaceholderRegion(l0), Self::PlaceholderRegion(r0)) => l0 == r0,
253+
(Self::Const(l0, l1), Self::Const(r0, r1)) => l0 == r0 && l1 == r1,
254+
(Self::PlaceholderConst(l0, l1), Self::PlaceholderConst(r0, r1)) => {
255+
l0 == r0 && l1 == r1
256+
}
257+
_ => std::mem::discriminant(self) == std::mem::discriminant(other),
258+
}
259+
}
260+
}
261+
262+
impl<I: Interner> Eq for CanonicalVarKind<I> {}
263+
264+
impl<I: Interner> TypeVisitable<I> for CanonicalVarKind<I>
265+
where
266+
I::Ty: TypeVisitable<I>,
267+
{
268+
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
269+
match self {
270+
CanonicalVarKind::Ty(_)
271+
| CanonicalVarKind::PlaceholderTy(_)
272+
| CanonicalVarKind::Region(_)
273+
| CanonicalVarKind::PlaceholderRegion(_)
274+
| CanonicalVarKind::Effect => ControlFlow::Continue(()),
275+
CanonicalVarKind::Const(_, ty) | CanonicalVarKind::PlaceholderConst(_, ty) => {
276+
ty.visit_with(visitor)
277+
}
278+
}
279+
}
280+
}
281+
282+
impl<I: Interner> TypeFoldable<I> for CanonicalVarKind<I>
283+
where
284+
I::Ty: TypeFoldable<I>,
285+
{
286+
fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
287+
Ok(match self {
288+
CanonicalVarKind::Ty(kind) => CanonicalVarKind::Ty(kind),
289+
CanonicalVarKind::Region(kind) => CanonicalVarKind::Region(kind),
290+
CanonicalVarKind::Const(kind, ty) => {
291+
CanonicalVarKind::Const(kind, ty.try_fold_with(folder)?)
292+
}
293+
CanonicalVarKind::PlaceholderTy(placeholder) => {
294+
CanonicalVarKind::PlaceholderTy(placeholder)
295+
}
296+
CanonicalVarKind::PlaceholderRegion(placeholder) => {
297+
CanonicalVarKind::PlaceholderRegion(placeholder)
298+
}
299+
CanonicalVarKind::PlaceholderConst(placeholder, ty) => {
300+
CanonicalVarKind::PlaceholderConst(placeholder, ty.try_fold_with(folder)?)
301+
}
302+
CanonicalVarKind::Effect => CanonicalVarKind::Effect,
303+
})
304+
}
305+
}
306+
307+
impl<I: Interner> CanonicalVarKind<I> {
308+
pub fn universe(&self) -> UniverseIndex {
309+
match self {
310+
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) => *ui,
311+
CanonicalVarKind::Region(ui) => *ui,
312+
CanonicalVarKind::Const(ui, _) => *ui,
313+
CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe(),
314+
CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe(),
315+
CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.universe(),
316+
CanonicalVarKind::Ty(CanonicalTyVarKind::Float | CanonicalTyVarKind::Int) => {
317+
UniverseIndex::ROOT
318+
}
319+
CanonicalVarKind::Effect => UniverseIndex::ROOT,
320+
}
321+
}
322+
323+
/// Replaces the universe of this canonical variable with `ui`.
324+
///
325+
/// In case this is a float or int variable, this causes an ICE if
326+
/// the updated universe is not the root.
327+
pub fn with_updated_universe(self, ui: UniverseIndex) -> CanonicalVarKind<I> {
328+
match self {
329+
CanonicalVarKind::Ty(CanonicalTyVarKind::General(_)) => {
330+
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui))
331+
}
332+
CanonicalVarKind::Region(_) => CanonicalVarKind::Region(ui),
333+
CanonicalVarKind::Const(_, ty) => CanonicalVarKind::Const(ui, ty),
334+
335+
CanonicalVarKind::PlaceholderTy(placeholder) => {
336+
CanonicalVarKind::PlaceholderTy(placeholder.with_updated_universe(ui))
337+
}
338+
CanonicalVarKind::PlaceholderRegion(placeholder) => {
339+
CanonicalVarKind::PlaceholderRegion(placeholder.with_updated_universe(ui))
340+
}
341+
CanonicalVarKind::PlaceholderConst(placeholder, ty) => {
342+
CanonicalVarKind::PlaceholderConst(placeholder.with_updated_universe(ui), ty)
343+
}
344+
CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float)
345+
| CanonicalVarKind::Effect => {
346+
assert_eq!(ui, UniverseIndex::ROOT);
347+
self
348+
}
349+
}
350+
}
351+
}
352+
353+
/// Rust actually has more than one category of type variables;
354+
/// notably, the type variables we create for literals (e.g., 22 or
355+
/// 22.) can only be instantiated with integral/float types (e.g.,
356+
/// usize or f32). In order to faithfully reproduce a type, we need to
357+
/// know what set of types a given type variable can be unified with.
358+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
359+
#[derive(Decodable, Encodable, HashStable_NoContext)]
360+
pub enum CanonicalTyVarKind {
361+
/// General type variable `?T` that can be unified with arbitrary types.
362+
General(UniverseIndex),
363+
364+
/// Integral type variable `?I` (that can only be unified with integral types).
365+
Int,
366+
367+
/// Floating-point type variable `?F` (that can only be unified with float types).
368+
Float,
369+
}

‎compiler/rustc_type_ir/src/interner.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use smallvec::SmallVec;
22
use std::fmt::Debug;
33
use std::hash::Hash;
44

5-
use crate::{DebugWithInfcx, Mutability};
5+
use crate::{BoundVar, DebugWithInfcx, Mutability, UniverseIndex};
66

77
pub trait Interner: Sized {
88
type DefId: Clone + Debug + Hash + Ord;
@@ -26,7 +26,7 @@ pub trait Interner: Sized {
2626
type AliasTy: Clone + DebugWithInfcx<Self> + Hash + Ord;
2727
type ParamTy: Clone + Debug + Hash + Ord;
2828
type BoundTy: Clone + Debug + Hash + Ord;
29-
type PlaceholderTy: Clone + Debug + Hash + Ord;
29+
type PlaceholderTy: Clone + Debug + Hash + Ord + Placeholder;
3030
type InferTy: Clone + DebugWithInfcx<Self> + Hash + Ord;
3131

3232
// Things stored inside of tys
@@ -39,7 +39,7 @@ pub trait Interner: Sized {
3939
type Const: Clone + DebugWithInfcx<Self> + Hash + Ord;
4040
type InferConst: Clone + DebugWithInfcx<Self> + Hash + Ord;
4141
type AliasConst: Clone + DebugWithInfcx<Self> + Hash + Ord;
42-
type PlaceholderConst: Clone + Debug + Hash + Ord;
42+
type PlaceholderConst: Clone + Debug + Hash + Ord + Placeholder;
4343
type ParamConst: Clone + Debug + Hash + Ord;
4444
type BoundConst: Clone + Debug + Hash + Ord;
4545
type ValueConst: Clone + Debug + Hash + Ord;
@@ -51,7 +51,7 @@ pub trait Interner: Sized {
5151
type BoundRegion: Clone + Debug + Hash + Ord;
5252
type LateParamRegion: Clone + Debug + Hash + Ord;
5353
type InferRegion: Clone + DebugWithInfcx<Self> + Hash + Ord;
54-
type PlaceholderRegion: Clone + Debug + Hash + Ord;
54+
type PlaceholderRegion: Clone + Debug + Hash + Ord + Placeholder;
5555

5656
// Predicates
5757
type Predicate: Clone + Debug + Hash + Eq;
@@ -66,6 +66,14 @@ pub trait Interner: Sized {
6666
fn ty_and_mut_to_parts(ty_and_mut: Self::TypeAndMut) -> (Self::Ty, Mutability);
6767
}
6868

69+
/// Common capabilities of placeholder kinds
70+
pub trait Placeholder {
71+
fn universe(&self) -> UniverseIndex;
72+
fn var(&self) -> BoundVar;
73+
74+
fn with_updated_universe(self, ui: UniverseIndex) -> Self;
75+
}
76+
6977
/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`
7078
/// that produces `T` items. You could combine them with
7179
/// `f(&iter.collect::<Vec<_>>())`, but this requires allocating memory for the

0 commit comments

Comments
 (0)
Please sign in to comment.