@@ -48,6 +48,21 @@ pub struct Constraint<'a> {
48
48
pub variance : & ' a VarianceTerm < ' a > ,
49
49
}
50
50
51
+ /// To build constriants, we visit one item (type, trait) at a time
52
+ /// and look at its contents. So e.g. if we have
53
+ ///
54
+ /// struct Foo<T> {
55
+ /// b: Bar<T>
56
+ /// }
57
+ ///
58
+ /// then while we are visiting `Bar<T>`, the `CurrentItem` would have
59
+ /// the def-id and generics of `Foo`.
60
+ #[ allow( dead_code) ] // TODO -- `def_id` field not used yet
61
+ pub struct CurrentItem < ' a > {
62
+ def_id : DefId ,
63
+ generics : & ' a ty:: Generics ,
64
+ }
65
+
51
66
pub fn add_constraints_from_crate < ' a , ' tcx > ( terms_cx : TermsContext < ' a , ' tcx > )
52
67
-> ConstraintContext < ' a , ' tcx > {
53
68
let tcx = terms_cx. tcx ;
@@ -73,7 +88,7 @@ pub fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>)
73
88
impl < ' a , ' tcx , ' v > ItemLikeVisitor < ' v > for ConstraintContext < ' a , ' tcx > {
74
89
fn visit_item ( & mut self , item : & hir:: Item ) {
75
90
let tcx = self . terms_cx . tcx ;
76
- let did = tcx. hir . local_def_id ( item. id ) ;
91
+ let def_id = tcx. hir . local_def_id ( item. id ) ;
77
92
78
93
debug ! ( "visit_item item={}" , tcx. hir. node_to_string( item. id) ) ;
79
94
@@ -82,6 +97,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> {
82
97
hir:: ItemStruct ( ..) |
83
98
hir:: ItemUnion ( ..) => {
84
99
let generics = tcx. generics_of ( did) ;
100
+ let current_item = & CurrentItem { def_id, generics } ;
85
101
86
102
// Not entirely obvious: constraints on structs/enums do not
87
103
// affect the variance of their type parameters. See discussion
@@ -90,18 +106,19 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> {
90
106
// self.add_constraints_from_generics(generics);
91
107
92
108
for field in tcx. adt_def ( did) . all_fields ( ) {
93
- self . add_constraints_from_ty ( generics ,
94
- tcx. type_of ( field. did ) ,
109
+ self . add_constraints_from_ty ( current_item ,
110
+ tcx. item_type ( field. did ) ,
95
111
self . covariant ) ;
96
112
}
97
113
}
98
114
hir:: ItemTrait ( ..) => {
99
115
let generics = tcx. generics_of ( did) ;
116
+ let current_item = & CurrentItem { def_id, generics } ;
100
117
let trait_ref = ty:: TraitRef {
101
- def_id : did ,
102
- substs : Substs :: identity_for_item ( tcx, did )
118
+ def_id : def_id ,
119
+ substs : Substs :: identity_for_item ( tcx, def_id )
103
120
} ;
104
- self . add_constraints_from_trait_ref ( generics ,
121
+ self . add_constraints_from_trait_ref ( current_item ,
105
122
trait_ref,
106
123
self . invariant ) ;
107
124
}
@@ -279,7 +296,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
279
296
}
280
297
281
298
fn add_constraints_from_trait_ref ( & mut self ,
282
- generics : & ty :: Generics ,
299
+ current : & CurrentItem ,
283
300
trait_ref : ty:: TraitRef < ' tcx > ,
284
301
variance : VarianceTermPtr < ' a > ) {
285
302
debug ! ( "add_constraints_from_trait_ref: trait_ref={:?} variance={:?}" ,
@@ -293,7 +310,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
293
310
// README.md for a discussion on dep-graph management.
294
311
self . tcx ( ) . dep_graph . read ( VarianceDepNode ( trait_ref. def_id ) ) ;
295
312
296
- self . add_constraints_from_substs ( generics ,
313
+ self . add_constraints_from_substs ( current ,
297
314
trait_ref. def_id ,
298
315
& trait_generics. types ,
299
316
& trait_generics. regions ,
@@ -305,7 +322,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
305
322
/// in a context with the generics defined in `generics` and
306
323
/// ambient variance `variance`
307
324
fn add_constraints_from_ty ( & mut self ,
308
- generics : & ty :: Generics ,
325
+ current : & CurrentItem ,
309
326
ty : Ty < ' tcx > ,
310
327
variance : VarianceTermPtr < ' a > ) {
311
328
debug ! ( "add_constraints_from_ty(ty={:?}, variance={:?})" ,
@@ -325,22 +342,22 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
325
342
326
343
ty:: TyRef ( region, ref mt) => {
327
344
let contra = self . contravariant ( variance) ;
328
- self . add_constraints_from_region ( generics , region, contra) ;
329
- self . add_constraints_from_mt ( generics , mt, variance) ;
345
+ self . add_constraints_from_region ( current , region, contra) ;
346
+ self . add_constraints_from_mt ( current , mt, variance) ;
330
347
}
331
348
332
349
ty:: TyArray ( typ, _) |
333
350
ty:: TySlice ( typ) => {
334
- self . add_constraints_from_ty ( generics , typ, variance) ;
351
+ self . add_constraints_from_ty ( current , typ, variance) ;
335
352
}
336
353
337
354
ty:: TyRawPtr ( ref mt) => {
338
- self . add_constraints_from_mt ( generics , mt, variance) ;
355
+ self . add_constraints_from_mt ( current , mt, variance) ;
339
356
}
340
357
341
358
ty:: TyTuple ( subtys, _) => {
342
359
for & subty in subtys {
343
- self . add_constraints_from_ty ( generics , subty, variance) ;
360
+ self . add_constraints_from_ty ( current , subty, variance) ;
344
361
}
345
362
}
346
363
@@ -352,7 +369,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
352
369
// README.md for a discussion on dep-graph management.
353
370
self . tcx ( ) . dep_graph . read ( VarianceDepNode ( def. did ) ) ;
354
371
355
- self . add_constraints_from_substs ( generics ,
372
+ self . add_constraints_from_substs ( current ,
356
373
def. did ,
357
374
& adt_generics. types ,
358
375
& adt_generics. regions ,
@@ -369,7 +386,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
369
386
// README.md for a discussion on dep-graph management.
370
387
self . tcx ( ) . dep_graph . read ( VarianceDepNode ( trait_ref. def_id ) ) ;
371
388
372
- self . add_constraints_from_substs ( generics ,
389
+ self . add_constraints_from_substs ( current ,
373
390
trait_ref. def_id ,
374
391
& trait_generics. types ,
375
392
& trait_generics. regions ,
@@ -380,25 +397,25 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
380
397
ty:: TyDynamic ( ref data, r) => {
381
398
// The type `Foo<T+'a>` is contravariant w/r/t `'a`:
382
399
let contra = self . contravariant ( variance) ;
383
- self . add_constraints_from_region ( generics , r, contra) ;
400
+ self . add_constraints_from_region ( current , r, contra) ;
384
401
385
402
if let Some ( p) = data. principal ( ) {
386
403
let poly_trait_ref = p. with_self_ty ( self . tcx ( ) , self . tcx ( ) . types . err ) ;
387
- self . add_constraints_from_trait_ref ( generics , poly_trait_ref. 0 , variance) ;
404
+ self . add_constraints_from_trait_ref ( current , poly_trait_ref. 0 , variance) ;
388
405
}
389
406
390
407
for projection in data. projection_bounds ( ) {
391
- self . add_constraints_from_ty ( generics , projection. 0 . ty , self . invariant ) ;
408
+ self . add_constraints_from_ty ( current , projection. 0 . ty , self . invariant ) ;
392
409
}
393
410
}
394
411
395
412
ty:: TyParam ( ref data) => {
396
- assert_eq ! ( generics. parent, None ) ;
413
+ assert_eq ! ( current . generics. parent, None ) ;
397
414
let mut i = data. idx as usize ;
398
- if !generics. has_self || i > 0 {
399
- i -= generics. regions . len ( ) ;
415
+ if !current . generics . has_self || i > 0 {
416
+ i -= current . generics . regions . len ( ) ;
400
417
}
401
- let def_id = generics. types [ i] . def_id ;
418
+ let def_id = current . generics . types [ i] . def_id ;
402
419
let node_id = self . tcx ( ) . hir . as_local_node_id ( def_id) . unwrap ( ) ;
403
420
match self . terms_cx . inferred_map . get ( & node_id) {
404
421
Some ( & index) => {
@@ -414,7 +431,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
414
431
415
432
ty:: TyFnDef ( .., sig) |
416
433
ty:: TyFnPtr ( sig) => {
417
- self . add_constraints_from_sig ( generics , sig, variance) ;
434
+ self . add_constraints_from_sig ( current , sig, variance) ;
418
435
}
419
436
420
437
ty:: TyError => {
@@ -433,7 +450,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
433
450
/// Adds constraints appropriate for a nominal type (enum, struct,
434
451
/// object, etc) appearing in a context with ambient variance `variance`
435
452
fn add_constraints_from_substs ( & mut self ,
436
- generics : & ty :: Generics ,
453
+ current : & CurrentItem ,
437
454
def_id : DefId ,
438
455
type_param_defs : & [ ty:: TypeParameterDef ] ,
439
456
region_param_defs : & [ ty:: RegionParameterDef ] ,
@@ -451,41 +468,41 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
451
468
debug ! ( "add_constraints_from_substs: variance_decl={:?} variance_i={:?}" ,
452
469
variance_decl,
453
470
variance_i) ;
454
- self . add_constraints_from_ty ( generics , substs_ty, variance_i) ;
471
+ self . add_constraints_from_ty ( current , substs_ty, variance_i) ;
455
472
}
456
473
457
474
for p in region_param_defs {
458
475
let variance_decl = self . declared_variance ( p. def_id , def_id, p. index as usize ) ;
459
476
let variance_i = self . xform ( variance, variance_decl) ;
460
477
let substs_r = substs. region_for_def ( p) ;
461
- self . add_constraints_from_region ( generics , substs_r, variance_i) ;
478
+ self . add_constraints_from_region ( current , substs_r, variance_i) ;
462
479
}
463
480
}
464
481
465
482
/// Adds constraints appropriate for a function with signature
466
483
/// `sig` appearing in a context with ambient variance `variance`
467
484
fn add_constraints_from_sig ( & mut self ,
468
- generics : & ty :: Generics ,
485
+ current : & CurrentItem ,
469
486
sig : ty:: PolyFnSig < ' tcx > ,
470
487
variance : VarianceTermPtr < ' a > ) {
471
488
let contra = self . contravariant ( variance) ;
472
489
for & input in sig. 0 . inputs ( ) {
473
- self . add_constraints_from_ty ( generics , input, contra) ;
490
+ self . add_constraints_from_ty ( current , input, contra) ;
474
491
}
475
- self . add_constraints_from_ty ( generics , sig. 0 . output ( ) , variance) ;
492
+ self . add_constraints_from_ty ( current , sig. 0 . output ( ) , variance) ;
476
493
}
477
494
478
495
/// Adds constraints appropriate for a region appearing in a
479
496
/// context with ambient variance `variance`
480
497
fn add_constraints_from_region ( & mut self ,
481
- generics : & ty :: Generics ,
498
+ current : & CurrentItem ,
482
499
region : ty:: Region < ' tcx > ,
483
500
variance : VarianceTermPtr < ' a > ) {
484
501
match * region {
485
502
ty:: ReEarlyBound ( ref data) => {
486
- assert_eq ! ( generics. parent, None ) ;
487
- let i = data. index as usize - generics. has_self as usize ;
488
- let def_id = generics. regions [ i] . def_id ;
503
+ assert_eq ! ( current . generics. parent, None ) ;
504
+ let i = data. index as usize - current . generics . has_self as usize ;
505
+ let def_id = current . generics . regions [ i] . def_id ;
489
506
let node_id = self . tcx ( ) . hir . as_local_node_id ( def_id) . unwrap ( ) ;
490
507
if self . is_to_be_inferred ( node_id) {
491
508
let index = self . inferred_index ( node_id) ;
@@ -518,17 +535,17 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
518
535
/// Adds constraints appropriate for a mutability-type pair
519
536
/// appearing in a context with ambient variance `variance`
520
537
fn add_constraints_from_mt ( & mut self ,
521
- generics : & ty :: Generics ,
538
+ current : & CurrentItem ,
522
539
mt : & ty:: TypeAndMut < ' tcx > ,
523
540
variance : VarianceTermPtr < ' a > ) {
524
541
match mt. mutbl {
525
542
hir:: MutMutable => {
526
543
let invar = self . invariant ( variance) ;
527
- self . add_constraints_from_ty ( generics , mt. ty , invar) ;
544
+ self . add_constraints_from_ty ( current , mt. ty , invar) ;
528
545
}
529
546
530
547
hir:: MutImmutable => {
531
- self . add_constraints_from_ty ( generics , mt. ty , variance) ;
548
+ self . add_constraints_from_ty ( current , mt. ty , variance) ;
532
549
}
533
550
}
534
551
}
0 commit comments