Skip to content

vec::IntoIter::{nth_back,advance_back_by} creates unaligned reference for ZST with alignment greater than 1 #148682

@theemathas

Description

@theemathas
#[repr(align(8))]
struct Thing;

fn main() {
    let v = vec![Thing, Thing];
    let _ = v.into_iter().nth_back(1);
}

Miri output:

error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required 8 byte alignment but found 1)
   --> /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1
    |
805 | / pub const unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T)
806 | | where
807 | |     T: [const] Destruct,
    | |________________________^ Undefined Behavior occurred here
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
    = note: BACKTRACE:
    = note: inside `std::ptr::drop_in_place::<[Thing]> - shim(None)` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1: 807:25
    = note: inside `<std::vec::IntoIter<Thing> as std::iter::DoubleEndedIterator>::advance_back_by` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/into_iter.rs:417:13: 417:40
    = note: inside `<std::vec::IntoIter<Thing> as std::iter::DoubleEndedIterator>::nth_back` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/double_ended.rs:192:12: 192:35
note: inside `main`
   --> src/main.rs:6:13
    |
  6 |     let _ = v.into_iter().nth_back(1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to 1 previous error

The stable method nth_back calls the unstable method advance_back_by. This line inside advance_back_by creates an unaligned slice:

let to_drop = ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size);

A few lines above this code, there's a comment about ZST alignment in the next_back method that was seemingly missed while implementing advance_next_by.

I have not checked if any other code has a similar problem.

Meta

Reproducible on the playground with version 1.93.0-nightly (2025-11-07 843f8ce2ebc01d35a304)

Metadata

Metadata

Assignees

Labels

A-ZSTArea: Zero-sized types (ZSTs).A-alignArea: alignment control (`repr(align(N))` and so on)A-iteratorsArea: IteratorsC-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityT-libsRelevant to the library team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions