add write_box_via_move intrinsic and use it for vec!
This allows us to get rid of box_new entirely
This commit is contained in:
parent
93d45480aa
commit
5e65109f21
81 changed files with 1097 additions and 1400 deletions
|
|
@ -622,11 +622,6 @@ impl<T: ?Sized> Deref for Box<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "exchange_malloc"]
|
|
||||||
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
|
|
||||||
unsafe { libc::malloc(size) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[lang = "drop"]
|
#[lang = "drop"]
|
||||||
pub trait Drop {
|
pub trait Drop {
|
||||||
fn drop(&mut self);
|
fn drop(&mut self);
|
||||||
|
|
|
||||||
|
|
@ -628,11 +628,6 @@ impl<T: ?Sized, A: Allocator> Deref for Box<T, A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "exchange_malloc"]
|
|
||||||
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
|
|
||||||
libc::malloc(size)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[lang = "drop"]
|
#[lang = "drop"]
|
||||||
pub trait Drop {
|
pub trait Drop {
|
||||||
fn drop(&mut self);
|
fn drop(&mut self);
|
||||||
|
|
|
||||||
|
|
@ -845,13 +845,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This can be called on stable via the `vec!` macro.
|
|
||||||
if tcx.is_lang_item(callee, LangItem::ExchangeMalloc) {
|
|
||||||
self.check_op(ops::HeapAllocation);
|
|
||||||
// Allow this call, skip all the checks below.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Intrinsics are language primitives, not regular calls, so treat them separately.
|
// Intrinsics are language primitives, not regular calls, so treat them separately.
|
||||||
if let Some(intrinsic) = tcx.intrinsic(callee) {
|
if let Some(intrinsic) = tcx.intrinsic(callee) {
|
||||||
if !tcx.is_const_fn(callee) {
|
if !tcx.is_const_fn(callee) {
|
||||||
|
|
|
||||||
|
|
@ -540,18 +540,6 @@ impl<'tcx> NonConstOp<'tcx> for Coroutine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub(crate) struct HeapAllocation;
|
|
||||||
impl<'tcx> NonConstOp<'tcx> for HeapAllocation {
|
|
||||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
|
|
||||||
ccx.dcx().create_err(errors::UnallowedHeapAllocations {
|
|
||||||
span,
|
|
||||||
kind: ccx.const_kind(),
|
|
||||||
teach: ccx.tcx.sess.teach(E0010),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct InlineAsm;
|
pub(crate) struct InlineAsm;
|
||||||
impl<'tcx> NonConstOp<'tcx> for InlineAsm {
|
impl<'tcx> NonConstOp<'tcx> for InlineAsm {
|
||||||
|
|
|
||||||
|
|
@ -289,31 +289,6 @@ pub(crate) struct UnallowedOpInConstContext {
|
||||||
pub msg: String,
|
pub msg: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(r#"allocations are not allowed in {$kind ->
|
|
||||||
[const] constant
|
|
||||||
[static] static
|
|
||||||
[const_fn] constant function
|
|
||||||
*[other] {""}
|
|
||||||
}s"#, code = E0010)]
|
|
||||||
pub(crate) struct UnallowedHeapAllocations {
|
|
||||||
#[primary_span]
|
|
||||||
#[label(
|
|
||||||
r#"allocation not allowed in {$kind ->
|
|
||||||
[const] constant
|
|
||||||
[static] static
|
|
||||||
[const_fn] constant function
|
|
||||||
*[other] {""}
|
|
||||||
}s"#
|
|
||||||
)]
|
|
||||||
pub span: Span,
|
|
||||||
pub kind: ConstContext,
|
|
||||||
#[note(
|
|
||||||
"the runtime heap is not yet available at compile-time, so no runtime heap allocations can be created"
|
|
||||||
)]
|
|
||||||
pub teach: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(r#"inline assembly is not allowed in {$kind ->
|
#[diag(r#"inline assembly is not allowed in {$kind ->
|
||||||
[const] constant
|
[const] constant
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
|
#### Note: this error code is no longer emitted by the compiler.
|
||||||
|
|
||||||
The value of statics and constants must be known at compile time, and they live
|
The value of statics and constants must be known at compile time, and they live
|
||||||
for the entire lifetime of a program. Creating a boxed value allocates memory on
|
for the entire lifetime of a program. Creating a boxed value allocates memory on
|
||||||
the heap at runtime, and therefore cannot be done at compile time.
|
the heap at runtime, and therefore cannot be done at compile time.
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0010
|
```ignore (no longer emitted)
|
||||||
const CON : Vec<i32> = vec![1, 2, 3];
|
const CON : Vec<i32> = vec![1, 2, 3];
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@
|
||||||
//
|
//
|
||||||
// Do *not* remove entries from this list. Instead, just add a note to the corresponding markdown
|
// Do *not* remove entries from this list. Instead, just add a note to the corresponding markdown
|
||||||
// file saying that this error is not emitted by the compiler any more (see E0001.md for an
|
// file saying that this error is not emitted by the compiler any more (see E0001.md for an
|
||||||
// example), and remove all code examples that do not build any more.
|
// example), and remove all code examples that do not build any more by marking them
|
||||||
|
// with `ignore (no longer emitted)`.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
macro_rules! error_codes {
|
macro_rules! error_codes {
|
||||||
|
|
|
||||||
|
|
@ -320,7 +320,6 @@ language_item_table! {
|
||||||
FormatArgument, sym::format_argument, format_argument, Target::Struct, GenericRequirement::None;
|
FormatArgument, sym::format_argument, format_argument, Target::Struct, GenericRequirement::None;
|
||||||
FormatArguments, sym::format_arguments, format_arguments, Target::Struct, GenericRequirement::None;
|
FormatArguments, sym::format_arguments, format_arguments, Target::Struct, GenericRequirement::None;
|
||||||
|
|
||||||
ExchangeMalloc, sym::exchange_malloc, exchange_malloc_fn, Target::Fn, GenericRequirement::None;
|
|
||||||
DropInPlace, sym::drop_in_place, drop_in_place_fn, Target::Fn, GenericRequirement::Minimum(1);
|
DropInPlace, sym::drop_in_place, drop_in_place_fn, Target::Fn, GenericRequirement::Minimum(1);
|
||||||
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
|
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,6 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
|
||||||
| sym::autodiff
|
| sym::autodiff
|
||||||
| sym::bitreverse
|
| sym::bitreverse
|
||||||
| sym::black_box
|
| sym::black_box
|
||||||
| sym::box_new
|
|
||||||
| sym::breakpoint
|
| sym::breakpoint
|
||||||
| sym::bswap
|
| sym::bswap
|
||||||
| sym::caller_location
|
| sym::caller_location
|
||||||
|
|
@ -223,6 +222,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
|
||||||
| sym::wrapping_add
|
| sym::wrapping_add
|
||||||
| sym::wrapping_mul
|
| sym::wrapping_mul
|
||||||
| sym::wrapping_sub
|
| sym::wrapping_sub
|
||||||
|
| sym::write_box_via_move
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
=> hir::Safety::Safe,
|
=> hir::Safety::Safe,
|
||||||
_ => hir::Safety::Unsafe,
|
_ => hir::Safety::Unsafe,
|
||||||
|
|
@ -584,6 +584,13 @@ pub(crate) fn check_intrinsic_type(
|
||||||
sym::write_via_move => {
|
sym::write_via_move => {
|
||||||
(1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit)
|
(1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit)
|
||||||
}
|
}
|
||||||
|
sym::write_box_via_move => {
|
||||||
|
let t = param(0);
|
||||||
|
let maybe_uninit_t = Ty::new_maybe_uninit(tcx, t);
|
||||||
|
let box_mu_t = Ty::new_box(tcx, maybe_uninit_t);
|
||||||
|
|
||||||
|
(1, 0, vec![box_mu_t, param(0)], box_mu_t)
|
||||||
|
}
|
||||||
|
|
||||||
sym::typed_swap_nonoverlapping => {
|
sym::typed_swap_nonoverlapping => {
|
||||||
(1, 0, vec![Ty::new_mut_ptr(tcx, param(0)); 2], tcx.types.unit)
|
(1, 0, vec![Ty::new_mut_ptr(tcx, param(0)); 2], tcx.types.unit)
|
||||||
|
|
@ -689,8 +696,6 @@ pub(crate) fn check_intrinsic_type(
|
||||||
|
|
||||||
sym::ub_checks | sym::overflow_checks => (0, 0, Vec::new(), tcx.types.bool),
|
sym::ub_checks | sym::overflow_checks => (0, 0, Vec::new(), tcx.types.bool),
|
||||||
|
|
||||||
sym::box_new => (1, 0, vec![param(0)], Ty::new_box(tcx, param(0))),
|
|
||||||
|
|
||||||
// contract_check_requires::<C>(C) -> bool, where C: impl Fn() -> bool
|
// contract_check_requires::<C>(C) -> bool, where C: impl Fn() -> bool
|
||||||
sym::contract_check_requires => (1, 0, vec![param(0)], tcx.types.unit),
|
sym::contract_check_requires => (1, 0, vec![param(0)], tcx.types.unit),
|
||||||
sym::contract_check_ensures => {
|
sym::contract_check_ensures => {
|
||||||
|
|
|
||||||
|
|
@ -3110,6 +3110,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
{
|
{
|
||||||
let deref_kind = if checked_ty.is_box() {
|
let deref_kind = if checked_ty.is_box() {
|
||||||
// detect Box::new(..)
|
// detect Box::new(..)
|
||||||
|
// FIXME: use `box_new` diagnostic item instead?
|
||||||
if let ExprKind::Call(box_new, [_]) = expr.kind
|
if let ExprKind::Call(box_new, [_]) = expr.kind
|
||||||
&& let ExprKind::Path(qpath) = &box_new.kind
|
&& let ExprKind::Path(qpath) = &box_new.kind
|
||||||
&& let Res::Def(DefKind::AssocFn, fn_id) =
|
&& let Res::Def(DefKind::AssocFn, fn_id) =
|
||||||
|
|
|
||||||
|
|
@ -268,10 +268,6 @@ pub enum ExprKind<'tcx> {
|
||||||
hir_id: HirId,
|
hir_id: HirId,
|
||||||
value: ExprId,
|
value: ExprId,
|
||||||
},
|
},
|
||||||
/// A `box <value>` expression.
|
|
||||||
Box {
|
|
||||||
value: ExprId,
|
|
||||||
},
|
|
||||||
/// An `if` expression.
|
/// An `if` expression.
|
||||||
If {
|
If {
|
||||||
if_then_scope: region::Scope,
|
if_then_scope: region::Scope,
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,6 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
|
||||||
let Expr { kind, ty: _, temp_scope_id: _, span: _ } = expr;
|
let Expr { kind, ty: _, temp_scope_id: _, span: _ } = expr;
|
||||||
match *kind {
|
match *kind {
|
||||||
Scope { value, region_scope: _, hir_id: _ } => visitor.visit_expr(&visitor.thir()[value]),
|
Scope { value, region_scope: _, hir_id: _ } => visitor.visit_expr(&visitor.thir()[value]),
|
||||||
Box { value } => visitor.visit_expr(&visitor.thir()[value]),
|
|
||||||
If { cond, then, else_opt, if_then_scope: _ } => {
|
If { cond, then, else_opt, if_then_scope: _ } => {
|
||||||
visitor.visit_expr(&visitor.thir()[cond]);
|
visitor.visit_expr(&visitor.thir()[cond]);
|
||||||
visitor.visit_expr(&visitor.thir()[then]);
|
visitor.visit_expr(&visitor.thir()[then]);
|
||||||
|
|
|
||||||
|
|
@ -552,7 +552,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
| ExprKind::Unary { .. }
|
| ExprKind::Unary { .. }
|
||||||
| ExprKind::Binary { .. }
|
| ExprKind::Binary { .. }
|
||||||
| ExprKind::LogicalOp { .. }
|
| ExprKind::LogicalOp { .. }
|
||||||
| ExprKind::Box { .. }
|
|
||||||
| ExprKind::Cast { .. }
|
| ExprKind::Cast { .. }
|
||||||
| ExprKind::Use { .. }
|
| ExprKind::Use { .. }
|
||||||
| ExprKind::NeverToAny { .. }
|
| ExprKind::NeverToAny { .. }
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
//! See docs in `build/expr/mod.rs`.
|
//! See docs in `build/expr/mod.rs`.
|
||||||
|
|
||||||
use rustc_abi::FieldIdx;
|
use rustc_abi::FieldIdx;
|
||||||
use rustc_hir::lang_items::LangItem;
|
|
||||||
use rustc_index::{Idx, IndexVec};
|
use rustc_index::{Idx, IndexVec};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::middle::region::{self, TempLifetime};
|
use rustc_middle::middle::region::{self, TempLifetime};
|
||||||
|
|
@ -124,65 +123,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
block.and(Rvalue::UnaryOp(op, arg))
|
block.and(Rvalue::UnaryOp(op, arg))
|
||||||
}
|
}
|
||||||
ExprKind::Box { value } => {
|
|
||||||
let value_ty = this.thir[value].ty;
|
|
||||||
let tcx = this.tcx;
|
|
||||||
let source_info = this.source_info(expr_span);
|
|
||||||
|
|
||||||
let size = tcx.require_lang_item(LangItem::SizeOf, expr_span);
|
|
||||||
let size = Operand::unevaluated_constant(tcx, size, &[value_ty.into()], expr_span);
|
|
||||||
|
|
||||||
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(
|
|
||||||
tcx,
|
|
||||||
tcx.require_lang_item(LangItem::ExchangeMalloc, expr_span),
|
|
||||||
[],
|
|
||||||
expr_span,
|
|
||||||
);
|
|
||||||
let storage = this.temp(Ty::new_mut_ptr(tcx, tcx.types.u8), expr_span);
|
|
||||||
let success = this.cfg.start_new_block();
|
|
||||||
this.cfg.terminate(
|
|
||||||
block,
|
|
||||||
source_info,
|
|
||||||
TerminatorKind::Call {
|
|
||||||
func: exchange_malloc,
|
|
||||||
args: [
|
|
||||||
Spanned { node: size, span: DUMMY_SP },
|
|
||||||
Spanned { node: align, span: DUMMY_SP },
|
|
||||||
]
|
|
||||||
.into(),
|
|
||||||
destination: storage,
|
|
||||||
target: Some(success),
|
|
||||||
unwind: UnwindAction::Continue,
|
|
||||||
call_source: CallSource::Misc,
|
|
||||||
fn_span: expr_span,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
this.diverge_from(block);
|
|
||||||
block = success;
|
|
||||||
|
|
||||||
let result = this.local_decls.push(LocalDecl::new(expr.ty, expr_span));
|
|
||||||
this.cfg
|
|
||||||
.push(block, Statement::new(source_info, StatementKind::StorageLive(result)));
|
|
||||||
if let Some(scope) = scope.temp_lifetime {
|
|
||||||
// schedule a shallow free of that memory, lest we unwind:
|
|
||||||
this.schedule_drop_storage_and_value(expr_span, scope, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transmute `*mut u8` to the box (thus far, uninitialized):
|
|
||||||
let box_ = Rvalue::ShallowInitBox(Operand::Move(storage), value_ty);
|
|
||||||
this.cfg.push_assign(block, source_info, Place::from(result), box_);
|
|
||||||
|
|
||||||
// initialize the box contents:
|
|
||||||
block = this
|
|
||||||
.expr_into_dest(this.tcx.mk_place_deref(Place::from(result)), block, value)
|
|
||||||
.into_block();
|
|
||||||
block.and(Rvalue::Use(Operand::Move(Place::from(result))))
|
|
||||||
}
|
|
||||||
ExprKind::Cast { source } => {
|
ExprKind::Cast { source } => {
|
||||||
let source_expr = &this.thir[source];
|
let source_expr = &this.thir[source];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,6 @@ impl Category {
|
||||||
| ExprKind::Closure { .. }
|
| ExprKind::Closure { .. }
|
||||||
| ExprKind::Unary { .. }
|
| ExprKind::Unary { .. }
|
||||||
| ExprKind::Binary { .. }
|
| ExprKind::Binary { .. }
|
||||||
| ExprKind::Box { .. }
|
|
||||||
| ExprKind::Cast { .. }
|
| ExprKind::Cast { .. }
|
||||||
| ExprKind::PointerCoercion { .. }
|
| ExprKind::PointerCoercion { .. }
|
||||||
| ExprKind::Repeat { .. }
|
| ExprKind::Repeat { .. }
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
//! See docs in build/expr/mod.rs
|
//! See docs in build/expr/mod.rs
|
||||||
|
|
||||||
|
use rustc_abi::FieldIdx;
|
||||||
use rustc_ast::{AsmMacro, InlineAsmOptions};
|
use rustc_ast::{AsmMacro, InlineAsmOptions};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
|
|
@ -366,30 +367,96 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// The `write_via_move` intrinsic needs to be special-cased very early to avoid
|
// Some intrinsics are handled here because they desperately want to avoid introducing
|
||||||
// introducing unnecessary copies that can be hard to remove again later:
|
// unnecessary copies.
|
||||||
// `write_via_move(ptr, val)` becomes `*ptr = val` but without any dropping.
|
|
||||||
ExprKind::Call { ty, fun, ref args, .. }
|
ExprKind::Call { ty, fun, ref args, .. }
|
||||||
if let ty::FnDef(def_id, _generic_args) = ty.kind()
|
if let ty::FnDef(def_id, generic_args) = ty.kind()
|
||||||
&& let Some(intrinsic) = this.tcx.intrinsic(def_id)
|
&& let Some(intrinsic) = this.tcx.intrinsic(def_id)
|
||||||
&& intrinsic.name == sym::write_via_move =>
|
&& matches!(intrinsic.name, sym::write_via_move | sym::write_box_via_move) =>
|
||||||
{
|
{
|
||||||
// We still have to evaluate the callee expression as normal (but we don't care
|
// We still have to evaluate the callee expression as normal (but we don't care
|
||||||
// about its result).
|
// about its result).
|
||||||
let _fun = unpack!(block = this.as_local_operand(block, fun));
|
let _fun = unpack!(block = this.as_local_operand(block, fun));
|
||||||
// The destination must have unit type (so we don't actually have to store anything
|
|
||||||
// into it).
|
|
||||||
assert!(destination.ty(&this.local_decls, this.tcx).ty.is_unit());
|
|
||||||
|
|
||||||
// Compile this to an assignment of the argument into the destination.
|
match intrinsic.name {
|
||||||
let [ptr, val] = **args else {
|
sym::write_via_move => {
|
||||||
span_bug!(expr_span, "invalid write_via_move call")
|
// `write_via_move(ptr, val)` becomes `*ptr = val` but without any dropping.
|
||||||
};
|
|
||||||
let Some(ptr) = unpack!(block = this.as_local_operand(block, ptr)).place() else {
|
// The destination must have unit type (so we don't actually have to store anything
|
||||||
span_bug!(expr_span, "invalid write_via_move call")
|
// into it).
|
||||||
};
|
assert!(destination.ty(&this.local_decls, this.tcx).ty.is_unit());
|
||||||
let ptr_deref = ptr.project_deeper(&[ProjectionElem::Deref], this.tcx);
|
|
||||||
this.expr_into_dest(ptr_deref, block, val)
|
// Compile this to an assignment of the argument into the destination.
|
||||||
|
let [ptr, val] = **args else {
|
||||||
|
span_bug!(expr_span, "invalid write_via_move call")
|
||||||
|
};
|
||||||
|
let Some(ptr) = unpack!(block = this.as_local_operand(block, ptr)).place()
|
||||||
|
else {
|
||||||
|
span_bug!(expr_span, "invalid write_via_move call")
|
||||||
|
};
|
||||||
|
let ptr_deref = ptr.project_deeper(&[ProjectionElem::Deref], this.tcx);
|
||||||
|
this.expr_into_dest(ptr_deref, block, val)
|
||||||
|
}
|
||||||
|
sym::write_box_via_move => {
|
||||||
|
// The signature is:
|
||||||
|
// `fn write_box_via_move<T>(b: Box<MaybeUninit<T>>, val: T) -> Box<MaybeUninit<T>>`.
|
||||||
|
// `write_box_via_move(b, val)` becomes
|
||||||
|
// ```
|
||||||
|
// (*b).value.value.value = val;
|
||||||
|
// b
|
||||||
|
// ```
|
||||||
|
// One crucial aspect of this lowering is that the generated code must
|
||||||
|
// cause the borrow checker to enforce that `val` lives sufficiently
|
||||||
|
// long to be stored in `b`. The above lowering does this; anything that
|
||||||
|
// involves a `*const T` or a `NonNull<T>` does not as those are covariant.
|
||||||
|
let tcx = this.tcx;
|
||||||
|
|
||||||
|
// Extract the operands, compile `b`.
|
||||||
|
let [b, val] = **args else {
|
||||||
|
span_bug!(expr_span, "invalid init_box_via_move call")
|
||||||
|
};
|
||||||
|
let Some(b) = unpack!(block = this.as_local_operand(block, b)).place()
|
||||||
|
else {
|
||||||
|
span_bug!(expr_span, "invalid init_box_via_move call")
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper to project to a field of an ADT.
|
||||||
|
let place_project_field = |place: Place<'tcx>, idx: FieldIdx| {
|
||||||
|
let ty = place.ty(&this.local_decls, tcx).ty;
|
||||||
|
let ty::Adt(adt, args) = ty.kind() else {
|
||||||
|
panic!("projecting to field of non-ADT {ty}")
|
||||||
|
};
|
||||||
|
let field = &adt.non_enum_variant().fields[idx];
|
||||||
|
let field_ty = field.ty(tcx, args);
|
||||||
|
place.project_deeper(&[ProjectionElem::Field(idx, field_ty)], tcx)
|
||||||
|
};
|
||||||
|
|
||||||
|
// `b` is a `Box<MaybeUninit<T>>`.
|
||||||
|
let place = b.project_deeper(&[ProjectionElem::Deref], tcx);
|
||||||
|
// Current type: `MaybeUninit<T>`. Field #1 is `ManuallyDrop<T>`.
|
||||||
|
let place = place_project_field(place, FieldIdx::from_u32(1));
|
||||||
|
// Current type: `ManuallyDrop<T>`. Field #0 is `MaybeDangling<T>`.
|
||||||
|
let place = place_project_field(place, FieldIdx::ZERO);
|
||||||
|
// Current type: `MaybeDangling<T>`. Field #0 is `T`.
|
||||||
|
let place = place_project_field(place, FieldIdx::ZERO);
|
||||||
|
// Sanity check.
|
||||||
|
assert_eq!(place.ty(&this.local_decls, tcx).ty, generic_args.type_at(0));
|
||||||
|
|
||||||
|
// Store `val` into place.
|
||||||
|
unpack!(block = this.expr_into_dest(place, block, val));
|
||||||
|
|
||||||
|
// Return `b`
|
||||||
|
this.cfg.push_assign(
|
||||||
|
block,
|
||||||
|
source_info,
|
||||||
|
destination,
|
||||||
|
// Move from `b` so that does not get dropped any more.
|
||||||
|
Rvalue::Use(Operand::Move(b)),
|
||||||
|
);
|
||||||
|
block.unit()
|
||||||
|
}
|
||||||
|
_ => rustc_middle::bug!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Call { ty: _, fun, ref args, from_hir_call, fn_span } => {
|
ExprKind::Call { ty: _, fun, ref args, from_hir_call, fn_span } => {
|
||||||
let fun = unpack!(block = this.as_local_operand(block, fun));
|
let fun = unpack!(block = this.as_local_operand(block, fun));
|
||||||
|
|
@ -795,7 +862,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
// these are the cases that are more naturally handled by some other mode
|
// these are the cases that are more naturally handled by some other mode
|
||||||
ExprKind::Unary { .. }
|
ExprKind::Unary { .. }
|
||||||
| ExprKind::Binary { .. }
|
| ExprKind::Binary { .. }
|
||||||
| ExprKind::Box { .. }
|
|
||||||
| ExprKind::Cast { .. }
|
| ExprKind::Cast { .. }
|
||||||
| ExprKind::PointerCoercion { .. }
|
| ExprKind::PointerCoercion { .. }
|
||||||
| ExprKind::Repeat { .. }
|
| ExprKind::Repeat { .. }
|
||||||
|
|
|
||||||
|
|
@ -449,7 +449,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
||||||
| ExprKind::LoopMatch { .. }
|
| ExprKind::LoopMatch { .. }
|
||||||
| ExprKind::Let { .. }
|
| ExprKind::Let { .. }
|
||||||
| ExprKind::Match { .. }
|
| ExprKind::Match { .. }
|
||||||
| ExprKind::Box { .. }
|
|
||||||
| ExprKind::If { .. }
|
| ExprKind::If { .. }
|
||||||
| ExprKind::InlineAsm { .. }
|
| ExprKind::InlineAsm { .. }
|
||||||
| ExprKind::LogicalOp { .. }
|
| ExprKind::LogicalOp { .. }
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ use rustc_middle::ty::{
|
||||||
self, AdtKind, GenericArgs, InlineConstArgs, InlineConstArgsParts, ScalarInt, Ty, UpvarArgs,
|
self, AdtKind, GenericArgs, InlineConstArgs, InlineConstArgsParts, ScalarInt, Ty, UpvarArgs,
|
||||||
};
|
};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_span::{Span, sym};
|
use rustc_span::Span;
|
||||||
use tracing::{debug, info, instrument, trace};
|
use tracing::{debug, info, instrument, trace};
|
||||||
|
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
|
|
@ -385,24 +385,6 @@ impl<'tcx> ThirBuildCx<'tcx> {
|
||||||
from_hir_call: true,
|
from_hir_call: true,
|
||||||
fn_span: expr.span,
|
fn_span: expr.span,
|
||||||
}
|
}
|
||||||
} else if let ty::FnDef(def_id, _) = self.typeck_results.expr_ty(fun).kind()
|
|
||||||
&& let Some(intrinsic) = self.tcx.intrinsic(def_id)
|
|
||||||
&& intrinsic.name == sym::box_new
|
|
||||||
{
|
|
||||||
// We don't actually evaluate `fun` here, so make sure that doesn't miss any side-effects.
|
|
||||||
if !matches!(fun.kind, hir::ExprKind::Path(_)) {
|
|
||||||
span_bug!(
|
|
||||||
expr.span,
|
|
||||||
"`box_new` intrinsic can only be called via path expression"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let value = &args[0];
|
|
||||||
return Expr {
|
|
||||||
temp_scope_id: expr.hir_id.local_id,
|
|
||||||
ty: expr_ty,
|
|
||||||
span: expr.span,
|
|
||||||
kind: ExprKind::Box { value: self.mirror_expr(value) },
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
// Tuple-like ADTs are represented as ExprKind::Call. We convert them here.
|
// Tuple-like ADTs are represented as ExprKind::Call. We convert them here.
|
||||||
let adt_data = if let hir::ExprKind::Path(ref qpath) = fun.kind
|
let adt_data = if let hir::ExprKind::Path(ref qpath) = fun.kind
|
||||||
|
|
|
||||||
|
|
@ -342,7 +342,6 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
|
||||||
| Binary { .. }
|
| Binary { .. }
|
||||||
| Block { .. }
|
| Block { .. }
|
||||||
| Borrow { .. }
|
| Borrow { .. }
|
||||||
| Box { .. }
|
|
||||||
| Call { .. }
|
| Call { .. }
|
||||||
| ByUse { .. }
|
| ByUse { .. }
|
||||||
| Closure { .. }
|
| Closure { .. }
|
||||||
|
|
|
||||||
|
|
@ -223,11 +223,6 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
|
||||||
self.print_expr(*value, depth_lvl + 2);
|
self.print_expr(*value, depth_lvl + 2);
|
||||||
print_indented!(self, "}", depth_lvl);
|
print_indented!(self, "}", depth_lvl);
|
||||||
}
|
}
|
||||||
Box { value } => {
|
|
||||||
print_indented!(self, "Box {", depth_lvl);
|
|
||||||
self.print_expr(*value, depth_lvl + 1);
|
|
||||||
print_indented!(self, "}", depth_lvl);
|
|
||||||
}
|
|
||||||
If { if_then_scope, cond, then, else_opt } => {
|
If { if_then_scope, cond, then, else_opt } => {
|
||||||
print_indented!(self, "If {", depth_lvl);
|
print_indented!(self, "If {", depth_lvl);
|
||||||
print_indented!(self, format!("if_then_scope: {:?}", if_then_scope), depth_lvl + 1);
|
print_indented!(self, format!("if_then_scope: {:?}", if_then_scope), depth_lvl + 1);
|
||||||
|
|
|
||||||
|
|
@ -990,7 +990,6 @@ symbols! {
|
||||||
exact_div,
|
exact_div,
|
||||||
except,
|
except,
|
||||||
exception_handling: "exception-handling",
|
exception_handling: "exception-handling",
|
||||||
exchange_malloc,
|
|
||||||
exclusive_range_pattern,
|
exclusive_range_pattern,
|
||||||
exhaustive_integer_patterns,
|
exhaustive_integer_patterns,
|
||||||
exhaustive_patterns,
|
exhaustive_patterns,
|
||||||
|
|
@ -2541,6 +2540,7 @@ symbols! {
|
||||||
wrapping_rem_euclid,
|
wrapping_rem_euclid,
|
||||||
wrapping_sub,
|
wrapping_sub,
|
||||||
wreg,
|
wreg,
|
||||||
|
write_box_via_move,
|
||||||
write_bytes,
|
write_bytes,
|
||||||
write_fmt,
|
write_fmt,
|
||||||
write_macro,
|
write_macro,
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,6 @@ fn recurse_build<'tcx>(
|
||||||
| ExprKind::LoopMatch { .. } => {
|
| ExprKind::LoopMatch { .. } => {
|
||||||
error(GenericConstantTooComplexSub::LoopNotSupported(node.span))?
|
error(GenericConstantTooComplexSub::LoopNotSupported(node.span))?
|
||||||
}
|
}
|
||||||
ExprKind::Box { .. } => error(GenericConstantTooComplexSub::BoxNotSupported(node.span))?,
|
|
||||||
ExprKind::ByUse { .. } => {
|
ExprKind::ByUse { .. } => {
|
||||||
error(GenericConstantTooComplexSub::ByUseNotSupported(node.span))?
|
error(GenericConstantTooComplexSub::ByUseNotSupported(node.span))?
|
||||||
}
|
}
|
||||||
|
|
@ -260,7 +259,6 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> {
|
||||||
count.has_non_region_param()
|
count.has_non_region_param()
|
||||||
}
|
}
|
||||||
thir::ExprKind::Scope { .. }
|
thir::ExprKind::Scope { .. }
|
||||||
| thir::ExprKind::Box { .. }
|
|
||||||
| thir::ExprKind::If { .. }
|
| thir::ExprKind::If { .. }
|
||||||
| thir::ExprKind::Call { .. }
|
| thir::ExprKind::Call { .. }
|
||||||
| thir::ExprKind::ByUse { .. }
|
| thir::ExprKind::ByUse { .. }
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,6 @@ pub(crate) enum GenericConstantTooComplexSub {
|
||||||
YieldNotSupported(#[primary_span] Span),
|
YieldNotSupported(#[primary_span] Span),
|
||||||
#[label("loops and loop control flow are not supported in generic constants")]
|
#[label("loops and loop control flow are not supported in generic constants")]
|
||||||
LoopNotSupported(#[primary_span] Span),
|
LoopNotSupported(#[primary_span] Span),
|
||||||
#[label("allocations are not allowed in generic constants")]
|
|
||||||
BoxNotSupported(#[primary_span] Span),
|
|
||||||
#[label("unsupported binary operation in generic constants")]
|
#[label("unsupported binary operation in generic constants")]
|
||||||
BinaryNotSupported(#[primary_span] Span),
|
BinaryNotSupported(#[primary_span] Span),
|
||||||
#[label(".use is not allowed in generic constants")]
|
#[label(".use is not allowed in generic constants")]
|
||||||
|
|
|
||||||
|
|
@ -479,23 +479,6 @@ unsafe impl const Allocator for Global {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The allocator for `Box`.
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// `size` and `align` must satisfy the conditions in [`Layout::from_size_align`].
|
|
||||||
#[cfg(not(no_global_oom_handling))]
|
|
||||||
#[lang = "exchange_malloc"]
|
|
||||||
#[inline]
|
|
||||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
|
||||||
pub(crate) unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
|
|
||||||
let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
|
|
||||||
match Global.allocate(layout) {
|
|
||||||
Ok(ptr) => ptr.as_mut_ptr(),
|
|
||||||
Err(_) => handle_alloc_error(layout),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// # Allocation error handler
|
// # Allocation error handler
|
||||||
|
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,7 @@ use core::task::{Context, Poll};
|
||||||
|
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
use crate::alloc::handle_alloc_error;
|
use crate::alloc::handle_alloc_error;
|
||||||
use crate::alloc::{AllocError, Allocator, Global, Layout, exchange_malloc};
|
use crate::alloc::{AllocError, Allocator, Global, Layout};
|
||||||
use crate::raw_vec::RawVec;
|
use crate::raw_vec::RawVec;
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
use crate::str::from_boxed_utf8_unchecked;
|
use crate::str::from_boxed_utf8_unchecked;
|
||||||
|
|
@ -236,14 +236,34 @@ pub struct Box<
|
||||||
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
|
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
|
||||||
>(Unique<T>, A);
|
>(Unique<T>, A);
|
||||||
|
|
||||||
/// Constructs a `Box<T>` by calling the `exchange_malloc` lang item and moving the argument into
|
/// Monomorphic function for allocating an uninit `Box`.
|
||||||
/// the newly allocated memory. This is an intrinsic to avoid unnecessary copies.
|
|
||||||
///
|
///
|
||||||
/// This is the surface syntax for `box <expr>` expressions.
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// size and align need to be safe for `Layout::from_size_align_unchecked`.
|
||||||
|
#[inline]
|
||||||
|
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
|
unsafe fn box_new_uninit(size: usize, align: usize) -> *mut u8 {
|
||||||
|
let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
|
||||||
|
match Global.allocate(layout) {
|
||||||
|
Ok(ptr) => ptr.as_mut_ptr(),
|
||||||
|
Err(_) => handle_alloc_error(layout),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper for `vec!`.
|
||||||
|
///
|
||||||
|
/// This is unsafe, but has to be marked as safe or else we couldn't use it in `vec!`.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[rustc_intrinsic]
|
|
||||||
#[unstable(feature = "liballoc_internals", issue = "none")]
|
#[unstable(feature = "liballoc_internals", issue = "none")]
|
||||||
pub fn box_new<T>(x: T) -> Box<T>;
|
#[inline(always)]
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
|
pub fn box_assume_init_into_vec_unsafe<T, const N: usize>(
|
||||||
|
b: Box<MaybeUninit<[T; N]>>,
|
||||||
|
) -> crate::vec::Vec<T> {
|
||||||
|
unsafe { (b.assume_init() as Box<[T]>).into_vec() }
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Box<T> {
|
impl<T> Box<T> {
|
||||||
/// Allocates memory on the heap and then places `x` into it.
|
/// Allocates memory on the heap and then places `x` into it.
|
||||||
|
|
@ -262,9 +282,10 @@ impl<T> Box<T> {
|
||||||
#[rustc_diagnostic_item = "box_new"]
|
#[rustc_diagnostic_item = "box_new"]
|
||||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||||
pub fn new(x: T) -> Self {
|
pub fn new(x: T) -> Self {
|
||||||
// SAFETY: the size and align of a valid type `T` are always valid for `Layout`.
|
// This is `Box::new_uninit` but inlined to avoid build time regressions.
|
||||||
|
// SAFETY: The size and align of a valid type `T` are always valid for `Layout`.
|
||||||
let ptr = unsafe {
|
let ptr = unsafe {
|
||||||
exchange_malloc(<T as SizedTypeProperties>::SIZE, <T as SizedTypeProperties>::ALIGN)
|
box_new_uninit(<T as SizedTypeProperties>::SIZE, <T as SizedTypeProperties>::ALIGN)
|
||||||
} as *mut T;
|
} as *mut T;
|
||||||
// Nothing below can panic so we do not have to worry about deallocating `ptr`.
|
// Nothing below can panic so we do not have to worry about deallocating `ptr`.
|
||||||
// SAFETY: we just allocated the box to store `x`.
|
// SAFETY: we just allocated the box to store `x`.
|
||||||
|
|
@ -288,9 +309,21 @@ impl<T> Box<T> {
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
#[stable(feature = "new_uninit", since = "1.82.0")]
|
#[stable(feature = "new_uninit", since = "1.82.0")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline]
|
#[inline(always)]
|
||||||
|
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||||
pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
|
pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
|
||||||
Self::new_uninit_in(Global)
|
// This is the same as `Self::new_uninit_in(Global)`, but manually inlined (just like
|
||||||
|
// `Box::new`).
|
||||||
|
|
||||||
|
// SAFETY:
|
||||||
|
// - The size and align of a valid type `T` are always valid for `Layout`.
|
||||||
|
// - If `allocate` succeeds, the returned pointer exactly matches what `Box` needs.
|
||||||
|
unsafe {
|
||||||
|
mem::transmute(box_new_uninit(
|
||||||
|
<T as SizedTypeProperties>::SIZE,
|
||||||
|
<T as SizedTypeProperties>::ALIGN,
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new `Box` with uninitialized contents, with the memory
|
/// Constructs a new `Box` with uninitialized contents, with the memory
|
||||||
|
|
@ -1150,10 +1183,12 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
|
||||||
/// assert_eq!(*five, 5)
|
/// assert_eq!(*five, 5)
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "new_uninit", since = "1.82.0")]
|
#[stable(feature = "new_uninit", since = "1.82.0")]
|
||||||
#[inline]
|
#[inline(always)]
|
||||||
pub unsafe fn assume_init(self) -> Box<T, A> {
|
pub unsafe fn assume_init(self) -> Box<T, A> {
|
||||||
let (raw, alloc) = Box::into_raw_with_allocator(self);
|
// This is used in the `vec!` macro, so we optimize for minimal IR generation
|
||||||
unsafe { Box::from_raw_in(raw as *mut T, alloc) }
|
// even in debug builds.
|
||||||
|
// SAFETY: `Box<T>` and `Box<MaybeUninit<T>>` have the same layout.
|
||||||
|
unsafe { core::intrinsics::transmute_unchecked(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes the value and converts to `Box<T, A>`.
|
/// Writes the value and converts to `Box<T, A>`.
|
||||||
|
|
|
||||||
15
library/alloc/src/intrinsics.rs
Normal file
15
library/alloc/src/intrinsics.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
//! Intrinsics that cannot be moved to `core` because they depend on `alloc` types.
|
||||||
|
#![unstable(feature = "liballoc_internals", issue = "none")]
|
||||||
|
|
||||||
|
use core::mem::MaybeUninit;
|
||||||
|
|
||||||
|
use crate::boxed::Box;
|
||||||
|
|
||||||
|
/// Writes `x` into `b`.
|
||||||
|
///
|
||||||
|
/// This is needed for `vec!`, which can't afford any extra copies of the argument (or else debug
|
||||||
|
/// builds regress), has to be written fully as a call chain without `let` (or else this breaks inference
|
||||||
|
/// of e.g. unsizing coercions), and can't use an `unsafe` block as that would then also
|
||||||
|
/// include the user-provided `$x`.
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
pub fn write_box_via_move<T>(b: Box<MaybeUninit<T>>, x: T) -> Box<MaybeUninit<T>>;
|
||||||
|
|
@ -224,6 +224,7 @@ pub mod collections;
|
||||||
#[cfg(all(not(no_rc), not(no_sync), not(no_global_oom_handling)))]
|
#[cfg(all(not(no_rc), not(no_sync), not(no_global_oom_handling)))]
|
||||||
pub mod ffi;
|
pub mod ffi;
|
||||||
pub mod fmt;
|
pub mod fmt;
|
||||||
|
pub mod intrinsics;
|
||||||
#[cfg(not(no_rc))]
|
#[cfg(not(no_rc))]
|
||||||
pub mod rc;
|
pub mod rc;
|
||||||
pub mod slice;
|
pub mod slice;
|
||||||
|
|
|
||||||
|
|
@ -47,10 +47,16 @@ macro_rules! vec {
|
||||||
$crate::vec::from_elem($elem, $n)
|
$crate::vec::from_elem($elem, $n)
|
||||||
);
|
);
|
||||||
($($x:expr),+ $(,)?) => (
|
($($x:expr),+ $(,)?) => (
|
||||||
<[_]>::into_vec(
|
// Using `write_box_via_move` produces a dramatic improvement in stack usage for unoptimized
|
||||||
// Using the intrinsic produces a dramatic improvement in stack usage for
|
// programs using this code path to construct large Vecs. We can't use `write_via_move`
|
||||||
// unoptimized programs using this code path to construct large Vecs.
|
// because this entire invocation has to remain a call chain without `let` bindings, or else
|
||||||
$crate::boxed::box_new([$($x),+])
|
// inference and temporary lifetimes change and things break (see `vec-macro-rvalue-scope`,
|
||||||
|
// `vec-macro-coercions`, and `autoderef-vec-box-fn-36786` tests).
|
||||||
|
//
|
||||||
|
// `box_assume_init_into_vec_unsafe` isn't actually safe but the way we use it here is. We
|
||||||
|
// can't use an unsafe block as that would also wrap `$x`.
|
||||||
|
$crate::boxed::box_assume_init_into_vec_unsafe(
|
||||||
|
$crate::intrinsics::write_box_via_move($crate::boxed::Box::new_uninit(), [$($x),+])
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,24 @@ fn extract_if() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn vec_macro_cleanup() {
|
||||||
|
// Ensure memory gets deallocated when control flow leaves the `vec!` macro.
|
||||||
|
#[allow(unreachable_code)]
|
||||||
|
loop {
|
||||||
|
let _v = vec![Box::new(0), break];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn panic<T>() -> T {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
|
// Ensure all memory gets deallocated on a panic: the `Box` we construct, and the `Box`
|
||||||
|
// constructed inside `vec!` to eventually turn into a `Vec`.
|
||||||
|
std::panic::catch_unwind(|| {
|
||||||
|
let _v = vec![Box::new(0), panic()];
|
||||||
|
})
|
||||||
|
.unwrap_err();
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert_eq!(vec_reallocate().len(), 5);
|
assert_eq!(vec_reallocate().len(), 5);
|
||||||
|
|
||||||
|
|
@ -209,4 +227,5 @@ fn main() {
|
||||||
reverse();
|
reverse();
|
||||||
miri_issue_2759();
|
miri_issue_2759();
|
||||||
extract_if();
|
extract_if();
|
||||||
|
vec_macro_cleanup();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
5
src/tools/miri/tests/pass/vec.stack.stderr
Normal file
5
src/tools/miri/tests/pass/vec.stack.stderr
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
thread 'main' ($TID) panicked at tests/pass/vec.rs:LL:CC:
|
||||||
|
explicit panic
|
||||||
|
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||||
|
note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||||
5
src/tools/miri/tests/pass/vec.tree.stderr
Normal file
5
src/tools/miri/tests/pass/vec.tree.stderr
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
thread 'main' ($TID) panicked at tests/pass/vec.rs:LL:CC:
|
||||||
|
explicit panic
|
||||||
|
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||||
|
note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
|
||||||
|
|
@ -2450,7 +2450,6 @@ ui/single-use-lifetime/issue-107998.rs
|
||||||
ui/single-use-lifetime/issue-117965.rs
|
ui/single-use-lifetime/issue-117965.rs
|
||||||
ui/span/issue-107353.rs
|
ui/span/issue-107353.rs
|
||||||
ui/span/issue-11925.rs
|
ui/span/issue-11925.rs
|
||||||
ui/span/issue-15480.rs
|
|
||||||
ui/span/issue-23338-locals-die-before-temps-of-body.rs
|
ui/span/issue-23338-locals-die-before-temps-of-body.rs
|
||||||
ui/span/issue-23729.rs
|
ui/span/issue-23729.rs
|
||||||
ui/span/issue-23827.rs
|
ui/span/issue-23827.rs
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ pub fn foo2() -> Box<dyn TestTrait2> {
|
||||||
}
|
}
|
||||||
|
|
||||||
//~ MONO_ITEM fn <TestStruct2 as TestTrait2>::test_func2
|
//~ MONO_ITEM fn <TestStruct2 as TestTrait2>::test_func2
|
||||||
//~ MONO_ITEM fn alloc::alloc::exchange_malloc
|
|
||||||
//~ MONO_ITEM fn foo2
|
//~ MONO_ITEM fn foo2
|
||||||
//~ MONO_ITEM fn std::alloc::Global::alloc_impl_runtime
|
//~ MONO_ITEM fn std::alloc::Global::alloc_impl_runtime
|
||||||
//~ MONO_ITEM fn std::boxed::Box::<TestStruct2>::new
|
//~ MONO_ITEM fn std::boxed::Box::<TestStruct2>::new
|
||||||
|
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
||||||
- // MIR for `main` before ElaborateDrops
|
|
||||||
+ // MIR for `main` after ElaborateDrops
|
|
||||||
|
|
||||||
fn main() -> () {
|
|
||||||
let mut _0: ();
|
|
||||||
let _1: std::boxed::Box<S>;
|
|
||||||
let mut _2: *mut u8;
|
|
||||||
let mut _3: std::boxed::Box<S>;
|
|
||||||
let _4: ();
|
|
||||||
let mut _5: std::boxed::Box<S>;
|
|
||||||
+ let mut _6: &mut std::boxed::Box<S>;
|
|
||||||
+ let mut _7: ();
|
|
||||||
+ let mut _8: *const S;
|
|
||||||
scope 1 {
|
|
||||||
debug x => _1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb0: {
|
|
||||||
StorageLive(_1);
|
|
||||||
_2 = alloc::alloc::exchange_malloc(const <S as std::mem::SizedTypeProperties>::SIZE, const <S as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind continue];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb1: {
|
|
||||||
StorageLive(_3);
|
|
||||||
_3 = ShallowInitBox(move _2, S);
|
|
||||||
(*_3) = S::new() -> [return: bb2, unwind: bb8];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb2: {
|
|
||||||
_1 = move _3;
|
|
||||||
- drop(_3) -> [return: bb3, unwind continue];
|
|
||||||
+ goto -> bb3;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb3: {
|
|
||||||
StorageDead(_3);
|
|
||||||
StorageLive(_4);
|
|
||||||
StorageLive(_5);
|
|
||||||
_5 = move _1;
|
|
||||||
_4 = std::mem::drop::<Box<S>>(move _5) -> [return: bb4, unwind: bb6];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb4: {
|
|
||||||
StorageDead(_5);
|
|
||||||
StorageDead(_4);
|
|
||||||
_0 = const ();
|
|
||||||
- drop(_1) -> [return: bb5, unwind continue];
|
|
||||||
+ goto -> bb5;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb5: {
|
|
||||||
StorageDead(_1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb6 (cleanup): {
|
|
||||||
- drop(_5) -> [return: bb7, unwind terminate(cleanup)];
|
|
||||||
+ goto -> bb7;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb7 (cleanup): {
|
|
||||||
- drop(_1) -> [return: bb9, unwind terminate(cleanup)];
|
|
||||||
+ goto -> bb9;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb8 (cleanup): {
|
|
||||||
- drop(_3) -> [return: bb9, unwind terminate(cleanup)];
|
|
||||||
+ goto -> bb12;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb9 (cleanup): {
|
|
||||||
resume;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ bb10 (cleanup): {
|
|
||||||
+ _6 = &mut _3;
|
|
||||||
+ _7 = <Box<S> as Drop>::drop(move _6) -> [return: bb9, unwind terminate(cleanup)];
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ bb11 (cleanup): {
|
|
||||||
+ goto -> bb10;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ bb12 (cleanup): {
|
|
||||||
+ _8 = copy ((_3.0: std::ptr::Unique<S>).0: std::ptr::NonNull<S>) as *const S (Transmute);
|
|
||||||
+ goto -> bb11;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
//@ test-mir-pass: ElaborateDrops
|
|
||||||
//@ needs-unwind
|
|
||||||
|
|
||||||
#![feature(rustc_attrs, liballoc_internals)]
|
|
||||||
|
|
||||||
// EMIT_MIR box_expr.main.ElaborateDrops.diff
|
|
||||||
fn main() {
|
|
||||||
// CHECK-LABEL: fn main(
|
|
||||||
// CHECK: [[ptr:_.*]] = move {{_.*}} as *const S (Transmute);
|
|
||||||
// CHECK: [[nonnull:_.*]] = NonNull::<S> { pointer: move [[ptr]] };
|
|
||||||
// CHECK: [[unique:_.*]] = std::ptr::Unique::<S> { pointer: move [[nonnull]], _marker: const PhantomData::<S> };
|
|
||||||
// CHECK: [[box:_.*]] = Box::<S>(move [[unique]], const std::alloc::Global);
|
|
||||||
// CHECK: [[ptr:_.*]] = copy (([[box]].0: std::ptr::Unique<S>).0: std::ptr::NonNull<S>) as *const S (Transmute);
|
|
||||||
// CHECK: (*[[ptr]]) = S::new() -> [return: [[ret:bb.*]], unwind: [[unwind:bb.*]]];
|
|
||||||
// CHECK: [[ret]]: {
|
|
||||||
// CHECK: [[box2:_.*]] = move [[box]];
|
|
||||||
// CHECK: [[box3:_.*]] = move [[box2]];
|
|
||||||
// CHECK: std::mem::drop::<Box<S>>(move [[box3]])
|
|
||||||
// CHECK: [[unwind]] (cleanup): {
|
|
||||||
// CHECK: [[boxref:_.*]] = &mut [[box]];
|
|
||||||
// CHECK: <Box<S> as Drop>::drop(move [[boxref]])
|
|
||||||
|
|
||||||
let x = std::boxed::box_new(S::new());
|
|
||||||
drop(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct S;
|
|
||||||
|
|
||||||
impl S {
|
|
||||||
fn new() -> Self {
|
|
||||||
S
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for S {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
println!("splat!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
// MIR for `move_out_by_subslice` after CleanupPostBorrowck
|
||||||
|
|
||||||
|
fn move_out_by_subslice() -> () {
|
||||||
|
let mut _0: ();
|
||||||
|
let _1: [std::boxed::Box<i32>; 2];
|
||||||
|
let mut _2: std::boxed::Box<i32>;
|
||||||
|
let mut _3: std::boxed::Box<i32>;
|
||||||
|
scope 1 {
|
||||||
|
debug a => _1;
|
||||||
|
let _4: [std::boxed::Box<i32>; 2];
|
||||||
|
scope 2 {
|
||||||
|
debug _y => _4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bb0: {
|
||||||
|
StorageLive(_1);
|
||||||
|
StorageLive(_2);
|
||||||
|
_2 = Box::<i32>::new(const 1_i32) -> [return: bb1, unwind: bb9];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb1: {
|
||||||
|
StorageLive(_3);
|
||||||
|
_3 = Box::<i32>::new(const 2_i32) -> [return: bb2, unwind: bb8];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb2: {
|
||||||
|
_1 = [move _2, move _3];
|
||||||
|
drop(_3) -> [return: bb3, unwind: bb8];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb3: {
|
||||||
|
StorageDead(_3);
|
||||||
|
drop(_2) -> [return: bb4, unwind: bb9];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb4: {
|
||||||
|
StorageDead(_2);
|
||||||
|
nop;
|
||||||
|
PlaceMention(_1);
|
||||||
|
StorageLive(_4);
|
||||||
|
_4 = move _1[0..2];
|
||||||
|
_0 = const ();
|
||||||
|
drop(_4) -> [return: bb5, unwind: bb7];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb5: {
|
||||||
|
StorageDead(_4);
|
||||||
|
drop(_1) -> [return: bb6, unwind: bb9];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb6: {
|
||||||
|
StorageDead(_1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb7 (cleanup): {
|
||||||
|
drop(_1) -> [return: bb9, unwind terminate(cleanup)];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb8 (cleanup): {
|
||||||
|
drop(_2) -> [return: bb9, unwind terminate(cleanup)];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb9 (cleanup): {
|
||||||
|
resume;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
// MIR for `move_out_by_subslice` after built
|
|
||||||
|
|
||||||
fn move_out_by_subslice() -> () {
|
|
||||||
let mut _0: ();
|
|
||||||
let _1: [std::boxed::Box<i32>; 2];
|
|
||||||
let mut _2: std::boxed::Box<i32>;
|
|
||||||
let mut _3: *mut u8;
|
|
||||||
let mut _4: std::boxed::Box<i32>;
|
|
||||||
let mut _5: std::boxed::Box<i32>;
|
|
||||||
let mut _6: *mut u8;
|
|
||||||
let mut _7: std::boxed::Box<i32>;
|
|
||||||
scope 1 {
|
|
||||||
debug a => _1;
|
|
||||||
let _8: [std::boxed::Box<i32>; 2];
|
|
||||||
scope 2 {
|
|
||||||
debug _y => _8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bb0: {
|
|
||||||
StorageLive(_1);
|
|
||||||
StorageLive(_2);
|
|
||||||
_3 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind: bb13];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb1: {
|
|
||||||
StorageLive(_4);
|
|
||||||
_4 = ShallowInitBox(move _3, i32);
|
|
||||||
(*_4) = const 1_i32;
|
|
||||||
_2 = move _4;
|
|
||||||
drop(_4) -> [return: bb2, unwind: bb12];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb2: {
|
|
||||||
StorageDead(_4);
|
|
||||||
StorageLive(_5);
|
|
||||||
_6 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb3, unwind: bb12];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb3: {
|
|
||||||
StorageLive(_7);
|
|
||||||
_7 = ShallowInitBox(move _6, i32);
|
|
||||||
(*_7) = const 2_i32;
|
|
||||||
_5 = move _7;
|
|
||||||
drop(_7) -> [return: bb4, unwind: bb11];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb4: {
|
|
||||||
StorageDead(_7);
|
|
||||||
_1 = [move _2, move _5];
|
|
||||||
drop(_5) -> [return: bb5, unwind: bb12];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb5: {
|
|
||||||
StorageDead(_5);
|
|
||||||
drop(_2) -> [return: bb6, unwind: bb13];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb6: {
|
|
||||||
StorageDead(_2);
|
|
||||||
FakeRead(ForLet(None), _1);
|
|
||||||
PlaceMention(_1);
|
|
||||||
StorageLive(_8);
|
|
||||||
_8 = move _1[0..2];
|
|
||||||
_0 = const ();
|
|
||||||
drop(_8) -> [return: bb8, unwind: bb10];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb7: {
|
|
||||||
FakeRead(ForMatchedPlace(None), _1);
|
|
||||||
unreachable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb8: {
|
|
||||||
StorageDead(_8);
|
|
||||||
drop(_1) -> [return: bb9, unwind: bb13];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb9: {
|
|
||||||
StorageDead(_1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb10 (cleanup): {
|
|
||||||
drop(_1) -> [return: bb13, unwind terminate(cleanup)];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb11 (cleanup): {
|
|
||||||
drop(_5) -> [return: bb12, unwind terminate(cleanup)];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb12 (cleanup): {
|
|
||||||
drop(_2) -> [return: bb13, unwind terminate(cleanup)];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb13 (cleanup): {
|
|
||||||
resume;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
// MIR for `move_out_from_end` after CleanupPostBorrowck
|
||||||
|
|
||||||
|
fn move_out_from_end() -> () {
|
||||||
|
let mut _0: ();
|
||||||
|
let _1: [std::boxed::Box<i32>; 2];
|
||||||
|
let mut _2: std::boxed::Box<i32>;
|
||||||
|
let mut _3: std::boxed::Box<i32>;
|
||||||
|
scope 1 {
|
||||||
|
debug a => _1;
|
||||||
|
let _4: std::boxed::Box<i32>;
|
||||||
|
scope 2 {
|
||||||
|
debug _y => _4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bb0: {
|
||||||
|
StorageLive(_1);
|
||||||
|
StorageLive(_2);
|
||||||
|
_2 = Box::<i32>::new(const 1_i32) -> [return: bb1, unwind: bb9];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb1: {
|
||||||
|
StorageLive(_3);
|
||||||
|
_3 = Box::<i32>::new(const 2_i32) -> [return: bb2, unwind: bb8];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb2: {
|
||||||
|
_1 = [move _2, move _3];
|
||||||
|
drop(_3) -> [return: bb3, unwind: bb8];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb3: {
|
||||||
|
StorageDead(_3);
|
||||||
|
drop(_2) -> [return: bb4, unwind: bb9];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb4: {
|
||||||
|
StorageDead(_2);
|
||||||
|
nop;
|
||||||
|
PlaceMention(_1);
|
||||||
|
StorageLive(_4);
|
||||||
|
_4 = move _1[1 of 2];
|
||||||
|
_0 = const ();
|
||||||
|
drop(_4) -> [return: bb5, unwind: bb7];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb5: {
|
||||||
|
StorageDead(_4);
|
||||||
|
drop(_1) -> [return: bb6, unwind: bb9];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb6: {
|
||||||
|
StorageDead(_1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb7 (cleanup): {
|
||||||
|
drop(_1) -> [return: bb9, unwind terminate(cleanup)];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb8 (cleanup): {
|
||||||
|
drop(_2) -> [return: bb9, unwind terminate(cleanup)];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb9 (cleanup): {
|
||||||
|
resume;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
// MIR for `move_out_from_end` after built
|
|
||||||
|
|
||||||
fn move_out_from_end() -> () {
|
|
||||||
let mut _0: ();
|
|
||||||
let _1: [std::boxed::Box<i32>; 2];
|
|
||||||
let mut _2: std::boxed::Box<i32>;
|
|
||||||
let mut _3: *mut u8;
|
|
||||||
let mut _4: std::boxed::Box<i32>;
|
|
||||||
let mut _5: std::boxed::Box<i32>;
|
|
||||||
let mut _6: *mut u8;
|
|
||||||
let mut _7: std::boxed::Box<i32>;
|
|
||||||
scope 1 {
|
|
||||||
debug a => _1;
|
|
||||||
let _8: std::boxed::Box<i32>;
|
|
||||||
scope 2 {
|
|
||||||
debug _y => _8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bb0: {
|
|
||||||
StorageLive(_1);
|
|
||||||
StorageLive(_2);
|
|
||||||
_3 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind: bb13];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb1: {
|
|
||||||
StorageLive(_4);
|
|
||||||
_4 = ShallowInitBox(move _3, i32);
|
|
||||||
(*_4) = const 1_i32;
|
|
||||||
_2 = move _4;
|
|
||||||
drop(_4) -> [return: bb2, unwind: bb12];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb2: {
|
|
||||||
StorageDead(_4);
|
|
||||||
StorageLive(_5);
|
|
||||||
_6 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb3, unwind: bb12];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb3: {
|
|
||||||
StorageLive(_7);
|
|
||||||
_7 = ShallowInitBox(move _6, i32);
|
|
||||||
(*_7) = const 2_i32;
|
|
||||||
_5 = move _7;
|
|
||||||
drop(_7) -> [return: bb4, unwind: bb11];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb4: {
|
|
||||||
StorageDead(_7);
|
|
||||||
_1 = [move _2, move _5];
|
|
||||||
drop(_5) -> [return: bb5, unwind: bb12];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb5: {
|
|
||||||
StorageDead(_5);
|
|
||||||
drop(_2) -> [return: bb6, unwind: bb13];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb6: {
|
|
||||||
StorageDead(_2);
|
|
||||||
FakeRead(ForLet(None), _1);
|
|
||||||
PlaceMention(_1);
|
|
||||||
StorageLive(_8);
|
|
||||||
_8 = move _1[1 of 2];
|
|
||||||
_0 = const ();
|
|
||||||
drop(_8) -> [return: bb8, unwind: bb10];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb7: {
|
|
||||||
FakeRead(ForMatchedPlace(None), _1);
|
|
||||||
unreachable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb8: {
|
|
||||||
StorageDead(_8);
|
|
||||||
drop(_1) -> [return: bb9, unwind: bb13];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb9: {
|
|
||||||
StorageDead(_1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb10 (cleanup): {
|
|
||||||
drop(_1) -> [return: bb13, unwind terminate(cleanup)];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb11 (cleanup): {
|
|
||||||
drop(_5) -> [return: bb12, unwind terminate(cleanup)];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb12 (cleanup): {
|
|
||||||
drop(_2) -> [return: bb13, unwind terminate(cleanup)];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb13 (cleanup): {
|
|
||||||
resume;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
//@ compile-flags: -Zmir-opt-level=0
|
//@ compile-flags: -Zmir-opt-level=0
|
||||||
// skip-filecheck
|
// skip-filecheck
|
||||||
#![feature(liballoc_internals, rustc_attrs)]
|
|
||||||
|
|
||||||
// EMIT_MIR uniform_array_move_out.move_out_from_end.built.after.mir
|
// Can't emit `built.after` here as that contains user type annotations which contain DefId that
|
||||||
|
// change all the time.
|
||||||
|
// EMIT_MIR uniform_array_move_out.move_out_from_end.CleanupPostBorrowck.after.mir
|
||||||
fn move_out_from_end() {
|
fn move_out_from_end() {
|
||||||
let a = [std::boxed::box_new(1), std::boxed::box_new(2)];
|
let a = [Box::new(1), Box::new(2)];
|
||||||
let [.., _y] = a;
|
let [.., _y] = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
// EMIT_MIR uniform_array_move_out.move_out_by_subslice.built.after.mir
|
// EMIT_MIR uniform_array_move_out.move_out_by_subslice.CleanupPostBorrowck.after.mir
|
||||||
fn move_out_by_subslice() {
|
fn move_out_by_subslice() {
|
||||||
let a = [std::boxed::box_new(1), std::boxed::box_new(2)];
|
let a = [Box::new(1), Box::new(2)];
|
||||||
let [_y @ ..] = a;
|
let [_y @ ..] = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
// MIR for `box_new` after CleanupPostBorrowck
|
||||||
|
|
||||||
|
fn box_new(_1: T) -> Box<[T; 1024]> {
|
||||||
|
debug x => _1;
|
||||||
|
let mut _0: std::boxed::Box<[T; 1024]>;
|
||||||
|
let mut _2: std::boxed::Box<std::mem::MaybeUninit<[T; 1024]>>;
|
||||||
|
let mut _3: std::boxed::Box<std::mem::MaybeUninit<[T; 1024]>>;
|
||||||
|
let mut _4: std::boxed::Box<std::mem::MaybeUninit<[T; 1024]>>;
|
||||||
|
let mut _5: T;
|
||||||
|
scope 1 {
|
||||||
|
debug b => _2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb0: {
|
||||||
|
StorageLive(_2);
|
||||||
|
_2 = Box::<[T; 1024]>::new_uninit() -> [return: bb1, unwind: bb7];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb1: {
|
||||||
|
nop;
|
||||||
|
StorageLive(_3);
|
||||||
|
StorageLive(_4);
|
||||||
|
_4 = move _2;
|
||||||
|
StorageLive(_5);
|
||||||
|
_5 = copy _1;
|
||||||
|
((((*_4).1: std::mem::ManuallyDrop<[T; 1024]>).0: std::mem::MaybeDangling<[T; 1024]>).0: [T; 1024]) = [move _5; 1024];
|
||||||
|
StorageDead(_5);
|
||||||
|
_3 = move _4;
|
||||||
|
drop(_4) -> [return: bb2, unwind: bb5];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb2: {
|
||||||
|
StorageDead(_4);
|
||||||
|
_0 = Box::<MaybeUninit<[T; 1024]>>::assume_init(move _3) -> [return: bb3, unwind: bb5];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb3: {
|
||||||
|
StorageDead(_3);
|
||||||
|
drop(_2) -> [return: bb4, unwind: bb7];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb4: {
|
||||||
|
StorageDead(_2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb5 (cleanup): {
|
||||||
|
drop(_3) -> [return: bb6, unwind terminate(cleanup)];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb6 (cleanup): {
|
||||||
|
drop(_2) -> [return: bb7, unwind terminate(cleanup)];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb7 (cleanup): {
|
||||||
|
resume;
|
||||||
|
}
|
||||||
|
}
|
||||||
29
tests/mir-opt/building/write_box_via_move.rs
Normal file
29
tests/mir-opt/building/write_box_via_move.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
//! Ensure we don't generate unnecessary copys for `write_via_move`.
|
||||||
|
//@ compile-flags: -Zmir-opt-level=0
|
||||||
|
#![feature(liballoc_internals)]
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
|
// Can't emit `built.after` here as that contains user type annotations which contain DefId that
|
||||||
|
// change all the time.
|
||||||
|
// EMIT_MIR write_box_via_move.box_new.CleanupPostBorrowck.after.mir
|
||||||
|
// CHECK-LABEL: fn box_new
|
||||||
|
#[inline(never)]
|
||||||
|
fn box_new<T: Copy>(x: T) -> Box<[T; 1024]> {
|
||||||
|
let mut b = Box::new_uninit();
|
||||||
|
// Ensure the array gets constructed directly into the deref'd pointer.
|
||||||
|
// CHECK: (*[[TEMP1:_.+]]) = [{{(move|copy) _.+}}; 1024];
|
||||||
|
unsafe { alloc::intrinsics::write_box_via_move(b, [x; 1024]).assume_init() }
|
||||||
|
}
|
||||||
|
|
||||||
|
// EMIT_MIR write_box_via_move.vec_macro.CleanupPostBorrowck.after.mir
|
||||||
|
// CHECK-LABEL: fn vec_macro
|
||||||
|
fn vec_macro() -> Vec<i32> {
|
||||||
|
// CHECK: (*[[TEMP1:_.+]]) = [const 0_i32, const 1_i32,
|
||||||
|
vec![0, 1, 2, 3, 4, 5, 6, 7]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
box_new(0);
|
||||||
|
vec_macro();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
// MIR for `vec_macro` after CleanupPostBorrowck
|
||||||
|
|
||||||
|
fn vec_macro() -> Vec<i32> {
|
||||||
|
let mut _0: std::vec::Vec<i32>;
|
||||||
|
let mut _1: std::boxed::Box<std::mem::MaybeUninit<[i32; 8]>>;
|
||||||
|
let mut _2: std::boxed::Box<std::mem::MaybeUninit<[i32; 8]>>;
|
||||||
|
|
||||||
|
bb0: {
|
||||||
|
StorageLive(_1);
|
||||||
|
StorageLive(_2);
|
||||||
|
_2 = Box::<[i32; 8]>::new_uninit() -> [return: bb1, unwind: bb5];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb1: {
|
||||||
|
((((*_2).1: std::mem::ManuallyDrop<[i32; 8]>).0: std::mem::MaybeDangling<[i32; 8]>).0: [i32; 8]) = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32, const 6_i32, const 7_i32];
|
||||||
|
_1 = move _2;
|
||||||
|
drop(_2) -> [return: bb2, unwind: bb4];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb2: {
|
||||||
|
StorageDead(_2);
|
||||||
|
_0 = std::boxed::box_assume_init_into_vec_unsafe::<i32, 8>(move _1) -> [return: bb3, unwind: bb4];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb3: {
|
||||||
|
StorageDead(_1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb4 (cleanup): {
|
||||||
|
drop(_1) -> [return: bb5, unwind terminate(cleanup)];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb5 (cleanup): {
|
||||||
|
resume;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
- // MIR for `main` before GVN
|
|
||||||
+ // MIR for `main` after GVN
|
|
||||||
|
|
||||||
fn main() -> () {
|
|
||||||
let mut _0: ();
|
|
||||||
let _1: i32;
|
|
||||||
let mut _2: i32;
|
|
||||||
let mut _3: std::boxed::Box<i32>;
|
|
||||||
let mut _4: *mut u8;
|
|
||||||
let mut _5: std::boxed::Box<i32>;
|
|
||||||
let mut _6: *const i32;
|
|
||||||
let mut _7: std::ptr::NonNull<i32>;
|
|
||||||
let mut _8: std::ptr::Unique<i32>;
|
|
||||||
let mut _9: *const i32;
|
|
||||||
let mut _10: *const i32;
|
|
||||||
scope 1 {
|
|
||||||
debug x => _1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb0: {
|
|
||||||
StorageLive(_1);
|
|
||||||
- StorageLive(_2);
|
|
||||||
+ nop;
|
|
||||||
StorageLive(_3);
|
|
||||||
_4 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind unreachable];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb1: {
|
|
||||||
StorageLive(_5);
|
|
||||||
- _6 = move _4 as *const i32 (Transmute);
|
|
||||||
- _7 = NonNull::<i32> { pointer: move _6 };
|
|
||||||
- _8 = std::ptr::Unique::<i32> { pointer: move _7, _marker: const PhantomData::<i32> };
|
|
||||||
+ _6 = copy _4 as *const i32 (PtrToPtr);
|
|
||||||
+ _7 = NonNull::<i32> { pointer: copy _6 };
|
|
||||||
+ _8 = std::ptr::Unique::<i32> { pointer: copy _7, _marker: const PhantomData::<i32> };
|
|
||||||
_5 = Box::<i32>(move _8, const std::alloc::Global);
|
|
||||||
- _9 = copy ((_5.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>) as *const i32 (Transmute);
|
|
||||||
- (*_9) = const 42_i32;
|
|
||||||
+ _9 = copy _6;
|
|
||||||
+ (*_6) = const 42_i32;
|
|
||||||
_3 = move _5;
|
|
||||||
StorageDead(_5);
|
|
||||||
_10 = copy ((_3.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>) as *const i32 (Transmute);
|
|
||||||
_2 = copy (*_10);
|
|
||||||
- _1 = Add(move _2, const 0_i32);
|
|
||||||
- StorageDead(_2);
|
|
||||||
+ _1 = copy _2;
|
|
||||||
+ nop;
|
|
||||||
drop(_3) -> [return: bb2, unwind unreachable];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb2: {
|
|
||||||
StorageDead(_3);
|
|
||||||
_0 = const ();
|
|
||||||
StorageDead(_1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
- // MIR for `main` before GVN
|
|
||||||
+ // MIR for `main` after GVN
|
|
||||||
|
|
||||||
fn main() -> () {
|
|
||||||
let mut _0: ();
|
|
||||||
let _1: i32;
|
|
||||||
let mut _2: i32;
|
|
||||||
let mut _3: std::boxed::Box<i32>;
|
|
||||||
let mut _4: *mut u8;
|
|
||||||
let mut _5: std::boxed::Box<i32>;
|
|
||||||
let mut _6: *const i32;
|
|
||||||
let mut _7: std::ptr::NonNull<i32>;
|
|
||||||
let mut _8: std::ptr::Unique<i32>;
|
|
||||||
let mut _9: *const i32;
|
|
||||||
let mut _10: *const i32;
|
|
||||||
scope 1 {
|
|
||||||
debug x => _1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb0: {
|
|
||||||
StorageLive(_1);
|
|
||||||
- StorageLive(_2);
|
|
||||||
+ nop;
|
|
||||||
StorageLive(_3);
|
|
||||||
_4 = alloc::alloc::exchange_malloc(const <i32 as std::mem::SizedTypeProperties>::SIZE, const <i32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind continue];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb1: {
|
|
||||||
StorageLive(_5);
|
|
||||||
- _6 = move _4 as *const i32 (Transmute);
|
|
||||||
- _7 = NonNull::<i32> { pointer: move _6 };
|
|
||||||
- _8 = std::ptr::Unique::<i32> { pointer: move _7, _marker: const PhantomData::<i32> };
|
|
||||||
+ _6 = copy _4 as *const i32 (PtrToPtr);
|
|
||||||
+ _7 = NonNull::<i32> { pointer: copy _6 };
|
|
||||||
+ _8 = std::ptr::Unique::<i32> { pointer: copy _7, _marker: const PhantomData::<i32> };
|
|
||||||
_5 = Box::<i32>(move _8, const std::alloc::Global);
|
|
||||||
- _9 = copy ((_5.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>) as *const i32 (Transmute);
|
|
||||||
- (*_9) = const 42_i32;
|
|
||||||
+ _9 = copy _6;
|
|
||||||
+ (*_6) = const 42_i32;
|
|
||||||
_3 = move _5;
|
|
||||||
StorageDead(_5);
|
|
||||||
_10 = copy ((_3.0: std::ptr::Unique<i32>).0: std::ptr::NonNull<i32>) as *const i32 (Transmute);
|
|
||||||
_2 = copy (*_10);
|
|
||||||
- _1 = Add(move _2, const 0_i32);
|
|
||||||
- StorageDead(_2);
|
|
||||||
+ _1 = copy _2;
|
|
||||||
+ nop;
|
|
||||||
drop(_3) -> [return: bb2, unwind: bb3];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb2: {
|
|
||||||
StorageDead(_3);
|
|
||||||
_0 = const ();
|
|
||||||
StorageDead(_1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb3 (cleanup): {
|
|
||||||
resume;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
//@ test-mir-pass: GVN
|
|
||||||
//@ compile-flags: -O
|
|
||||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
|
||||||
|
|
||||||
#![feature(rustc_attrs, liballoc_internals)]
|
|
||||||
|
|
||||||
// Note: this test verifies that we, in fact, do not const prop `#[rustc_box]`
|
|
||||||
|
|
||||||
// EMIT_MIR boxes.main.GVN.diff
|
|
||||||
fn main() {
|
|
||||||
// CHECK-LABEL: fn main(
|
|
||||||
// CHECK: debug x => [[x:_.*]];
|
|
||||||
// CHECK: (*{{_.*}}) = const 42_i32;
|
|
||||||
// CHECK: [[tmp:_.*]] = copy (*{{_.*}});
|
|
||||||
// CHECK: [[x]] = copy [[tmp]];
|
|
||||||
let x = *(std::boxed::box_new(42)) + 0;
|
|
||||||
}
|
|
||||||
|
|
@ -11,9 +11,9 @@
|
||||||
let mut _9: *const [()];
|
let mut _9: *const [()];
|
||||||
let mut _10: std::boxed::Box<()>;
|
let mut _10: std::boxed::Box<()>;
|
||||||
let mut _11: *const ();
|
let mut _11: *const ();
|
||||||
let mut _16: usize;
|
let mut _14: usize;
|
||||||
let mut _17: usize;
|
let mut _15: usize;
|
||||||
let mut _26: usize;
|
let mut _24: usize;
|
||||||
scope 1 {
|
scope 1 {
|
||||||
debug vp_ctx => _1;
|
debug vp_ctx => _1;
|
||||||
let _5: *const ();
|
let _5: *const ();
|
||||||
|
|
@ -26,49 +26,49 @@
|
||||||
scope 4 {
|
scope 4 {
|
||||||
debug _x => _8;
|
debug _x => _8;
|
||||||
}
|
}
|
||||||
scope 19 (inlined foo) {
|
scope 20 (inlined foo) {
|
||||||
let mut _27: *const [()];
|
let mut _25: *const [()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope 17 (inlined slice_from_raw_parts::<()>) {
|
scope 18 (inlined slice_from_raw_parts::<()>) {
|
||||||
scope 18 (inlined std::ptr::from_raw_parts::<[()], ()>) {
|
scope 19 (inlined std::ptr::from_raw_parts::<[()], ()>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope 5 (inlined Box::<()>::new) {
|
scope 5 (inlined Box::<()>::new) {
|
||||||
let mut _12: *mut u8;
|
let mut _12: *mut ();
|
||||||
let mut _13: *const ();
|
let mut _13: *mut u8;
|
||||||
let mut _14: std::ptr::NonNull<()>;
|
scope 6 {
|
||||||
let mut _15: std::ptr::Unique<()>;
|
}
|
||||||
scope 6 (inlined alloc::alloc::exchange_malloc) {
|
scope 7 (inlined boxed::box_new_uninit) {
|
||||||
let _18: std::alloc::Layout;
|
let _16: std::alloc::Layout;
|
||||||
let mut _19: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
|
let mut _17: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
|
||||||
let mut _20: isize;
|
let mut _18: isize;
|
||||||
let mut _22: !;
|
let mut _20: !;
|
||||||
scope 7 {
|
scope 8 {
|
||||||
let _21: std::ptr::NonNull<[u8]>;
|
let _19: std::ptr::NonNull<[u8]>;
|
||||||
scope 8 {
|
scope 9 {
|
||||||
scope 12 (inlined NonNull::<[u8]>::as_mut_ptr) {
|
scope 13 (inlined NonNull::<[u8]>::as_mut_ptr) {
|
||||||
scope 13 (inlined NonNull::<[u8]>::as_non_null_ptr) {
|
scope 14 (inlined NonNull::<[u8]>::as_non_null_ptr) {
|
||||||
scope 14 (inlined NonNull::<[u8]>::cast::<u8>) {
|
scope 15 (inlined NonNull::<[u8]>::cast::<u8>) {
|
||||||
let mut _25: *mut [u8];
|
let mut _23: *mut [u8];
|
||||||
scope 15 (inlined NonNull::<[u8]>::as_ptr) {
|
scope 16 (inlined NonNull::<[u8]>::as_ptr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope 16 (inlined NonNull::<u8>::as_ptr) {
|
scope 17 (inlined NonNull::<u8>::as_ptr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope 10 (inlined <std::alloc::Global as Allocator>::allocate) {
|
scope 11 (inlined <std::alloc::Global as Allocator>::allocate) {
|
||||||
scope 11 (inlined std::alloc::Global::alloc_impl) {
|
scope 12 (inlined std::alloc::Global::alloc_impl) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope 9 (inlined #[track_caller] Layout::from_size_align_unchecked) {
|
scope 10 (inlined #[track_caller] Layout::from_size_align_unchecked) {
|
||||||
let _23: ();
|
let _21: ();
|
||||||
let mut _24: std::ptr::Alignment;
|
let mut _22: std::ptr::Alignment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -83,18 +83,16 @@
|
||||||
StorageLive(_12);
|
StorageLive(_12);
|
||||||
StorageLive(_13);
|
StorageLive(_13);
|
||||||
StorageLive(_14);
|
StorageLive(_14);
|
||||||
|
- _14 = const <() as std::mem::SizedTypeProperties>::SIZE;
|
||||||
|
+ _14 = const 0_usize;
|
||||||
StorageLive(_15);
|
StorageLive(_15);
|
||||||
|
- _15 = const <() as std::mem::SizedTypeProperties>::ALIGN;
|
||||||
|
+ _15 = const 1_usize;
|
||||||
StorageLive(_16);
|
StorageLive(_16);
|
||||||
- _16 = const <() as std::mem::SizedTypeProperties>::SIZE;
|
|
||||||
+ _16 = const 0_usize;
|
|
||||||
StorageLive(_17);
|
|
||||||
- _17 = const <() as std::mem::SizedTypeProperties>::ALIGN;
|
|
||||||
+ _17 = const 1_usize;
|
|
||||||
StorageLive(_18);
|
StorageLive(_18);
|
||||||
|
StorageLive(_19);
|
||||||
StorageLive(_20);
|
StorageLive(_20);
|
||||||
StorageLive(_21);
|
StorageLive(_21);
|
||||||
StorageLive(_22);
|
|
||||||
StorageLive(_23);
|
|
||||||
switchInt(UbChecks) -> [0: bb6, otherwise: bb5];
|
switchInt(UbChecks) -> [0: bb6, otherwise: bb5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,35 +107,31 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
bb3: {
|
bb3: {
|
||||||
- _22 = handle_alloc_error(move _18) -> unwind unreachable;
|
- _20 = handle_alloc_error(move _16) -> unwind unreachable;
|
||||||
+ _22 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> unwind unreachable;
|
+ _20 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> unwind unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
bb4: {
|
bb4: {
|
||||||
_21 = copy ((_19 as Ok).0: std::ptr::NonNull<[u8]>);
|
_19 = copy ((_17 as Ok).0: std::ptr::NonNull<[u8]>);
|
||||||
- StorageLive(_25);
|
- StorageLive(_23);
|
||||||
+ nop;
|
+ nop;
|
||||||
_25 = copy _21 as *mut [u8] (Transmute);
|
_23 = copy _19 as *mut [u8] (Transmute);
|
||||||
_12 = copy _25 as *mut u8 (PtrToPtr);
|
_13 = copy _23 as *mut u8 (PtrToPtr);
|
||||||
- StorageDead(_25);
|
- StorageDead(_23);
|
||||||
+ nop;
|
+ nop;
|
||||||
StorageDead(_19);
|
StorageDead(_17);
|
||||||
StorageDead(_23);
|
|
||||||
StorageDead(_22);
|
|
||||||
StorageDead(_21);
|
StorageDead(_21);
|
||||||
StorageDead(_20);
|
StorageDead(_20);
|
||||||
|
StorageDead(_19);
|
||||||
StorageDead(_18);
|
StorageDead(_18);
|
||||||
StorageDead(_17);
|
|
||||||
StorageDead(_16);
|
StorageDead(_16);
|
||||||
- _13 = copy _12 as *const () (PtrToPtr);
|
|
||||||
+ _13 = copy _25 as *const () (PtrToPtr);
|
|
||||||
_14 = NonNull::<()> { pointer: copy _13 };
|
|
||||||
_15 = std::ptr::Unique::<()> { pointer: copy _14, _marker: const PhantomData::<()> };
|
|
||||||
_3 = Box::<()>(move _15, const std::alloc::Global);
|
|
||||||
- (*_13) = move _4;
|
|
||||||
+ (*_13) = const ();
|
|
||||||
StorageDead(_15);
|
StorageDead(_15);
|
||||||
StorageDead(_14);
|
StorageDead(_14);
|
||||||
|
- _12 = copy _13 as *mut () (PtrToPtr);
|
||||||
|
- (*_12) = move _4;
|
||||||
|
+ _12 = copy _23 as *mut () (PtrToPtr);
|
||||||
|
+ (*_12) = const ();
|
||||||
|
_3 = copy _13 as std::boxed::Box<()> (Transmute);
|
||||||
StorageDead(_13);
|
StorageDead(_13);
|
||||||
StorageDead(_12);
|
StorageDead(_12);
|
||||||
StorageDead(_4);
|
StorageDead(_4);
|
||||||
|
|
@ -153,21 +147,21 @@
|
||||||
+ nop;
|
+ nop;
|
||||||
StorageLive(_7);
|
StorageLive(_7);
|
||||||
_7 = copy _5;
|
_7 = copy _5;
|
||||||
StorageLive(_26);
|
StorageLive(_24);
|
||||||
_26 = const 1_usize;
|
_24 = const 1_usize;
|
||||||
- _6 = *const [()] from (copy _7, copy _26);
|
- _6 = *const [()] from (copy _7, copy _24);
|
||||||
+ _6 = *const [()] from (copy _5, const 1_usize);
|
+ _6 = *const [()] from (copy _5, const 1_usize);
|
||||||
StorageDead(_26);
|
StorageDead(_24);
|
||||||
StorageDead(_7);
|
StorageDead(_7);
|
||||||
StorageLive(_8);
|
StorageLive(_8);
|
||||||
StorageLive(_9);
|
StorageLive(_9);
|
||||||
_9 = copy _6;
|
_9 = copy _6;
|
||||||
StorageLive(_27);
|
StorageLive(_25);
|
||||||
- _27 = copy _9;
|
- _25 = copy _9;
|
||||||
- _8 = copy _9 as *mut () (PtrToPtr);
|
- _8 = copy _9 as *mut () (PtrToPtr);
|
||||||
+ _27 = copy _6;
|
+ _25 = copy _6;
|
||||||
+ _8 = copy _5 as *mut () (PtrToPtr);
|
+ _8 = copy _5 as *mut () (PtrToPtr);
|
||||||
StorageDead(_27);
|
StorageDead(_25);
|
||||||
StorageDead(_9);
|
StorageDead(_9);
|
||||||
_0 = const ();
|
_0 = const ();
|
||||||
StorageDead(_8);
|
StorageDead(_8);
|
||||||
|
|
@ -179,25 +173,25 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
bb5: {
|
bb5: {
|
||||||
- _23 = Layout::from_size_align_unchecked::precondition_check(copy _16, copy _17) -> [return: bb6, unwind unreachable];
|
- _21 = Layout::from_size_align_unchecked::precondition_check(copy _14, copy _15) -> [return: bb6, unwind unreachable];
|
||||||
+ _23 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable];
|
+ _21 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb6: {
|
bb6: {
|
||||||
StorageLive(_24);
|
StorageLive(_22);
|
||||||
- _24 = copy _17 as std::ptr::Alignment (Transmute);
|
- _22 = copy _15 as std::ptr::Alignment (Transmute);
|
||||||
- _18 = Layout { size: copy _16, align: move _24 };
|
- _16 = Layout { size: copy _14, align: move _22 };
|
||||||
+ _24 = const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }};
|
+ _22 = const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }};
|
||||||
+ _18 = const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }};
|
+ _16 = const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }};
|
||||||
StorageDead(_24);
|
StorageDead(_22);
|
||||||
StorageLive(_19);
|
StorageLive(_17);
|
||||||
- _19 = std::alloc::Global::alloc_impl_runtime(copy _18, const false) -> [return: bb7, unwind unreachable];
|
- _17 = std::alloc::Global::alloc_impl_runtime(copy _16, const false) -> [return: bb7, unwind unreachable];
|
||||||
+ _19 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}, const false) -> [return: bb7, unwind unreachable];
|
+ _17 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}, const false) -> [return: bb7, unwind unreachable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb7: {
|
bb7: {
|
||||||
_20 = discriminant(_19);
|
_18 = discriminant(_17);
|
||||||
switchInt(move _20) -> [0: bb4, 1: bb3, otherwise: bb2];
|
switchInt(move _18) -> [0: bb4, 1: bb3, otherwise: bb2];
|
||||||
}
|
}
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@
|
||||||
let mut _9: *const [()];
|
let mut _9: *const [()];
|
||||||
let mut _10: std::boxed::Box<()>;
|
let mut _10: std::boxed::Box<()>;
|
||||||
let mut _11: *const ();
|
let mut _11: *const ();
|
||||||
let mut _16: usize;
|
let mut _14: usize;
|
||||||
let mut _17: usize;
|
let mut _15: usize;
|
||||||
let mut _26: usize;
|
let mut _24: usize;
|
||||||
scope 1 {
|
scope 1 {
|
||||||
debug vp_ctx => _1;
|
debug vp_ctx => _1;
|
||||||
let _5: *const ();
|
let _5: *const ();
|
||||||
|
|
@ -26,49 +26,49 @@
|
||||||
scope 4 {
|
scope 4 {
|
||||||
debug _x => _8;
|
debug _x => _8;
|
||||||
}
|
}
|
||||||
scope 19 (inlined foo) {
|
scope 20 (inlined foo) {
|
||||||
let mut _27: *const [()];
|
let mut _25: *const [()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope 17 (inlined slice_from_raw_parts::<()>) {
|
scope 18 (inlined slice_from_raw_parts::<()>) {
|
||||||
scope 18 (inlined std::ptr::from_raw_parts::<[()], ()>) {
|
scope 19 (inlined std::ptr::from_raw_parts::<[()], ()>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope 5 (inlined Box::<()>::new) {
|
scope 5 (inlined Box::<()>::new) {
|
||||||
let mut _12: *mut u8;
|
let mut _12: *mut ();
|
||||||
let mut _13: *const ();
|
let mut _13: *mut u8;
|
||||||
let mut _14: std::ptr::NonNull<()>;
|
scope 6 {
|
||||||
let mut _15: std::ptr::Unique<()>;
|
}
|
||||||
scope 6 (inlined alloc::alloc::exchange_malloc) {
|
scope 7 (inlined boxed::box_new_uninit) {
|
||||||
let _18: std::alloc::Layout;
|
let _16: std::alloc::Layout;
|
||||||
let mut _19: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
|
let mut _17: std::result::Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError>;
|
||||||
let mut _20: isize;
|
let mut _18: isize;
|
||||||
let mut _22: !;
|
let mut _20: !;
|
||||||
scope 7 {
|
scope 8 {
|
||||||
let _21: std::ptr::NonNull<[u8]>;
|
let _19: std::ptr::NonNull<[u8]>;
|
||||||
scope 8 {
|
scope 9 {
|
||||||
scope 12 (inlined NonNull::<[u8]>::as_mut_ptr) {
|
scope 13 (inlined NonNull::<[u8]>::as_mut_ptr) {
|
||||||
scope 13 (inlined NonNull::<[u8]>::as_non_null_ptr) {
|
scope 14 (inlined NonNull::<[u8]>::as_non_null_ptr) {
|
||||||
scope 14 (inlined NonNull::<[u8]>::cast::<u8>) {
|
scope 15 (inlined NonNull::<[u8]>::cast::<u8>) {
|
||||||
let mut _25: *mut [u8];
|
let mut _23: *mut [u8];
|
||||||
scope 15 (inlined NonNull::<[u8]>::as_ptr) {
|
scope 16 (inlined NonNull::<[u8]>::as_ptr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope 16 (inlined NonNull::<u8>::as_ptr) {
|
scope 17 (inlined NonNull::<u8>::as_ptr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope 10 (inlined <std::alloc::Global as Allocator>::allocate) {
|
scope 11 (inlined <std::alloc::Global as Allocator>::allocate) {
|
||||||
scope 11 (inlined std::alloc::Global::alloc_impl) {
|
scope 12 (inlined std::alloc::Global::alloc_impl) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope 9 (inlined #[track_caller] Layout::from_size_align_unchecked) {
|
scope 10 (inlined #[track_caller] Layout::from_size_align_unchecked) {
|
||||||
let _23: ();
|
let _21: ();
|
||||||
let mut _24: std::ptr::Alignment;
|
let mut _22: std::ptr::Alignment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -83,18 +83,16 @@
|
||||||
StorageLive(_12);
|
StorageLive(_12);
|
||||||
StorageLive(_13);
|
StorageLive(_13);
|
||||||
StorageLive(_14);
|
StorageLive(_14);
|
||||||
|
- _14 = const <() as std::mem::SizedTypeProperties>::SIZE;
|
||||||
|
+ _14 = const 0_usize;
|
||||||
StorageLive(_15);
|
StorageLive(_15);
|
||||||
|
- _15 = const <() as std::mem::SizedTypeProperties>::ALIGN;
|
||||||
|
+ _15 = const 1_usize;
|
||||||
StorageLive(_16);
|
StorageLive(_16);
|
||||||
- _16 = const <() as std::mem::SizedTypeProperties>::SIZE;
|
|
||||||
+ _16 = const 0_usize;
|
|
||||||
StorageLive(_17);
|
|
||||||
- _17 = const <() as std::mem::SizedTypeProperties>::ALIGN;
|
|
||||||
+ _17 = const 1_usize;
|
|
||||||
StorageLive(_18);
|
StorageLive(_18);
|
||||||
|
StorageLive(_19);
|
||||||
StorageLive(_20);
|
StorageLive(_20);
|
||||||
StorageLive(_21);
|
StorageLive(_21);
|
||||||
StorageLive(_22);
|
|
||||||
StorageLive(_23);
|
|
||||||
switchInt(UbChecks) -> [0: bb6, otherwise: bb5];
|
switchInt(UbChecks) -> [0: bb6, otherwise: bb5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,35 +107,31 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
bb3: {
|
bb3: {
|
||||||
- _22 = handle_alloc_error(move _18) -> unwind unreachable;
|
- _20 = handle_alloc_error(move _16) -> unwind unreachable;
|
||||||
+ _22 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> unwind unreachable;
|
+ _20 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}) -> unwind unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
bb4: {
|
bb4: {
|
||||||
_21 = copy ((_19 as Ok).0: std::ptr::NonNull<[u8]>);
|
_19 = copy ((_17 as Ok).0: std::ptr::NonNull<[u8]>);
|
||||||
- StorageLive(_25);
|
- StorageLive(_23);
|
||||||
+ nop;
|
+ nop;
|
||||||
_25 = copy _21 as *mut [u8] (Transmute);
|
_23 = copy _19 as *mut [u8] (Transmute);
|
||||||
_12 = copy _25 as *mut u8 (PtrToPtr);
|
_13 = copy _23 as *mut u8 (PtrToPtr);
|
||||||
- StorageDead(_25);
|
- StorageDead(_23);
|
||||||
+ nop;
|
+ nop;
|
||||||
StorageDead(_19);
|
StorageDead(_17);
|
||||||
StorageDead(_23);
|
|
||||||
StorageDead(_22);
|
|
||||||
StorageDead(_21);
|
StorageDead(_21);
|
||||||
StorageDead(_20);
|
StorageDead(_20);
|
||||||
|
StorageDead(_19);
|
||||||
StorageDead(_18);
|
StorageDead(_18);
|
||||||
StorageDead(_17);
|
|
||||||
StorageDead(_16);
|
StorageDead(_16);
|
||||||
- _13 = copy _12 as *const () (PtrToPtr);
|
|
||||||
+ _13 = copy _25 as *const () (PtrToPtr);
|
|
||||||
_14 = NonNull::<()> { pointer: copy _13 };
|
|
||||||
_15 = std::ptr::Unique::<()> { pointer: copy _14, _marker: const PhantomData::<()> };
|
|
||||||
_3 = Box::<()>(move _15, const std::alloc::Global);
|
|
||||||
- (*_13) = move _4;
|
|
||||||
+ (*_13) = const ();
|
|
||||||
StorageDead(_15);
|
StorageDead(_15);
|
||||||
StorageDead(_14);
|
StorageDead(_14);
|
||||||
|
- _12 = copy _13 as *mut () (PtrToPtr);
|
||||||
|
- (*_12) = move _4;
|
||||||
|
+ _12 = copy _23 as *mut () (PtrToPtr);
|
||||||
|
+ (*_12) = const ();
|
||||||
|
_3 = copy _13 as std::boxed::Box<()> (Transmute);
|
||||||
StorageDead(_13);
|
StorageDead(_13);
|
||||||
StorageDead(_12);
|
StorageDead(_12);
|
||||||
StorageDead(_4);
|
StorageDead(_4);
|
||||||
|
|
@ -153,21 +147,21 @@
|
||||||
+ nop;
|
+ nop;
|
||||||
StorageLive(_7);
|
StorageLive(_7);
|
||||||
_7 = copy _5;
|
_7 = copy _5;
|
||||||
StorageLive(_26);
|
StorageLive(_24);
|
||||||
_26 = const 1_usize;
|
_24 = const 1_usize;
|
||||||
- _6 = *const [()] from (copy _7, copy _26);
|
- _6 = *const [()] from (copy _7, copy _24);
|
||||||
+ _6 = *const [()] from (copy _5, const 1_usize);
|
+ _6 = *const [()] from (copy _5, const 1_usize);
|
||||||
StorageDead(_26);
|
StorageDead(_24);
|
||||||
StorageDead(_7);
|
StorageDead(_7);
|
||||||
StorageLive(_8);
|
StorageLive(_8);
|
||||||
StorageLive(_9);
|
StorageLive(_9);
|
||||||
_9 = copy _6;
|
_9 = copy _6;
|
||||||
StorageLive(_27);
|
StorageLive(_25);
|
||||||
- _27 = copy _9;
|
- _25 = copy _9;
|
||||||
- _8 = copy _9 as *mut () (PtrToPtr);
|
- _8 = copy _9 as *mut () (PtrToPtr);
|
||||||
+ _27 = copy _6;
|
+ _25 = copy _6;
|
||||||
+ _8 = copy _5 as *mut () (PtrToPtr);
|
+ _8 = copy _5 as *mut () (PtrToPtr);
|
||||||
StorageDead(_27);
|
StorageDead(_25);
|
||||||
StorageDead(_9);
|
StorageDead(_9);
|
||||||
_0 = const ();
|
_0 = const ();
|
||||||
StorageDead(_8);
|
StorageDead(_8);
|
||||||
|
|
@ -179,25 +173,25 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
bb5: {
|
bb5: {
|
||||||
- _23 = Layout::from_size_align_unchecked::precondition_check(copy _16, copy _17) -> [return: bb6, unwind unreachable];
|
- _21 = Layout::from_size_align_unchecked::precondition_check(copy _14, copy _15) -> [return: bb6, unwind unreachable];
|
||||||
+ _23 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable];
|
+ _21 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb6: {
|
bb6: {
|
||||||
StorageLive(_24);
|
StorageLive(_22);
|
||||||
- _24 = copy _17 as std::ptr::Alignment (Transmute);
|
- _22 = copy _15 as std::ptr::Alignment (Transmute);
|
||||||
- _18 = Layout { size: copy _16, align: move _24 };
|
- _16 = Layout { size: copy _14, align: move _22 };
|
||||||
+ _24 = const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }};
|
+ _22 = const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }};
|
||||||
+ _18 = const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }};
|
+ _16 = const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }};
|
||||||
StorageDead(_24);
|
StorageDead(_22);
|
||||||
StorageLive(_19);
|
StorageLive(_17);
|
||||||
- _19 = std::alloc::Global::alloc_impl_runtime(copy _18, const false) -> [return: bb7, unwind unreachable];
|
- _17 = std::alloc::Global::alloc_impl_runtime(copy _16, const false) -> [return: bb7, unwind unreachable];
|
||||||
+ _19 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}, const false) -> [return: bb7, unwind unreachable];
|
+ _17 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }} }}, const false) -> [return: bb7, unwind unreachable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb7: {
|
bb7: {
|
||||||
_20 = discriminant(_19);
|
_18 = discriminant(_17);
|
||||||
switchInt(move _20) -> [0: bb4, 1: bb3, otherwise: bb2];
|
switchInt(move _18) -> [0: bb4, 1: bb3, otherwise: bb2];
|
||||||
}
|
}
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,7 @@
|
||||||
+ StorageLive(_42);
|
+ StorageLive(_42);
|
||||||
+ _42 = Option::<()>::None;
|
+ _42 = Option::<()>::None;
|
||||||
+ _35 = copy ((*_37).0: std::option::Option<()>);
|
+ _35 = copy ((*_37).0: std::option::Option<()>);
|
||||||
+ ((*_37).0: std::option::Option<()>) = copy _42;
|
+ ((*_37).0: std::option::Option<()>) = move _42;
|
||||||
+ StorageDead(_42);
|
+ StorageDead(_42);
|
||||||
+ StorageLive(_43);
|
+ StorageLive(_43);
|
||||||
+ _43 = discriminant(_35);
|
+ _43 = discriminant(_35);
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@
|
||||||
|
|
||||||
#![feature(rustc_attrs, liballoc_internals)]
|
#![feature(rustc_attrs, liballoc_internals)]
|
||||||
|
|
||||||
// EMIT_MIR issue_62289.test.ElaborateDrops.before.mir
|
// EMIT_MIR issue_62289.test.ElaborateDrops.after.mir
|
||||||
fn test() -> Option<Box<u32>> {
|
fn test() -> Option<Vec<u32>> {
|
||||||
Some(std::boxed::box_new(None?))
|
Some(vec![None?])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
// MIR for `test` after ElaborateDrops
|
||||||
|
|
||||||
|
fn test() -> Option<Vec<u32>> {
|
||||||
|
let mut _0: std::option::Option<std::vec::Vec<u32>>;
|
||||||
|
let mut _1: std::vec::Vec<u32>;
|
||||||
|
let mut _2: std::boxed::Box<std::mem::MaybeUninit<[u32; 1]>>;
|
||||||
|
let mut _3: std::boxed::Box<std::mem::MaybeUninit<[u32; 1]>>;
|
||||||
|
let mut _4: u32;
|
||||||
|
let mut _5: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>;
|
||||||
|
let mut _6: std::option::Option<u32>;
|
||||||
|
let mut _7: isize;
|
||||||
|
let _8: std::option::Option<std::convert::Infallible>;
|
||||||
|
let mut _9: !;
|
||||||
|
let mut _10: std::option::Option<std::convert::Infallible>;
|
||||||
|
let _11: u32;
|
||||||
|
scope 1 {
|
||||||
|
debug residual => _8;
|
||||||
|
scope 2 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scope 3 {
|
||||||
|
debug val => _11;
|
||||||
|
scope 4 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bb0: {
|
||||||
|
StorageLive(_1);
|
||||||
|
StorageLive(_2);
|
||||||
|
StorageLive(_3);
|
||||||
|
_3 = Box::<[u32; 1]>::new_uninit() -> [return: bb1, unwind: bb14];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb1: {
|
||||||
|
StorageLive(_4);
|
||||||
|
StorageLive(_5);
|
||||||
|
StorageLive(_6);
|
||||||
|
_6 = Option::<u32>::None;
|
||||||
|
_5 = <Option<u32> as Try>::branch(move _6) -> [return: bb2, unwind: bb13];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb2: {
|
||||||
|
StorageDead(_6);
|
||||||
|
PlaceMention(_5);
|
||||||
|
_7 = discriminant(_5);
|
||||||
|
switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb3];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb3: {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb4: {
|
||||||
|
StorageLive(_11);
|
||||||
|
_11 = copy ((_5 as Continue).0: u32);
|
||||||
|
_4 = copy _11;
|
||||||
|
StorageDead(_11);
|
||||||
|
((((*_3).1: std::mem::ManuallyDrop<[u32; 1]>).0: std::mem::MaybeDangling<[u32; 1]>).0: [u32; 1]) = [move _4];
|
||||||
|
StorageDead(_4);
|
||||||
|
_2 = move _3;
|
||||||
|
goto -> bb7;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb5: {
|
||||||
|
StorageLive(_8);
|
||||||
|
_8 = copy ((_5 as Break).0: std::option::Option<std::convert::Infallible>);
|
||||||
|
StorageLive(_10);
|
||||||
|
_10 = copy _8;
|
||||||
|
_0 = <Option<Vec<u32>> as FromResidual<Option<Infallible>>>::from_residual(move _10) -> [return: bb6, unwind: bb13];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb6: {
|
||||||
|
StorageDead(_10);
|
||||||
|
StorageDead(_8);
|
||||||
|
StorageDead(_4);
|
||||||
|
drop(_3) -> [return: bb10, unwind: bb14];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb7: {
|
||||||
|
StorageDead(_3);
|
||||||
|
_1 = std::boxed::box_assume_init_into_vec_unsafe::<u32, 1>(move _2) -> [return: bb8, unwind: bb12];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb8: {
|
||||||
|
StorageDead(_2);
|
||||||
|
_0 = Option::<Vec<u32>>::Some(move _1);
|
||||||
|
goto -> bb9;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb9: {
|
||||||
|
StorageDead(_1);
|
||||||
|
StorageDead(_5);
|
||||||
|
goto -> bb11;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb10: {
|
||||||
|
StorageDead(_3);
|
||||||
|
StorageDead(_2);
|
||||||
|
StorageDead(_1);
|
||||||
|
StorageDead(_5);
|
||||||
|
goto -> bb11;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb11: {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb12 (cleanup): {
|
||||||
|
goto -> bb14;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb13 (cleanup): {
|
||||||
|
drop(_3) -> [return: bb14, unwind terminate(cleanup)];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb14 (cleanup): {
|
||||||
|
resume;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
// MIR for `test` after ElaborateDrops
|
||||||
|
|
||||||
|
fn test() -> Option<Vec<u32>> {
|
||||||
|
let mut _0: std::option::Option<std::vec::Vec<u32>>;
|
||||||
|
let mut _1: std::vec::Vec<u32>;
|
||||||
|
let mut _2: std::boxed::Box<std::mem::MaybeUninit<[u32; 1]>>;
|
||||||
|
let mut _3: std::boxed::Box<std::mem::MaybeUninit<[u32; 1]>>;
|
||||||
|
let mut _4: u32;
|
||||||
|
let mut _5: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>;
|
||||||
|
let mut _6: std::option::Option<u32>;
|
||||||
|
let mut _7: isize;
|
||||||
|
let _8: std::option::Option<std::convert::Infallible>;
|
||||||
|
let mut _9: !;
|
||||||
|
let mut _10: std::option::Option<std::convert::Infallible>;
|
||||||
|
let _11: u32;
|
||||||
|
scope 1 {
|
||||||
|
debug residual => _8;
|
||||||
|
scope 2 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scope 3 {
|
||||||
|
debug val => _11;
|
||||||
|
scope 4 {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bb0: {
|
||||||
|
StorageLive(_1);
|
||||||
|
StorageLive(_2);
|
||||||
|
StorageLive(_3);
|
||||||
|
_3 = Box::<[u32; 1]>::new_uninit() -> [return: bb1, unwind continue];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb1: {
|
||||||
|
StorageLive(_4);
|
||||||
|
StorageLive(_5);
|
||||||
|
StorageLive(_6);
|
||||||
|
_6 = Option::<u32>::None;
|
||||||
|
_5 = <Option<u32> as Try>::branch(move _6) -> [return: bb2, unwind: bb13];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb2: {
|
||||||
|
StorageDead(_6);
|
||||||
|
PlaceMention(_5);
|
||||||
|
_7 = discriminant(_5);
|
||||||
|
switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb3];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb3: {
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb4: {
|
||||||
|
StorageLive(_11);
|
||||||
|
_11 = copy ((_5 as Continue).0: u32);
|
||||||
|
_4 = copy _11;
|
||||||
|
StorageDead(_11);
|
||||||
|
((((*_3).1: std::mem::ManuallyDrop<[u32; 1]>).0: std::mem::MaybeDangling<[u32; 1]>).0: [u32; 1]) = [move _4];
|
||||||
|
StorageDead(_4);
|
||||||
|
_2 = move _3;
|
||||||
|
goto -> bb7;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb5: {
|
||||||
|
StorageLive(_8);
|
||||||
|
_8 = copy ((_5 as Break).0: std::option::Option<std::convert::Infallible>);
|
||||||
|
StorageLive(_10);
|
||||||
|
_10 = copy _8;
|
||||||
|
_0 = <Option<Vec<u32>> as FromResidual<Option<Infallible>>>::from_residual(move _10) -> [return: bb6, unwind: bb13];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb6: {
|
||||||
|
StorageDead(_10);
|
||||||
|
StorageDead(_8);
|
||||||
|
StorageDead(_4);
|
||||||
|
drop(_3) -> [return: bb10, unwind: bb14];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb7: {
|
||||||
|
StorageDead(_3);
|
||||||
|
_1 = std::boxed::box_assume_init_into_vec_unsafe::<u32, 1>(move _2) -> [return: bb8, unwind: bb12];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb8: {
|
||||||
|
StorageDead(_2);
|
||||||
|
_0 = Option::<Vec<u32>>::Some(move _1);
|
||||||
|
goto -> bb9;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb9: {
|
||||||
|
StorageDead(_1);
|
||||||
|
StorageDead(_5);
|
||||||
|
goto -> bb11;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb10: {
|
||||||
|
StorageDead(_3);
|
||||||
|
StorageDead(_2);
|
||||||
|
StorageDead(_1);
|
||||||
|
StorageDead(_5);
|
||||||
|
goto -> bb11;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb11: {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb12 (cleanup): {
|
||||||
|
goto -> bb14;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb13 (cleanup): {
|
||||||
|
drop(_3) -> [return: bb14, unwind terminate(cleanup)];
|
||||||
|
}
|
||||||
|
|
||||||
|
bb14 (cleanup): {
|
||||||
|
resume;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
// MIR for `test` before ElaborateDrops
|
|
||||||
|
|
||||||
fn test() -> Option<Box<u32>> {
|
|
||||||
let mut _0: std::option::Option<std::boxed::Box<u32>>;
|
|
||||||
let mut _1: std::boxed::Box<u32>;
|
|
||||||
let mut _2: *mut u8;
|
|
||||||
let mut _3: std::boxed::Box<u32>;
|
|
||||||
let mut _4: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>;
|
|
||||||
let mut _5: std::option::Option<u32>;
|
|
||||||
let mut _6: isize;
|
|
||||||
let _7: std::option::Option<std::convert::Infallible>;
|
|
||||||
let mut _8: !;
|
|
||||||
let mut _9: std::option::Option<std::convert::Infallible>;
|
|
||||||
let _10: u32;
|
|
||||||
scope 1 {
|
|
||||||
debug residual => _7;
|
|
||||||
scope 2 {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scope 3 {
|
|
||||||
debug val => _10;
|
|
||||||
scope 4 {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bb0: {
|
|
||||||
StorageLive(_1);
|
|
||||||
_2 = alloc::alloc::exchange_malloc(const <u32 as std::mem::SizedTypeProperties>::SIZE, const <u32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind: bb13];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb1: {
|
|
||||||
StorageLive(_3);
|
|
||||||
_3 = ShallowInitBox(move _2, u32);
|
|
||||||
StorageLive(_4);
|
|
||||||
StorageLive(_5);
|
|
||||||
_5 = Option::<u32>::None;
|
|
||||||
_4 = <Option<u32> as Try>::branch(move _5) -> [return: bb2, unwind: bb12];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb2: {
|
|
||||||
StorageDead(_5);
|
|
||||||
PlaceMention(_4);
|
|
||||||
_6 = discriminant(_4);
|
|
||||||
switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb3];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb3: {
|
|
||||||
unreachable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb4: {
|
|
||||||
StorageLive(_10);
|
|
||||||
_10 = copy ((_4 as Continue).0: u32);
|
|
||||||
(*_3) = copy _10;
|
|
||||||
StorageDead(_10);
|
|
||||||
_1 = move _3;
|
|
||||||
drop(_3) -> [return: bb7, unwind: bb11];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb5: {
|
|
||||||
StorageLive(_7);
|
|
||||||
_7 = copy ((_4 as Break).0: std::option::Option<std::convert::Infallible>);
|
|
||||||
StorageLive(_9);
|
|
||||||
_9 = copy _7;
|
|
||||||
_0 = <Option<Box<u32>> as FromResidual<Option<Infallible>>>::from_residual(move _9) -> [return: bb6, unwind: bb12];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb6: {
|
|
||||||
StorageDead(_9);
|
|
||||||
StorageDead(_7);
|
|
||||||
drop(_3) -> [return: bb9, unwind: bb13];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb7: {
|
|
||||||
StorageDead(_3);
|
|
||||||
_0 = Option::<Box<u32>>::Some(move _1);
|
|
||||||
drop(_1) -> [return: bb8, unwind: bb13];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb8: {
|
|
||||||
StorageDead(_1);
|
|
||||||
StorageDead(_4);
|
|
||||||
goto -> bb10;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb9: {
|
|
||||||
StorageDead(_3);
|
|
||||||
StorageDead(_1);
|
|
||||||
StorageDead(_4);
|
|
||||||
goto -> bb10;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb10: {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb11 (cleanup): {
|
|
||||||
drop(_1) -> [return: bb13, unwind terminate(cleanup)];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb12 (cleanup): {
|
|
||||||
drop(_3) -> [return: bb13, unwind terminate(cleanup)];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb13 (cleanup): {
|
|
||||||
resume;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
// MIR for `test` before ElaborateDrops
|
|
||||||
|
|
||||||
fn test() -> Option<Box<u32>> {
|
|
||||||
let mut _0: std::option::Option<std::boxed::Box<u32>>;
|
|
||||||
let mut _1: std::boxed::Box<u32>;
|
|
||||||
let mut _2: *mut u8;
|
|
||||||
let mut _3: std::boxed::Box<u32>;
|
|
||||||
let mut _4: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, u32>;
|
|
||||||
let mut _5: std::option::Option<u32>;
|
|
||||||
let mut _6: isize;
|
|
||||||
let _7: std::option::Option<std::convert::Infallible>;
|
|
||||||
let mut _8: !;
|
|
||||||
let mut _9: std::option::Option<std::convert::Infallible>;
|
|
||||||
let _10: u32;
|
|
||||||
scope 1 {
|
|
||||||
debug residual => _7;
|
|
||||||
scope 2 {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scope 3 {
|
|
||||||
debug val => _10;
|
|
||||||
scope 4 {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bb0: {
|
|
||||||
StorageLive(_1);
|
|
||||||
_2 = alloc::alloc::exchange_malloc(const <u32 as std::mem::SizedTypeProperties>::SIZE, const <u32 as std::mem::SizedTypeProperties>::ALIGN) -> [return: bb1, unwind continue];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb1: {
|
|
||||||
StorageLive(_3);
|
|
||||||
_3 = ShallowInitBox(move _2, u32);
|
|
||||||
StorageLive(_4);
|
|
||||||
StorageLive(_5);
|
|
||||||
_5 = Option::<u32>::None;
|
|
||||||
_4 = <Option<u32> as Try>::branch(move _5) -> [return: bb2, unwind: bb12];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb2: {
|
|
||||||
StorageDead(_5);
|
|
||||||
PlaceMention(_4);
|
|
||||||
_6 = discriminant(_4);
|
|
||||||
switchInt(move _6) -> [0: bb4, 1: bb5, otherwise: bb3];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb3: {
|
|
||||||
unreachable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb4: {
|
|
||||||
StorageLive(_10);
|
|
||||||
_10 = copy ((_4 as Continue).0: u32);
|
|
||||||
(*_3) = copy _10;
|
|
||||||
StorageDead(_10);
|
|
||||||
_1 = move _3;
|
|
||||||
drop(_3) -> [return: bb7, unwind: bb11];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb5: {
|
|
||||||
StorageLive(_7);
|
|
||||||
_7 = copy ((_4 as Break).0: std::option::Option<std::convert::Infallible>);
|
|
||||||
StorageLive(_9);
|
|
||||||
_9 = copy _7;
|
|
||||||
_0 = <Option<Box<u32>> as FromResidual<Option<Infallible>>>::from_residual(move _9) -> [return: bb6, unwind: bb12];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb6: {
|
|
||||||
StorageDead(_9);
|
|
||||||
StorageDead(_7);
|
|
||||||
drop(_3) -> [return: bb9, unwind continue];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb7: {
|
|
||||||
StorageDead(_3);
|
|
||||||
_0 = Option::<Box<u32>>::Some(move _1);
|
|
||||||
drop(_1) -> [return: bb8, unwind continue];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb8: {
|
|
||||||
StorageDead(_1);
|
|
||||||
StorageDead(_4);
|
|
||||||
goto -> bb10;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb9: {
|
|
||||||
StorageDead(_3);
|
|
||||||
StorageDead(_1);
|
|
||||||
StorageDead(_4);
|
|
||||||
goto -> bb10;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb10: {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bb11 (cleanup): {
|
|
||||||
drop(_1) -> [return: bb13, unwind terminate(cleanup)];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb12 (cleanup): {
|
|
||||||
drop(_3) -> [return: bb13, unwind terminate(cleanup)];
|
|
||||||
}
|
|
||||||
|
|
||||||
bb13 (cleanup): {
|
|
||||||
resume;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,33 +5,36 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
||||||
debug f => _2;
|
debug f => _2;
|
||||||
let mut _0: ();
|
let mut _0: ();
|
||||||
let mut _10: usize;
|
let mut _10: usize;
|
||||||
let mut _28: std::option::Option<(usize, &T)>;
|
let mut _31: std::option::Option<(usize, &T)>;
|
||||||
let mut _31: &impl Fn(usize, &T);
|
let mut _34: &impl Fn(usize, &T);
|
||||||
let mut _32: (usize, &T);
|
let mut _35: (usize, &T);
|
||||||
let _33: ();
|
let _36: ();
|
||||||
scope 1 {
|
scope 1 {
|
||||||
debug (((iter: Enumerate<std::slice::Iter<'_, T>>).0: std::slice::Iter<'_, T>).0: std::ptr::NonNull<T>) => _6;
|
debug (((iter: Enumerate<std::slice::Iter<'_, T>>).0: std::slice::Iter<'_, T>).0: std::ptr::NonNull<T>) => _6;
|
||||||
debug (((iter: Enumerate<std::slice::Iter<'_, T>>).0: std::slice::Iter<'_, T>).1: *const T) => _9;
|
debug (((iter: Enumerate<std::slice::Iter<'_, T>>).0: std::slice::Iter<'_, T>).1: *const T) => _9;
|
||||||
debug (((iter: Enumerate<std::slice::Iter<'_, T>>).0: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>;
|
debug (((iter: Enumerate<std::slice::Iter<'_, T>>).0: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>;
|
||||||
debug ((iter: Enumerate<std::slice::Iter<'_, T>>).1: usize) => _10;
|
debug ((iter: Enumerate<std::slice::Iter<'_, T>>).1: usize) => _10;
|
||||||
let _29: usize;
|
let _32: usize;
|
||||||
let _30: &T;
|
let _33: &T;
|
||||||
scope 2 {
|
scope 2 {
|
||||||
debug i => _29;
|
debug i => _32;
|
||||||
debug x => _30;
|
debug x => _33;
|
||||||
}
|
}
|
||||||
scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
|
scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
|
||||||
let mut _23: std::option::Option<&T>;
|
let mut _21: std::option::Option<std::convert::Infallible>;
|
||||||
let mut _26: (usize, bool);
|
let mut _26: std::option::Option<&T>;
|
||||||
let mut _27: (usize, &T);
|
let mut _29: (usize, bool);
|
||||||
|
let mut _30: (usize, &T);
|
||||||
scope 19 {
|
scope 19 {
|
||||||
let _25: usize;
|
let _28: usize;
|
||||||
scope 24 {
|
scope 24 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope 20 {
|
scope 20 {
|
||||||
scope 21 {
|
scope 21 {
|
||||||
scope 27 (inlined <Option<(usize, &T)> as FromResidual<Option<Infallible>>>::from_residual) {
|
scope 27 (inlined <Option<(usize, &T)> as FromResidual<Option<Infallible>>>::from_residual) {
|
||||||
|
let mut _20: isize;
|
||||||
|
let mut _22: bool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -40,7 +43,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope 25 (inlined <Option<&T> as Try>::branch) {
|
scope 25 (inlined <Option<&T> as Try>::branch) {
|
||||||
let _24: &T;
|
let _27: &T;
|
||||||
scope 26 {
|
scope 26 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -49,8 +52,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
||||||
let _11: std::ptr::NonNull<T>;
|
let _11: std::ptr::NonNull<T>;
|
||||||
let _13: std::ptr::NonNull<T>;
|
let _13: std::ptr::NonNull<T>;
|
||||||
let mut _16: bool;
|
let mut _16: bool;
|
||||||
let mut _20: usize;
|
let mut _23: usize;
|
||||||
let _22: &T;
|
let _25: &T;
|
||||||
scope 29 {
|
scope 29 {
|
||||||
let _12: *const T;
|
let _12: *const T;
|
||||||
scope 30 {
|
scope 30 {
|
||||||
|
|
@ -84,7 +87,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope 43 (inlined NonNull::<T>::as_ref::<'_>) {
|
scope 43 (inlined NonNull::<T>::as_ref::<'_>) {
|
||||||
let _21: *const T;
|
let _24: *const T;
|
||||||
scope 44 (inlined NonNull::<T>::as_ptr) {
|
scope 44 (inlined NonNull::<T>::as_ptr) {
|
||||||
}
|
}
|
||||||
scope 45 (inlined std::ptr::mut_ptr::<impl *mut T>::cast_const) {
|
scope 45 (inlined std::ptr::mut_ptr::<impl *mut T>::cast_const) {
|
||||||
|
|
@ -169,16 +172,16 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
||||||
}
|
}
|
||||||
|
|
||||||
bb4: {
|
bb4: {
|
||||||
|
StorageLive(_31);
|
||||||
StorageLive(_28);
|
StorageLive(_28);
|
||||||
StorageLive(_25);
|
StorageLive(_29);
|
||||||
StorageLive(_26);
|
StorageLive(_26);
|
||||||
StorageLive(_23);
|
|
||||||
StorageLive(_11);
|
StorageLive(_11);
|
||||||
StorageLive(_12);
|
StorageLive(_12);
|
||||||
StorageLive(_19);
|
StorageLive(_19);
|
||||||
StorageLive(_20);
|
StorageLive(_23);
|
||||||
StorageLive(_13);
|
StorageLive(_13);
|
||||||
StorageLive(_22);
|
StorageLive(_25);
|
||||||
_11 = copy _6;
|
_11 = copy _6;
|
||||||
_12 = copy _9;
|
_12 = copy _9;
|
||||||
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb5, otherwise: bb8];
|
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb5, otherwise: bb8];
|
||||||
|
|
@ -224,16 +227,23 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
||||||
}
|
}
|
||||||
|
|
||||||
bb10: {
|
bb10: {
|
||||||
StorageDead(_22);
|
StorageDead(_25);
|
||||||
StorageDead(_13);
|
StorageDead(_13);
|
||||||
StorageDead(_20);
|
StorageDead(_23);
|
||||||
StorageDead(_19);
|
StorageDead(_19);
|
||||||
StorageDead(_12);
|
StorageDead(_12);
|
||||||
StorageDead(_11);
|
StorageDead(_11);
|
||||||
StorageDead(_23);
|
|
||||||
StorageDead(_26);
|
StorageDead(_26);
|
||||||
StorageDead(_25);
|
StorageLive(_20);
|
||||||
|
StorageLive(_22);
|
||||||
|
_20 = discriminant(_21);
|
||||||
|
_22 = Eq(copy _20, const 0_isize);
|
||||||
|
assume(move _22);
|
||||||
|
StorageDead(_22);
|
||||||
|
StorageDead(_20);
|
||||||
|
StorageDead(_29);
|
||||||
StorageDead(_28);
|
StorageDead(_28);
|
||||||
|
StorageDead(_31);
|
||||||
StorageDead(_10);
|
StorageDead(_10);
|
||||||
drop(_2) -> [return: bb11, unwind unreachable];
|
drop(_2) -> [return: bb11, unwind unreachable];
|
||||||
}
|
}
|
||||||
|
|
@ -243,51 +253,51 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
||||||
}
|
}
|
||||||
|
|
||||||
bb12: {
|
bb12: {
|
||||||
_20 = SubUnchecked(copy _19, const 1_usize);
|
_23 = SubUnchecked(copy _19, const 1_usize);
|
||||||
_9 = copy _20 as *const T (Transmute);
|
_9 = copy _23 as *const T (Transmute);
|
||||||
goto -> bb13;
|
goto -> bb13;
|
||||||
}
|
}
|
||||||
|
|
||||||
bb13: {
|
bb13: {
|
||||||
StorageLive(_21);
|
StorageLive(_24);
|
||||||
_21 = copy _11 as *const T (Transmute);
|
_24 = copy _11 as *const T (Transmute);
|
||||||
_22 = &(*_21);
|
_25 = &(*_24);
|
||||||
StorageDead(_21);
|
StorageDead(_24);
|
||||||
_23 = Option::<&T>::Some(copy _22);
|
_26 = Option::<&T>::Some(copy _25);
|
||||||
StorageDead(_22);
|
StorageDead(_25);
|
||||||
StorageDead(_13);
|
StorageDead(_13);
|
||||||
StorageDead(_20);
|
StorageDead(_23);
|
||||||
StorageDead(_19);
|
StorageDead(_19);
|
||||||
StorageDead(_12);
|
StorageDead(_12);
|
||||||
StorageDead(_11);
|
StorageDead(_11);
|
||||||
_24 = copy ((_23 as Some).0: &T);
|
_27 = copy ((_26 as Some).0: &T);
|
||||||
StorageDead(_23);
|
StorageDead(_26);
|
||||||
_25 = copy _10;
|
_28 = copy _10;
|
||||||
_26 = AddWithOverflow(copy _10, const 1_usize);
|
_29 = AddWithOverflow(copy _10, const 1_usize);
|
||||||
assert(!move (_26.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _10, const 1_usize) -> [success: bb14, unwind unreachable];
|
assert(!move (_29.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _10, const 1_usize) -> [success: bb14, unwind unreachable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb14: {
|
bb14: {
|
||||||
_10 = move (_26.0: usize);
|
_10 = move (_29.0: usize);
|
||||||
StorageLive(_27);
|
StorageLive(_30);
|
||||||
_27 = (copy _25, copy _24);
|
_30 = (copy _28, copy _27);
|
||||||
_28 = Option::<(usize, &T)>::Some(move _27);
|
_31 = Option::<(usize, &T)>::Some(move _30);
|
||||||
StorageDead(_27);
|
StorageDead(_30);
|
||||||
StorageDead(_26);
|
StorageDead(_29);
|
||||||
StorageDead(_25);
|
StorageDead(_28);
|
||||||
_29 = copy (((_28 as Some).0: (usize, &T)).0: usize);
|
_32 = copy (((_31 as Some).0: (usize, &T)).0: usize);
|
||||||
_30 = copy (((_28 as Some).0: (usize, &T)).1: &T);
|
_33 = copy (((_31 as Some).0: (usize, &T)).1: &T);
|
||||||
StorageLive(_31);
|
StorageLive(_34);
|
||||||
_31 = &_2;
|
_34 = &_2;
|
||||||
StorageLive(_32);
|
StorageLive(_35);
|
||||||
_32 = (copy _29, copy _30);
|
_35 = (copy _32, copy _33);
|
||||||
_33 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _31, move _32) -> [return: bb15, unwind unreachable];
|
_36 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _34, move _35) -> [return: bb15, unwind unreachable];
|
||||||
}
|
}
|
||||||
|
|
||||||
bb15: {
|
bb15: {
|
||||||
StorageDead(_32);
|
StorageDead(_35);
|
||||||
|
StorageDead(_34);
|
||||||
StorageDead(_31);
|
StorageDead(_31);
|
||||||
StorageDead(_28);
|
|
||||||
goto -> bb4;
|
goto -> bb4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
tests/ui/coercion/vec-macro-coercions.rs
Normal file
12
tests/ui/coercion/vec-macro-coercions.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let functions = &vec![
|
||||||
|
|x: i32| -> i32 { x + 3 },
|
||||||
|
|x: i32| -> i32 { x + 3 },
|
||||||
|
];
|
||||||
|
|
||||||
|
let string = String::new();
|
||||||
|
let a = vec![&string, "abc"];
|
||||||
|
let b = vec!["abc", &string];
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const fn foo(a: i32) -> Vec<i32> {
|
const fn foo(a: i32) -> Vec<i32> {
|
||||||
vec![1, 2, 3]
|
vec![1, 2, 3]
|
||||||
//~^ ERROR allocations are not allowed
|
//~^ ERROR cannot call non-const
|
||||||
//~| ERROR cannot call non-const method
|
//~| ERROR cannot call non-const
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,4 @@
|
||||||
error[E0010]: allocations are not allowed in constant functions
|
error[E0015]: cannot call non-const associated function `Box::<[i32; 3]>::new_uninit` in constant functions
|
||||||
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
|
||||||
|
|
|
||||||
LL | vec![1, 2, 3]
|
|
||||||
| ^^^^^^^^^^^^^ allocation not allowed in constant functions
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const method `slice::<impl [i32]>::into_vec::<std::alloc::Global>` in constant functions
|
|
||||||
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
||||||
|
|
|
|
||||||
LL | vec![1, 2, 3]
|
LL | vec![1, 2, 3]
|
||||||
|
|
@ -12,7 +6,16 @@ LL | vec![1, 2, 3]
|
||||||
|
|
|
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
|
|
||||||
|
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<i32, 3>` in constant functions
|
||||||
|
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
||||||
|
|
|
||||||
|
LL | vec![1, 2, 3]
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||||
|
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||||
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0010, E0015.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0010`.
|
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,11 @@ fn main() {
|
||||||
let mut g = #[coroutine]
|
let mut g = #[coroutine]
|
||||||
|| {
|
|| {
|
||||||
// This is desuraged as 4 stages:
|
// This is desuraged as 4 stages:
|
||||||
// - allocate a `*mut u8` with `exchange_malloc`;
|
// - `vec!` macro
|
||||||
// - create a Box that is ignored for trait computations;
|
// - `write_via_move`
|
||||||
// - compute fields (and yields);
|
// - compute fields (and yields);
|
||||||
// - assign to `t`.
|
// - assign to `t`.
|
||||||
let t = std::boxed::box_new((5, yield));
|
let t = vec![(5, yield)];
|
||||||
drop(t);
|
drop(t);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ fn main() {
|
||||||
// As it is not taken into account for trait computation,
|
// As it is not taken into account for trait computation,
|
||||||
// the coroutine is `Copy`.
|
// the coroutine is `Copy`.
|
||||||
let mut h = copy(g);
|
let mut h = copy(g);
|
||||||
//~^ ERROR the trait bound `Box<(i32, ())>: Copy` is not satisfied in
|
//~^ ERROR the trait bound `Box<MaybeUninit<[(i32, ()); 1]>>: Copy` is not satisfied in
|
||||||
|
|
||||||
// We now have 2 boxes with the same backing allocation:
|
// We now have 2 boxes with the same backing allocation:
|
||||||
// one inside `g` and one inside `h`.
|
// one inside `g` and one inside `h`.
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
error[E0277]: the trait bound `Box<(i32, ())>: Copy` is not satisfied in `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`
|
error[E0277]: the trait bound `Box<MaybeUninit<[(i32, ()); 1]>>: Copy` is not satisfied in `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`
|
||||||
--> $DIR/issue-105084.rs:32:17
|
--> $DIR/issue-105084.rs:32:17
|
||||||
|
|
|
|
||||||
LL | || {
|
LL | || {
|
||||||
| -- within this `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`
|
| -- within this `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`
|
||||||
...
|
...
|
||||||
LL | let mut h = copy(g);
|
LL | let mut h = copy(g);
|
||||||
| ^^^^^^^ within `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`, the trait `Copy` is not implemented for `Box<(i32, ())>`
|
| ^^^^^^^ within `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`, the trait `Copy` is not implemented for `Box<MaybeUninit<[(i32, ()); 1]>>`
|
||||||
|
|
|
|
||||||
note: coroutine does not implement `Copy` as this value is used across a yield
|
note: coroutine does not implement `Copy` as this value is used across a yield
|
||||||
--> $DIR/issue-105084.rs:22:41
|
--> $DIR/issue-105084.rs:22:26
|
||||||
|
|
|
|
||||||
LL | let t = std::boxed::box_new((5, yield));
|
LL | let t = vec![(5, yield)];
|
||||||
| ------------------------^^^^^--
|
| ---------^^^^^--
|
||||||
| | |
|
| | |
|
||||||
| | yield occurs here, with `std::boxed::box_new((5, yield))` maybe used later
|
| | yield occurs here, with the value maybe used later
|
||||||
| has type `Box<(i32, ())>` which does not implement `Copy`
|
| has type `Box<MaybeUninit<[(i32, ()); 1]>>` which does not implement `Copy`
|
||||||
note: required by a bound in `copy`
|
note: required by a bound in `copy`
|
||||||
--> $DIR/issue-105084.rs:10:12
|
--> $DIR/issue-105084.rs:10:12
|
||||||
|
|
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
//@ compile-flags: -Z teach
|
|
||||||
|
|
||||||
#![allow(warnings)]
|
|
||||||
|
|
||||||
const CON: Vec<i32> = vec![1, 2, 3]; //~ ERROR E0010
|
|
||||||
//~| ERROR cannot call non-const method
|
|
||||||
fn main() {}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
error[E0010]: allocations are not allowed in constants
|
|
||||||
--> $DIR/E0010-teach.rs:5:23
|
|
||||||
|
|
|
||||||
LL | const CON: Vec<i32> = vec![1, 2, 3];
|
|
||||||
| ^^^^^^^^^^^^^ allocation not allowed in constants
|
|
||||||
|
|
|
||||||
= note: the runtime heap is not yet available at compile-time, so no runtime heap allocations can be created
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const method `slice::<impl [i32]>::into_vec::<std::alloc::Global>` in constants
|
|
||||||
--> $DIR/E0010-teach.rs:5:23
|
|
||||||
|
|
|
||||||
LL | const CON: Vec<i32> = vec![1, 2, 3];
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0010, E0015.
|
|
||||||
For more information about an error, try `rustc --explain E0010`.
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
#![allow(warnings)]
|
|
||||||
|
|
||||||
const CON: Vec<i32> = vec![1, 2, 3]; //~ ERROR E0010
|
|
||||||
//~| ERROR cannot call non-const method
|
|
||||||
fn main() {}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
error[E0010]: allocations are not allowed in constants
|
|
||||||
--> $DIR/E0010.rs:3:23
|
|
||||||
|
|
|
||||||
LL | const CON: Vec<i32> = vec![1, 2, 3];
|
|
||||||
| ^^^^^^^^^^^^^ allocation not allowed in constants
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const method `slice::<impl [i32]>::into_vec::<std::alloc::Global>` in constants
|
|
||||||
--> $DIR/E0010.rs:3:23
|
|
||||||
|
|
|
||||||
LL | const CON: Vec<i32> = vec![1, 2, 3];
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0010, E0015.
|
|
||||||
For more information about an error, try `rustc --explain E0010`.
|
|
||||||
|
|
@ -390,14 +390,6 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani
|
||||||
- impl<F, Args> Fn<Args> for Exclusive<F>
|
- impl<F, Args> Fn<Args> for Exclusive<F>
|
||||||
where F: Sync, F: Fn<Args>, Args: std::marker::Tuple;
|
where F: Sync, F: Fn<Args>, Args: std::marker::Tuple;
|
||||||
|
|
||||||
error[E0118]: no nominal type found for inherent implementation
|
|
||||||
--> $DIR/where-allowed.rs:241:1
|
|
||||||
|
|
|
||||||
LL | impl<T = impl Debug> T {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
|
|
||||||
|
|
|
||||||
= note: either implement a trait on it or create a newtype to wrap it instead
|
|
||||||
|
|
||||||
error: unconstrained opaque type
|
error: unconstrained opaque type
|
||||||
--> $DIR/where-allowed.rs:122:16
|
--> $DIR/where-allowed.rs:122:16
|
||||||
|
|
|
|
||||||
|
|
@ -414,6 +406,14 @@ LL | type InTypeAlias<R> = impl Debug;
|
||||||
|
|
|
|
||||||
= note: `InTypeAlias` must be used in combination with a concrete type within the same crate
|
= note: `InTypeAlias` must be used in combination with a concrete type within the same crate
|
||||||
|
|
||||||
|
error[E0118]: no nominal type found for inherent implementation
|
||||||
|
--> $DIR/where-allowed.rs:241:1
|
||||||
|
|
|
||||||
|
LL | impl<T = impl Debug> T {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
|
||||||
|
|
|
||||||
|
= note: either implement a trait on it or create a newtype to wrap it instead
|
||||||
|
|
||||||
error: aborting due to 48 previous errors
|
error: aborting due to 48 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0658, E0666.
|
Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0658, E0666.
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,19 @@
|
||||||
error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture
|
|
||||||
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
|
||||||
|
|
|
||||||
= note: evaluation of `<std::mem::MaybeUninit<[&usize; usize::MAX]> as std::mem::SizedTypeProperties>::SIZE` failed here
|
|
||||||
|
|
||||||
error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture
|
|
||||||
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
|
||||||
|
|
|
||||||
= note: evaluation of `<std::mem::MaybeUninit<[&usize; usize::MAX]> as std::mem::SizedTypeProperties>::ALIGN` failed here
|
|
||||||
|
|
||||||
note: the above error was encountered while instantiating `fn Box::<[&usize; usize::MAX]>::new_uninit_in`
|
|
||||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
|
||||||
|
|
||||||
error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture
|
error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture
|
||||||
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
||||||
|
|
|
|
||||||
= note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::SIZE` failed here
|
= note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::SIZE` failed here
|
||||||
|
|
||||||
note: the above error was encountered while instantiating `fn Box::<[&usize; usize::MAX]>::try_new_uninit_in`
|
error[E0080]: values of the type `[&usize; usize::MAX]` are too big for the target architecture
|
||||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
|
||||||
|
|
|
||||||
|
= note: evaluation of `<[&usize; usize::MAX] as std::mem::SizedTypeProperties>::ALIGN` failed here
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
note: the above error was encountered while instantiating `fn Box::<[&usize; usize::MAX]>::new`
|
||||||
|
--> $DIR/issue-17913.rs:16:21
|
||||||
|
|
|
||||||
|
LL | let a: Box<_> = Box::new([&n; SIZE]);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0080`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ fn main() {
|
||||||
match Some(vec![42]) {
|
match Some(vec![42]) {
|
||||||
Some(vec![43]) => {} //~ ERROR expected a pattern, found a function call
|
Some(vec![43]) => {} //~ ERROR expected a pattern, found a function call
|
||||||
//~| ERROR found associated function
|
//~| ERROR found associated function
|
||||||
//~| ERROR usage of qualified paths in this context is experimental
|
//~| ERROR expected a pattern, found a function call
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,15 @@ LL | Some(vec![43]) => {}
|
||||||
|
|
|
|
||||||
= note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
|
= note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
|
||||||
|
|
||||||
error[E0658]: usage of qualified paths in this context is experimental
|
error[E0532]: expected a pattern, found a function call
|
||||||
--> $DIR/vec-macro-in-pattern.rs:7:14
|
--> $DIR/vec-macro-in-pattern.rs:7:14
|
||||||
|
|
|
|
||||||
LL | Some(vec![43]) => {}
|
LL | Some(vec![43]) => {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^ not a tuple struct or tuple variant
|
||||||
|
|
|
|
||||||
= note: see issue #86935 <https://github.com/rust-lang/rust/issues/86935> for more information
|
= note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
|
||||||
= help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable
|
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
||||||
|
|
||||||
error[E0164]: expected tuple struct or tuple variant, found associated function `<[_]>::into_vec`
|
error[E0164]: expected tuple struct or tuple variant, found associated function `::alloc::boxed::Box::new_uninit`
|
||||||
--> $DIR/vec-macro-in-pattern.rs:7:14
|
--> $DIR/vec-macro-in-pattern.rs:7:14
|
||||||
|
|
|
|
||||||
LL | Some(vec![43]) => {}
|
LL | Some(vec![43]) => {}
|
||||||
|
|
@ -26,5 +24,5 @@ LL | Some(vec![43]) => {}
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0164, E0532, E0658.
|
Some errors have detailed explanations: E0164, E0532.
|
||||||
For more information about an error, try `rustc --explain E0164`.
|
For more information about an error, try `rustc --explain E0164`.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
//! regression test for issue <https://github.com/rust-lang/rust/issues/47184>
|
|
||||||
fn main() {
|
|
||||||
let _vec: Vec<&'static String> = vec![&String::new()];
|
|
||||||
//~^ ERROR temporary value dropped while borrowed [E0716]
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
error[E0716]: temporary value dropped while borrowed
|
|
||||||
--> $DIR/borrowck-annotate-static-lifetime.rs:3:44
|
|
||||||
|
|
|
||||||
LL | let _vec: Vec<&'static String> = vec![&String::new()];
|
|
||||||
| -------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
|
|
||||||
| | |
|
|
||||||
| | creates a temporary value which is freed while still in use
|
|
||||||
| type annotation requires that borrow lasts for `'static`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0716`.
|
|
||||||
|
|
@ -70,6 +70,11 @@ fn underscore_with_initializer() {
|
||||||
//~^ ERROR temporary value dropped while borrowed [E0716]
|
//~^ ERROR temporary value dropped while borrowed [E0716]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn issue_47184() {
|
||||||
|
let _vec: Vec<&'static String> = vec![&String::new()];
|
||||||
|
//~^ ERROR temporary value dropped while borrowed [E0716]
|
||||||
|
}
|
||||||
|
|
||||||
fn pair_underscores_with_initializer() {
|
fn pair_underscores_with_initializer() {
|
||||||
let x = 22;
|
let x = 22;
|
||||||
let (_, _): (&'static u32, u32) = (&x, 44); //~ ERROR
|
let (_, _): (&'static u32, u32) = (&x, 44); //~ ERROR
|
||||||
|
|
|
||||||
|
|
@ -111,8 +111,17 @@ LL | let (_a, b): (Vec<&'static String>, _) = (vec![&String::new()], 44);
|
||||||
| | creates a temporary value which is freed while still in use
|
| | creates a temporary value which is freed while still in use
|
||||||
| type annotation requires that borrow lasts for `'static`
|
| type annotation requires that borrow lasts for `'static`
|
||||||
|
|
||||||
|
error[E0716]: temporary value dropped while borrowed
|
||||||
|
--> $DIR/patterns.rs:74:44
|
||||||
|
|
|
||||||
|
LL | let _vec: Vec<&'static String> = vec![&String::new()];
|
||||||
|
| -------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
|
||||||
|
| | |
|
||||||
|
| | creates a temporary value which is freed while still in use
|
||||||
|
| type annotation requires that borrow lasts for `'static`
|
||||||
|
|
||||||
error[E0597]: `x` does not live long enough
|
error[E0597]: `x` does not live long enough
|
||||||
--> $DIR/patterns.rs:75:40
|
--> $DIR/patterns.rs:80:40
|
||||||
|
|
|
|
||||||
LL | let x = 22;
|
LL | let x = 22;
|
||||||
| - binding `x` declared here
|
| - binding `x` declared here
|
||||||
|
|
@ -124,7 +133,7 @@ LL | }
|
||||||
| - `x` dropped here while still borrowed
|
| - `x` dropped here while still borrowed
|
||||||
|
|
||||||
error[E0597]: `x` does not live long enough
|
error[E0597]: `x` does not live long enough
|
||||||
--> $DIR/patterns.rs:80:40
|
--> $DIR/patterns.rs:85:40
|
||||||
|
|
|
|
||||||
LL | let x = 22;
|
LL | let x = 22;
|
||||||
| - binding `x` declared here
|
| - binding `x` declared here
|
||||||
|
|
@ -136,7 +145,7 @@ LL | }
|
||||||
| - `x` dropped here while still borrowed
|
| - `x` dropped here while still borrowed
|
||||||
|
|
||||||
error[E0597]: `x` does not live long enough
|
error[E0597]: `x` does not live long enough
|
||||||
--> $DIR/patterns.rs:85:69
|
--> $DIR/patterns.rs:90:69
|
||||||
|
|
|
|
||||||
LL | let x = 22;
|
LL | let x = 22;
|
||||||
| - binding `x` declared here
|
| - binding `x` declared here
|
||||||
|
|
@ -148,7 +157,7 @@ LL | }
|
||||||
| - `x` dropped here while still borrowed
|
| - `x` dropped here while still borrowed
|
||||||
|
|
||||||
error[E0597]: `x` does not live long enough
|
error[E0597]: `x` does not live long enough
|
||||||
--> $DIR/patterns.rs:90:69
|
--> $DIR/patterns.rs:95:69
|
||||||
|
|
|
|
||||||
LL | let x = 22;
|
LL | let x = 22;
|
||||||
| - binding `x` declared here
|
| - binding `x` declared here
|
||||||
|
|
@ -160,7 +169,7 @@ LL | }
|
||||||
| - `x` dropped here while still borrowed
|
| - `x` dropped here while still borrowed
|
||||||
|
|
||||||
error[E0597]: `x` does not live long enough
|
error[E0597]: `x` does not live long enough
|
||||||
--> $DIR/patterns.rs:98:17
|
--> $DIR/patterns.rs:103:17
|
||||||
|
|
|
|
||||||
LL | let x = 22;
|
LL | let x = 22;
|
||||||
| - binding `x` declared here
|
| - binding `x` declared here
|
||||||
|
|
@ -173,7 +182,7 @@ LL | }
|
||||||
| - `x` dropped here while still borrowed
|
| - `x` dropped here while still borrowed
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/patterns.rs:111:5
|
--> $DIR/patterns.rs:116:5
|
||||||
|
|
|
|
||||||
LL | fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 {
|
LL | fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
|
|
@ -182,7 +191,7 @@ LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ returning this value requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/patterns.rs:123:5
|
--> $DIR/patterns.rs:128:5
|
||||||
|
|
|
|
||||||
LL | fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 {
|
LL | fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
|
|
@ -191,7 +200,7 @@ LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ returning this value requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/patterns.rs:128:5
|
--> $DIR/patterns.rs:133:5
|
||||||
|
|
|
|
||||||
LL | fn static_to_a_to_static_through_struct<'a>(_x: &'a u32) -> &'static u32 {
|
LL | fn static_to_a_to_static_through_struct<'a>(_x: &'a u32) -> &'static u32 {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
|
|
@ -200,14 +209,14 @@ LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ returning this value requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/patterns.rs:132:18
|
--> $DIR/patterns.rs:137:18
|
||||||
|
|
|
|
||||||
LL | fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 {
|
LL | fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
LL | let (y, _z): (&'static u32, u32) = (x, 44);
|
LL | let (y, _z): (&'static u32, u32) = (x, 44);
|
||||||
| ^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: aborting due to 19 previous errors
|
error: aborting due to 20 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0597, E0716.
|
Some errors have detailed explanations: E0597, E0716.
|
||||||
For more information about an error, try `rustc --explain E0597`.
|
For more information about an error, try `rustc --explain E0597`.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
let vec![const { vec![] }]: Vec<usize> = vec![];
|
let vec![const { vec![] }]: Vec<usize> = vec![];
|
||||||
//~^ ERROR expected a pattern, found a function call
|
//~^ ERROR expected a pattern, found a function call
|
||||||
//~| ERROR usage of qualified paths in this context is experimental
|
//~| ERROR expected a pattern, found a function call
|
||||||
//~| ERROR expected tuple struct or tuple variant
|
//~| ERROR expected tuple struct or tuple variant
|
||||||
//~| ERROR arbitrary expressions aren't allowed in patterns
|
//~| ERROR arbitrary expressions aren't allowed in patterns
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,13 @@ LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
||||||
|
|
|
|
||||||
= note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
|
= note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
|
||||||
|
|
||||||
error[E0658]: usage of qualified paths in this context is experimental
|
error[E0532]: expected a pattern, found a function call
|
||||||
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9
|
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9
|
||||||
|
|
|
|
||||||
LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
|
||||||
|
|
|
|
||||||
= note: see issue #86935 <https://github.com/rust-lang/rust/issues/86935> for more information
|
= note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
|
||||||
= help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable
|
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
||||||
|
|
||||||
error: arbitrary expressions aren't allowed in patterns
|
error: arbitrary expressions aren't allowed in patterns
|
||||||
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:14
|
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:14
|
||||||
|
|
@ -24,7 +22,7 @@ LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
||||||
|
|
|
|
||||||
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
|
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
|
||||||
|
|
||||||
error[E0164]: expected tuple struct or tuple variant, found associated function `<[_]>::into_vec`
|
error[E0164]: expected tuple struct or tuple variant, found associated function `::alloc::boxed::Box::new_uninit`
|
||||||
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9
|
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9
|
||||||
|
|
|
|
||||||
LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
||||||
|
|
@ -34,5 +32,5 @@ LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0164, E0532, E0658.
|
Some errors have detailed explanations: E0164, E0532.
|
||||||
For more information about an error, try `rustc --explain E0164`.
|
For more information about an error, try `rustc --explain E0164`.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0716]: temporary value dropped while borrowed
|
error[E0716]: temporary value dropped while borrowed
|
||||||
--> $DIR/issue-15480.rs:6:10
|
--> $DIR/vec-macro-outlives-issue-15480.rs:6:10
|
||||||
|
|
|
|
||||||
LL | &id(3)
|
LL | &id(3)
|
||||||
| ^^^^^ creates a temporary value which is freed while still in use
|
| ^^^^^ creates a temporary value which is freed while still in use
|
||||||
|
|
@ -79,8 +79,8 @@ static STATIC10: UnsafeStruct = UnsafeStruct;
|
||||||
struct MyOwned;
|
struct MyOwned;
|
||||||
|
|
||||||
static STATIC11: Vec<MyOwned> = vec![MyOwned];
|
static STATIC11: Vec<MyOwned> = vec![MyOwned];
|
||||||
//~^ ERROR allocations are not allowed in statics
|
//~^ ERROR cannot call non-const function
|
||||||
//~^^ ERROR cannot call non-const
|
//~| ERROR cannot call non-const
|
||||||
|
|
||||||
static mut STATIC12: UnsafeStruct = UnsafeStruct;
|
static mut STATIC12: UnsafeStruct = UnsafeStruct;
|
||||||
|
|
||||||
|
|
@ -93,29 +93,29 @@ static mut STATIC14: SafeStruct = SafeStruct {
|
||||||
};
|
};
|
||||||
|
|
||||||
static STATIC15: &'static [Vec<MyOwned>] = &[
|
static STATIC15: &'static [Vec<MyOwned>] = &[
|
||||||
vec![MyOwned], //~ ERROR allocations are not allowed in statics
|
vec![MyOwned], //~ ERROR cannot call non-const function
|
||||||
//~^ ERROR cannot call non-const
|
//~| ERROR cannot call non-const
|
||||||
vec![MyOwned], //~ ERROR allocations are not allowed in statics
|
vec![MyOwned], //~ ERROR cannot call non-const function
|
||||||
//~^ ERROR cannot call non-const
|
//~| ERROR cannot call non-const
|
||||||
];
|
];
|
||||||
|
|
||||||
static STATIC16: (&'static Vec<MyOwned>, &'static Vec<MyOwned>) = (
|
static STATIC16: (&'static Vec<MyOwned>, &'static Vec<MyOwned>) = (
|
||||||
&vec![MyOwned], //~ ERROR allocations are not allowed in statics
|
&vec![MyOwned], //~ ERROR cannot call non-const function
|
||||||
//~^ ERROR cannot call non-const
|
//~| ERROR cannot call non-const
|
||||||
&vec![MyOwned], //~ ERROR allocations are not allowed in statics
|
&vec![MyOwned], //~ ERROR cannot call non-const function
|
||||||
//~^ ERROR cannot call non-const
|
//~| ERROR cannot call non-const
|
||||||
);
|
);
|
||||||
|
|
||||||
static mut STATIC17: SafeEnum = SafeEnum::Variant1;
|
static mut STATIC17: SafeEnum = SafeEnum::Variant1;
|
||||||
|
|
||||||
static STATIC19: Vec<isize> = vec![3];
|
static STATIC19: Vec<isize> = vec![3];
|
||||||
//~^ ERROR allocations are not allowed in statics
|
//~^ ERROR cannot call non-const function
|
||||||
//~^^ ERROR cannot call non-const
|
//~| ERROR cannot call non-const
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let y = {
|
let y = {
|
||||||
static x: Vec<isize> = vec![3]; //~ ERROR allocations are not allowed in statics
|
static x: Vec<isize> = vec![3]; //~ ERROR cannot call non-const function
|
||||||
//~^ ERROR cannot call non-const
|
//~| ERROR cannot call non-const
|
||||||
x
|
x
|
||||||
//~^ ERROR cannot move out of static
|
//~^ ERROR cannot move out of static
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,7 @@ LL | | }
|
||||||
LL | };
|
LL | };
|
||||||
| - value is dropped here
|
| - value is dropped here
|
||||||
|
|
||||||
error[E0010]: allocations are not allowed in statics
|
error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics
|
||||||
--> $DIR/check-values-constraints.rs:81:33
|
|
||||||
|
|
|
||||||
LL | static STATIC11: Vec<MyOwned> = vec![MyOwned];
|
|
||||||
| ^^^^^^^^^^^^^ allocation not allowed in statics
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const method `slice::<impl [MyOwned]>::into_vec::<std::alloc::Global>` in statics
|
|
||||||
--> $DIR/check-values-constraints.rs:81:33
|
--> $DIR/check-values-constraints.rs:81:33
|
||||||
|
|
|
|
||||||
LL | static STATIC11: Vec<MyOwned> = vec![MyOwned];
|
LL | static STATIC11: Vec<MyOwned> = vec![MyOwned];
|
||||||
|
|
@ -26,6 +20,17 @@ LL | static STATIC11: Vec<MyOwned> = vec![MyOwned];
|
||||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||||
|
|
||||||
|
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<MyOwned, 1>` in statics
|
||||||
|
--> $DIR/check-values-constraints.rs:81:33
|
||||||
|
|
|
||||||
|
LL | static STATIC11: Vec<MyOwned> = vec![MyOwned];
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||||
|
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||||
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||||
|
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||||
|
|
||||||
error[E0015]: cannot call non-const method `<str as ToString>::to_string` in statics
|
error[E0015]: cannot call non-const method `<str as ToString>::to_string` in statics
|
||||||
--> $DIR/check-values-constraints.rs:92:38
|
--> $DIR/check-values-constraints.rs:92:38
|
||||||
|
|
|
|
||||||
|
|
@ -42,13 +47,7 @@ note: method `to_string` is not const because trait `ToString` is not const
|
||||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||||
|
|
||||||
error[E0010]: allocations are not allowed in statics
|
error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics
|
||||||
--> $DIR/check-values-constraints.rs:96:5
|
|
||||||
|
|
|
||||||
LL | vec![MyOwned],
|
|
||||||
| ^^^^^^^^^^^^^ allocation not allowed in statics
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const method `slice::<impl [MyOwned]>::into_vec::<std::alloc::Global>` in statics
|
|
||||||
--> $DIR/check-values-constraints.rs:96:5
|
--> $DIR/check-values-constraints.rs:96:5
|
||||||
|
|
|
|
||||||
LL | vec![MyOwned],
|
LL | vec![MyOwned],
|
||||||
|
|
@ -57,13 +56,18 @@ LL | vec![MyOwned],
|
||||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||||
|
|
||||||
error[E0010]: allocations are not allowed in statics
|
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<MyOwned, 1>` in statics
|
||||||
--> $DIR/check-values-constraints.rs:98:5
|
--> $DIR/check-values-constraints.rs:96:5
|
||||||
|
|
|
|
||||||
LL | vec![MyOwned],
|
LL | vec![MyOwned],
|
||||||
| ^^^^^^^^^^^^^ allocation not allowed in statics
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||||
|
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||||
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||||
|
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||||
|
|
||||||
error[E0015]: cannot call non-const method `slice::<impl [MyOwned]>::into_vec::<std::alloc::Global>` in statics
|
error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics
|
||||||
--> $DIR/check-values-constraints.rs:98:5
|
--> $DIR/check-values-constraints.rs:98:5
|
||||||
|
|
|
|
||||||
LL | vec![MyOwned],
|
LL | vec![MyOwned],
|
||||||
|
|
@ -72,13 +76,18 @@ LL | vec![MyOwned],
|
||||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||||
|
|
||||||
error[E0010]: allocations are not allowed in statics
|
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<MyOwned, 1>` in statics
|
||||||
--> $DIR/check-values-constraints.rs:103:6
|
--> $DIR/check-values-constraints.rs:98:5
|
||||||
|
|
|
|
||||||
LL | &vec![MyOwned],
|
LL | vec![MyOwned],
|
||||||
| ^^^^^^^^^^^^^ allocation not allowed in statics
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||||
|
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||||
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||||
|
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||||
|
|
||||||
error[E0015]: cannot call non-const method `slice::<impl [MyOwned]>::into_vec::<std::alloc::Global>` in statics
|
error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics
|
||||||
--> $DIR/check-values-constraints.rs:103:6
|
--> $DIR/check-values-constraints.rs:103:6
|
||||||
|
|
|
|
||||||
LL | &vec![MyOwned],
|
LL | &vec![MyOwned],
|
||||||
|
|
@ -87,13 +96,18 @@ LL | &vec![MyOwned],
|
||||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||||
|
|
||||||
error[E0010]: allocations are not allowed in statics
|
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<MyOwned, 1>` in statics
|
||||||
--> $DIR/check-values-constraints.rs:105:6
|
--> $DIR/check-values-constraints.rs:103:6
|
||||||
|
|
|
|
||||||
LL | &vec![MyOwned],
|
LL | &vec![MyOwned],
|
||||||
| ^^^^^^^^^^^^^ allocation not allowed in statics
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||||
|
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||||
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||||
|
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||||
|
|
||||||
error[E0015]: cannot call non-const method `slice::<impl [MyOwned]>::into_vec::<std::alloc::Global>` in statics
|
error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics
|
||||||
--> $DIR/check-values-constraints.rs:105:6
|
--> $DIR/check-values-constraints.rs:105:6
|
||||||
|
|
|
|
||||||
LL | &vec![MyOwned],
|
LL | &vec![MyOwned],
|
||||||
|
|
@ -102,13 +116,18 @@ LL | &vec![MyOwned],
|
||||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||||
|
|
||||||
error[E0010]: allocations are not allowed in statics
|
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<MyOwned, 1>` in statics
|
||||||
--> $DIR/check-values-constraints.rs:111:31
|
--> $DIR/check-values-constraints.rs:105:6
|
||||||
|
|
|
|
||||||
LL | static STATIC19: Vec<isize> = vec![3];
|
LL | &vec![MyOwned],
|
||||||
| ^^^^^^^ allocation not allowed in statics
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||||
|
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||||
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||||
|
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||||
|
|
||||||
error[E0015]: cannot call non-const method `slice::<impl [isize]>::into_vec::<std::alloc::Global>` in statics
|
error[E0015]: cannot call non-const associated function `Box::<[isize; 1]>::new_uninit` in statics
|
||||||
--> $DIR/check-values-constraints.rs:111:31
|
--> $DIR/check-values-constraints.rs:111:31
|
||||||
|
|
|
|
||||||
LL | static STATIC19: Vec<isize> = vec![3];
|
LL | static STATIC19: Vec<isize> = vec![3];
|
||||||
|
|
@ -117,13 +136,18 @@ LL | static STATIC19: Vec<isize> = vec![3];
|
||||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||||
|
|
||||||
error[E0010]: allocations are not allowed in statics
|
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<isize, 1>` in statics
|
||||||
--> $DIR/check-values-constraints.rs:117:32
|
--> $DIR/check-values-constraints.rs:111:31
|
||||||
|
|
|
|
||||||
LL | static x: Vec<isize> = vec![3];
|
LL | static STATIC19: Vec<isize> = vec![3];
|
||||||
| ^^^^^^^ allocation not allowed in statics
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||||
|
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||||
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||||
|
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||||
|
|
||||||
error[E0015]: cannot call non-const method `slice::<impl [isize]>::into_vec::<std::alloc::Global>` in statics
|
error[E0015]: cannot call non-const associated function `Box::<[isize; 1]>::new_uninit` in statics
|
||||||
--> $DIR/check-values-constraints.rs:117:32
|
--> $DIR/check-values-constraints.rs:117:32
|
||||||
|
|
|
|
||||||
LL | static x: Vec<isize> = vec![3];
|
LL | static x: Vec<isize> = vec![3];
|
||||||
|
|
@ -132,6 +156,17 @@ LL | static x: Vec<isize> = vec![3];
|
||||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||||
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||||
|
|
||||||
|
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<isize, 1>` in statics
|
||||||
|
--> $DIR/check-values-constraints.rs:117:32
|
||||||
|
|
|
||||||
|
LL | static x: Vec<isize> = vec![3];
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
note: function `box_assume_init_into_vec_unsafe` is not const
|
||||||
|
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||||
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||||
|
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
|
||||||
|
|
||||||
error[E0507]: cannot move out of static item `x`
|
error[E0507]: cannot move out of static item `x`
|
||||||
--> $DIR/check-values-constraints.rs:119:9
|
--> $DIR/check-values-constraints.rs:119:9
|
||||||
|
|
|
|
||||||
|
|
@ -149,5 +184,5 @@ LL | x.clone()
|
||||||
|
|
||||||
error: aborting due to 17 previous errors
|
error: aborting due to 17 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0010, E0015, E0493, E0507.
|
Some errors have detailed explanations: E0015, E0493, E0507.
|
||||||
For more information about an error, try `rustc --explain E0010`.
|
For more information about an error, try `rustc --explain E0015`.
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
//@ compile-flags: -Zunpretty=thir-tree
|
|
||||||
//@ check-pass
|
|
||||||
|
|
||||||
#![feature(liballoc_internals)]
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let _ = std::boxed::box_new(1);
|
|
||||||
}
|
|
||||||
|
|
@ -1,90 +0,0 @@
|
||||||
DefId(0:3 ~ box[efb9]::main):
|
|
||||||
params: [
|
|
||||||
]
|
|
||||||
body:
|
|
||||||
Expr {
|
|
||||||
ty: ()
|
|
||||||
temp_scope_id: 11
|
|
||||||
span: $DIR/box.rs:6:11: 8:2 (#0)
|
|
||||||
kind:
|
|
||||||
Scope {
|
|
||||||
region_scope: Node(11)
|
|
||||||
hir_id: HirId(DefId(0:3 ~ box[efb9]::main).11)
|
|
||||||
value:
|
|
||||||
Expr {
|
|
||||||
ty: ()
|
|
||||||
temp_scope_id: 11
|
|
||||||
span: $DIR/box.rs:6:11: 8:2 (#0)
|
|
||||||
kind:
|
|
||||||
Block {
|
|
||||||
targeted_by_break: false
|
|
||||||
span: $DIR/box.rs:6:11: 8:2 (#0)
|
|
||||||
region_scope: Node(1)
|
|
||||||
safety_mode: Safe
|
|
||||||
stmts: [
|
|
||||||
Stmt {
|
|
||||||
kind: Let {
|
|
||||||
remainder_scope: Remainder { block: 1, first_statement_index: 0}
|
|
||||||
init_scope: Node(2)
|
|
||||||
pattern:
|
|
||||||
Pat {
|
|
||||||
ty: std::boxed::Box<i32, std::alloc::Global>
|
|
||||||
span: $DIR/box.rs:7:9: 7:10 (#0)
|
|
||||||
kind: PatKind {
|
|
||||||
Wild
|
|
||||||
}
|
|
||||||
}
|
|
||||||
,
|
|
||||||
initializer: Some(
|
|
||||||
Expr {
|
|
||||||
ty: std::boxed::Box<i32, std::alloc::Global>
|
|
||||||
temp_scope_id: 3
|
|
||||||
span: $DIR/box.rs:7:13: 7:35 (#0)
|
|
||||||
kind:
|
|
||||||
Scope {
|
|
||||||
region_scope: Node(3)
|
|
||||||
hir_id: HirId(DefId(0:3 ~ box[efb9]::main).3)
|
|
||||||
value:
|
|
||||||
Expr {
|
|
||||||
ty: std::boxed::Box<i32, std::alloc::Global>
|
|
||||||
temp_scope_id: 3
|
|
||||||
span: $DIR/box.rs:7:13: 7:35 (#0)
|
|
||||||
kind:
|
|
||||||
Box {
|
|
||||||
Expr {
|
|
||||||
ty: i32
|
|
||||||
temp_scope_id: 8
|
|
||||||
span: $DIR/box.rs:7:33: 7:34 (#0)
|
|
||||||
kind:
|
|
||||||
Scope {
|
|
||||||
region_scope: Node(8)
|
|
||||||
hir_id: HirId(DefId(0:3 ~ box[efb9]::main).8)
|
|
||||||
value:
|
|
||||||
Expr {
|
|
||||||
ty: i32
|
|
||||||
temp_scope_id: 8
|
|
||||||
span: $DIR/box.rs:7:33: 7:34 (#0)
|
|
||||||
kind:
|
|
||||||
Literal( lit: Spanned { node: Int(Pu128(1), Unsuffixed), span: $DIR/box.rs:7:33: 7:34 (#0) }, neg: false)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
else_block: None
|
|
||||||
hir_id: HirId(DefId(0:3 ~ box[efb9]::main).9)
|
|
||||||
span: $DIR/box.rs:7:5: 7:35 (#0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
expr: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue