Skip to content

Commit 8fe9e4d

Browse files
committed
Insert coercions to fn pointer types required for the new types
post-unboxed-closure-conversion. This requires a fair amount of annoying coercions because all the `map` etc types are defined generically over the `F`, so the automatic coercions don't propagate; this is compounded by the need to use `let` and not `as` due to stage0. That said, this pattern is to a large extent temporary and unusual.
1 parent 7f6177e commit 8fe9e4d

File tree

11 files changed

+31
-4
lines changed

11 files changed

+31
-4
lines changed

src/libcollections/btree/map.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,7 @@ impl<K, V> BTreeMap<K, V> {
12301230
#[unstable = "matches collection reform specification, waiting for dust to settle"]
12311231
pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
12321232
fn first<A, B>((a, _): (A, B)) -> A { a }
1233+
let first: fn((&'a K, &'a V)) -> &'a K = first; // coerce to fn pointer
12331234

12341235
Keys { inner: self.iter().map(first) }
12351236
}
@@ -1251,6 +1252,7 @@ impl<K, V> BTreeMap<K, V> {
12511252
#[unstable = "matches collection reform specification, waiting for dust to settle"]
12521253
pub fn values<'a>(&'a self) -> Values<'a, K, V> {
12531254
fn second<A, B>((_, b): (A, B)) -> B { b }
1255+
let second: fn((&'a K, &'a V)) -> &'a V = second; // coerce to fn pointer
12541256

12551257
Values { inner: self.iter().map(second) }
12561258
}

