@@ -38,31 +38,6 @@ 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-
6641 /// The idea is that we should ensure that the type variable `target_vid`
6742 /// is equal to, a subtype of, or a supertype of `source_ty`.
6843 ///
@@ -86,31 +61,53 @@ impl<'tcx> InferCtxt<'tcx> {
8661 ) -> RelateResult < ' tcx , ( ) > {
8762 debug_assert ! ( self . inner. borrow_mut( ) . type_variables( ) . probe( target_vid) . is_unknown( ) ) ;
8863
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- } ;
64+ let generalized_ty = if self . next_trait_solver ( )
65+ && matches ! ( relation. structurally_relate_aliases( ) , StructurallyRelateAliases :: No )
66+ && let ty:: Alias ( _, alias) = source_ty. kind ( )
67+ {
68+ let normalized_alias = relation. try_eagerly_normalize_alias ( * alias) ;
69+
70+ if normalized_alias. is_ty_var ( ) {
71+ normalized_alias
72+ } else {
73+ let Generalization { value_may_be_infer : generalized_ty } = self . generalize (
74+ relation. span ( ) ,
75+ GeneralizerState :: ShallowStructurallyRelateAliases ,
76+ target_vid,
77+ instantiation_variance,
78+ normalized_alias,
79+ & mut |alias| relation. try_eagerly_normalize_alias ( alias) ,
80+ ) ?;
81+
82+ // The only way to get a tyvar back is if the outermost type is an alias.
83+ // However, here, though we know it *is* an alias, we initialize the generalizer
84+ // with `ShallowStructurallyRelateAliases` so we treat the outermost alias as rigid,
85+ // ensuring this is never a tyvar.
86+ assert ! ( !generalized_ty. is_ty_var( ) ) ;
87+
88+ generalized_ty
89+ }
90+ } else {
91+ // Generalize `source_ty` depending on the current variance. As an example, assume
92+ // `?target <: &'x ?1`, where `'x` is some free region and `?1` is an inference
93+ // variable.
94+ //
95+ // Then the `generalized_ty` would be `&'?2 ?3`, where `'?2` and `?3` are fresh
96+ // region/type inference variables.
97+ //
98+ // We then relate `generalized_ty <: source_ty`, adding constraints like `'x: '?2` and
99+ // `?1 <: ?3`.
100+ let Generalization { value_may_be_infer : generalized_ty } = self . generalize (
101+ relation. span ( ) ,
102+ relation. structurally_relate_aliases ( ) . into ( ) ,
103+ target_vid,
104+ instantiation_variance,
105+ source_ty,
106+ & mut |alias| relation. try_eagerly_normalize_alias ( alias) ,
107+ ) ?;
108+
109+ generalized_ty
110+ } ;
114111
115112 // Finally, relate `generalized_ty` to `source_ty`, as described in previous comment.
116113 //
@@ -239,7 +236,7 @@ impl<'tcx> InferCtxt<'tcx> {
239236 // constants and generic expressions are not yet handled correctly.
240237 let Generalization { value_may_be_infer : generalized_ct } = self . generalize (
241238 relation. span ( ) ,
242- relation. structurally_relate_aliases ( ) ,
239+ relation. structurally_relate_aliases ( ) . into ( ) ,
243240 target_vid,
244241 ty:: Invariant ,
245242 source_ct,
@@ -279,7 +276,7 @@ impl<'tcx> InferCtxt<'tcx> {
279276 fn generalize < T : Into < Term < ' tcx > > + Relate < TyCtxt < ' tcx > > > (
280277 & self ,
281278 span : Span ,
282- structurally_relate_aliases : StructurallyRelateAliases ,
279+ initial_state : GeneralizerState ,
283280 target_vid : impl Into < TermVid > ,
284281 ambient_variance : ty:: Variance ,
285282 source_term : T ,
@@ -303,10 +300,7 @@ impl<'tcx> InferCtxt<'tcx> {
303300 for_universe,
304301 root_term : source_term. into ( ) ,
305302 ambient_variance,
306- state : match structurally_relate_aliases {
307- StructurallyRelateAliases :: No => GeneralizerState :: Default ,
308- StructurallyRelateAliases :: Yes => GeneralizerState :: StructurallyRelateAliases ,
309- } ,
303+ state : initial_state,
310304 cache : Default :: default ( ) ,
311305 normalize,
312306 } ;
@@ -365,6 +359,15 @@ enum GeneralizerState {
365359 StructurallyRelateAliases ,
366360}
367361
362+ impl From < StructurallyRelateAliases > for GeneralizerState {
363+ fn from ( structurally_relate_aliases : StructurallyRelateAliases ) -> Self {
364+ match structurally_relate_aliases {
365+ StructurallyRelateAliases :: No => GeneralizerState :: Default ,
366+ StructurallyRelateAliases :: Yes => GeneralizerState :: StructurallyRelateAliases ,
367+ }
368+ }
369+ }
370+
368371/// The "generalizer" is used when handling inference variables.
369372///
370373/// The basic strategy for handling a constraint like `?A <: B` is to
0 commit comments