Skip to content

Commit 8718f45

Browse files
committed
Make the alignment intrinsics return ptr::Alignment
1 parent eb25fe3 commit 8718f45

35 files changed

Lines changed: 278 additions & 337 deletions

File tree

compiler/rustc_codegen_cranelift/example/mini_core.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,12 @@ pub union MaybeUninit<T> {
686686
pub value: ManuallyDrop<T>,
687687
}
688688

689+
pub mod mem {
690+
#[lang = "Alignment"]
691+
#[repr(transparent)]
692+
pub struct Alignment(pub usize);
693+
}
694+
689695
pub mod intrinsics {
690696
#[rustc_intrinsic]
691697
pub fn abort() -> !;
@@ -694,9 +700,9 @@ pub mod intrinsics {
694700
#[rustc_intrinsic]
695701
pub unsafe fn size_of_val<T: ?crate::Sized>(val: *const T) -> usize;
696702
#[rustc_intrinsic]
697-
pub const fn align_of<T>() -> usize;
703+
pub const fn align_of<T>() -> crate::ptr::Alignment;
698704
#[rustc_intrinsic]
699-
pub unsafe fn align_of_val<T: ?crate::Sized>(val: *const T) -> usize;
705+
pub unsafe fn align_of_val<T: ?crate::Sized>(val: *const T) -> crate::ptr::Alignment;
700706
#[rustc_intrinsic]
701707
pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize);
702708
#[rustc_intrinsic]
@@ -764,15 +770,15 @@ pub const fn size_of<T>() -> usize {
764770
}
765771

766772
pub const fn align_of<T>() -> usize {
767-
<T as SizedTypeProperties>::ALIGN
773+
<T as SizedTypeProperties>::ALIGN.0
768774
}
769775

770776
trait SizedTypeProperties: Sized {
771777
#[lang = "mem_size_const"]
772778
const SIZE: usize = intrinsics::size_of::<Self>();
773779

774780
#[lang = "mem_align_const"]
775-
const ALIGN: usize = intrinsics::align_of::<Self>();
781+
const ALIGN: crate::ptr::Alignment = intrinsics::align_of::<Self>();
776782
}
777783
impl<T> SizedTypeProperties for T {}
778784

compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ fn main() {
220220
assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4);
221221

222222
assert_eq!(align_of::<u16>() as u8, 2);
223-
assert_eq!(intrinsics::align_of_val(&a) as u8, align_of::<&str>() as u8);
223+
assert_eq!(intrinsics::align_of_val(&a).0 as u8, align_of::<&str>() as u8);
224224

225225
let u8_needs_drop = const { intrinsics::needs_drop::<u8>() };
226226
assert!(!u8_needs_drop);

compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,8 @@ fn codegen_regular_intrinsic_call<'tcx>(
592592
None
593593
};
594594
let (_size, align) = crate::unsize::size_and_align_of(fx, layout, meta);
595-
ret.write_cvalue(fx, CValue::by_val(align, usize_layout));
595+
let alignment_layout = fx.layout_of(fx.tcx.ty_alignment(source_info.span));
596+
ret.write_cvalue(fx, CValue::by_val(align, alignment_layout));
596597
}
597598

