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.
This commit is contained in:
parent
7f6177e646
commit
8fe9e4dff6
|
@ -1230,6 +1230,7 @@ impl<K, V> BTreeMap<K, V> {
|
|||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
|
||||
fn first<A, B>((a, _): (A, B)) -> A { a }
|
||||
let first: fn((&'a K, &'a V)) -> &'a K = first; // coerce to fn pointer
|
||||
|
||||
Keys { inner: self.iter().map(first) }
|
||||
}
|
||||
|
@ -1251,6 +1252,7 @@ impl<K, V> BTreeMap<K, V> {
|
|||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn values<'a>(&'a self) -> Values<'a, K, V> {
|
||||
fn second<A, B>((_, b): (A, B)) -> B { b }
|
||||
let second: fn((&'a K, &'a V)) -> &'a V = second; // coerce to fn pointer
|
||||
|
||||
Values { inner: self.iter().map(second) }
|
||||
}
|
||||
|
|
|
@ -126,6 +126,7 @@ impl<T> BTreeSet<T> {
|
|||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn into_iter(self) -> MoveItems<T> {
|
||||
fn first<A, B>((a, _): (A, B)) -> A { a }
|
||||
let first: fn((T, ())) -> T = first; // coerce to fn pointer
|
||||
|
||||
MoveItems { iter: self.map.into_iter().map(first) }
|
||||
}
|
||||
|
|
|
@ -144,6 +144,7 @@ impl<V> VecMap<V> {
|
|||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn keys<'r>(&'r self) -> Keys<'r, V> {
|
||||
fn first<A, B>((a, _): (A, B)) -> A { a }
|
||||
let first: fn((uint, &'r V)) -> uint = first; // coerce to fn pointer
|
||||
|
||||
Keys { iter: self.iter().map(first) }
|
||||
}
|
||||
|
@ -153,6 +154,7 @@ impl<V> VecMap<V> {
|
|||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn values<'r>(&'r self) -> Values<'r, V> {
|
||||
fn second<A, B>((_, b): (A, B)) -> B { b }
|
||||
let second: fn((uint, &'r V)) -> &'r V = second; // coerce to fn pointer
|
||||
|
||||
Values { iter: self.iter().map(second) }
|
||||
}
|
||||
|
@ -239,6 +241,7 @@ impl<V> VecMap<V> {
|
|||
fn filter<A>((i, v): (uint, Option<A>)) -> Option<(uint, A)> {
|
||||
v.map(|v| (i, v))
|
||||
}
|
||||
let filter: fn((uint, Option<V>)) -> Option<(uint, V)> = filter; // coerce to fn ptr
|
||||
|
||||
let values = replace(&mut self.v, vec!());
|
||||
MoveItems { iter: values.into_iter().enumerate().filter_map(filter) }
|
||||
|
|
|
@ -2612,6 +2612,9 @@ pub fn iterate<T, F>(seed: T, f: F) -> Iterate<T, F> where
|
|||
val.clone()
|
||||
}
|
||||
|
||||
// coerce to a fn pointer
|
||||
let next: fn(&mut IterateState<T,F>) -> Option<T> = next;
|
||||
|
||||
Unfold::new((f, Some(seed), true), next)
|
||||
}
|
||||
|
||||
|
|
|
@ -2101,6 +2101,7 @@ impl StrPrelude for str {
|
|||
else { line }
|
||||
}
|
||||
|
||||
let f: fn(&str) -> &str = f; // coerce to fn pointer
|
||||
self.lines().map(f)
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,10 @@ impl BasicBlock {
|
|||
|
||||
pub fn pred_iter(self) -> Preds {
|
||||
fn is_a_terminator_inst(user: &Value) -> bool { user.is_a_terminator_inst() }
|
||||
let is_a_terminator_inst: fn(&Value) -> bool = is_a_terminator_inst;
|
||||
|
||||
fn get_parent(user: Value) -> BasicBlock { user.get_parent().unwrap() }
|
||||
let get_parent: fn(Value) -> BasicBlock = get_parent;
|
||||
|
||||
self.as_value().user_iter()
|
||||
.filter(is_a_terminator_inst)
|
||||
|
|
|
@ -838,8 +838,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
|
|||
/// }
|
||||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn keys(&self) -> Keys<K, V> {
|
||||
pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
|
||||
fn first<A, B>((a, _): (A, B)) -> A { a }
|
||||
let first: fn((&'a K,&'a V)) -> &'a K = first; // coerce to fn ptr
|
||||
|
||||
Keys { inner: self.iter().map(first) }
|
||||
}
|
||||
|
@ -862,8 +863,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
|
|||
/// }
|
||||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn values(&self) -> Values<K, V> {
|
||||
pub fn values<'a>(&'a self) -> Values<'a, K, V> {
|
||||
fn second<A, B>((_, b): (A, B)) -> B { b }
|
||||
let second: fn((&'a K,&'a V)) -> &'a V = second; // coerce to fn ptr
|
||||
|
||||
Values { inner: self.iter().map(second) }
|
||||
}
|
||||
|
@ -938,6 +940,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
|
|||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn into_iter(self) -> MoveEntries<K, V> {
|
||||
fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
|
||||
let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two;
|
||||
|
||||
MoveEntries {
|
||||
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> {
|
|||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn drain(&mut self) -> Drain<K, V> {
|
||||
fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
|
||||
let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two; // coerce to fn pointer
|
||||
|
||||
Drain {
|
||||
inner: self.table.drain().map(last_two),
|
||||
|
|
|
@ -277,6 +277,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
|
|||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn into_iter(self) -> IntoIter<T> {
|
||||
fn first<A, B>((a, _): (A, B)) -> A { a }
|
||||
let first: fn((T, ())) -> T = first;
|
||||
|
||||
IntoIter { iter: self.map.into_iter().map(first) }
|
||||
}
|
||||
|
@ -419,6 +420,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
|
|||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn drain(&mut self) -> Drain<T> {
|
||||
fn first<A, B>((a, _): (A, B)) -> A { a }
|
||||
let first: fn((T, ())) -> T = first; // coerce to fn pointer
|
||||
|
||||
Drain { iter: self.map.drain().map(first) }
|
||||
}
|
||||
|
||||
|
|
|
@ -390,6 +390,7 @@ impl Path {
|
|||
let v = if self.repr[0] == SEP_BYTE {
|
||||
self.repr[1..]
|
||||
} else { self.repr.as_slice() };
|
||||
let is_sep_byte: fn(&u8) -> bool = is_sep_byte; // coerce to fn ptr
|
||||
let mut ret = v.split(is_sep_byte);
|
||||
if v.is_empty() {
|
||||
// consume the empty "" component
|
||||
|
@ -401,7 +402,8 @@ impl Path {
|
|||
/// Returns an iterator that yields each component of the path as Option<&str>.
|
||||
/// See components() for details.
|
||||
pub fn str_components<'a>(&'a self) -> StrComponents<'a> {
|
||||
self.components().map(str::from_utf8)
|
||||
let from_utf8: fn(&[u8]) -> Option<&str> = str::from_utf8; // coerce to fn ptr
|
||||
self.components().map(from_utf8)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -655,7 +655,8 @@ impl Path {
|
|||
None if repr.as_bytes()[0] == SEP_BYTE => repr.slice_from(1),
|
||||
None => repr
|
||||
};
|
||||
let ret = s.split_terminator(SEP).map(Some);
|
||||
let some: fn(&'a str) -> Option<&'a str> = Some; // coerce to fn ptr
|
||||
let ret = s.split_terminator(SEP).map(some);
|
||||
ret
|
||||
}
|
||||
|
||||
|
@ -666,6 +667,7 @@ impl Path {
|
|||
#![inline]
|
||||
x.unwrap().as_bytes()
|
||||
}
|
||||
let convert: for<'b> fn(Option<&'b str>) -> &'b [u8] = convert; // coerce to fn ptr
|
||||
self.str_components().map(convert)
|
||||
}
|
||||
|
||||
|
|
|
@ -143,7 +143,10 @@ impl UnicodeStrPrelude for str {
|
|||
#[inline]
|
||||
fn words(&self) -> Words {
|
||||
fn is_not_empty(s: &&str) -> bool { !s.is_empty() }
|
||||
let is_not_empty: fn(&&str) -> bool = is_not_empty; // coerce to fn pointer
|
||||
|
||||
fn is_whitespace(c: char) -> bool { c.is_whitespace() }
|
||||
let is_whitespace: fn(char) -> bool = is_whitespace; // coerce to fn pointer
|
||||
|
||||
self.split(is_whitespace).filter(is_not_empty)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue