@@ -5,6 +5,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
55use rustc_hir:: def_id:: DefId ;
66use rustc_middle:: bug;
77use rustc_middle:: ty:: error:: TypeError ;
8+ use rustc_middle:: ty:: relate:: { relate_args_invariantly, relate_args_with_variances} ;
89use rustc_middle:: ty:: {
910 self , AliasRelationDirection , InferConst , Term , Ty , TyCtxt , TypeSuperVisitable , TypeVisitable ,
1011 TypeVisitableExt , TypeVisitor , TypingMode ,
@@ -70,13 +71,14 @@ impl<'tcx> InferCtxt<'tcx> {
7071 //
7172 // We then relate `generalized_ty <: source_ty`, adding constraints like `'x: '?2` and
7273 // `?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- ) ?;
74+ let Generalization { value_may_be_infer : generalized_ty, has_unconstrained_ty_var } = self
75+ . generalize (
76+ relation. span ( ) ,
77+ relation. structurally_relate_aliases ( ) ,
78+ target_vid,
79+ instantiation_variance,
80+ source_ty,
81+ ) ?;
8082
8183 // Constrain `b_vid` to the generalized type `generalized_ty`.
8284 if let & ty:: Infer ( ty:: TyVar ( generalized_vid) ) = generalized_ty. kind ( ) {
@@ -85,6 +87,11 @@ impl<'tcx> InferCtxt<'tcx> {
8587 self . inner . borrow_mut ( ) . type_variables ( ) . instantiate ( target_vid, generalized_ty) ;
8688 }
8789
90+ // See the comment on `Generalization::has_unconstrained_ty_var`.
91+ if has_unconstrained_ty_var {
92+ relation. register_predicates ( [ ty:: ClauseKind :: WellFormed ( generalized_ty. into ( ) ) ] ) ;
93+ }
94+
8895 // Finally, relate `generalized_ty` to `source_ty`, as described in previous comment.
8996 //
9097 // FIXME(#16847): This code is non-ideal because all these subtype
@@ -204,15 +211,19 @@ impl<'tcx> InferCtxt<'tcx> {
204211 ) -> RelateResult < ' tcx , ( ) > {
205212 // FIXME(generic_const_exprs): Occurs check failures for unevaluated
206213 // constants and generic expressions are not yet handled correctly.
207- let Generalization { value_may_be_infer : generalized_ct } = self . generalize (
208- relation. span ( ) ,
209- relation. structurally_relate_aliases ( ) ,
210- target_vid,
211- ty:: Invariant ,
212- source_ct,
213- ) ?;
214+ let Generalization { value_may_be_infer : generalized_ct, has_unconstrained_ty_var } = self
215+ . generalize (
216+ relation. span ( ) ,
217+ relation. structurally_relate_aliases ( ) ,
218+ target_vid,
219+ ty:: Invariant ,
220+ source_ct,
221+ ) ?;
214222
215223 debug_assert ! ( !generalized_ct. is_ct_infer( ) ) ;
224+ if has_unconstrained_ty_var {
225+ bug ! ( "unconstrained ty var when generalizing `{source_ct:?}`" ) ;
226+ }
216227
217228 self . inner
218229 . borrow_mut ( )
@@ -271,10 +282,12 @@ impl<'tcx> InferCtxt<'tcx> {
271282 ambient_variance,
272283 in_alias : false ,
273284 cache : Default :: default ( ) ,
285+ has_unconstrained_ty_var : false ,
274286 } ;
275287
276288 let value_may_be_infer = generalizer. relate ( source_term, source_term) ?;
277- Ok ( Generalization { value_may_be_infer } )
289+ let has_unconstrained_ty_var = generalizer. has_unconstrained_ty_var ;
290+ Ok ( Generalization { value_may_be_infer, has_unconstrained_ty_var } )
278291 }
279292}
280293
@@ -364,6 +377,9 @@ struct Generalizer<'me, 'tcx> {
364377 in_alias : bool ,
365378
366379 cache : SsoHashMap < ( Ty < ' tcx > , ty:: Variance , bool ) , Ty < ' tcx > > ,
380+
381+ /// See the field `has_unconstrained_ty_var` in `Generalization`.
382+ has_unconstrained_ty_var : bool ,
367383}
368384
369385impl < ' tcx > Generalizer < ' _ , ' tcx > {
@@ -376,8 +392,10 @@ impl<'tcx> Generalizer<'_, 'tcx> {
376392 }
377393
378394 /// Create a new type variable in the universe of the target when
379- /// generalizing an alias.
395+ /// generalizing an alias. This has to set `has_unconstrained_ty_var`
396+ /// if we're currently in a bivariant context.
380397 fn next_ty_var_for_alias ( & mut self ) -> Ty < ' tcx > {
398+ self . has_unconstrained_ty_var |= self . ambient_variance == ty:: Bivariant ;
381399 self . infcx . next_ty_var_in_universe ( self . span , self . for_universe )
382400 }
383401
@@ -457,15 +475,13 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
457475 // Avoid fetching the variance if we are in an invariant
458476 // context; no need, and it can induce dependency cycles
459477 // (e.g., #41849).
460- relate :: relate_args_invariantly ( self , a_args, b_args)
478+ relate_args_invariantly ( self , a_args, b_args)
461479 } else {
462- let tcx = self . cx ( ) ;
463- let variances = tcx. variances_of ( def_id) ;
464- relate:: relate_args_with_variances ( self , variances, a_args, b_args)
480+ let variances = self . cx ( ) . variances_of ( def_id) ;
481+ relate_args_with_variances ( self , variances, a_args, b_args)
465482 } ?;
466483 if args == a_args { Ok ( a_ty) } else { Ok ( mk ( args) ) }
467484 }
468-
469485 #[ instrument( level = "debug" , skip( self , variance, b) , ret) ]
470486 fn relate_with_variance < T : Relate < TyCtxt < ' tcx > > > (
471487 & mut self ,
@@ -525,8 +541,14 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
525541 }
526542 }
527543
528- // We do need a fresh type variable otherwise.
529- ty:: Bivariant | ty:: Covariant | ty:: Contravariant => ( ) ,
544+ // Bivariant: make a fresh var, but remember that
545+ // it is unconstrained. See the comment in
546+ // `Generalization`.
547+ ty:: Bivariant => self . has_unconstrained_ty_var = true ,
548+
549+ // Co/contravariant: this will be
550+ // sufficiently constrained later on.
551+ ty:: Covariant | ty:: Contravariant => ( ) ,
530552 }
531553
532554 let origin = inner. type_variables ( ) . var_origin ( vid) ;
@@ -745,8 +767,32 @@ struct Generalization<T> {
745767 /// for `?0` generalization returns an inference
746768 /// variable.
747769 ///
748- /// This has to be handled with care as it can
770+ /// This has to be handled wotj care as it can
749771 /// otherwise very easily result in infinite
750772 /// recursion.
751773 pub value_may_be_infer : T ,
774+
775+ /// In general, we do not check whether all types which occur during
776+ /// type checking are well-formed. We only check wf of user-provided types
777+ /// and when actually using a type, e.g. for method calls.
778+ ///
779+ /// This means that when subtyping, we may end up with unconstrained
780+ /// inference variables if a generalized type has bivariant parameters.
781+ /// A parameter may only be bivariant if it is constrained by a projection
782+ /// bound in a where-clause. As an example, imagine a type:
783+ ///
784+ /// struct Foo<A, B> where A: Iterator<Item = B> {
785+ /// data: A
786+ /// }
787+ ///
788+ /// here, `A` will be covariant, but `B` is unconstrained.
789+ ///
790+ /// However, whatever it is, for `Foo` to be WF, it must be equal to `A::Item`.
791+ /// If we have an input `Foo<?A, ?B>`, then after generalization we will wind
792+ /// up with a type like `Foo<?C, ?D>`. When we enforce `Foo<?A, ?B> <: Foo<?C, ?D>`,
793+ /// we will wind up with the requirement that `?A <: ?C`, but no particular
794+ /// relationship between `?B` and `?D` (after all, these types may be completely
795+ /// different). If we do nothing else, this may mean that `?D` goes unconstrained
796+ /// (as in #41677). To avoid this we emit a `WellFormed` obligation in these cases.
797+ pub has_unconstrained_ty_var : bool ,
752798}
0 commit comments