Skip to content

Commit 0666255

Browse files
committed
Simplify variance code to just track *VARIANT* and *INVARIANT*.
1 parent d515e9c commit 0666255

15 files changed

+91
-163
lines changed

src/librustc/middle/implicator.rs

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -272,28 +272,16 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
272272
.map(|pred| Implication::Predicate(def_id, pred));
273273
self.out.extend(obligations);
274274

275-
let variances = self.tcx().item_variances(def_id);
276-
277-
for (&region, &variance) in substs.regions().iter().zip(&variances.regions) {
278-
match variance {
279-
ty::Contravariant | ty::Invariant => {
280-
// If any data with this lifetime is reachable
281-
// within, it must be at least contravariant.
282-
self.push_region_constraint_from_top(region)
283-
}
284-
ty::Covariant | ty::Bivariant => { }
285-
}
275+
for &region in substs.regions().iter() {
276+
// If any data with this lifetime is reachable
277+
// within, it must be at least contravariant.
278+
self.push_region_constraint_from_top(region)
286279
}
287280

288-
for (&ty, &variance) in substs.types.iter().zip(&variances.types) {
289-
match variance {
290-
ty::Covariant | ty::Invariant => {
291-
// If any data of this type is reachable within,
292-
// it must be at least covariant.
293-
self.accumulate_from_ty(ty);
294-
}
295-
ty::Contravariant | ty::Bivariant => { }
296-
}
281+
for &ty in substs.types.iter() {
282+
// If any data of this type is reachable within,
283+
// it must be at least covariant.
284+
self.accumulate_from_ty(ty);
297285
}
298286
}
299287

src/librustc/middle/lang_items.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -328,14 +328,6 @@ lets_do_this! {
328328

329329
PhantomDataItem, "phantom_data", phantom_data;
330330

331-
// Deprecated:
332-
CovariantTypeItem, "covariant_type", covariant_type;
333-
ContravariantTypeItem, "contravariant_type", contravariant_type;
334-
InvariantTypeItem, "invariant_type", invariant_type;
335-
CovariantLifetimeItem, "covariant_lifetime", covariant_lifetime;
336-
ContravariantLifetimeItem, "contravariant_lifetime", contravariant_lifetime;
337-
InvariantLifetimeItem, "invariant_lifetime", invariant_lifetime;
338-
339331
NoCopyItem, "no_copy_bound", no_copy_bound;
340332

341333
NonZeroItem, "non_zero", non_zero;

src/librustc/middle/ty.rs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ pub use self::InferTy::*;
1616
pub use self::InferRegion::*;
1717
pub use self::ImplOrTraitItemId::*;
1818
pub use self::ClosureKind::*;
19-
pub use self::Variance::*;
2019
pub use self::AutoAdjustment::*;
2120
pub use self::Representability::*;
2221
pub use self::AutoRef::*;
@@ -507,23 +506,11 @@ pub struct ItemVariances {
507506
pub regions: VecPerParamSpace<Variance>,
508507
}
509508

510-
#[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
509+
#[derive(Clone, Debug, PartialEq, RustcDecodable, RustcEncodable, Copy)]
511510
pub enum Variance {
512-
Covariant, // T<A> <: T<B> iff A <: B -- e.g., function return type
513-
Invariant, // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
514-
Contravariant, // T<A> <: T<B> iff B <: A -- e.g., function param type
515-
Bivariant, // T<A> <: T<B> -- e.g., unused type parameter
516-
}
517-
518-
impl fmt::Debug for Variance {
519-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
520-
f.write_str(match *self {
521-
Covariant => "+",
522-
Contravariant => "-",
523-
Invariant => "o",
524-
Bivariant => "*",
525-
})
526-
}
511+
B, // Bivariant
512+
V, // Variant (co- for types, contra- for lifetimes)
513+
I, // Invariant
527514
}
528515

529516
#[derive(Copy, Clone)]

src/librustc/middle/ty_relate/mod.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,11 @@ fn relate_type_params<'a,'tcx:'a,R>(relation: &mut R,
191191
.map(|i| {
192192
let a_ty = a_tys[i];
193193
let b_ty = b_tys[i];
194-
let v = variances.map_or(ty::Invariant, |v| v[i]);
194+
let v = variances.map_or(ty::Variance::I, |v| v[i]);
195195
match v {
196-
ty::Bivariant => relation.bivar(&a_ty, &b_ty),
197-
ty::Covariant => relation.relate(&a_ty, &b_ty),
198-
ty::Contravariant => relation.contra(&a_ty, &b_ty),
199-
ty::Invariant => relation.equate(&a_ty, &b_ty),
196+
ty::Variance::B => relation.bivar(&a_ty, &b_ty),
197+
ty::Variance::V => relation.relate(&a_ty, &b_ty),
198+
ty::Variance::I => relation.equate(&a_ty, &b_ty),
200199
}
201200
})
202201
.collect()
@@ -227,12 +226,11 @@ fn relate_region_params<'a,'tcx:'a,R>(relation: &mut R,
227226
.map(|i| {
228227
let a_r = a_rs[i];
229228
let b_r = b_rs[i];
230-
let variance = variances.map_or(ty::Invariant, |v| v[i]);
229+
let variance = variances.map_or(ty::Variance::I, |v| v[i]);
231230
match variance {
232-
ty::Bivariant => relation.bivar(&a_r, &b_r),
233-
ty::Covariant => relation.relate(&a_r, &b_r),
234-
ty::Contravariant => relation.contra(&a_r, &b_r),
235-
ty::Invariant => relation.equate(&a_r, &b_r),
231+
ty::Variance::B => relation.bivar(&a_r, &b_r),
232+
ty::Variance::V => relation.contra(&a_r, &b_r),
233+
ty::Variance::I => relation.equate(&a_r, &b_r),
236234
}
237235
})
238236
.collect()

src/librustc_typeck/check/wf.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
291291
let mut constrained_parameters: HashSet<_> =
292292
variances.types
293293
.iter_enumerated()
294-
.filter(|&(_, _, &variance)| variance != ty::Bivariant)
294+
.filter(|&(_, _, &variance)| variance != ty::Variance::B)
295295
.map(|(space, index, _)| self.param_ty(ast_generics, space, index))
296296
.map(|p| Parameter::Type(p))
297297
.collect();
@@ -311,7 +311,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
311311
}
312312

313313
for (space, index, &variance) in variances.regions.iter_enumerated() {
314-
if variance != ty::Bivariant {
314+
if variance != ty::Variance::B {
315315
continue;
316316
}
317317

src/librustc_typeck/variance.rs

Lines changed: 27 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -389,17 +389,8 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
389389

390390
fn lang_items(tcx: &ty::ctxt) -> Vec<(ast::NodeId,Vec<ty::Variance>)> {
391391
let all = vec![
392-
(tcx.lang_items.phantom_data(), vec![ty::Covariant]),
393-
(tcx.lang_items.unsafe_cell_type(), vec![ty::Invariant]),
394-
395-
// Deprecated:
396-
(tcx.lang_items.covariant_type(), vec![ty::Covariant]),
397-
(tcx.lang_items.contravariant_type(), vec![ty::Contravariant]),
398-
(tcx.lang_items.invariant_type(), vec![ty::Invariant]),
399-
(tcx.lang_items.covariant_lifetime(), vec![ty::Covariant]),
400-
(tcx.lang_items.contravariant_lifetime(), vec![ty::Contravariant]),
401-
(tcx.lang_items.invariant_lifetime(), vec![ty::Invariant]),
402-
392+
(tcx.lang_items.phantom_data(), vec![ty::Variance::V]),
393+
(tcx.lang_items.unsafe_cell_type(), vec![ty::Variance::I]),
403394
];
404395

405396
all.into_iter()
@@ -498,13 +489,13 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
498489
{
499490
match space {
500491
SelfSpace | FnSpace => {
501-
ty::Bivariant
492+
ty::Variance::B
502493
}
503494

504495
TypeSpace => {
505496
match self.lang_items.iter().find(|&&(n, _)| n == item_id) {
506497
Some(&(_, ref variances)) => variances[index],
507-
None => ty::Bivariant
498+
None => ty::Variance::B
508499
}
509500
}
510501
}
@@ -558,8 +549,7 @@ struct ConstraintContext<'a, 'tcx: 'a> {
558549
terms_cx: TermsContext<'a, 'tcx>,
559550

560551
// These are pointers to common `ConstantTerm` instances
561-
covariant: VarianceTermPtr<'a>,
562-
contravariant: VarianceTermPtr<'a>,
552+
variant: VarianceTermPtr<'a>,
563553
invariant: VarianceTermPtr<'a>,
564554
bivariant: VarianceTermPtr<'a>,
565555

@@ -578,14 +568,12 @@ fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>,
578568
krate: &ast::Crate)
579569
-> ConstraintContext<'a, 'tcx>
580570
{
581-
let covariant = terms_cx.arena.alloc(ConstantTerm(ty::Covariant));
582-
let contravariant = terms_cx.arena.alloc(ConstantTerm(ty::Contravariant));
583-
let invariant = terms_cx.arena.alloc(ConstantTerm(ty::Invariant));
584-
let bivariant = terms_cx.arena.alloc(ConstantTerm(ty::Bivariant));
571+
let variant = terms_cx.arena.alloc(ConstantTerm(ty::Variance::V));
572+
let invariant = terms_cx.arena.alloc(ConstantTerm(ty::Variance::I));
573+
let bivariant = terms_cx.arena.alloc(ConstantTerm(ty::Variance::B));
585574
let mut constraint_cx = ConstraintContext {
586575
terms_cx: terms_cx,
587-
covariant: covariant,
588-
contravariant: contravariant,
576+
variant: variant,
589577
invariant: invariant,
590578
bivariant: bivariant,
591579
constraints: Vec::new(),
@@ -627,7 +615,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
627615
&**ast_variant,
628616
/*discriminant*/ 0);
629617
for arg_ty in &variant.args {
630-
self.add_constraints_from_ty(&scheme.generics, *arg_ty, self.covariant);
618+
self.add_constraints_from_ty(&scheme.generics, *arg_ty, self.variant);
631619
}
632620
}
633621
}
@@ -645,7 +633,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
645633
for field_info in &struct_fields {
646634
assert_eq!(field_info.id.krate, ast::LOCAL_CRATE);
647635
let field_ty = tcx.node_id_to_type(field_info.id.node);
648-
self.add_constraints_from_ty(&scheme.generics, field_ty, self.covariant);
636+
self.add_constraints_from_ty(&scheme.generics, field_ty, self.variant);
649637
}
650638
}
651639

@@ -799,12 +787,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
799787
variance: variance });
800788
}
801789

