23
23
//! this should be correctly updated.
24
24
25
25
use super :: equate:: Equate ;
26
- use super :: generalize:: { self , CombineDelegate , Generalization } ;
27
26
use super :: glb:: Glb ;
28
27
use super :: lub:: Lub ;
29
28
use super :: sub:: Sub ;
30
29
use crate :: infer:: { DefineOpaqueTypes , InferCtxt , TypeTrace } ;
31
30
use crate :: traits:: { Obligation , PredicateObligations } ;
32
31
use rustc_middle:: infer:: canonical:: OriginalQueryValues ;
33
- use rustc_middle:: infer:: unify_key:: { ConstVariableValue , EffectVarValue } ;
32
+ use rustc_middle:: infer:: unify_key:: EffectVarValue ;
34
33
use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
35
34
use rustc_middle:: ty:: relate:: { RelateResult , TypeRelation } ;
36
35
use rustc_middle:: ty:: { self , InferConst , ToPredicate , Ty , TyCtxt , TypeVisitableExt } ;
37
- use rustc_middle:: ty:: { AliasRelationDirection , TyVar } ;
38
36
use rustc_middle:: ty:: { IntType , UintType } ;
37
+ use rustc_span:: Span ;
39
38
40
39
#[ derive( Clone ) ]
41
40
pub struct CombineFields < ' infcx , ' tcx > {
@@ -221,11 +220,11 @@ impl<'tcx> InferCtxt<'tcx> {
221
220
}
222
221
223
222
( ty:: ConstKind :: Infer ( InferConst :: Var ( vid) ) , _) => {
224
- return self . unify_const_variable ( vid, b) ;
223
+ return self . instantiate_const_var ( vid, b) ;
225
224
}
226
225
227
226
( _, ty:: ConstKind :: Infer ( InferConst :: Var ( vid) ) ) => {
228
- return self . unify_const_variable ( vid, a) ;
227
+ return self . instantiate_const_var ( vid, a) ;
229
228
}
230
229
231
230
( ty:: ConstKind :: Infer ( InferConst :: EffectVar ( vid) ) , _) => {
@@ -259,73 +258,6 @@ impl<'tcx> InferCtxt<'tcx> {
259
258
ty:: relate:: structurally_relate_consts ( relation, a, b)
260
259
}
261
260
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
-
329
261
fn unify_integral_variable (
330
262
& self ,
331
263
vid_is_expected : bool ,
@@ -387,132 +319,6 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
387
319
Glb :: new ( self , a_is_expected)
388
320
}
389
321
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
-
516
322
pub fn register_obligations ( & mut self , obligations : PredicateObligations < ' tcx > ) {
517
323
self . obligations . extend ( obligations) ;
518
324
}
@@ -525,6 +331,8 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
525
331
}
526
332
527
333
pub trait ObligationEmittingRelation < ' tcx > : TypeRelation < ' tcx > {
334
+ fn span ( & self ) -> Span ;
335
+
528
336
fn param_env ( & self ) -> ty:: ParamEnv < ' tcx > ;
529
337
530
338
/// Register obligations that must hold in order for this relation to hold
0 commit comments