Skip to content

Commit c168494

Browse files
committed
Make align_of behave like min_align_of.
This removes a footgun, since it is a reasonable assumption to make that pointers to `T` will be aligned to `align_of::<T>()`. This also matches the behaviour of C/C++. `min_align_of` is now deprecated. Closes #21611.
1 parent b301e02 commit c168494

File tree

8 files changed

+68
-56
lines changed

8 files changed

+68
-56
lines changed

src/liballoc/arc.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ use core::atomic;
7777
use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst};
7878
use core::fmt;
7979
use core::cmp::Ordering;
80-
use core::mem::{min_align_of_val, size_of_val};
80+
use core::mem::{align_of_val, size_of_val};
8181
use core::intrinsics::drop_in_place;
8282
use core::mem;
8383
use core::nonzero::NonZero;
@@ -230,7 +230,7 @@ impl<T: ?Sized> Arc<T> {
230230

231231
if self.inner().weak.fetch_sub(1, Release) == 1 {
232232
atomic::fence(Acquire);
233-
deallocate(ptr as *mut u8, size_of_val(&*ptr), min_align_of_val(&*ptr))
233+
deallocate(ptr as *mut u8, size_of_val(&*ptr), align_of_val(&*ptr))
234234
}
235235
}
236236
}
@@ -533,7 +533,7 @@ impl<T: ?Sized> Drop for Weak<T> {
533533
atomic::fence(Acquire);
534534
unsafe { deallocate(ptr as *mut u8,
535535
size_of_val(&*ptr),
536-
min_align_of_val(&*ptr)) }
536+
align_of_val(&*ptr)) }
537537
}
538538
}
539539
}

src/liballoc/rc.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ use core::default::Default;
160160
use core::fmt;
161161
use core::hash::{Hasher, Hash};
162162
use core::marker::{self, Sized};
163-
use core::mem::{self, min_align_of, size_of, forget};
163+
use core::mem::{self, align_of, size_of, forget};
164164
use core::nonzero::NonZero;
165165
use core::ops::{Deref, Drop};
166166
use core::option::Option;
@@ -175,7 +175,7 @@ use core::intrinsics::drop_in_place;
175175
#[cfg(not(stage0))]
176176
use core::marker::Unsize;
177177
#[cfg(not(stage0))]
178-
use core::mem::{min_align_of_val, size_of_val};
178+
use core::mem::{align_of_val, size_of_val};
179179
#[cfg(not(stage0))]
180180
use core::ops::CoerceUnsized;
181181

@@ -369,7 +369,7 @@ pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> {
369369
// destruct the box and skip our Drop
370370
// we can ignore the refcounts because we know we're unique
371371
deallocate(*rc._ptr as *mut u8, size_of::<RcBox<T>>(),
372-
min_align_of::<RcBox<T>>());
372+
align_of::<RcBox<T>>());
373373
forget(rc);
374374
Ok(val)
375375
}
@@ -502,7 +502,7 @@ impl<T> Drop for Rc<T> {
502502

503503
if self.weak() == 0 {
504504
deallocate(ptr as *mut u8, size_of::<RcBox<T>>(),
505-
min_align_of::<RcBox<T>>())
505+
align_of::<RcBox<T>>())
506506
}
507507
}
508508
}
@@ -556,7 +556,7 @@ impl<T: ?Sized> Drop for Rc<T> {
556556
if self.weak() == 0 {
557557
deallocate(ptr as *mut u8,
558558
size_of_val(&*ptr),
559-
min_align_of_val(&*ptr))
559+
align_of_val(&*ptr))
560560
}
561561
}
562562
}
@@ -1011,7 +1011,7 @@ impl<T> Drop for Weak<T> {
10111011
// the strong pointers have disappeared.
10121012
if self.weak() == 0 {
10131013
deallocate(ptr as *mut u8, size_of::<RcBox<T>>(),
1014-
min_align_of::<RcBox<T>>())
1014+
align_of::<RcBox<T>>())
10151015
}
10161016
}
10171017
}
@@ -1057,7 +1057,7 @@ impl<T: ?Sized> Drop for Weak<T> {
10571057
// the strong pointers have disappeared.
10581058
if self.weak() == 0 {
10591059
deallocate(ptr as *mut u8, size_of_val(&*ptr),
1060-
min_align_of_val(&*ptr))
1060+
align_of_val(&*ptr))
10611061
}
10621062
}
10631063
}

