Skip to content

Commit 55412a2

Browse files
committedMay 3, 2017
track CurrentItem, not just Generics
1 parent b175aef commit 55412a2

File tree

1 file changed

+54
-37
lines changed

1 file changed

+54
-37
lines changed
 

‎src/librustc_typeck/variance/constraints.rs

+54-37
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,21 @@ pub struct Constraint<'a> {
4848
pub variance: &'a VarianceTerm<'a>,
4949
}
5050

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+
5166
pub fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>)
5267
-> ConstraintContext<'a, 'tcx> {
5368
let tcx = terms_cx.tcx;
@@ -73,7 +88,7 @@ pub fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>)
7388
impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> {
7489
fn visit_item(&mut self, item: &hir::Item) {
7590
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);
7792

7893
debug!("visit_item item={}", tcx.hir.node_to_string(item.id));
7994

@@ -82,6 +97,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> {
8297
hir::ItemStruct(..) |
8398
hir::ItemUnion(..) => {
8499
let generics = tcx.generics_of(did);
100+
let current_item = &CurrentItem { def_id, generics };
85101

86102
// Not entirely obvious: constraints on structs/enums do not
87103
// affect the variance of their type parameters. See discussion
@@ -90,18 +106,19 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> {
90106
// self.add_constraints_from_generics(generics);
91107

92108
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),
95111
self.covariant);
96112
}
97113
}
98114
hir::ItemTrait(..) => {
99115
let generics = tcx.generics_of(did);
116+
let current_item = &CurrentItem { def_id, generics };
100117
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)
103120
};
104-
self.add_constraints_from_trait_ref(generics,
121+
self.add_constraints_from_trait_ref(current_item,
105122
trait_ref,
106123
self.invariant);
107124
}
@@ -279,7 +296,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
279296
}
280297