802-
fn contravariant(&mut self,
803-
variance: VarianceTermPtr<'a>)
804-
-> VarianceTermPtr<'a> {
805-
self.xform(variance, self.contravariant)
806-
}
807-
808790
fn invariant(&mut self,
809791
variance: VarianceTermPtr<'a>)
810792
-> VarianceTermPtr<'a> {
@@ -813,10 +795,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
813795

814796
fn constant_term(&self, v: ty::Variance) -> VarianceTermPtr<'a> {
815797
match v {
816-
ty::Covariant => self.covariant,
817-
ty::Invariant => self.invariant,
818-
ty::Contravariant => self.contravariant,
819-
ty::Bivariant => self.bivariant,
798+
ty::Variance::V => self.variant,
799+
ty::Variance::I => self.invariant,
800+
ty::Variance::B => self.bivariant,
820801
}
821802
}
822803

@@ -825,8 +806,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
825806
v2: VarianceTermPtr<'a>)
826807
-> VarianceTermPtr<'a> {
827808
match (*v1, *v2) {
828-
(_, ConstantTerm(ty::Covariant)) => {
829-
// Applying a "covariant" transform is always a no-op
809+
(_, ConstantTerm(ty::Variance::V)) => {
810+
// Applying a "variant" transform is always a no-op
830811
v1
831812
}
832813

@@ -882,8 +863,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
882863
}
883864

884865
ty::TyRef(region, ref mt) => {
885-
let contra = self.contravariant(variance);
886-
self.add_constraints_from_region(generics, *region, contra);
866+
self.add_constraints_from_region(generics, *region, variance);
887867
self.add_constraints_from_mt(generics, mt, variance);
888868
}
889869

@@ -939,9 +919,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
939919
data.principal_trait_ref_with_self_ty(self.tcx(),
940920
self.tcx().types.err);
941921

942-
// The type `Foo<T+'a>` is contravariant w/r/t `'a`:
943-
let contra = self.contravariant(variance);
944-
self.add_constraints_from_region(generics, data.bounds.region_bound, contra);
922+
// The type `Foo<T+'a>` is variant w/r/t `'a`:
923+
self.add_constraints_from_region(generics, data.bounds.region_bound, variance);
945924

946925
// Ignore the SelfSpace, it is erased.
947926
self.add_constraints_from_trait_ref(generics, poly_trait_ref.0, variance);
@@ -1240,22 +1219,13 @@ impl Xform for ty::Variance {
12401219
// "Variance transformation", Figure 1 of The Paper
12411220
match (self, v) {
12421221
// Figure 1, column 1.
1243-
(ty::Covariant, ty::Covariant) => ty::Covariant,
1244-
(ty::Covariant, ty::Contravariant) => ty::Contravariant,
1245-
(ty::Covariant, ty::Invariant) => ty::Invariant,
1246-
(ty::Covariant, ty::Bivariant) => ty::Bivariant,
1247-
1248-
// Figure 1, column 2.
1249-
(ty::Contravariant, ty::Covariant) => ty::Contravariant,
1250-
(ty::Contravariant, ty::Contravariant) => ty::Covariant,
1251-
(ty::Contravariant, ty::Invariant) => ty::Invariant,
1252-
(ty::Contravariant, ty::Bivariant) => ty::Bivariant,
1222+
(ty::Variance::V, v) => v,
12531223

12541224
// Figure 1, column 3.
1255-
(ty::Invariant, _) => ty::Invariant,
1225+
(ty::Variance::I, _) => ty::Variance::I,
12561226

12571227
// Figure 1, column 4.
1258-
(ty::Bivariant, _) => ty::Bivariant,
1228+
(ty::Variance::B, _) => ty::Variance::B,
12591229
}
12601230
}
12611231
}
@@ -1265,18 +1235,11 @@ fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance {
12651235
// defined in The Paper:
12661236
//
12671237
// *
1268-
// - +
1269-
// o
1238+
// v
1239+
// i
12701240
match (v1, v2) {
1271-
(ty::Invariant, _) | (_, ty::Invariant) => ty::Invariant,
1272-
1273-
(ty::Covariant, ty::Contravariant) => ty::Invariant,
1274-
(ty::Contravariant, ty::Covariant) => ty::Invariant,
1275-
1276-
(ty::Covariant, ty::Covariant) => ty::Covariant,
1277-
1278-
(ty::Contravariant, ty::Contravariant) => ty::Contravariant,
1279-
1280-
(x, ty::Bivariant) | (ty::Bivariant, x) => x,
1241+
(ty::Variance::I, _) | (_, ty::Variance::I) => ty::Variance::I,
1242+
(ty::Variance::V, _) | (_, ty::Variance::V) => ty::Variance::V,
1243+
(ty::Variance::B, _) => ty::Variance::B,
12811244
}
12821245
}