598599
sym::vtable_size => {

compiler/rustc_codegen_gcc/example/mini_core.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,12 @@ pub union MaybeUninit<T> {
694694
pub value: ManuallyDrop<T>,
695695
}
696696

697+
pub mod mem {
698+
#[lang = "Alignment"]
699+
#[repr(transparent)]
700+
pub struct Alignment(pub usize);
701+
}
702+
697703
pub mod intrinsics {
698704
#[rustc_intrinsic]
699705
pub const fn black_box<T>(_dummy: T) -> T;
@@ -704,9 +710,9 @@ pub mod intrinsics {
704710
#[rustc_intrinsic]
705711
pub unsafe fn size_of_val<T: ?::Sized>(val: *const T) -> usize;
706712
#[rustc_intrinsic]
707-
pub const fn align_of<T>() -> usize;
713+
pub const fn align_of<T>() -> crate::mem::Alignment;
708714
#[rustc_intrinsic]
709-
pub unsafe fn align_of_val<T: ?::Sized>(val: *const T) -> usize;
715+
pub unsafe fn align_of_val<T: ?::Sized>(val: *const T) -> crate::mem::Alignment;
710716
#[rustc_intrinsic]
711717
pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize);
712718
#[rustc_intrinsic]
@@ -747,15 +753,15 @@ pub const fn size_of<T>() -> usize {
747753
}
748754

749755
pub const fn align_of<T>() -> usize {
750-
<T as SizedTypeProperties>::ALIGN
756+
<T as SizedTypeProperties>::ALIGN.0
751757
}
752758

753759
trait SizedTypeProperties: Sized {
754760
#[lang = "mem_size_const"]
755761
const SIZE: usize = intrinsics::size_of::<Self>();
756762

757763
#[lang = "mem_align_const"]
758-
const ALIGN: usize = intrinsics::align_of::<Self>();
764+
const ALIGN: crate::ptr::Alignment = intrinsics::align_of::<Self>();
759765
}
760766

761767
impl<T> SizedTypeProperties for T {}

compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ fn main() {
196196
assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4);
197197

198198
assert_eq!(align_of::<u16>() as u8, 2);
199-
assert_eq!(intrinsics::align_of_val(&a) as u8, align_of::<&str>() as u8);
199+
assert_eq!(intrinsics::align_of_val(&a).0 as u8, align_of::<&str>() as u8);
200200

201201
let u8_needs_drop = const { intrinsics::needs_drop::<u8>() };
202202
assert!(!u8_needs_drop);

compiler/rustc_hir/src/lang_items.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ language_item_table! {
156156
MetaSized, sym::meta_sized, meta_sized_trait, Target::Trait, GenericRequirement::Exact(0);
157157
PointeeSized, sym::pointee_sized, pointee_sized_trait, Target::Trait, GenericRequirement::Exact(0);
158158
Unsize, sym::unsize, unsize_trait, Target::Trait, GenericRequirement::Minimum(1);
159+
Alignment, sym::Alignment, alignment_type, Target::Struct, GenericRequirement::Exact(0);
159160
AlignOf, sym::mem_align_const, align_const, Target::AssocConst, GenericRequirement::Exact(0);
160161
SizeOf, sym::mem_size_const, size_const, Target::AssocConst, GenericRequirement::Exact(0);
161162
OffsetOf, sym::offset_of, offset_of, Target::Fn, GenericRequirement::Exact(1);

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,10 +292,10 @@ pub(crate) fn check_intrinsic_type(
292292
sym::amdgpu_dispatch_ptr => (0, 0, vec![], Ty::new_imm_ptr(tcx, tcx.types.unit)),
293293
sym::unreachable => (0, 0, vec![], tcx.types.never),
294294
sym::breakpoint => (0, 0, vec![], tcx.types.unit),
295-
sym::size_of | sym::align_of | sym::variant_count => (1, 0, vec![], tcx.types.usize),
296-
sym::size_of_val | sym::align_of_val => {
297-
(1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize)
298-
}
295+
sym::size_of | sym::variant_count => (1, 0, vec![], tcx.types.usize),
296+
sym::align_of => (1, 0, vec![], tcx.ty_alignment(span)),
297+
sym::size_of_val => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize),
298+
sym::align_of_val => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.ty_alignment(span)),
299299
sym::size_of_type_id => (0, 0, vec![type_id_ty()], Ty::new_option(tcx, tcx.types.usize)),
300300
sym::offset_of => (1, 0, vec![tcx.types.u32, tcx.types.u32], tcx.types.usize),
301301
sym::field_offset => (1, 0, vec![], tcx.types.usize),

compiler/rustc_middle/src/ty/context.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,13 @@ impl<'tcx> TyCtxt<'tcx> {
979979
self.type_of(ordering_enum).no_bound_vars().unwrap()
980980
}
981981

982+
/// Gets a `Ty` representing the [`LangItem::Alignment`]
983+
#[track_caller]
984+
pub fn ty_alignment(self, span: Span) -> Ty<'tcx> {
985+
let alignment = self.require_lang_item(hir::LangItem::Alignment, span);
986+
self.type_of(alignment).no_bound_vars().unwrap()
987+
}
988+
982989
/// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
983990
/// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
984991
pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {

compiler/rustc_mir_transform/src/check_alignment.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,23 @@ fn insert_alignment_check<'tcx>(
5555
stmts.push(Statement::new(source_info, StatementKind::Assign(Box::new((thin_ptr, rvalue)))));
5656

5757
// Transmute the pointer to a usize (equivalent to `ptr.addr()`).
58-
let rvalue = Rvalue::Cast(CastKind::Transmute, Operand::Copy(thin_ptr), tcx.types.usize);
58+
let rvalue = Rvalue::Cast(CastKind::Transmute, Operand::Move(thin_ptr), tcx.types.usize);
5959
let addr = local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
6060
stmts.push(Statement::new(source_info, StatementKind::Assign(Box::new((addr, rvalue)))));
6161

6262
// Get the alignment of the pointee
6363
let align_def_id = tcx.require_lang_item(LangItem::AlignOf, source_info.span);
64+
let alignment_usize =
65+
local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
6466
let alignment =
6567
Operand::unevaluated_constant(tcx, align_def_id, &[pointee_ty.into()], source_info.span);
68+
stmts.push(Statement::new(
69+
source_info,
70+
StatementKind::Assign(Box::new((
71+
alignment_usize,
72+
Rvalue::Cast(CastKind::Transmute, alignment.clone(), tcx.types.usize),
73+
))),
74+
));
6675

6776
// Subtract 1 from the alignment to get the alignment mask
6877
let alignment_mask =
@@ -76,7 +85,7 @@ fn insert_alignment_check<'tcx>(
7685
source_info,
7786
StatementKind::Assign(Box::new((
7887
alignment_mask,
79-
Rvalue::BinaryOp(BinOp::Sub, Box::new((alignment.clone(), one))),
88+
Rvalue::BinaryOp(BinOp::SubUnchecked, Box::new((Operand::Move(alignment_usize), one))),
8089
))),
8190
));
8291

