jiebi/CodeConvo huggingface dataset:
LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &'a isize { |                                                  ++ <del> error: aborting due to 6 previous errors </del> <ins> error[E0106]: missing lifetime specifier --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:45:37 | LL | fn l<'a>(_: &'a str, _: &'a str) -> &str { "" } |             -------     -------     ^ expected named lifetime parameter | = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments help: consider using the `'a` lifetime | LL | fn l<'a>(_: &'a str, _: &'a str) -> &'a str { "" } |                                      ++ error: aborting due to 7 previous errors </ins> For more information about this error, try `rustc --explain E0106`.
// FIXME(#75598): Direct use of these intrinsics improves codegen significantly at opt-level <= // 1, where the method versions of these operations are not inlined. use intrinsics::{ <del> cttz_nonzero, exact_div, unchecked_rem, unchecked_shl, unchecked_shr, unchecked_sub, wrapping_add, wrapping_mul, wrapping_sub, </del> <ins> cttz_nonzero, exact_div, mul_with_overflow, unchecked_rem, unchecked_shl, unchecked_shr, unchecked_sub, wrapping_add, wrapping_mul, wrapping_sub, </ins> }; /// Calculate multiplicative modular inverse of `x` modulo `m`.
const INV_TABLE_MOD_16: [u8; 8] = [1, 11, 13, 7, 9, 3, 5, 15]; /// Modulo for which the `INV_TABLE_MOD_16` is intended. const INV_TABLE_MOD: usize = 16; <del> /// INV_TABLE_MOD² const INV_TABLE_MOD_SQUARED: usize = INV_TABLE_MOD * INV_TABLE_MOD; let table_inverse = INV_TABLE_MOD_16[(x & (INV_TABLE_MOD - 1)) >> 1] as usize; </del> // SAFETY: `m` is required to be a power-of-two, hence non-zero. let m_minus_one = unsafe { unchecked_sub(m, 1) }; <del> if m <= INV_TABLE_MOD { table_inverse & m_minus_one } else { // We iterate "up" using the following formula: // // $$ xy ≡ 1 (mod 2ⁿ) → xy (2 - xy) ≡ 1 (mod 2²ⁿ) $$ </del> <ins> let mut inverse = INV_TABLE_MOD_16[(x & (INV_TABLE_MOD - 1)) >> 1] as usize; let mut mod_gate = INV_TABLE_MOD; // We iterate "up" using the following formula: // // $$ xy ≡ 1 (mod 2ⁿ) → xy (2 - xy) ≡ 1 (mod 2²ⁿ) $$ // // This application needs to be applied at least until `2²ⁿ ≥ m`, at which point we can // finally reduce the computation to our desired `m` by taking `inverse mod m`. // // This computation is `O(log log m)`, which is to say, that on 64-bit machines this loop // will always finish in at most 4 iterations. loop { // y = y * (2 - xy) mod n </ins> // <del> // until 2²ⁿ ≥ m. Then we can reduce to our desired `m` by taking the result `mod m`. let mut inverse = table_inverse; let mut going_mod = INV_TABLE_MOD_SQUARED; loop { // y = y * (2 - xy) mod n // // Note, that we use wrapping operations here intentionally – the original formula // uses e.g., subtraction `mod n`. It is entirely fine to do them `mod // usize::MAX` instead, because we take the result `mod n` at the end // anyway. inverse = wrapping_mul(inverse, wrapping_sub(2usize, wrapping_mul(x, inverse))); if going_mod >= m { return inverse & m_minus_one; } going_mod = wrapping_mul(going_mod, going_mod); </del> <ins> // Note, that we use wrapping operations here intentionally – the original formula // uses e.g., subtraction `mod n`. It is entirely fine to do them `mod // usize::MAX` instead, because we take the result `mod n` at the end // anyway. if mod_gate >= m { break; } inverse = wrapping_mul(inverse, wrapping_sub(2usize, wrapping_mul(x, inverse))); let (new_gate, overflow) = mul_with_overflow(mod_gate, mod_gate); if overflow { break; </ins> } <ins> mod_gate = new_gate; </ins> } <ins> inverse & m_minus_one </ins> } let addr = p.addr();
} #[test] <ins> fn align_offset_issue_103361() { #[cfg(target_pointer_width = "64")] const SIZE: usize = 1 << 47; #[cfg(target_pointer_width = "32")] const SIZE: usize = 1 << 30; #[cfg(target_pointer_width = "16")] const SIZE: usize = 1 << 13; struct HugeSize([u8; SIZE - 1]); let _ = (SIZE as *const HugeSize).align_offset(SIZE); } #[test] </ins> fn offset_from() { let mut a = [0; 5]; let ptr1: *mut i32 = &mut a[1];
<ins> trait TraitA { type TypeA; } trait TraitD { type TypeD; } pub trait TraitB { type TypeB: TraitD; fn f(_: &<Self::TypeB as TraitD>::TypeD); } pub trait TraitC<E> { type TypeC<'a>: TraitB; fn g<'a>(_: &<<Self::TypeC<'a> as TraitB>::TypeB as TraitA>::TypeA); //~^ ERROR the trait bound `<<Self as TraitC<E>>::TypeC<'a> as TraitB>::TypeB: TraitA` is not satisfied } fn main() {} </ins>
<ins> error[E0277]: the trait bound `<<Self as TraitC<E>>::TypeC<'a> as TraitB>::TypeB: TraitA` is not satisfied --> $DIR/issue-103573.rs:18:5 | LL |     fn g<'a>(_: &<<Self::TypeC<'a> as TraitB>::TypeB as TraitA>::TypeA); |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitA` is not implemented for `<<Self as TraitC<E>>::TypeC<'a> as TraitB>::TypeB` | help: consider further restricting the associated type | LL |     fn g<'a>(_: &<<Self::TypeC<'a> as TraitB>::TypeB as TraitA>::TypeA) where <<Self as TraitC<E>>::TypeC<'a> as TraitB>::TypeB: TraitA; |                                                                         +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. </ins>
}); if check_params && let Some(args) = path.segments.last().unwrap().args { let params_in_repr = tcx.params_in_repr(def_id); <del> for (i, arg) in args.args.iter().enumerate() { </del> <ins> // the domain size check is needed because the HIR may not be well-formed at this point for (i, arg) in args.args.iter().enumerate().take(params_in_repr.domain_size()) { </ins> if let hir::GenericArg::Type(ty) = arg && params_in_repr.contains(i as u32) { find_item_ty_spans(tcx, ty, needle, spans, seen_representable); }
<ins> #![crate_type = "lib"] struct Apple((Apple, Option(Banana ? Citron))); //~^ ERROR invalid `?` in type //~| ERROR expected one of `)` or `,`, found `Citron` //~| ERROR cannot find type `Citron` in this scope [E0412] //~| ERROR parenthesized type parameters may only be used with a `Fn` trait [E0214] //~| ERROR recursive type `Apple` has infinite size [E0072] </ins>
<ins> error: invalid `?` in type --> $DIR/issue-103748-ICE-wrong-braces.rs:3:36 | LL | struct Apple((Apple, Option(Banana ? Citron))); |                                    ^ `?` is only allowed on expressions, not types | help: if you meant to express that the type might not contain a value, use the `Option` wrapper type | LL | struct Apple((Apple, Option(Option<Banana > Citron))); |                             +++++++       ~ error: expected one of `)` or `,`, found `Citron` --> $DIR/issue-103748-ICE-wrong-braces.rs:3:38 | LL | struct Apple((Apple, Option(Banana ? Citron))); |                                     -^^^^^^ expected one of `)` or `,` |                                     | |                                     help: missing `,` error[E0412]: cannot find type `Citron` in this scope --> $DIR/issue-103748-ICE-wrong-braces.rs:3:38 | LL | struct Apple((Apple, Option(Banana ? Citron))); |                                      ^^^^^^ not found in this scope error[E0214]: parenthesized type parameters may only be used with a `Fn` trait --> $DIR/issue-103748-ICE-wrong-braces.rs:3:22 | LL | struct Apple((Apple, Option(Banana ? Citron))); |                      ^^^^^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses | help: use angle brackets instead | LL | struct Apple((Apple, Option<Banana ? Citron>)); |                            ~               ~ error[E0072]: recursive type `Apple` has infinite size --> $DIR/issue-103748-ICE-wrong-braces.rs:3:1 | LL | struct Apple((Apple, Option(Banana ? Citron))); | ^^^^^^^^^^^^  ----- recursive without indirection | help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle | LL | struct Apple((Box<Apple>, Option(Banana ? Citron))); |               ++++     + error: aborting due to 5 previous errors Some errors have detailed explanations: E0072, E0214, E0412. For more information about an error, try `rustc --explain E0072`. </ins>
[submodule "src/llvm-project"] path = src/llvm-project url = https://github.com/rust-lang/llvm-project.git <del> branch = rustc/15.0-2022-08-09 </del> <ins> branch = rustc/15.0-2022-12-07 </ins> [submodule "src/doc/embedded-book"] path = src/doc/embedded-book url = https://github.com/rust-embedded/book.git
// Check if we have an enum variant. let mut variant_resolution = None; <del> if let ty::Adt(adt_def, _) = qself_ty.kind() { </del> <ins> if let ty::Adt(adt_def, adt_substs) = qself_ty.kind() { </ins> if adt_def.is_enum() { let variant_def = adt_def .variants()
let Some(assoc_ty_did) = self.lookup_assoc_ty(assoc_ident, hir_ref_id, span, impl_) else { continue; }; <del> // FIXME(inherent_associated_types): This does not substitute parameters. let ty = tcx.type_of(assoc_ty_did); </del> <ins> let item_substs = self.create_substs_for_associated_item( span, assoc_ty_did, assoc_segment, adt_substs, ); let ty = tcx.bound_type_of(assoc_ty_did).subst(tcx, item_substs); </ins> return Ok((ty, DefKind::AssocTy, assoc_ty_did)); } }
} // see if we can satisfy using an inherent associated type <del> for impl_ in tcx.inherent_impls(adt_def.did()) { let assoc_ty = tcx.associated_items(impl_).find_by_name_and_kind( tcx, assoc_ident, ty::AssocKind::Type, *impl_, ); if let Some(assoc_ty) = assoc_ty { let ty = tcx.type_of(assoc_ty.def_id); return Ok((ty, DefKind::AssocTy, assoc_ty.def_id)); } </del> <ins> for &impl_ in tcx.inherent_impls(adt_def.did()) { let Some(assoc_ty_did) = self.lookup_assoc_ty(assoc_ident, hir_ref_id, span, impl_) else { continue; }; // FIXME(inherent_associated_types): This does not substitute parameters. let ty = tcx.type_of(assoc_ty_did); return Ok((ty, DefKind::AssocTy, assoc_ty_did)); </ins> } }
}; let trait_did = bound.def_id(); <del> let (assoc_ident, def_scope) = tcx.adjust_ident_and_get_scope(assoc_ident, trait_did, hir_ref_id); // We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead // of calling `filter_by_name_and_kind`. let item = tcx.associated_items(trait_did).in_definition_order().find(|i| { i.kind.namespace() == Namespace::TypeNS && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident }); // Assume that if it's not matched, there must be a const defined with the same name // but it was used in a type position. let Some(item) = item else { </del> <ins> let Some(assoc_ty_did) = self.lookup_assoc_ty(assoc_ident, hir_ref_id, span, trait_did) else { // Assume that if it's not matched, there must be a const defined with the same name // but it was used in a type position. </ins> let msg = format!("found associated const `{assoc_ident}` when type was expected"); let guar = tcx.sess.struct_span_err(span, &msg).emit(); return Err(guar); }; <del> let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, assoc_segment, bound); </del> <ins> let ty = self.projected_ty_from_poly_trait_ref(span, assoc_ty_did, assoc_segment, bound); </ins> let ty = self.normalize_ty(span, ty); <del> let kind = DefKind::AssocTy; if !item.visibility(tcx).is_accessible_from(def_scope, tcx) { let kind = kind.descr(item.def_id); let msg = format!("{} `{}` is private", kind, assoc_ident); tcx.sess .struct_span_err(span, &msg) .span_label(span, &format!("private {}", kind)) .emit(); } tcx.check_stability(item.def_id, Some(hir_ref_id), span, None); </del> if let Some(variant_def_id) = variant_resolution { tcx.struct_span_lint_hir( AMBIGUOUS_ASSOCIATED_ITEMS,
}, ); } <del> Ok((ty, kind, item.def_id)) </del> <ins> Ok((ty, DefKind::AssocTy, assoc_ty_did)) } fn lookup_assoc_ty( &self, ident: Ident, block: hir::HirId, span: Span, scope: DefId, ) -> Option<DefId> { let tcx = self.tcx(); let (ident, def_scope) = tcx.adjust_ident_and_get_scope(ident, scope, block); // We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead // of calling `find_by_name_and_kind`. let item = tcx.associated_items(scope).in_definition_order().find(|i| { i.kind.namespace() == Namespace::TypeNS && i.ident(tcx).normalize_to_macros_2_0() == ident })?; let kind = DefKind::AssocTy; if !item.visibility(tcx).is_accessible_from(def_scope, tcx) { let kind = kind.descr(item.def_id); let msg = format!("{kind} `{ident}` is private"); let def_span = self.tcx().def_span(item.def_id); tcx.sess .struct_span_err_with_code(span, &msg, rustc_errors::error_code!(E0624)) .span_label(span, &format!("private {kind}")) .span_label(def_span, &format!("{kind} defined here")) .emit(); } tcx.check_stability(item.def_id, Some(block), span, None); Some(item.def_id) </ins> } fn qpath_to_ty(
<ins> #![feature(inherent_associated_types)] #![allow(incomplete_features)] mod m { pub struct T; impl T { type P = (); } } type U = m::T::P; //~ ERROR associated type `P` is private mod n { pub mod n { pub struct T; impl T { pub(super) type P = bool; } } type U = n::T::P; } type V = n::n::T::P; //~ ERROR associated type `P` is private fn main() {} </ins>
<ins> error[E0624]: associated type `P` is private --> $DIR/assoc-inherent-private.rs:10:10 | LL |         type P = (); |         ------ associated type defined here ... LL | type U = m::T::P; |          ^^^^^^^ private associated type error[E0624]: associated type `P` is private --> $DIR/assoc-inherent-private.rs:21:10 | LL |             pub(super) type P = bool; |             ----------------- associated type defined here ... LL | type V = n::n::T::P; |          ^^^^^^^^^^ private associated type error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0624`. </ins>
<ins> error[E0658]: use of unstable library feature 'data' --> $DIR/assoc-inherent-unstable.rs:4:13 | LL | type Data = aux::Owner::Data; |             ^^^^^^^^^^^^^^^^ | = help: add `#![feature(data)]` to the crate attributes to enable error: aborting due to previous error For more information about this error, try `rustc --explain E0658`. </ins>
LL |     let _: S::C; |            ^^^^ help: use fully-qualified syntax: `<S as Trait>::C` <del> error: associated type `A` is private </del> <ins> error[E0624]: associated type `A` is private </ins> --> $DIR/item-privacy.rs:119:12 | <ins> LL |         type A = u8; |         ------ associated type defined here ... </ins> LL |     let _: T::A; |            ^^^^ private associated type
/// /// assert_eq!(n.leading_zeros(), 0); /// ``` <ins> #[doc = concat!("[`ilog2`]: ", stringify!($SelfT), "::ilog2")] </ins> #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")] #[must_use = "this returns the result of the operation,
/// /// assert_eq!(n.leading_zeros(), 2); /// ``` <ins> #[doc = concat!("[`ilog2`]: ", stringify!($SelfT), "::ilog2")] </ins> #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_math", since = "1.32.0")] #[must_use = "this returns the result of the operation,
}; e_flags } <del> Architecture::Riscv64 if sess.target.options.features.contains("+d") => { // copied from `riscv64-linux-gnu-gcc foo.c -c`, note though // that the `+d` target feature represents whether the double // float abi is enabled. let e_flags = elf::EF_RISCV_RVC | elf::EF_RISCV_FLOAT_ABI_DOUBLE; </del> <ins> Architecture::Riscv32 | Architecture::Riscv64 => { // Source: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/079772828bd10933d34121117a222b4cc0ee2200/riscv-elf.adoc let mut e_flags: u32 = 0x0; let features = &sess.target.options.features; // Check if compressed is enabled if features.contains("+c") { e_flags |= elf::EF_RISCV_RVC; } // Select the appropriate floating-point ABI if features.contains("+d") { e_flags |= elf::EF_RISCV_FLOAT_ABI_DOUBLE; } else if features.contains("+f") { e_flags |= elf::EF_RISCV_FLOAT_ABI_SINGLE; } else { e_flags |= elf::EF_RISCV_FLOAT_ABI_SOFT; } </ins> e_flags } _ => 0,
// In the algorithm above, we can change // cast(relative_tag) + niche_variants.start() // into <del> // cast(tag) + (niche_variants.start() - niche_start) </del> <ins> // cast(tag + (niche_variants.start() - niche_start)) </ins> // if either the casted type is no larger than the original // type, or if the niche values are contiguous (in either the // signed or unsigned sense). <del> let can_incr_after_cast = cast_smaller || niches_ule || niches_sle; </del> <ins> let can_incr = cast_smaller || niches_ule || niches_sle; </ins> let data_for_boundary_niche = || -> Option<(IntPredicate, u128)> { <del> if !can_incr_after_cast { </del> <ins> if !can_incr { </ins> None } else if niche_start == low_unsigned { Some((IntPredicate::IntULE, niche_end))
// The algorithm is now this: // is_niche = tag <= niche_end // discr = if is_niche { <del> //     cast(tag) + (niche_variants.start() - niche_start) </del> <ins> //     cast(tag + (niche_variants.start() - niche_start)) </ins> // } else { //     untagged_variant // } // (the first line may instead be tag >= niche_start, // and may be a signed or unsigned comparison) <ins> // The arithmetic must be done before the cast, so we can // have the correct wrapping behavior. See issue #104519 for // the consequences of getting this wrong. </ins> let is_niche = bx.icmp(predicate, tag, bx.cx().const_uint_big(tag_llty, constant)); <ins> let delta = (niche_variants.start().as_u32() as u128).wrapping_sub(niche_start); let incr_tag = if delta == 0 { tag } else { bx.add(tag, bx.cx().const_uint_big(tag_llty, delta)) }; </ins> let cast_tag = if cast_smaller { <del> bx.intcast(tag, cast_to, false) </del> <ins> bx.intcast(incr_tag, cast_to, false) </ins> } else if niches_ule { <del> bx.zext(tag, cast_to) </del> <ins> bx.zext(incr_tag, cast_to) </ins> } else { <del> bx.sext(tag, cast_to) </del> <ins> bx.sext(incr_tag, cast_to) </ins> }; <del> let delta = (niche_variants.start().as_u32() as u128).wrapping_sub(niche_start); (is_niche, cast_tag, delta) </del> <ins> (is_niche, cast_tag, 0) </ins> } else { // The special cases don't apply, so we'll have to go with // the general algorithm.
// CHECK: define i8 @match1{{.*}} // CHECK-NEXT: start: <del> // CHECK-NEXT: %1 = icmp ugt i8 %0, 1 // CHECK-NEXT: %2 = zext i8 %0 to i64 // CHECK-NEXT: %3 = add nsw i64 %2, -1 // CHECK-NEXT: %_2 = select i1 %1, i64 %3, i64 0 // CHECK-NEXT: switch i64 %_2, label {{.*}} [ </del> <ins> // CHECK-NEXT: %1 = {{.*}}call i8 @llvm.usub.sat.i8(i8 %0, i8 1) // CHECK-NEXT: switch i8 %1, label {{.*}} [ </ins> #[no_mangle] pub fn match1(e: Enum1) -> u8 { use Enum1::*;
<ins> // run-pass #![allow(dead_code)] enum OpenResult { Ok(()), Err(()), TransportErr(TransportErr), } #[repr(i32)] enum TransportErr { UnknownMethod = -2, } #[inline(never)] fn some_match(result: OpenResult) -> u8 { match result { OpenResult::Ok(()) => 0, _ => 1, } } fn main() { let result = OpenResult::Ok(()); assert_eq!(some_match(result), 0); let result = OpenResult::Ok(()); match result { OpenResult::Ok(()) => (), _ => unreachable!("message a"), } match result { OpenResult::Ok(()) => (), _ => unreachable!("message b"), } } </ins>
} } <del> /// Create an `Rc<[T]>` by reusing the underlying memory /// of a `Vec<T>`. This will return the vector if the existing allocation /// is not large enough. #[cfg(not(no_global_oom_handling))] fn try_from_vec_in_place(mut v: Vec<T>) -> Result<Rc<[T]>, Vec<T>> { let layout_elements = Layout::array::<T>(v.len()).unwrap(); let layout_allocation = Layout::array::<T>(v.capacity()).unwrap(); let layout_rcbox = rcbox_layout_for_value_layout(layout_elements); let mut ptr = NonNull::new(v.as_mut_ptr()).expect("`Vec<T>` stores `NonNull<T>`"); if layout_rcbox.size() > layout_allocation.size() || layout_rcbox.align() > layout_allocation.align() { // Can't fit - calling `grow` would involve `realloc` // (which copies the elements), followed by copying again. return Err(v); } if layout_rcbox.size() < layout_allocation.size() || layout_rcbox.align() < layout_allocation.align() { // We need to shrink the allocation so that it fits // https://doc.rust-lang.org/nightly/std/alloc/trait.Allocator.html#memory-fitting // SAFETY: // - Vec allocates by requesting `Layout::array::<T>(capacity)`, so this capacity matches // - `layout_rcbox` is smaller // If this fails, the ownership has not been transferred if let Ok(p) = unsafe { Global.shrink(ptr.cast(), layout_allocation, layout_rcbox) } { ptr = p.cast(); } else { return Err(v); } } // Make sure the vec's memory isn't deallocated now let v = mem::ManuallyDrop::new(v); let ptr: *mut RcBox<[T]> = ptr::slice_from_raw_parts_mut(ptr.as_ptr(), v.len()) as _; unsafe { ptr::copy(ptr.cast::<T>(), &mut (*ptr).value as *mut [T] as *mut T, v.len()); ptr::write(&mut (*ptr).strong, Cell::new(1)); ptr::write(&mut (*ptr).weak, Cell::new(1)); Ok(Self::from_ptr(ptr)) } } </del> /// Constructs an `Rc<[T]>` from an iterator known to be of a certain size. /// /// Behavior is undefined should the size be wrong.
/// assert_eq!(vec![1, 2, 3], *shared); /// ``` #[inline] <del> fn from(v: Vec<T>) -> Rc<[T]> { match Rc::try_from_vec_in_place(v) { Ok(rc) => rc, Err(mut v) => { unsafe { let rc = Rc::copy_from_slice(&v); // Allow the Vec to free its memory, but not destroy its contents v.set_len(0); rc } } </del> <ins> fn from(mut v: Vec<T>) -> Rc<[T]> { unsafe { let rc = Rc::copy_from_slice(&v); // Allow the Vec to free its memory, but not destroy its contents v.set_len(0); rc </ins> } } }
} } <del> /// Create an `Arc<[T]>` by reusing the underlying memory /// of a `Vec<T>`. This will return the vector if the existing allocation /// is not large enough. #[cfg(not(no_global_oom_handling))] fn try_from_vec_in_place(mut v: Vec<T>) -> Result<Arc<[T]>, Vec<T>> { let layout_elements = Layout::array::<T>(v.len()).unwrap(); let layout_allocation = Layout::array::<T>(v.capacity()).unwrap(); let layout_arcinner = arcinner_layout_for_value_layout(layout_elements); let mut ptr = NonNull::new(v.as_mut_ptr()).expect("`Vec<T>` stores `NonNull<T>`"); if layout_arcinner.size() > layout_allocation.size() || layout_arcinner.align() > layout_allocation.align() { // Can't fit - calling `grow` would involve `realloc` // (which copies the elements), followed by copying again. return Err(v); } if layout_arcinner.size() < layout_allocation.size() || layout_arcinner.align() < layout_allocation.align() { // We need to shrink the allocation so that it fits // https://doc.rust-lang.org/nightly/std/alloc/trait.Allocator.html#memory-fitting // SAFETY: // - Vec allocates by requesting `Layout::array::<T>(capacity)`, so this capacity matches // - `layout_arcinner` is smaller // If this fails, the ownership has not been transferred if let Ok(p) = unsafe { Global.shrink(ptr.cast(), layout_allocation, layout_arcinner) } { ptr = p.cast(); } else { return Err(v); } } // Make sure the vec's memory isn't deallocated now let v = mem::ManuallyDrop::new(v); let ptr: *mut ArcInner<[T]> = ptr::slice_from_raw_parts_mut(ptr.as_ptr(), v.len()) as _; unsafe { ptr::copy(ptr.cast::<T>(), &mut (*ptr).data as *mut [T] as *mut T, v.len()); ptr::write(&mut (*ptr).strong, atomic::AtomicUsize::new(1)); ptr::write(&mut (*ptr).weak, atomic::AtomicUsize::new(1)); Ok(Self::from_ptr(ptr)) } } </del> /// Constructs an `Arc<[T]>` from an iterator known to be of a certain size. /// /// Behavior is undefined should the size be wrong.
/// assert_eq!(&[1, 2, 3], &shared[..]); /// ``` #[inline] <del> fn from(v: Vec<T>) -> Arc<[T]> { match Arc::try_from_vec_in_place(v) { Ok(rc) => rc, Err(mut v) => { unsafe { let rc = Arc::copy_from_slice(&v); // Allow the Vec to free its memory, but not destroy its contents v.set_len(0); rc } } </del> <ins> fn from(mut v: Vec<T>) -> Arc<[T]> { unsafe { let rc = Arc::copy_from_slice(&v); // Allow the Vec to free its memory, but not destroy its contents v.set_len(0); rc </ins> } } }
// `val` dropped here while still borrowed // borrow might be used here, when `val` is dropped and runs the `Drop` code for type `std::sync::Weak` } <del> #[test] fn arc_from_vec_opt() { let mut v = Vec::with_capacity(64); v.push(0usize); let addr = v.as_ptr().cast::<u8>(); let arc: Arc<[_]> = v.into(); unsafe { assert_eq!( arc.as_ptr().cast::<u8>().offset_from(addr), (std::mem::size_of::<usize>() * 2) as isize, "Vector allocation not reused" ); } } </del>