Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: no error Instead, this happened: note: no zero was pushed, this is reading an undefined byte. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: I believe this happens because the following case is not handled in In this case, , so two of the "cases of interest" are not a match, and , so the last case isn't matched either.
cc
I can submit a PR to fix it later today. I was under the impression that the tests covered all cases for but apparently not.

Discussion:
return; } <del> if target_cap < self.capacity() { // There are three cases of interest: //   All elements are out of desired bounds //   Elements are contiguous, and head is out of desired bounds //   Elements are discontiguous, and tail is out of desired bounds </del> <ins> // There are three cases of interest: //   All elements are out of desired bounds //   Elements are contiguous, and tail is out of desired bounds //   Elements are discontiguous // // At all other times, element positions are unaffected. // `head` and `len` are at most `isize::MAX` and `target_cap < self.capacity()`, so nothing can // overflow. let tail_outside = (target_cap + 1..=self.capacity()).contains(&(self.head + self.len)); if self.len == 0 { self.head = 0; } else if self.head >= target_cap && tail_outside { // Head and tail are both out of bounds, so copy all of them to the front. </ins> // <del> // At all other times, element positions are unaffected. </del> <ins> //  H := head //  L := last element //                    H           L //   [. . . . . . . . o o o o o o o . ] //    H           L //   [o o o o o o o . ] unsafe { // nonoverlapping because `self.head >= target_cap >= self.len`. self.copy_nonoverlapping(self.head, 0, self.len); } self.head = 0; } else if self.head < target_cap && tail_outside { // Head is in bounds, tail is out of bounds. // Copy the overflowing part to the beginning of the // buffer. This won't overlap because `target_cap >= self.len`. </ins> // <del> // Indicates that elements at the head should be moved. let tail_outside = (target_cap + 1..=self.capacity()).contains(&(self.head + self.len)); // Move elements from out of desired bounds (positions after target_cap) if self.len == 0 { self.head = 0; } else if self.head >= target_cap && tail_outside { //  H := head //  L := last element //                    H           L //   [. . . . . . . . o o o o o o o . ] //    H           L //   [o o o o o o o . ] unsafe { // nonoverlapping because self.head >= target_cap >= self.len self.copy_nonoverlapping(self.head, 0, self.len); } self.head = 0; } else if self.head < target_cap && tail_outside { //  H := head //  L := last element //          H           L //   [. . . o o o o o o o . . . . . . ] //      L   H //   [o o . o o o o o ] let len = self.head + self.len - target_cap; unsafe { self.copy_nonoverlapping(target_cap, 0, len); } } else if self.head >= target_cap { //  H := head //  L := last element //            L                   H //   [o o o o o . . . . . . . . . o o ] //            L   H //   [o o o o o . o o ] let len = self.capacity() - self.head; let new_head = target_cap - len; unsafe { // can't use copy_nonoverlapping here for the same reason // as in `handle_capacity_increase()` self.copy(self.head, new_head, len); } self.head = new_head; </del> <ins> //  H := head //  L := last element //          H           L //   [. . . o o o o o o o . . . . . . ] //      L   H //   [o o . o o o o o ] let len = self.head + self.len - target_cap; unsafe { self.copy_nonoverlapping(target_cap, 0, len); </ins> } <del> self.buf.shrink_to_fit(target_cap); debug_assert!(self.head < self.capacity() || self.capacity() == 0); debug_assert!(self.len <= self.capacity()); </del> <ins> } else if !self.is_contiguous() { // The head slice is at least partially out of bounds, tail is in bounds. // Copy the head backwards so it lines up with the target capacity. // This won't overlap because `target_cap >= self.len`. // //  H := head //  L := last element //            L                   H //   [o o o o o . . . . . . . . . o o ] //            L   H //   [o o o o o . o o ] let head_len = self.capacity() - self.head; let new_head = target_cap - head_len; unsafe { // can't use `copy_nonoverlapping()` here because the new and old // regions for the head might overlap. self.copy(self.head, new_head, head_len); } self.head = new_head; </ins> } <ins> self.buf.shrink_to_fit(target_cap); debug_assert!(self.head < self.capacity() || self.capacity() == 0); debug_assert!(self.len <= self.capacity()); </ins> } /// Shortens the deque, keeping the first `len` elements and dropping

} #[test] <ins> fn issue_108453() { let mut deque = VecDeque::with_capacity(10); deque.push_back(1u8); deque.push_back(2); deque.push_back(3); deque.push_front(10); deque.push_front(9); deque.shrink_to(9); assert_eq!(deque.into_iter().collect::<Vec<_>>(), vec![9, 10, 1, 2, 3]); } #[test] fn test_shrink_to() { // test deques with capacity 16 with all possible head positions, lengths and target capacities. let cap = 16; for len in 0..cap { for head in 0..cap { let expected = (1..=len).collect::<VecDeque<_>>(); for target_cap in len..cap { let mut deque = VecDeque::with_capacity(cap); // currently, `with_capacity` always allocates the exact capacity if it's greater than 8. assert_eq!(deque.capacity(), cap); // we can let the head point anywhere in the buffer since the deque is empty. deque.head = head; deque.extend(1..=len); deque.shrink_to(target_cap); assert_eq!(deque, expected); } } } } #[test] </ins> fn test_shrink_to_fit() { // This test checks that every single combination of head and tail position, // is tested. Capacity 15 should be large enough to cover every case.