@@ -38,6 +38,31 @@ impl From<ty::ConstVid> for TermVid {
3838}
3939
4040impl < ' tcx > InferCtxt < ' tcx > {
41+ fn check_generalized_alias_normalizes_to_tyvar < R : PredicateEmittingRelation < Self > > (
42+ & self ,
43+ relation : & mut R ,
44+ source_ty : Ty < ' tcx > ,
45+ ) -> Option < Ty < ' tcx > > {
46+ if !self . next_trait_solver ( )
47+ || matches ! ( relation. structurally_relate_aliases( ) , StructurallyRelateAliases :: Yes )
48+ {
49+ return None ;
50+ }
51+
52+ // If we get an alias
53+ let ty:: Alias ( _, alias) = source_ty. kind ( ) else {
54+ return None ;
55+ } ;
56+
57+ if alias. has_escaping_bound_vars ( ) {
58+ return None ;
59+ }
60+
61+ let normalized_alias = relation. try_eagerly_normalize_alias ( * alias) ;
62+
63+ normalized_alias. is_ty_var ( ) . then_some ( normalized_alias)
64+ }
65+
4166 /// The idea is that we should ensure that the type variable `target_vid`
4267 /// is equal to, a subtype of, or a supertype of `source_ty`.
4368 ///
@@ -51,7 +76,7 @@ impl<'tcx> InferCtxt<'tcx> {
5176 /// `TypeRelation`. Do not use this, and instead please use `At::eq`, for all
5277 /// other usecases (i.e. setting the value of a type var).
5378 #[ instrument( level = "debug" , skip( self , relation) ) ]
54- pub fn instantiate_ty_var < R : PredicateEmittingRelation < InferCtxt < ' tcx > > > (
79+ pub fn instantiate_ty_var < R : PredicateEmittingRelation < Self > > (
5580 & self ,
5681 relation : & mut R ,
5782 target_is_expected : bool ,
@@ -61,38 +86,42 @@ impl<'tcx> InferCtxt<'tcx> {
6186 ) -> RelateResult < ' tcx , ( ) > {
6287 debug_assert ! ( self . inner. borrow_mut( ) . type_variables( ) . probe( target_vid) . is_unknown( ) ) ;
6388
64- // Generalize `source_ty` depending on the current variance. As an example, assume
65- // `?target <: &'x ?1`, where `'x` is some free region and `?1` is an inference
66- // variable.
67- //
68- // Then the `generalized_ty` would be `&'?2 ?3`, where `'?2` and `?3` are fresh
69- // region/type inference variables.
70- //
71- // We then relate `generalized_ty <: source_ty`, adding constraints like `'x: '?2` and
72- // `?1 <: ?3`.
73- let Generalization { value_may_be_infer : generalized_ty } = self . generalize (
74- relation. span ( ) ,
75- relation. structurally_relate_aliases ( ) ,
76- target_vid,
77- instantiation_variance,
78- source_ty,
79- & mut |alias| relation. try_eagerly_normalize_alias ( alias) ,
80- ) ?;
81-
82- // Constrain `b_vid` to the generalized type `generalized_ty`.
83- if let & ty:: Infer ( ty:: TyVar ( generalized_vid) ) = generalized_ty. kind ( ) {
84- self . inner . borrow_mut ( ) . type_variables ( ) . equate ( target_vid, generalized_vid) ;
85- } else {
86- self . inner . borrow_mut ( ) . type_variables ( ) . instantiate ( target_vid, generalized_ty) ;
87- }
89+ let generalized_ty =
90+ match self . check_generalized_alias_normalizes_to_tyvar ( relation, source_ty) {
91+ Some ( tyvar) => tyvar,
92+ None => {
93+ // Generalize `source_ty` depending on the current variance. As an example, assume
94+ // `?target <: &'x ?1`, where `'x` is some free region and `?1` is an inference
95+ // variable.
96+ //
97+ // Then the `generalized_ty` would be `&'?2 ?3`, where `'?2` and `?3` are fresh
98+ // region/type inference variables.
99+ //
100+ // We then relate `generalized_ty <: source_ty`, adding constraints like `'x: '?2` and
101+ // `?1 <: ?3`.
102+ let generalizer = self . generalize (
103+ relation. span ( ) ,
104+ relation. structurally_relate_aliases ( ) ,
105+ target_vid,
106+ instantiation_variance,
107+ source_ty,
108+ & mut |alias| relation. try_eagerly_normalize_alias ( alias) ,
109+ ) ?;
110+
111+ generalizer. value_may_be_infer
112+ }
113+ } ;
88114
89115 // Finally, relate `generalized_ty` to `source_ty`, as described in previous comment.
90116 //
91117 // FIXME(#16847): This code is non-ideal because all these subtype
92118 // relations wind up attributed to the same spans. We need
93119 // to associate causes/spans with each of the relations in
94120 // the stack to get this right.
95- if generalized_ty. is_ty_var ( ) {
121+ if let & ty:: Infer ( ty:: TyVar ( generalized_vid) ) = generalized_ty. kind ( ) {
122+ // Constrain `b_vid` to the generalized type variable.
123+ self . inner . borrow_mut ( ) . type_variables ( ) . equate ( target_vid, generalized_vid) ;
124+
96125 // This happens for cases like `<?0 as Trait>::Assoc == ?0`.
97126 // We can't instantiate `?0` here as that would result in a
98127 // cyclic type. We instead delay the unification in case
@@ -133,6 +162,9 @@ impl<'tcx> InferCtxt<'tcx> {
133162 }
134163 }
135164 } else {
165+ // Constrain `b_vid` to the generalized type `generalized_ty`.
166+ self . inner . borrow_mut ( ) . type_variables ( ) . instantiate ( target_vid, generalized_ty) ;
167+
136168 // NOTE: The `instantiation_variance` is not the same variance as
137169 // used by the relation. When instantiating `b`, `target_is_expected`
138170 // is flipped and the `instantiation_variance` is also flipped. To
0 commit comments