diff --git a/charon-ml/src/CharonVersion.ml b/charon-ml/src/CharonVersion.ml index 76fcd2c8d..11aaef7ed 100644 --- a/charon-ml/src/CharonVersion.ml +++ b/charon-ml/src/CharonVersion.ml @@ -1,3 +1,3 @@ (* This is an automatically generated file, generated from `charon/Cargo.toml`. *) (* To re-generate this file, rune `make` in the root directory *) -let supported_charon_version = "0.1.176" +let supported_charon_version = "0.1.177" diff --git a/charon-ml/src/PrintExpressions.ml b/charon-ml/src/PrintExpressions.ml index fb5490ca7..48cc36969 100644 --- a/charon-ml/src/PrintExpressions.ml +++ b/charon-ml/src/PrintExpressions.ml @@ -222,6 +222,4 @@ and rvalue_to_string (env : 'a fmt_env) (rv : rvalue) : string = "[" ^ operand_to_string env v ^ ";" ^ constant_expr_to_string env len ^ "]" - | ShallowInitBox (op, _) -> - "shallow-init-box(" ^ operand_to_string env op ^ ")" | Aggregate (akind, ops) -> aggregate_to_string env akind ops diff --git a/charon-ml/src/generated/Generated_Expressions.ml b/charon-ml/src/generated/Generated_Expressions.ml index a52a6eabc..1c743526d 100644 --- a/charon-ml/src/generated/Generated_Expressions.ml +++ b/charon-ml/src/generated/Generated_Expressions.ml @@ -310,11 +310,6 @@ and rvalue = (** [Repeat(x, n)] creates an array where [x] is copied [n] times. We translate this to a function call for LLBC. *) - | ShallowInitBox of operand * ty - (** Transmutes a [*mut u8] (obtained from [malloc]) into - shallow-initialized [Box]. This only appears as part of lowering - [Box::new()] in some cases. We reconstruct the original [Box::new()] - call, but sometimes may fail to do so, leaking the expression. *) (** Unary operation *) and unop = diff --git a/charon-ml/src/generated/Generated_GAstOfJson.ml b/charon-ml/src/generated/Generated_GAstOfJson.ml index 6210c49c9..2bc2ea267 100644 --- a/charon-ml/src/generated/Generated_GAstOfJson.ml +++ b/charon-ml/src/generated/Generated_GAstOfJson.ml @@ -295,6 +295,8 @@ and builtin_fun_id_of_json (ctx : of_json_ctx) (js : json) : combine_error_msgs js __FUNCTION__ (match js with | `String "BoxNew" -> Ok BoxNew + | `String "BoxWrite" -> Ok BoxWrite + | `String "SliceIntoVec" -> Ok SliceIntoVec | `String "ArrayToSliceShared" -> Ok ArrayToSliceShared | `String "ArrayToSliceMut" -> Ok ArrayToSliceMut | `String "ArrayRepeat" -> Ok ArrayRepeat @@ -1780,10 +1782,6 @@ and rvalue_of_json (ctx : of_json_ctx) (js : json) : (rvalue, string) result = let* x_1 = ty_of_json ctx x_1 in let* x_2 = box_of_json constant_expr_of_json ctx x_2 in Ok (Repeat (x_0, x_1, x_2)) - | `Assoc [ ("ShallowInitBox", `List [ x_0; x_1 ]) ] -> - let* x_0 = operand_of_json ctx x_0 in - let* x_1 = ty_of_json ctx x_1 in - Ok (ShallowInitBox (x_0, x_1)) | _ -> Error "") and scalar_value_of_json (ctx : of_json_ctx) (js : json) : diff --git a/charon-ml/src/generated/Generated_Types.ml b/charon-ml/src/generated/Generated_Types.ml index d2e910634..d2130334b 100644 --- a/charon-ml/src/generated/Generated_Types.ml +++ b/charon-ml/src/generated/Generated_Types.ml @@ -175,6 +175,13 @@ and builtin_fun_id = | BoxNew (** Used instead of [alloc::boxed::Box::new] when [--treat-box-as-builtin] is set. *) + | BoxWrite + (** Used instead of [alloc::boxed::Box::write] when rewriting [vec!] + lowering. Writes into a [Box>] and returns a [Box]. + *) + | SliceIntoVec + (** Used instead of [alloc::slice::into_vec] when rewriting [vec!] + lowering. Takes a [Box<[T]>] and returns a [Vec]. *) | ArrayToSliceShared (** Cast [&[T; N]] to [&[T]]. diff --git a/charon/Cargo.lock b/charon/Cargo.lock index 691b2cb87..ad226c6b4 100644 --- a/charon/Cargo.lock +++ b/charon/Cargo.lock @@ -219,7 +219,7 @@ checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "charon" -version = "0.1.176" +version = "0.1.177" dependencies = [ "annotate-snippets", "anstream", diff --git a/charon/Cargo.toml b/charon/Cargo.toml index ca9bca6d2..a1026d560 100644 --- a/charon/Cargo.toml +++ b/charon/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "charon" -version = "0.1.176" +version = "0.1.177" authors = [ "Son Ho ", "Guillaume Boisseau ", diff --git a/charon/hax-frontend/src/lib.rs b/charon/hax-frontend/src/lib.rs index f4c940b96..d10d82b2e 100644 --- a/charon/hax-frontend/src/lib.rs +++ b/charon/hax-frontend/src/lib.rs @@ -1,5 +1,4 @@ #![allow(rustdoc::private_intra_doc_links)] -#![feature(if_let_guard)] #![feature(macro_metavar_expr)] #![feature(rustc_private)] #![feature(sized_hierarchy)] diff --git a/charon/rust-toolchain b/charon/rust-toolchain index ebd45d66e..8d2e91ba5 100644 --- a/charon/rust-toolchain +++ b/charon/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2026-02-07" +channel = "nightly-2026-02-22" components = [ "rustc-dev", "llvm-tools-preview", "rust-src", "miri" ] targets = [ "x86_64-apple-darwin", "i686-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", "riscv64gc-unknown-none-elf" ] diff --git a/charon/src/ast/expressions.rs b/charon/src/ast/expressions.rs index 5965a73a7..cd3e06926 100644 --- a/charon/src/ast/expressions.rs +++ b/charon/src/ast/expressions.rs @@ -428,6 +428,12 @@ impl From for FunId { pub enum BuiltinFunId { /// Used instead of `alloc::boxed::Box::new` when `--treat-box-as-builtin` is set. BoxNew, + /// Used instead of `alloc::boxed::Box::write` when rewriting `vec!` lowering. + /// Writes into a `Box>` and returns a `Box`. + BoxWrite, + /// Used instead of `alloc::slice::into_vec` when rewriting `vec!` lowering. + /// Takes a `Box<[T]>` and returns a `Vec`. + SliceIntoVec, /// Cast `&[T; N]` to `&[T]`. /// /// This is used instead of unsizing coercions when `--ops-to-function-calls` is set. @@ -761,10 +767,6 @@ pub enum Rvalue { /// /// We translate this to a function call for LLBC. Repeat(Operand, Ty, Box), - /// Transmutes a `*mut u8` (obtained from `malloc`) into shallow-initialized `Box`. This - /// only appears as part of lowering `Box::new()` in some cases. We reconstruct the original - /// `Box::new()` call, but sometimes may fail to do so, leaking the expression. - ShallowInitBox(Operand, Ty), } /// An aggregated ADT. diff --git a/charon/src/ast/hash_cons.rs b/charon/src/ast/hash_cons.rs index 1411f1659..491d9b333 100644 --- a/charon/src/ast/hash_cons.rs +++ b/charon/src/ast/hash_cons.rs @@ -60,7 +60,6 @@ mod intern_table { pub fn intern(inner: T) -> HashConsed { // Fast read-only check. - #[expect(irrefutable_let_patterns)] // https://github.com/rust-lang/rust/issues/139369 let arc = if let read_guard = INTERNED.read().unwrap() && let Some(set) = read_guard.get::() && let Some(arc) = set.get(&inner) diff --git a/charon/src/ast/types_utils.rs b/charon/src/ast/types_utils.rs index 817e23d42..e5ea7f316 100644 --- a/charon/src/ast/types_utils.rs +++ b/charon/src/ast/types_utils.rs @@ -760,6 +760,10 @@ impl Ty { } } + pub fn as_adt_id(&self) -> Option { + self.kind().as_adt().and_then(|a| a.id.as_adt().cloned()) + } + pub fn get_ptr_metadata(&self, translated: &TranslatedCrate) -> PtrMetadata { let ref ty_decls = translated.type_decls; match self.kind() { diff --git a/charon/src/bin/charon-driver/main.rs b/charon/src/bin/charon-driver/main.rs index 3ff2e09fc..486afde28 100644 --- a/charon/src/bin/charon-driver/main.rs +++ b/charon/src/bin/charon-driver/main.rs @@ -4,7 +4,6 @@ #![expect(incomplete_features)] #![feature(box_patterns)] #![feature(deref_patterns)] -#![feature(if_let_guard)] #![feature(iter_array_chunks)] #![feature(iterator_try_collect)] diff --git a/charon/src/bin/charon-driver/translate/translate_bodies.rs b/charon/src/bin/charon-driver/translate/translate_bodies.rs index 2a5b2fc66..2cbc3b572 100644 --- a/charon/src/bin/charon-driver/translate/translate_bodies.rs +++ b/charon/src/bin/charon-driver/translate/translate_bodies.rs @@ -895,11 +895,6 @@ impl<'tcx> BlockTransCtx<'tcx, '_, '_, '_> { } } } - mir::Rvalue::ShallowInitBox(op, ty) => { - let op = self.translate_operand(span, op)?; - let ty = self.translate_rustc_ty(span, ty)?; - Ok(Rvalue::ShallowInitBox(op, ty)) - } mir::Rvalue::ThreadLocalRef(_) => { raise_error!( self, diff --git a/charon/src/bin/generate-ml/main.rs b/charon/src/bin/generate-ml/main.rs index ba3dbae26..3aaba51d8 100644 --- a/charon/src/bin/generate-ml/main.rs +++ b/charon/src/bin/generate-ml/main.rs @@ -6,7 +6,6 @@ //! //! To run it, call `cargo run --bin generate-ml`. It is also run by `make generate-ml` in the //! crate root. Don't forget to format the output code after regenerating. -#![feature(if_let_guard)] use anyhow::{Context, Result, bail}; use assert_cmd::cargo::CommandCargoExt; diff --git a/charon/src/lib.rs b/charon/src/lib.rs index 4e34ee72a..cb5050cc0 100644 --- a/charon/src/lib.rs +++ b/charon/src/lib.rs @@ -14,11 +14,9 @@ // For rustdoc: prevents overflows #![recursion_limit = "256"] #![expect(incomplete_features)] -#![feature(assert_matches)] #![feature(box_patterns)] #![feature(deref_patterns)] #![feature(deref_pure_trait)] -#![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] #![feature(iterator_try_collect)] #![feature(register_tool)] diff --git a/charon/src/pretty/fmt_with_ctx.rs b/charon/src/pretty/fmt_with_ctx.rs index 892910fe3..9fa610415 100644 --- a/charon/src/pretty/fmt_with_ctx.rs +++ b/charon/src/pretty/fmt_with_ctx.rs @@ -269,6 +269,8 @@ impl Display for BuiltinFunId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> { let name = match *self { BuiltinFunId::BoxNew => "BoxNew", + BuiltinFunId::BoxWrite => "BoxWrite", + BuiltinFunId::SliceIntoVec => "SliceIntoVec", BuiltinFunId::ArrayToSliceShared => "ArrayToSliceShared", BuiltinFunId::ArrayToSliceMut => "ArrayToSliceMut", BuiltinFunId::ArrayRepeat => "ArrayRepeat", @@ -1534,14 +1536,6 @@ impl FmtWithCtx for Rvalue { Rvalue::Repeat(op, _ty, cg) => { write!(f, "[{}; {}]", op.with_ctx(ctx), cg.with_ctx(ctx)) } - Rvalue::ShallowInitBox(op, ty) => { - write!( - f, - "shallow_init_box::<{}>({})", - ty.with_ctx(ctx), - op.with_ctx(ctx) - ) - } } } } diff --git a/charon/src/transform/mod.rs b/charon/src/transform/mod.rs index 8c30970eb..7494ed87d 100644 --- a/charon/src/transform/mod.rs +++ b/charon/src/transform/mod.rs @@ -34,10 +34,10 @@ pub mod resugar { pub mod inline_local_panic_functions; pub mod move_asserts_to_statements; pub mod reconstruct_asserts; - pub mod reconstruct_boxes; pub mod reconstruct_fallible_operations; pub mod reconstruct_intrinsics; pub mod reconstruct_matches; + pub mod reconstruct_vec_boxes; } /// Passes that make the output simpler/easier to consume. @@ -143,12 +143,11 @@ pub static ULLBC_PASSES: &[Pass] = &[ // Recognize calls to the `offset_of` intrinsics and replace them with the corresponding // `NullOp`. UnstructuredBody(&resugar::reconstruct_intrinsics::Transform), - // # Micro-pass: reconstruct the special `Box::new` operations inserted e.g. in the `vec![]` - // macro. + // # Micro-pass: reconstruct `vec![x]` lowering to avoid unsafe operations. // **WARNING**: this pass relies on a precise structure of the MIR statements. Because of this, // it must happen before passes that insert statements like [simplify_constants]. // **WARNING**: this pass works across calls, hence must happen after `merge_goto_chains`, - UnstructuredBody(&resugar::reconstruct_boxes::Transform), + UnstructuredBody(&resugar::reconstruct_vec_boxes::Transform), // # Micro-pass: reconstruct the asserts UnstructuredBody(&resugar::reconstruct_asserts::Transform), // # Micro-pass: `panic!()` expands to a new function definition each time. This pass cleans diff --git a/charon/src/transform/resugar/reconstruct_boxes.rs b/charon/src/transform/resugar/reconstruct_boxes.rs deleted file mode 100644 index 24efc2cf8..000000000 --- a/charon/src/transform/resugar/reconstruct_boxes.rs +++ /dev/null @@ -1,168 +0,0 @@ -//! # Micro-pass: reconstruct piecewise box allocations using `malloc` and `ShallowInitBox`. - -use crate::register_error; -use crate::transform::TransformCtx; -use crate::ullbc_ast::*; - -use crate::transform::ctx::UllbcPass; - -pub struct Transform; - -/// The special `alloc::boxed::box_new(x)` intrinsic becomes the following: -/// -/// ```text -/// @4 := alloc::alloc::exchange_malloc(const .., const ..) -/// storage_live(@5) -/// @5 := shallow_init_box::(move (@4)) -/// // possibly some intermediate statements -/// *(@5) := x -/// ``` -/// -/// We reconstruct this into a call to `Box::new(x)`. -impl UllbcPass for Transform { - fn transform_body(&self, ctx: &mut TransformCtx, b: &mut ExprBody) { - if !ctx.options.treat_box_as_builtin { - return; - } - - // We need to find a block that has exchange_malloc as the terminator: - // ```text - // @4 := alloc::alloc::exchange_malloc(..) - // ``` - // We then check that that the target block starts with: - // ```text - // storage_live(@5) - // @5 := shallow_init_box::(move (@4)) - // ``` - // We then look for the assignment into the box and take a note of its index. - // ```text - // *(@5) := x - // ``` - // Finally, we replace all these assignments with a call to `@5 = Box::new(x)` - // We do so by replacing the terminator (exchange_malloc) with the correct call and adding - // a `StorageLive`. Everything else becomes Nop. - - for candidate_block_idx in b.body.all_indices() { - let second_block; - let box_place; - let box_generics; - let value_to_write; - let old_assign_idx; - let assign_span; - let unwind_target; - - if let Some(candidate_block) = b.body.get(candidate_block_idx) - // If the terminator is a call - && let TerminatorKind::Call { - target: target_block_idx, - call: - Call { - args: malloc_args, - func: _, // TODO: once we have a system to recognize intrinsics, check the call is to exchange_malloc. - dest: malloc_dest, - }, - on_unwind, - } = &candidate_block.terminator.kind - // The call has two const arguments - && let [Operand::Const(..), Operand::Const(..)] = malloc_args.as_slice() - && let Some(target_block) = b.body.get(*target_block_idx) - && let [Statement { - kind: StatementKind::StorageLive(target_var), - .. - }, Statement { - kind: - StatementKind::Assign(box_make, Rvalue::ShallowInitBox(Operand::Move(alloc_use), _)), - .. - }, rest @ ..] = target_block.statements.as_slice() - && alloc_use == malloc_dest - && let Some(local_id) = box_make.as_local() - && local_id == *target_var - && let TyKind::Adt(ty_ref) = box_make.ty().kind() - && let TypeId::Builtin(BuiltinTy::Box) = ty_ref.id - && let Some((assign_idx_in_rest, val, span)) = rest.iter().enumerate().find_map(|(idx, st)| { - if let Statement { - kind: StatementKind::Assign(box_deref, val), - span, - .. - } = st - && let Some((sub, ProjectionElem::Deref)) = box_deref.as_projection() - && sub == box_make - { - Some((idx, val, span)) - } else { - None - } - }) - { - box_place = box_make.clone(); - old_assign_idx = assign_idx_in_rest + 2; // +2 because rest skips the first two statements - value_to_write = val.clone(); - box_generics = ty_ref.generics.clone(); - second_block = *target_block_idx; - assign_span = *span; - unwind_target = *on_unwind; - } else { - continue; - } - - let first_block = b.body.get_mut(candidate_block_idx).unwrap(); - let box_place_local = box_place.as_local().unwrap(); - let value_to_write = match value_to_write { - Rvalue::Use(op) => op, - _ => { - // We need to create a new variable to store the value. - let name = b.locals[box_place_local].name.clone(); - let ty = box_generics.types[0].clone(); - let var = b.locals.new_var(name, ty); - first_block.statements.push(Statement::new( - assign_span, - StatementKind::StorageLive(var.as_local().unwrap()), - )); - first_block.statements.push(Statement::new( - assign_span, - StatementKind::Assign(var.clone(), value_to_write), - )); - Operand::Move(var) - } - }; - first_block.statements.push(Statement::new( - assign_span, - StatementKind::StorageLive(box_place_local), - )); - first_block.terminator.kind = TerminatorKind::Call { - call: Call { - func: FnOperand::Regular(FnPtr::new( - FnPtrKind::Fun(FunId::Builtin(BuiltinFunId::BoxNew)), - box_generics, - )), - args: vec![value_to_write], - dest: box_place, - }, - target: second_block, - on_unwind: unwind_target, - }; - - // We now update the statements in the second block. - let second_block = b.body.get_mut(second_block).unwrap(); - second_block.statements.get_mut(0).unwrap().kind = StatementKind::Nop; - second_block.statements.get_mut(1).unwrap().kind = StatementKind::Nop; - second_block - .statements - .get_mut(old_assign_idx) - .unwrap() - .kind = StatementKind::Nop; - } - - // Make sure we got all the `ShallowInitBox`es. - b.body.dyn_visit_in_body(|rvalue: &Rvalue| { - if rvalue.is_shallow_init_box() { - register_error!( - ctx, - b.span, - "Could not reconstruct `Box` initialization; \ - branching during `Box` initialization is not supported." - ); - } - }); - } -} diff --git a/charon/src/transform/resugar/reconstruct_vec_boxes.rs b/charon/src/transform/resugar/reconstruct_vec_boxes.rs new file mode 100644 index 000000000..bce6a5da9 --- /dev/null +++ b/charon/src/transform/resugar/reconstruct_vec_boxes.rs @@ -0,0 +1,303 @@ +//! Reconstruct rustc's `vec![..]` lowering based on `Box>`. +//! +//! Rustc lowers `vec![elems...]` into something like: +//! ```ignore +//! let mut box = Box::new_uninit::<[T; N]>(); +//! ((((*box)).1).0).0 = [elems...]; +//! let vec = Box::box_assume_init_into_vec_unsafe::(box); +//! ``` +//! The last function is internally unsafe, although its signature is safe. It is +//! lowered this way for performance, which is not a concern here. Instead, we thus +//! rewrite this into something safe: +//! ```ignore +//! let box_uninit = Box::new_uninit::<[T; N]>(); +//! let arr = [elems...]; +//! let box_arr = Box::write::<[T; N]>(box_uninit, arr); +//! let box_slice = box_arr as Box<[T]>; +//! let vec = box_slice.into_vec(); +//! ``` +//! +//! See also: https://github.com/rust-lang/rust/pull/148190 + +use itertools::Itertools; + +use crate::transform::TransformCtx; +use crate::transform::ctx::UllbcPass; +use crate::ullbc_ast::*; + +const LANG_ITEM_BOX_ASSUME_INIT_INTO_VEC_UNSAFE: &'static str = "box_assume_init_into_vec_unsafe"; + +pub struct Transform; + +#[derive(PartialEq, Eq)] +struct Rewrite { + drop_bid: BlockId, + target_bid: BlockId, + payload_bid: BlockId, + payload_idx: usize, + move_bid: BlockId, + move_idx: usize, + span: Span, + payload_elems: Vec, + elem_ty: Ty, + len: Box, + alloc_ty: Option, + uninit_box: Place, + vec_dest: Place, + drop_on_unwind: BlockId, +} + +impl Ord for Rewrite { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.drop_bid.cmp(&other.drop_bid) + } +} + +impl PartialOrd for Rewrite { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +fn is_assume_init_into_vec_call(ctx: &TransformCtx, call: &Call) -> bool { + if let FnOperand::Regular(fn_ptr) = &call.func + && let FnPtrKind::Fun(FunId::Regular(fid)) = *fn_ptr.kind + && let Some(decl) = ctx.translated.fun_decls.get(fid) + { + decl.item_meta.lang_item.as_deref() == Some(LANG_ITEM_BOX_ASSUME_INIT_INTO_VEC_UNSAFE) + } else { + false + } +} + +fn box_inner_and_alloc(ty: &Ty) -> Option<(Ty, Option)> { + let TyKind::Adt(TypeDeclRef { + id: TypeId::Builtin(BuiltinTy::Box), + generics, + }) = ty.kind() + else { + return None; + }; + let inner = generics.types[TypeVarId::from_usize(0)].clone(); + let alloc = generics.types.get(TypeVarId::from_usize(1)).cloned(); + Some((inner, alloc)) +} + +fn mk_generics(ty0: Ty, ty1: Option) -> GenericArgs { + match ty1 { + None => GenericArgs::new_types([ty0].into()), + Some(ty1) => GenericArgs::new_types([ty0, ty1].into()), + } +} + +fn mk_box_ty(inner: Ty, alloc: Option) -> Ty { + TyKind::Adt(TypeDeclRef::new( + TypeId::Builtin(BuiltinTy::Box), + mk_generics(inner, alloc), + )) + .into_ty() +} + +/// Given `src`, find the *unique* statement in the body of the form `src = [elems...]` +/// where the rvalue is an array aggregate. +/// Returns: +/// - the block and statement indices of the statement +/// - the span of the statement +/// - the operands of the array aggregate +/// - the element type and length of the array +fn find_array_assign( + body: &ExprBody, + src_local: LocalId, +) -> Option<(BlockId, usize, Span, Vec, Ty, Box)> { + let mut out = None; + for bid in body.body.all_indices() { + for (idx, st) in body.body[bid].statements.iter().enumerate() { + if let Some((place, Rvalue::Aggregate(AggregateKind::Array(elem_ty, len), elems))) = + st.kind.as_assign() + && place.local_id() == Some(src_local) + { + if out.is_some() { + return None; + } + + out = Some(( + bid, + idx, + st.span, + elems.clone(), + elem_ty.clone(), + len.clone(), + )); + }; + } + } + out +} + +/// Given `src` and `dst`, find the *unique* statement in the body of the form `dst = move src`. +/// Return its block and statement indices, and `None` if there is no such statement, or if there are multiple. +fn find_move_into(body: &ExprBody, src_local: LocalId, dst: &Place) -> Option<(BlockId, usize)> { + let mut out = None; + for bid in body.body.all_indices() { + for (idx, st) in body.body[bid].statements.iter().enumerate() { + if let Some((dst_place, Rvalue::Use(Operand::Move(src_place)))) = st.kind.as_assign() + && dst_place == dst + && src_place.local_id() == Some(src_local) + { + if out.is_some() { + return None; + } + out = Some((bid, idx)); + } + } + } + out +} + +impl UllbcPass for Transform { + fn should_run(&self, options: &crate::options::TranslateOptions) -> bool { + options.treat_box_as_builtin + } + + fn transform_body(&self, ctx: &mut TransformCtx, body: &mut ExprBody) { + // We are looking for, in (flattened) ULLBC: + // + // dropped_box = [payload_elems...]: [elem_ty; len] + // init_box = move dropped_box + // drop (dropped_box) + // vec_dest = box_assume_init_into_vec_unsafe(init_box) + + let rewrites = body.body.all_indices().filter_map(|bid| { + // drop (dropped_box) + let (_kind, dropped_box, _trait_ref, target, on_unwind) = + body.body[bid].terminator.kind.as_drop()?; + // check dropped_box: Box> + let (maybe_uninit_array_ty, alloc_ty) = box_inner_and_alloc(dropped_box.ty())?; + let mu_decl = &ctx.translated.type_decls[maybe_uninit_array_ty.as_adt_id()?]; + if mu_decl.item_meta.lang_item.as_deref() != Some("maybe_uninit") { + return None; + }; + let dropped_box_l = dropped_box.local_id()?; + + // vec_dest = box_assume_init_into_vec_unsafe(init_box) + let target_block = &body.body[*target]; + let (call, _tgt, _unwind) = &target_block.terminator.kind.as_call()?; + + if !is_assume_init_into_vec_call(ctx, call) { + return None; + } + let [Operand::Move(init_box)] = call.args.as_slice() else { + return None; + }; + + // dropped_box = [payload_elems...]: [elem_ty; len] + let (payload_bid, payload_idx, span, payload_elems, elem_ty, len) = + find_array_assign(body, dropped_box_l)?; + + // init_box = move dropped_box + let (move_bid, move_idx) = find_move_into(body, dropped_box_l, init_box)?; + + Some(Rewrite { + drop_bid: bid, + target_bid: *target, + payload_bid, + payload_idx, + move_bid, + move_idx, + span, + payload_elems, + elem_ty, + len, + alloc_ty, + uninit_box: dropped_box.clone(), + vec_dest: call.dest.clone(), + drop_on_unwind: *on_unwind, + }) + }); + + for rw in rewrites.sorted() { + let array_ty = Ty::mk_array(rw.elem_ty.clone(), *rw.len.clone()); + let array_local = body.locals.new_var(None, array_ty.clone()); + let box_array_ty = mk_box_ty(array_ty.clone(), rw.alloc_ty.clone()); + let box_slice_ty = mk_box_ty(Ty::mk_slice(rw.elem_ty.clone()), rw.alloc_ty.clone()); + let box_array_local = body.locals.new_var(None, box_array_ty.clone()); + let box_slice_local = body.locals.new_var(None, box_slice_ty.clone()); + + let array_lid = array_local.as_local().unwrap(); + let box_array_lid = box_array_local.as_local().unwrap(); + let box_slice_lid = box_slice_local.as_local().unwrap(); + + body.body[rw.move_bid].statements[rw.move_idx].kind = StatementKind::Nop; + + body.body[rw.payload_bid].statements.splice( + rw.payload_idx..=rw.payload_idx, + [ + StatementKind::StorageLive(array_lid), + StatementKind::Assign( + array_local.clone(), + Rvalue::Aggregate( + AggregateKind::Array(rw.elem_ty.clone(), rw.len.clone()), + rw.payload_elems, + ), + ), + ] + .map(|k| Statement::new(rw.span, k)), + ); + + let drop_block = &mut body.body[rw.drop_bid]; + drop_block.statements.push(Statement::new( + rw.span, + StatementKind::StorageLive(box_array_lid), + )); + + drop_block.terminator.kind = TerminatorKind::Call { + call: Call { + func: FnOperand::Regular(FnPtr::new( + FnPtrKind::Fun(FunId::Builtin(BuiltinFunId::BoxWrite)), + mk_generics(array_ty, rw.alloc_ty.clone()), + )), + args: vec![ + Operand::Move(rw.uninit_box), + Operand::Move(array_local.clone()), + ], + dest: box_array_local.clone(), + }, + target: rw.target_bid, + on_unwind: rw.drop_on_unwind, + }; + + let target_block = &mut body.body[rw.target_bid]; + + target_block.statements.splice( + 0..0, + [ + StatementKind::StorageDead(array_lid), + StatementKind::StorageLive(box_slice_lid), + StatementKind::Assign( + box_slice_local.clone(), + Rvalue::UnaryOp( + UnOp::Cast(CastKind::Unsize( + box_array_ty, + box_slice_ty, + UnsizingMetadata::Length(rw.len), + )), + Operand::Move(box_array_local), + ), + ), + ] + .map(|k| Statement::new(rw.span, k)), + ); + + let (target_call, _, _) = target_block.terminator.kind.as_call_mut().unwrap(); + + *target_call = Call { + func: FnOperand::Regular(FnPtr::new( + FnPtrKind::Fun(FunId::Builtin(BuiltinFunId::SliceIntoVec)), + mk_generics(rw.elem_ty, rw.alloc_ty), + )), + args: vec![Operand::Move(box_slice_local)], + dest: rw.vec_dest, + }; + } + } +} diff --git a/charon/src/transform/simplify_output/index_to_function_calls.rs b/charon/src/transform/simplify_output/index_to_function_calls.rs index bc4b8ffda..963a91583 100644 --- a/charon/src/transform/simplify_output/index_to_function_calls.rs +++ b/charon/src/transform/simplify_output/index_to_function_calls.rs @@ -186,8 +186,9 @@ impl VisitBodyMut for IndexVisitor<'_, '_> { | Discriminant(..) | Len(..) => self.visit_inner_with_mutability(x, false), - Use(_) | NullaryOp(..) | UnaryOp(..) | BinaryOp(..) | Aggregate(..) | Repeat(..) - | ShallowInitBox(..) => self.visit_inner(x), + Use(_) | NullaryOp(..) | UnaryOp(..) | BinaryOp(..) | Aggregate(..) | Repeat(..) => { + self.visit_inner(x) + } } } diff --git a/charon/tests/ui/copy_nonoverlapping.out b/charon/tests/ui/copy_nonoverlapping.out index 88b0a16b0..ccc22276e 100644 --- a/charon/tests/ui/copy_nonoverlapping.out +++ b/charon/tests/ui/copy_nonoverlapping.out @@ -184,7 +184,8 @@ where undefined_behavior } -pub fn core::intrinsics::align_of() -> usize +// Full name: core::intrinsics::align_of +pub fn align_of() -> usize where [@TraitClause0]: Sized, { @@ -204,6 +205,130 @@ impl Copy for usize { unsafe fn drop_in_place(_1: *mut Self) = +// Full name: core::ptr::alignment::AlignmentEnum +enum AlignmentEnum { + _Align1Shl0, + _Align1Shl1, + _Align1Shl2, + _Align1Shl3, + _Align1Shl4, + _Align1Shl5, + _Align1Shl6, + _Align1Shl7, + _Align1Shl8, + _Align1Shl9, + _Align1Shl10, + _Align1Shl11, + _Align1Shl12, + _Align1Shl13, + _Align1Shl14, + _Align1Shl15, + _Align1Shl16, + _Align1Shl17, + _Align1Shl18, + _Align1Shl19, + _Align1Shl20, + _Align1Shl21, + _Align1Shl22, + _Align1Shl23, + _Align1Shl24, + _Align1Shl25, + _Align1Shl26, + _Align1Shl27, + _Align1Shl28, + _Align1Shl29, + _Align1Shl30, + _Align1Shl31, + _Align1Shl32, + _Align1Shl33, + _Align1Shl34, + _Align1Shl35, + _Align1Shl36, + _Align1Shl37, + _Align1Shl38, + _Align1Shl39, + _Align1Shl40, + _Align1Shl41, + _Align1Shl42, + _Align1Shl43, + _Align1Shl44, + _Align1Shl45, + _Align1Shl46, + _Align1Shl47, + _Align1Shl48, + _Align1Shl49, + _Align1Shl50, + _Align1Shl51, + _Align1Shl52, + _Align1Shl53, + _Align1Shl54, + _Align1Shl55, + _Align1Shl56, + _Align1Shl57, + _Align1Shl58, + _Align1Shl59, + _Align1Shl60, + _Align1Shl61, + _Align1Shl62, + _Align1Shl63, +} + +// Full name: core::ptr::alignment::Alignment +pub struct Alignment { + _inner_repr_trick: AlignmentEnum, +} + +// Full name: core::mem::SizedTypeProperties +pub trait SizedTypeProperties +{ + parent_clause0 : [@TraitClause0]: Sized + const SIZE : usize + const ALIGN : usize + const ALIGNMENT : Alignment + const IS_ZST : bool + const LAYOUT : Layout + const MAX_SLICE_LEN : usize + non-dyn-compatible +} + +// Full name: core::mem::SizedTypeProperties::SIZE +#[lang_item("mem_size_const")] +pub fn SIZE() -> usize +where + [@TraitClause0]: SizedTypeProperties, +{ + let _0: usize; // return + + _0 = size_of[@TraitClause0::parent_clause0]() + return +} + +// Full name: core::mem::SizedTypeProperties::SIZE +#[lang_item("mem_size_const")] +pub const SIZE: usize +where + [@TraitClause0]: SizedTypeProperties, + = SIZE() + +// Full name: core::mem::SizedTypeProperties::ALIGN +#[lang_item("mem_align_const")] +pub fn ALIGN() -> usize +where + [@TraitClause0]: SizedTypeProperties, +{ + let _0: usize; // return + + _0 = align_of[@TraitClause0::parent_clause0]() + return +} + +// Full name: core::mem::SizedTypeProperties::ALIGN +#[lang_item("mem_align_const")] +pub const ALIGN: usize +where + [@TraitClause0]: SizedTypeProperties, + = ALIGN() + // Full name: core::panicking::panic_nounwind_fmt pub fn panic_nounwind_fmt<'_0>(_1: Arguments<'_0>, _2: bool) -> ! { @@ -286,79 +411,6 @@ fn core::ptr::alignment::{Alignment}::new_unchecked::precondition_check(_1: usiz return } -// Full name: core::ptr::alignment::AlignmentEnum -enum AlignmentEnum { - _Align1Shl0, - _Align1Shl1, - _Align1Shl2, - _Align1Shl3, - _Align1Shl4, - _Align1Shl5, - _Align1Shl6, - _Align1Shl7, - _Align1Shl8, - _Align1Shl9, - _Align1Shl10, - _Align1Shl11, - _Align1Shl12, - _Align1Shl13, - _Align1Shl14, - _Align1Shl15, - _Align1Shl16, - _Align1Shl17, - _Align1Shl18, - _Align1Shl19, - _Align1Shl20, - _Align1Shl21, - _Align1Shl22, - _Align1Shl23, - _Align1Shl24, - _Align1Shl25, - _Align1Shl26, - _Align1Shl27, - _Align1Shl28, - _Align1Shl29, - _Align1Shl30, - _Align1Shl31, - _Align1Shl32, - _Align1Shl33, - _Align1Shl34, - _Align1Shl35, - _Align1Shl36, - _Align1Shl37, - _Align1Shl38, - _Align1Shl39, - _Align1Shl40, - _Align1Shl41, - _Align1Shl42, - _Align1Shl43, - _Align1Shl44, - _Align1Shl45, - _Align1Shl46, - _Align1Shl47, - _Align1Shl48, - _Align1Shl49, - _Align1Shl50, - _Align1Shl51, - _Align1Shl52, - _Align1Shl53, - _Align1Shl54, - _Align1Shl55, - _Align1Shl56, - _Align1Shl57, - _Align1Shl58, - _Align1Shl59, - _Align1Shl60, - _Align1Shl61, - _Align1Shl62, - _Align1Shl63, -} - -// Full name: core::ptr::alignment::Alignment -pub struct Alignment { - _inner_repr_trick: AlignmentEnum, -} - // Full name: core::option::Option #[lang_item("Option")] pub enum Option @@ -438,6 +490,61 @@ where _2 = unwrap_failed() } +// Full name: core::mem::SizedTypeProperties::ALIGNMENT +pub fn ALIGNMENT() -> Alignment +where + [@TraitClause0]: SizedTypeProperties, +{ + let _0: Alignment; // return + let _1: Option[{built_in impl Sized for Alignment}]; // anonymous local + + storage_live(_1) + _1 = new(const @TraitClause0::ALIGN) + _0 = unwrap[{built_in impl Sized for Alignment}](move _1) + storage_dead(_1) + return +} + +// Full name: core::mem::SizedTypeProperties::ALIGNMENT +pub const ALIGNMENT: Alignment +where + [@TraitClause0]: SizedTypeProperties, + = ALIGNMENT() + +// Full name: core::mem::SizedTypeProperties::IS_ZST +pub fn IS_ZST() -> bool +where + [@TraitClause0]: SizedTypeProperties, +{ + let _0: bool; // return + + _0 = const @TraitClause0::SIZE == const 0 : usize + return +} + +// Full name: core::mem::SizedTypeProperties::IS_ZST +pub const IS_ZST: bool +where + [@TraitClause0]: SizedTypeProperties, + = IS_ZST() + +// Full name: core::mem::SizedTypeProperties::LAYOUT +pub fn LAYOUT() -> Layout +where + [@TraitClause0]: SizedTypeProperties, +{ + let _0: Layout; // return + + _0 = from_size_align_unchecked(const @TraitClause0::SIZE, const @TraitClause0::ALIGN) + return +} + +// Full name: core::mem::SizedTypeProperties::LAYOUT +pub const LAYOUT: Layout +where + [@TraitClause0]: SizedTypeProperties, + = LAYOUT() + pub fn core::num::{usize}::MAX() -> usize { let _0: usize; // return @@ -462,19 +569,6 @@ pub fn core::num::{isize}::MAX() -> isize pub const core::num::{isize}::MAX: isize = core::num::{isize}::MAX() -// Full name: core::mem::SizedTypeProperties -pub trait SizedTypeProperties -{ - parent_clause0 : [@TraitClause0]: Sized - const SIZE : usize - const ALIGN : usize - const ALIGNMENT : Alignment - const IS_ZST : bool - const LAYOUT : Layout - const MAX_SLICE_LEN : usize - non-dyn-compatible -} - // Full name: core::mem::SizedTypeProperties::MAX_SLICE_LEN pub fn MAX_SLICE_LEN() -> usize where @@ -515,106 +609,6 @@ where [@TraitClause0]: SizedTypeProperties, = MAX_SLICE_LEN() -// Full name: core::mem::SizedTypeProperties::LAYOUT -pub fn LAYOUT() -> Layout -where - [@TraitClause0]: SizedTypeProperties, -{ - let _0: Layout; // return - - _0 = from_size_align_unchecked(const @TraitClause0::SIZE, const @TraitClause0::ALIGN) - return -} - -// Full name: core::mem::SizedTypeProperties::LAYOUT -pub const LAYOUT: Layout -where - [@TraitClause0]: SizedTypeProperties, - = LAYOUT() - -// Full name: core::mem::SizedTypeProperties::IS_ZST -pub fn IS_ZST() -> bool -where - [@TraitClause0]: SizedTypeProperties, -{ - let _0: bool; // return - - _0 = const @TraitClause0::SIZE == const 0 : usize - return -} - -// Full name: core::mem::SizedTypeProperties::IS_ZST -pub const IS_ZST: bool -where - [@TraitClause0]: SizedTypeProperties, - = IS_ZST() - -// Full name: core::mem::SizedTypeProperties::ALIGN -#[lang_item("mem_align_const")] -pub fn ALIGN() -> usize -where - [@TraitClause0]: SizedTypeProperties, -{ - let _0: usize; // return - - _0 = core::intrinsics::align_of[@TraitClause0::parent_clause0]() - return -} - -// Full name: core::mem::SizedTypeProperties::ALIGN -#[lang_item("mem_align_const")] -pub const ALIGN: usize -where - [@TraitClause0]: SizedTypeProperties, - = ALIGN() - -// Full name: core::mem::SizedTypeProperties::SIZE -#[lang_item("mem_size_const")] -pub fn SIZE() -> usize -where - [@TraitClause0]: SizedTypeProperties, -{ - let _0: usize; // return - - _0 = size_of[@TraitClause0::parent_clause0]() - return -} - -// Full name: core::mem::SizedTypeProperties::SIZE -#[lang_item("mem_size_const")] -pub const SIZE: usize -where - [@TraitClause0]: SizedTypeProperties, - = SIZE() - -#[lang_item("mem_align_of")] -pub fn core::mem::align_of() -> usize -where - [@TraitClause0]: Sized, -{ - let _0: usize; // return - - _0 = const {impl SizedTypeProperties for T}[@TraitClause0]::ALIGN - return -} - -// Full name: core::mem::SizedTypeProperties::ALIGNMENT -pub fn ALIGNMENT() -> Alignment -where - [@TraitClause0]: SizedTypeProperties, -{ - let _0: Alignment; // return - - _0 = of[@TraitClause0::parent_clause0]() - return -} - -// Full name: core::mem::SizedTypeProperties::ALIGNMENT -pub const ALIGNMENT: Alignment -where - [@TraitClause0]: SizedTypeProperties, - = ALIGNMENT() - // Full name: core::mem::{impl SizedTypeProperties for T} impl SizedTypeProperties for T where @@ -630,28 +624,6 @@ where non-dyn-compatible } -// Full name: core::ptr::alignment::{Alignment}::of -pub fn of() -> Alignment -where - [@TraitClause0]: Sized, -{ - let _0: Alignment; // return - let _1: Alignment; // anonymous local - let _2: Option[{built_in impl Sized for Alignment}]; // anonymous local - let _3: usize; // anonymous local - - storage_live(_1) - storage_live(_2) - storage_live(_3) - _3 = core::mem::align_of[@TraitClause0]() - _2 = new(move _3) - storage_dead(_3) - _1 = unwrap[{built_in impl Sized for Alignment}](move _2) - storage_dead(_2) - _0 = move _1 - return -} - fn core::ptr::copy_nonoverlapping::precondition_check(_1: *const (), _2: *mut (), _3: usize, _4: usize, _5: usize) = diff --git a/charon/tests/ui/dyn-with-diamond-supertraits.out b/charon/tests/ui/dyn-with-diamond-supertraits.out index 3303fb40b..ee8f95282 100644 --- a/charon/tests/ui/dyn-with-diamond-supertraits.out +++ b/charon/tests/ui/dyn-with-diamond-supertraits.out @@ -129,11 +129,11 @@ where struct test_crate::Join::{vtable} { size: usize, align: usize, - drop: unsafe fn(*mut (dyn Join)), - method_join_method: fn<'_0_1>(&'_0_1 (dyn Join)) -> (Ty3, Ty2), + drop: unsafe fn(*mut (dyn Join)), + method_join_method: fn<'_0_1>(&'_0_1 (dyn Join)) -> (Ty2, Ty3), super_trait_0: &'static core::marker::MetaSized::{vtable}, - super_trait_1: &'static test_crate::Left::{vtable}, - super_trait_2: &'static test_crate::Right::{vtable}, + super_trait_1: &'static test_crate::Left::{vtable}, + super_trait_2: &'static test_crate::Right::{vtable}, } // Full name: test_crate::Join @@ -504,28 +504,28 @@ fn {impl Join for i32}::join_method<'_0>(_1: &'_0 i32) -> (i32, i32) } // Full name: test_crate::{impl Join for i32}::join_method::{vtable_method} -fn {impl Join for i32}::join_method::{vtable_method}<'_0>(_1: &'_0 (dyn Join)) -> (i32, i32) +fn {impl Join for i32}::join_method::{vtable_method}<'_0>(_1: &'_0 (dyn Join)) -> (i32, i32) { let _0: (i32, i32); // return - let _1: &'_0 (dyn Join + '0); // arg #1 + let _1: &'_0 (dyn Join + '0); // arg #1 let _2: &'_0 i32; // anonymous local storage_live(_2) - _2 = concretize<&'_0 (dyn Join + '1), &'_0 i32>(move _1) + _2 = concretize<&'_0 (dyn Join + '1), &'_0 i32>(move _1) _0 = {impl Join for i32}::join_method<'_0>(move _2) return } // Full name: test_crate::{impl Join for i32}::{vtable_drop_shim} -unsafe fn {impl Join for i32}::{vtable_drop_shim}(_1: *mut (dyn Join)) +unsafe fn {impl Join for i32}::{vtable_drop_shim}(_1: *mut (dyn Join)) { let ret_0: (); // return - let dyn_self_1: *mut (dyn Join + '0); // arg #1 + let dyn_self_1: *mut (dyn Join + '0); // arg #1 let target_self_2: *mut i32; // local ret_0 = () storage_live(target_self_2) - target_self_2 = concretize<*mut (dyn Join + '1), *mut i32>(move dyn_self_1) + target_self_2 = concretize<*mut (dyn Join + '1), *mut i32>(move dyn_self_1) return } @@ -567,11 +567,11 @@ impl Join for i32 { fn main() { let _0: (); // return - let v_1: &'3 (dyn Join + '4); // local + let v_1: &'3 (dyn Join + '4); // local let _2: &'6 i32; // anonymous local let _3: &'7 i32; // anonymous local let _4: (i32, i32); // anonymous local - let _5: &'8 (dyn Join + '9); // anonymous local + let _5: &'8 (dyn Join + '9); // anonymous local let _6: &'10 i32; // anonymous local let _7: &'19 i32; // anonymous local let _8: i32; // anonymous local @@ -588,7 +588,7 @@ fn main() _6 = move _7 _3 = &(*_6) _2 = &(*_3) - v_1 = unsize_cast<&'6 i32, &'12 (dyn Join + '13), &{impl Join for i32}::{vtable}>(move _2) + v_1 = unsize_cast<&'6 i32, &'12 (dyn Join + '13), &{impl Join for i32}::{vtable}>(move _2) storage_dead(_2) storage_dead(_3) storage_live(_4) diff --git a/charon/tests/ui/issue-114-opaque-bodies.out b/charon/tests/ui/issue-114-opaque-bodies.out index 06f4feb7f..290c3a8bc 100644 --- a/charon/tests/ui/issue-114-opaque-bodies.out +++ b/charon/tests/ui/issue-114-opaque-bodies.out @@ -107,7 +107,7 @@ unsafe fn core::marker::Destruct::drop_in_place(_1: *mut Self) // Full name: core::num::niche_types::UsizeNoHighBit pub struct UsizeNoHighBit { - usize, + type_error("Unsupported type: "pattern_type!(usize is 0..=core::::num::niche_types::UsizeNoHighBit::0::{constant#1})""), } // Full name: core::num::{usize}::MAX diff --git a/charon/tests/ui/issue-114-opaque-bodies.rs b/charon/tests/ui/issue-114-opaque-bodies.rs index 01173e272..6c6c09422 100644 --- a/charon/tests/ui/issue-114-opaque-bodies.rs +++ b/charon/tests/ui/issue-114-opaque-bodies.rs @@ -1,3 +1,4 @@ +//@ ignore-warnings //@ charon-args=--extract-opaque-bodies //@ charon-arg=--opaque={impl core::marker::Destruct for alloc::vec::Vec} //@ aux-crate=issue-114-opaque-bodies-aux.rs diff --git a/charon/tests/ui/issue-165-vec-macro.out b/charon/tests/ui/issue-165-vec-macro.out index a97f0bbd4..1f4185b92 100644 --- a/charon/tests/ui/issue-165-vec-macro.out +++ b/charon/tests/ui/issue-165-vec-macro.out @@ -49,27 +49,22 @@ pub trait Destruct unsafe fn core::marker::Destruct::drop_in_place(_1: *mut Self) = +// Full name: core::mem::maybe_uninit::MaybeUninit +#[lang_item("maybe_uninit")] +pub opaque type MaybeUninit +where + [@TraitClause0]: Sized, + // Full name: alloc::alloc::Global #[lang_item("global_alloc_ty")] pub struct Global {} -// Full name: alloc::boxed::Box::{impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}::drop_in_place -unsafe fn {impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}::drop_in_place(_1: *mut alloc::boxed::Box[@TraitClause0, @TraitClause1]) +// Full name: alloc::boxed::{alloc::boxed::Box[@TraitClause0::parent_clause0, {built_in impl Sized for Global}]}::new_uninit +pub fn new_uninit() -> alloc::boxed::Box[@TraitClause0]>[{built_in impl MetaSized for MaybeUninit[@TraitClause0]}, {built_in impl Sized for Global}] where - [@TraitClause0]: MetaSized, - [@TraitClause1]: Sized, + [@TraitClause0]: Sized, = -// Full name: alloc::boxed::Box::{impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]} -impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1] -where - [@TraitClause0]: MetaSized, - [@TraitClause1]: Sized, -{ - fn drop_in_place = {impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}::drop_in_place[@TraitClause0, @TraitClause1] - non-dyn-compatible -} - // Full name: alloc::vec::Vec #[lang_item("Vec")] pub opaque type Vec @@ -77,14 +72,6 @@ where [@TraitClause0]: Sized, [@TraitClause1]: Sized, -// Full name: alloc::slice::{[T]}::into_vec -#[lang_item("slice_into_vec")] -pub fn into_vec(_1: alloc::boxed::Box<[T]>[{built_in impl MetaSized for [T]}, @TraitClause1]) -> Vec[@TraitClause0, @TraitClause1] -where - [@TraitClause0]: Sized, - [@TraitClause1]: Sized, -= - // Full name: alloc::vec::Vec::{impl Destruct for Vec[@TraitClause0, @TraitClause1]}::drop_in_place unsafe fn {impl Destruct for Vec[@TraitClause0, @TraitClause1]}::drop_in_place(_1: *mut Vec[@TraitClause0, @TraitClause1]) where @@ -115,33 +102,30 @@ fn foo() { let _0: (); // return let _v_1: Vec[{built_in impl Sized for i32}, {built_in impl Sized for Global}]; // local - let _2: alloc::boxed::Box<[i32]>[{built_in impl MetaSized for [i32]}, {built_in impl Sized for Global}]; // anonymous local - let _3: alloc::boxed::Box<[i32; 1 : usize]>[{built_in impl MetaSized for [i32; 1 : usize]}, {built_in impl Sized for Global}]; // anonymous local - let _4: alloc::boxed::Box<[i32; 1 : usize]>[{built_in impl MetaSized for [i32; 1 : usize]}, {built_in impl Sized for Global}]; // anonymous local - let _v2_5: Vec[{built_in impl Sized for i32}, {built_in impl Sized for Global}]; // local - let _6: [i32; 1 : usize]; // anonymous local + let _2: alloc::boxed::Box[{built_in impl Sized for [i32; 1 : usize]}]>[{built_in impl MetaSized for MaybeUninit<[i32; 1 : usize]>[{built_in impl Sized for [i32; 1 : usize]}]}, {built_in impl Sized for Global}]; // anonymous local + let _v2_3: Vec[{built_in impl Sized for i32}, {built_in impl Sized for Global}]; // local + let _4: [i32; 1 : usize]; // anonymous local + let _5: alloc::boxed::Box<[i32; 1 : usize]>; // anonymous local + let _6: alloc::boxed::Box<[i32]>; // anonymous local _0 = () storage_live(_v_1) storage_live(_2) - storage_live(_3) - storage_live(_6) - _6 = [const 1 : i32] + _2 = new_uninit<[i32; 1 : usize]>[{built_in impl Sized for [i32; 1 : usize]}]() storage_live(_4) - _4 = @BoxNew<[i32; 1 : usize]>[{built_in impl MetaSized for [i32; 1 : usize]}, {built_in impl Sized for Global}](move _6) - _3 = move _4 - _2 = unsize_cast[{built_in impl MetaSized for [i32; 1 : usize]}, {built_in impl Sized for Global}], alloc::boxed::Box<[i32]>[{built_in impl MetaSized for [i32]}, {built_in impl Sized for Global}], 1 : usize>(move _3) - conditional_drop[{impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}<[i32; 1 : usize], Global>[{built_in impl MetaSized for [i32; 1 : usize]}, {built_in impl Sized for Global}]] _3 - conditional_drop[{impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}<[i32; 1 : usize], Global>[{built_in impl MetaSized for [i32; 1 : usize]}, {built_in impl Sized for Global}]] _4 + _4 = [const 1 : i32] + storage_live(_5) + _5 = @BoxWrite<[i32; 1 : usize]>(move _2, move _4) storage_dead(_4) - storage_dead(_3) - _v_1 = into_vec[{built_in impl Sized for i32}, {built_in impl Sized for Global}](move _2) + storage_live(_6) + _6 = unsize_cast, alloc::boxed::Box<[i32]>, 1 : usize>(move _5) storage_dead(_2) - storage_live(_v2_5) - _v2_5 = from_elem[{built_in impl Sized for i32}, {impl Clone for i32}](const 1 : i32, const 10 : usize) + _v_1 = @SliceIntoVec(move _6) + storage_live(_v2_3) + _v2_3 = from_elem[{built_in impl Sized for i32}, {impl Clone for i32}](const 1 : i32, const 10 : usize) _0 = () - conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for i32}, {built_in impl Sized for Global}]] _v2_5 - storage_dead(_v2_5) + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for i32}, {built_in impl Sized for Global}]] _v2_3 + storage_dead(_v2_3) conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for i32}, {built_in impl Sized for Global}]] _v_1 storage_dead(_v_1) return @@ -155,31 +139,28 @@ pub fn bar() { let _0: (); // return let _1: Vec[{built_in impl Sized for Foo}, {built_in impl Sized for Global}]; // anonymous local - let _2: alloc::boxed::Box<[Foo]>[{built_in impl MetaSized for [Foo]}, {built_in impl Sized for Global}]; // anonymous local - let _3: alloc::boxed::Box<[Foo; 1 : usize]>[{built_in impl MetaSized for [Foo; 1 : usize]}, {built_in impl Sized for Global}]; // anonymous local - let _4: alloc::boxed::Box<[Foo; 1 : usize]>[{built_in impl MetaSized for [Foo; 1 : usize]}, {built_in impl Sized for Global}]; // anonymous local - let _5: Foo; // anonymous local - let _6: [Foo; 1 : usize]; // anonymous local + let _2: alloc::boxed::Box[{built_in impl Sized for [Foo; 1 : usize]}]>[{built_in impl MetaSized for MaybeUninit<[Foo; 1 : usize]>[{built_in impl Sized for [Foo; 1 : usize]}]}, {built_in impl Sized for Global}]; // anonymous local + let _3: Foo; // anonymous local + let _4: [Foo; 1 : usize]; // anonymous local + let _5: alloc::boxed::Box<[Foo; 1 : usize]>; // anonymous local + let _6: alloc::boxed::Box<[Foo]>; // anonymous local _0 = () storage_live(_1) storage_live(_2) + _2 = new_uninit<[Foo; 1 : usize]>[{built_in impl Sized for [Foo; 1 : usize]}]() storage_live(_3) - storage_live(_6) - _6 = [move _5] + _3 = Foo { } storage_live(_4) - _4 = @BoxNew<[Foo; 1 : usize]>[{built_in impl MetaSized for [Foo; 1 : usize]}, {built_in impl Sized for Global}](move _6) + _4 = [move _3] + storage_dead(_3) storage_live(_5) - _5 = Foo { } - storage_dead(_5) - _3 = move _4 - _2 = unsize_cast[{built_in impl MetaSized for [Foo; 1 : usize]}, {built_in impl Sized for Global}], alloc::boxed::Box<[Foo]>[{built_in impl MetaSized for [Foo]}, {built_in impl Sized for Global}], 1 : usize>(move _3) - conditional_drop[{impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}<[Foo; 1 : usize], Global>[{built_in impl MetaSized for [Foo; 1 : usize]}, {built_in impl Sized for Global}]] _3 - conditional_drop[{impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}<[Foo; 1 : usize], Global>[{built_in impl MetaSized for [Foo; 1 : usize]}, {built_in impl Sized for Global}]] _4 + _5 = @BoxWrite<[Foo; 1 : usize]>(move _2, move _4) storage_dead(_4) - storage_dead(_3) - _1 = into_vec[{built_in impl Sized for Foo}, {built_in impl Sized for Global}](move _2) + storage_live(_6) + _6 = unsize_cast, alloc::boxed::Box<[Foo]>, 1 : usize>(move _5) storage_dead(_2) + _1 = @SliceIntoVec(move _6) conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for Foo}, {built_in impl Sized for Global}]] _1 storage_dead(_1) _0 = () diff --git a/charon/tests/ui/issue-393-shallowinitbox.out b/charon/tests/ui/issue-393-shallowinitbox.out index eb06e48ea..34d804286 100644 --- a/charon/tests/ui/issue-393-shallowinitbox.out +++ b/charon/tests/ui/issue-393-shallowinitbox.out @@ -1,10 +1,146 @@ -error: Could not reconstruct `Box` initialization; branching during `Box` initialization is not supported. - --> tests/ui/issue-393-shallowinitbox.rs:2:1 - | -2 | / pub fn next(b: bool) -> Option> { -3 | | let vec = vec![if b { 42 } else { return None }]; -4 | | Some(vec) -5 | | } - | |_^ - -ERROR Charon failed to translate this code (1 errors) +# Final LLBC before serialization: + +// Full name: core::marker::MetaSized +#[lang_item("meta_sized")] +pub trait MetaSized + +// Full name: core::marker::Sized +#[lang_item("sized")] +pub trait Sized +{ + parent_clause0 : [@TraitClause0]: MetaSized + non-dyn-compatible +} + +// Full name: core::marker::Destruct +#[lang_item("destruct")] +pub trait Destruct +{ + fn drop_in_place = core::marker::Destruct::drop_in_place + non-dyn-compatible +} + +unsafe fn core::marker::Destruct::drop_in_place(_1: *mut Self) += + +// Full name: core::mem::maybe_uninit::MaybeUninit +#[lang_item("maybe_uninit")] +pub opaque type MaybeUninit +where + [@TraitClause0]: Sized, + +// Full name: core::option::Option +#[lang_item("Option")] +pub enum Option +where + [@TraitClause0]: Sized, +{ + None, + Some(T), +} + +// Full name: alloc::alloc::Global +#[lang_item("global_alloc_ty")] +pub struct Global {} + +// Full name: alloc::boxed::Box::{impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}::drop_in_place +unsafe fn {impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}::drop_in_place(_1: *mut alloc::boxed::Box[@TraitClause0, @TraitClause1]) +where + [@TraitClause0]: MetaSized, + [@TraitClause1]: Sized, += + +// Full name: alloc::boxed::Box::{impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]} +impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1] +where + [@TraitClause0]: MetaSized, + [@TraitClause1]: Sized, +{ + fn drop_in_place = {impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}::drop_in_place[@TraitClause0, @TraitClause1] + non-dyn-compatible +} + +// Full name: alloc::boxed::{alloc::boxed::Box[@TraitClause0::parent_clause0, {built_in impl Sized for Global}]}::new_uninit +pub fn new_uninit() -> alloc::boxed::Box[@TraitClause0]>[{built_in impl MetaSized for MaybeUninit[@TraitClause0]}, {built_in impl Sized for Global}] +where + [@TraitClause0]: Sized, += + +// Full name: alloc::vec::Vec +#[lang_item("Vec")] +pub opaque type Vec +where + [@TraitClause0]: Sized, + [@TraitClause1]: Sized, + +// Full name: alloc::vec::Vec::{impl Destruct for Vec[@TraitClause0, @TraitClause1]}::drop_in_place +unsafe fn {impl Destruct for Vec[@TraitClause0, @TraitClause1]}::drop_in_place(_1: *mut Vec[@TraitClause0, @TraitClause1]) +where + [@TraitClause0]: Sized, + [@TraitClause1]: Sized, += + +// Full name: alloc::vec::Vec::{impl Destruct for Vec[@TraitClause0, @TraitClause1]} +impl Destruct for Vec[@TraitClause0, @TraitClause1] +where + [@TraitClause0]: Sized, + [@TraitClause1]: Sized, +{ + fn drop_in_place = {impl Destruct for Vec[@TraitClause0, @TraitClause1]}::drop_in_place[@TraitClause0, @TraitClause1] + non-dyn-compatible +} + +// Full name: test_crate::next +pub fn next(_1: bool) -> Option[{built_in impl Sized for u8}, {built_in impl Sized for Global}]>[{built_in impl Sized for Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]}] +{ + let _0: Option[{built_in impl Sized for u8}, {built_in impl Sized for Global}]>[{built_in impl Sized for Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]}]; // return + let b_1: bool; // arg #1 + let vec_2: Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; // local + let _3: alloc::boxed::Box[{built_in impl Sized for [u8; 1 : usize]}]>[{built_in impl MetaSized for MaybeUninit<[u8; 1 : usize]>[{built_in impl Sized for [u8; 1 : usize]}]}, {built_in impl Sized for Global}]; // anonymous local + let _4: u8; // anonymous local + let _5: bool; // anonymous local + let _6: Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; // anonymous local + let _7: [u8; 1 : usize]; // anonymous local + let _8: alloc::boxed::Box<[u8; 1 : usize]>; // anonymous local + let _9: alloc::boxed::Box<[u8]>; // anonymous local + + storage_live(vec_2) + storage_live(_3) + _3 = new_uninit<[u8; 1 : usize]>[{built_in impl Sized for [u8; 1 : usize]}]() + storage_live(_4) + storage_live(_5) + _5 = copy b_1 + if move _5 { + } else { + _0 = Option::None { } + storage_dead(_5) + storage_dead(_4) + conditional_drop[{impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}[{built_in impl Sized for [u8; 1 : usize]}], Global>[{built_in impl MetaSized for MaybeUninit<[u8; 1 : usize]>[{built_in impl Sized for [u8; 1 : usize]}]}, {built_in impl Sized for Global}]] _3 + storage_dead(_3) + storage_dead(vec_2) + return + } + _4 = const 42 : u8 + storage_dead(_5) + storage_live(_7) + _7 = [move _4] + storage_dead(_4) + storage_live(_8) + _8 = @BoxWrite<[u8; 1 : usize]>(move _3, move _7) + storage_dead(_7) + storage_live(_9) + _9 = unsize_cast, alloc::boxed::Box<[u8]>, 1 : usize>(move _8) + storage_dead(_3) + vec_2 = @SliceIntoVec(move _9) + storage_live(_6) + _6 = move vec_2 + _0 = Option::Some { 0: move _6 } + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for u8}, {built_in impl Sized for Global}]] _6 + storage_dead(_6) + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for u8}, {built_in impl Sized for Global}]] vec_2 + storage_dead(vec_2) + return +} + + + diff --git a/charon/tests/ui/issue-393-shallowinitbox.rs b/charon/tests/ui/issue-393-shallowinitbox.rs index aa8278a28..712a45d2f 100644 --- a/charon/tests/ui/issue-393-shallowinitbox.rs +++ b/charon/tests/ui/issue-393-shallowinitbox.rs @@ -1,4 +1,3 @@ -//@ known-failure pub fn next(b: bool) -> Option> { let vec = vec![if b { 42 } else { return None }]; Some(vec) diff --git a/charon/tests/ui/raw-boxes.out b/charon/tests/ui/raw-boxes.out index 4d6fd1a06..a6ec85976 100644 --- a/charon/tests/ui/raw-boxes.out +++ b/charon/tests/ui/raw-boxes.out @@ -615,84 +615,6 @@ where Break(B), } -// Full name: core::option::Option -#[lang_item("Option")] -pub enum Option -where - [@TraitClause0]: Sized, -{ - None, - Some(T), -} - -pub fn core::ptr::alignment::{Alignment}::new(_1: usize) -> Option[{built_in impl Sized for Alignment}] -{ - let _0: Option[{built_in impl Sized for Alignment}]; // return - let align_1: usize; // arg #1 - let _2: Alignment; // anonymous local - let _3: u32; // anonymous local - let _4: (); // anonymous local - let _5: bool; // anonymous local - let _6: Option[{built_in impl Sized for Alignment}]; // anonymous local - - storage_live(_4) - storage_live(_3) - _3 = ctpop[{built_in impl Sized for usize}, {impl Copy for usize}](copy align_1) - switch copy _3 { - 1 : u32 => { - }, - _ => { - storage_dead(_3) - storage_live(_6) - _6 = Option::None { } - _0 = move _6 - return - }, - } - storage_dead(_3) - storage_live(_2) - storage_live(_5) - _5 = ub_checks - if move _5 { - _4 = core::ptr::alignment::{Alignment}::new_unchecked::precondition_check(copy align_1) - } else { - } - _2 = transmute(copy align_1) - _0 = Option::Some { 0: move _2 } - storage_dead(_2) - return -} - -// Full name: core::option::unwrap_failed -fn unwrap_failed() -> ! -{ - let _0: !; // return - - panic(core::panicking::panic) -} - -// Full name: core::option::{Option[@TraitClause0]}::unwrap -#[lang_item("option_unwrap")] -pub fn unwrap(_1: Option[@TraitClause0]) -> T -where - [@TraitClause0]: Sized, -{ - let val_0: T; // return - let self_1: Option[@TraitClause0]; // arg #1 - let _2: !; // anonymous local - - storage_live(_2) - match self_1 { - Option::None => { - }, - Option::Some => { - val_0 = move (self_1 as variant Option::Some).0 - return - }, - } - _2 = unwrap_failed() -} - pub fn core::num::{usize}::MAX() -> usize { let _0: usize; // return @@ -815,7 +737,107 @@ where [@TraitClause0]: SizedTypeProperties, = IS_ZST() -pub fn core::intrinsics::align_of() -> usize +// Full name: core::option::Option +#[lang_item("Option")] +pub enum Option +where + [@TraitClause0]: Sized, +{ + None, + Some(T), +} + +pub fn core::ptr::alignment::{Alignment}::new(_1: usize) -> Option[{built_in impl Sized for Alignment}] +{ + let _0: Option[{built_in impl Sized for Alignment}]; // return + let align_1: usize; // arg #1 + let _2: Alignment; // anonymous local + let _3: u32; // anonymous local + let _4: (); // anonymous local + let _5: bool; // anonymous local + let _6: Option[{built_in impl Sized for Alignment}]; // anonymous local + + storage_live(_4) + storage_live(_3) + _3 = ctpop[{built_in impl Sized for usize}, {impl Copy for usize}](copy align_1) + switch copy _3 { + 1 : u32 => { + }, + _ => { + storage_dead(_3) + storage_live(_6) + _6 = Option::None { } + _0 = move _6 + return + }, + } + storage_dead(_3) + storage_live(_2) + storage_live(_5) + _5 = ub_checks + if move _5 { + _4 = core::ptr::alignment::{Alignment}::new_unchecked::precondition_check(copy align_1) + } else { + } + _2 = transmute(copy align_1) + _0 = Option::Some { 0: move _2 } + storage_dead(_2) + return +} + +// Full name: core::option::unwrap_failed +fn unwrap_failed() -> ! +{ + let _0: !; // return + + panic(core::panicking::panic) +} + +// Full name: core::option::{Option[@TraitClause0]}::unwrap +#[lang_item("option_unwrap")] +pub fn unwrap(_1: Option[@TraitClause0]) -> T +where + [@TraitClause0]: Sized, +{ + let val_0: T; // return + let self_1: Option[@TraitClause0]; // arg #1 + let _2: !; // anonymous local + + storage_live(_2) + match self_1 { + Option::None => { + }, + Option::Some => { + val_0 = move (self_1 as variant Option::Some).0 + return + }, + } + _2 = unwrap_failed() +} + +// Full name: core::mem::SizedTypeProperties::ALIGNMENT +pub fn ALIGNMENT() -> Alignment +where + [@TraitClause0]: SizedTypeProperties, +{ + let _0: Alignment; // return + let _1: Option[{built_in impl Sized for Alignment}]; // anonymous local + + storage_live(_1) + _1 = core::ptr::alignment::{Alignment}::new(const @TraitClause0::ALIGN) + _0 = unwrap[{built_in impl Sized for Alignment}](move _1) + storage_dead(_1) + return +} + +// Full name: core::mem::SizedTypeProperties::ALIGNMENT +pub const ALIGNMENT: Alignment +where + [@TraitClause0]: SizedTypeProperties, + = ALIGNMENT() + +// Full name: core::intrinsics::align_of +pub fn align_of() -> usize where [@TraitClause0]: Sized, { @@ -832,7 +854,7 @@ where { let _0: usize; // return - _0 = core::intrinsics::align_of[@TraitClause0::parent_clause0]() + _0 = align_of[@TraitClause0::parent_clause0]() return } @@ -872,34 +894,6 @@ where [@TraitClause0]: SizedTypeProperties, = SIZE() -#[lang_item("mem_align_of")] -pub fn core::mem::align_of() -> usize -where - [@TraitClause0]: Sized, -{ - let _0: usize; // return - - _0 = const {impl SizedTypeProperties for T}[@TraitClause0]::ALIGN - return -} - -// Full name: core::mem::SizedTypeProperties::ALIGNMENT -pub fn ALIGNMENT() -> Alignment -where - [@TraitClause0]: SizedTypeProperties, -{ - let _0: Alignment; // return - - _0 = of[@TraitClause0::parent_clause0]() - return -} - -// Full name: core::mem::SizedTypeProperties::ALIGNMENT -pub const ALIGNMENT: Alignment -where - [@TraitClause0]: SizedTypeProperties, - = ALIGNMENT() - // Full name: core::mem::{impl SizedTypeProperties for T} impl SizedTypeProperties for T where @@ -915,28 +909,6 @@ where non-dyn-compatible } -// Full name: core::ptr::alignment::{Alignment}::of -pub fn of() -> Alignment -where - [@TraitClause0]: Sized, -{ - let _0: Alignment; // return - let _1: Alignment; // anonymous local - let _2: Option[{built_in impl Sized for Alignment}]; // anonymous local - let _3: usize; // anonymous local - - storage_live(_1) - storage_live(_2) - storage_live(_3) - _3 = core::mem::align_of[@TraitClause0]() - _2 = core::ptr::alignment::{Alignment}::new(move _3) - storage_dead(_3) - _1 = unwrap[{built_in impl Sized for Alignment}](move _2) - storage_dead(_2) - _0 = move _1 - return -} - // Full name: core::intrinsics::write_bytes pub unsafe fn write_bytes(_1: *mut T, _2: u8, _3: usize) where @@ -964,77 +936,88 @@ where let layout_2: Layout; // arg #2 let _3: ControlFlow[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}], NonNull<[u8]>>[{built_in impl Sized for Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]}, {built_in impl Sized for NonNull<[u8]>}]; // anonymous local let self_4: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // local - let ptr_5: NonNull<[u8]>; // local - let _6: (); // anonymous local - let self_7: *mut u8; // local - let self_8: NonNull; // local - let count_9: usize; // local - let v_10: NonNull<[u8]>; // local - let _11: *const u8; // anonymous local - let _12: *mut [u8]; // anonymous local - let _13: (); // anonymous local - let _14: *const (); // anonymous local + let _5: Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]; // anonymous local + let ptr_6: NonNull<[u8]>; // local + let _7: (); // anonymous local + let self_8: *mut u8; // local + let self_9: NonNull; // local + let count_10: usize; // local + let v_11: NonNull<[u8]>; // local + let _12: *const u8; // anonymous local + let _13: *mut [u8]; // anonymous local + let _14: isize; // anonymous local let _15: bool; // anonymous local - let _16: bool; // anonymous local - let _17: AllocError; // anonymous local - let _18: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local + let _16: (); // anonymous local + let _17: *const (); // anonymous local + let _18: bool; // anonymous local + let _19: bool; // anonymous local + let _20: AllocError; // anonymous local + let _21: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local - storage_live(ptr_5) - storage_live(_6) - storage_live(_12) + storage_live(_5) + storage_live(ptr_6) + storage_live(_7) storage_live(_13) + storage_live(_16) storage_live(_3) storage_live(self_4) self_4 = @TraitClause0::allocate<'3>(move self_1, move layout_2) - storage_live(v_10) + storage_live(v_11) match self_4 { Result::Ok => { }, Result::Err => { - storage_dead(v_10) + storage_dead(v_11) storage_dead(self_4) - storage_live(_17) - _17 = AllocError { } - storage_live(_18) - _18 = Result::Err { 0: move _17 } - _0 = move _18 + storage_live(_14) + storage_live(_15) + _14 = @discriminant(_5) + _15 = copy _14 == const 1 : isize + assert(move _15 == true) else undefined_behavior + storage_live(_20) + _20 = AllocError { } + storage_live(_21) + _21 = Result::Err { 0: move _20 } + _0 = move _21 + storage_dead(_15) + storage_dead(_14) storage_dead(_3) return }, } - v_10 = move (self_4 as variant Result::Ok).0 - _3 = ControlFlow::Continue { 0: copy v_10 } - storage_dead(v_10) + v_11 = move (self_4 as variant Result::Ok).0 + _3 = ControlFlow::Continue { 0: copy v_11 } + storage_dead(v_11) storage_dead(self_4) - ptr_5 = copy (_3 as variant ControlFlow::Continue).0 + ptr_6 = copy (_3 as variant ControlFlow::Continue).0 storage_dead(_3) - storage_live(self_7) storage_live(self_8) - storage_live(_11) - _12 = transmute, *mut [u8]>(copy ptr_5) - _11 = cast<*mut [u8], *const u8>(copy _12) - self_8 = NonNull { pointer: copy _11 } - storage_dead(_11) - self_7 = cast<*mut [u8], *mut u8>(copy _12) - storage_dead(self_8) - storage_live(count_9) - count_9 = copy _12.metadata - storage_live(_16) - _16 = ub_checks - if move _16 { - storage_live(_14) - _14 = cast<*mut [u8], *const ()>(copy _12) - storage_live(_15) - _15 = copy count_9 == const 0 : usize - _13 = core::ptr::write_bytes::precondition_check(move _14, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::ALIGN, move _15) - storage_dead(_15) - storage_dead(_14) + storage_live(self_9) + storage_live(_12) + _13 = transmute, *mut [u8]>(copy ptr_6) + _12 = cast<*mut [u8], *const u8>(copy _13) + self_9 = NonNull { pointer: copy _12 } + storage_dead(_12) + self_8 = cast<*mut [u8], *mut u8>(copy _13) + storage_dead(self_9) + storage_live(count_10) + count_10 = copy _13.metadata + storage_live(_19) + _19 = ub_checks + if move _19 { + storage_live(_17) + _17 = cast<*mut [u8], *const ()>(copy _13) + storage_live(_18) + _18 = copy count_10 == const 0 : usize + _16 = core::ptr::write_bytes::precondition_check(move _17, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::ALIGN, move _18) + storage_dead(_18) + storage_dead(_17) } else { } - _6 = write_bytes[{built_in impl Sized for u8}](move self_7, const 0 : u8, move count_9) - storage_dead(count_9) - storage_dead(self_7) - _0 = Result::Ok { 0: copy ptr_5 } + _7 = write_bytes[{built_in impl Sized for u8}](move self_8, const 0 : u8, move count_10) + storage_dead(count_10) + storage_dead(self_8) + _0 = Result::Ok { 0: copy ptr_6 } return } @@ -1391,74 +1374,85 @@ where let new_layout_4: Layout; // arg #4 let _5: ControlFlow[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}], NonNull<[u8]>>[{built_in impl Sized for Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]}, {built_in impl Sized for NonNull<[u8]>}]; // anonymous local let self_6: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // local - let new_ptr_7: NonNull<[u8]>; // local - let src_8: *const u8; // local - let dst_9: *mut u8; // local - let count_10: usize; // local - let _11: (); // anonymous local - let v_12: NonNull<[u8]>; // local - let _13: *mut [u8]; // anonymous local - let _14: (); // anonymous local - let _15: *const (); // anonymous local - let _16: *mut (); // anonymous local - let _17: bool; // anonymous local - let _18: AllocError; // anonymous local - let _19: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local - - storage_live(new_ptr_7) - storage_live(_11) - storage_live(_13) - storage_live(_14) + let _7: Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]; // anonymous local + let new_ptr_8: NonNull<[u8]>; // local + let src_9: *const u8; // local + let dst_10: *mut u8; // local + let count_11: usize; // local + let _12: (); // anonymous local + let v_13: NonNull<[u8]>; // local + let _14: isize; // anonymous local + let _15: bool; // anonymous local + let _16: *mut [u8]; // anonymous local + let _17: (); // anonymous local + let _18: *const (); // anonymous local + let _19: *mut (); // anonymous local + let _20: bool; // anonymous local + let _21: AllocError; // anonymous local + let _22: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local + + storage_live(_7) + storage_live(new_ptr_8) + storage_live(_12) + storage_live(_16) + storage_live(_17) storage_live(_5) storage_live(self_6) self_6 = @TraitClause0::allocate<'9>(copy self_1, move new_layout_4) - storage_live(v_12) + storage_live(v_13) match self_6 { Result::Ok => { }, Result::Err => { - storage_dead(v_12) + storage_dead(v_13) storage_dead(self_6) - storage_live(_18) - _18 = AllocError { } - storage_live(_19) - _19 = Result::Err { 0: move _18 } - _0 = move _19 + storage_live(_14) + storage_live(_15) + _14 = @discriminant(_7) + _15 = copy _14 == const 1 : isize + assert(move _15 == true) else undefined_behavior + storage_live(_21) + _21 = AllocError { } + storage_live(_22) + _22 = Result::Err { 0: move _21 } + _0 = move _22 + storage_dead(_15) + storage_dead(_14) storage_dead(_5) return }, } - v_12 = move (self_6 as variant Result::Ok).0 - _5 = ControlFlow::Continue { 0: copy v_12 } - storage_dead(v_12) + v_13 = move (self_6 as variant Result::Ok).0 + _5 = ControlFlow::Continue { 0: copy v_13 } + storage_dead(v_13) storage_dead(self_6) - new_ptr_7 = copy (_5 as variant ControlFlow::Continue).0 + new_ptr_8 = copy (_5 as variant ControlFlow::Continue).0 storage_dead(_5) - storage_live(src_8) - src_8 = transmute, *const u8>(copy ptr_2) - storage_live(dst_9) - _13 = transmute, *mut [u8]>(copy new_ptr_7) - dst_9 = cast<*mut [u8], *mut u8>(copy _13) - storage_live(count_10) - count_10 = copy (old_layout_3).size - storage_live(_17) - _17 = ub_checks - if move _17 { - storage_live(_15) - _15 = transmute, *const ()>(copy ptr_2) - storage_live(_16) - _16 = cast<*mut [u8], *mut ()>(copy _13) - _14 = core::ptr::copy_nonoverlapping::precondition_check(move _15, move _16, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::SIZE, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::ALIGN, copy count_10) - storage_dead(_16) - storage_dead(_15) + storage_live(src_9) + src_9 = transmute, *const u8>(copy ptr_2) + storage_live(dst_10) + _16 = transmute, *mut [u8]>(copy new_ptr_8) + dst_10 = cast<*mut [u8], *mut u8>(copy _16) + storage_live(count_11) + count_11 = copy (old_layout_3).size + storage_live(_20) + _20 = ub_checks + if move _20 { + storage_live(_18) + _18 = transmute, *const ()>(copy ptr_2) + storage_live(_19) + _19 = cast<*mut [u8], *mut ()>(copy _16) + _17 = core::ptr::copy_nonoverlapping::precondition_check(move _18, move _19, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::SIZE, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::ALIGN, copy count_11) + storage_dead(_19) + storage_dead(_18) } else { } - copy_nonoverlapping(copy src_8, copy dst_9, copy count_10) - storage_dead(count_10) - storage_dead(dst_9) - storage_dead(src_8) - _11 = @TraitClause0::deallocate<'11>(move self_1, move ptr_2, move old_layout_3) - _0 = Result::Ok { 0: copy new_ptr_7 } + copy_nonoverlapping(copy src_9, copy dst_10, copy count_11) + storage_dead(count_11) + storage_dead(dst_10) + storage_dead(src_9) + _12 = @TraitClause0::deallocate<'11>(move self_1, move ptr_2, move old_layout_3) + _0 = Result::Ok { 0: copy new_ptr_8 } return } @@ -1473,74 +1467,85 @@ where let new_layout_4: Layout; // arg #4 let _5: ControlFlow[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}], NonNull<[u8]>>[{built_in impl Sized for Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]}, {built_in impl Sized for NonNull<[u8]>}]; // anonymous local let self_6: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // local - let new_ptr_7: NonNull<[u8]>; // local - let src_8: *const u8; // local - let dst_9: *mut u8; // local - let count_10: usize; // local - let _11: (); // anonymous local - let v_12: NonNull<[u8]>; // local - let _13: *mut [u8]; // anonymous local - let _14: (); // anonymous local - let _15: *const (); // anonymous local - let _16: *mut (); // anonymous local - let _17: bool; // anonymous local - let _18: AllocError; // anonymous local - let _19: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local - - storage_live(new_ptr_7) - storage_live(_11) - storage_live(_13) - storage_live(_14) + let _7: Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]; // anonymous local + let new_ptr_8: NonNull<[u8]>; // local + let src_9: *const u8; // local + let dst_10: *mut u8; // local + let count_11: usize; // local + let _12: (); // anonymous local + let v_13: NonNull<[u8]>; // local + let _14: isize; // anonymous local + let _15: bool; // anonymous local + let _16: *mut [u8]; // anonymous local + let _17: (); // anonymous local + let _18: *const (); // anonymous local + let _19: *mut (); // anonymous local + let _20: bool; // anonymous local + let _21: AllocError; // anonymous local + let _22: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local + + storage_live(_7) + storage_live(new_ptr_8) + storage_live(_12) + storage_live(_16) + storage_live(_17) storage_live(_5) storage_live(self_6) self_6 = @TraitClause0::allocate_zeroed<'9>(copy self_1, move new_layout_4) - storage_live(v_12) + storage_live(v_13) match self_6 { Result::Ok => { }, Result::Err => { - storage_dead(v_12) + storage_dead(v_13) storage_dead(self_6) - storage_live(_18) - _18 = AllocError { } - storage_live(_19) - _19 = Result::Err { 0: move _18 } - _0 = move _19 + storage_live(_14) + storage_live(_15) + _14 = @discriminant(_7) + _15 = copy _14 == const 1 : isize + assert(move _15 == true) else undefined_behavior + storage_live(_21) + _21 = AllocError { } + storage_live(_22) + _22 = Result::Err { 0: move _21 } + _0 = move _22 + storage_dead(_15) + storage_dead(_14) storage_dead(_5) return }, } - v_12 = move (self_6 as variant Result::Ok).0 - _5 = ControlFlow::Continue { 0: copy v_12 } - storage_dead(v_12) + v_13 = move (self_6 as variant Result::Ok).0 + _5 = ControlFlow::Continue { 0: copy v_13 } + storage_dead(v_13) storage_dead(self_6) - new_ptr_7 = copy (_5 as variant ControlFlow::Continue).0 + new_ptr_8 = copy (_5 as variant ControlFlow::Continue).0 storage_dead(_5) - storage_live(src_8) - src_8 = transmute, *const u8>(copy ptr_2) - storage_live(dst_9) - _13 = transmute, *mut [u8]>(copy new_ptr_7) - dst_9 = cast<*mut [u8], *mut u8>(copy _13) - storage_live(count_10) - count_10 = copy (old_layout_3).size - storage_live(_17) - _17 = ub_checks - if move _17 { - storage_live(_15) - _15 = transmute, *const ()>(copy ptr_2) - storage_live(_16) - _16 = cast<*mut [u8], *mut ()>(copy _13) - _14 = core::ptr::copy_nonoverlapping::precondition_check(move _15, move _16, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::SIZE, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::ALIGN, copy count_10) - storage_dead(_16) - storage_dead(_15) + storage_live(src_9) + src_9 = transmute, *const u8>(copy ptr_2) + storage_live(dst_10) + _16 = transmute, *mut [u8]>(copy new_ptr_8) + dst_10 = cast<*mut [u8], *mut u8>(copy _16) + storage_live(count_11) + count_11 = copy (old_layout_3).size + storage_live(_20) + _20 = ub_checks + if move _20 { + storage_live(_18) + _18 = transmute, *const ()>(copy ptr_2) + storage_live(_19) + _19 = cast<*mut [u8], *mut ()>(copy _16) + _17 = core::ptr::copy_nonoverlapping::precondition_check(move _18, move _19, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::SIZE, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::ALIGN, copy count_11) + storage_dead(_19) + storage_dead(_18) } else { } - copy_nonoverlapping(copy src_8, copy dst_9, copy count_10) - storage_dead(count_10) - storage_dead(dst_9) - storage_dead(src_8) - _11 = @TraitClause0::deallocate<'11>(move self_1, move ptr_2, move old_layout_3) - _0 = Result::Ok { 0: copy new_ptr_7 } + copy_nonoverlapping(copy src_9, copy dst_10, copy count_11) + storage_dead(count_11) + storage_dead(dst_10) + storage_dead(src_9) + _12 = @TraitClause0::deallocate<'11>(move self_1, move ptr_2, move old_layout_3) + _0 = Result::Ok { 0: copy new_ptr_8 } return } @@ -1555,74 +1560,85 @@ where let new_layout_4: Layout; // arg #4 let _5: ControlFlow[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}], NonNull<[u8]>>[{built_in impl Sized for Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]}, {built_in impl Sized for NonNull<[u8]>}]; // anonymous local let self_6: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // local - let new_ptr_7: NonNull<[u8]>; // local - let src_8: *const u8; // local - let dst_9: *mut u8; // local - let count_10: usize; // local - let _11: (); // anonymous local - let v_12: NonNull<[u8]>; // local - let _13: *mut [u8]; // anonymous local - let _14: (); // anonymous local - let _15: *const (); // anonymous local - let _16: *mut (); // anonymous local - let _17: bool; // anonymous local - let _18: AllocError; // anonymous local - let _19: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local - - storage_live(new_ptr_7) - storage_live(_11) - storage_live(_13) - storage_live(_14) + let _7: Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]; // anonymous local + let new_ptr_8: NonNull<[u8]>; // local + let src_9: *const u8; // local + let dst_10: *mut u8; // local + let count_11: usize; // local + let _12: (); // anonymous local + let v_13: NonNull<[u8]>; // local + let _14: isize; // anonymous local + let _15: bool; // anonymous local + let _16: *mut [u8]; // anonymous local + let _17: (); // anonymous local + let _18: *const (); // anonymous local + let _19: *mut (); // anonymous local + let _20: bool; // anonymous local + let _21: AllocError; // anonymous local + let _22: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local + + storage_live(_7) + storage_live(new_ptr_8) + storage_live(_12) + storage_live(_16) + storage_live(_17) storage_live(_5) storage_live(self_6) self_6 = @TraitClause0::allocate<'9>(copy self_1, copy new_layout_4) - storage_live(v_12) + storage_live(v_13) match self_6 { Result::Ok => { }, Result::Err => { - storage_dead(v_12) + storage_dead(v_13) storage_dead(self_6) - storage_live(_18) - _18 = AllocError { } - storage_live(_19) - _19 = Result::Err { 0: move _18 } - _0 = move _19 + storage_live(_14) + storage_live(_15) + _14 = @discriminant(_7) + _15 = copy _14 == const 1 : isize + assert(move _15 == true) else undefined_behavior + storage_live(_21) + _21 = AllocError { } + storage_live(_22) + _22 = Result::Err { 0: move _21 } + _0 = move _22 + storage_dead(_15) + storage_dead(_14) storage_dead(_5) return }, } - v_12 = move (self_6 as variant Result::Ok).0 - _5 = ControlFlow::Continue { 0: copy v_12 } - storage_dead(v_12) + v_13 = move (self_6 as variant Result::Ok).0 + _5 = ControlFlow::Continue { 0: copy v_13 } + storage_dead(v_13) storage_dead(self_6) - new_ptr_7 = copy (_5 as variant ControlFlow::Continue).0 + new_ptr_8 = copy (_5 as variant ControlFlow::Continue).0 storage_dead(_5) - storage_live(src_8) - src_8 = transmute, *const u8>(copy ptr_2) - storage_live(dst_9) - _13 = transmute, *mut [u8]>(copy new_ptr_7) - dst_9 = cast<*mut [u8], *mut u8>(copy _13) - storage_live(count_10) - count_10 = copy (new_layout_4).size - storage_live(_17) - _17 = ub_checks - if move _17 { - storage_live(_15) - _15 = transmute, *const ()>(copy ptr_2) - storage_live(_16) - _16 = cast<*mut [u8], *mut ()>(copy _13) - _14 = core::ptr::copy_nonoverlapping::precondition_check(move _15, move _16, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::SIZE, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::ALIGN, copy count_10) - storage_dead(_16) - storage_dead(_15) + storage_live(src_9) + src_9 = transmute, *const u8>(copy ptr_2) + storage_live(dst_10) + _16 = transmute, *mut [u8]>(copy new_ptr_8) + dst_10 = cast<*mut [u8], *mut u8>(copy _16) + storage_live(count_11) + count_11 = copy (new_layout_4).size + storage_live(_20) + _20 = ub_checks + if move _20 { + storage_live(_18) + _18 = transmute, *const ()>(copy ptr_2) + storage_live(_19) + _19 = cast<*mut [u8], *mut ()>(copy _16) + _17 = core::ptr::copy_nonoverlapping::precondition_check(move _18, move _19, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::SIZE, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::ALIGN, copy count_11) + storage_dead(_19) + storage_dead(_18) } else { } - copy_nonoverlapping(copy src_8, copy dst_9, copy count_10) - storage_dead(count_10) - storage_dead(dst_9) - storage_dead(src_8) - _11 = @TraitClause0::deallocate<'11>(move self_1, move ptr_2, move old_layout_3) - _0 = Result::Ok { 0: copy new_ptr_7 } + copy_nonoverlapping(copy src_9, copy dst_10, copy count_11) + storage_dead(count_11) + storage_dead(dst_10) + storage_dead(src_9) + _12 = @TraitClause0::deallocate<'11>(move self_1, move ptr_2, move old_layout_3) + _0 = Result::Ok { 0: copy new_ptr_8 } return } @@ -1787,19 +1803,19 @@ fn core::hint::assert_unchecked::precondition_check(_1: bool) } // Full name: alloc::alloc::__rust_alloc -unsafe fn __rust_alloc(_1: usize, _2: usize) -> *mut u8 +unsafe fn __rust_alloc(_1: usize, _2: Alignment) -> *mut u8 = // Full name: alloc::alloc::__rust_dealloc -unsafe fn __rust_dealloc(_1: *mut u8, _2: usize, _3: usize) +unsafe fn __rust_dealloc(_1: *mut u8, _2: usize, _3: Alignment) = // Full name: alloc::alloc::__rust_realloc -unsafe fn __rust_realloc(_1: *mut u8, _2: usize, _3: usize, _4: usize) -> *mut u8 +unsafe fn __rust_realloc(_1: *mut u8, _2: usize, _3: Alignment, _4: usize) -> *mut u8 = // Full name: alloc::alloc::__rust_alloc_zeroed -unsafe fn __rust_alloc_zeroed(_1: usize, _2: usize) -> *mut u8 +unsafe fn __rust_alloc_zeroed(_1: usize, _2: Alignment) -> *mut u8 = // Full name: alloc::alloc::__rust_no_alloc_shim_is_unstable_v2 @@ -1823,187 +1839,190 @@ fn alloc_impl_runtime(_1: Layout, _2: bool) -> Result, AllocError> let _7: ControlFlow[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}], NonNull>[{built_in impl Sized for Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]}, {built_in impl Sized for NonNull}]; // anonymous local let self_8: Result, AllocError>[{built_in impl Sized for NonNull}, {built_in impl Sized for AllocError}]; // local let self_9: Option>[{built_in impl Sized for NonNull}]; // local - let ptr_10: NonNull; // local - let _11: NonNull<[u8]>; // anonymous local - let _12: Alignment; // anonymous local - let _13: *const u8; // anonymous local - let ptr_14: *mut [u8]; // local - let data_15: *mut u8; // local - let _16: (); // anonymous local - let _17: *mut (); // anonymous local - let _18: *const [u8]; // anonymous local - let _19: (); // anonymous local - let _20: usize; // anonymous local + let _10: Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]; // anonymous local + let ptr_11: NonNull; // local + let _12: NonNull<[u8]>; // anonymous local + let _13: Alignment; // anonymous local + let _14: *const u8; // anonymous local + let ptr_15: *mut [u8]; // local + let data_16: *mut u8; // local + let _17: (); // anonymous local + let _18: *mut (); // anonymous local + let _19: *const [u8]; // anonymous local + let _20: (); // anonymous local let _21: Alignment; // anonymous local let _22: (); // anonymous local - let _23: usize; // anonymous local - let _24: Alignment; // anonymous local - let _25: NonNull; // anonymous local - let _26: *const u8; // anonymous local - let _27: usize; // anonymous local - let _28: (); // anonymous local - let _29: *mut (); // anonymous local + let _23: Alignment; // anonymous local + let _24: NonNull; // anonymous local + let _25: *const u8; // anonymous local + let _26: usize; // anonymous local + let _27: (); // anonymous local + let _28: *mut (); // anonymous local + let v_29: NonNull; // local let v_30: NonNull; // local - let v_31: NonNull; // local - let ptr_32: *mut [u8]; // local - let data_33: *mut u8; // local - let _34: (); // anonymous local - let _35: *mut (); // anonymous local - let _36: *const [u8]; // anonymous local + let ptr_31: *mut [u8]; // local + let data_32: *mut u8; // local + let _33: (); // anonymous local + let _34: *mut (); // anonymous local + let _35: *const [u8]; // anonymous local + let _36: isize; // anonymous local let _37: bool; // anonymous local let _38: bool; // anonymous local let _39: bool; // anonymous local - let _40: Option>[{built_in impl Sized for NonNull}]; // anonymous local - let _41: AllocError; // anonymous local - let _42: Result, AllocError>[{built_in impl Sized for NonNull}, {built_in impl Sized for AllocError}]; // anonymous local - let _43: AllocError; // anonymous local - let _44: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local + let _40: bool; // anonymous local + let _41: Option>[{built_in impl Sized for NonNull}]; // anonymous local + let _42: AllocError; // anonymous local + let _43: Result, AllocError>[{built_in impl Sized for NonNull}, {built_in impl Sized for AllocError}]; // anonymous local + let _44: AllocError; // anonymous local + let _45: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local storage_live(size_3) storage_live(raw_ptr_6) - storage_live(ptr_10) - storage_live(_12) - storage_live(_16) - storage_live(_19) + storage_live(_10) + storage_live(ptr_11) + storage_live(_13) + storage_live(_17) + storage_live(_20) storage_live(_22) - storage_live(_26) - storage_live(_28) - storage_live(_34) + storage_live(_25) + storage_live(_27) + storage_live(_33) size_3 = copy (layout_1).size switch copy size_3 { 0 : usize => { }, _ => { if copy zeroed_2 { - _19 = __rust_no_alloc_shim_is_unstable_v2() - storage_live(_20) + _20 = __rust_no_alloc_shim_is_unstable_v2() storage_live(_21) _21 = copy (layout_1).align - _20 = transmute(copy _21) + raw_ptr_6 = __rust_alloc_zeroed(copy size_3, move _21) storage_dead(_21) - raw_ptr_6 = __rust_alloc_zeroed(copy size_3, move _20) - storage_dead(_20) } else { _22 = __rust_no_alloc_shim_is_unstable_v2() storage_live(_23) - storage_live(_24) - _24 = copy (layout_1).align - _23 = transmute(copy _24) - storage_dead(_24) + _23 = copy (layout_1).align raw_ptr_6 = __rust_alloc(copy size_3, move _23) storage_dead(_23) } storage_live(_7) storage_live(self_8) storage_live(self_9) - _26 = cast<*mut u8, *const u8>(copy raw_ptr_6) - storage_live(_27) - _27 = transmute<*mut u8, usize>(copy raw_ptr_6) - switch copy _27 { + _25 = cast<*mut u8, *const u8>(copy raw_ptr_6) + storage_live(_26) + _26 = transmute<*mut u8, usize>(copy raw_ptr_6) + switch copy _26 { 0 : usize => { }, _ => { - storage_dead(_27) - storage_live(_25) - storage_live(_38) - _38 = ub_checks - if move _38 { - storage_live(_29) - _29 = cast<*mut u8, *mut ()>(copy raw_ptr_6) - _28 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _29) - storage_dead(_29) + storage_dead(_26) + storage_live(_24) + storage_live(_39) + _39 = ub_checks + if move _39 { + storage_live(_28) + _28 = cast<*mut u8, *mut ()>(copy raw_ptr_6) + _27 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _28) + storage_dead(_28) } else { } - _25 = NonNull { pointer: copy _26 } - self_9 = Option::Some { 0: move _25 } - storage_dead(_25) + _24 = NonNull { pointer: copy _25 } + self_9 = Option::Some { 0: move _24 } + storage_dead(_24) + storage_live(v_29) + v_29 = move (self_9 as variant Option::Some).0 + self_8 = Result::Ok { 0: copy v_29 } + storage_dead(v_29) + storage_dead(self_9) storage_live(v_30) - v_30 = move (self_9 as variant Option::Some).0 - self_8 = Result::Ok { 0: copy v_30 } + v_30 = move (self_8 as variant Result::Ok).0 + _7 = ControlFlow::Continue { 0: copy v_30 } storage_dead(v_30) - storage_dead(self_9) - storage_live(v_31) - v_31 = move (self_8 as variant Result::Ok).0 - _7 = ControlFlow::Continue { 0: copy v_31 } - storage_dead(v_31) storage_dead(self_8) - ptr_10 = copy (_7 as variant ControlFlow::Continue).0 + ptr_11 = copy (_7 as variant ControlFlow::Continue).0 storage_dead(_7) - storage_live(_11) - storage_live(ptr_32) - storage_live(data_33) - data_33 = transmute, *mut u8>(copy ptr_10) - ptr_32 = *mut (copy data_33, copy size_3) - storage_dead(data_33) - storage_live(_36) - storage_live(_39) - _39 = ub_checks - if move _39 { - storage_live(_35) - _35 = transmute, *mut ()>(copy ptr_10) - _34 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _35) - storage_dead(_35) + storage_live(_12) + storage_live(ptr_31) + storage_live(data_32) + data_32 = transmute, *mut u8>(copy ptr_11) + ptr_31 = *mut (copy data_32, copy size_3) + storage_dead(data_32) + storage_live(_35) + storage_live(_40) + _40 = ub_checks + if move _40 { + storage_live(_34) + _34 = transmute, *mut ()>(copy ptr_11) + _33 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _34) + storage_dead(_34) } else { } - _36 = cast<*mut [u8], *const [u8]>(copy ptr_32) - _11 = NonNull { pointer: copy _36 } - storage_dead(_36) - storage_dead(ptr_32) - _0 = Result::Ok { 0: move _11 } - storage_dead(_11) + _35 = cast<*mut [u8], *const [u8]>(copy ptr_31) + _12 = NonNull { pointer: copy _35 } + storage_dead(_35) + storage_dead(ptr_31) + _0 = Result::Ok { 0: move _12 } + storage_dead(_12) return }, } - storage_dead(_27) - storage_live(_40) - _40 = Option::None { } - self_9 = move _40 - storage_live(v_30) + storage_dead(_26) storage_live(_41) - _41 = AllocError { } + _41 = Option::None { } + self_9 = move _41 + storage_live(v_29) storage_live(_42) - _42 = Result::Err { 0: move _41 } - self_8 = move _42 - storage_dead(v_30) + _42 = AllocError { } + storage_live(_43) + _43 = Result::Err { 0: move _42 } + self_8 = move _43 + storage_dead(v_29) storage_dead(self_9) - storage_live(v_31) - storage_dead(v_31) + storage_live(v_30) + storage_dead(v_30) storage_dead(self_8) - storage_live(_43) - _43 = AllocError { } + storage_live(_36) + storage_live(_37) + _36 = @discriminant(_10) + _37 = copy _36 == const 1 : isize + assert(move _37 == true) else undefined_behavior storage_live(_44) - _44 = Result::Err { 0: move _43 } - _0 = move _44 + _44 = AllocError { } + storage_live(_45) + _45 = Result::Err { 0: move _44 } + _0 = move _45 + storage_dead(_37) + storage_dead(_36) storage_dead(_7) return }, } storage_live(_4) storage_live(data_5) - _12 = copy (layout_1).align - storage_live(_13) - _13 = transmute(copy _12) - data_5 = NonNull { pointer: copy _13 } - storage_dead(_13) - storage_live(ptr_14) - storage_live(data_15) - data_15 = transmute(copy _12) - ptr_14 = *mut (copy data_15, const 0 : usize) - storage_dead(data_15) - storage_live(_18) - storage_live(_37) - _37 = ub_checks - if move _37 { - storage_live(_17) - _17 = transmute(copy _12) - _16 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _17) - storage_dead(_17) + _13 = copy (layout_1).align + storage_live(_14) + _14 = transmute(copy _13) + data_5 = NonNull { pointer: copy _14 } + storage_dead(_14) + storage_live(ptr_15) + storage_live(data_16) + data_16 = transmute(copy _13) + ptr_15 = *mut (copy data_16, const 0 : usize) + storage_dead(data_16) + storage_live(_19) + storage_live(_38) + _38 = ub_checks + if move _38 { + storage_live(_18) + _18 = transmute(copy _13) + _17 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _18) + storage_dead(_18) } else { } - _18 = cast<*mut [u8], *const [u8]>(copy ptr_14) - _4 = NonNull { pointer: copy _18 } - storage_dead(_18) - storage_dead(ptr_14) + _19 = cast<*mut [u8], *const [u8]>(copy ptr_15) + _4 = NonNull { pointer: copy _19 } + storage_dead(_19) + storage_dead(ptr_15) storage_dead(data_5) _0 = Result::Ok { 0: move _4 } storage_dead(_4) @@ -2030,259 +2049,283 @@ fn grow_impl_runtime<'_0>(_1: &'_0 Global, _2: NonNull, _3: Layout, _4: Layo let _14: ControlFlow[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}], NonNull>[{built_in impl Sized for Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]}, {built_in impl Sized for NonNull}]; // anonymous local let self_15: Result, AllocError>[{built_in impl Sized for NonNull}, {built_in impl Sized for AllocError}]; // local let self_16: Option>[{built_in impl Sized for NonNull}]; // local - let ptr_17: NonNull; // local - let _18: (); // anonymous local - let self_19: *mut u8; // local - let count_20: usize; // local - let _21: NonNull<[u8]>; // anonymous local - let _22: ControlFlow[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}], NonNull<[u8]>>[{built_in impl Sized for Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]}, {built_in impl Sized for NonNull<[u8]>}]; // anonymous local - let self_23: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // local - let new_ptr_24: NonNull<[u8]>; // local - let src_25: *const u8; // local - let ptr_26: *mut u8; // local - let dst_27: *mut u8; // local - let _28: (); // anonymous local - let _29: Alignment; // anonymous local - let _30: Alignment; // anonymous local - let _31: (); // anonymous local - let _32: NonNull; // anonymous local - let _33: *const u8; // anonymous local - let _34: usize; // anonymous local - let _35: (); // anonymous local - let _36: *mut (); // anonymous local - let v_37: NonNull; // local - let v_38: NonNull; // local - let _39: (); // anonymous local - let _40: *const (); // anonymous local - let _41: bool; // anonymous local - let ptr_42: *mut [u8]; // local - let data_43: *mut u8; // local - let _44: (); // anonymous local - let _45: *mut (); // anonymous local - let _46: *const [u8]; // anonymous local - let v_47: NonNull<[u8]>; // local - let _48: *mut [u8]; // anonymous local - let _49: (); // anonymous local - let _50: *const (); // anonymous local - let _51: *mut (); // anonymous local - let _52: bool; // anonymous local + let _17: Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]; // anonymous local + let ptr_18: NonNull; // local + let _19: (); // anonymous local + let self_20: *mut u8; // local + let count_21: usize; // local + let _22: NonNull<[u8]>; // anonymous local + let _23: ControlFlow[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}], NonNull<[u8]>>[{built_in impl Sized for Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]}, {built_in impl Sized for NonNull<[u8]>}]; // anonymous local + let self_24: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // local + let _25: Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]; // anonymous local + let new_ptr_26: NonNull<[u8]>; // local + let src_27: *const u8; // local + let ptr_28: *mut u8; // local + let dst_29: *mut u8; // local + let _30: (); // anonymous local + let _31: Alignment; // anonymous local + let _32: Alignment; // anonymous local + let _33: (); // anonymous local + let _34: NonNull; // anonymous local + let _35: *const u8; // anonymous local + let _36: usize; // anonymous local + let _37: (); // anonymous local + let _38: *mut (); // anonymous local + let v_39: NonNull; // local + let v_40: NonNull; // local + let _41: isize; // anonymous local + let _42: bool; // anonymous local + let _43: (); // anonymous local + let _44: *const (); // anonymous local + let _45: bool; // anonymous local + let ptr_46: *mut [u8]; // local + let data_47: *mut u8; // local + let _48: (); // anonymous local + let _49: *mut (); // anonymous local + let _50: *const [u8]; // anonymous local + let v_51: NonNull<[u8]>; // local + let _52: isize; // anonymous local let _53: bool; // anonymous local - let _54: bool; // anonymous local - let _55: bool; // anonymous local - let _56: bool; // anonymous local - let _57: AllocError; // anonymous local - let _58: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local - let _59: Option>[{built_in impl Sized for NonNull}]; // anonymous local - let _60: AllocError; // anonymous local - let _61: Result, AllocError>[{built_in impl Sized for NonNull}, {built_in impl Sized for AllocError}]; // anonymous local - let _62: AllocError; // anonymous local - let _63: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local + let _54: *mut [u8]; // anonymous local + let _55: (); // anonymous local + let _56: *const (); // anonymous local + let _57: *mut (); // anonymous local + let _58: bool; // anonymous local + let _59: bool; // anonymous local + let _60: bool; // anonymous local + let _61: bool; // anonymous local + let _62: bool; // anonymous local + let _63: AllocError; // anonymous local + let _64: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local + let _65: Option>[{built_in impl Sized for NonNull}]; // anonymous local + let _66: AllocError; // anonymous local + let _67: Result, AllocError>[{built_in impl Sized for NonNull}, {built_in impl Sized for AllocError}]; // anonymous local + let _68: AllocError; // anonymous local + let _69: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local storage_live(old_size_6) - storage_live(_8) storage_live(new_size_10) storage_live(raw_ptr_12) - storage_live(ptr_17) - storage_live(_18) - storage_live(new_ptr_24) - storage_live(ptr_26) - storage_live(_28) - storage_live(_29) + storage_live(_17) + storage_live(ptr_18) + storage_live(_19) + storage_live(_25) + storage_live(new_ptr_26) + storage_live(ptr_28) + storage_live(_30) storage_live(_31) storage_live(_33) storage_live(_35) - storage_live(_39) - storage_live(_44) + storage_live(_37) + storage_live(_43) storage_live(_48) - storage_live(_49) + storage_live(_54) + storage_live(_55) old_size_6 = copy (old_layout_3).size switch copy old_size_6 { 0 : usize => { }, _ => { storage_live(_7) - _29 = copy (old_layout_3).align - _8 = transmute(copy _29) + storage_live(_8) + _31 = copy (old_layout_3).align + _8 = transmute(copy _31) storage_live(_9) - storage_live(_30) - _30 = copy (new_layout_4).align - _9 = transmute(copy _30) - storage_dead(_30) - _7 = copy _8 == move _9 + storage_live(_32) + _32 = copy (new_layout_4).align + _9 = transmute(copy _32) + storage_dead(_32) + _7 = move _8 == move _9 if move _7 { } else { storage_dead(_9) + storage_dead(_8) storage_dead(_7) - storage_live(_22) - storage_live(self_23) - self_23 = alloc_impl_runtime(move new_layout_4, move zeroed_5) - storage_live(v_47) - match self_23 { + storage_live(_23) + storage_live(self_24) + self_24 = alloc_impl_runtime(move new_layout_4, move zeroed_5) + storage_live(v_51) + match self_24 { Result::Ok => { }, Result::Err => { - storage_dead(v_47) - storage_dead(self_23) - storage_live(_57) - _57 = AllocError { } - storage_live(_58) - _58 = Result::Err { 0: move _57 } - _0 = move _58 - storage_dead(_22) + storage_dead(v_51) + storage_dead(self_24) + storage_live(_52) + storage_live(_53) + _52 = @discriminant(_25) + _53 = copy _52 == const 1 : isize + assert(move _53 == true) else undefined_behavior + storage_live(_63) + _63 = AllocError { } + storage_live(_64) + _64 = Result::Err { 0: move _63 } + _0 = move _64 + storage_dead(_53) + storage_dead(_52) + storage_dead(_23) return }, } - v_47 = move (self_23 as variant Result::Ok).0 - _22 = ControlFlow::Continue { 0: copy v_47 } - storage_dead(v_47) - storage_dead(self_23) - new_ptr_24 = copy (_22 as variant ControlFlow::Continue).0 - storage_dead(_22) - storage_live(src_25) - ptr_26 = transmute, *mut u8>(copy ptr_2) - src_25 = transmute, *const u8>(copy ptr_2) - storage_live(dst_27) - _48 = transmute, *mut [u8]>(copy new_ptr_24) - dst_27 = cast<*mut [u8], *mut u8>(copy _48) - storage_live(_53) - _53 = ub_checks - if move _53 { - storage_live(_50) - _50 = transmute, *const ()>(copy ptr_2) - storage_live(_51) - _51 = cast<*mut [u8], *mut ()>(copy _48) - _49 = core::ptr::copy_nonoverlapping::precondition_check(move _50, move _51, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::SIZE, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::ALIGN, copy old_size_6) - storage_dead(_51) - storage_dead(_50) + v_51 = move (self_24 as variant Result::Ok).0 + _23 = ControlFlow::Continue { 0: copy v_51 } + storage_dead(v_51) + storage_dead(self_24) + new_ptr_26 = copy (_23 as variant ControlFlow::Continue).0 + storage_dead(_23) + storage_live(src_27) + ptr_28 = transmute, *mut u8>(copy ptr_2) + src_27 = transmute, *const u8>(copy ptr_2) + storage_live(dst_29) + _54 = transmute, *mut [u8]>(copy new_ptr_26) + dst_29 = cast<*mut [u8], *mut u8>(copy _54) + storage_live(_59) + _59 = ub_checks + if move _59 { + storage_live(_56) + _56 = transmute, *const ()>(copy ptr_2) + storage_live(_57) + _57 = cast<*mut [u8], *mut ()>(copy _54) + _55 = core::ptr::copy_nonoverlapping::precondition_check(move _56, move _57, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::SIZE, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::ALIGN, copy old_size_6) + storage_dead(_57) + storage_dead(_56) } else { } - copy_nonoverlapping(copy src_25, copy dst_27, copy old_size_6) - storage_dead(dst_27) - storage_dead(src_25) - _28 = __rust_dealloc(move ptr_26, move old_size_6, move _8) - _0 = Result::Ok { 0: copy new_ptr_24 } + copy_nonoverlapping(copy src_27, copy dst_29, copy old_size_6) + storage_dead(dst_29) + storage_dead(src_27) + _30 = __rust_dealloc(move ptr_28, move old_size_6, move _31) + _0 = Result::Ok { 0: copy new_ptr_26 } return } storage_dead(_9) + storage_dead(_8) storage_dead(_7) new_size_10 = copy (new_layout_4).size storage_live(cond_11) cond_11 = copy new_size_10 >= copy old_size_6 - storage_live(_52) - _52 = ub_checks - if move _52 { - _31 = core::hint::assert_unchecked::precondition_check(copy cond_11) + storage_live(_58) + _58 = ub_checks + if move _58 { + _33 = core::hint::assert_unchecked::precondition_check(copy cond_11) } else { } assert(copy cond_11 == true) else undefined_behavior storage_dead(cond_11) storage_live(ptr_13) ptr_13 = transmute, *mut u8>(copy ptr_2) - raw_ptr_12 = __rust_realloc(move ptr_13, copy old_size_6, move _8, copy new_size_10) + raw_ptr_12 = __rust_realloc(move ptr_13, copy old_size_6, move _31, copy new_size_10) storage_dead(ptr_13) storage_live(_14) storage_live(self_15) storage_live(self_16) - _33 = cast<*mut u8, *const u8>(copy raw_ptr_12) - storage_live(_34) - _34 = transmute<*mut u8, usize>(copy raw_ptr_12) - switch copy _34 { + _35 = cast<*mut u8, *const u8>(copy raw_ptr_12) + storage_live(_36) + _36 = transmute<*mut u8, usize>(copy raw_ptr_12) + switch copy _36 { 0 : usize => { }, _ => { - storage_dead(_34) - storage_live(_32) - storage_live(_54) - _54 = ub_checks - if move _54 { - storage_live(_36) - _36 = cast<*mut u8, *mut ()>(copy raw_ptr_12) - _35 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _36) - storage_dead(_36) + storage_dead(_36) + storage_live(_34) + storage_live(_60) + _60 = ub_checks + if move _60 { + storage_live(_38) + _38 = cast<*mut u8, *mut ()>(copy raw_ptr_12) + _37 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _38) + storage_dead(_38) } else { } - _32 = NonNull { pointer: copy _33 } - self_16 = Option::Some { 0: move _32 } - storage_dead(_32) - storage_live(v_37) - v_37 = move (self_16 as variant Option::Some).0 - self_15 = Result::Ok { 0: copy v_37 } - storage_dead(v_37) + _34 = NonNull { pointer: copy _35 } + self_16 = Option::Some { 0: move _34 } + storage_dead(_34) + storage_live(v_39) + v_39 = move (self_16 as variant Option::Some).0 + self_15 = Result::Ok { 0: copy v_39 } + storage_dead(v_39) storage_dead(self_16) - storage_live(v_38) - v_38 = move (self_15 as variant Result::Ok).0 - _14 = ControlFlow::Continue { 0: copy v_38 } - storage_dead(v_38) + storage_live(v_40) + v_40 = move (self_15 as variant Result::Ok).0 + _14 = ControlFlow::Continue { 0: copy v_40 } + storage_dead(v_40) storage_dead(self_15) - ptr_17 = copy (_14 as variant ControlFlow::Continue).0 + ptr_18 = copy (_14 as variant ControlFlow::Continue).0 storage_dead(_14) if copy zeroed_5 { - storage_live(self_19) - self_19 = copy raw_ptr_12 offset copy old_size_6 - storage_live(count_20) - count_20 = copy new_size_10 wrap.- copy old_size_6 - storage_live(_55) - _55 = ub_checks - if move _55 { - storage_live(_40) - _40 = cast<*mut u8, *const ()>(copy self_19) - storage_live(_41) - _41 = copy count_20 == const 0 : usize - _39 = core::ptr::write_bytes::precondition_check(move _40, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::ALIGN, move _41) - storage_dead(_41) - storage_dead(_40) + storage_live(self_20) + self_20 = copy raw_ptr_12 offset copy old_size_6 + storage_live(count_21) + count_21 = copy new_size_10 wrap.- copy old_size_6 + storage_live(_61) + _61 = ub_checks + if move _61 { + storage_live(_44) + _44 = cast<*mut u8, *const ()>(copy self_20) + storage_live(_45) + _45 = copy count_21 == const 0 : usize + _43 = core::ptr::write_bytes::precondition_check(move _44, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::ALIGN, move _45) + storage_dead(_45) + storage_dead(_44) } else { } - _18 = write_bytes[{built_in impl Sized for u8}](move self_19, const 0 : u8, move count_20) - storage_dead(count_20) - storage_dead(self_19) + _19 = write_bytes[{built_in impl Sized for u8}](move self_20, const 0 : u8, move count_21) + storage_dead(count_21) + storage_dead(self_20) } else { } - storage_live(_21) - storage_live(ptr_42) - storage_live(data_43) - data_43 = transmute, *mut u8>(copy ptr_17) - ptr_42 = *mut (copy data_43, copy new_size_10) - storage_dead(data_43) - storage_live(_46) - storage_live(_56) - _56 = ub_checks - if move _56 { - storage_live(_45) - _45 = transmute, *mut ()>(copy ptr_17) - _44 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _45) - storage_dead(_45) + storage_live(_22) + storage_live(ptr_46) + storage_live(data_47) + data_47 = transmute, *mut u8>(copy ptr_18) + ptr_46 = *mut (copy data_47, copy new_size_10) + storage_dead(data_47) + storage_live(_50) + storage_live(_62) + _62 = ub_checks + if move _62 { + storage_live(_49) + _49 = transmute, *mut ()>(copy ptr_18) + _48 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _49) + storage_dead(_49) } else { } - _46 = cast<*mut [u8], *const [u8]>(copy ptr_42) - _21 = NonNull { pointer: copy _46 } - storage_dead(_46) - storage_dead(ptr_42) - _0 = Result::Ok { 0: move _21 } - storage_dead(_21) + _50 = cast<*mut [u8], *const [u8]>(copy ptr_46) + _22 = NonNull { pointer: copy _50 } + storage_dead(_50) + storage_dead(ptr_46) + _0 = Result::Ok { 0: move _22 } + storage_dead(_22) return }, } - storage_dead(_34) - storage_live(_59) - _59 = Option::None { } - self_16 = move _59 - storage_live(v_37) - storage_live(_60) - _60 = AllocError { } - storage_live(_61) - _61 = Result::Err { 0: move _60 } - self_15 = move _61 - storage_dead(v_37) + storage_dead(_36) + storage_live(_65) + _65 = Option::None { } + self_16 = move _65 + storage_live(v_39) + storage_live(_66) + _66 = AllocError { } + storage_live(_67) + _67 = Result::Err { 0: move _66 } + self_15 = move _67 + storage_dead(v_39) storage_dead(self_16) - storage_live(v_38) - storage_dead(v_38) + storage_live(v_40) + storage_dead(v_40) storage_dead(self_15) - storage_live(_62) - _62 = AllocError { } - storage_live(_63) - _63 = Result::Err { 0: move _62 } - _0 = move _63 + storage_live(_41) + storage_live(_42) + _41 = @discriminant(_17) + _42 = copy _41 == const 1 : isize + assert(move _42 == true) else undefined_behavior + storage_live(_68) + _68 = AllocError { } + storage_live(_69) + _69 = Result::Err { 0: move _68 } + _0 = move _69 + storage_dead(_42) + storage_dead(_41) storage_dead(_14) return }, @@ -2314,302 +2357,322 @@ fn shrink_impl_runtime<'_0>(_1: &'_0 Global, _2: NonNull, _3: Layout, _4: La let _17: ControlFlow[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}], NonNull>[{built_in impl Sized for Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]}, {built_in impl Sized for NonNull}]; // anonymous local let self_18: Result, AllocError>[{built_in impl Sized for NonNull}, {built_in impl Sized for AllocError}]; // local let self_19: Option>[{built_in impl Sized for NonNull}]; // local - let ptr_20: NonNull; // local - let _21: NonNull<[u8]>; // anonymous local - let _22: ControlFlow[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}], NonNull<[u8]>>[{built_in impl Sized for Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]}, {built_in impl Sized for NonNull<[u8]>}]; // anonymous local - let self_23: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // local - let new_ptr_24: NonNull<[u8]>; // local - let src_25: *const u8; // local - let ptr_26: *mut u8; // local - let dst_27: *mut u8; // local - let _28: (); // anonymous local - let _29: Alignment; // anonymous local - let _30: usize; // anonymous local - let ptr_31: *mut u8; // local + let _20: Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]; // anonymous local + let ptr_21: NonNull; // local + let _22: NonNull<[u8]>; // anonymous local + let _23: ControlFlow[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}], NonNull<[u8]>>[{built_in impl Sized for Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]}, {built_in impl Sized for NonNull<[u8]>}]; // anonymous local + let self_24: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // local + let _25: Result[{built_in impl Sized for Infallible}, {built_in impl Sized for AllocError}]; // anonymous local + let new_ptr_26: NonNull<[u8]>; // local + let src_27: *const u8; // local + let ptr_28: *mut u8; // local + let dst_29: *mut u8; // local + let _30: (); // anonymous local + let _31: Alignment; // anonymous local let _32: usize; // anonymous local - let _33: Alignment; // anonymous local + let ptr_33: *mut u8; // local let _34: Alignment; // anonymous local - let _35: *const u8; // anonymous local - let ptr_36: *mut [u8]; // local - let data_37: *mut u8; // local - let _38: (); // anonymous local - let _39: *mut (); // anonymous local - let _40: *const [u8]; // anonymous local - let _41: Alignment; // anonymous local - let _42: (); // anonymous local - let _43: NonNull; // anonymous local - let _44: *const u8; // anonymous local - let _45: usize; // anonymous local - let _46: (); // anonymous local - let _47: *mut (); // anonymous local - let v_48: NonNull; // local + let _35: Alignment; // anonymous local + let _36: *const u8; // anonymous local + let ptr_37: *mut [u8]; // local + let data_38: *mut u8; // local + let _39: (); // anonymous local + let _40: *mut (); // anonymous local + let _41: *const [u8]; // anonymous local + let _42: Alignment; // anonymous local + let _43: (); // anonymous local + let _44: NonNull; // anonymous local + let _45: *const u8; // anonymous local + let _46: usize; // anonymous local + let _47: (); // anonymous local + let _48: *mut (); // anonymous local let v_49: NonNull; // local - let ptr_50: *mut [u8]; // local - let data_51: *mut u8; // local - let _52: (); // anonymous local - let _53: *mut (); // anonymous local - let _54: *const [u8]; // anonymous local - let v_55: NonNull<[u8]>; // local - let _56: *mut [u8]; // anonymous local - let _57: (); // anonymous local - let _58: *const (); // anonymous local - let _59: *mut (); // anonymous local - let _60: usize; // anonymous local - let _61: bool; // anonymous local - let _62: bool; // anonymous local - let _63: bool; // anonymous local - let _64: bool; // anonymous local - let _65: bool; // anonymous local - let _66: AllocError; // anonymous local - let _67: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local - let _68: Option>[{built_in impl Sized for NonNull}]; // anonymous local - let _69: AllocError; // anonymous local - let _70: Result, AllocError>[{built_in impl Sized for NonNull}, {built_in impl Sized for AllocError}]; // anonymous local + let v_50: NonNull; // local + let ptr_51: *mut [u8]; // local + let data_52: *mut u8; // local + let _53: (); // anonymous local + let _54: *mut (); // anonymous local + let _55: *const [u8]; // anonymous local + let _56: isize; // anonymous local + let _57: bool; // anonymous local + let v_58: NonNull<[u8]>; // local + let _59: isize; // anonymous local + let _60: bool; // anonymous local + let _61: *mut [u8]; // anonymous local + let _62: (); // anonymous local + let _63: *const (); // anonymous local + let _64: *mut (); // anonymous local + let _65: usize; // anonymous local + let _66: bool; // anonymous local + let _67: bool; // anonymous local + let _68: bool; // anonymous local + let _69: bool; // anonymous local + let _70: bool; // anonymous local let _71: AllocError; // anonymous local let _72: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local + let _73: Option>[{built_in impl Sized for NonNull}]; // anonymous local + let _74: AllocError; // anonymous local + let _75: Result, AllocError>[{built_in impl Sized for NonNull}, {built_in impl Sized for AllocError}]; // anonymous local + let _76: AllocError; // anonymous local + let _77: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local storage_live(new_size_6) storage_live(_7) - storage_live(_11) storage_live(_14) storage_live(raw_ptr_15) - storage_live(ptr_20) - storage_live(new_ptr_24) - storage_live(ptr_26) - storage_live(_28) - storage_live(_29) - storage_live(_34) - storage_live(_38) - storage_live(_42) - storage_live(_44) - storage_live(_46) - storage_live(_52) - storage_live(_56) - storage_live(_57) + storage_live(_20) + storage_live(ptr_21) + storage_live(_25) + storage_live(new_ptr_26) + storage_live(ptr_28) + storage_live(_30) + storage_live(_31) + storage_live(_35) + storage_live(_39) + storage_live(_43) + storage_live(_45) + storage_live(_47) + storage_live(_53) + storage_live(_61) + storage_live(_62) new_size_6 = copy (new_layout_4).size switch copy new_size_6 { 0 : usize => { }, _ => { storage_live(_10) - _29 = copy (old_layout_3).align - _11 = transmute(copy _29) + storage_live(_11) + _31 = copy (old_layout_3).align + _11 = transmute(copy _31) storage_live(_12) - storage_live(_41) - _41 = copy (new_layout_4).align - _12 = transmute(copy _41) - storage_dead(_41) - _10 = copy _11 == move _12 + storage_live(_42) + _42 = copy (new_layout_4).align + _12 = transmute(copy _42) + storage_dead(_42) + _10 = move _11 == move _12 if move _10 { } else { storage_dead(_12) + storage_dead(_11) storage_dead(_10) - storage_live(_22) - storage_live(self_23) - self_23 = alloc_impl_runtime(move new_layout_4, const false) - storage_live(v_55) - match self_23 { + storage_live(_23) + storage_live(self_24) + self_24 = alloc_impl_runtime(move new_layout_4, const false) + storage_live(v_58) + match self_24 { Result::Ok => { }, Result::Err => { - storage_dead(v_55) - storage_dead(self_23) - storage_live(_66) - _66 = AllocError { } - storage_live(_67) - _67 = Result::Err { 0: move _66 } - _0 = move _67 - storage_dead(_22) + storage_dead(v_58) + storage_dead(self_24) + storage_live(_59) + storage_live(_60) + _59 = @discriminant(_25) + _60 = copy _59 == const 1 : isize + assert(move _60 == true) else undefined_behavior + storage_live(_71) + _71 = AllocError { } + storage_live(_72) + _72 = Result::Err { 0: move _71 } + _0 = move _72 + storage_dead(_60) + storage_dead(_59) + storage_dead(_23) return }, } - v_55 = move (self_23 as variant Result::Ok).0 - _22 = ControlFlow::Continue { 0: copy v_55 } - storage_dead(v_55) - storage_dead(self_23) - new_ptr_24 = copy (_22 as variant ControlFlow::Continue).0 - storage_dead(_22) - storage_live(src_25) - ptr_26 = transmute, *mut u8>(copy ptr_2) - src_25 = transmute, *const u8>(copy ptr_2) - storage_live(dst_27) - _56 = transmute, *mut [u8]>(copy new_ptr_24) - dst_27 = cast<*mut [u8], *mut u8>(copy _56) - storage_live(_63) - _63 = ub_checks - if move _63 { - storage_live(_58) - _58 = transmute, *const ()>(copy ptr_2) - storage_live(_59) - _59 = cast<*mut [u8], *mut ()>(copy _56) - _57 = core::ptr::copy_nonoverlapping::precondition_check(move _58, move _59, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::SIZE, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::ALIGN, copy new_size_6) - storage_dead(_59) - storage_dead(_58) + v_58 = move (self_24 as variant Result::Ok).0 + _23 = ControlFlow::Continue { 0: copy v_58 } + storage_dead(v_58) + storage_dead(self_24) + new_ptr_26 = copy (_23 as variant ControlFlow::Continue).0 + storage_dead(_23) + storage_live(src_27) + ptr_28 = transmute, *mut u8>(copy ptr_2) + src_27 = transmute, *const u8>(copy ptr_2) + storage_live(dst_29) + _61 = transmute, *mut [u8]>(copy new_ptr_26) + dst_29 = cast<*mut [u8], *mut u8>(copy _61) + storage_live(_68) + _68 = ub_checks + if move _68 { + storage_live(_63) + _63 = transmute, *const ()>(copy ptr_2) + storage_live(_64) + _64 = cast<*mut [u8], *mut ()>(copy _61) + _62 = core::ptr::copy_nonoverlapping::precondition_check(move _63, move _64, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::SIZE, const {impl SizedTypeProperties for T}[{built_in impl Sized for u8}]::ALIGN, copy new_size_6) + storage_dead(_64) + storage_dead(_63) } else { } - copy_nonoverlapping(copy src_25, copy dst_27, copy new_size_6) - storage_dead(dst_27) - storage_dead(src_25) - storage_live(_60) - _60 = copy (old_layout_3).size - switch copy _60 { + copy_nonoverlapping(copy src_27, copy dst_29, copy new_size_6) + storage_dead(dst_29) + storage_dead(src_27) + storage_live(_65) + _65 = copy (old_layout_3).size + switch copy _65 { 0 : usize => { }, _ => { - _28 = __rust_dealloc(move ptr_26, move _60, move _11) + _30 = __rust_dealloc(move ptr_28, move _65, move _31) }, } - storage_dead(_60) - _0 = Result::Ok { 0: copy new_ptr_24 } + storage_dead(_65) + _0 = Result::Ok { 0: copy new_ptr_26 } return } storage_dead(_12) + storage_dead(_11) storage_dead(_10) storage_live(cond_13) _14 = copy (old_layout_3).size cond_13 = copy new_size_6 <= copy _14 - storage_live(_62) - _62 = ub_checks - if move _62 { - _42 = core::hint::assert_unchecked::precondition_check(copy cond_13) + storage_live(_67) + _67 = ub_checks + if move _67 { + _43 = core::hint::assert_unchecked::precondition_check(copy cond_13) } else { } assert(copy cond_13 == true) else undefined_behavior storage_dead(cond_13) storage_live(ptr_16) ptr_16 = transmute, *mut u8>(copy ptr_2) - raw_ptr_15 = __rust_realloc(move ptr_16, move _14, move _11, copy new_size_6) + raw_ptr_15 = __rust_realloc(move ptr_16, move _14, move _31, copy new_size_6) storage_dead(ptr_16) storage_live(_17) storage_live(self_18) storage_live(self_19) - _44 = cast<*mut u8, *const u8>(copy raw_ptr_15) - storage_live(_45) - _45 = transmute<*mut u8, usize>(copy raw_ptr_15) - switch copy _45 { + _45 = cast<*mut u8, *const u8>(copy raw_ptr_15) + storage_live(_46) + _46 = transmute<*mut u8, usize>(copy raw_ptr_15) + switch copy _46 { 0 : usize => { }, _ => { - storage_dead(_45) - storage_live(_43) - storage_live(_64) - _64 = ub_checks - if move _64 { - storage_live(_47) - _47 = cast<*mut u8, *mut ()>(copy raw_ptr_15) - _46 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _47) - storage_dead(_47) + storage_dead(_46) + storage_live(_44) + storage_live(_69) + _69 = ub_checks + if move _69 { + storage_live(_48) + _48 = cast<*mut u8, *mut ()>(copy raw_ptr_15) + _47 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _48) + storage_dead(_48) } else { } - _43 = NonNull { pointer: copy _44 } - self_19 = Option::Some { 0: move _43 } - storage_dead(_43) - storage_live(v_48) - v_48 = move (self_19 as variant Option::Some).0 - self_18 = Result::Ok { 0: copy v_48 } - storage_dead(v_48) - storage_dead(self_19) + _44 = NonNull { pointer: copy _45 } + self_19 = Option::Some { 0: move _44 } + storage_dead(_44) storage_live(v_49) - v_49 = move (self_18 as variant Result::Ok).0 - _17 = ControlFlow::Continue { 0: copy v_49 } + v_49 = move (self_19 as variant Option::Some).0 + self_18 = Result::Ok { 0: copy v_49 } storage_dead(v_49) + storage_dead(self_19) + storage_live(v_50) + v_50 = move (self_18 as variant Result::Ok).0 + _17 = ControlFlow::Continue { 0: copy v_50 } + storage_dead(v_50) storage_dead(self_18) - ptr_20 = copy (_17 as variant ControlFlow::Continue).0 + ptr_21 = copy (_17 as variant ControlFlow::Continue).0 storage_dead(_17) - storage_live(_21) - storage_live(ptr_50) - storage_live(data_51) - data_51 = transmute, *mut u8>(copy ptr_20) - ptr_50 = *mut (copy data_51, copy new_size_6) - storage_dead(data_51) - storage_live(_54) - storage_live(_65) - _65 = ub_checks - if move _65 { - storage_live(_53) - _53 = transmute, *mut ()>(copy ptr_20) - _52 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _53) - storage_dead(_53) + storage_live(_22) + storage_live(ptr_51) + storage_live(data_52) + data_52 = transmute, *mut u8>(copy ptr_21) + ptr_51 = *mut (copy data_52, copy new_size_6) + storage_dead(data_52) + storage_live(_55) + storage_live(_70) + _70 = ub_checks + if move _70 { + storage_live(_54) + _54 = transmute, *mut ()>(copy ptr_21) + _53 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _54) + storage_dead(_54) } else { } - _54 = cast<*mut [u8], *const [u8]>(copy ptr_50) - _21 = NonNull { pointer: copy _54 } - storage_dead(_54) - storage_dead(ptr_50) - _0 = Result::Ok { 0: move _21 } - storage_dead(_21) + _55 = cast<*mut [u8], *const [u8]>(copy ptr_51) + _22 = NonNull { pointer: copy _55 } + storage_dead(_55) + storage_dead(ptr_51) + _0 = Result::Ok { 0: move _22 } + storage_dead(_22) return }, } - storage_dead(_45) - storage_live(_68) - _68 = Option::None { } - self_19 = move _68 - storage_live(v_48) - storage_live(_69) - _69 = AllocError { } - storage_live(_70) - _70 = Result::Err { 0: move _69 } - self_18 = move _70 - storage_dead(v_48) - storage_dead(self_19) + storage_dead(_46) + storage_live(_73) + _73 = Option::None { } + self_19 = move _73 storage_live(v_49) + storage_live(_74) + _74 = AllocError { } + storage_live(_75) + _75 = Result::Err { 0: move _74 } + self_18 = move _75 storage_dead(v_49) + storage_dead(self_19) + storage_live(v_50) + storage_dead(v_50) storage_dead(self_18) - storage_live(_71) - _71 = AllocError { } - storage_live(_72) - _72 = Result::Err { 0: move _71 } - _0 = move _72 + storage_live(_56) + storage_live(_57) + _56 = @discriminant(_20) + _57 = copy _56 == const 1 : isize + assert(move _57 == true) else undefined_behavior + storage_live(_76) + _76 = AllocError { } + storage_live(_77) + _77 = Result::Err { 0: move _76 } + _0 = move _77 + storage_dead(_57) + storage_dead(_56) storage_dead(_17) return }, } - storage_live(_30) - _30 = copy (old_layout_3).size - switch copy _30 { + storage_live(_32) + _32 = copy (old_layout_3).size + switch copy _32 { 0 : usize => { }, _ => { - storage_live(ptr_31) - ptr_31 = transmute, *mut u8>(copy ptr_2) - storage_live(_32) - storage_live(_33) - _33 = copy (old_layout_3).align - _32 = transmute(copy _33) - storage_dead(_33) - _7 = __rust_dealloc(move ptr_31, move _30, move _32) - storage_dead(_32) - storage_dead(ptr_31) + storage_live(ptr_33) + ptr_33 = transmute, *mut u8>(copy ptr_2) + storage_live(_34) + _34 = copy (old_layout_3).align + _7 = __rust_dealloc(move ptr_33, move _32, move _34) + storage_dead(_34) + storage_dead(ptr_33) }, } - storage_dead(_30) + storage_dead(_32) storage_live(_8) storage_live(data_9) - _34 = copy (new_layout_4).align - storage_live(_35) - _35 = transmute(copy _34) - data_9 = NonNull { pointer: copy _35 } - storage_dead(_35) - storage_live(ptr_36) - storage_live(data_37) - data_37 = transmute(copy _34) - ptr_36 = *mut (copy data_37, const 0 : usize) - storage_dead(data_37) - storage_live(_40) - storage_live(_61) - _61 = ub_checks - if move _61 { - storage_live(_39) - _39 = transmute(copy _34) - _38 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _39) - storage_dead(_39) + _35 = copy (new_layout_4).align + storage_live(_36) + _36 = transmute(copy _35) + data_9 = NonNull { pointer: copy _36 } + storage_dead(_36) + storage_live(ptr_37) + storage_live(data_38) + data_38 = transmute(copy _35) + ptr_37 = *mut (copy data_38, const 0 : usize) + storage_dead(data_38) + storage_live(_41) + storage_live(_66) + _66 = ub_checks + if move _66 { + storage_live(_40) + _40 = transmute(copy _35) + _39 = core::ptr::non_null::{NonNull}::new_unchecked::precondition_check(move _40) + storage_dead(_40) } else { } - _40 = cast<*mut [u8], *const [u8]>(copy ptr_36) - _8 = NonNull { pointer: copy _40 } - storage_dead(_40) - storage_dead(ptr_36) + _41 = cast<*mut [u8], *const [u8]>(copy ptr_37) + _8 = NonNull { pointer: copy _41 } + storage_dead(_41) + storage_dead(ptr_37) storage_dead(data_9) _0 = Result::Ok { 0: move _8 } storage_dead(_8) @@ -2664,8 +2727,7 @@ pub unsafe fn {impl Allocator for Global}::deallocate<'_0>(_1: &'_0 Global, _2: let layout_3: Layout; // arg #3 let _4: usize; // anonymous local let ptr_5: *mut u8; // local - let _6: usize; // anonymous local - let _7: Alignment; // anonymous local + let _6: Alignment; // anonymous local _0 = () storage_live(_4) @@ -2677,10 +2739,7 @@ pub unsafe fn {impl Allocator for Global}::deallocate<'_0>(_1: &'_0 Global, _2: storage_live(ptr_5) ptr_5 = transmute, *mut u8>(copy ptr_2) storage_live(_6) - storage_live(_7) - _7 = copy (layout_3).align - _6 = transmute(copy _7) - storage_dead(_7) + _6 = copy (layout_3).align _0 = __rust_dealloc(move ptr_5, move _4, move _6) storage_dead(_6) storage_dead(ptr_5) @@ -2765,54 +2824,6 @@ pub fn handle_alloc_error(_1: Layout) -> ! _0 = ct_error(move _2.0) } -// Full name: alloc::alloc::exchange_malloc -#[lang_item("exchange_malloc")] -unsafe fn exchange_malloc(_1: usize, _2: usize) -> *mut u8 -{ - let _0: *mut u8; // return - let size_1: usize; // arg #1 - let align_2: usize; // arg #2 - let layout_3: Layout; // local - let _4: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local - let ptr_5: NonNull<[u8]>; // local - let _6: !; // anonymous local - let _7: (); // anonymous local - let _8: Alignment; // anonymous local - let _9: *mut [u8]; // anonymous local - let _10: bool; // anonymous local - - storage_live(layout_3) - storage_live(ptr_5) - storage_live(_6) - storage_live(_7) - storage_live(_10) - _10 = ub_checks - if move _10 { - _7 = core::alloc::layout::{Layout}::from_size_align_unchecked::precondition_check(copy size_1, copy align_2) - } else { - } - storage_live(_8) - _8 = transmute(copy align_2) - layout_3 = Layout { size: copy size_1, align: move _8 } - storage_dead(_8) - storage_live(_4) - _4 = alloc_impl_runtime(copy layout_3, const false) - match _4 { - Result::Ok => { - }, - Result::Err => { - _6 = handle_alloc_error(move layout_3) - }, - } - ptr_5 = copy (_4 as variant Result::Ok).0 - storage_live(_9) - _9 = transmute, *mut [u8]>(copy ptr_5) - _0 = cast<*mut [u8], *mut u8>(copy _9) - storage_dead(_9) - storage_dead(_4) - return -} - // Full name: alloc::boxed::Box #[lang_item("owned_box")] pub struct Box @@ -2851,27 +2862,57 @@ where { let _0: Box[@TraitClause0::parent_clause0, {built_in impl Sized for Global}, {impl Allocator for Global}]; // return let x_1: T; // arg #1 - let _2: *mut u8; // anonymous local - let _3: *const T; // anonymous local - let _4: NonNull; // anonymous local - let _5: Unique; // anonymous local - let _6: PhantomData; // anonymous local - let _7: Global; // anonymous local + let ptr_2: *mut T; // local + let size_3: usize; // local + let align_4: usize; // local + let layout_5: Layout; // local + let _6: Result, AllocError>[{built_in impl Sized for NonNull<[u8]>}, {built_in impl Sized for AllocError}]; // anonymous local + let ptr_7: NonNull<[u8]>; // local + let _8: !; // anonymous local + let _9: (); // anonymous local + let _10: Alignment; // anonymous local + let _11: *mut [u8]; // anonymous local + let _12: bool; // anonymous local - storage_live(_2) - storage_live(_3) - storage_live(_4) - storage_live(_5) - _2 = exchange_malloc(const {impl SizedTypeProperties for T}[@TraitClause0]::SIZE, const {impl SizedTypeProperties for T}[@TraitClause0]::ALIGN) - _3 = cast<*mut u8, *const T>(copy _2) - _4 = NonNull { pointer: copy _3 } + storage_live(ptr_2) + storage_live(_8) + storage_live(_9) + storage_live(_11) + storage_live(size_3) + size_3 = const {impl SizedTypeProperties for T}[@TraitClause0]::SIZE + storage_live(align_4) + align_4 = const {impl SizedTypeProperties for T}[@TraitClause0]::ALIGN + storage_live(layout_5) + storage_live(ptr_7) + storage_live(_12) + _12 = ub_checks + if move _12 { + _9 = core::alloc::layout::{Layout}::from_size_align_unchecked::precondition_check(copy size_3, copy align_4) + } else { + } + storage_live(_10) + _10 = transmute(copy align_4) + layout_5 = Layout { size: copy size_3, align: move _10 } + storage_dead(_10) storage_live(_6) - _6 = PhantomData { } - _5 = Unique { pointer: copy _4, _marker: move _6 } - storage_live(_7) - _7 = Global { } - _0 = Box { 0: move _5, 1: move _7 } - (*_3) = move x_1 + _6 = alloc_impl_runtime(copy layout_5, const false) + match _6 { + Result::Ok => { + }, + Result::Err => { + _8 = handle_alloc_error(move layout_5) + }, + } + ptr_7 = copy (_6 as variant Result::Ok).0 + _11 = transmute, *mut [u8]>(copy ptr_7) + storage_dead(_6) + storage_dead(ptr_7) + storage_dead(layout_5) + storage_dead(align_4) + storage_dead(size_3) + ptr_2 = cast<*mut [u8], *mut T>(copy _11) + (*ptr_2) = move x_1 + _0 = transmute<*mut T, Box[@TraitClause0::parent_clause0, {built_in impl Sized for Global}, {impl Allocator for Global}]>(copy ptr_2) return } diff --git a/charon/tests/ui/regressions/issue-1075-primty-def-id.out b/charon/tests/ui/regressions/issue-1075-primty-def-id.out index 5837bb78a..48237c071 100644 --- a/charon/tests/ui/regressions/issue-1075-primty-def-id.out +++ b/charon/tests/ui/regressions/issue-1075-primty-def-id.out @@ -1,11 +1,11 @@ -thread 'rustc' panicked at /nix/store/1nbfrsmfmhmhq75gkxk9nik63sq798g5-rust-default-1.95.0-nightly-2026-02-07/lib/rustlib/rustc-src/rust/compiler/rustc_hir/src/def.rs:823:45: +thread 'rustc' panicked at /nix/store/1nbfrsmfmhmhq75gkxk9nik63sq798g5-rust-default-1.95.0-nightly-2026-02-22/lib/rustlib/rustc-src/rust/compiler/rustc_hir/src/def.rs:823:45: attempted .def_id() on invalid res: PrimTy(Bool) note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: Hax panicked when translating `core::primitive`. - --> /rustc/library/core/src/lib.rs:359:1 + --> /rustc/library/core/src/lib.rs:340:1 error: Item `core::primitive` caused errors; ignoring. - --> /rustc/library/core/src/lib.rs:359:1 + --> /rustc/library/core/src/lib.rs:340:1 ERROR Charon failed to translate this code (2 errors) diff --git a/charon/tests/ui/rvalues.out b/charon/tests/ui/rvalues.out index e27cae4c7..5db5964a6 100644 --- a/charon/tests/ui/rvalues.out +++ b/charon/tests/ui/rvalues.out @@ -111,27 +111,6 @@ where [@TraitClause0]: FnOnce, = -// Full name: alloc::alloc::Global -#[lang_item("global_alloc_ty")] -pub struct Global {} - -// Full name: alloc::boxed::Box::{impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}::drop_in_place -unsafe fn {impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}::drop_in_place(_1: *mut alloc::boxed::Box[@TraitClause0, @TraitClause1]) -where - [@TraitClause0]: MetaSized, - [@TraitClause1]: Sized, -= - -// Full name: alloc::boxed::Box::{impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]} -impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1] -where - [@TraitClause0]: MetaSized, - [@TraitClause1]: Sized, -{ - fn drop_in_place = {impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}::drop_in_place[@TraitClause0, @TraitClause1] - non-dyn-compatible -} - fn UNIT_METADATA() { let _0: (); // return @@ -458,26 +437,6 @@ impl Fn<(u8,)> for closure { non-dyn-compatible } -// Full name: test_crate::boxes -fn boxes() -{ - let _0: (); // return - let _1: alloc::boxed::Box[{built_in impl MetaSized for i32}, {built_in impl Sized for Global}]; // anonymous local - let _2: alloc::boxed::Box[{built_in impl MetaSized for i32}, {built_in impl Sized for Global}]; // anonymous local - - _0 = () - storage_live(_1) - storage_live(_2) - _2 = @BoxNew[{built_in impl MetaSized for i32}, {built_in impl Sized for Global}](const 42 : i32) - _1 = move _2 - conditional_drop[{impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}[{built_in impl MetaSized for i32}, {built_in impl Sized for Global}]] _2 - storage_dead(_2) - conditional_drop[{impl Destruct for alloc::boxed::Box[@TraitClause0, @TraitClause1]}[{built_in impl MetaSized for i32}, {built_in impl Sized for Global}]] _1 - storage_dead(_1) - _0 = () - return -} - // Full name: test_crate::STEAL fn STEAL() -> [(); 1 : usize] { diff --git a/charon/tests/ui/rvalues.rs b/charon/tests/ui/rvalues.rs index d02edfae2..36d6810db 100644 --- a/charon/tests/ui/rvalues.rs +++ b/charon/tests/ui/rvalues.rs @@ -46,10 +46,6 @@ fn fn_casts() { let _ = closure as unsafe fn(u8); } -fn boxes() { - let _ = std::boxed::box_new(42); -} - // We force stealing to get the optimized_mir of the function. Optimizing the whole file would // remove most of our (indeed useless) assignments. static STEAL: [(); transmute([1, 0]) as usize] = [(); 1]; diff --git a/charon/tests/ui/simple/drop-glue-with-const-generic.out b/charon/tests/ui/simple/drop-glue-with-const-generic.out index 8f578c6d6..7575499f4 100644 --- a/charon/tests/ui/simple/drop-glue-with-const-generic.out +++ b/charon/tests/ui/simple/drop-glue-with-const-generic.out @@ -1,4 +1,4 @@ -error: internal compiler error: /rustc-dev/efc9e1b50cbf2cede7ebe25f0a1fc64fd8b3e942/compiler/rustc_middle/src/ty/sty.rs:352:13: cannot find `K/#0` in param-env: ParamEnv { +error: internal compiler error: /rustc-dev/5fb2ff8611e5a4af4dc85977cfdecfbf3ffa6ade/compiler/rustc_middle/src/ty/sty.rs:352:13: cannot find `K/#0` in param-env: ParamEnv { caller_bounds: [ Binder { value: HostEffectPredicate { trait_ref: , constness: Maybe }, bound_vars: [] }, Binder { value: TraitPredicate(, polarity:Positive), bound_vars: [] }, @@ -6,7 +6,7 @@ error: internal compiler error: /rustc-dev/efc9e1b50cbf2cede7ebe25f0a1fc64fd8b3e } -thread 'rustc' panicked at /rustc-dev/efc9e1b50cbf2cede7ebe25f0a1fc64fd8b3e942/compiler/rustc_middle/src/ty/sty.rs:352:13: +thread 'rustc' panicked at /rustc-dev/5fb2ff8611e5a4af4dc85977cfdecfbf3ffa6ade/compiler/rustc_middle/src/ty/sty.rs:352:13: Box note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: rustc panicked while retrieving drop glue. This is known to happen with `--precise-drops`; to silence this warning, pass `--opaque '{impl core::marker::Destruct for test_crate::PortableHash}'` to charon diff --git a/charon/tests/ui/simple/slice_index_range.out b/charon/tests/ui/simple/slice_index_range.out index 5d1057e6d..a7cfce61a 100644 --- a/charon/tests/ui/simple/slice_index_range.out +++ b/charon/tests/ui/simple/slice_index_range.out @@ -479,18 +479,6 @@ fn compiletime<'_0>(_1: Arguments<'_0>, _2: bool) -> ! panic(core::panicking::panic_fmt) } -// Full name: core::num::{usize}::MAX -pub fn MAX() -> usize -{ - let _0: usize; // return - - _0 = ~(const 0 : usize) - return -} - -// Full name: core::num::{usize}::MAX -pub const MAX: usize = MAX() - // Full name: core::ops::range::RangeInclusive #[lang_item("RangeInclusive")] pub struct RangeInclusive @@ -1198,9 +1186,9 @@ where let slice_2: &'9 mut [T]; // arg #2 let _3: bool; // anonymous local let self_4: usize; // local - let exclusive_end_5: usize; // local - let _6: bool; // anonymous local - let _7: usize; // anonymous local + let _5: usize; // anonymous local + let exclusive_end_6: usize; // local + let _7: bool; // anonymous local let _8: &'12 mut [T]; // anonymous local let _9: *mut [T]; // anonymous local let ptr_10: *mut [T]; // local @@ -1214,13 +1202,15 @@ where let _18: Option<&'16 mut [T]>[{built_in impl Sized for &'18 mut [T]}]; // anonymous local storage_live(self_4) - storage_live(exclusive_end_5) + storage_live(_5) + storage_live(exclusive_end_6) storage_live(new_len_12) storage_live(self_15) storage_live(self_16) storage_live(_3) self_4 = copy (self_1).end - _3 = copy self_4 == copy MAX + _5 = copy slice_2.metadata + _3 = copy self_4 >= copy _5 if move _3 { storage_live(_17) _17 = Option::None { } @@ -1228,28 +1218,25 @@ where } else { self_15 = move (self_1).start self_16 = move (self_1).exhausted - exclusive_end_5 = copy self_4 wrap.+ const 1 : usize + exclusive_end_6 = copy self_4 wrap.+ const 1 : usize if copy self_16 { - self_15 = copy exclusive_end_5 + self_15 = copy exclusive_end_6 } else { } storage_live(_8) storage_live(_11) - _11 = copy exclusive_end_5 < copy self_15 + _11 = copy exclusive_end_6 < copy self_15 if move _11 { storage_dead(_11) storage_live(_18) _18 = Option::None { } _0 = move _18 } else { - new_len_12 = copy exclusive_end_5 ub.- copy self_15 + new_len_12 = copy exclusive_end_6 ub.- copy self_15 storage_dead(_11) - storage_live(_6) storage_live(_7) - _7 = copy slice_2.metadata - _6 = copy exclusive_end_5 <= move _7 - if move _6 { - storage_dead(_7) + _7 = copy exclusive_end_6 <= copy _5 + if move _7 { storage_live(_9) storage_live(ptr_10) ptr_10 = &raw mut (*slice_2) with_metadata(copy slice_2.metadata) @@ -1265,13 +1252,12 @@ where _0 = Option::Some { 0: copy _8 } storage_dead(_9) } else { - storage_dead(_7) storage_live(_18) _18 = Option::None { } _0 = move _18 } } - storage_dead(_6) + storage_dead(_7) storage_dead(_8) } storage_dead(_3) @@ -1288,9 +1274,9 @@ where let slice_2: &'9 [T]; // arg #2 let _3: bool; // anonymous local let self_4: usize; // local - let exclusive_end_5: usize; // local - let _6: bool; // anonymous local - let _7: usize; // anonymous local + let _5: usize; // anonymous local + let exclusive_end_6: usize; // local + let _7: bool; // anonymous local let _8: &'12 [T]; // anonymous local let _9: *const [T]; // anonymous local let _10: *const [T]; // anonymous local @@ -1304,13 +1290,15 @@ where let _18: Option<&'16 [T]>[{built_in impl Sized for &'18 [T]}]; // anonymous local storage_live(self_4) - storage_live(exclusive_end_5) + storage_live(_5) + storage_live(exclusive_end_6) storage_live(new_len_12) storage_live(self_15) storage_live(self_16) storage_live(_3) self_4 = copy (self_1).end - _3 = copy self_4 == copy MAX + _5 = copy slice_2.metadata + _3 = copy self_4 >= copy _5 if move _3 { storage_live(_17) _17 = Option::None { } @@ -1318,28 +1306,25 @@ where } else { self_15 = move (self_1).start self_16 = move (self_1).exhausted - exclusive_end_5 = copy self_4 wrap.+ const 1 : usize + exclusive_end_6 = copy self_4 wrap.+ const 1 : usize if copy self_16 { - self_15 = copy exclusive_end_5 + self_15 = copy exclusive_end_6 } else { } storage_live(_8) storage_live(_11) - _11 = copy exclusive_end_5 < copy self_15 + _11 = copy exclusive_end_6 < copy self_15 if move _11 { storage_dead(_11) storage_live(_18) _18 = Option::None { } _0 = move _18 } else { - new_len_12 = copy exclusive_end_5 ub.- copy self_15 + new_len_12 = copy exclusive_end_6 ub.- copy self_15 storage_dead(_11) - storage_live(_6) storage_live(_7) - _7 = copy slice_2.metadata - _6 = copy exclusive_end_5 <= move _7 - if move _6 { - storage_dead(_7) + _7 = copy exclusive_end_6 <= copy _5 + if move _7 { storage_live(_9) storage_live(_10) _10 = &raw const (*slice_2) with_metadata(copy slice_2.metadata) @@ -1355,13 +1340,12 @@ where _0 = Option::Some { 0: copy _8 } storage_dead(_9) } else { - storage_dead(_7) storage_live(_18) _18 = Option::None { } _0 = move _18 } } - storage_dead(_6) + storage_dead(_7) storage_dead(_8) } storage_dead(_3) diff --git a/charon/tests/ui/simple/vec-push.out b/charon/tests/ui/simple/vec-push.out index 575947c05..287f4d07e 100644 --- a/charon/tests/ui/simple/vec-push.out +++ b/charon/tests/ui/simple/vec-push.out @@ -256,7 +256,7 @@ where storage_dead(self_9) storage_live(src_10) src_10 = move value_2 - (*end_8) = copy src_10 + (*end_8) = move src_10 storage_dead(src_10) ((*self_1)).len = copy len_3 wrap.+ const 1 : usize _0 = &mut (*end_8) diff --git a/charon/tests/ui/vec-reconstruct-move-values.out b/charon/tests/ui/vec-reconstruct-move-values.out new file mode 100644 index 000000000..3a2494c5c --- /dev/null +++ b/charon/tests/ui/vec-reconstruct-move-values.out @@ -0,0 +1,145 @@ +# Final LLBC before serialization: + +// Full name: core::marker::MetaSized +#[lang_item("meta_sized")] +pub trait MetaSized + +// Full name: core::marker::Sized +#[lang_item("sized")] +pub trait Sized +{ + parent_clause0 : [@TraitClause0]: MetaSized + non-dyn-compatible +} + +// Full name: core::marker::Destruct +#[lang_item("destruct")] +pub trait Destruct +{ + fn drop_in_place = core::marker::Destruct::drop_in_place + non-dyn-compatible +} + +unsafe fn core::marker::Destruct::drop_in_place(_1: *mut Self) += + +// Full name: core::mem::maybe_uninit::MaybeUninit +#[lang_item("maybe_uninit")] +pub opaque type MaybeUninit +where + [@TraitClause0]: Sized, + +// Full name: alloc::alloc::Global +#[lang_item("global_alloc_ty")] +pub struct Global {} + +// Full name: alloc::boxed::{alloc::boxed::Box[@TraitClause0::parent_clause0, {built_in impl Sized for Global}]}::new_uninit +pub fn new_uninit() -> alloc::boxed::Box[@TraitClause0]>[{built_in impl MetaSized for MaybeUninit[@TraitClause0]}, {built_in impl Sized for Global}] +where + [@TraitClause0]: Sized, += + +// Full name: alloc::vec::Vec +#[lang_item("Vec")] +pub opaque type Vec +where + [@TraitClause0]: Sized, + [@TraitClause1]: Sized, + +// Full name: alloc::vec::Vec::{impl Destruct for Vec[@TraitClause0, @TraitClause1]}::drop_in_place +unsafe fn {impl Destruct for Vec[@TraitClause0, @TraitClause1]}::drop_in_place(_1: *mut Vec[@TraitClause0, @TraitClause1]) +where + [@TraitClause0]: Sized, + [@TraitClause1]: Sized, += + +// Full name: alloc::vec::Vec::{impl Destruct for Vec[@TraitClause0, @TraitClause1]} +impl Destruct for Vec[@TraitClause0, @TraitClause1] +where + [@TraitClause0]: Sized, + [@TraitClause1]: Sized, +{ + fn drop_in_place = {impl Destruct for Vec[@TraitClause0, @TraitClause1]}::drop_in_place[@TraitClause0, @TraitClause1] + non-dyn-compatible +} + +// Full name: test_crate::NoCopy +struct NoCopy { + u8, +} + +// Full name: test_crate::move_values +fn move_values(_1: bool) +{ + let _0: (); // return + let flag_1: bool; // arg #1 + let x_2: NoCopy; // local + let _v_3: Vec[{built_in impl Sized for NoCopy}, {built_in impl Sized for Global}]; // local + let _4: alloc::boxed::Box[{built_in impl Sized for [NoCopy; 1 : usize]}]>[{built_in impl MetaSized for MaybeUninit<[NoCopy; 1 : usize]>[{built_in impl Sized for [NoCopy; 1 : usize]}]}, {built_in impl Sized for Global}]; // anonymous local + let _5: NoCopy; // anonymous local + let _6: bool; // anonymous local + let y_7: NoCopy; // local + let _w_8: Vec[{built_in impl Sized for NoCopy}, {built_in impl Sized for Global}]; // local + let _9: alloc::boxed::Box[{built_in impl Sized for [NoCopy; 1 : usize]}]>[{built_in impl MetaSized for MaybeUninit<[NoCopy; 1 : usize]>[{built_in impl Sized for [NoCopy; 1 : usize]}]}, {built_in impl Sized for Global}]; // anonymous local + let _10: NoCopy; // anonymous local + let _11: [NoCopy; 1 : usize]; // anonymous local + let _12: alloc::boxed::Box<[NoCopy; 1 : usize]>; // anonymous local + let _13: alloc::boxed::Box<[NoCopy]>; // anonymous local + let _14: [NoCopy; 1 : usize]; // anonymous local + let _15: alloc::boxed::Box<[NoCopy; 1 : usize]>; // anonymous local + let _16: alloc::boxed::Box<[NoCopy]>; // anonymous local + + _0 = () + storage_live(x_2) + x_2 = NoCopy { 0: const 4 : u8 } + storage_live(_v_3) + storage_live(_4) + _4 = new_uninit<[NoCopy; 1 : usize]>[{built_in impl Sized for [NoCopy; 1 : usize]}]() + storage_live(_5) + _5 = move x_2 + storage_live(_11) + _11 = [move _5] + storage_dead(_5) + storage_live(_12) + _12 = @BoxWrite<[NoCopy; 1 : usize]>(move _4, move _11) + storage_dead(_11) + storage_live(_13) + _13 = unsize_cast, alloc::boxed::Box<[NoCopy]>, 1 : usize>(move _12) + storage_dead(_4) + _v_3 = @SliceIntoVec(move _13) + storage_live(_6) + _6 = copy flag_1 + if move _6 { + storage_live(y_7) + y_7 = NoCopy { 0: const 5 : u8 } + storage_live(_w_8) + storage_live(_9) + _9 = new_uninit<[NoCopy; 1 : usize]>[{built_in impl Sized for [NoCopy; 1 : usize]}]() + storage_live(_10) + _10 = move y_7 + storage_live(_14) + _14 = [move _10] + storage_dead(_10) + storage_live(_15) + _15 = @BoxWrite<[NoCopy; 1 : usize]>(move _9, move _14) + storage_dead(_14) + storage_live(_16) + _16 = unsize_cast, alloc::boxed::Box<[NoCopy]>, 1 : usize>(move _15) + storage_dead(_9) + _w_8 = @SliceIntoVec(move _16) + _0 = () + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for NoCopy}, {built_in impl Sized for Global}]] _w_8 + storage_dead(_w_8) + storage_dead(y_7) + } else { + _0 = () + } + storage_dead(_6) + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for NoCopy}, {built_in impl Sized for Global}]] _v_3 + storage_dead(_v_3) + storage_dead(x_2) + return +} + + + diff --git a/charon/tests/ui/vec-reconstruct-move-values.rs b/charon/tests/ui/vec-reconstruct-move-values.rs new file mode 100644 index 000000000..3ccccadc2 --- /dev/null +++ b/charon/tests/ui/vec-reconstruct-move-values.rs @@ -0,0 +1,10 @@ +struct NoCopy(u8); + +fn move_values(flag: bool) { + let x = NoCopy(4); + let _v = vec![x]; + if flag { + let y = NoCopy(5); + let _w = vec![y]; + } +} diff --git a/charon/tests/ui/vec-reconstruct-multiple-adjacent.out b/charon/tests/ui/vec-reconstruct-multiple-adjacent.out new file mode 100644 index 000000000..b9bd1d1ce --- /dev/null +++ b/charon/tests/ui/vec-reconstruct-multiple-adjacent.out @@ -0,0 +1,258 @@ +# Final LLBC before serialization: + +// Full name: core::marker::MetaSized +#[lang_item("meta_sized")] +pub trait MetaSized + +// Full name: core::marker::Sized +#[lang_item("sized")] +pub trait Sized +{ + parent_clause0 : [@TraitClause0]: MetaSized + non-dyn-compatible +} + +// Full name: core::clone::Clone +#[lang_item("clone")] +pub trait Clone +{ + parent_clause0 : [@TraitClause0]: Sized + fn clone<'_0_1> = core::clone::Clone::clone<'_0_1, Self>[Self] + non-dyn-compatible +} + +#[lang_item("clone_fn")] +pub fn core::clone::Clone::clone<'_0, Self>(_1: &'_0 Self) -> Self +where + [@TraitClause0]: Clone, += + +// Full name: core::clone::impls::{impl Clone for u8}::clone +pub fn {impl Clone for u8}::clone<'_0>(_1: &'_0 u8) -> u8 += + +// Full name: core::clone::impls::{impl Clone for u8} +impl Clone for u8 { + parent_clause0 = {built_in impl Sized for u8} + fn clone<'_0_1> = {impl Clone for u8}::clone<'_0_1> + non-dyn-compatible +} + +// Full name: core::marker::Destruct +#[lang_item("destruct")] +pub trait Destruct +{ + fn drop_in_place = core::marker::Destruct::drop_in_place + non-dyn-compatible +} + +unsafe fn core::marker::Destruct::drop_in_place(_1: *mut Self) += + +// Full name: core::mem::maybe_uninit::MaybeUninit +#[lang_item("maybe_uninit")] +pub opaque type MaybeUninit +where + [@TraitClause0]: Sized, + +// Full name: alloc::alloc::Global +#[lang_item("global_alloc_ty")] +pub struct Global {} + +// Full name: alloc::boxed::{alloc::boxed::Box[@TraitClause0::parent_clause0, {built_in impl Sized for Global}]}::new_uninit +pub fn new_uninit() -> alloc::boxed::Box[@TraitClause0]>[{built_in impl MetaSized for MaybeUninit[@TraitClause0]}, {built_in impl Sized for Global}] +where + [@TraitClause0]: Sized, += + +// Full name: alloc::vec::Vec +#[lang_item("Vec")] +pub opaque type Vec +where + [@TraitClause0]: Sized, + [@TraitClause1]: Sized, + +// Full name: alloc::vec::Vec::{impl Destruct for Vec[@TraitClause0, @TraitClause1]}::drop_in_place +unsafe fn {impl Destruct for Vec[@TraitClause0, @TraitClause1]}::drop_in_place(_1: *mut Vec[@TraitClause0, @TraitClause1]) +where + [@TraitClause0]: Sized, + [@TraitClause1]: Sized, += + +// Full name: alloc::vec::Vec::{impl Destruct for Vec[@TraitClause0, @TraitClause1]} +impl Destruct for Vec[@TraitClause0, @TraitClause1] +where + [@TraitClause0]: Sized, + [@TraitClause1]: Sized, +{ + fn drop_in_place = {impl Destruct for Vec[@TraitClause0, @TraitClause1]}::drop_in_place[@TraitClause0, @TraitClause1] + non-dyn-compatible +} + +// Full name: alloc::vec::from_elem +#[lang_item("vec_from_elem")] +pub fn from_elem(_1: T, _2: usize) -> Vec[@TraitClause0, {built_in impl Sized for Global}] +where + [@TraitClause0]: Sized, + [@TraitClause1]: Clone, += + +// Full name: test_crate::multiple_adjacent +fn multiple_adjacent() +{ + let _0: (); // return + let _a_1: Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; // local + let _2: alloc::boxed::Box[{built_in impl Sized for [u8; 1 : usize]}]>[{built_in impl MetaSized for MaybeUninit<[u8; 1 : usize]>[{built_in impl Sized for [u8; 1 : usize]}]}, {built_in impl Sized for Global}]; // anonymous local + let _b_3: Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; // local + let _4: alloc::boxed::Box[{built_in impl Sized for [u8; 1 : usize]}]>[{built_in impl MetaSized for MaybeUninit<[u8; 1 : usize]>[{built_in impl Sized for [u8; 1 : usize]}]}, {built_in impl Sized for Global}]; // anonymous local + let _c_5: Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; // local + let _6: alloc::boxed::Box[{built_in impl Sized for [u8; 1 : usize]}]>[{built_in impl MetaSized for MaybeUninit<[u8; 1 : usize]>[{built_in impl Sized for [u8; 1 : usize]}]}, {built_in impl Sized for Global}]; // anonymous local + let _7: [u8; 1 : usize]; // anonymous local + let _8: alloc::boxed::Box<[u8; 1 : usize]>; // anonymous local + let _9: alloc::boxed::Box<[u8]>; // anonymous local + let _10: [u8; 1 : usize]; // anonymous local + let _11: alloc::boxed::Box<[u8; 1 : usize]>; // anonymous local + let _12: alloc::boxed::Box<[u8]>; // anonymous local + let _13: [u8; 1 : usize]; // anonymous local + let _14: alloc::boxed::Box<[u8; 1 : usize]>; // anonymous local + let _15: alloc::boxed::Box<[u8]>; // anonymous local + + _0 = () + storage_live(_a_1) + storage_live(_2) + _2 = new_uninit<[u8; 1 : usize]>[{built_in impl Sized for [u8; 1 : usize]}]() + storage_live(_7) + _7 = [const 1 : u8] + storage_live(_8) + _8 = @BoxWrite<[u8; 1 : usize]>(move _2, move _7) + storage_dead(_7) + storage_live(_9) + _9 = unsize_cast, alloc::boxed::Box<[u8]>, 1 : usize>(move _8) + storage_dead(_2) + _a_1 = @SliceIntoVec(move _9) + storage_live(_b_3) + storage_live(_4) + _4 = new_uninit<[u8; 1 : usize]>[{built_in impl Sized for [u8; 1 : usize]}]() + storage_live(_10) + _10 = [const 2 : u8] + storage_live(_11) + _11 = @BoxWrite<[u8; 1 : usize]>(move _4, move _10) + storage_dead(_10) + storage_live(_12) + _12 = unsize_cast, alloc::boxed::Box<[u8]>, 1 : usize>(move _11) + storage_dead(_4) + _b_3 = @SliceIntoVec(move _12) + storage_live(_c_5) + storage_live(_6) + _6 = new_uninit<[u8; 1 : usize]>[{built_in impl Sized for [u8; 1 : usize]}]() + storage_live(_13) + _13 = [const 3 : u8] + storage_live(_14) + _14 = @BoxWrite<[u8; 1 : usize]>(move _6, move _13) + storage_dead(_13) + storage_live(_15) + _15 = unsize_cast, alloc::boxed::Box<[u8]>, 1 : usize>(move _14) + storage_dead(_6) + _c_5 = @SliceIntoVec(move _15) + _0 = () + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for u8}, {built_in impl Sized for Global}]] _c_5 + storage_dead(_c_5) + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for u8}, {built_in impl Sized for Global}]] _b_3 + storage_dead(_b_3) + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for u8}, {built_in impl Sized for Global}]] _a_1 + storage_dead(_a_1) + return +} + +// Full name: test_crate::multiple_values +fn multiple_values() +{ + let _0: (); // return + let _a_1: Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; // local + let _2: alloc::boxed::Box[{built_in impl Sized for [u8; 3 : usize]}]>[{built_in impl MetaSized for MaybeUninit<[u8; 3 : usize]>[{built_in impl Sized for [u8; 3 : usize]}]}, {built_in impl Sized for Global}]; // anonymous local + let _3: [u8; 3 : usize]; // anonymous local + let _4: alloc::boxed::Box<[u8; 3 : usize]>; // anonymous local + let _5: alloc::boxed::Box<[u8]>; // anonymous local + + _0 = () + storage_live(_a_1) + storage_live(_2) + _2 = new_uninit<[u8; 3 : usize]>[{built_in impl Sized for [u8; 3 : usize]}]() + storage_live(_3) + _3 = [const 1 : u8, const 2 : u8, const 3 : u8] + storage_live(_4) + _4 = @BoxWrite<[u8; 3 : usize]>(move _2, move _3) + storage_dead(_3) + storage_live(_5) + _5 = unsize_cast, alloc::boxed::Box<[u8]>, 3 : usize>(move _4) + storage_dead(_2) + _a_1 = @SliceIntoVec(move _5) + _0 = () + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for u8}, {built_in impl Sized for Global}]] _a_1 + storage_dead(_a_1) + return +} + +// Full name: test_crate::with_fn_calls::foo +fn foo() -> u8 +{ + let _0: u8; // return + + _0 = const 42 : u8 + return +} + +// Full name: test_crate::with_fn_calls +fn with_fn_calls() +{ + let _0: (); // return + let _a_1: Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; // local + let _2: alloc::boxed::Box[{built_in impl Sized for [u8; 2 : usize]}]>[{built_in impl MetaSized for MaybeUninit<[u8; 2 : usize]>[{built_in impl Sized for [u8; 2 : usize]}]}, {built_in impl Sized for Global}]; // anonymous local + let _3: u8; // anonymous local + let _4: u8; // anonymous local + let _5: [u8; 2 : usize]; // anonymous local + let _6: alloc::boxed::Box<[u8; 2 : usize]>; // anonymous local + let _7: alloc::boxed::Box<[u8]>; // anonymous local + + _0 = () + storage_live(_a_1) + storage_live(_2) + _2 = new_uninit<[u8; 2 : usize]>[{built_in impl Sized for [u8; 2 : usize]}]() + storage_live(_3) + _3 = foo() + storage_live(_4) + _4 = foo() + storage_live(_5) + _5 = [move _3, move _4] + storage_dead(_4) + storage_dead(_3) + storage_live(_6) + _6 = @BoxWrite<[u8; 2 : usize]>(move _2, move _5) + storage_dead(_5) + storage_live(_7) + _7 = unsize_cast, alloc::boxed::Box<[u8]>, 2 : usize>(move _6) + storage_dead(_2) + _a_1 = @SliceIntoVec(move _7) + _0 = () + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for u8}, {built_in impl Sized for Global}]] _a_1 + storage_dead(_a_1) + return +} + +// Full name: test_crate::repeated +fn repeated() +{ + let _0: (); // return + let _a_1: Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; // local + + _0 = () + storage_live(_a_1) + _a_1 = from_elem[{built_in impl Sized for u8}, {impl Clone for u8}](const 1 : u8, const 3 : usize) + _0 = () + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for u8}, {built_in impl Sized for Global}]] _a_1 + storage_dead(_a_1) + return +} + + + diff --git a/charon/tests/ui/vec-reconstruct-multiple-adjacent.rs b/charon/tests/ui/vec-reconstruct-multiple-adjacent.rs new file mode 100644 index 000000000..79475f660 --- /dev/null +++ b/charon/tests/ui/vec-reconstruct-multiple-adjacent.rs @@ -0,0 +1,20 @@ +fn multiple_adjacent() { + let _a = vec![1u8]; + let _b = vec![2u8]; + let _c = vec![3u8]; +} + +fn multiple_values() { + let _a = vec![1u8, 2u8, 3u8]; +} + +fn with_fn_calls() { + fn foo() -> u8 { + 42 + } + let _a = vec![foo(), foo()]; +} + +fn repeated() { + let _a = vec![1u8; 3]; +} diff --git a/charon/tests/ui/vec-reconstruct-nested.out b/charon/tests/ui/vec-reconstruct-nested.out new file mode 100644 index 000000000..3fe1ab14e --- /dev/null +++ b/charon/tests/ui/vec-reconstruct-nested.out @@ -0,0 +1,182 @@ +# Final LLBC before serialization: + +// Full name: core::marker::MetaSized +#[lang_item("meta_sized")] +pub trait MetaSized + +// Full name: core::marker::Sized +#[lang_item("sized")] +pub trait Sized +{ + parent_clause0 : [@TraitClause0]: MetaSized + non-dyn-compatible +} + +// Full name: core::marker::Destruct +#[lang_item("destruct")] +pub trait Destruct +{ + fn drop_in_place = core::marker::Destruct::drop_in_place + non-dyn-compatible +} + +unsafe fn core::marker::Destruct::drop_in_place(_1: *mut Self) += + +// Full name: core::mem::maybe_uninit::MaybeUninit +#[lang_item("maybe_uninit")] +pub opaque type MaybeUninit +where + [@TraitClause0]: Sized, + +// Full name: alloc::alloc::Global +#[lang_item("global_alloc_ty")] +pub struct Global {} + +// Full name: alloc::boxed::{alloc::boxed::Box[@TraitClause0::parent_clause0, {built_in impl Sized for Global}]}::new_uninit +pub fn new_uninit() -> alloc::boxed::Box[@TraitClause0]>[{built_in impl MetaSized for MaybeUninit[@TraitClause0]}, {built_in impl Sized for Global}] +where + [@TraitClause0]: Sized, += + +// Full name: alloc::vec::Vec +#[lang_item("Vec")] +pub opaque type Vec +where + [@TraitClause0]: Sized, + [@TraitClause1]: Sized, + +// Full name: alloc::vec::Vec::{impl Destruct for Vec[@TraitClause0, @TraitClause1]}::drop_in_place +unsafe fn {impl Destruct for Vec[@TraitClause0, @TraitClause1]}::drop_in_place(_1: *mut Vec[@TraitClause0, @TraitClause1]) +where + [@TraitClause0]: Sized, + [@TraitClause1]: Sized, += + +// Full name: alloc::vec::Vec::{impl Destruct for Vec[@TraitClause0, @TraitClause1]} +impl Destruct for Vec[@TraitClause0, @TraitClause1] +where + [@TraitClause0]: Sized, + [@TraitClause1]: Sized, +{ + fn drop_in_place = {impl Destruct for Vec[@TraitClause0, @TraitClause1]}::drop_in_place[@TraitClause0, @TraitClause1] + non-dyn-compatible +} + +// Full name: test_crate::nested_vecs +fn nested_vecs() +{ + let _0: (); // return + let _nested_1: Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]>[{built_in impl Sized for Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]}, {built_in impl Sized for Global}]; // local + let _2: alloc::boxed::Box[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 2 : usize]>[{built_in impl Sized for [Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 2 : usize]}]>[{built_in impl MetaSized for MaybeUninit<[Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 2 : usize]>[{built_in impl Sized for [Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 2 : usize]}]}, {built_in impl Sized for Global}]; // anonymous local + let _3: Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; // anonymous local + let _4: alloc::boxed::Box[{built_in impl Sized for [u8; 1 : usize]}]>[{built_in impl MetaSized for MaybeUninit<[u8; 1 : usize]>[{built_in impl Sized for [u8; 1 : usize]}]}, {built_in impl Sized for Global}]; // anonymous local + let _5: Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; // anonymous local + let _6: alloc::boxed::Box[{built_in impl Sized for [u8; 1 : usize]}]>[{built_in impl MetaSized for MaybeUninit<[u8; 1 : usize]>[{built_in impl Sized for [u8; 1 : usize]}]}, {built_in impl Sized for Global}]; // anonymous local + let _7: [u8; 1 : usize]; // anonymous local + let _8: alloc::boxed::Box<[u8; 1 : usize]>; // anonymous local + let _9: alloc::boxed::Box<[u8]>; // anonymous local + let _10: [u8; 1 : usize]; // anonymous local + let _11: alloc::boxed::Box<[u8; 1 : usize]>; // anonymous local + let _12: alloc::boxed::Box<[u8]>; // anonymous local + let _13: [Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 2 : usize]; // anonymous local + let _14: alloc::boxed::Box<[Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 2 : usize]>; // anonymous local + let _15: alloc::boxed::Box<[Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]]>; // anonymous local + + _0 = () + storage_live(_nested_1) + storage_live(_2) + _2 = new_uninit<[Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 2 : usize]>[{built_in impl Sized for [Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 2 : usize]}]() + storage_live(_3) + storage_live(_4) + _4 = new_uninit<[u8; 1 : usize]>[{built_in impl Sized for [u8; 1 : usize]}]() + storage_live(_7) + _7 = [const 1 : u8] + storage_live(_8) + _8 = @BoxWrite<[u8; 1 : usize]>(move _4, move _7) + storage_dead(_7) + storage_live(_9) + _9 = unsize_cast, alloc::boxed::Box<[u8]>, 1 : usize>(move _8) + storage_dead(_4) + _3 = @SliceIntoVec(move _9) + storage_live(_5) + storage_live(_6) + _6 = new_uninit<[u8; 1 : usize]>[{built_in impl Sized for [u8; 1 : usize]}]() + storage_live(_10) + _10 = [const 2 : u8] + storage_live(_11) + _11 = @BoxWrite<[u8; 1 : usize]>(move _6, move _10) + storage_dead(_10) + storage_live(_12) + _12 = unsize_cast, alloc::boxed::Box<[u8]>, 1 : usize>(move _11) + storage_dead(_6) + _5 = @SliceIntoVec(move _12) + storage_live(_13) + _13 = [move _3, move _5] + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for u8}, {built_in impl Sized for Global}]] _5 + storage_dead(_5) + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for u8}, {built_in impl Sized for Global}]] _3 + storage_dead(_3) + storage_live(_14) + _14 = @BoxWrite<[Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 2 : usize]>(move _2, move _13) + storage_dead(_13) + storage_live(_15) + _15 = unsize_cast[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 2 : usize]>, alloc::boxed::Box<[Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]]>, 2 : usize>(move _14) + storage_dead(_2) + _nested_1 = @SliceIntoVec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]>(move _15) + _0 = () + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for u8}, {built_in impl Sized for Global}], Global>[{built_in impl Sized for Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]}, {built_in impl Sized for Global}]] _nested_1 + storage_dead(_nested_1) + return +} + +// Full name: test_crate::nested_single +fn nested_single() +{ + let _0: (); // return + let _nested_1: Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]>[{built_in impl Sized for Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]}, {built_in impl Sized for Global}]; // local + let _2: alloc::boxed::Box[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 1 : usize]>[{built_in impl Sized for [Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 1 : usize]}]>[{built_in impl MetaSized for MaybeUninit<[Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 1 : usize]>[{built_in impl Sized for [Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 1 : usize]}]}, {built_in impl Sized for Global}]; // anonymous local + let _3: Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; // anonymous local + let _4: alloc::boxed::Box[{built_in impl Sized for [u8; 1 : usize]}]>[{built_in impl MetaSized for MaybeUninit<[u8; 1 : usize]>[{built_in impl Sized for [u8; 1 : usize]}]}, {built_in impl Sized for Global}]; // anonymous local + let _5: [u8; 1 : usize]; // anonymous local + let _6: alloc::boxed::Box<[u8; 1 : usize]>; // anonymous local + let _7: alloc::boxed::Box<[u8]>; // anonymous local + let _8: [Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 1 : usize]; // anonymous local + let _9: alloc::boxed::Box<[Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 1 : usize]>; // anonymous local + let _10: alloc::boxed::Box<[Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]]>; // anonymous local + + _0 = () + storage_live(_nested_1) + storage_live(_2) + _2 = new_uninit<[Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 1 : usize]>[{built_in impl Sized for [Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 1 : usize]}]() + storage_live(_3) + storage_live(_4) + _4 = new_uninit<[u8; 1 : usize]>[{built_in impl Sized for [u8; 1 : usize]}]() + storage_live(_5) + _5 = [const 1 : u8] + storage_live(_6) + _6 = @BoxWrite<[u8; 1 : usize]>(move _4, move _5) + storage_dead(_5) + storage_live(_7) + _7 = unsize_cast, alloc::boxed::Box<[u8]>, 1 : usize>(move _6) + storage_dead(_4) + _3 = @SliceIntoVec(move _7) + storage_live(_8) + _8 = [move _3] + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for u8}, {built_in impl Sized for Global}]] _3 + storage_dead(_3) + storage_live(_9) + _9 = @BoxWrite<[Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 1 : usize]>(move _2, move _8) + storage_dead(_8) + storage_live(_10) + _10 = unsize_cast[{built_in impl Sized for u8}, {built_in impl Sized for Global}]; 1 : usize]>, alloc::boxed::Box<[Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]]>, 1 : usize>(move _9) + storage_dead(_2) + _nested_1 = @SliceIntoVec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]>(move _10) + _0 = () + conditional_drop[{impl Destruct for Vec[@TraitClause0, @TraitClause1]}[{built_in impl Sized for u8}, {built_in impl Sized for Global}], Global>[{built_in impl Sized for Vec[{built_in impl Sized for u8}, {built_in impl Sized for Global}]}, {built_in impl Sized for Global}]] _nested_1 + storage_dead(_nested_1) + return +} + + + diff --git a/charon/tests/ui/vec-reconstruct-nested.rs b/charon/tests/ui/vec-reconstruct-nested.rs new file mode 100644 index 000000000..c258fe9b2 --- /dev/null +++ b/charon/tests/ui/vec-reconstruct-nested.rs @@ -0,0 +1,7 @@ +fn nested_vecs() { + let _nested = vec![vec![1u8], vec![2u8]]; +} + +fn nested_single() { + let _nested = vec![vec![1u8]]; +}