src/libarena/lib.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ impl<'longer_than_self> Arena<'longer_than_self> {
241241
fn alloc_copy<T, F>(&self, op: F) -> &mut T where F: FnOnce() -> T {
242242
unsafe {
243243
let ptr = self.alloc_copy_inner(mem::size_of::<T>(),
244-
mem::min_align_of::<T>());
244+
mem::align_of::<T>());
245245
let ptr = ptr as *mut T;
246246
ptr::write(&mut (*ptr), op());
247247
return &mut *ptr;
@@ -297,7 +297,7 @@ impl<'longer_than_self> Arena<'longer_than_self> {
297297
let tydesc = get_tydesc::<T>();
298298
let (ty_ptr, ptr) =
299299
self.alloc_noncopy_inner(mem::size_of::<T>(),
300-
mem::min_align_of::<T>());
300+
mem::align_of::<T>());
301301
let ty_ptr = ty_ptr as *mut usize;
302302
let ptr = ptr as *mut T;
303303
// Write in our tydesc along with a bit indicating that it
@@ -390,7 +390,7 @@ struct TypedArenaChunk<T> {
390390

391391
fn calculate_size<T>(capacity: usize) -> usize {
392392
let mut size = mem::size_of::<TypedArenaChunk<T>>();
393-
size = round_up(size, mem::min_align_of::<T>());
393+
size = round_up(size, mem::align_of::<T>());
394394
let elem_size = mem::size_of::<T>();
395395
let elems_size = elem_size.checked_mul(capacity).unwrap();
396396
size = size.checked_add(elems_size).unwrap();
@@ -402,7 +402,7 @@ impl<T> TypedArenaChunk<T> {
402402
unsafe fn new(next: *mut TypedArenaChunk<T>, capacity: usize)
403403
-> *mut TypedArenaChunk<T> {
404404
let size = calculate_size::<T>(capacity);
405-
let chunk = allocate(size, mem::min_align_of::<TypedArenaChunk<T>>())
405+
let chunk = allocate(size, mem::align_of::<TypedArenaChunk<T>>())
406406
as *mut TypedArenaChunk<T>;
407407
if chunk.is_null() { alloc::oom() }
408408
(*chunk).next = next;
@@ -428,7 +428,7 @@ impl<T> TypedArenaChunk<T> {
428428
let size = calculate_size::<T>(self.capacity);
429429
let self_ptr: *mut TypedArenaChunk<T> = self;
430430
deallocate(self_ptr as *mut u8, size,
431-
mem::min_align_of::<TypedArenaChunk<T>>());
431+
mem::align_of::<TypedArenaChunk<T>>());
432432
if !next.is_null() {
433433
let capacity = (*next).capacity;
434434
(*next).destroy(capacity);
@@ -441,7 +441,7 @@ impl<T> TypedArenaChunk<T> {
441441
let this: *const TypedArenaChunk<T> = self;
442442
unsafe {
443443
mem::transmute(round_up(this.offset(1) as usize,
444-
mem::min_align_of::<T>()))
444+
mem::align_of::<T>()))
445445
}
446446
}
447447

src/libcollections/btree/node.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,12 @@ fn test_offset_calculation() {
164164
}
165165

166166
fn calculate_allocation_generic<K, V>(capacity: usize, is_leaf: bool) -> (usize, usize) {
167-
let (keys_size, keys_align) = (capacity * mem::size_of::<K>(), mem::min_align_of::<K>());
168-
let (vals_size, vals_align) = (capacity * mem::size_of::<V>(), mem::min_align_of::<V>());
167+
let (keys_size, keys_align) = (capacity * mem::size_of::<K>(), mem::align_of::<K>());
168+
let (vals_size, vals_align) = (capacity * mem::size_of::<V>(), mem::align_of::<V>());
169169
let (edges_size, edges_align) = if is_leaf {
170170
(0, 1)
171171
} else {
172-
((capacity + 1) * mem::size_of::<Node<K, V>>(), mem::min_align_of::<Node<K, V>>())
172+
((capacity + 1) * mem::size_of::<Node<K, V>>(), mem::align_of::<Node<K, V>>())
173173
};
174174

175175
calculate_allocation(
@@ -182,11 +182,11 @@ fn calculate_allocation_generic<K, V>(capacity: usize, is_leaf: bool) -> (usize,
182182
fn calculate_offsets_generic<K, V>(capacity: usize, is_leaf: bool) -> (usize, usize) {
183183
let keys_size = capacity * mem::size_of::<K>();
184184
let vals_size = capacity * mem::size_of::<V>();
185-
let vals_align = mem::min_align_of::<V>();
185+
let vals_align = mem::align_of::<V>();
186186
let edges_align = if is_leaf {
187187
1
188188
} else {
189-
mem::min_align_of::<Node<K, V>>()
189+
mem::align_of::<Node<K, V>>()
190190
};
191191

192192
calculate_offsets(

src/libcollections/vec.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ impl<T> Vec<T> {
221221
} else {
222222
let size = capacity.checked_mul(mem::size_of::<T>())
223223
.expect("capacity overflow");
224-
let ptr = unsafe { allocate(size, mem::min_align_of::<T>()) };
224+
let ptr = unsafe { allocate(size, mem::align_of::<T>()) };
225225
if ptr.is_null() { ::alloc::oom() }
226226
unsafe { Vec::from_raw_parts(ptr as *mut T, 0, capacity) }
227227
}
@@ -394,7 +394,7 @@ impl<T> Vec<T> {
394394
let ptr = reallocate(*self.ptr as *mut u8,
395395
self.cap * mem::size_of::<T>(),
396396
self.len * mem::size_of::<T>(),
397-
mem::min_align_of::<T>()) as *mut T;
397+
mem::align_of::<T>()) as *mut T;
398398
if ptr.is_null() { ::alloc::oom() }
399399
self.ptr = Unique::new(ptr);
400400
}
@@ -865,9 +865,9 @@ impl<T> Vec<T> {
865865
// FIXME: Assert statically that the types `T` and `U` have the
866866
// same minimal alignment in case they are not zero-sized.
867867

868-
// These asserts are necessary because the `min_align_of` of the
868+
// These asserts are necessary because the `align_of` of the
869869
// types are passed to the allocator by `Vec`.
870-
assert!(mem::min_align_of::<T>() == mem::min_align_of::<U>());
870+
assert!(mem::align_of::<T>() == mem::align_of::<U>());
871871

872872
// This `as isize` cast is safe, because the size of the elements of the
873873
// vector is not 0, and:
@@ -1268,9 +1268,9 @@ impl<T> Vec<T> {
12681268
#[inline(never)]
12691269
unsafe fn alloc_or_realloc<T>(ptr: *mut T, old_size: usize, size: usize) -> *mut T {
12701270
if old_size == 0 {
1271-
allocate(size, mem::min_align_of::<T>()) as *mut T
1271+
allocate(size, mem::align_of::<T>()) as *mut T
12721272
} else {
1273-
reallocate(ptr as *mut u8, old_size, size, mem::min_align_of::<T>()) as *mut T
1273+
reallocate(ptr as *mut u8, old_size, size, mem::align_of::<T>()) as *mut T
12741274
}
12751275
}
12761276

@@ -1279,7 +1279,7 @@ unsafe fn dealloc<T>(ptr: *mut T, len: usize) {
12791279
if mem::size_of::<T>() != 0 {
12801280
deallocate(ptr as *mut u8,
12811281
len * mem::size_of::<T>(),
1282-
mem::min_align_of::<T>())
1282+
mem::align_of::<T>())
12831283
}
12841284
}
12851285

src/libcollections/vec_deque.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl<T> Drop for VecDeque<T> {
6767
if mem::size_of::<T>() != 0 {
6868
heap::deallocate(*self.ptr as *mut u8,
6969
self.cap * mem::size_of::<T>(),
70-
mem::min_align_of::<T>())
70+
mem::align_of::<T>())
7171
}
7272
}
7373
}
@@ -172,7 +172,7 @@ impl<T> VecDeque<T> {
172172

173173
let ptr = unsafe {
174174
if mem::size_of::<T>() != 0 {
175-
let ptr = heap::allocate(size, mem::min_align_of::<T>()) as *mut T;;
175+
let ptr = heap::allocate(size, mem::align_of::<T>()) as *mut T;;
176176
if ptr.is_null() { ::alloc::oom() }
177177
Unique::new(ptr)
178178
} else {
@@ -344,7 +344,7 @@ impl<T> VecDeque<T> {
344344
let ptr = heap::reallocate(*self.ptr as *mut u8,
345345
old,
346346
new,
347-
mem::min_align_of::<T>()) as *mut T;
347+
mem::align_of::<T>()) as *mut T;
348348
if ptr.is_null() { ::alloc::oom() }
349349
self.ptr = Unique::new(ptr);
350350
}
@@ -464,7 +464,7 @@ impl<T> VecDeque<T> {
464464
let ptr = heap::reallocate(*self.ptr as *mut u8,
465465
old,
466466
new_size,
467-
mem::min_align_of::<T>()) as *mut T;
467+
mem::align_of::<T>()) as *mut T;
468468
if ptr.is_null() { ::alloc::oom() }
469469
self.ptr = Unique::new(ptr);
470470
}

src/libcore/mem.rs

+25-13
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ pub fn size_of_val<T>(_val: &T) -> usize {
131131
/// ```
132132
#[inline]
133133
#[stable(feature = "rust1", since = "1.0.0")]
134+
#[deprecated(reason = "use `align_of` instead", since = "1.1.0")]
134135
pub fn min_align_of<T>() -> usize {
135136
unsafe { intrinsics::min_align_of::<T>() }
136137
}
@@ -147,6 +148,7 @@ pub fn min_align_of<T>() -> usize {
147148
#[cfg(not(stage0))]
148149
#[inline]
149150
#[stable(feature = "rust1", since = "1.0.0")]
151+
#[deprecated(reason = "use `align_of_val` instead", since = "1.1.0")]
150152
pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize {
151153
unsafe { intrinsics::min_align_of_val(val) }
152154
}
@@ -163,44 +165,54 @@ pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize {
163165
#[cfg(stage0)]
164166
#[inline]
165167
#[stable(feature = "rust1", since = "1.0.0")]
168+
#[deprecated(reason = "use `align_of_val` instead", since = "1.1.0")]
166169
pub fn min_align_of_val<T>(_val: &T) -> usize {
167170
min_align_of::<T>()
168171
}
169172

170-
/// Returns the alignment in memory for a type.
173+
/// Returns the ABI-required minimum alignment of a type
171174
///
172-
/// This function will return the alignment, in bytes, of a type in memory. If the alignment
173-
/// returned is adhered to, then the type is guaranteed to function properly.
175+
/// This is the alignment used for struct fields. It may be smaller than the preferred alignment.
174176
///
175177
/// # Examples
176178
///
177179
/// ```
178180
/// use std::mem;
179181
///
180-
/// assert_eq!(4, mem::align_of::<i32>());
182+
/// assert_eq!(4, mem::min_align_of::<i32>());
181183
/// ```
182184
#[inline]
183185
#[stable(feature = "rust1", since = "1.0.0")]
184186
pub fn align_of<T>() -> usize {
185-
// We use the preferred alignment as the default alignment for a type. This
186-
// appears to be what clang migrated towards as well:
187-
//
188-
// http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110725/044411.html
189-
unsafe { intrinsics::pref_align_of::<T>() }
187+
unsafe { intrinsics::min_align_of::<T>() }
190188
}
191189

192-
/// Returns the alignment of the type of the value that `_val` points to.
190+
/// Returns the ABI-required minimum alignment of the type of the value that `val` points to
193191
///
194-
/// This is similar to `align_of`, but function will properly handle types such as trait objects
195-
/// (in the future), returning the alignment for an arbitrary value at runtime.
192+
/// # Examples
193+
///
194+
/// ```
195+
/// use std::mem;
196+
///
197+
/// assert_eq!(4, mem::min_align_of_val(&5i32));
198+
/// ```
199+
#[cfg(not(stage0))]
200+
#[inline]
201+
#[stable(feature = "rust1", since = "1.0.0")]
202+
pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
203+
unsafe { intrinsics::min_align_of_val(val) }
204+
}
205+
206+
/// Returns the ABI-required minimum alignment of the type of the value that `_val` points to
196207
///
197208
/// # Examples
198209
///
199210
/// ```
200211
/// use std::mem;
201212
///
202-
/// assert_eq!(4, mem::align_of_val(&5i32));
213+
/// assert_eq!(4, mem::min_align_of_val(&5i32));
203214
/// ```
215+
#[cfg(stage0)]
204216
#[inline]
205217
#[stable(feature = "rust1", since = "1.0.0")]
206218
pub fn align_of_val<T>(_val: &T) -> usize {

0 commit comments

Comments
 (0)