@@ -43,14 +43,14 @@ pub fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> + Rela
4343 for_universe,
4444 root_term : term. into ( ) ,
4545 in_alias : false ,
46- needs_wf : false ,
46+ has_unconstrained_ty_var : false ,
4747 cache : Default :: default ( ) ,
4848 } ;
4949
5050 assert ! ( !term. has_escaping_bound_vars( ) ) ;
5151 let value_may_be_infer = generalizer. relate ( term, term) ?;
52- let needs_wf = generalizer. needs_wf ;
53- Ok ( Generalization { value_may_be_infer, needs_wf } )
52+ let has_unconstrained_ty_var = generalizer. has_unconstrained_ty_var ;
53+ Ok ( Generalization { value_may_be_infer, has_unconstrained_ty_var } )
5454}
5555
5656/// Abstracts the handling of region vars between HIR and MIR/NLL typechecking
@@ -150,8 +150,8 @@ struct Generalizer<'me, 'tcx, D> {
150150 /// hold by either normalizing the outer or the inner associated type.
151151 in_alias : bool ,
152152
153- /// See the field `needs_wf ` in `Generalization`.
154- needs_wf : bool ,
153+ /// See the field `has_unconstrained_ty_var ` in `Generalization`.
154+ has_unconstrained_ty_var : bool ,
155155}
156156
157157impl < ' tcx , D > Generalizer < ' _ , ' tcx , D > {
@@ -272,11 +272,10 @@ where
272272 }
273273 }
274274
275- // Bivariant: make a fresh var, but we
276- // may need a WF predicate. See
277- // comment on `needs_wf` field for
278- // more info.
279- ty:: Bivariant => self . needs_wf = true ,
275+ // Bivariant: make a fresh var, but remember that
276+ // it is unconstrained. See the comment in
277+ // `Generalization`.
278+ ty:: Bivariant => self . has_unconstrained_ty_var = true ,
280279
281280 // Co/contravariant: this will be
282281 // sufficiently constrained later on.
@@ -511,30 +510,27 @@ pub struct Generalization<T> {
511510 /// recursion.
512511 pub value_may_be_infer : T ,
513512
514- /// If true, then the generalized type may not be well-formed,
515- /// even if the source type is well-formed, so we should add an
516- /// additional check to enforce that it is. This arises in
517- /// particular around 'bivariant' type parameters that are only
518- /// constrained by a where-clause. As an example, imagine a type:
513+ /// In general, we do not check whether all types which occur during
514+ /// type checking are well-formed. We only check wf of user-provided types
515+ /// and when actually using a type, e.g. for method calls.
516+ ///
517+ /// This means that when subtyping, we may end up with unconstrained
518+ /// inference variables if a generalized type has bivariant parameters.
519+ /// A parameter may only be bivariant if it is constrained by a projection
520+ /// bound in a where-clause. As an example, imagine a type:
519521 ///
520522 /// struct Foo<A, B> where A: Iterator<Item = B> {
521523 /// data: A
522524 /// }
523525 ///
524- /// here, `A` will be covariant, but `B` is
525- /// unconstrained. However, whatever it is, for `Foo` to be WF, it
526- /// must be equal to `A::Item`. If we have an input `Foo<?A, ?B>`,
527- /// then after generalization we will wind up with a type like
528- /// `Foo<?C, ?D>`. When we enforce that `Foo<?A, ?B> <: Foo<?C,
529- /// ?D>` (or `>:`), we will wind up with the requirement that `?A
530- /// <: ?C`, but no particular relationship between `?B` and `?D`
531- /// (after all, we do not know the variance of the normalized form
532- /// of `A::Item` with respect to `A`). If we do nothing else, this
533- /// may mean that `?D` goes unconstrained (as in #41677). So, in
534- /// this scenario where we create a new type variable in a
535- /// bivariant context, we set the `needs_wf` flag to true. This
536- /// will force the calling code to check that `WF(Foo<?C, ?D>)`
537- /// holds, which in turn implies that `?C::Item == ?D`. So once
538- /// `?C` is constrained, that should suffice to restrict `?D`.
539- pub needs_wf : bool ,
526+ /// here, `A` will be covariant, but `B` is unconstrained.
527+ ///
528+ /// However, whatever it is, for `Foo` to be WF, it must be equal to `A::Item`.
529+ /// If we have an input `Foo<?A, ?B>`, then after generalization we will wind
530+ /// up with a type like `Foo<?C, ?D>`. When we enforce `Foo<?A, ?B> <: Foo<?C, ?D>`,
531+ /// we will wind up with the requirement that `?A <: ?C`, but no particular
532+ /// relationship between `?B` and `?D` (after all, these types may be completely
533+ /// different). If we do nothing else, this may mean that `?D` goes unconstrained
534+ /// (as in #41677). To avoid this we emit a `WellFormed` obligation in these cases.
535+ pub has_unconstrained_ty_var : bool ,
540536}
0 commit comments