@@ -138,10 +147,10 @@ fn insert_alignment_check<'tcx>(
138147
// Emit a check that asserts on the alignment and otherwise triggers a
139148
// AssertKind::MisalignedPointerDereference.
140149
PointerCheck {
141-
cond: Operand::Copy(is_ok),
150+
cond: Operand::Move(is_ok),
142151
assert_kind: Box::new(AssertKind::MisalignedPointerDereference {
143152
required: alignment,
144-
found: Operand::Copy(addr),
153+
found: Operand::Move(addr),
145154
}),
146155
}
147156
}

library/core/src/intrinsics/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2797,7 +2797,7 @@ pub const fn size_of<T>() -> usize;
27972797
#[unstable(feature = "core_intrinsics", issue = "none")]
27982798
#[rustc_intrinsic_const_stable_indirect]
27992799
#[rustc_intrinsic]
2800-
pub const fn align_of<T>() -> usize;
2800+
pub const fn align_of<T>() -> mem::Alignment;
28012801

28022802
/// The offset of a field inside a type.
28032803
///
@@ -2871,7 +2871,7 @@ pub const unsafe fn size_of_val<T: ?Sized>(ptr: *const T) -> usize;
28712871
#[unstable(feature = "core_intrinsics", issue = "none")]
28722872
#[rustc_intrinsic]
28732873
#[rustc_intrinsic_const_stable_indirect]
2874-
pub const unsafe fn align_of_val<T: ?Sized>(ptr: *const T) -> usize;
2874+
pub const unsafe fn align_of_val<T: ?Sized>(ptr: *const T) -> mem::Alignment;
28752875

28762876
#[rustc_intrinsic]
28772877
#[unstable(feature = "core_intrinsics", issue = "none")]

0 commit comments

Comments
 (0)