Skip to content

Commit 12714de

Browse files
committed
---
yaml --- r: 194664 b: refs/heads/master c: c59fe8b h: refs/heads/master v: v3
1 parent 47edbc5 commit 12714de

File tree

3 files changed

+47
-4
lines changed

3 files changed

+47
-4
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 9c9bb9ce1d51e2a9ca4963bd418e365b6e17fbfa
2+
refs/heads/master: c59fe8bde2be55c46f627277e2cc37515fb7165e
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 552080181c58beef03493a110b4a38b20b6b5da5
55
refs/heads/try: 961e0358e1a5c0faaef606e31e9965742c1643bf

trunk/src/librustc_typeck/variance.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,14 +1059,29 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
10591059
}
10601060

10611061
ty::Predicate::Equate(ty::Binder(ref data)) => {
1062-
self.add_constraints_from_ty(generics, data.0, variance);
1063-
self.add_constraints_from_ty(generics, data.1, variance);
1062+
// A == B is only true if A and B are the same
1063+
// types, not subtypes of one another, so this is
1064+
// an invariant position:
1065+
self.add_constraints_from_ty(generics, data.0, self.invariant);
1066+
self.add_constraints_from_ty(generics, data.1, self.invariant);
10641067
}
10651068

10661069
ty::Predicate::TypeOutlives(ty::Binder(ref data)) => {
1067-
self.add_constraints_from_ty(generics, data.0, variance);
1070+
// Why contravariant on both? Let's consider:
1071+
//
1072+
// Under what conditions is `(T:'t) <: (U:'u)`,
1073+
// meaning that `(T:'t) => (U:'u)`. The answer is
1074+
// if `U <: T` or `'u <= 't`. Let's see some examples:
1075+
//
1076+
// (T: 'big) => (T: 'small)
1077+
// where 'small <= 'big
1078+
//
1079+
// (&'small Foo: 't) => (&'big Foo: 't)
1080+
// where 'small <= 'big
1081+
// note that &'big Foo <: &'small Foo
10681082

10691083
let variance_r = self.xform(variance, self.contravariant);
1084+
self.add_constraints_from_ty(generics, data.0, variance_r);
10701085
self.add_constraints_from_region(generics, data.1, variance_r);
10711086
}
10721087

@@ -1084,6 +1099,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
10841099
&*data.projection_ty.trait_ref,
10851100
variance);
10861101

1102+
// as the equality predicate above, a binder is a
1103+
// type equality relation, not a subtyping
1104+
// relation
10871105
self.add_constraints_from_ty(generics, data.ty, self.invariant);
10881106
}
10891107
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Check that `T:'a` is contravariant in T.
12+
13+
#![feature(rustc_attrs)]
14+
15+
#[rustc_variance]
16+
trait Foo: 'static { //~ ERROR types=[[];[-];[]]
17+
}
18+
19+
#[rustc_variance]
20+
trait Bar<T> { //~ ERROR types=[[+];[-];[]]
21+
fn do_it(&self)
22+
where T: 'static;
23+
}
24+
25+
fn main() { }

0 commit comments

Comments
 (0)