diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index 79e6b11beaca6..f506b8a967b5c 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -1050,13 +1050,13 @@ unsafe impl<A, B> TrustedLen for Zip<A, B>
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
-pub struct Map<I, F> {
+pub struct Map<I, F: ?Sized> {
     iter: I,
     f: F,
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, F> fmt::Debug for Map<I, F> {
+impl<I: fmt::Debug, F: ?Sized> fmt::Debug for Map<I, F> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.debug_struct("Map")
             .field("iter", &self.iter)
@@ -1065,7 +1065,8 @@ impl<I: fmt::Debug, F> fmt::Debug for Map<I, F> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<B, I: Iterator, F> Iterator for Map<I, F> where F: FnMut(I::Item) -> B {
+impl<B, I: Iterator, F: ?Sized> Iterator for Map<I, F> where F: FnMut(I::Item) -> B
+{
     type Item = B;
 
     #[inline]
@@ -1078,16 +1079,17 @@ impl<B, I: Iterator, F> Iterator for Map<I, F> where F: FnMut(I::Item) -> B {
         self.iter.size_hint()
     }
 
-    fn fold<Acc, G>(self, init: Acc, mut g: G) -> Acc
+    fn fold<Acc, G>(mut self, init: Acc, mut g: G) -> Acc
         where G: FnMut(Acc, Self::Item) -> Acc,
+              Self: Sized,
     {
-        let mut f = self.f;
+        let f = &mut self.f;
         self.iter.fold(init, move |acc, elt| g(acc, f(elt)))
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F> where
+impl<B, I: DoubleEndedIterator, F: ?Sized> DoubleEndedIterator for Map<I, F> where
     F: FnMut(I::Item) -> B,
 {
     #[inline]
@@ -1097,7 +1099,7 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F> where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<B, I: ExactSizeIterator, F> ExactSizeIterator for Map<I, F>
+impl<B, I: ExactSizeIterator, F: ?Sized> ExactSizeIterator for Map<I, F>
     where F: FnMut(I::Item) -> B
 {
     fn len(&self) -> usize {
@@ -1110,16 +1112,16 @@ impl<B, I: ExactSizeIterator, F> ExactSizeIterator for Map<I, F>
 }
 
 #[unstable(feature = "fused", issue = "35602")]
-impl<B, I: FusedIterator, F> FusedIterator for Map<I, F>
+impl<B, I: FusedIterator, F: ?Sized> FusedIterator for Map<I, F>
     where F: FnMut(I::Item) -> B {}
 
 #[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<B, I, F> TrustedLen for Map<I, F>
+unsafe impl<B, I, F: ?Sized> TrustedLen for Map<I, F>
     where I: TrustedLen,
           F: FnMut(I::Item) -> B {}
 
 #[doc(hidden)]
-unsafe impl<B, I, F> TrustedRandomAccess for Map<I, F>
+unsafe impl<B, I, F: ?Sized> TrustedRandomAccess for Map<I, F>
     where I: TrustedRandomAccess,
           F: FnMut(I::Item) -> B,
 {
@@ -1140,13 +1142,13 @@ unsafe impl<B, I, F> TrustedRandomAccess for Map<I, F>
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
-pub struct Filter<I, P> {
+pub struct Filter<I, P: ?Sized> {
     iter: I,
     predicate: P,
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, P> fmt::Debug for Filter<I, P> {
+impl<I: fmt::Debug, P: ?Sized> fmt::Debug for Filter<I, P> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.debug_struct("Filter")
             .field("iter", &self.iter)
@@ -1155,7 +1157,8 @@ impl<I: fmt::Debug, P> fmt::Debug for Filter<I, P> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool {
+impl<I: Iterator, P: ?Sized> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool
+{
     type Item = I::Item;
 
     #[inline]
@@ -1186,7 +1189,9 @@ impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool
     // Using the branchless version will also simplify the LLVM byte code, thus
     // leaving more budget for LLVM optimizations.
     #[inline]
-    fn count(mut self) -> usize {
+    fn count(mut self) -> usize
+        where Self: Sized
+    {
         let mut count = 0;
         for x in &mut self.iter {
             count += (self.predicate)(&x) as usize;
@@ -1196,7 +1201,7 @@ impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>
+impl<I: DoubleEndedIterator, P: ?Sized> DoubleEndedIterator for Filter<I, P>
     where P: FnMut(&I::Item) -> bool,
 {
     #[inline]
@@ -1211,7 +1216,7 @@ impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>
 }
 
 #[unstable(feature = "fused", issue = "35602")]
-impl<I: FusedIterator, P> FusedIterator for Filter<I, P>
+impl<I: FusedIterator, P: ?Sized> FusedIterator for Filter<I, P>
     where P: FnMut(&I::Item) -> bool {}
 
 /// An iterator that uses `f` to both filter and map elements from `iter`.
@@ -1224,13 +1229,13 @@ impl<I: FusedIterator, P> FusedIterator for Filter<I, P>
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
-pub struct FilterMap<I, F> {
+pub struct FilterMap<I, F: ?Sized> {
     iter: I,
     f: F,
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, F> fmt::Debug for FilterMap<I, F> {
+impl<I: fmt::Debug, F: ?Sized> fmt::Debug for FilterMap<I, F> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.debug_struct("FilterMap")
             .field("iter", &self.iter)
@@ -1239,7 +1244,7 @@ impl<I: fmt::Debug, F> fmt::Debug for FilterMap<I, F> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
+impl<B, I: Iterator, F: ?Sized> Iterator for FilterMap<I, F>
     where F: FnMut(I::Item) -> Option<B>,
 {
     type Item = B;
@@ -1262,7 +1267,7 @@ impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
+impl<B, I: DoubleEndedIterator, F: ?Sized> DoubleEndedIterator for FilterMap<I, F>
     where F: FnMut(I::Item) -> Option<B>,
 {
     #[inline]
@@ -1277,7 +1282,7 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
 }
 
 #[unstable(feature = "fused", issue = "35602")]
-impl<B, I: FusedIterator, F> FusedIterator for FilterMap<I, F>
+impl<B, I: FusedIterator, F: ?Sized> FusedIterator for FilterMap<I, F>
     where F: FnMut(I::Item) -> Option<B> {}
 
 /// An iterator that yields the current count and the element during iteration.
@@ -1534,14 +1539,14 @@ impl<I: Iterator> Peekable<I> {
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
-pub struct SkipWhile<I, P> {
+pub struct SkipWhile<I, P: ?Sized> {
     iter: I,
     flag: bool,
     predicate: P,
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, P> fmt::Debug for SkipWhile<I, P> {
+impl<I: fmt::Debug, P: ?Sized> fmt::Debug for SkipWhile<I, P> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.debug_struct("SkipWhile")
             .field("iter", &self.iter)
@@ -1551,7 +1556,7 @@ impl<I: fmt::Debug, P> fmt::Debug for SkipWhile<I, P> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator, P> Iterator for SkipWhile<I, P>
+impl<I: Iterator, P: ?Sized> Iterator for SkipWhile<I, P>
     where P: FnMut(&I::Item) -> bool
 {
     type Item = I::Item;
@@ -1575,7 +1580,7 @@ impl<I: Iterator, P> Iterator for SkipWhile<I, P>
 }
 
 #[unstable(feature = "fused", issue = "35602")]
-impl<I, P> FusedIterator for SkipWhile<I, P>
+impl<I, P: ?Sized> FusedIterator for SkipWhile<I, P>
     where I: FusedIterator, P: FnMut(&I::Item) -> bool {}
 
 /// An iterator that only accepts elements while `predicate` is true.
@@ -1588,14 +1593,14 @@ impl<I, P> FusedIterator for SkipWhile<I, P>
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
-pub struct TakeWhile<I, P> {
+pub struct TakeWhile<I, P: ?Sized> {
     iter: I,
     flag: bool,
     predicate: P,
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, P> fmt::Debug for TakeWhile<I, P> {
+impl<I: fmt::Debug, P: ?Sized> fmt::Debug for TakeWhile<I, P> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.debug_struct("TakeWhile")
             .field("iter", &self.iter)
@@ -1605,7 +1610,7 @@ impl<I: fmt::Debug, P> fmt::Debug for TakeWhile<I, P> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator, P> Iterator for TakeWhile<I, P>
+impl<I: Iterator, P: ?Sized> Iterator for TakeWhile<I, P>
     where P: FnMut(&I::Item) -> bool
 {
     type Item = I::Item;
@@ -1634,7 +1639,7 @@ impl<I: Iterator, P> Iterator for TakeWhile<I, P>
 }
 
 #[unstable(feature = "fused", issue = "35602")]
-impl<I, P> FusedIterator for TakeWhile<I, P>
+impl<I, P: ?Sized> FusedIterator for TakeWhile<I, P>
     where I: FusedIterator, P: FnMut(&I::Item) -> bool {}
 
 /// An iterator that skips over `n` elements of `iter`.
@@ -1851,15 +1856,15 @@ impl<B, I, St, F> Iterator for Scan<I, St, F> where
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
-pub struct FlatMap<I, U: IntoIterator, F> {
+pub struct FlatMap<I, U: IntoIterator, F: ?Sized> {
     iter: I,
-    f: F,
     frontiter: Option<U::IntoIter>,
     backiter: Option<U::IntoIter>,
+    f: F,
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, U: IntoIterator, F> fmt::Debug for FlatMap<I, U, F>
+impl<I: fmt::Debug, U: IntoIterator, F: ?Sized> fmt::Debug for FlatMap<I, U, F>
     where U::IntoIter: fmt::Debug
 {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -1872,7 +1877,7 @@ impl<I: fmt::Debug, U: IntoIterator, F> fmt::Debug for FlatMap<I, U, F>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
+impl<I: Iterator, U: IntoIterator, F: ?Sized> Iterator for FlatMap<I, U, F>
     where F: FnMut(I::Item) -> U,
 {
     type Item = U::Item;
@@ -1905,7 +1910,7 @@ impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F> where
+impl<I: DoubleEndedIterator, U, F: ?Sized> DoubleEndedIterator for FlatMap<I, U, F> where
     F: FnMut(I::Item) -> U,
     U: IntoIterator,
     U::IntoIter: DoubleEndedIterator
@@ -1927,7 +1932,7 @@ impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F> wher
 }
 
 #[unstable(feature = "fused", issue = "35602")]
-impl<I, U, F> FusedIterator for FlatMap<I, U, F>
+impl<I, U, F: ?Sized> FusedIterator for FlatMap<I, U, F>
     where I: FusedIterator, U: IntoIterator, F: FnMut(I::Item) -> U {}
 
 /// An iterator that yields `None` forever after the underlying iterator
@@ -2090,13 +2095,13 @@ impl<I> ExactSizeIterator for Fuse<I> where I: ExactSizeIterator {
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
-pub struct Inspect<I, F> {
+pub struct Inspect<I, F: ?Sized> {
     iter: I,
     f: F,
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
-impl<I: fmt::Debug, F> fmt::Debug for Inspect<I, F> {
+impl<I: fmt::Debug, F: ?Sized> fmt::Debug for Inspect<I, F> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.debug_struct("Inspect")
             .field("iter", &self.iter)
@@ -2104,7 +2109,7 @@ impl<I: fmt::Debug, F> fmt::Debug for Inspect<I, F> {
     }
 }
 
-impl<I: Iterator, F> Inspect<I, F> where F: FnMut(&I::Item) {
+impl<I: Iterator, F: ?Sized> Inspect<I, F> where F: FnMut(&I::Item) {
     #[inline]
     fn do_inspect(&mut self, elt: Option<I::Item>) -> Option<I::Item> {
         if let Some(ref a) = elt {
@@ -2116,7 +2121,7 @@ impl<I: Iterator, F> Inspect<I, F> where F: FnMut(&I::Item) {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator, F> Iterator for Inspect<I, F> where F: FnMut(&I::Item) {
+impl<I: Iterator, F: ?Sized> Iterator for Inspect<I, F> where F: FnMut(&I::Item) {
     type Item = I::Item;
 
     #[inline]
@@ -2132,7 +2137,7 @@ impl<I: Iterator, F> Iterator for Inspect<I, F> where F: FnMut(&I::Item) {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: DoubleEndedIterator, F> DoubleEndedIterator for Inspect<I, F>
+impl<I: DoubleEndedIterator, F: ?Sized> DoubleEndedIterator for Inspect<I, F>
     where F: FnMut(&I::Item),
 {
     #[inline]
@@ -2143,7 +2148,7 @@ impl<I: DoubleEndedIterator, F> DoubleEndedIterator for Inspect<I, F>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: ExactSizeIterator, F> ExactSizeIterator for Inspect<I, F>
+impl<I: ExactSizeIterator, F: ?Sized> ExactSizeIterator for Inspect<I, F>
     where F: FnMut(&I::Item)
 {
     fn len(&self) -> usize {
@@ -2156,5 +2161,5 @@ impl<I: ExactSizeIterator, F> ExactSizeIterator for Inspect<I, F>
 }
 
 #[unstable(feature = "fused", issue = "35602")]
-impl<I: FusedIterator, F> FusedIterator for Inspect<I, F>
+impl<I: FusedIterator, F: ?Sized> FusedIterator for Inspect<I, F>
     where F: FnMut(&I::Item) {}
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index a1249a5f22cf7..91d201ed633ab 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -1288,3 +1288,16 @@ fn test_step_replace_no_between() {
     assert_eq!(x, 1);
     assert_eq!(y, 5);
 }
+
+#[test]
+fn test_unsized_closures_in_map_etc() {
+    fn an_iterator<I: Iterator + ?Sized>(iter: &mut I) { let _ = iter.next(); }
+
+    an_iterator::<Filter<_, FnMut(&_) -> _>>(&mut (0..10).filter(|_| true));
+    an_iterator::<FilterMap<_, FnMut(_) -> _>>(&mut (0..10).filter_map(|i| Some(i)));
+    an_iterator::<FlatMap<_, _, FnMut(_) -> _>>(&mut (0..10).flat_map(|i| 0..i));
+    an_iterator::<Inspect<_, FnMut(&_)>>(&mut (0..10).inspect(|_| {}));
+    an_iterator::<Map<_, FnMut(_) -> _>>(&mut (0..10).map(|x| x + 1));
+    an_iterator::<SkipWhile<_, FnMut(&_) -> _>>(&mut (0..10).skip_while(|_| true));
+    an_iterator::<TakeWhile<_, FnMut(&_) -> _>>(&mut (0..10).take_while(|_| true));
+}