281298
fn add_constraints_from_trait_ref(&mut self,
282-
generics: &ty::Generics,
299+
current: &CurrentItem,
283300
trait_ref: ty::TraitRef<'tcx>,
284301
variance: VarianceTermPtr<'a>) {
285302
debug!("add_constraints_from_trait_ref: trait_ref={:?} variance={:?}",
@@ -293,7 +310,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
293310
// README.md for a discussion on dep-graph management.
294311
self.tcx().dep_graph.read(VarianceDepNode(trait_ref.def_id));
295312

296-
self.add_constraints_from_substs(generics,
313+
self.add_constraints_from_substs(current,
297314
trait_ref.def_id,
298315
&trait_generics.types,
299316
&trait_generics.regions,
@@ -305,7 +322,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
305322
/// in a context with the generics defined in `generics` and
306323
/// ambient variance `variance`
307324
fn add_constraints_from_ty(&mut self,
308-
generics: &ty::Generics,
325+
current: &CurrentItem,
309326
ty: Ty<'tcx>,
310327
variance: VarianceTermPtr<'a>) {
311328
debug!("add_constraints_from_ty(ty={:?}, variance={:?})",
@@ -325,22 +342,22 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
325342

326343
ty::TyRef(region, ref mt) => {
327344
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);
330347
}
331348

332349
ty::TyArray(typ, _) |
333350
ty::TySlice(typ) => {
334-
self.add_constraints_from_ty(generics, typ, variance);
351+
self.add_constraints_from_ty(current, typ, variance);
335352
}
336353

337354
ty::TyRawPtr(ref mt) => {
338-
self.add_constraints_from_mt(generics, mt, variance);
355+
self.add_constraints_from_mt(current, mt, variance);
339356
}
340357

341358
ty::TyTuple(subtys, _) => {
342359
for &subty in subtys {
343-
self.add_constraints_from_ty(generics, subty, variance);
360+
self.add_constraints_from_ty(current, subty, variance);
344361
}
345362
}
346363

@@ -352,7 +369,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
352369
// README.md for a discussion on dep-graph management.
353370
self.tcx().dep_graph.read(VarianceDepNode(def.did));
354371

355-
self.add_constraints_from_substs(generics,
372+
self.add_constraints_from_substs(current,
356373
def.did,
357374
&adt_generics.types,
358375
&adt_generics.regions,
@@ -369,7 +386,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
369386
// README.md for a discussion on dep-graph management.
370387
self.tcx().dep_graph.read(VarianceDepNode(trait_ref.def_id));
371388

372-
self.add_constraints_from_substs(generics,
389+
self.add_constraints_from_substs(current,
373390
trait_ref.def_id,
374391
&trait_generics.types,
375392
&trait_generics.regions,
@@ -380,25 +397,25 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
380397
ty::TyDynamic(ref data, r) => {
381398
// The type `Foo<T+'a>` is contravariant w/r/t `'a`:
382399
let contra = self.contravariant(variance);
383-
self.add_constraints_from_region(generics, r, contra);
400+
self.add_constraints_from_region(current, r, contra);
384401

385402
if let Some(p) = data.principal() {
386403
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);
388405
}
389406

390407
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);
392409
}
393410
}
394411

395412
ty::TyParam(ref data) => {
396-
assert_eq!(generics.parent, None);
413+
assert_eq!(current.generics.parent, None);
397414
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();
400417
}
401-
let def_id = generics.types[i].def_id;
418+
let def_id = current.generics.types[i].def_id;
402419
let node_id = self.tcx().hir.as_local_node_id(def_id).unwrap();
403420
match self.terms_cx.inferred_map.get(&node_id) {
404421
Some(&index) => {
@@ -414,7 +431,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
414431

415432
ty::TyFnDef(.., sig) |
416433
ty::TyFnPtr(sig) => {
417-
self.add_constraints_from_sig(generics, sig, variance);
434+
self.add_constraints_from_sig(current, sig, variance);
418435
}
419436

420437
ty::TyError => {
@@ -433,7 +450,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
433450
/// Adds constraints appropriate for a nominal type (enum, struct,
434451
/// object, etc) appearing in a context with ambient variance `variance`
435452
fn add_constraints_from_substs(&mut self,
436-
generics: &ty::Generics,
453+
current: &CurrentItem,
437454
def_id: DefId,
438455
type_param_defs: &[ty::TypeParameterDef],
439456
region_param_defs: &[ty::RegionParameterDef],
@@ -451,41 +468,41 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
451468
debug!("add_constraints_from_substs: variance_decl={:?} variance_i={:?}",
452469
variance_decl,
453470
variance_i);
454-
self.add_constraints_from_ty(generics, substs_ty, variance_i);
471+
self.add_constraints_from_ty(current, substs_ty, variance_i);
455472
}
456473

457474
for p in region_param_defs {
458475
let variance_decl = self.declared_variance(p.def_id, def_id, p.index as usize);
459476
let variance_i = self.xform(variance, variance_decl);
460477
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);
462479
}
463480
}
464481

465482
/// Adds constraints appropriate for a function with signature
466483
/// `sig` appearing in a context with ambient variance `variance`
467484
fn add_constraints_from_sig(&mut self,
468-
generics: &ty::Generics,
485+
current: &CurrentItem,
469486
sig: ty::PolyFnSig<'tcx>,
470487
variance: VarianceTermPtr<'a>) {
471488
let contra = self.contravariant(variance);
472489
for &input in sig.0.inputs() {
473-
self.add_constraints_from_ty(generics, input, contra);
490+
self.add_constraints_from_ty(current, input, contra);
474491
}
475-
self.add_constraints_from_ty(generics, sig.0.output(), variance);
492+
self.add_constraints_from_ty(current, sig.0.output(), variance);
476493
}
477494

478495
/// Adds constraints appropriate for a region appearing in a
479496
/// context with ambient variance `variance`
480497
fn add_constraints_from_region(&mut self,
481-
generics: &ty::Generics,
498+
current: &CurrentItem,
482499
region: ty::Region<'tcx>,
483500
variance: VarianceTermPtr<'a>) {
484501
match *region {
485502
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;
489506
let node_id = self.tcx().hir.as_local_node_id(def_id).unwrap();
490507
if self.is_to_be_inferred(node_id) {
491508
let index = self.inferred_index(node_id);
@@ -518,17 +535,17 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
518535
/// Adds constraints appropriate for a mutability-type pair
519536
/// appearing in a context with ambient variance `variance`
520537
fn add_constraints_from_mt(&mut self,
521-
generics: &ty::Generics,
538+
current: &CurrentItem,
522539
mt: &ty::TypeAndMut<'tcx>,
523540
variance: VarianceTermPtr<'a>) {
524541
match mt.mutbl {
525542
hir::MutMutable => {
526543
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);
528545
}
529546

530547
hir::MutImmutable => {
531-
self.add_constraints_from_ty(generics, mt.ty, variance);
548+
self.add_constraints_from_ty(current, mt.ty, variance);
532549
}
533550
}
534551
}

0 commit comments

Comments
 (0)
Please sign in to comment.