Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1046,16 +1046,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}

&Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
let trait_ref =
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, span), [ty]);

self.prove_trait_ref(
trait_ref,
location.to_locations(),
ConstraintCategory::SizedBound,
);
}
&Rvalue::NullaryOp(NullOp::ContractChecks, _) => {}
&Rvalue::NullaryOp(NullOp::UbChecks, _) => {}

Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_codegen_cranelift/example/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,6 @@ pub fn debug_tuple() -> DebugTuple {
DebugTuple(())
}

pub fn size_of<T>() -> usize {
intrinsics::size_of::<T>()
}

pub fn use_size_of() -> usize {
size_of::<u64>()
}
Expand Down
24 changes: 21 additions & 3 deletions compiler/rustc_codegen_cranelift/example/mini_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
extern_types,
decl_macro,
rustc_attrs,
rustc_private,
transparent_unions,
auto_traits,
freeze_impls,
Expand Down Expand Up @@ -594,7 +595,7 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}
impl<T> Box<T> {
pub fn new(val: T) -> Box<T> {
unsafe {
let size = intrinsics::size_of::<T>();
let size = size_of::<T>();
let ptr = libc::malloc(size);
intrinsics::copy(&val as *const T as *const u8, ptr, size);
Box(Unique { pointer: NonNull(ptr as *const T), _marker: PhantomData }, Global)
Expand Down Expand Up @@ -646,11 +647,11 @@ pub mod intrinsics {
#[rustc_intrinsic]
pub fn abort() -> !;
#[rustc_intrinsic]
pub fn size_of<T>() -> usize;
pub const fn size_of<T>() -> usize;
#[rustc_intrinsic]
pub unsafe fn size_of_val<T: ?::Sized>(val: *const T) -> usize;
#[rustc_intrinsic]
pub fn align_of<T>() -> usize;
pub const fn align_of<T>() -> usize;
#[rustc_intrinsic]
pub unsafe fn align_of_val<T: ?::Sized>(val: *const T) -> usize;
#[rustc_intrinsic]
Expand Down Expand Up @@ -715,6 +716,23 @@ impl<T> Index<usize> for [T] {
}
}

pub const fn size_of<T>() -> usize {
<T as SizedTypeProperties>::SIZE
}

pub const fn align_of<T>() -> usize {
<T as SizedTypeProperties>::ALIGN
}

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

#[lang = "mem_align_const"]
const ALIGN: usize = intrinsics::align_of::<Self>();
}
impl<T> SizedTypeProperties for T {}

extern "C" {
type VaListImpl;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,10 @@ fn start<T: Termination + 'static>(
puts(*argv as *const i8);
}
unsafe {
puts(*((argv as usize + intrinsics::size_of::<*const u8>()) as *const *const i8));
puts(*((argv as usize + size_of::<*const u8>()) as *const *const i8));
}
unsafe {
puts(*((argv as usize + 2 * intrinsics::size_of::<*const u8>()) as *const *const i8));
puts(*((argv as usize + 2 * size_of::<*const u8>()) as *const *const i8));
}
}

Expand Down Expand Up @@ -213,8 +213,8 @@ fn main() {
assert_eq!(intrinsics::size_of_val(a) as u8, 16);
assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4);

assert_eq!(intrinsics::align_of::<u16>() as u8, 2);
assert_eq!(intrinsics::align_of_val(&a) as u8, intrinsics::align_of::<&str>() as u8);
assert_eq!(align_of::<u16>() as u8, 2);
assert_eq!(intrinsics::align_of_val(&a) as u8, align_of::<&str>() as u8);

let u8_needs_drop = const { intrinsics::needs_drop::<u8>() };
assert!(!u8_needs_drop);
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -833,8 +833,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt:
assert!(lval.layout().ty.is_sized(fx.tcx, fx.typing_env()));
let layout = fx.layout_of(fx.monomorphize(ty));
let val = match null_op {
NullOp::SizeOf => layout.size.bytes(),
NullOp::AlignOf => layout.align.bytes(),
NullOp::OffsetOf(fields) => fx
.tcx
.offset_of_subfield(
Expand Down
10 changes: 0 additions & 10 deletions compiler/rustc_codegen_ssa/src/mir/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -611,16 +611,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let ty = self.monomorphize(ty);
let layout = bx.cx().layout_of(ty);
let val = match null_op {
mir::NullOp::SizeOf => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(No action) I do like that this means the different backends don't need this any more, which is nice since it all needs to match what CTFE did anyway 👍

assert!(bx.cx().type_is_sized(ty));
let val = layout.size.bytes();
bx.cx().const_usize(val)
}
mir::NullOp::AlignOf => {
assert!(bx.cx().type_is_sized(ty));
let val = layout.align.bytes();
bx.cx().const_usize(val)
}
mir::NullOp::OffsetOf(fields) => {
let val = bx
.tcx()
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,11 +646,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
Rvalue::Cast(_, _, _) => {}

Rvalue::NullaryOp(
NullOp::SizeOf
| NullOp::AlignOf
| NullOp::OffsetOf(_)
| NullOp::UbChecks
| NullOp::ContractChecks,
NullOp::OffsetOf(_) | NullOp::UbChecks | NullOp::ContractChecks,
_,
) => {}
Rvalue::ShallowInitBox(_, _) => {}
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_const_eval/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,6 @@ fn report_eval_error<'tcx>(
let (error, backtrace) = error.into_parts();
backtrace.print_backtrace();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one here should stay -- it's part of how RUST_CTFE_BACKTRACE works. By default this is a fairly trivial NOP.


let instance = with_no_trimmed_paths!(cid.instance.to_string());

super::report(
ecx,
error,
Expand All @@ -430,7 +428,7 @@ fn report_eval_error<'tcx>(
diag.subdiagnostic(frame);
}
// Add after the frame rendering above, as it adds its own `instance` args.
diag.arg("instance", instance);
diag.arg("instance", with_no_trimmed_paths!(cid.instance.to_string()));
diag.arg("num_frames", num_frames);
},
)
Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,24 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let b_ty = self.read_type_id(&args[1])?;
self.write_scalar(Scalar::from_bool(a_ty == b_ty), dest)?;
}
sym::size_of => {
let tp_ty = instance.args.type_at(0);
let layout = self.layout_of(tp_ty)?;
if !layout.is_sized() {
span_bug!(self.cur_span(), "unsized type for `size_of`");
}
let val = layout.size.bytes();
self.write_scalar(Scalar::from_target_usize(val, self), dest)?;
}
sym::align_of => {
let tp_ty = instance.args.type_at(0);
let layout = self.layout_of(tp_ty)?;
if !layout.is_sized() {
span_bug!(self.cur_span(), "unsized type for `align_of`");
}
let val = layout.align.bytes();
self.write_scalar(Scalar::from_target_usize(val, self), dest)?;
}
sym::variant_count => {
let tp_ty = instance.args.type_at(0);
let ty = match tp_ty.kind() {
Expand Down
14 changes: 0 additions & 14 deletions compiler/rustc_const_eval/src/interpret/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,20 +517,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let usize_layout = || self.layout_of(self.tcx.types.usize).unwrap();

interp_ok(match null_op {
SizeOf => {
if !layout.is_sized() {
span_bug!(self.cur_span(), "unsized type for `NullaryOp::SizeOf`");
}
let val = layout.size.bytes();
ImmTy::from_uint(val, usize_layout())
}
AlignOf => {
if !layout.is_sized() {
span_bug!(self.cur_span(), "unsized type for `NullaryOp::AlignOf`");
}
let val = layout.align.bytes();
ImmTy::from_uint(val, usize_layout())
}
OffsetOf(fields) => {
let val =
self.tcx.offset_of_subfield(self.typing_env, layout, fields.iter()).bytes();
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ language_item_table! {
MetaSized, sym::meta_sized, meta_sized_trait, Target::Trait, GenericRequirement::Exact(0);
PointeeSized, sym::pointee_sized, pointee_sized_trait, Target::Trait, GenericRequirement::Exact(0);
Unsize, sym::unsize, unsize_trait, Target::Trait, GenericRequirement::Minimum(1);
AlignOf, sym::mem_align_const, align_const, Target::AssocConst, GenericRequirement::Exact(0);
SizeOf, sym::mem_size_const, size_const, Target::AssocConst, GenericRequirement::Exact(0);
/// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ").
StructuralPeq, sym::structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None;
Copy, sym::copy, copy_trait, Target::Trait, GenericRequirement::Exact(0);
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1092,8 +1092,6 @@ impl<'tcx> Debug for Rvalue<'tcx> {
NullaryOp(ref op, ref t) => {
let t = with_no_trimmed_paths!(format!("{}", t));
match op {
NullOp::SizeOf => write!(fmt, "SizeOf({t})"),
NullOp::AlignOf => write!(fmt, "AlignOf({t})"),
NullOp::OffsetOf(fields) => write!(fmt, "OffsetOf({t}, {fields:?})"),
NullOp::UbChecks => write!(fmt, "UbChecks()"),
NullOp::ContractChecks => write!(fmt, "ContractChecks()"),
Expand Down
18 changes: 14 additions & 4 deletions compiler/rustc_middle/src/mir/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,18 @@ impl<'tcx> Operand<'tcx> {
}))
}

/// Convenience helper to make a constant that refers to the given `DefId` and args. Since this
/// is used to synthesize MIR, assumes `user_ty` is None.
pub fn unevaluated_constant(
tcx: TyCtxt<'tcx>,
def_id: DefId,
args: &[GenericArg<'tcx>],
span: Span,
) -> Self {
let const_ = Const::from_unevaluated(tcx, def_id).instantiate(tcx, args);
Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_ }))
}

pub fn is_move(&self) -> bool {
matches!(self, Operand::Move(..))
}
Expand Down Expand Up @@ -782,9 +794,7 @@ impl<'tcx> Rvalue<'tcx> {
op.ty(tcx, arg_ty)
}
Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx),
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {
tcx.types.usize
}
Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => tcx.types.usize,
Rvalue::NullaryOp(NullOp::ContractChecks, _)
| Rvalue::NullaryOp(NullOp::UbChecks, _) => tcx.types.bool,
Rvalue::Aggregate(ref ak, ref ops) => match **ak {
Expand Down Expand Up @@ -853,7 +863,7 @@ impl BorrowKind {
impl<'tcx> NullOp<'tcx> {
pub fn ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match self {
NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) => tcx.types.usize,
NullOp::OffsetOf(_) => tcx.types.usize,
NullOp::UbChecks | NullOp::ContractChecks => tcx.types.bool,
}
}
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_middle/src/mir/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1563,10 +1563,6 @@ pub enum AggregateKind<'tcx> {

#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
pub enum NullOp<'tcx> {
/// Returns the size of a value of that type
SizeOf,
/// Returns the minimum alignment of a type
AlignOf,
/// Returns the offset of a field
OffsetOf(&'tcx List<(VariantIdx, FieldIdx)>),
/// Returns whether we should perform some UB-checking at runtime.
Expand Down
23 changes: 7 additions & 16 deletions compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,21 +126,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let tcx = this.tcx;
let source_info = this.source_info(expr_span);

let size = this.temp(tcx.types.usize, expr_span);
this.cfg.push_assign(
block,
source_info,
size,
Rvalue::NullaryOp(NullOp::SizeOf, value_ty),
);
let size = tcx.require_lang_item(LangItem::SizeOf, expr_span);
let size = Operand::unevaluated_constant(tcx, size, &[value_ty.into()], expr_span);

let align = this.temp(tcx.types.usize, expr_span);
this.cfg.push_assign(
block,
source_info,
align,
Rvalue::NullaryOp(NullOp::AlignOf, value_ty),
);
let align = tcx.require_lang_item(LangItem::AlignOf, expr_span);
let align =
Operand::unevaluated_constant(tcx, align, &[value_ty.into()], expr_span);

// malloc some memory of suitable size and align:
let exchange_malloc = Operand::function_handle(
Expand All @@ -157,8 +148,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
TerminatorKind::Call {
func: exchange_malloc,
args: [
Spanned { node: Operand::Move(size), span: DUMMY_SP },
Spanned { node: Operand::Move(align), span: DUMMY_SP },
Spanned { node: size, span: DUMMY_SP },
Spanned { node: align, span: DUMMY_SP },
]
.into(),
destination: storage,
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_mir_dataflow/src/move_paths/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,11 +452,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
| Rvalue::RawPtr(..)
| Rvalue::Discriminant(..)
| Rvalue::NullaryOp(
NullOp::SizeOf
| NullOp::AlignOf
| NullOp::OffsetOf(..)
| NullOp::UbChecks
| NullOp::ContractChecks,
NullOp::OffsetOf(..) | NullOp::UbChecks | NullOp::ContractChecks,
_,
) => {}
}
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_mir_transform/src/check_alignment.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use rustc_abi::Align;
use rustc_hir::LangItem;
use rustc_index::IndexVec;
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::visit::PlaceContext;
Expand Down Expand Up @@ -59,10 +60,9 @@ fn insert_alignment_check<'tcx>(
stmts.push(Statement::new(source_info, StatementKind::Assign(Box::new((addr, rvalue)))));

// Get the alignment of the pointee
let align_def_id = tcx.require_lang_item(LangItem::AlignOf, source_info.span);
let alignment =
local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into();
let rvalue = Rvalue::NullaryOp(NullOp::AlignOf, pointee_ty);
stmts.push(Statement::new(source_info, StatementKind::Assign(Box::new((alignment, rvalue)))));
Operand::unevaluated_constant(tcx, align_def_id, &[pointee_ty.into()], source_info.span);

// Subtract 1 from the alignment to get the alignment mask
let alignment_mask =
Expand All @@ -76,7 +76,7 @@ fn insert_alignment_check<'tcx>(
source_info,
StatementKind::Assign(Box::new((
alignment_mask,
Rvalue::BinaryOp(BinOp::Sub, Box::new((Operand::Copy(alignment), one))),
Rvalue::BinaryOp(BinOp::Sub, Box::new((alignment.clone(), one))),
))),
));

Expand Down Expand Up @@ -141,7 +141,7 @@ fn insert_alignment_check<'tcx>(
PointerCheck {
cond: Operand::Copy(is_ok),
assert_kind: Box::new(AssertKind::MisalignedPointerDereference {
required: Operand::Copy(alignment),
required: alignment,
found: Operand::Copy(addr),
}),
}
Expand Down
Loading
Loading