@@ -22,7 +22,7 @@ impl<'tcx> InferCtxt<'tcx> {
2222     /// subtyping could occur. This also does the occurs checks, detecting whether 
2323     /// instantiating `target_vid` would result in a cyclic type. We eagerly error 
2424     /// in this case. 
25-      #[ instrument( skip( self ,  relation,  target_is_expected) ,  level =  "debug" ) ]  
25+      #[ instrument( level =  "debug" ,   skip( self ,  relation,  target_is_expected) ) ]  
2626    pub ( super )  fn  instantiate_ty_var < R :  ObligationEmittingRelation < ' tcx > > ( 
2727        & self , 
2828        relation :  & mut  R , 
@@ -158,36 +158,48 @@ impl<'tcx> InferCtxt<'tcx> {
158158     /// As `3 + 4` contains `N` in its args, this must not succeed. 
159159     /// 
160160     /// See `tests/ui/const-generics/occurs-check/` for more examples where this is relevant. 
161-      #[ instrument( level = "debug" ,  skip( self ) ) ]  
162-     pub ( super )  fn  instantiate_const_var ( 
161+      #[ instrument( level = "debug" ,  skip( self ,  relation ) ) ]  
162+     pub ( super )  fn  instantiate_const_var < R :   ObligationEmittingRelation < ' tcx > > ( 
163163        & self , 
164+         relation :  & mut  R , 
165+         target_is_expected :  bool , 
164166        target_vid :  ty:: ConstVid , 
165167        source_ct :  ty:: Const < ' tcx > , 
166-     )  -> RelateResult < ' tcx ,  ty:: Const < ' tcx > >  { 
167-         let  span = match  self . inner . borrow_mut ( ) . const_unification_table ( ) . probe_value ( target_vid)  { 
168-             ConstVariableValue :: Known  {  value }  => { 
169-                 bug ! ( "instantiating a known const var: {target_vid:?} {value} {source_ct}" ) 
170-             } 
171-             ConstVariableValue :: Unknown  {  origin,  universe :  _ }  => origin. span , 
172-         } ; 
168+     )  -> RelateResult < ' tcx ,  ( ) >  { 
173169        // FIXME(generic_const_exprs): Occurs check failures for unevaluated 
174170        // constants and generic expressions are not yet handled correctly. 
175171        let  Generalization  {  value_may_be_infer :  generalized_ct,  has_unconstrained_ty_var }  =
176-             self . generalize ( span,  target_vid,  ty:: Variance :: Invariant ,  source_ct) ?; 
172+             self . generalize ( relation . span ( ) ,  target_vid,  ty:: Variance :: Invariant ,  source_ct) ?; 
177173
178174        debug_assert ! ( !generalized_ct. is_ct_infer( ) ) ; 
179175        if  has_unconstrained_ty_var { 
180-             span_bug ! ( span ,   "unconstrained ty var when generalizing `{source_ct:?}`" ) ; 
176+             bug ! ( "unconstrained ty var when generalizing `{source_ct:?}`" ) ; 
181177        } 
182178
183179        self . inner 
184180            . borrow_mut ( ) 
185181            . const_unification_table ( ) 
186182            . union_value ( target_vid,  ConstVariableValue :: Known  {  value :  generalized_ct } ) ; 
187183
188-         // FIXME(generic_const_exprs): We have to make sure we actually equate 
189-         // `generalized_ct` and `source_ct` here. 
190-         Ok ( generalized_ct) 
184+         // HACK: make sure that we `a_is_expected` continues to be 
185+         // correct when relating the generalized type with the source. 
186+         if  target_is_expected == relation. a_is_expected ( )  { 
187+             relation. relate_with_variance ( 
188+                 ty:: Variance :: Invariant , 
189+                 ty:: VarianceDiagInfo :: default ( ) , 
190+                 generalized_ct, 
191+                 source_ct, 
192+             ) ?; 
193+         }  else  { 
194+             relation. relate_with_variance ( 
195+                 ty:: Variance :: Invariant , 
196+                 ty:: VarianceDiagInfo :: default ( ) , 
197+                 source_ct, 
198+                 generalized_ct, 
199+             ) ?; 
200+         } 
201+ 
202+         Ok ( ( ) ) 
191203    } 
192204
193205    /// Attempts to generalize `source_term` for the type variable `target_vid`. 
@@ -287,6 +299,49 @@ impl<'tcx> Generalizer<'_, 'tcx> {
287299            ty:: TermKind :: Const ( ct)  => TypeError :: CyclicConst ( ct) , 
288300        } 
289301    } 
302+ 
303+     /// An occurs check failure inside of an alias does not mean 
304+      /// that the types definitely don't unify. We may be able 
305+      /// to normalize the alias after all. 
306+      /// 
307+      /// We handle this by lazily equating the alias and generalizing 
308+      /// it to an inference variable. 
309+      /// 
310+      /// This is incomplete and will hopefully soon get fixed by #119106. 
311+      fn  generalize_alias_ty ( 
312+         & mut  self , 
313+         alias :  ty:: AliasTy < ' tcx > , 
314+     )  -> Result < Ty < ' tcx > ,  TypeError < ' tcx > >  { 
315+         let  is_nested_alias = mem:: replace ( & mut  self . in_alias ,  true ) ; 
316+         let  result = match  self . relate ( alias,  alias)  { 
317+             Ok ( alias)  => Ok ( alias. to_ty ( self . tcx ( ) ) ) , 
318+             Err ( e)  => { 
319+                 if  is_nested_alias { 
320+                     return  Err ( e) ; 
321+                 }  else  { 
322+                     let  mut  visitor = MaxUniverse :: new ( ) ; 
323+                     alias. visit_with ( & mut  visitor) ; 
324+                     let  infer_replacement_is_complete =
325+                         self . for_universe . can_name ( visitor. max_universe ( ) ) 
326+                             && !alias. has_escaping_bound_vars ( ) ; 
327+                     if  !infer_replacement_is_complete { 
328+                         warn ! ( "may incompletely handle alias type: {alias:?}" ) ; 
329+                     } 
330+ 
331+                     debug ! ( "generalization failure in alias" ) ; 
332+                     Ok ( self . infcx . next_ty_var_in_universe ( 
333+                         TypeVariableOrigin  { 
334+                             kind :  TypeVariableOriginKind :: MiscVariable , 
335+                             span :  self . span , 
336+                         } , 
337+                         self . for_universe , 
338+                     ) ) 
339+                 } 
340+             } 
341+         } ; 
342+         self . in_alias  = is_nested_alias; 
343+         result
344+     } 
290345} 
291346
292347impl < ' tcx >  TypeRelation < ' tcx >  for  Generalizer < ' _ ,  ' tcx >  { 
@@ -433,43 +488,7 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
433488                } 
434489            } 
435490
436-             ty:: Alias ( kind,  data)  => { 
437-                 // An occurs check failure inside of an alias does not mean 
438-                 // that the types definitely don't unify. We may be able 
439-                 // to normalize the alias after all. 
440-                 // 
441-                 // We handle this by lazily equating the alias and generalizing 
442-                 // it to an inference variable. 
443-                 let  is_nested_alias = mem:: replace ( & mut  self . in_alias ,  true ) ; 
444-                 let  result = match  self . relate ( data,  data)  { 
445-                     Ok ( data)  => Ok ( Ty :: new_alias ( self . tcx ( ) ,  kind,  data) ) , 
446-                     Err ( e)  => { 
447-                         if  is_nested_alias { 
448-                             return  Err ( e) ; 
449-                         }  else  { 
450-                             let  mut  visitor = MaxUniverse :: new ( ) ; 
451-                             t. visit_with ( & mut  visitor) ; 
452-                             let  infer_replacement_is_complete =
453-                                 self . for_universe . can_name ( visitor. max_universe ( ) ) 
454-                                     && !t. has_escaping_bound_vars ( ) ; 
455-                             if  !infer_replacement_is_complete { 
456-                                 warn ! ( "may incompletely handle alias type: {t:?}" ) ; 
457-                             } 
458- 
459-                             debug ! ( "generalization failure in alias" ) ; 
460-                             Ok ( self . infcx . next_ty_var_in_universe ( 
461-                                 TypeVariableOrigin  { 
462-                                     kind :  TypeVariableOriginKind :: MiscVariable , 
463-                                     span :  self . span , 
464-                                 } , 
465-                                 self . for_universe , 
466-                             ) ) 
467-                         } 
468-                     } 
469-                 } ; 
470-                 self . in_alias  = is_nested_alias; 
471-                 result
472-             } 
491+             ty:: Alias ( _,  data)  => self . generalize_alias_ty ( data) , 
473492
474493            _ => relate:: structurally_relate_tys ( self ,  t,  t) , 
475494        } ?; 
0 commit comments