@@ -6,8 +6,8 @@ use rustc_hir::def_id::DefId;
66use rustc_middle:: bug;
77use rustc_middle:: ty:: error:: TypeError ;
88use 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} ;
1212use rustc_span:: Span ;
1313use tracing:: { debug, instrument, warn} ;
@@ -19,31 +19,6 @@ use crate::infer::type_variable::TypeVariableValue;
1919use crate :: infer:: unify_key:: ConstVariableValue ;
2020use 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-
4722impl < ' 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)
0 commit comments