Skip to content

Commit 15274a8

Browse files
committed
---
yaml --- r: 179005 b: refs/heads/master c: 8d9bb17 h: refs/heads/master i: 179003: 42e5338 v: v3
1 parent e09e5b0 commit 15274a8

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
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: be8d9bb98a140d4a4df762e2ea44109c2f05ce6c
2+
refs/heads/master: 8d9bb17204c0b3b9c8ade3569ac4501fac18b885
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: ac134f7ca435551964996ee88319241cd3c7c110
55
refs/heads/try: ccf8fedf1cffcb8f6f3581d53d220039e192fe77

trunk/src/librustc/middle/traits/util.rs

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,47 @@ use util::ppaux::Repr;
2222
use super::{Obligation, ObligationCause, PredicateObligation,
2323
VtableImpl, VtableParam, VtableImplData};
2424

25+
struct PredicateSet<'a,'tcx:'a> {
26+
tcx: &'a ty::ctxt<'tcx>,
27+
set: FnvHashSet<ty::Predicate<'tcx>>,
28+
}
29+
30+
impl<'a,'tcx> PredicateSet<'a,'tcx> {
31+
fn new(tcx: &'a ty::ctxt<'tcx>) -> PredicateSet<'a,'tcx> {
32+
PredicateSet { tcx: tcx, set: FnvHashSet() }
33+
}
34+
35+
fn insert(&mut self, pred: &ty::Predicate<'tcx>) -> bool {
36+
// We have to be careful here because we want
37+
//
38+
// for<'a> Foo<&'a int>
39+
//
40+
// and
41+
//
42+
// for<'b> Foo<&'b int>
43+
//
44+
// to be considered equivalent. So normalize all late-bound
45+
// regions before we throw things into the underlying set.
46+
let normalized_pred = match *pred {
47+
ty::Predicate::Trait(ref data) =>
48+
ty::Predicate::Trait(ty::anonymize_late_bound_regions(self.tcx, data)),
49+
50+
ty::Predicate::Equate(ref data) =>
51+
ty::Predicate::Equate(ty::anonymize_late_bound_regions(self.tcx, data)),
52+
53+
ty::Predicate::RegionOutlives(ref data) =>
54+
ty::Predicate::RegionOutlives(ty::anonymize_late_bound_regions(self.tcx, data)),
55+
56+
ty::Predicate::TypeOutlives(ref data) =>
57+
ty::Predicate::TypeOutlives(ty::anonymize_late_bound_regions(self.tcx, data)),
58+
59+
ty::Predicate::Projection(ref data) =>
60+
ty::Predicate::Projection(ty::anonymize_late_bound_regions(self.tcx, data)),
61+
};
62+
self.set.insert(normalized_pred)
63+
}
64+
}
65+
2566
///////////////////////////////////////////////////////////////////////////
2667
// `Elaboration` iterator
2768
///////////////////////////////////////////////////////////////////////////
@@ -36,7 +77,7 @@ use super::{Obligation, ObligationCause, PredicateObligation,
3677
pub struct Elaborator<'cx, 'tcx:'cx> {
3778
tcx: &'cx ty::ctxt<'tcx>,
3879
stack: Vec<StackEntry<'tcx>>,
39-
visited: FnvHashSet<ty::Predicate<'tcx>>,
80+
visited: PredicateSet<'cx,'tcx>,
4081
}
4182

4283
struct StackEntry<'tcx> {
@@ -68,8 +109,8 @@ pub fn elaborate_predicates<'cx, 'tcx>(
68109
mut predicates: Vec<ty::Predicate<'tcx>>)
69110
-> Elaborator<'cx, 'tcx>
70111
{
71-
let mut visited = FnvHashSet();
72-
predicates.retain(|pred| visited.insert(pred.clone()));
112+
let mut visited = PredicateSet::new(tcx);
113+
predicates.retain(|pred| visited.insert(pred));
73114
let entry = StackEntry { position: 0, predicates: predicates };
74115
Elaborator { tcx: tcx, stack: vec![entry], visited: visited }
75116
}
@@ -91,7 +132,7 @@ impl<'cx, 'tcx> Elaborator<'cx, 'tcx> {
91132
// recursion in some cases. One common case is when
92133
// people define `trait Sized: Sized { }` rather than `trait
93134
// Sized { }`.
94-
predicates.retain(|r| self.visited.insert(r.clone()));
135+
predicates.retain(|r| self.visited.insert(r));
95136

96137
self.stack.push(StackEntry { position: 0,
97138
predicates: predicates });
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
fn foo<T>(t: T) -> i32
2+
where T : for<'a> Fn(&'a u8) -> i32,
3+
T : for<'b> Fn(&'b u8) -> i32,
4+
{
5+
t(&3)
6+
}
7+
8+
fn main() {
9+
}

0 commit comments

Comments
 (0)