fix issues pointed out in review
diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs
index eae9ad0..8a2d254 100644
--- a/library/alloc/src/vec/into_iter.rs
+++ b/library/alloc/src/vec/into_iter.rs
@@ -164,18 +164,19 @@ fn size_hint(&self) -> (usize, Option<usize>) {
     #[inline]
     fn advance_by(&mut self, n: usize) -> Result<(), usize> {
         let step_size = self.len().min(n);
+        let to_drop = ptr::slice_from_raw_parts_mut(self.ptr as *mut T, step_size);
         if mem::size_of::<T>() == 0 {
             // SAFETY: due to unchecked casts of unsigned amounts to signed offsets the wraparound
             // effectively results in unsigned pointers representing positions 0..usize::MAX,
             // which is valid for ZSTs.
             self.ptr = unsafe { arith_offset(self.ptr as *const i8, step_size as isize) as *mut T }
         } else {
-            let to_drop = ptr::slice_from_raw_parts_mut(self.ptr as *mut T, step_size);
             // SAFETY: the min() above ensures that step_size is in bounds
-            unsafe {
-                self.ptr = self.ptr.add(step_size);
-                ptr::drop_in_place(to_drop);
-            }
+            self.ptr = unsafe { self.ptr.add(step_size) };
+        }
+        // SAFETY: the min() above ensures that step_size is in bounds
+        unsafe {
+            ptr::drop_in_place(to_drop);
         }
         if step_size < n {
             return Err(step_size);
@@ -237,11 +238,11 @@ fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
         } else {
             // SAFETY: same as for advance_by()
             self.end = unsafe { self.end.offset(step_size.wrapping_neg() as isize) };
-            let to_drop = ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size);
-            // SAFETY: same as for advance_by()
-            unsafe {
-                ptr::drop_in_place(to_drop);
-            }
+        }
+        let to_drop = ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size);
+        // SAFETY: same as for advance_by()
+        unsafe {
+            ptr::drop_in_place(to_drop);
         }
         if step_size < n {
             return Err(step_size);
diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs
index e1d665b..351fd56 100644
--- a/library/core/src/iter/adapters/flatten.rs
+++ b/library/core/src/iter/adapters/flatten.rs
@@ -412,8 +412,9 @@ fn advance_by(&mut self, n: usize) -> Result<(), usize> {
         self.frontiter = None;
 
         if let Some(ref mut back) = self.backiter {
-            if let Err(advanced) = back.advance_by(rem) {
-                rem -= advanced
+            match back.advance_by(rem) {
+                ret @ Ok(_) => return ret,
+                Err(advanced) => rem -= advanced,
             }
         }
 
diff --git a/library/core/src/iter/adapters/skip.rs b/library/core/src/iter/adapters/skip.rs
index e29ff12..9b89ca5 100644
--- a/library/core/src/iter/adapters/skip.rs
+++ b/library/core/src/iter/adapters/skip.rs
@@ -116,14 +116,35 @@ fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
     }
 
     #[inline]
+    #[rustc_inherit_overflow_checks]
     fn advance_by(&mut self, n: usize) -> Result<(), usize> {
-        if self.n >= n {
-            self.n -= n;
-            return Ok(());
+        let mut rem = n;
+
+        let step_one = self.n.saturating_add(rem);
+        match self.iter.advance_by(step_one) {
+            Ok(_) => {
+                rem -= step_one - self.n;
+                self.n = 0;
+            }
+            Err(advanced) => {
+                let advanced_without_skip = advanced.saturating_sub(self.n);
+                self.n = self.n.saturating_sub(advanced);
+                return Err(advanced_without_skip);
+            }
         }
-        let rem = n - self.n;
-        self.n = 0;
-        self.iter.advance_by(rem)
+
+        // step_one calculation may have saturated
+        if unlikely(rem > 0) {
+            return match self.iter.advance_by(rem) {
+                ret @ Ok(_) => ret,
+                Err(advanced) => {
+                    rem -= advanced;
+                    Err(n - rem)
+                }
+            };
+        }
+
+        Ok(())
     }
 }