@@ -43,14 +43,14 @@ pub fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> + Rela
43
43
for_universe,
44
44
root_term : term. into ( ) ,
45
45
in_alias : false ,
46
- needs_wf : false ,
46
+ has_unconstrained_ty_var : false ,
47
47
cache : Default :: default ( ) ,
48
48
} ;
49
49
50
50
assert ! ( !term. has_escaping_bound_vars( ) ) ;
51
51
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 } )
54
54
}
55
55
56
56
/// Abstracts the handling of region vars between HIR and MIR/NLL typechecking
@@ -150,8 +150,8 @@ struct Generalizer<'me, 'tcx, D> {
150
150
/// hold by either normalizing the outer or the inner associated type.
151
151
in_alias : bool ,
152
152
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 ,
155
155
}
156
156
157
157
impl < ' tcx , D > Generalizer < ' _ , ' tcx , D > {
@@ -272,11 +272,10 @@ where
272
272
}
273
273
}
274
274
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 ,
280
279
281
280
// Co/contravariant: this will be
282
281
// sufficiently constrained later on.
@@ -511,30 +510,27 @@ pub struct Generalization<T> {
511
510
/// recursion.
512
511
pub value_may_be_infer : T ,
513
512
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:
519
521
///
520
522
/// struct Foo<A, B> where A: Iterator<Item = B> {
521
523
/// data: A
522
524
/// }
523
525
///
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 ,
540
536
}
0 commit comments