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,69 +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, 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
-
325
261
fn unify_integral_variable (
326
262
& self ,
327
263
vid_is_expected : bool ,
@@ -383,131 +319,6 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
383
319
Glb :: new ( self , a_is_expected)
384
320
}
385
321
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
-
511
322
pub fn register_obligations ( & mut self , obligations : PredicateObligations < ' tcx > ) {
512
323
self . obligations . extend ( obligations) ;
513
324
}
@@ -520,6 +331,8 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
520
331
}
521
332
522
333
pub trait ObligationEmittingRelation < ' tcx > : TypeRelation < ' tcx > {
334
+ fn span ( & self ) -> Span ;
335
+
523
336
fn param_env ( & self ) -> ty:: ParamEnv < ' tcx > ;
524
337
525
338
/// Register obligations that must hold in order for this relation to hold
0 commit comments