src/test/compile-fail/variance-associated-types.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ trait Trait<'a> {
2020
}
2121

2222
#[rustc_variance]
23-
struct Foo<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[[+];[];[]], regions=[[-];[];[]])
23+
struct Foo<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[[V];[];[]], regions=[[V];[];[]])
2424
field: (T, &'a ())
2525
}
2626

2727
#[rustc_variance]
28-
struct Bar<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[[o];[];[]], regions=[[o];[];[]])
28+
struct Bar<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[[I];[];[]], regions=[[I];[];[]])
2929
field: <T as Trait<'a>>::Type
3030
}
3131

src/test/compile-fail/variance-object-types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::cell::Cell;
1818
// For better or worse, associated types are invariant, and hence we
1919
// get an invariant result for `'a`.
2020
#[rustc_variance]
21-
struct Foo<'a> { //~ ERROR regions=[[o];[];[]]
21+
struct Foo<'a> { //~ ERROR regions=[[I];[];[]]
2222
x: Box<Fn(i32) -> &'a i32 + 'static>
2323
}
2424

src/test/compile-fail/variance-region-bounds.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313
#![feature(rustc_attrs)]
1414

1515
#[rustc_variance]
16-
trait Foo: 'static { //~ ERROR types=[[];[o];[]]
16+
trait Foo: 'static { //~ ERROR types=[[];[I];[]]
1717
}
1818

1919
#[rustc_variance]
20-
trait Bar<T> { //~ ERROR types=[[o];[o];[]]
20+
trait Bar<T> { //~ ERROR types=[[I];[I];[]]
2121
fn do_it(&self)
2222
where T: 'static;
2323
}

0 commit comments

Comments
 (0)