Skip to content

Commit d1daf0e

Browse files
Uplift CanonicalVarInfo and friends
1 parent f26e8ff commit d1daf0e

File tree

4 files changed

+313
-158
lines changed

4 files changed

+313
-158
lines changed

compiler/rustc_middle/src/infer/canonical.rs

+4-153
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

+42
Original file line numberDiff line numberDiff line change
@@ -1517,8 +1517,36 @@ pub struct Placeholder<T> {
15171517

15181518
pub type PlaceholderRegion = Placeholder<BoundRegion>;
15191519

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

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

15291557
pub type PlaceholderConst = Placeholder<BoundVar>;
15301558

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

0 commit comments

Comments
 (0)