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,69 +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, needs_wf : _ } = generalize:: generalize (
311- self ,
312- & mut CombineDelegate { infcx : self , span } ,
313- ct,
314- target_vid,
315- ty:: Variance :: Invariant ,
316- ) ?;
317-
318- self . inner
319- . borrow_mut ( )
320- . const_unification_table ( )
321- . union_value ( target_vid, ConstVariableValue :: Known { value } ) ;
322- Ok ( value)
323- }
324-
325261 fn unify_integral_variable (
326262 & self ,
327263 vid_is_expected : bool ,
@@ -383,131 +319,6 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
383319 Glb :: new ( self , a_is_expected)
384320 }
385321
386- /// Here, `dir` is either `EqTo`, `SubtypeOf`, or `SupertypeOf`.
387- /// The idea is that we should ensure that the type `a_ty` is equal
388- /// to, a subtype of, or a supertype of (respectively) the type
389- /// to which `b_vid` is bound.
390- ///
391- /// Since `b_vid` has not yet been instantiated with a type, we
392- /// will first instantiate `b_vid` with a *generalized* version
393- /// of `a_ty`. Generalization introduces other inference
394- /// variables wherever subtyping could occur.
395- #[ instrument( skip( self ) , level = "debug" ) ]
396- pub fn instantiate (
397- & mut self ,
398- a_ty : Ty < ' tcx > ,
399- ambient_variance : ty:: Variance ,
400- b_vid : ty:: TyVid ,
401- a_is_expected : bool ,
402- ) -> RelateResult < ' tcx , ( ) > {
403- // Get the actual variable that b_vid has been inferred to
404- debug_assert ! ( self . infcx. inner. borrow_mut( ) . type_variables( ) . probe( b_vid) . is_unknown( ) ) ;
405-
406- // Generalize type of `a_ty` appropriately depending on the
407- // direction. As an example, assume:
408- //
409- // - `a_ty == &'x ?1`, where `'x` is some free region and `?1` is an
410- // inference variable,
411- // - and `dir` == `SubtypeOf`.
412- //
413- // Then the generalized form `b_ty` would be `&'?2 ?3`, where
414- // `'?2` and `?3` are fresh region/type inference
415- // variables. (Down below, we will relate `a_ty <: b_ty`,
416- // adding constraints like `'x: '?2` and `?1 <: ?3`.)
417- let Generalization { value_may_be_infer : b_ty, needs_wf } = generalize:: generalize (
418- self . infcx ,
419- & mut CombineDelegate { infcx : self . infcx , span : self . trace . span ( ) } ,
420- a_ty,
421- b_vid,
422- ambient_variance,
423- ) ?;
424-
425- // Constrain `b_vid` to the generalized type `b_ty`.
426- if let & ty:: Infer ( TyVar ( b_ty_vid) ) = b_ty. kind ( ) {
427- self . infcx . inner . borrow_mut ( ) . type_variables ( ) . equate ( b_vid, b_ty_vid) ;
428- } else {
429- self . infcx . inner . borrow_mut ( ) . type_variables ( ) . instantiate ( b_vid, b_ty) ;
430- }
431-
432- if needs_wf {
433- self . obligations . push ( Obligation :: new (
434- self . tcx ( ) ,
435- self . trace . cause . clone ( ) ,
436- self . param_env ,
437- ty:: Binder :: dummy ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: WellFormed (
438- b_ty. into ( ) ,
439- ) ) ) ,
440- ) ) ;
441- }
442-
443- // Finally, relate `b_ty` to `a_ty`, as described in previous comment.
444- //
445- // FIXME(#16847): This code is non-ideal because all these subtype
446- // relations wind up attributed to the same spans. We need
447- // to associate causes/spans with each of the relations in
448- // the stack to get this right.
449- if b_ty. is_ty_var ( ) {
450- // This happens for cases like `<?0 as Trait>::Assoc == ?0`.
451- // We can't instantiate `?0` here as that would result in a
452- // cyclic type. We instead delay the unification in case
453- // the alias can be normalized to something which does not
454- // mention `?0`.
455- if self . infcx . next_trait_solver ( ) {
456- let ( lhs, rhs, direction) = match ambient_variance {
457- ty:: Variance :: Invariant => {
458- ( a_ty. into ( ) , b_ty. into ( ) , AliasRelationDirection :: Equate )
459- }
460- ty:: Variance :: Covariant => {
461- ( a_ty. into ( ) , b_ty. into ( ) , AliasRelationDirection :: Subtype )
462- }
463- ty:: Variance :: Contravariant => {
464- ( b_ty. into ( ) , a_ty. into ( ) , AliasRelationDirection :: Subtype )
465- }
466- ty:: Variance :: Bivariant => unreachable ! ( "bivariant generalization" ) ,
467- } ;
468- self . obligations . push ( Obligation :: new (
469- self . tcx ( ) ,
470- self . trace . cause . clone ( ) ,
471- self . param_env ,
472- ty:: PredicateKind :: AliasRelate ( lhs, rhs, direction) ,
473- ) ) ;
474- } else {
475- match a_ty. kind ( ) {
476- & ty:: Alias ( ty:: Projection , data) => {
477- // FIXME: This does not handle subtyping correctly, we could
478- // instead create a new inference variable for `a_ty`, emitting
479- // `Projection(a_ty, a_infer)` and `a_infer <: b_ty`.
480- self . obligations . push ( Obligation :: new (
481- self . tcx ( ) ,
482- self . trace . cause . clone ( ) ,
483- self . param_env ,
484- ty:: ProjectionPredicate { projection_ty : data, term : b_ty. into ( ) } ,
485- ) )
486- }
487- // The old solver only accepts projection predicates for associated types.
488- ty:: Alias ( ty:: Inherent | ty:: Weak | ty:: Opaque , _) => {
489- return Err ( TypeError :: CyclicTy ( a_ty) ) ;
490- }
491- _ => bug ! ( "generalizated `{a_ty:?} to infer, not an alias" ) ,
492- }
493- }
494- } else {
495- match ambient_variance {
496- ty:: Variance :: Invariant => self . equate ( a_is_expected) . relate ( a_ty, b_ty) ,
497- ty:: Variance :: Covariant => self . sub ( a_is_expected) . relate ( a_ty, b_ty) ,
498- ty:: Variance :: Contravariant => self . sub ( a_is_expected) . relate_with_variance (
499- ty:: Contravariant ,
500- ty:: VarianceDiagInfo :: default ( ) ,
501- a_ty,
502- b_ty,
503- ) ,
504- ty:: Variance :: Bivariant => unreachable ! ( "bivariant generalization" ) ,
505- } ?;
506- }
507-
508- Ok ( ( ) )
509- }
510-
511322 pub fn register_obligations ( & mut self , obligations : PredicateObligations < ' tcx > ) {
512323 self . obligations . extend ( obligations) ;
513324 }
@@ -520,6 +331,8 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
520331}
521332
522333pub trait ObligationEmittingRelation < ' tcx > : TypeRelation < ' tcx > {
334+ fn span ( & self ) -> Span ;
335+
523336 fn param_env ( & self ) -> ty:: ParamEnv < ' tcx > ;
524337
525338 /// Register obligations that must hold in order for this relation to hold
0 commit comments