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:
Niko Matsakis 2014-12-15 15:41:30 -05:00
parent 7f6177e646
commit 8fe9e4dff6
11 changed files with 31 additions and 4 deletions

View File

@ -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) }
}

View File

@ -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) }
}

View File

@ -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) }

View File

@ -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)
}

View File

@ -2101,6 +2101,7 @@ impl StrPrelude for str {
else { line }
}
let f: fn(&str) -> &str = f; // coerce to fn pointer
self.lines().map(f)
}

View File

@ -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)

View File

@ -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),

View File

@ -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) }
}

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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)
}