2323//! this should be correctly updated.
2424
2525use super :: equate:: Equate ;
26- use super :: generalize:: { self , CombineDelegate , Generalization } ;
2726use super :: glb:: Glb ;
2827use super :: lub:: Lub ;
2928use super :: sub:: Sub ;
3029use crate :: infer:: { DefineOpaqueTypes , InferCtxt , TypeTrace } ;
3130use crate :: traits:: { Obligation , PredicateObligations } ;
3231use rustc_middle:: infer:: canonical:: OriginalQueryValues ;
33- use rustc_middle:: infer:: unify_key:: { ConstVariableValue , EffectVarValue } ;
32+ use rustc_middle:: infer:: unify_key:: EffectVarValue ;
3433use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
3534use rustc_middle:: ty:: relate:: { RelateResult , TypeRelation } ;
3635use rustc_middle:: ty:: { self , InferConst , ToPredicate , Ty , TyCtxt , TypeVisitableExt } ;
37- use rustc_middle:: ty:: { AliasRelationDirection , TyVar } ;
3836use rustc_middle:: ty:: { IntType , UintType } ;
37+ use rustc_span:: Span ;
3938
4039#[ derive( Clone ) ]
4140pub struct CombineFields < ' infcx , ' tcx > {
@@ -221,11 +220,11 @@ impl<'tcx> InferCtxt<'tcx> {
221220 }
222221
223222 ( ty:: ConstKind :: Infer ( InferConst :: Var ( vid) ) , _) => {
224- return self . unify_const_variable ( vid, b) ;
223+ return self . instantiate_const_var ( vid, b) ;
225224 }
226225
227226 ( _, ty:: ConstKind :: Infer ( InferConst :: Var ( vid) ) ) => {
228- return self . unify_const_variable ( vid, a) ;
227+ return self . instantiate_const_var ( vid, a) ;
229228 }
230229
231230 ( ty:: ConstKind :: Infer ( InferConst :: EffectVar ( vid) ) , _) => {
@@ -259,73 +258,6 @@ impl<'tcx> InferCtxt<'tcx> {
259258 ty:: relate:: structurally_relate_consts ( relation, a, b)
260259 }
261260
262- /// Unifies the const variable `target_vid` with the given constant.
263- ///
264- /// This also tests if the given const `ct` contains an inference variable which was previously
265- /// unioned with `target_vid`. If this is the case, inferring `target_vid` to `ct`
266- /// would result in an infinite type as we continuously replace an inference variable
267- /// in `ct` with `ct` itself.
268- ///
269- /// This is especially important as unevaluated consts use their parents generics.
270- /// They therefore often contain unused args, making these errors far more likely.
271- ///
272- /// A good example of this is the following:
273- ///
274- /// ```compile_fail,E0308
275- /// #![feature(generic_const_exprs)]
276- ///
277- /// fn bind<const N: usize>(value: [u8; N]) -> [u8; 3 + 4] {
278- /// todo!()
279- /// }
280- ///
281- /// fn main() {
282- /// let mut arr = Default::default();
283- /// arr = bind(arr);
284- /// }
285- /// ```
286- ///
287- /// Here `3 + 4` ends up as `ConstKind::Unevaluated` which uses the generics
288- /// of `fn bind` (meaning that its args contain `N`).
289- ///
290- /// `bind(arr)` now infers that the type of `arr` must be `[u8; N]`.
291- /// The assignment `arr = bind(arr)` now tries to equate `N` with `3 + 4`.
292- ///
293- /// As `3 + 4` contains `N` in its args, this must not succeed.
294- ///
295- /// See `tests/ui/const-generics/occurs-check/` for more examples where this is relevant.
296- #[ instrument( level = "debug" , skip( self ) ) ]
297- fn unify_const_variable (
298- & self ,
299- target_vid : ty:: ConstVid ,
300- ct : ty:: Const < ' tcx > ,
301- ) -> RelateResult < ' tcx , ty:: Const < ' tcx > > {
302- let span = match self . inner . borrow_mut ( ) . const_unification_table ( ) . probe_value ( target_vid) {
303- ConstVariableValue :: Known { value } => {
304- bug ! ( "instantiating a known const var: {target_vid:?} {value} {ct}" )
305- }
306- ConstVariableValue :: Unknown { origin, universe : _ } => origin. span ,
307- } ;
308- // FIXME(generic_const_exprs): Occurs check failures for unevaluated
309- // constants and generic expressions are not yet handled correctly.
310- let Generalization { value_may_be_infer : value, has_unconstrained_ty_var } =
311- generalize:: generalize (
312- self ,
313- & mut CombineDelegate { infcx : self , span } ,
314- ct,
315- target_vid,
316- ty:: Variance :: Invariant ,
317- ) ?;
318-
319- if has_unconstrained_ty_var {
320- span_bug ! ( span, "unconstrained ty var when generalizing `{ct:?}`" ) ;
321- }
322- self . inner
323- . borrow_mut ( )
324- . const_unification_table ( )
325- . union_value ( target_vid, ConstVariableValue :: Known { value } ) ;
326- Ok ( value)
327- }
328-
329261 fn unify_integral_variable (
330262 & self ,
331263 vid_is_expected : bool ,
@@ -387,132 +319,6 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
387319 Glb :: new ( self , a_is_expected)
388320 }
389321
390- /// Here, `dir` is either `EqTo`, `SubtypeOf`, or `SupertypeOf`.
391- /// The idea is that we should ensure that the type `a_ty` is equal
392- /// to, a subtype of, or a supertype of (respectively) the type
393- /// to which `b_vid` is bound.
394- ///
395- /// Since `b_vid` has not yet been instantiated with a type, we
396- /// will first instantiate `b_vid` with a *generalized* version
397- /// of `a_ty`. Generalization introduces other inference
398- /// variables wherever subtyping could occur.
399- #[ instrument( skip( self ) , level = "debug" ) ]
400- pub fn instantiate (
401- & mut self ,
402- a_ty : Ty < ' tcx > ,
403- ambient_variance : ty:: Variance ,
404- b_vid : ty:: TyVid ,
405- a_is_expected : bool ,
406- ) -> RelateResult < ' tcx , ( ) > {
407- // Get the actual variable that b_vid has been inferred to
408- debug_assert ! ( self . infcx. inner. borrow_mut( ) . type_variables( ) . probe( b_vid) . is_unknown( ) ) ;
409-
410- // Generalize type of `a_ty` appropriately depending on the
411- // direction. As an example, assume:
412- //
413- // - `a_ty == &'x ?1`, where `'x` is some free region and `?1` is an
414- // inference variable,
415- // - and `dir` == `SubtypeOf`.
416- //
417- // Then the generalized form `b_ty` would be `&'?2 ?3`, where
418- // `'?2` and `?3` are fresh region/type inference
419- // variables. (Down below, we will relate `a_ty <: b_ty`,
420- // adding constraints like `'x: '?2` and `?1 <: ?3`.)
421- let Generalization { value_may_be_infer : b_ty, has_unconstrained_ty_var } =
422- generalize:: generalize (
423- self . infcx ,
424- & mut CombineDelegate { infcx : self . infcx , span : self . trace . span ( ) } ,
425- a_ty,
426- b_vid,
427- ambient_variance,
428- ) ?;
429-
430- // Constrain `b_vid` to the generalized type `b_ty`.
431- if let & ty:: Infer ( TyVar ( b_ty_vid) ) = b_ty. kind ( ) {
432- self . infcx . inner . borrow_mut ( ) . type_variables ( ) . equate ( b_vid, b_ty_vid) ;
433- } else {
434- self . infcx . inner . borrow_mut ( ) . type_variables ( ) . instantiate ( b_vid, b_ty) ;
435- }
436-
437- if has_unconstrained_ty_var {
438- self . obligations . push ( Obligation :: new (
439- self . tcx ( ) ,
440- self . trace . cause . clone ( ) ,
441- self . param_env ,
442- ty:: Binder :: dummy ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: WellFormed (
443- b_ty. into ( ) ,
444- ) ) ) ,
445- ) ) ;
446- }
447-
448- // Finally, relate `b_ty` to `a_ty`, as described in previous comment.
449- //
450- // FIXME(#16847): This code is non-ideal because all these subtype
451- // relations wind up attributed to the same spans. We need
452- // to associate causes/spans with each of the relations in
453- // the stack to get this right.
454- if b_ty. is_ty_var ( ) {
455- // This happens for cases like `<?0 as Trait>::Assoc == ?0`.
456- // We can't instantiate `?0` here as that would result in a
457- // cyclic type. We instead delay the unification in case
458- // the alias can be normalized to something which does not
459- // mention `?0`.
460- if self . infcx . next_trait_solver ( ) {
461- let ( lhs, rhs, direction) = match ambient_variance {
462- ty:: Variance :: Invariant => {
463- ( a_ty. into ( ) , b_ty. into ( ) , AliasRelationDirection :: Equate )
464- }
465- ty:: Variance :: Covariant => {
466- ( a_ty. into ( ) , b_ty. into ( ) , AliasRelationDirection :: Subtype )
467- }
468- ty:: Variance :: Contravariant => {
469- ( b_ty. into ( ) , a_ty. into ( ) , AliasRelationDirection :: Subtype )
470- }
471- ty:: Variance :: Bivariant => unreachable ! ( "bivariant generalization" ) ,
472- } ;
473- self . obligations . push ( Obligation :: new (
474- self . tcx ( ) ,
475- self . trace . cause . clone ( ) ,
476- self . param_env ,
477- ty:: PredicateKind :: AliasRelate ( lhs, rhs, direction) ,
478- ) ) ;
479- } else {
480- match a_ty. kind ( ) {
481- & ty:: Alias ( ty:: Projection , data) => {
482- // FIXME: This does not handle subtyping correctly, we could
483- // instead create a new inference variable for `a_ty`, emitting
484- // `Projection(a_ty, a_infer)` and `a_infer <: b_ty`.
485- self . obligations . push ( Obligation :: new (
486- self . tcx ( ) ,
487- self . trace . cause . clone ( ) ,
488- self . param_env ,
489- ty:: ProjectionPredicate { projection_ty : data, term : b_ty. into ( ) } ,
490- ) )
491- }
492- // The old solver only accepts projection predicates for associated types.
493- ty:: Alias ( ty:: Inherent | ty:: Weak | ty:: Opaque , _) => {
494- return Err ( TypeError :: CyclicTy ( a_ty) ) ;
495- }
496- _ => bug ! ( "generalizated `{a_ty:?} to infer, not an alias" ) ,
497- }
498- }
499- } else {
500- match ambient_variance {
501- ty:: Variance :: Invariant => self . equate ( a_is_expected) . relate ( a_ty, b_ty) ,
502- ty:: Variance :: Covariant => self . sub ( a_is_expected) . relate ( a_ty, b_ty) ,
503- ty:: Variance :: Contravariant => self . sub ( a_is_expected) . relate_with_variance (
504- ty:: Contravariant ,
505- ty:: VarianceDiagInfo :: default ( ) ,
506- a_ty,
507- b_ty,
508- ) ,
509- ty:: Variance :: Bivariant => unreachable ! ( "bivariant generalization" ) ,
510- } ?;
511- }
512-
513- Ok ( ( ) )
514- }
515-
516322 pub fn register_obligations ( & mut self , obligations : PredicateObligations < ' tcx > ) {
517323 self . obligations . extend ( obligations) ;
518324 }
@@ -525,6 +331,8 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
525331}
526332
527333pub trait ObligationEmittingRelation < ' tcx > : TypeRelation < ' tcx > {
334+ fn span ( & self ) -> Span ;
335+
528336 fn param_env ( & self ) -> ty:: ParamEnv < ' tcx > ;
529337
530338 /// Register obligations that must hold in order for this relation to hold
0 commit comments