mirror of https://github.com/rust-lang/rust.git
Auto merge of #124241 - matthiaskrgr:rollup-xhu90xr, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #123840 (Add an intrinsic for `ptr::from_raw_parts(_mut)`) - #124224 (cleanup: unnecessary clone during lower generics args) - #124229 (Add gnullvm targets to manifest) - #124231 (remove from reviewers) - #124235 (Move some tests) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
fb898629a2
|
@ -1315,7 +1315,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
}
|
||||
AggregateKind::Adt(..)
|
||||
| AggregateKind::Array(..)
|
||||
| AggregateKind::Tuple { .. } => (),
|
||||
| AggregateKind::Tuple { .. }
|
||||
| AggregateKind::RawPtr(..) => (),
|
||||
}
|
||||
|
||||
for operand in operands {
|
||||
|
|
|
@ -1921,7 +1921,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
AggregateKind::Array(ty) => Ok(ty),
|
||||
AggregateKind::Tuple => {
|
||||
AggregateKind::Tuple | AggregateKind::RawPtr(..) => {
|
||||
unreachable!("This should have been covered in check_rvalues");
|
||||
}
|
||||
}
|
||||
|
@ -2518,6 +2518,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
AggregateKind::Closure(_, _) => None,
|
||||
AggregateKind::Coroutine(_, _) => None,
|
||||
AggregateKind::CoroutineClosure(_, _) => None,
|
||||
AggregateKind::RawPtr(_, _) => None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -2539,6 +2540,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
if let AggregateKind::RawPtr(..) = aggregate_kind {
|
||||
bug!("RawPtr should only be in runtime MIR");
|
||||
}
|
||||
|
||||
for (i, operand) in operands.iter_enumerated() {
|
||||
let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) {
|
||||
Ok(field_ty) => field_ty,
|
||||
|
@ -2757,7 +2762,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
),
|
||||
),
|
||||
|
||||
AggregateKind::Array(_) | AggregateKind::Tuple => {
|
||||
AggregateKind::Array(_) | AggregateKind::Tuple | AggregateKind::RawPtr(..) => {
|
||||
(CRATE_DEF_ID.to_def_id(), ty::InstantiatedPredicates::empty())
|
||||
}
|
||||
};
|
||||
|
|
|
@ -813,6 +813,19 @@ fn codegen_stmt<'tcx>(
|
|||
);
|
||||
lval.write_cvalue(fx, val);
|
||||
}
|
||||
Rvalue::Aggregate(ref kind, ref operands)
|
||||
if matches!(**kind, AggregateKind::RawPtr(..)) =>
|
||||
{
|
||||
let ty = to_place_and_rval.1.ty(&fx.mir.local_decls, fx.tcx);
|
||||
let layout = fx.layout_of(fx.monomorphize(ty));
|
||||
let [data, meta] = &*operands.raw else {
|
||||
bug!("RawPtr fields: {operands:?}");
|
||||
};
|
||||
let data = codegen_operand(fx, data);
|
||||
let meta = codegen_operand(fx, meta);
|
||||
let ptr_val = CValue::pointer_from_data_and_meta(data, meta, layout);
|
||||
lval.write_cvalue(fx, ptr_val);
|
||||
}
|
||||
Rvalue::Aggregate(ref kind, ref operands) => {
|
||||
let (variant_index, variant_dest, active_field_index) = match **kind {
|
||||
mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => {
|
||||
|
|
|
@ -94,6 +94,23 @@ impl<'tcx> CValue<'tcx> {
|
|||
CValue(CValueInner::ByValPair(value, extra), layout)
|
||||
}
|
||||
|
||||
/// For `AggregateKind::RawPtr`, create a pointer from its parts.
|
||||
///
|
||||
/// Panics if the `layout` is not a raw pointer.
|
||||
pub(crate) fn pointer_from_data_and_meta(
|
||||
data: CValue<'tcx>,
|
||||
meta: CValue<'tcx>,
|
||||
layout: TyAndLayout<'tcx>,
|
||||
) -> CValue<'tcx> {
|
||||
assert!(layout.ty.is_unsafe_ptr());
|
||||
let inner = match (data.0, meta.0) {
|
||||
(CValueInner::ByVal(p), CValueInner::ByVal(m)) => CValueInner::ByValPair(p, m),
|
||||
(p @ CValueInner::ByVal(_), CValueInner::ByRef(..)) if meta.1.is_zst() => p,
|
||||
_ => bug!("RawPtr operands {data:?} {meta:?}"),
|
||||
};
|
||||
CValue(inner, layout)
|
||||
}
|
||||
|
||||
pub(crate) fn layout(&self) -> TyAndLayout<'tcx> {
|
||||
self.1
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::MemFlags;
|
|||
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::Operand;
|
||||
use rustc_middle::mir::{AggregateKind, Operand};
|
||||
use rustc_middle::ty::cast::{CastTy, IntTy};
|
||||
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, Ty, TyCtxt};
|
||||
|
@ -720,6 +720,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
OperandRef { val: OperandValue::Immediate(static_), layout }
|
||||
}
|
||||
mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand),
|
||||
mir::Rvalue::Aggregate(box mir::AggregateKind::RawPtr(..), ref fields) => {
|
||||
let ty = rvalue.ty(self.mir, self.cx.tcx());
|
||||
let layout = self.cx.layout_of(self.monomorphize(ty));
|
||||
let [data, meta] = &*fields.raw else {
|
||||
bug!("RawPtr fields: {fields:?}");
|
||||
};
|
||||
let data = self.codegen_operand(bx, data);
|
||||
let meta = self.codegen_operand(bx, meta);
|
||||
match (data.val, meta.val) {
|
||||
(p @ OperandValue::Immediate(_), OperandValue::ZeroSized) => {
|
||||
OperandRef { val: p, layout }
|
||||
}
|
||||
(OperandValue::Immediate(p), OperandValue::Immediate(m)) => {
|
||||
OperandRef { val: OperandValue::Pair(p, m), layout }
|
||||
}
|
||||
_ => bug!("RawPtr operands {data:?} {meta:?}"),
|
||||
}
|
||||
}
|
||||
mir::Rvalue::Repeat(..) | mir::Rvalue::Aggregate(..) => {
|
||||
// According to `rvalue_creates_operand`, only ZST
|
||||
// aggregate rvalues are allowed to be operands.
|
||||
|
@ -1032,6 +1050,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
mir::Rvalue::ThreadLocalRef(_) |
|
||||
mir::Rvalue::Use(..) => // (*)
|
||||
true,
|
||||
// This always produces a `ty::RawPtr`, so will be Immediate or Pair
|
||||
mir::Rvalue::Aggregate(box AggregateKind::RawPtr(..), ..) => true,
|
||||
mir::Rvalue::Repeat(..) |
|
||||
mir::Rvalue::Aggregate(..) => {
|
||||
let ty = rvalue.ty(self.mir, self.cx.tcx());
|
||||
|
|
|
@ -9,7 +9,9 @@ use rustc_middle::mir;
|
|||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
|
||||
|
||||
use super::{ImmTy, InterpCx, InterpResult, Machine, PlaceTy, Projectable, Scalar};
|
||||
use super::{
|
||||
ImmTy, Immediate, InterpCx, InterpResult, Machine, MemPlaceMeta, PlaceTy, Projectable, Scalar,
|
||||
};
|
||||
use crate::util;
|
||||
|
||||
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
|
@ -303,6 +305,27 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
let variant_dest = self.project_downcast(dest, variant_index)?;
|
||||
(variant_index, variant_dest, active_field_index)
|
||||
}
|
||||
mir::AggregateKind::RawPtr(..) => {
|
||||
// Pointers don't have "fields" in the normal sense, so the
|
||||
// projection-based code below would either fail in projection
|
||||
// or in type mismatches. Instead, build an `Immediate` from
|
||||
// the parts and write that to the destination.
|
||||
let [data, meta] = &operands.raw else {
|
||||
bug!("{kind:?} should have 2 operands, had {operands:?}");
|
||||
};
|
||||
let data = self.eval_operand(data, None)?;
|
||||
let data = self.read_pointer(&data)?;
|
||||
let meta = self.eval_operand(meta, None)?;
|
||||
let meta = if meta.layout.is_zst() {
|
||||
MemPlaceMeta::None
|
||||
} else {
|
||||
MemPlaceMeta::Meta(self.read_scalar(&meta)?)
|
||||
};
|
||||
let ptr_imm = Immediate::new_pointer_with_meta(data, meta, self);
|
||||
let ptr = ImmTy::from_immediate(ptr_imm, dest.layout);
|
||||
self.copy_op(&ptr, dest)?;
|
||||
return Ok(());
|
||||
}
|
||||
_ => (FIRST_VARIANT, dest.clone(), None),
|
||||
};
|
||||
if active_field_index.is_some() {
|
||||
|
|
|
@ -923,6 +923,47 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
AggregateKind::RawPtr(pointee_ty, mutability) => {
|
||||
if !matches!(self.mir_phase, MirPhase::Runtime(_)) {
|
||||
// It would probably be fine to support this in earlier phases,
|
||||
// but at the time of writing it's only ever introduced from intrinsic lowering,
|
||||
// so earlier things just `bug!` on it.
|
||||
self.fail(location, "RawPtr should be in runtime MIR only");
|
||||
}
|
||||
|
||||
if fields.len() != 2 {
|
||||
self.fail(location, "raw pointer aggregate must have 2 fields");
|
||||
} else {
|
||||
let data_ptr_ty = fields.raw[0].ty(self.body, self.tcx);
|
||||
let metadata_ty = fields.raw[1].ty(self.body, self.tcx);
|
||||
if let ty::RawPtr(in_pointee, in_mut) = data_ptr_ty.kind() {
|
||||
if *in_mut != mutability {
|
||||
self.fail(location, "input and output mutability must match");
|
||||
}
|
||||
|
||||
// FIXME: check `Thin` instead of `Sized`
|
||||
if !in_pointee.is_sized(self.tcx, self.param_env) {
|
||||
self.fail(location, "input pointer must be thin");
|
||||
}
|
||||
} else {
|
||||
self.fail(
|
||||
location,
|
||||
"first operand to raw pointer aggregate must be a raw pointer",
|
||||
);
|
||||
}
|
||||
|
||||
// FIXME: Check metadata more generally
|
||||
if pointee_ty.is_slice() {
|
||||
if !self.mir_assign_valid_types(metadata_ty, self.tcx.types.usize) {
|
||||
self.fail(location, "slice metadata must be usize");
|
||||
}
|
||||
} else if pointee_ty.is_sized(self.tcx, self.param_env) {
|
||||
if metadata_ty != self.tcx.types.unit {
|
||||
self.fail(location, "metadata for pointer-to-thin must be unit");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Rvalue::Ref(_, BorrowKind::Fake, _) => {
|
||||
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
|
||||
|
|
|
@ -128,6 +128,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
|
|||
| sym::variant_count
|
||||
| sym::is_val_statically_known
|
||||
| sym::ptr_mask
|
||||
| sym::aggregate_raw_ptr
|
||||
| sym::ub_checks
|
||||
| sym::fadd_algebraic
|
||||
| sym::fsub_algebraic
|
||||
|
@ -574,6 +575,10 @@ pub fn check_intrinsic_type(
|
|||
(0, 0, vec![Ty::new_imm_ptr(tcx, Ty::new_unit(tcx))], tcx.types.usize)
|
||||
}
|
||||
|
||||
// This type check is not particularly useful, but the `where` bounds
|
||||
// on the definition in `core` do the heavy lifting for checking it.
|
||||
sym::aggregate_raw_ptr => (3, 1, vec![param(1), param(2)], param(0)),
|
||||
|
||||
sym::ub_checks => (0, 1, Vec::new(), tcx.types.bool),
|
||||
|
||||
sym::simd_eq
|
||||
|
|
|
@ -228,8 +228,8 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
|
|||
// Check whether this segment takes generic arguments and the user has provided any.
|
||||
let (generic_args, infer_args) = ctx.args_for_def_id(def_id);
|
||||
|
||||
let args_iter = generic_args.iter().flat_map(|generic_args| generic_args.args.iter());
|
||||
let mut args_iter = args_iter.clone().peekable();
|
||||
let mut args_iter =
|
||||
generic_args.iter().flat_map(|generic_args| generic_args.args.iter()).peekable();
|
||||
|
||||
// If we encounter a type or const when we expect a lifetime, we infer the lifetimes.
|
||||
// If we later encounter a lifetime, we know that the arguments were provided in the
|
||||
|
|
|
@ -1094,6 +1094,15 @@ impl<'tcx> Debug for Rvalue<'tcx> {
|
|||
|
||||
struct_fmt.finish()
|
||||
}),
|
||||
|
||||
AggregateKind::RawPtr(pointee_ty, mutability) => {
|
||||
let kind_str = match mutability {
|
||||
Mutability::Mut => "mut",
|
||||
Mutability::Not => "const",
|
||||
};
|
||||
with_no_trimmed_paths!(write!(fmt, "*{kind_str} {pointee_ty} from "))?;
|
||||
fmt_tuple(fmt, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1351,6 +1351,21 @@ pub enum AggregateKind<'tcx> {
|
|||
Closure(DefId, GenericArgsRef<'tcx>),
|
||||
Coroutine(DefId, GenericArgsRef<'tcx>),
|
||||
CoroutineClosure(DefId, GenericArgsRef<'tcx>),
|
||||
|
||||
/// Construct a raw pointer from the data pointer and metadata.
|
||||
///
|
||||
/// The `Ty` here is the type of the *pointee*, not the pointer itself.
|
||||
/// The `Mutability` indicates whether this produces a `*const` or `*mut`.
|
||||
///
|
||||
/// The [`Rvalue::Aggregate`] operands for thus must be
|
||||
///
|
||||
/// 0. A raw pointer of matching mutability with any [`core::ptr::Thin`] pointee
|
||||
/// 1. A value of the appropriate [`core::ptr::Pointee::Metadata`] type
|
||||
///
|
||||
/// *Both* operands must always be included, even the unit value if this is
|
||||
/// creating a thin pointer. If you're just converting between thin pointers,
|
||||
/// you may want an [`Rvalue::Cast`] with [`CastKind::PtrToPtr`] instead.
|
||||
RawPtr(Ty<'tcx>, Mutability),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
|
||||
|
|
|
@ -206,6 +206,7 @@ impl<'tcx> Rvalue<'tcx> {
|
|||
AggregateKind::CoroutineClosure(did, args) => {
|
||||
Ty::new_coroutine_closure(tcx, did, args)
|
||||
}
|
||||
AggregateKind::RawPtr(ty, mutability) => Ty::new_ptr(tcx, ty, mutability),
|
||||
},
|
||||
Rvalue::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty),
|
||||
Rvalue::CopyForDeref(ref place) => place.ty(local_decls, tcx).ty,
|
||||
|
|
|
@ -751,6 +751,9 @@ macro_rules! make_mir_visitor {
|
|||
) => {
|
||||
self.visit_args(coroutine_closure_args, location);
|
||||
}
|
||||
AggregateKind::RawPtr(ty, _) => {
|
||||
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
||||
}
|
||||
}
|
||||
|
||||
for operand in operands {
|
||||
|
|
|
@ -885,6 +885,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
AggregateKind::Adt(did, ..) => tcx.def_kind(did) != DefKind::Enum,
|
||||
// Coroutines are never ZST, as they at least contain the implicit states.
|
||||
AggregateKind::Coroutine(..) => false,
|
||||
AggregateKind::RawPtr(..) => bug!("MIR for RawPtr aggregate must have 2 fields"),
|
||||
};
|
||||
|
||||
if is_zst {
|
||||
|
@ -910,6 +911,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
}
|
||||
// Do not track unions.
|
||||
AggregateKind::Adt(_, _, _, _, Some(_)) => return None,
|
||||
// FIXME: Do the extra work to GVN `from_raw_parts`
|
||||
AggregateKind::RawPtr(..) => return None,
|
||||
};
|
||||
|
||||
let fields: Option<Vec<_>> = fields
|
||||
|
|
|
@ -36,6 +36,7 @@ impl<'tcx> MirPass<'tcx> for InstSimplify {
|
|||
ctx.simplify_bool_cmp(&statement.source_info, rvalue);
|
||||
ctx.simplify_ref_deref(&statement.source_info, rvalue);
|
||||
ctx.simplify_len(&statement.source_info, rvalue);
|
||||
ctx.simplify_ptr_aggregate(&statement.source_info, rvalue);
|
||||
ctx.simplify_cast(rvalue);
|
||||
}
|
||||
_ => {}
|
||||
|
@ -58,8 +59,17 @@ struct InstSimplifyContext<'tcx, 'a> {
|
|||
|
||||
impl<'tcx> InstSimplifyContext<'tcx, '_> {
|
||||
fn should_simplify(&self, source_info: &SourceInfo, rvalue: &Rvalue<'tcx>) -> bool {
|
||||
self.should_simplify_custom(source_info, "Rvalue", rvalue)
|
||||
}
|
||||
|
||||
fn should_simplify_custom(
|
||||
&self,
|
||||
source_info: &SourceInfo,
|
||||
label: &str,
|
||||
value: impl std::fmt::Debug,
|
||||
) -> bool {
|
||||
self.tcx.consider_optimizing(|| {
|
||||
format!("InstSimplify - Rvalue: {rvalue:?} SourceInfo: {source_info:?}")
|
||||
format!("InstSimplify - {label}: {value:?} SourceInfo: {source_info:?}")
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -111,7 +121,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
|
|||
if a.const_.ty().is_bool() { a.const_.try_to_bool() } else { None }
|
||||
}
|
||||
|
||||
/// Transform "&(*a)" ==> "a".
|
||||
/// Transform `&(*a)` ==> `a`.
|
||||
fn simplify_ref_deref(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
|
||||
if let Rvalue::Ref(_, _, place) = rvalue {
|
||||
if let Some((base, ProjectionElem::Deref)) = place.as_ref().last_projection() {
|
||||
|
@ -131,7 +141,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Transform "Len([_; N])" ==> "N".
|
||||
/// Transform `Len([_; N])` ==> `N`.
|
||||
fn simplify_len(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
|
||||
if let Rvalue::Len(ref place) = *rvalue {
|
||||
let place_ty = place.ty(self.local_decls, self.tcx).ty;
|
||||
|
@ -147,6 +157,30 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Transform `Aggregate(RawPtr, [p, ()])` ==> `Cast(PtrToPtr, p)`.
|
||||
fn simplify_ptr_aggregate(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
|
||||
if let Rvalue::Aggregate(box AggregateKind::RawPtr(pointee_ty, mutability), fields) = rvalue
|
||||
{
|
||||
let meta_ty = fields.raw[1].ty(self.local_decls, self.tcx);
|
||||
if meta_ty.is_unit() {
|
||||
// The mutable borrows we're holding prevent printing `rvalue` here
|
||||
if !self.should_simplify_custom(
|
||||
source_info,
|
||||
"Aggregate::RawPtr",
|
||||
(&pointee_ty, *mutability, &fields),
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut fields = std::mem::take(fields);
|
||||
let _meta = fields.pop().unwrap();
|
||||
let data = fields.pop().unwrap();
|
||||
let ptr_ty = Ty::new_ptr(self.tcx, *pointee_ty, *mutability);
|
||||
*rvalue = Rvalue::Cast(CastKind::PtrToPtr, data, ptr_ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn simplify_ub_check(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
|
||||
if let Rvalue::NullaryOp(NullOp::UbChecks, _) = *rvalue {
|
||||
let const_ = Const::from_bool(self.tcx, self.tcx.sess.ub_checks());
|
||||
|
|
|
@ -603,6 +603,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
AggregateKind::Adt(_, variant, _, _, _) => variant,
|
||||
AggregateKind::Array(_)
|
||||
| AggregateKind::Tuple
|
||||
| AggregateKind::RawPtr(_, _)
|
||||
| AggregateKind::Closure(_, _)
|
||||
| AggregateKind::Coroutine(_, _)
|
||||
| AggregateKind::CoroutineClosure(_, _) => VariantIdx::ZERO,
|
||||
|
|
|
@ -287,6 +287,34 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
|||
terminator.kind = TerminatorKind::Unreachable;
|
||||
}
|
||||
}
|
||||
sym::aggregate_raw_ptr => {
|
||||
let Ok([data, meta]) = <[_; 2]>::try_from(std::mem::take(args)) else {
|
||||
span_bug!(
|
||||
terminator.source_info.span,
|
||||
"Wrong number of arguments for aggregate_raw_ptr intrinsic",
|
||||
);
|
||||
};
|
||||
let target = target.unwrap();
|
||||
let pointer_ty = generic_args.type_at(0);
|
||||
let kind = if let ty::RawPtr(pointee_ty, mutability) = pointer_ty.kind() {
|
||||
AggregateKind::RawPtr(*pointee_ty, *mutability)
|
||||
} else {
|
||||
span_bug!(
|
||||
terminator.source_info.span,
|
||||
"Return type of aggregate_raw_ptr intrinsic must be a raw pointer",
|
||||
);
|
||||
};
|
||||
let fields = [data.node, meta.node];
|
||||
block.statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::Aggregate(Box::new(kind), fields.into()),
|
||||
))),
|
||||
});
|
||||
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -543,6 +543,9 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
|
|||
mir::AggregateKind::CoroutineClosure(..) => {
|
||||
todo!("FIXME(async_closures): Lower these to SMIR")
|
||||
}
|
||||
mir::AggregateKind::RawPtr(ty, mutability) => {
|
||||
stable_mir::mir::AggregateKind::RawPtr(ty.stable(tables), mutability.stable(tables))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -361,6 +361,7 @@ symbols! {
|
|||
adt_const_params,
|
||||
advanced_slice_patterns,
|
||||
adx_target_feature,
|
||||
aggregate_raw_ptr,
|
||||
alias,
|
||||
align,
|
||||
align_offset,
|
||||
|
|
|
@ -602,6 +602,7 @@ impl Rvalue {
|
|||
AggregateKind::Coroutine(def, ref args, mov) => {
|
||||
Ok(Ty::new_coroutine(def, args.clone(), mov))
|
||||
}
|
||||
AggregateKind::RawPtr(ty, mutability) => Ok(Ty::new_ptr(ty, mutability)),
|
||||
},
|
||||
Rvalue::ShallowInitBox(_, ty) => Ok(Ty::new_box(*ty)),
|
||||
Rvalue::CopyForDeref(place) => place.ty(locals),
|
||||
|
@ -617,6 +618,7 @@ pub enum AggregateKind {
|
|||
Closure(ClosureDef, GenericArgs),
|
||||
// FIXME(stable_mir): Movability here is redundant
|
||||
Coroutine(CoroutineDef, GenericArgs, Movability),
|
||||
RawPtr(Ty, Mutability),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
|
|
|
@ -2779,6 +2779,34 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize {
|
|||
unreachable!()
|
||||
}
|
||||
|
||||
/// Lowers in MIR to `Rvalue::Aggregate` with `AggregateKind::RawPtr`.
|
||||
///
|
||||
/// This is used to implement functions like `slice::from_raw_parts_mut` and
|
||||
/// `ptr::from_raw_parts` in a way compatible with the compiler being able to
|
||||
/// change the possible layouts of pointers.
|
||||
#[rustc_nounwind]
|
||||
#[unstable(feature = "core_intrinsics", issue = "none")]
|
||||
#[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
|
||||
#[rustc_intrinsic]
|
||||
#[rustc_intrinsic_must_be_overridden]
|
||||
#[cfg(not(bootstrap))]
|
||||
pub const fn aggregate_raw_ptr<P: AggregateRawPtr<D, Metadata = M>, D, M>(_data: D, _meta: M) -> P {
|
||||
// To implement a fallback we'd have to assume the layout of the pointer,
|
||||
// but the whole point of this intrinsic is that we shouldn't do that.
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
#[unstable(feature = "core_intrinsics", issue = "none")]
|
||||
pub trait AggregateRawPtr<D> {
|
||||
type Metadata: Copy;
|
||||
}
|
||||
impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*const T> for *const P {
|
||||
type Metadata = <P as ptr::Pointee>::Metadata;
|
||||
}
|
||||
impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*mut T> for *mut P {
|
||||
type Metadata = <P as ptr::Pointee>::Metadata;
|
||||
}
|
||||
|
||||
// Some functions are defined here because they accidentally got made
|
||||
// available in this module on stable. See <https://github.com/rust-lang/rust/issues/15702>.
|
||||
// (`transmute` also falls into this category, but it cannot be wrapped due to the
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
use crate::fmt;
|
||||
use crate::hash::{Hash, Hasher};
|
||||
#[cfg(not(bootstrap))]
|
||||
use crate::intrinsics::aggregate_raw_ptr;
|
||||
use crate::marker::Freeze;
|
||||
|
||||
/// Provides the pointer metadata type of any pointed-to type.
|
||||
|
@ -113,10 +115,17 @@ pub const fn from_raw_parts<T: ?Sized>(
|
|||
data_pointer: *const (),
|
||||
metadata: <T as Pointee>::Metadata,
|
||||
) -> *const T {
|
||||
// SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
|
||||
// and PtrComponents<T> have the same memory layouts. Only std can make this
|
||||
// guarantee.
|
||||
unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.const_ptr }
|
||||
#[cfg(bootstrap)]
|
||||
{
|
||||
// SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
|
||||
// and PtrComponents<T> have the same memory layouts. Only std can make this
|
||||
// guarantee.
|
||||
unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.const_ptr }
|
||||
}
|
||||
#[cfg(not(bootstrap))]
|
||||
{
|
||||
aggregate_raw_ptr(data_pointer, metadata)
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs the same functionality as [`from_raw_parts`], except that a
|
||||
|
@ -130,10 +139,17 @@ pub const fn from_raw_parts_mut<T: ?Sized>(
|
|||
data_pointer: *mut (),
|
||||
metadata: <T as Pointee>::Metadata,
|
||||
) -> *mut T {
|
||||
// SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
|
||||
// and PtrComponents<T> have the same memory layouts. Only std can make this
|
||||
// guarantee.
|
||||
unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.mut_ptr }
|
||||
#[cfg(bootstrap)]
|
||||
{
|
||||
// SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
|
||||
// and PtrComponents<T> have the same memory layouts. Only std can make this
|
||||
// guarantee.
|
||||
unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.mut_ptr }
|
||||
}
|
||||
#[cfg(not(bootstrap))]
|
||||
{
|
||||
aggregate_raw_ptr(data_pointer, metadata)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
|
|
@ -1163,3 +1163,11 @@ fn test_null_array_as_slice() {
|
|||
assert!(ptr.is_null());
|
||||
assert_eq!(ptr.len(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ptr_from_raw_parts_in_const() {
|
||||
const EMPTY_SLICE_PTR: *const [i32] =
|
||||
std::ptr::slice_from_raw_parts(std::ptr::without_provenance(123), 456);
|
||||
assert_eq!(EMPTY_SLICE_PTR.addr(), 123);
|
||||
assert_eq!(EMPTY_SLICE_PTR.len(), 456);
|
||||
}
|
||||
|
|
|
@ -2678,3 +2678,16 @@ fn test_get_many_mut_duplicate() {
|
|||
let mut v = vec![1, 2, 3, 4, 5];
|
||||
assert!(v.get_many_mut([1, 3, 3, 4]).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_slice_from_raw_parts_in_const() {
|
||||
static FANCY: i32 = 4;
|
||||
static FANCY_SLICE: &[i32] = unsafe { std::slice::from_raw_parts(&FANCY, 1) };
|
||||
assert_eq!(FANCY_SLICE.as_ptr(), std::ptr::addr_of!(FANCY));
|
||||
assert_eq!(FANCY_SLICE.len(), 1);
|
||||
|
||||
const EMPTY_SLICE: &[i32] =
|
||||
unsafe { std::slice::from_raw_parts(std::ptr::without_provenance(123456), 0) };
|
||||
assert_eq!(EMPTY_SLICE.as_ptr().addr(), 123456);
|
||||
assert_eq!(EMPTY_SLICE.len(), 0);
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ static TARGETS: &[&str] = &[
|
|||
"aarch64-apple-ios-sim",
|
||||
"aarch64-unknown-fuchsia",
|
||||
"aarch64-linux-android",
|
||||
"aarch64-pc-windows-gnullvm",
|
||||
"aarch64-pc-windows-msvc",
|
||||
"aarch64-unknown-hermit",
|
||||
"aarch64-unknown-linux-gnu",
|
||||
|
@ -96,6 +97,7 @@ static TARGETS: &[&str] = &[
|
|||
"i686-apple-darwin",
|
||||
"i686-linux-android",
|
||||
"i686-pc-windows-gnu",
|
||||
"i686-pc-windows-gnullvm",
|
||||
"i686-pc-windows-msvc",
|
||||
"i686-unknown-freebsd",
|
||||
"i686-unknown-linux-gnu",
|
||||
|
@ -157,6 +159,7 @@ static TARGETS: &[&str] = &[
|
|||
"x86_64-unknown-fuchsia",
|
||||
"x86_64-linux-android",
|
||||
"x86_64-pc-windows-gnu",
|
||||
"x86_64-pc-windows-gnullvm",
|
||||
"x86_64-pc-windows-msvc",
|
||||
"x86_64-pc-solaris",
|
||||
"x86_64-unikraft-linux-musl",
|
||||
|
|
|
@ -74,8 +74,12 @@ ui/associated-type-bounds/issue-99828.rs
|
|||
ui/associated-type-bounds/return-type-notation/issue-120208-higher-ranked-const.rs
|
||||
ui/associated-types/issue-18655.rs
|
||||
ui/associated-types/issue-19081.rs
|
||||
ui/associated-types/issue-19129-1.rs
|
||||
ui/associated-types/issue-19129-2.rs
|
||||
ui/associated-types/issue-19883.rs
|
||||
ui/associated-types/issue-20005.rs
|
||||
ui/associated-types/issue-20763-1.rs
|
||||
ui/associated-types/issue-20763-2.rs
|
||||
ui/associated-types/issue-20825-2.rs
|
||||
ui/associated-types/issue-20825.rs
|
||||
ui/associated-types/issue-21363.rs
|
||||
|
@ -281,6 +285,8 @@ ui/auxiliary/issue-18502.rs
|
|||
ui/auxiliary/issue-24106.rs
|
||||
ui/auxiliary/issue-76387.rs
|
||||
ui/bench/issue-32062.rs
|
||||
ui/binding/issue-40402-1.rs
|
||||
ui/binding/issue-40402-2.rs
|
||||
ui/binding/issue-53114-borrow-checks.rs
|
||||
ui/binding/issue-53114-safety-checks.rs
|
||||
ui/binop/issue-25916.rs
|
||||
|
@ -431,12 +437,16 @@ ui/closures/issue-111932.rs
|
|||
ui/closures/issue-113087.rs
|
||||
ui/closures/issue-11873.rs
|
||||
ui/closures/issue-1460.rs
|
||||
ui/closures/issue-22864-1.rs
|
||||
ui/closures/issue-22864-2.rs
|
||||
ui/closures/issue-23012-supertrait-signature-inference.rs
|
||||
ui/closures/issue-25439.rs
|
||||
ui/closures/issue-41366.rs
|
||||
ui/closures/issue-42463.rs
|
||||
ui/closures/issue-46742.rs
|
||||
ui/closures/issue-48109.rs
|
||||
ui/closures/issue-5239-1.rs
|
||||
ui/closures/issue-5239-2.rs
|
||||
ui/closures/issue-52437.rs
|
||||
ui/closures/issue-67123.rs
|
||||
ui/closures/issue-6801.rs
|
||||
|
@ -482,6 +492,8 @@ ui/coercion/issue-101066.rs
|
|||
ui/coercion/issue-14589.rs
|
||||
ui/coercion/issue-26905-rpass.rs
|
||||
ui/coercion/issue-26905.rs
|
||||
ui/coercion/issue-32122-1.rs
|
||||
ui/coercion/issue-32122-2.rs
|
||||
ui/coercion/issue-36007.rs
|
||||
ui/coercion/issue-37655.rs
|
||||
ui/coercion/issue-3794.rs
|
||||
|
@ -721,6 +733,8 @@ ui/consts/issue-17718-references.rs
|
|||
ui/consts/issue-17718.rs
|
||||
ui/consts/issue-17756.rs
|
||||
ui/consts/issue-18294.rs
|
||||
ui/consts/issue-19244-1.rs
|
||||
ui/consts/issue-19244-2.rs
|
||||
ui/consts/issue-19244.rs
|
||||
ui/consts/issue-21562.rs
|
||||
ui/consts/issue-21721.rs
|
||||
|
@ -845,6 +859,8 @@ ui/cycle-trait/issue-12511.rs
|
|||
ui/debuginfo/issue-105386-debuginfo-ub.rs
|
||||
ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs
|
||||
ui/deprecation/issue-84637-deprecated-associated-function.rs
|
||||
ui/deref-patterns/issue-71676-1.rs
|
||||
ui/deref-patterns/issue-71676-2.rs
|
||||
ui/derived-errors/issue-30580.rs
|
||||
ui/derived-errors/issue-31997-1.rs
|
||||
ui/derived-errors/issue-31997.rs
|
||||
|
@ -952,7 +968,12 @@ ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs
|
|||
ui/enum-discriminant/issue-70509-partial_eq.rs
|
||||
ui/enum-discriminant/issue-72554.rs
|
||||
ui/enum-discriminant/issue-90038.rs
|
||||
ui/enum/auxiliary/issue-19340-1.rs
|
||||
ui/enum/issue-1821.rs
|
||||
ui/enum/issue-19340-1.rs
|
||||
ui/enum/issue-19340-2.rs
|
||||
ui/enum/issue-23304-1.rs
|
||||
ui/enum/issue-23304-2.rs
|
||||
ui/enum/issue-42747.rs
|
||||
ui/enum/issue-67945-1.rs
|
||||
ui/enum/issue-67945-2.rs
|
||||
|
@ -965,6 +986,8 @@ ui/errors/issue-104621-extern-not-file.rs
|
|||
ui/errors/issue-89280-emitter-overflow-splice-lines.rs
|
||||
ui/errors/issue-99572-impl-trait-on-pointer.rs
|
||||
ui/expr/if/issue-4201.rs
|
||||
ui/expr/issue-22933-1.rs
|
||||
ui/expr/issue-22933-2.rs
|
||||
ui/extern/auxiliary/issue-80074-macro-2.rs
|
||||
ui/extern/auxiliary/issue-80074-macro.rs
|
||||
ui/extern/issue-10025.rs
|
||||
|
@ -1400,7 +1423,6 @@ ui/issues/auxiliary/issue-18711.rs
|
|||
ui/issues/auxiliary/issue-18913-1.rs
|
||||
ui/issues/auxiliary/issue-18913-2.rs
|
||||
ui/issues/auxiliary/issue-19293.rs
|
||||
ui/issues/auxiliary/issue-19340-1.rs
|
||||
ui/issues/auxiliary/issue-20389.rs
|
||||
ui/issues/auxiliary/issue-21202.rs
|
||||
ui/issues/auxiliary/issue-2170-lib.rs
|
||||
|
@ -1492,8 +1514,6 @@ ui/issues/issue-11592.rs
|
|||
ui/issues/issue-11677.rs
|
||||
ui/issues/issue-11680.rs
|
||||
ui/issues/issue-11681.rs
|
||||
ui/issues/issue-11692-1.rs
|
||||
ui/issues/issue-11692-2.rs
|
||||
ui/issues/issue-11709.rs
|
||||
ui/issues/issue-11740.rs
|
||||
ui/issues/issue-11771.rs
|
||||
|
@ -1504,8 +1524,6 @@ ui/issues/issue-11958.rs
|
|||
ui/issues/issue-12033.rs
|
||||
ui/issues/issue-12041.rs
|
||||
ui/issues/issue-12127.rs
|
||||
ui/issues/issue-12187-1.rs
|
||||
ui/issues/issue-12187-2.rs
|
||||
ui/issues/issue-12285.rs
|
||||
ui/issues/issue-12567.rs
|
||||
ui/issues/issue-12612.rs
|
||||
|
@ -1713,14 +1731,8 @@ ui/issues/issue-19097.rs
|
|||
ui/issues/issue-19098.rs
|
||||
ui/issues/issue-19100.rs
|
||||
ui/issues/issue-19127.rs
|
||||
ui/issues/issue-19129-1.rs
|
||||
ui/issues/issue-19129-2.rs
|
||||
ui/issues/issue-19135.rs
|
||||
ui/issues/issue-19244-1.rs
|
||||
ui/issues/issue-19244-2.rs
|
||||
ui/issues/issue-19293.rs
|
||||
ui/issues/issue-19340-1.rs
|
||||
ui/issues/issue-19340-2.rs
|
||||
ui/issues/issue-19367.rs
|
||||
ui/issues/issue-19380.rs
|
||||
ui/issues/issue-19398.rs
|
||||
|
@ -1761,8 +1773,6 @@ ui/issues/issue-20644.rs
|
|||
ui/issues/issue-20676.rs
|
||||
ui/issues/issue-20714.rs
|
||||
ui/issues/issue-2074.rs
|
||||
ui/issues/issue-20763-1.rs
|
||||
ui/issues/issue-20763-2.rs
|
||||
ui/issues/issue-20772.rs
|
||||
ui/issues/issue-20797.rs
|
||||
ui/issues/issue-20803.rs
|
||||
|
@ -1835,15 +1845,11 @@ ui/issues/issue-22789.rs
|
|||
ui/issues/issue-2281-part1.rs
|
||||
ui/issues/issue-22814.rs
|
||||
ui/issues/issue-2284.rs
|
||||
ui/issues/issue-22864-1.rs
|
||||
ui/issues/issue-22864-2.rs
|
||||
ui/issues/issue-22872.rs
|
||||
ui/issues/issue-22874.rs
|
||||
ui/issues/issue-2288.rs
|
||||
ui/issues/issue-22886.rs
|
||||
ui/issues/issue-22894.rs
|
||||
ui/issues/issue-22933-1.rs
|
||||
ui/issues/issue-22933-2.rs
|
||||
ui/issues/issue-22992-2.rs
|
||||
ui/issues/issue-22992.rs
|
||||
ui/issues/issue-23024.rs
|
||||
|
@ -1854,8 +1860,6 @@ ui/issues/issue-23073.rs
|
|||
ui/issues/issue-2311-2.rs
|
||||
ui/issues/issue-2311.rs
|
||||
ui/issues/issue-2312.rs
|
||||
ui/issues/issue-23122-1.rs
|
||||
ui/issues/issue-23122-2.rs
|
||||
ui/issues/issue-2316-c.rs
|
||||
ui/issues/issue-23173.rs
|
||||
ui/issues/issue-23189.rs
|
||||
|
@ -1863,8 +1867,6 @@ ui/issues/issue-23217.rs
|
|||
ui/issues/issue-23253.rs
|
||||
ui/issues/issue-23261.rs
|
||||
ui/issues/issue-23281.rs
|
||||
ui/issues/issue-23304-1.rs
|
||||
ui/issues/issue-23304-2.rs
|
||||
ui/issues/issue-23311.rs
|
||||
ui/issues/issue-23336.rs
|
||||
ui/issues/issue-23354-2.rs
|
||||
|
@ -2092,9 +2094,6 @@ ui/issues/issue-31910.rs
|
|||
ui/issues/issue-32004.rs
|
||||
ui/issues/issue-32008.rs
|
||||
ui/issues/issue-32086.rs
|
||||
ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.rs
|
||||
ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.rs
|
||||
ui/issues/issue-3214.rs
|
||||
ui/issues/issue-3220.rs
|
||||
ui/issues/issue-32292.rs
|
||||
ui/issues/issue-32324.rs
|
||||
|
@ -2243,8 +2242,6 @@ ui/issues/issue-4025.rs
|
|||
ui/issues/issue-40288-2.rs
|
||||
ui/issues/issue-40288.rs
|
||||
ui/issues/issue-40350.rs
|
||||
ui/issues/issue-40402-ref-hints/issue-40402-1.rs
|
||||
ui/issues/issue-40402-ref-hints/issue-40402-2.rs
|
||||
ui/issues/issue-40408.rs
|
||||
ui/issues/issue-40610.rs
|
||||
ui/issues/issue-40749.rs
|
||||
|
@ -2438,8 +2435,6 @@ ui/issues/issue-51947.rs
|
|||
ui/issues/issue-52049.rs
|
||||
ui/issues/issue-52126-assign-op-invariance.rs
|
||||
ui/issues/issue-52262.rs
|
||||
ui/issues/issue-5239-1.rs
|
||||
ui/issues/issue-5239-2.rs
|
||||
ui/issues/issue-52489.rs
|
||||
ui/issues/issue-52533.rs
|
||||
ui/issues/issue-52717.rs
|
||||
|
@ -2491,8 +2486,6 @@ ui/issues/issue-57162.rs
|
|||
ui/issues/issue-5718.rs
|
||||
ui/issues/issue-57198-pass.rs
|
||||
ui/issues/issue-57271.rs
|
||||
ui/issues/issue-57362-1.rs
|
||||
ui/issues/issue-57362-2.rs
|
||||
ui/issues/issue-57399-self-return-impl-trait.rs
|
||||
ui/issues/issue-5741.rs
|
||||
ui/issues/issue-5754.rs
|
||||
|
@ -2578,8 +2571,6 @@ ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs
|
|||
ui/issues/issue-70746.rs
|
||||
ui/issues/issue-7092.rs
|
||||
ui/issues/issue-71406.rs
|
||||
ui/issues/issue-71676-suggest-deref/issue-71676-1.rs
|
||||
ui/issues/issue-71676-suggest-deref/issue-71676-2.rs
|
||||
ui/issues/issue-7178.rs
|
||||
ui/issues/issue-72002.rs
|
||||
ui/issues/issue-72076.rs
|
||||
|
@ -2600,8 +2591,6 @@ ui/issues/issue-7563.rs
|
|||
ui/issues/issue-75704.rs
|
||||
ui/issues/issue-7575.rs
|
||||
ui/issues/issue-76042.rs
|
||||
ui/issues/issue-7607-1.rs
|
||||
ui/issues/issue-7607-2.rs
|
||||
ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.rs
|
||||
ui/issues/issue-76077-inaccesible-private-fields/issue-76077.rs
|
||||
ui/issues/issue-76191.rs
|
||||
|
@ -2851,6 +2840,8 @@ ui/macros/issue-109237.rs
|
|||
ui/macros/issue-111749.rs
|
||||
ui/macros/issue-112342-1.rs
|
||||
ui/macros/issue-112342-2.rs
|
||||
ui/macros/issue-11692-1.rs
|
||||
ui/macros/issue-11692-2.rs
|
||||
ui/macros/issue-118048.rs
|
||||
ui/macros/issue-118786.rs
|
||||
ui/macros/issue-16098.rs
|
||||
|
@ -3162,6 +3153,8 @@ ui/nll/issue-57265-return-type-wf-check.rs
|
|||
ui/nll/issue-57280-1-flipped.rs
|
||||
ui/nll/issue-57280-1.rs
|
||||
ui/nll/issue-57280.rs
|
||||
ui/nll/issue-57362-1.rs
|
||||
ui/nll/issue-57362-2.rs
|
||||
ui/nll/issue-57642-higher-ranked-subtype.rs
|
||||
ui/nll/issue-57843.rs
|
||||
ui/nll/issue-57960.rs
|
||||
|
@ -3218,6 +3211,8 @@ ui/packed/issue-27060.rs
|
|||
ui/packed/issue-46152.rs
|
||||
ui/panics/issue-47429-short-backtraces.rs
|
||||
ui/parser/issue-116781.rs
|
||||
ui/parser/issue-12187-1.rs
|
||||
ui/parser/issue-12187-2.rs
|
||||
ui/parser/issues/auxiliary/issue-21146-inc.rs
|
||||
ui/parser/issues/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs
|
||||
ui/parser/issues/auxiliary/issue-94340-inc.rs
|
||||
|
@ -3613,6 +3608,8 @@ ui/reachable/issue-11225-1.rs
|
|||
ui/reachable/issue-11225-2.rs
|
||||
ui/reachable/issue-11225-3.rs
|
||||
ui/reachable/issue-948.rs
|
||||
ui/recursion/issue-23122-1.rs
|
||||
ui/recursion/issue-23122-2.rs
|
||||
ui/recursion/issue-23302-1.rs
|
||||
ui/recursion/issue-23302-2.rs
|
||||
ui/recursion/issue-23302-3.rs
|
||||
|
@ -3692,6 +3689,7 @@ ui/resolve/issue-30535.rs
|
|||
ui/resolve/issue-3099-a.rs
|
||||
ui/resolve/issue-3099-b.rs
|
||||
ui/resolve/issue-31845.rs
|
||||
ui/resolve/issue-3214.rs
|
||||
ui/resolve/issue-33876.rs
|
||||
ui/resolve/issue-35675.rs
|
||||
ui/resolve/issue-3907-2.rs
|
||||
|
@ -4203,6 +4201,8 @@ ui/type/issue-102598.rs
|
|||
ui/type/issue-103271.rs
|
||||
ui/type/issue-58355.rs
|
||||
ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs
|
||||
ui/type/issue-7607-1.rs
|
||||
ui/type/issue-7607-2.rs
|
||||
ui/type/issue-91268.rs
|
||||
ui/type/issue-94187-verbose-type-name.rs
|
||||
ui/type/type-check/issue-116967-cannot-coerce-returned-result.rs
|
||||
|
|
|
@ -17,7 +17,7 @@ use std::path::{Path, PathBuf};
|
|||
const ENTRY_LIMIT: usize = 900;
|
||||
// FIXME: The following limits should be reduced eventually.
|
||||
|
||||
const ISSUES_ENTRY_LIMIT: usize = 1720;
|
||||
const ISSUES_ENTRY_LIMIT: usize = 1676;
|
||||
const ROOT_ENTRY_LIMIT: usize = 859;
|
||||
|
||||
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//@ test-mir-pass: InstSimplify
|
||||
//@ compile-flags: -Zinline-mir
|
||||
#![crate_type = "lib"]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
#[inline(always)]
|
||||
fn generic_cast<T, U>(x: *const T) -> *const U {
|
||||
|
@ -23,3 +24,11 @@ pub fn roundtrip(x: *const u8) -> *const u8 {
|
|||
// CHECK: _2 = move _3 as *const u8 (PointerCoercion(MutToConstPointer));
|
||||
x as *mut u8 as *const u8
|
||||
}
|
||||
|
||||
// EMIT_MIR casts.roundtrip.InstSimplify.diff
|
||||
pub fn cast_thin_via_aggregate(x: *const u8) -> *const () {
|
||||
// CHECK-LABEL: fn cast_thin_via_aggregate(
|
||||
// CHECK: _2 = _1;
|
||||
// CHECK: _0 = move _2 as *const () (PtrToPtr);
|
||||
std::intrinsics::aggregate_raw_ptr(x, ())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
- // MIR for `make_pointers` before LowerIntrinsics
|
||||
+ // MIR for `make_pointers` after LowerIntrinsics
|
||||
|
||||
fn make_pointers(_1: *const u8, _2: *mut (), _3: usize) -> () {
|
||||
debug a => _1;
|
||||
debug b => _2;
|
||||
debug n => _3;
|
||||
let mut _0: ();
|
||||
let _4: *const i32;
|
||||
let mut _5: *const u8;
|
||||
let mut _6: ();
|
||||
let mut _8: *mut ();
|
||||
let mut _9: ();
|
||||
let mut _11: *const u8;
|
||||
let mut _12: usize;
|
||||
let mut _14: *mut ();
|
||||
let mut _15: usize;
|
||||
scope 1 {
|
||||
debug _thin_const => _4;
|
||||
let _7: *mut u8;
|
||||
scope 2 {
|
||||
debug _thin_mut => _7;
|
||||
let _10: *const [u16];
|
||||
scope 3 {
|
||||
debug _slice_const => _10;
|
||||
let _13: *mut [u64];
|
||||
scope 4 {
|
||||
debug _slice_mut => _13;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_5 = _1;
|
||||
StorageLive(_6);
|
||||
_6 = ();
|
||||
- _4 = aggregate_raw_ptr::<*const i32, *const u8, ()>(move _5, move _6) -> [return: bb1, unwind unreachable];
|
||||
+ _4 = *const i32 from (move _5, move _6);
|
||||
+ goto -> bb1;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
_8 = _2;
|
||||
StorageLive(_9);
|
||||
_9 = ();
|
||||
- _7 = aggregate_raw_ptr::<*mut u8, *mut (), ()>(move _8, move _9) -> [return: bb2, unwind unreachable];
|
||||
+ _7 = *mut u8 from (move _8, move _9);
|
||||
+ goto -> bb2;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_9);
|
||||
StorageDead(_8);
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
_11 = _1;
|
||||
StorageLive(_12);
|
||||
_12 = _3;
|
||||
- _10 = aggregate_raw_ptr::<*const [u16], *const u8, usize>(move _11, move _12) -> [return: bb3, unwind unreachable];
|
||||
+ _10 = *const [u16] from (move _11, move _12);
|
||||
+ goto -> bb3;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageLive(_13);
|
||||
StorageLive(_14);
|
||||
_14 = _2;
|
||||
StorageLive(_15);
|
||||
_15 = _3;
|
||||
- _13 = aggregate_raw_ptr::<*mut [u64], *mut (), usize>(move _14, move _15) -> [return: bb4, unwind unreachable];
|
||||
+ _13 = *mut [u64] from (move _14, move _15);
|
||||
+ goto -> bb4;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_15);
|
||||
StorageDead(_14);
|
||||
_0 = const ();
|
||||
StorageDead(_13);
|
||||
StorageDead(_10);
|
||||
StorageDead(_7);
|
||||
StorageDead(_4);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
- // MIR for `make_pointers` before LowerIntrinsics
|
||||
+ // MIR for `make_pointers` after LowerIntrinsics
|
||||
|
||||
fn make_pointers(_1: *const u8, _2: *mut (), _3: usize) -> () {
|
||||
debug a => _1;
|
||||
debug b => _2;
|
||||
debug n => _3;
|
||||
let mut _0: ();
|
||||
let _4: *const i32;
|
||||
let mut _5: *const u8;
|
||||
let mut _6: ();
|
||||
let mut _8: *mut ();
|
||||
let mut _9: ();
|
||||
let mut _11: *const u8;
|
||||
let mut _12: usize;
|
||||
let mut _14: *mut ();
|
||||
let mut _15: usize;
|
||||
scope 1 {
|
||||
debug _thin_const => _4;
|
||||
let _7: *mut u8;
|
||||
scope 2 {
|
||||
debug _thin_mut => _7;
|
||||
let _10: *const [u16];
|
||||
scope 3 {
|
||||
debug _slice_const => _10;
|
||||
let _13: *mut [u64];
|
||||
scope 4 {
|
||||
debug _slice_mut => _13;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
_5 = _1;
|
||||
StorageLive(_6);
|
||||
_6 = ();
|
||||
- _4 = aggregate_raw_ptr::<*const i32, *const u8, ()>(move _5, move _6) -> [return: bb1, unwind unreachable];
|
||||
+ _4 = *const i32 from (move _5, move _6);
|
||||
+ goto -> bb1;
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
_8 = _2;
|
||||
StorageLive(_9);
|
||||
_9 = ();
|
||||
- _7 = aggregate_raw_ptr::<*mut u8, *mut (), ()>(move _8, move _9) -> [return: bb2, unwind unreachable];
|
||||
+ _7 = *mut u8 from (move _8, move _9);
|
||||
+ goto -> bb2;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageDead(_9);
|
||||
StorageDead(_8);
|
||||
StorageLive(_10);
|
||||
StorageLive(_11);
|
||||
_11 = _1;
|
||||
StorageLive(_12);
|
||||
_12 = _3;
|
||||
- _10 = aggregate_raw_ptr::<*const [u16], *const u8, usize>(move _11, move _12) -> [return: bb3, unwind unreachable];
|
||||
+ _10 = *const [u16] from (move _11, move _12);
|
||||
+ goto -> bb3;
|
||||
}
|
||||
|
||||
bb3: {
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
StorageLive(_13);
|
||||
StorageLive(_14);
|
||||
_14 = _2;
|
||||
StorageLive(_15);
|
||||
_15 = _3;
|
||||
- _13 = aggregate_raw_ptr::<*mut [u64], *mut (), usize>(move _14, move _15) -> [return: bb4, unwind unreachable];
|
||||
+ _13 = *mut [u64] from (move _14, move _15);
|
||||
+ goto -> bb4;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_15);
|
||||
StorageDead(_14);
|
||||
_0 = const ();
|
||||
StorageDead(_13);
|
||||
StorageDead(_10);
|
||||
StorageDead(_7);
|
||||
StorageDead(_4);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -248,3 +248,13 @@ pub fn three_way_compare_signed(a: i16, b: i16) {
|
|||
pub fn three_way_compare_unsigned(a: u32, b: u32) {
|
||||
let _x = core::intrinsics::three_way_compare(a, b);
|
||||
}
|
||||
|
||||
// EMIT_MIR lower_intrinsics.make_pointers.LowerIntrinsics.diff
|
||||
pub fn make_pointers(a: *const u8, b: *mut (), n: usize) {
|
||||
use std::intrinsics::aggregate_raw_ptr;
|
||||
|
||||
let _thin_const: *const i32 = aggregate_raw_ptr(a, ());
|
||||
let _thin_mut: *mut u8 = aggregate_raw_ptr(b, ());
|
||||
let _slice_const: *const [u16] = aggregate_raw_ptr(a, n);
|
||||
let _slice_mut: *mut [u64] = aggregate_raw_ptr(b, n);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
// MIR for `demo_byte_add_fat` after PreCodegen
|
||||
|
||||
fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
|
||||
debug p => _1;
|
||||
debug n => _2;
|
||||
let mut _0: *const [u32];
|
||||
scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::byte_add) {
|
||||
let mut _3: *const u8;
|
||||
let mut _4: *const u8;
|
||||
scope 2 (inlined std::ptr::const_ptr::<impl *const [u32]>::cast::<u8>) {
|
||||
}
|
||||
scope 3 (inlined std::ptr::const_ptr::<impl *const u8>::add) {
|
||||
}
|
||||
scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<[u32]>) {
|
||||
let mut _5: *const ();
|
||||
let mut _7: usize;
|
||||
scope 5 (inlined std::ptr::metadata::<[u32]>) {
|
||||
let mut _6: std::ptr::metadata::PtrRepr<[u32]>;
|
||||
}
|
||||
scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_4);
|
||||
StorageLive(_3);
|
||||
_3 = _1 as *const u8 (PtrToPtr);
|
||||
_4 = Offset(_3, _2);
|
||||
StorageDead(_3);
|
||||
StorageLive(_5);
|
||||
_5 = _4 as *const () (PtrToPtr);
|
||||
StorageLive(_7);
|
||||
StorageLive(_6);
|
||||
_6 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: _1 };
|
||||
_7 = ((_6.2: std::ptr::metadata::PtrComponents<[u32]>).1: usize);
|
||||
StorageDead(_6);
|
||||
_0 = *const [u32] from (_5, _7);
|
||||
StorageDead(_7);
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// MIR for `demo_byte_add_fat` after PreCodegen
|
||||
|
||||
fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
|
||||
debug p => _1;
|
||||
debug n => _2;
|
||||
let mut _0: *const [u32];
|
||||
scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::byte_add) {
|
||||
let mut _3: *const u8;
|
||||
let mut _4: *const u8;
|
||||
scope 2 (inlined std::ptr::const_ptr::<impl *const [u32]>::cast::<u8>) {
|
||||
}
|
||||
scope 3 (inlined std::ptr::const_ptr::<impl *const u8>::add) {
|
||||
}
|
||||
scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<[u32]>) {
|
||||
let mut _5: *const ();
|
||||
let mut _7: usize;
|
||||
scope 5 (inlined std::ptr::metadata::<[u32]>) {
|
||||
let mut _6: std::ptr::metadata::PtrRepr<[u32]>;
|
||||
}
|
||||
scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_4);
|
||||
StorageLive(_3);
|
||||
_3 = _1 as *const u8 (PtrToPtr);
|
||||
_4 = Offset(_3, _2);
|
||||
StorageDead(_3);
|
||||
StorageLive(_5);
|
||||
_5 = _4 as *const () (PtrToPtr);
|
||||
StorageLive(_7);
|
||||
StorageLive(_6);
|
||||
_6 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: _1 };
|
||||
_7 = ((_6.2: std::ptr::metadata::PtrComponents<[u32]>).1: usize);
|
||||
StorageDead(_6);
|
||||
_0 = *const [u32] from (_5, _7);
|
||||
StorageDead(_7);
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
// MIR for `demo_byte_add_thin` after PreCodegen
|
||||
|
||||
fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 {
|
||||
debug p => _1;
|
||||
debug n => _2;
|
||||
let mut _0: *const u32;
|
||||
scope 1 (inlined std::ptr::const_ptr::<impl *const u32>::byte_add) {
|
||||
let mut _3: *const u8;
|
||||
let mut _4: *const u8;
|
||||
scope 2 (inlined std::ptr::const_ptr::<impl *const u32>::cast::<u8>) {
|
||||
}
|
||||
scope 3 (inlined std::ptr::const_ptr::<impl *const u8>::add) {
|
||||
}
|
||||
scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<u32>) {
|
||||
scope 5 (inlined std::ptr::metadata::<u32>) {
|
||||
}
|
||||
scope 6 (inlined std::ptr::from_raw_parts::<u32>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_3);
|
||||
_3 = _1 as *const u8 (PtrToPtr);
|
||||
_4 = Offset(_3, _2);
|
||||
StorageDead(_3);
|
||||
_0 = _4 as *const u32 (PtrToPtr);
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
// MIR for `demo_byte_add_thin` after PreCodegen
|
||||
|
||||
fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 {
|
||||
debug p => _1;
|
||||
debug n => _2;
|
||||
let mut _0: *const u32;
|
||||
scope 1 (inlined std::ptr::const_ptr::<impl *const u32>::byte_add) {
|
||||
let mut _3: *const u8;
|
||||
let mut _4: *const u8;
|
||||
scope 2 (inlined std::ptr::const_ptr::<impl *const u32>::cast::<u8>) {
|
||||
}
|
||||
scope 3 (inlined std::ptr::const_ptr::<impl *const u8>::add) {
|
||||
}
|
||||
scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<u32>) {
|
||||
scope 5 (inlined std::ptr::metadata::<u32>) {
|
||||
}
|
||||
scope 6 (inlined std::ptr::from_raw_parts::<u32>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_3);
|
||||
_3 = _1 as *const u8 (PtrToPtr);
|
||||
_4 = Offset(_3, _2);
|
||||
StorageDead(_3);
|
||||
_0 = _4 as *const u32 (PtrToPtr);
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
// skip-filecheck
|
||||
//@ compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 -Zinline-mir
|
||||
//@ ignore-debug: precondition checks are under cfg(debug_assertions)
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// EMIT_MIR ptr_offset.demo_byte_add_thin.PreCodegen.after.mir
|
||||
pub unsafe fn demo_byte_add_thin(p: *const u32, n: usize) -> *const u32 {
|
||||
p.byte_add(n)
|
||||
}
|
||||
|
||||
// EMIT_MIR ptr_offset.demo_byte_add_fat.PreCodegen.after.mir
|
||||
pub unsafe fn demo_byte_add_fat(p: *const [u32], n: usize) -> *const [u32] {
|
||||
p.byte_add(n)
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(slice_ptr_get)]
|
||||
|
||||
use std::ops::Range;
|
||||
|
||||
|
@ -25,3 +26,11 @@ pub fn slice_index_range(slice: &[u32], index: Range<usize>) -> &[u32] {
|
|||
pub unsafe fn slice_get_unchecked_mut_range(slice: &mut [u32], index: Range<usize>) -> &mut [u32] {
|
||||
slice.get_unchecked_mut(index)
|
||||
}
|
||||
|
||||
// EMIT_MIR slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.mir
|
||||
pub unsafe fn slice_ptr_get_unchecked_range(
|
||||
slice: *const [u32],
|
||||
index: Range<usize>,
|
||||
) -> *const [u32] {
|
||||
slice.get_unchecked(index)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
// MIR for `slice_ptr_get_unchecked_range` after PreCodegen
|
||||
|
||||
fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range<usize>) -> *const [u32] {
|
||||
debug slice => _1;
|
||||
debug index => _2;
|
||||
let mut _0: *const [u32];
|
||||
let mut _3: usize;
|
||||
let mut _4: usize;
|
||||
scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::get_unchecked::<std::ops::Range<usize>>) {
|
||||
scope 2 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked) {
|
||||
let _5: usize;
|
||||
let mut _6: *const u32;
|
||||
let mut _7: *const u32;
|
||||
scope 3 {
|
||||
scope 6 (inlined std::ptr::const_ptr::<impl *const [u32]>::as_ptr) {
|
||||
}
|
||||
scope 7 (inlined std::ptr::const_ptr::<impl *const u32>::add) {
|
||||
}
|
||||
scope 8 (inlined slice_from_raw_parts::<u32>) {
|
||||
let mut _8: *const ();
|
||||
scope 9 (inlined std::ptr::const_ptr::<impl *const u32>::cast::<()>) {
|
||||
}
|
||||
scope 10 (inlined std::ptr::from_raw_parts::<[u32]>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 4 (inlined std::ptr::const_ptr::<impl *const [u32]>::len) {
|
||||
scope 5 (inlined std::ptr::metadata::<[u32]>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
_3 = move (_2.0: usize);
|
||||
_4 = move (_2.1: usize);
|
||||
StorageLive(_5);
|
||||
_5 = SubUnchecked(_4, _3);
|
||||
StorageLive(_7);
|
||||
StorageLive(_6);
|
||||
_6 = _1 as *const u32 (PtrToPtr);
|
||||
_7 = Offset(_6, _3);
|
||||
StorageDead(_6);
|
||||
StorageLive(_8);
|
||||
_8 = _7 as *const () (PtrToPtr);
|
||||
_0 = *const [u32] from (_8, _5);
|
||||
StorageDead(_8);
|
||||
StorageDead(_7);
|
||||
StorageDead(_5);
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
// MIR for `slice_ptr_get_unchecked_range` after PreCodegen
|
||||
|
||||
fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range<usize>) -> *const [u32] {
|
||||
debug slice => _1;
|
||||
debug index => _2;
|
||||
let mut _0: *const [u32];
|
||||
let mut _3: usize;
|
||||
let mut _4: usize;
|
||||
scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::get_unchecked::<std::ops::Range<usize>>) {
|
||||
scope 2 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked) {
|
||||
let _5: usize;
|
||||
let mut _6: *const u32;
|
||||
let mut _7: *const u32;
|
||||
scope 3 {
|
||||
scope 6 (inlined std::ptr::const_ptr::<impl *const [u32]>::as_ptr) {
|
||||
}
|
||||
scope 7 (inlined std::ptr::const_ptr::<impl *const u32>::add) {
|
||||
}
|
||||
scope 8 (inlined slice_from_raw_parts::<u32>) {
|
||||
let mut _8: *const ();
|
||||
scope 9 (inlined std::ptr::const_ptr::<impl *const u32>::cast::<()>) {
|
||||
}
|
||||
scope 10 (inlined std::ptr::from_raw_parts::<[u32]>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 4 (inlined std::ptr::const_ptr::<impl *const [u32]>::len) {
|
||||
scope 5 (inlined std::ptr::metadata::<[u32]>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
_3 = move (_2.0: usize);
|
||||
_4 = move (_2.1: usize);
|
||||
StorageLive(_5);
|
||||
_5 = SubUnchecked(_4, _3);
|
||||
StorageLive(_7);
|
||||
StorageLive(_6);
|
||||
_6 = _1 as *const u32 (PtrToPtr);
|
||||
_7 = Offset(_6, _3);
|
||||
StorageDead(_6);
|
||||
StorageLive(_8);
|
||||
_8 = _7 as *const () (PtrToPtr);
|
||||
_0 = *const [u32] from (_8, _5);
|
||||
StorageDead(_8);
|
||||
StorageDead(_7);
|
||||
StorageDead(_5);
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// skip-filecheck
|
||||
//@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=2
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// Added after it stopped inlining in a nightly; see
|
||||
// <https://github.com/rust-lang/rust/issues/123174>
|
||||
|
||||
// EMIT_MIR vec_deref.vec_deref_to_slice.PreCodegen.after.mir
|
||||
pub fn vec_deref_to_slice(v: &Vec<u8>) -> &[u8] {
|
||||
v
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
// MIR for `vec_deref_to_slice` after PreCodegen
|
||||
|
||||
fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
|
||||
debug v => _1;
|
||||
let mut _0: &[u8];
|
||||
scope 1 (inlined <Vec<u8> as Deref>::deref) {
|
||||
debug self => _1;
|
||||
let mut _4: *const u8;
|
||||
let mut _5: usize;
|
||||
scope 2 (inlined Vec::<u8>::as_ptr) {
|
||||
debug self => _1;
|
||||
let mut _2: &alloc::raw_vec::RawVec<u8>;
|
||||
scope 3 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
|
||||
debug self => _2;
|
||||
let mut _3: std::ptr::NonNull<u8>;
|
||||
scope 4 (inlined Unique::<u8>::as_ptr) {
|
||||
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _3;
|
||||
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
|
||||
scope 5 (inlined NonNull::<u8>::as_ptr) {
|
||||
debug self => _3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 6 (inlined std::slice::from_raw_parts::<'_, u8>) {
|
||||
debug data => _4;
|
||||
debug len => _5;
|
||||
let _7: *const [u8];
|
||||
scope 7 (inlined core::ub_checks::check_language_ub) {
|
||||
scope 8 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
}
|
||||
}
|
||||
scope 9 (inlined std::mem::size_of::<u8>) {
|
||||
}
|
||||
scope 10 (inlined align_of::<u8>) {
|
||||
}
|
||||
scope 11 (inlined slice_from_raw_parts::<u8>) {
|
||||
debug data => _4;
|
||||
debug len => _5;
|
||||
let mut _6: *const ();
|
||||
scope 12 (inlined std::ptr::const_ptr::<impl *const u8>::cast::<()>) {
|
||||
debug self => _4;
|
||||
}
|
||||
scope 13 (inlined std::ptr::from_raw_parts::<[u8]>) {
|
||||
debug data_pointer => _6;
|
||||
debug metadata => _5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_4);
|
||||
StorageLive(_2);
|
||||
_2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
|
||||
StorageLive(_3);
|
||||
_3 = ((((*_1).0: alloc::raw_vec::RawVec<u8>).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
|
||||
_4 = (_3.0: *const u8);
|
||||
StorageDead(_3);
|
||||
StorageDead(_2);
|
||||
StorageLive(_5);
|
||||
_5 = ((*_1).1: usize);
|
||||
StorageLive(_6);
|
||||
_6 = _4 as *const () (PtrToPtr);
|
||||
_7 = *const [u8] from (_6, _5);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
_0 = &(*_7);
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
// MIR for `vec_deref_to_slice` after PreCodegen
|
||||
|
||||
fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
|
||||
debug v => _1;
|
||||
let mut _0: &[u8];
|
||||
scope 1 (inlined <Vec<u8> as Deref>::deref) {
|
||||
debug self => _1;
|
||||
let mut _4: *const u8;
|
||||
let mut _5: usize;
|
||||
scope 2 (inlined Vec::<u8>::as_ptr) {
|
||||
debug self => _1;
|
||||
let mut _2: &alloc::raw_vec::RawVec<u8>;
|
||||
scope 3 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
|
||||
debug self => _2;
|
||||
let mut _3: std::ptr::NonNull<u8>;
|
||||
scope 4 (inlined Unique::<u8>::as_ptr) {
|
||||
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _3;
|
||||
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
|
||||
scope 5 (inlined NonNull::<u8>::as_ptr) {
|
||||
debug self => _3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 6 (inlined std::slice::from_raw_parts::<'_, u8>) {
|
||||
debug data => _4;
|
||||
debug len => _5;
|
||||
let _7: *const [u8];
|
||||
scope 7 (inlined core::ub_checks::check_language_ub) {
|
||||
scope 8 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
}
|
||||
}
|
||||
scope 9 (inlined std::mem::size_of::<u8>) {
|
||||
}
|
||||
scope 10 (inlined align_of::<u8>) {
|
||||
}
|
||||
scope 11 (inlined slice_from_raw_parts::<u8>) {
|
||||
debug data => _4;
|
||||
debug len => _5;
|
||||
let mut _6: *const ();
|
||||
scope 12 (inlined std::ptr::const_ptr::<impl *const u8>::cast::<()>) {
|
||||
debug self => _4;
|
||||
}
|
||||
scope 13 (inlined std::ptr::from_raw_parts::<[u8]>) {
|
||||
debug data_pointer => _6;
|
||||
debug metadata => _5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_4);
|
||||
StorageLive(_2);
|
||||
_2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
|
||||
StorageLive(_3);
|
||||
_3 = ((((*_1).0: alloc::raw_vec::RawVec<u8>).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
|
||||
_4 = (_3.0: *const u8);
|
||||
StorageDead(_3);
|
||||
StorageDead(_2);
|
||||
StorageLive(_5);
|
||||
_5 = ((*_1).1: usize);
|
||||
StorageLive(_6);
|
||||
_6 = _4 as *const () (PtrToPtr);
|
||||
_7 = *const [u8] from (_6, _5);
|
||||
StorageDead(_6);
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
_0 = &(*_7);
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -851,7 +851,6 @@ compiler-team-contributors = [
|
|||
"@nnethercote",
|
||||
"@fmease",
|
||||
"@fee1-dead",
|
||||
"@BoxyUwU",
|
||||
"@jieyouxu",
|
||||
]
|
||||
compiler = [
|
||||
|
|
Loading…
Reference in New Issue