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