Skip to content

Commit ee19635

Browse files
committed
Move TermVid to rustc_type_ir
1 parent ac88926 commit ee19635

6 files changed

Lines changed: 88 additions & 78 deletions

File tree

compiler/rustc_infer/src/infer/relate/generalize.rs

Lines changed: 42 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use rustc_hir::def_id::DefId;
66
use rustc_middle::bug;
77
use rustc_middle::ty::error::TypeError;
88
use rustc_middle::ty::{
9-
self, AliasRelationDirection, InferConst, Term, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
10-
TypeVisitableExt, TypeVisitor, TypingMode,
9+
self, AliasRelationDirection, InferConst, Term, TermVid, Ty, TyCtxt, TypeSuperVisitable,
10+
TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
1111
};
1212
use rustc_span::Span;
1313
use tracing::{debug, instrument, warn};
@@ -19,31 +19,6 @@ use crate::infer::type_variable::TypeVariableValue;
1919
use crate::infer::unify_key::ConstVariableValue;
2020
use crate::infer::{InferCtxt, RegionVariableOrigin, relate};
2121

22-
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
23-
enum TermVid {
24-
Ty(ty::TyVid),
25-
Const(ty::ConstVid),
26-
}
27-
28-
impl From<ty::TyVid> for TermVid {
29-
fn from(value: ty::TyVid) -> Self {
30-
TermVid::Ty(value)
31-
}
32-
}
33-
34-
impl From<ty::ConstVid> for TermVid {
35-
fn from(value: ty::ConstVid) -> Self {
36-
TermVid::Const(value)
37-
}
38-
}
39-
40-
fn term_vid<'tcx>(term: Term<'tcx>) -> Option<TermVid> {
41-
match term.kind() {
42-
rustc_type_ir::TermKind::Ty(ty) => ty.ty_vid().map(TermVid::Ty),
43-
rustc_type_ir::TermKind::Const(ct) => ct.ct_vid().map(TermVid::Const),
44-
}
45-
}
46-
4722
impl<'tcx> InferCtxt<'tcx> {
4823
/// The idea is that we should ensure that the type variable `target_vid`
4924
/// is equal to, a subtype of, or a supertype of `source_ty`.
@@ -153,7 +128,7 @@ impl<'tcx> InferCtxt<'tcx> {
153128
{
154129
let normalized_alias = relation.try_eagerly_normalize_alias(alias);
155130

156-
if term_vid(normalized_alias).is_some() {
131+
if normalized_alias.is_infer() {
157132
normalized_alias
158133
} else {
159134
let Generalization { value_may_be_infer: generalized_term } = self.generalize(
@@ -169,19 +144,19 @@ impl<'tcx> InferCtxt<'tcx> {
169144
// However, here, though we know it *is* an alias, we initialize the generalizer
170145
// with `ShallowStructurallyRelateAliases` so we treat the outermost alias as rigid,
171146
// ensuring this is never a tyvar.
172-
assert!(term_vid(generalized_term).is_none());
147+
assert!(!generalized_term.is_infer());
173148

174149
generalized_term
175150
}
176151
} else {
177-
// Generalize `source_ty` depending on the current variance. As an example, assume
152+
// Generalize `source_term` depending on the current variance. As an example, assume
178153
// `?target <: &'x ?1`, where `'x` is some free region and `?1` is an inference
179154
// variable.
180155
//
181-
// Then the `generalized_ty` would be `&'?2 ?3`, where `'?2` and `?3` are fresh
156+
// Then the `generalized_term` would be `&'?2 ?3`, where `'?2` and `?3` are fresh
182157
// region/type inference variables.
183158
//
184-
// We then relate `generalized_ty <: source_ty`, adding constraints like `'x: '?2` and
159+
// We then relate `generalized_term <: source_term`, adding constraints like `'x: '?2` and
185160
// `?1 <: ?3`.
186161
let Generalization { value_may_be_infer: generalized_term } = self.generalize(
187162
relation.span(),
@@ -198,15 +173,15 @@ impl<'tcx> InferCtxt<'tcx> {
198173
generalized_term
199174
};
200175

201-
// Finally, relate `generalized_ty` to `source_ty`, as described in previous comment.
176+
// Finally, relate `generalized_term` to `source_term`, as described in previous comment.
202177
//
203178
// FIXME(#16847): This code is non-ideal because all these subtype
204179
// relations wind up attributed to the same spans. We need
205180
// to associate causes/spans with each of the relations in
206181
// the stack to get this right.
207-
if let Some(generalized_vid) = term_vid(generalized_term) {
182+
if let Some(generalized_vid) = generalized_term.term_vid() {
208183
// Constrain `b_vid` to the generalized type variable.
209-
self.equate(target_vid, generalized_vid);
184+
self.union_vars(target_vid, generalized_vid);
210185

211186
// This happens for cases like `<?0 as Trait>::Assoc == ?0`.
212187
// We can't instantiate `?0` here as that would result in a
@@ -229,39 +204,41 @@ impl<'tcx> InferCtxt<'tcx> {
229204

230205
relation.register_predicates([ty::PredicateKind::AliasRelate(lhs, rhs, direction)]);
231206
} else {
232-
match source_term.kind() {
233-
ty::TermKind::Ty(source_ty) => {
234-
match source_ty.kind() {
235-
&ty::Alias(ty::Projection, data) => {
236-
// FIXME: This does not handle subtyping correctly, we could instead
237-
// create a new inference variable `?normalized_source`, emitting
238-
// `Projection(normalized_source, ?ty_normalized)` and
239-
// `?normalized_source <: generalized_ty`.
240-
relation.register_predicates([ty::ProjectionPredicate {
241-
projection_term: data.into(),
242-
term: generalized_term,
243-
}]);
244-
}
245-
// The old solver only accepts projection predicates for associated types.
246-
ty::Alias(ty::Inherent | ty::Free | ty::Opaque, _) => {
247-
return Err(TypeError::CyclicTy(source_ty));
248-
}
249-
_ => bug!("generalized `{source_ty:?} to infer, not an alias"),
250-
}
207+
let Some(source_alias) = source_term.to_alias_term() else {
208+
bug!("generalized `{source_term:?} to infer, not an alias");
209+
};
210+
match source_alias.kind(self.tcx) {
211+
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
212+
// FIXME: This does not handle subtyping correctly, we could
213+
// instead create a new inference variable `?normalized_source`, emitting
214+
// `Projection(normalized_source, ?ty_normalized)` and
215+
// `?normalized_source <: generalized_term`.
216+
relation.register_predicates([ty::ProjectionPredicate {
217+
projection_term: source_alias,
218+
term: generalized_term,
219+
}]);
220+
}
221+
// The old solver only accepts projection predicates for associated types.
222+
ty::AliasTermKind::InherentTy
223+
| ty::AliasTermKind::FreeTy
224+
| ty::AliasTermKind::OpaqueTy => {
225+
return Err(TypeError::CyclicTy(source_term.expect_type()));
251226
}
252-
ty::TermKind::Const(source_ct) => {
253-
return Err(TypeError::CyclicConst(source_ct));
227+
ty::AliasTermKind::InherentConst
228+
| ty::AliasTermKind::FreeConst
229+
| ty::AliasTermKind::UnevaluatedConst => {
230+
return Err(TypeError::CyclicConst(source_term.expect_const()));
254231
}
255232
}
256233
}
257234
} else {
258-
// Constrain `b_vid` to the generalized type `generalized_ty`.
259-
self.instantiate(target_vid, generalized_term);
235+
// Constrain `b_vid` to the generalized type `generalized_term`.
236+
self.union_var_term(target_vid, generalized_term);
260237

261238
// NOTE: The `instantiation_variance` is not the same variance as
262239
// used by the relation. When instantiating `b`, `target_is_expected`
263240
// is flipped and the `instantiation_variance` is also flipped. To
264-
// constrain the `generalized_ty` while using the original relation,
241+
// constrain the `generalized_term` while using the original relation,
265242
// we therefore only have to flip the arguments.
266243
//
267244
// ```ignore (not code)
@@ -308,7 +285,9 @@ impl<'tcx> InferCtxt<'tcx> {
308285
Ok(())
309286
}
310287

311-
fn equate(&self, l: TermVid, r: TermVid) {
288+
/// This is a thin wrapper around inserting into the var tables. You probably want
289+
/// [`Self::instantiate_var`] instead, which calls this method.
290+
fn union_vars(&self, l: TermVid, r: TermVid) {
312291
match (l, r) {
313292
(TermVid::Ty(l), TermVid::Ty(r)) => {
314293
self.inner.borrow_mut().type_variables().equate(l, r)
@@ -320,7 +299,9 @@ impl<'tcx> InferCtxt<'tcx> {
320299
}
321300
}
322301

323-
fn instantiate(&self, l: TermVid, r: ty::Term<'tcx>) {
302+
/// This is a thin wrapper around inserting into the var tables. You probably want
303+
/// [`Self::instantiate_var`] instead, which calls this method.
304+
fn union_var_term(&self, l: TermVid, r: ty::Term<'tcx>) {
324305
match (l, r.kind()) {
325306
(TermVid::Ty(l), ty::TermKind::Ty(r)) => {
326307
self.inner.borrow_mut().type_variables().instantiate(l, r)

compiler/rustc_middle/src/ty/consts.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,6 @@ impl<'tcx> Const<'tcx> {
323323
matches!(self.kind(), ty::ConstKind::Infer(_))
324324
}
325325

326-
pub fn is_ct_var(self) -> bool {
327-
matches!(self.kind(), ConstKind::Infer(ty::InferConst::Var(_)))
328-
}
329-
330326
pub fn ct_vid(self) -> Option<ty::ConstVid> {
331327
match self.kind() {
332328
ConstKind::Infer(ty::InferConst::Var(vid)) => Some(vid),

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,13 @@ impl<'tcx> Term<'tcx> {
621621
}
622622
}
623623

624+
pub fn term_vid(self) -> Option<TermVid> {
625+
match self.kind() {
626+
TermKind::Ty(ty) => ty.ty_vid().map(TermVid::Ty),
627+
TermKind::Const(ct) => ct.ct_vid().map(TermVid::Const),
628+
}
629+
}
630+
624631
pub fn is_trivially_wf(&self, tcx: TyCtxt<'tcx>) -> bool {
625632
match self.kind() {
626633
TermKind::Ty(ty) => ty.is_trivially_wf(tcx),

compiler/rustc_type_ir/src/generic_arg.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,3 @@ pub enum GenericArgKind<I: Interner> {
1818
}
1919

2020
impl<I: Interner> Eq for GenericArgKind<I> {}
21-
22-
#[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)]
23-
#[derive(GenericTypeVisitable)]
24-
#[cfg_attr(
25-
feature = "nightly",
26-
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
27-
)]
28-
pub enum TermKind<I: Interner> {
29-
Ty(I::Ty),
30-
Const(I::Const),
31-
}
32-
33-
impl<I: Interner> Eq for TermKind<I> {}

compiler/rustc_type_ir/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ mod pattern;
5151
mod predicate;
5252
mod predicate_kind;
5353
mod region_kind;
54+
mod term;
5455
mod ty_info;
5556
mod ty_kind;
5657
mod upcast;
@@ -78,6 +79,7 @@ pub use predicate_kind::*;
7879
pub use region_kind::*;
7980
pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy};
8081
use rustc_type_ir_macros::GenericTypeVisitable;
82+
pub use term::*;
8183
pub use ty_info::*;
8284
pub use ty_kind::*;
8385
pub use upcast::*;

compiler/rustc_type_ir/src/term.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use derive_where::derive_where;
2+
#[cfg(feature = "nightly")]
3+
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
4+
use rustc_type_ir_macros::GenericTypeVisitable;
5+
6+
use crate::{ConstVid, Interner, TyVid};
7+
8+
#[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)]
9+
#[derive(GenericTypeVisitable)]
10+
#[cfg_attr(
11+
feature = "nightly",
12+
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
13+
)]
14+
pub enum TermKind<I: Interner> {
15+
Ty(I::Ty),
16+
Const(I::Const),
17+
}
18+
19+
impl<I: Interner> Eq for TermKind<I> {}
20+
21+
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
22+
pub enum TermVid {
23+
Ty(TyVid),
24+
Const(ConstVid),
25+
}
26+
27+
impl From<TyVid> for TermVid {
28+
fn from(value: TyVid) -> Self {
29+
TermVid::Ty(value)
30+
}
31+
}
32+
33+
impl From<ConstVid> for TermVid {
34+
fn from(value: ConstVid) -> Self {
35+
TermVid::Const(value)
36+
}
37+
}

0 commit comments

Comments
 (0)