@@ -70,14 +70,13 @@ impl<'tcx> InferCtxt<'tcx> {
7070 //
7171 // We then relate `generalized_ty <: source_ty`, adding constraints like `'x: '?2` and
7272 // `?1 <: ?3`.
73- let Generalization { value_may_be_infer : generalized_ty, has_unconstrained_ty_var } = self
74- . generalize (
75- relation. span ( ) ,
76- relation. structurally_relate_aliases ( ) ,
77- target_vid,
78- instantiation_variance,
79- source_ty,
80- ) ?;
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+ ) ?;
8180
8281 // Constrain `b_vid` to the generalized type `generalized_ty`.
8382 if let & ty:: Infer ( ty:: TyVar ( generalized_vid) ) = generalized_ty. kind ( ) {
@@ -86,11 +85,6 @@ impl<'tcx> InferCtxt<'tcx> {
8685 self . inner . borrow_mut ( ) . type_variables ( ) . instantiate ( target_vid, generalized_ty) ;
8786 }
8887
89- // See the comment on `Generalization::has_unconstrained_ty_var`.
90- if has_unconstrained_ty_var {
91- relation. register_predicates ( [ ty:: ClauseKind :: WellFormed ( generalized_ty. into ( ) ) ] ) ;
92- }
93-
9488 // Finally, relate `generalized_ty` to `source_ty`, as described in previous comment.
9589 //
9690 // FIXME(#16847): This code is non-ideal because all these subtype
@@ -210,19 +204,15 @@ impl<'tcx> InferCtxt<'tcx> {
210204 ) -> RelateResult < ' tcx , ( ) > {
211205 // FIXME(generic_const_exprs): Occurs check failures for unevaluated
212206 // constants and generic expressions are not yet handled correctly.
213- let Generalization { value_may_be_infer : generalized_ct, has_unconstrained_ty_var } = self
214- . generalize (
215- relation. span ( ) ,
216- relation. structurally_relate_aliases ( ) ,
217- target_vid,
218- ty:: Invariant ,
219- source_ct,
220- ) ?;
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+ ) ?;
221214
222215 debug_assert ! ( !generalized_ct. is_ct_infer( ) ) ;
223- if has_unconstrained_ty_var {
224- bug ! ( "unconstrained ty var when generalizing `{source_ct:?}`" ) ;
225- }
226216
227217 self . inner
228218 . borrow_mut ( )
@@ -281,12 +271,10 @@ impl<'tcx> InferCtxt<'tcx> {
281271 ambient_variance,
282272 in_alias : false ,
283273 cache : Default :: default ( ) ,
284- has_unconstrained_ty_var : false ,
285274 } ;
286275
287276 let value_may_be_infer = generalizer. relate ( source_term, source_term) ?;
288- let has_unconstrained_ty_var = generalizer. has_unconstrained_ty_var ;
289- Ok ( Generalization { value_may_be_infer, has_unconstrained_ty_var } )
277+ Ok ( Generalization { value_may_be_infer } )
290278 }
291279}
292280
@@ -376,9 +364,6 @@ struct Generalizer<'me, 'tcx> {
376364 in_alias : bool ,
377365
378366 cache : SsoHashMap < ( Ty < ' tcx > , ty:: Variance , bool ) , Ty < ' tcx > > ,
379-
380- /// See the field `has_unconstrained_ty_var` in `Generalization`.
381- has_unconstrained_ty_var : bool ,
382367}
383368
384369impl < ' tcx > Generalizer < ' _ , ' tcx > {
@@ -391,10 +376,8 @@ impl<'tcx> Generalizer<'_, 'tcx> {
391376 }
392377
393378 /// Create a new type variable in the universe of the target when
394- /// generalizing an alias. This has to set `has_unconstrained_ty_var`
395- /// if we're currently in a bivariant context.
379+ /// generalizing an alias.
396380 fn next_ty_var_for_alias ( & mut self ) -> Ty < ' tcx > {
397- self . has_unconstrained_ty_var |= self . ambient_variance == ty:: Bivariant ;
398381 self . infcx . next_ty_var_in_universe ( self . span , self . for_universe )
399382 }
400383
@@ -461,29 +444,26 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
461444 self . infcx . tcx
462445 }
463446
464- fn relate_item_args (
447+ fn relate_ty_args (
465448 & mut self ,
466- item_def_id : DefId ,
467- a_arg : ty:: GenericArgsRef < ' tcx > ,
468- b_arg : ty:: GenericArgsRef < ' tcx > ,
469- ) -> RelateResult < ' tcx , ty:: GenericArgsRef < ' tcx > > {
470- if self . ambient_variance == ty:: Invariant {
449+ a_ty : Ty < ' tcx > ,
450+ _: Ty < ' tcx > ,
451+ def_id : DefId ,
452+ a_args : ty:: GenericArgsRef < ' tcx > ,
453+ b_args : ty:: GenericArgsRef < ' tcx > ,
454+ mk : impl FnOnce ( ty:: GenericArgsRef < ' tcx > ) -> Ty < ' tcx > ,
455+ ) -> RelateResult < ' tcx , Ty < ' tcx > > {
456+ let args = if self . ambient_variance == ty:: Invariant {
471457 // Avoid fetching the variance if we are in an invariant
472458 // context; no need, and it can induce dependency cycles
473459 // (e.g., #41849).
474- relate:: relate_args_invariantly ( self , a_arg , b_arg )
460+ relate:: relate_args_invariantly ( self , a_args , b_args )
475461 } else {
476462 let tcx = self . cx ( ) ;
477- let opt_variances = tcx. variances_of ( item_def_id) ;
478- relate:: relate_args_with_variances (
479- self ,
480- item_def_id,
481- opt_variances,
482- a_arg,
483- b_arg,
484- false ,
485- )
486- }
463+ let variances = tcx. variances_of ( def_id) ;
464+ relate:: relate_args_with_variances ( self , variances, a_args, b_args)
465+ } ?;
466+ if args == a_args { Ok ( a_ty) } else { Ok ( mk ( args) ) }
487467 }
488468
489469 #[ instrument( level = "debug" , skip( self , variance, b) , ret) ]
@@ -545,14 +525,8 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
545525 }
546526 }
547527
548- // Bivariant: make a fresh var, but remember that
549- // it is unconstrained. See the comment in
550- // `Generalization`.
551- ty:: Bivariant => self . has_unconstrained_ty_var = true ,
552-
553- // Co/contravariant: this will be
554- // sufficiently constrained later on.
555- ty:: Covariant | ty:: Contravariant => ( ) ,
528+ // We do need a fresh type variable otherwise.
529+ ty:: Bivariant | ty:: Covariant | ty:: Contravariant => ( ) ,
556530 }
557531
558532 let origin = inner. type_variables ( ) . var_origin ( vid) ;
@@ -771,32 +745,8 @@ struct Generalization<T> {
771745 /// for `?0` generalization returns an inference
772746 /// variable.
773747 ///
774- /// This has to be handled wotj care as it can
748+ /// This has to be handled with care as it can
775749 /// otherwise very easily result in infinite
776750 /// recursion.
777751 pub value_may_be_infer : T ,
778-
779- /// In general, we do not check whether all types which occur during
780- /// type checking are well-formed. We only check wf of user-provided types
781- /// and when actually using a type, e.g. for method calls.
782- ///
783- /// This means that when subtyping, we may end up with unconstrained
784- /// inference variables if a generalized type has bivariant parameters.
785- /// A parameter may only be bivariant if it is constrained by a projection
786- /// bound in a where-clause. As an example, imagine a type:
787- ///
788- /// struct Foo<A, B> where A: Iterator<Item = B> {
789- /// data: A
790- /// }
791- ///
792- /// here, `A` will be covariant, but `B` is unconstrained.
793- ///
794- /// However, whatever it is, for `Foo` to be WF, it must be equal to `A::Item`.
795- /// If we have an input `Foo<?A, ?B>`, then after generalization we will wind
796- /// up with a type like `Foo<?C, ?D>`. When we enforce `Foo<?A, ?B> <: Foo<?C, ?D>`,
797- /// we will wind up with the requirement that `?A <: ?C`, but no particular
798- /// relationship between `?B` and `?D` (after all, these types may be completely
799- /// different). If we do nothing else, this may mean that `?D` goes unconstrained
800- /// (as in #41677). To avoid this we emit a `WellFormed` obligation in these cases.
801- pub has_unconstrained_ty_var : bool ,
802752}
0 commit comments