@@ -25,13 +25,11 @@ use rustc_data_structures::fx::FxHashMap;
25
25
use rustc_middle:: traits:: ObligationCause ;
26
26
use rustc_middle:: ty:: fold:: FnMutDelegate ;
27
27
use rustc_middle:: ty:: relate:: { Relate , RelateResult , TypeRelation } ;
28
- use rustc_middle:: ty:: visit :: TypeVisitableExt ;
28
+ use rustc_middle:: ty:: TypeVisitableExt ;
29
29
use rustc_middle:: ty:: { self , InferConst , Ty , TyCtxt } ;
30
30
use rustc_span:: { Span , Symbol } ;
31
- use std:: fmt:: Debug ;
32
31
33
32
use super :: combine:: ObligationEmittingRelation ;
34
- use super :: generalize:: { self , Generalization } ;
35
33
use crate :: infer:: InferCtxt ;
36
34
use crate :: infer:: { TypeVariableOrigin , TypeVariableOriginKind } ;
37
35
use crate :: traits:: { Obligation , PredicateObligations } ;
@@ -99,15 +97,6 @@ pub trait TypeRelatingDelegate<'tcx> {
99
97
/// placeholder region.
100
98
fn next_placeholder_region ( & mut self , placeholder : ty:: PlaceholderRegion ) -> ty:: Region < ' tcx > ;
101
99
102
- /// Creates a new existential region in the given universe. This
103
- /// is used when handling subtyping and type variables -- if we
104
- /// have that `?X <: Foo<'a>`, for example, we would instantiate
105
- /// `?X` with a type like `Foo<'?0>` where `'?0` is a fresh
106
- /// existential variable created by this function. We would then
107
- /// relate `Foo<'?0>` with `Foo<'a>` (and probably add an outlives
108
- /// relation stating that `'?0: 'a`).
109
- fn generalize_existential ( & mut self , universe : ty:: UniverseIndex ) -> ty:: Region < ' tcx > ;
110
-
111
100
/// Enables some optimizations if we do not expect inference variables
112
101
/// in the RHS of the relation.
113
102
fn forbid_inference_vars ( ) -> bool ;
@@ -153,113 +142,44 @@ where
153
142
self . delegate . push_outlives ( sup, sub, info) ;
154
143
}
155
144
156
- /// Relate a type inference variable with a value type. This works
157
- /// by creating a "generalization" G of the value where all the
158
- /// lifetimes are replaced with fresh inference values. This
159
- /// generalization G becomes the value of the inference variable,
160
- /// and is then related in turn to the value. So e.g. if you had
161
- /// `vid = ?0` and `value = &'a u32`, we might first instantiate
162
- /// `?0` to a type like `&'0 u32` where `'0` is a fresh variable,
163
- /// and then relate `&'0 u32` with `&'a u32` (resulting in
164
- /// relations between `'0` and `'a`).
165
- ///
166
- /// The variable `pair` can be either a `(vid, ty)` or `(ty, vid)`
167
- /// -- in other words, it is always an (unresolved) inference
168
- /// variable `vid` and a type `ty` that are being related, but the
169
- /// vid may appear either as the "a" type or the "b" type,
170
- /// depending on where it appears in the tuple. The trait
171
- /// `VidValuePair` lets us work with the vid/type while preserving
172
- /// the "sidedness" when necessary -- the sidedness is relevant in
173
- /// particular for the variance and set of in-scope things.
174
- fn relate_ty_var < PAIR : VidValuePair < ' tcx > > (
175
- & mut self ,
176
- pair : PAIR ,
177
- ) -> RelateResult < ' tcx , Ty < ' tcx > > {
178
- debug ! ( "relate_ty_var({:?})" , pair) ;
179
-
180
- let vid = pair. vid ( ) ;
181
- let value_ty = pair. value_ty ( ) ;
182
-
183
- // FIXME(invariance) -- this logic assumes invariance, but that is wrong.
184
- // This only presently applies to chalk integration, as NLL
185
- // doesn't permit type variables to appear on both sides (and
186
- // doesn't use lazy norm).
187
- match * value_ty. kind ( ) {
188
- ty:: Infer ( ty:: TyVar ( value_vid) ) => {
189
- // Two type variables: just equate them.
190
- self . infcx . inner . borrow_mut ( ) . type_variables ( ) . equate ( vid, value_vid) ;
191
- return Ok ( value_ty) ;
192
- }
193
-
194
- _ => ( ) ,
195
- }
196
-
197
- let generalized_ty = self . generalize ( value_ty, vid) ?;
198
- debug ! ( "relate_ty_var: generalized_ty = {:?}" , generalized_ty) ;
199
-
200
- if D :: forbid_inference_vars ( ) {
201
- // In NLL, we don't have type inference variables
202
- // floating around, so we can do this rather imprecise
203
- // variant of the occurs-check.
204
- assert ! ( !generalized_ty. has_non_region_infer( ) ) ;
205
- }
206
-
207
- self . infcx . inner . borrow_mut ( ) . type_variables ( ) . instantiate ( vid, generalized_ty) ;
208
-
209
- // Relate the generalized kind to the original one.
210
- let result = pair. relate_generalized_ty ( self , generalized_ty) ;
211
-
212
- debug ! ( "relate_ty_var: complete, result = {:?}" , result) ;
213
- result
214
- }
215
-
216
- fn generalize ( & mut self , ty : Ty < ' tcx > , for_vid : ty:: TyVid ) -> RelateResult < ' tcx , Ty < ' tcx > > {
217
- let Generalization { value_may_be_infer : ty, has_unconstrained_ty_var : _ } =
218
- generalize:: generalize (
219
- self . infcx ,
220
- & mut self . delegate ,
221
- ty,
222
- for_vid,
223
- self . ambient_variance ,
224
- ) ?;
225
-
226
- if ty. is_ty_var ( ) {
227
- span_bug ! ( self . delegate. span( ) , "occurs check failure in MIR typeck" ) ;
228
- }
229
- Ok ( ty)
230
- }
231
-
232
- fn relate_opaques ( & mut self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
145
+ fn relate_opaques ( & mut self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> RelateResult < ' tcx , ( ) > {
146
+ let infcx = self . infcx ;
147
+ debug_assert ! ( !infcx. next_trait_solver( ) ) ;
233
148
let ( a, b) = if self . a_is_expected ( ) { ( a, b) } else { ( b, a) } ;
234
- let mut generalize = |ty, ty_is_expected| {
235
- let var = self . infcx . next_ty_var_id_in_universe (
149
+ // `handle_opaque_type` cannot handle subtyping, so to support subtyping
150
+ // we instead eagerly generalize here. This is a bit of a mess but will go
151
+ // away once we're using the new solver.
152
+ let mut enable_subtyping = |ty, ty_is_expected| {
153
+ let ty_vid = infcx. next_ty_var_id_in_universe (
236
154
TypeVariableOrigin {
237
155
kind : TypeVariableOriginKind :: MiscVariable ,
238
156
span : self . delegate . span ( ) ,
239
157
} ,
240
158
ty:: UniverseIndex :: ROOT ,
241
159
) ;
242
- if ty_is_expected {
243
- self . relate_ty_var ( ( ty, var) )
160
+
161
+ let variance = if ty_is_expected {
162
+ self . ambient_variance
244
163
} else {
245
- self . relate_ty_var ( ( var, ty) )
246
- }
164
+ self . ambient_variance . xform ( ty:: Contravariant )
165
+ } ;
166
+
167
+ self . infcx . instantiate_ty_var ( self , ty_is_expected, ty_vid, variance, ty) ?;
168
+ Ok ( infcx. resolve_vars_if_possible ( Ty :: new_infer ( infcx. tcx , ty:: TyVar ( ty_vid) ) ) )
247
169
} ;
170
+
248
171
let ( a, b) = match ( a. kind ( ) , b. kind ( ) ) {
249
- ( & ty:: Alias ( ty:: Opaque , ..) , _) => ( a, generalize ( b, false ) ?) ,
250
- ( _, & ty:: Alias ( ty:: Opaque , ..) ) => ( generalize ( a, true ) ?, b) ,
172
+ ( & ty:: Alias ( ty:: Opaque , ..) , _) => ( a, enable_subtyping ( b, false ) ?) ,
173
+ ( _, & ty:: Alias ( ty:: Opaque , ..) ) => ( enable_subtyping ( a, true ) ?, b) ,
251
174
_ => unreachable ! (
252
175
"expected at least one opaque type in `relate_opaques`, got {a} and {b}."
253
176
) ,
254
177
} ;
255
178
let cause = ObligationCause :: dummy_with_span ( self . delegate . span ( ) ) ;
256
- let obligations = self
257
- . infcx
258
- . handle_opaque_type ( a, b, true , & cause, self . delegate . param_env ( ) ) ?
259
- . obligations ;
179
+ let obligations =
180
+ infcx. handle_opaque_type ( a, b, true , & cause, self . delegate . param_env ( ) ) ?. obligations ;
260
181
self . delegate . register_obligations ( obligations) ;
261
- trace ! ( a = ?a. kind( ) , b = ?b. kind( ) , "opaque type instantiated" ) ;
262
- Ok ( a)
182
+ Ok ( ( ) )
263
183
}
264
184
265
185
fn enter_forall < T , U > (
@@ -357,76 +277,6 @@ where
357
277
}
358
278
}
359
279
360
- /// When we instantiate an inference variable with a value in
361
- /// `relate_ty_var`, we always have the pair of a `TyVid` and a `Ty`,
362
- /// but the ordering may vary (depending on whether the inference
363
- /// variable was found on the `a` or `b` sides). Therefore, this trait
364
- /// allows us to factor out common code, while preserving the order
365
- /// when needed.
366
- trait VidValuePair < ' tcx > : Debug {
367
- /// Extract the inference variable (which could be either the
368
- /// first or second part of the tuple).
369
- fn vid ( & self ) -> ty:: TyVid ;
370
-
371
- /// Extract the value it is being related to (which will be the
372
- /// opposite part of the tuple from the vid).
373
- fn value_ty ( & self ) -> Ty < ' tcx > ;
374
-
375
- /// Given a generalized type G that should replace the vid, relate
376
- /// G to the value, putting G on whichever side the vid would have
377
- /// appeared.
378
- fn relate_generalized_ty < D > (
379
- & self ,
380
- relate : & mut TypeRelating < ' _ , ' tcx , D > ,
381
- generalized_ty : Ty < ' tcx > ,
382
- ) -> RelateResult < ' tcx , Ty < ' tcx > >
383
- where
384
- D : TypeRelatingDelegate < ' tcx > ;
385
- }
386
-
387
- impl < ' tcx > VidValuePair < ' tcx > for ( ty:: TyVid , Ty < ' tcx > ) {
388
- fn vid ( & self ) -> ty:: TyVid {
389
- self . 0
390
- }
391
-
392
- fn value_ty ( & self ) -> Ty < ' tcx > {
393
- self . 1
394
- }
395
-
396
- fn relate_generalized_ty < D > (
397
- & self ,
398
- relate : & mut TypeRelating < ' _ , ' tcx , D > ,
399
- generalized_ty : Ty < ' tcx > ,
400
- ) -> RelateResult < ' tcx , Ty < ' tcx > >
401
- where
402
- D : TypeRelatingDelegate < ' tcx > ,
403
- {
404
- relate. relate ( generalized_ty, self . value_ty ( ) )
405
- }
406
- }
407
-
408
- // In this case, the "vid" is the "b" type.
409
- impl < ' tcx > VidValuePair < ' tcx > for ( Ty < ' tcx > , ty:: TyVid ) {
410
- fn vid ( & self ) -> ty:: TyVid {
411
- self . 1
412
- }
413
-
414
- fn value_ty ( & self ) -> Ty < ' tcx > {
415
- self . 0
416
- }
417
-
418
- fn relate_generalized_ty < D > (
419
- & self ,
420
- relate : & mut TypeRelating < ' _ , ' tcx , D > ,
421
- generalized_ty : Ty < ' tcx > ,
422
- ) -> RelateResult < ' tcx , Ty < ' tcx > >
423
- where
424
- D : TypeRelatingDelegate < ' tcx > ,
425
- {
426
- relate. relate ( self . value_ty ( ) , generalized_ty)
427
- }
428
- }
429
-
430
280
impl < ' tcx , D > TypeRelation < ' tcx > for TypeRelating < ' _ , ' tcx , D >
431
281
where
432
282
D : TypeRelatingDelegate < ' tcx > ,
@@ -473,29 +323,39 @@ where
473
323
474
324
if !D :: forbid_inference_vars ( ) {
475
325
b = self . infcx . shallow_resolve ( b) ;
326
+ } else {
327
+ assert ! ( !b. has_non_region_infer( ) , "unexpected inference var {:?}" , b) ;
476
328
}
477
329
478
330
if a == b {
479
331
return Ok ( a) ;
480
332
}
481
333
482
334
match ( a. kind ( ) , b. kind ( ) ) {
483
- ( _, & ty:: Infer ( ty:: TyVar ( vid) ) ) => {
484
- if D :: forbid_inference_vars ( ) {
485
- // Forbid inference variables in the RHS.
486
- bug ! ( "unexpected inference var {:?}" , b)
487
- } else {
488
- self . relate_ty_var ( ( a, vid) )
335
+ ( & ty:: Infer ( ty:: TyVar ( a_vid) ) , & ty:: Infer ( ty:: TyVar ( b_vid) ) ) => {
336
+ match self . ambient_variance {
337
+ ty:: Invariant => infcx. inner . borrow_mut ( ) . type_variables ( ) . equate ( a_vid, b_vid) ,
338
+ _ => unimplemented ! ( ) ,
489
339
}
490
340
}
491
341
492
- ( & ty:: Infer ( ty:: TyVar ( vid) ) , _) => self . relate_ty_var ( ( vid, b) ) ,
342
+ ( & ty:: Infer ( ty:: TyVar ( a_vid) ) , _) => {
343
+ infcx. instantiate_ty_var ( self , true , a_vid, self . ambient_variance , b) ?
344
+ }
345
+
346
+ ( _, & ty:: Infer ( ty:: TyVar ( b_vid) ) ) => infcx. instantiate_ty_var (
347
+ self ,
348
+ false ,
349
+ b_vid,
350
+ self . ambient_variance . xform ( ty:: Contravariant ) ,
351
+ a,
352
+ ) ?,
493
353
494
354
(
495
355
& ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id : a_def_id, .. } ) ,
496
356
& ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id : b_def_id, .. } ) ,
497
357
) if a_def_id == b_def_id || infcx. next_trait_solver ( ) => {
498
- infcx. super_combine_tys ( self , a, b) . or_else ( |err| {
358
+ infcx. super_combine_tys ( self , a, b) . map ( |_| ( ) ) . or_else ( |err| {
499
359
// This behavior is only there for the old solver, the new solver
500
360
// shouldn't ever fail. Instead, it unconditionally emits an
501
361
// alias-relate goal.
@@ -505,22 +365,24 @@ where
505
365
"failure to relate an opaque to itself should result in an error later on" ,
506
366
) ;
507
367
if a_def_id. is_local ( ) { self . relate_opaques ( a, b) } else { Err ( err) }
508
- } )
368
+ } ) ? ;
509
369
}
510
370
( & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, .. } ) , _)
511
371
| ( _, & ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, .. } ) )
512
372
if def_id. is_local ( ) && !self . infcx . next_trait_solver ( ) =>
513
373
{
514
- self . relate_opaques ( a, b)
374
+ self . relate_opaques ( a, b) ? ;
515
375
}
516
376
517
377
_ => {
518
378
debug ! ( ?a, ?b, ?self . ambient_variance) ;
519
379
520
380
// Will also handle unification of `IntVar` and `FloatVar`.
521
- self . infcx . super_combine_tys ( self , a, b)
381
+ self . infcx . super_combine_tys ( self , a, b) ? ;
522
382
}
523
383
}
384
+
385
+ Ok ( a)
524
386
}
525
387
526
388
#[ instrument( skip( self ) , level = "trace" ) ]
0 commit comments