src/libcollections/btree/set.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ impl<T> BTreeSet<T> {
126126
#[unstable = "matches collection reform specification, waiting for dust to settle"]
127127
pub fn into_iter(self) -> MoveItems<T> {
128128
fn first<A, B>((a, _): (A, B)) -> A { a }
129+
let first: fn((T, ())) -> T = first; // coerce to fn pointer
129130

130131
MoveItems { iter: self.map.into_iter().map(first) }
131132
}

src/libcollections/vec_map.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ impl<V> VecMap<V> {
144144
#[unstable = "matches collection reform specification, waiting for dust to settle"]
145145
pub fn keys<'r>(&'r self) -> Keys<'r, V> {
146146
fn first<A, B>((a, _): (A, B)) -> A { a }
147+
let first: fn((uint, &'r V)) -> uint = first; // coerce to fn pointer
147148

148149
Keys { iter: self.iter().map(first) }
149150
}
@@ -153,6 +154,7 @@ impl<V> VecMap<V> {
153154
#[unstable = "matches collection reform specification, waiting for dust to settle"]
154155
pub fn values<'r>(&'r self) -> Values<'r, V> {
155156
fn second<A, B>((_, b): (A, B)) -> B { b }
157+
let second: fn((uint, &'r V)) -> &'r V = second; // coerce to fn pointer
156158

157159
Values { iter: self.iter().map(second) }
158160
}
@@ -239,6 +241,7 @@ impl<V> VecMap<V> {
239241
fn filter<A>((i, v): (uint, Option<A>)) -> Option<(uint, A)> {
240242
v.map(|v| (i, v))
241243
}
244+
let filter: fn((uint, Option<V>)) -> Option<(uint, V)> = filter; // coerce to fn ptr
242245

243246
let values = replace(&mut self.v, vec!());
244247
MoveItems { iter: values.into_iter().enumerate().filter_map(filter) }

src/libcore/iter.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2612,6 +2612,9 @@ pub fn iterate<T, F>(seed: T, f: F) -> Iterate<T, F> where
26122612
val.clone()
26132613
}
26142614

2615+
// coerce to a fn pointer
2616+
let next: fn(&mut IterateState<T,F>) -> Option<T> = next;
2617+
26152618
Unfold::new((f, Some(seed), true), next)
26162619
}
26172620

src/libcore/str.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2101,6 +2101,7 @@ impl StrPrelude for str {
21012101
else { line }
21022102
}
21032103

2104+
let f: fn(&str) -> &str = f; // coerce to fn pointer
21042105
self.lines().map(f)
21052106
}
21062107

src/librustc_trans/trans/basic_block.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ impl BasicBlock {
3737

3838
pub fn pred_iter(self) -> Preds {
3939
fn is_a_terminator_inst(user: &Value) -> bool { user.is_a_terminator_inst() }
40+
let is_a_terminator_inst: fn(&Value) -> bool = is_a_terminator_inst;
41+
4042
fn get_parent(user: Value) -> BasicBlock { user.get_parent().unwrap() }
43+
let get_parent: fn(Value) -> BasicBlock = get_parent;
4144

4245
self.as_value().user_iter()
4346
.filter(is_a_terminator_inst)

src/libstd/collections/hash/map.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -838,8 +838,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
838838
/// }
839839
/// ```
840840
#[unstable = "matches collection reform specification, waiting for dust to settle"]
841-
pub fn keys(&self) -> Keys<K, V> {
841+
pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
842842
fn first<A, B>((a, _): (A, B)) -> A { a }
843+
let first: fn((&'a K,&'a V)) -> &'a K = first; // coerce to fn ptr
843844

844845
Keys { inner: self.iter().map(first) }
845846
}
@@ -862,8 +863,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
862863
/// }
863864
/// ```
864865
#[unstable = "matches collection reform specification, waiting for dust to settle"]
865-
pub fn values(&self) -> Values<K, V> {
866+
pub fn values<'a>(&'a self) -> Values<'a, K, V> {
866867
fn second<A, B>((_, b): (A, B)) -> B { b }
868+
let second: fn((&'a K,&'a V)) -> &'a V = second; // coerce to fn ptr
867869

868870
Values { inner: self.iter().map(second) }
869871
}
@@ -938,6 +940,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
938940
#[unstable = "matches collection reform specification, waiting for dust to settle"]
939941
pub fn into_iter(self) -> MoveEntries<K, V> {
940942
fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
943+
let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two;
941944

942945
MoveEntries {
943946
inner: self.table.into_iter().map(last_two)
@@ -1007,6 +1010,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
10071010
#[unstable = "matches collection reform specification, waiting for dust to settle"]
10081011
pub fn drain(&mut self) -> Drain<K, V> {
10091012
fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
1013+
let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two; // coerce to fn pointer
10101014

10111015
Drain {
10121016
inner: self.table.drain().map(last_two),

src/libstd/collections/hash/set.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
277277
#[unstable = "matches collection reform specification, waiting for dust to settle"]
278278
pub fn into_iter(self) -> IntoIter<T> {
279279
fn first<A, B>((a, _): (A, B)) -> A { a }
280+
let first: fn((T, ())) -> T = first;
280281

281282
IntoIter { iter: self.map.into_iter().map(first) }
282283
}
@@ -419,6 +420,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
419420
#[unstable = "matches collection reform specification, waiting for dust to settle"]
420421
pub fn drain(&mut self) -> Drain<T> {
421422
fn first<A, B>((a, _): (A, B)) -> A { a }
423+
let first: fn((T, ())) -> T = first; // coerce to fn pointer
424+
422425
Drain { iter: self.map.drain().map(first) }
423426
}
424427

src/libstd/path/posix.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,7 @@ impl Path {
390390
let v = if self.repr[0] == SEP_BYTE {
391391
self.repr[1..]
392392
} else { self.repr.as_slice() };
393+
let is_sep_byte: fn(&u8) -> bool = is_sep_byte; // coerce to fn ptr
393394
let mut ret = v.split(is_sep_byte);
394395
if v.is_empty() {
395396
// consume the empty "" component
@@ -401,7 +402,8 @@ impl Path {
401402
/// Returns an iterator that yields each component of the path as Option<&str>.
402403
/// See components() for details.
403404
pub fn str_components<'a>(&'a self) -> StrComponents<'a> {
404-
self.components().map(str::from_utf8)
405+
let from_utf8: fn(&[u8]) -> Option<&str> = str::from_utf8; // coerce to fn ptr
406+
self.components().map(from_utf8)
405407
}
406408
}
407409

src/libstd/path/windows.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,8 @@ impl Path {
655655
None if repr.as_bytes()[0] == SEP_BYTE => repr.slice_from(1),
656656
None => repr
657657
};
658-
let ret = s.split_terminator(SEP).map(Some);
658+
let some: fn(&'a str) -> Option<&'a str> = Some; // coerce to fn ptr
659+
let ret = s.split_terminator(SEP).map(some);
659660
ret
660661
}
661662

@@ -666,6 +667,7 @@ impl Path {
666667
#![inline]
667668
x.unwrap().as_bytes()
668669
}
670+
let convert: for<'b> fn(Option<&'b str>) -> &'b [u8] = convert; // coerce to fn ptr
669671
self.str_components().map(convert)
670672
}
671673

src/libunicode/u_str.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,10 @@ impl UnicodeStrPrelude for str {
143143
#[inline]
144144
fn words(&self) -> Words {
145145
fn is_not_empty(s: &&str) -> bool { !s.is_empty() }
146+
let is_not_empty: fn(&&str) -> bool = is_not_empty; // coerce to fn pointer
147+
146148
fn is_whitespace(c: char) -> bool { c.is_whitespace() }
149+
let is_whitespace: fn(char) -> bool = is_whitespace; // coerce to fn pointer
147150

148151
self.split(is_whitespace).filter(is_not_empty)
149152
}

0 commit comments

Comments
 (0)