fix new_cyclic_in for rc · qinheping/verify-rust-std@3e677e3 (original) (raw)

`@@ -687,54 +687,6 @@ impl<T, A: Allocator> Rc<T, A> {

`

687

687

`}

`

688

688

`}

`

689

689

``

690

``

`-

/// TODO: document

`

691

``

`-

#[cfg(not(no_global_oom_handling))]

`

692

``

`-

#[unstable(feature = "allocator_api", issue = "32838")]

`

693

``

`-

pub fn new_cyclic_in(data_fn: F, alloc: A) -> Rc<T, A>

`

694

``

`-

where

`

695

``

`-

F: FnOnce(&Weak<T, A>) -> T,

`

696

``

`-

{

`

697

``

`-

// Construct the inner in the "uninitialized" state with a single

`

698

``

`-

// weak reference.

`

699

``

`-

let uninit_ptr: NonNull<_> = Box::leak(

`

700

``

`-

Box::new_in(RcBox {

`

701

``

`-

strong: Cell::new(0),

`

702

``

`-

weak: Cell::new(1),

`

703

``

`-

value: mem::MaybeUninit::::uninit(),

`

704

``

`-

}),

`

705

``

`-

alloc,

`

706

``

`-

)

`

707

``

`-

.into();

`

708

``

-

709

``

`-

let init_ptr: NonNull<RcBox> = uninit_ptr.cast();

`

710

``

-

711

``

`-

let weak = Weak { ptr: init_ptr, alloc: Global };

`

712

``

-

713

``

`-

// It's important we don't give up ownership of the weak pointer, or

`

714

``

`` -

// else the memory might be freed by the time data_fn returns. If

``

715

``

`-

// we really wanted to pass ownership, we could create an additional

`

716

``

`-

// weak pointer for ourselves, but this would result in additional

`

717

``

`-

// updates to the weak reference count which might not be necessary

`

718

``

`-

// otherwise.

`

719

``

`-

let data = data_fn(&weak);

`

720

``

-

721

``

`-

let strong = unsafe {

`

722

``

`-

let inner = init_ptr.as_ptr();

`

723

``

`-

ptr::write(ptr::addr_of_mut!((*inner).value), data);

`

724

``

-

725

``

`-

let prev_value = (*inner).strong.get();

`

726

``

`-

debug_assert_eq!(prev_value, 0, "No prior strong references should exist");

`

727

``

`-

(*inner).strong.set(1);

`

728

``

-

729

``

`-

Rc::from_inner(init_ptr)

`

730

``

`-

};

`

731

``

-

732

``

`-

// Strong references should collectively own a shared weak reference,

`

733

``

`-

// so don't run the destructor for our old weak reference.

`

734

``

`-

mem::forget(weak);

`

735

``

`-

strong

`

736

``

`-

}

`

737

``

-

738

690

`` /// Constructs a new Rc with uninitialized contents in the provided allocator.

``

739

691

`///

`

740

692

`/// # Examples

`

`@@ -2312,6 +2264,85 @@ impl<T: ?Sized, A: Allocator + Clone> Clone for Rc<T, A> {

`

2312

2264

`}

`

2313

2265

`}

`

2314

2266

``

``

2267

`+

impl<T, A: Allocator + Clone> Rc<T, A> {

`

``

2268

`` +

/// Constructs a new Rc<T, A> in the given allocator while giving you a Weak<T, A> to the allocation,

``

``

2269

`` +

/// to allow you to construct a T which holds a weak pointer to itself.

``

``

2270

`+

///

`

``

2271

`+

/// Generally, a structure circularly referencing itself, either directly or

`

``

2272

`+

/// indirectly, should not hold a strong reference to itself to prevent a memory leak.

`

``

2273

`+

/// Using this function, you get access to the weak pointer during the

`

``

2274

`` +

/// initialization of T, before the Rc<T, A> is created, such that you can

``

``

2275

`` +

/// clone and store it inside the T.

``

``

2276

`+

///

`

``

2277

`` +

/// new_cyclic first allocates the managed allocation for the Rc<T, A>,

``

``

2278

`` +

/// then calls your closure, giving it a Weak<T, A> to this allocation,

``

``

2279

`` +

/// and only afterwards completes the construction of the Rc<T, A> by placing

``

``

2280

`` +

/// the T returned from your closure into the allocation.

``

``

2281

`+

///

`

``

2282

`` +

/// Since the new Rc<T, A> is not fully-constructed until Rc<T, A>::new_cyclic

``

``

2283

`` +

/// returns, calling [upgrade] on the weak reference inside your closure will

``

``

2284

`` +

/// fail and result in a None value.

``

``

2285

`+

///

`

``

2286

`+

/// # Panics

`

``

2287

`+

///

`

``

2288

`` +

/// If data_fn panics, the panic is propagated to the caller, and the

``

``

2289

`` +

/// temporary [Weak<T, A>] is dropped normally.

``

``

2290

`+

///

`

``

2291

`+

/// # Examples

`

``

2292

`` +

/// See [new_cyclic].

``

``

2293

`+

///

`

``

2294

`` +

/// [new_cyclic]: Rc::new_cyclic

``

``

2295

`` +

/// [upgrade]: Weak::upgrade

``

``

2296

`+

#[cfg(not(no_global_oom_handling))]

`

``

2297

`+

#[unstable(feature = "allocator_api", issue = "32838")]

`

``

2298

`+

pub fn new_cyclic_in(data_fn: F, alloc: A) -> Rc<T, A>

`

``

2299

`+

where

`

``

2300

`+

F: FnOnce(&Weak<T, A>) -> T,

`

``

2301

`+

{

`

``

2302

`+

// Note: comments and implementation are copied from Rc::new_cyclic.

`

``

2303

+

``

2304

`+

// Construct the inner in the "uninitialized" state with a single

`

``

2305

`+

// weak reference.

`

``

2306

`+

let uninit_ptr: NonNull<_> = Box::leak(Box::new_in(

`

``

2307

`+

RcBox {

`

``

2308

`+

strong: Cell::new(0),

`

``

2309

`+

weak: Cell::new(1),

`

``

2310

`+

value: mem::MaybeUninit::::uninit(),

`

``

2311

`+

},

`

``

2312

`+

alloc.clone(),

`

``

2313

`+

))

`

``

2314

`+

.into();

`

``

2315

+

``

2316

`+

let init_ptr: NonNull<RcBox> = uninit_ptr.cast();

`

``

2317

+

``

2318

`+

let weak = Weak { ptr: init_ptr, alloc: alloc.clone() };

`

``

2319

+

``

2320

`+

// It's important we don't give up ownership of the weak pointer, or

`

``

2321

`` +

// else the memory might be freed by the time data_fn returns. If

``

``

2322

`+

// we really wanted to pass ownership, we could create an additional

`

``

2323

`+

// weak pointer for ourselves, but this would result in additional

`

``

2324

`+

// updates to the weak reference count which might not be necessary

`

``

2325

`+

// otherwise.

`

``

2326

`+

let data = data_fn(&weak);

`

``

2327

+

``

2328

`+

let strong = unsafe {

`

``

2329

`+

let inner = init_ptr.as_ptr();

`

``

2330

`+

ptr::write(ptr::addr_of_mut!((*inner).value), data);

`

``

2331

+

``

2332

`+

let prev_value = (*inner).strong.get();

`

``

2333

`+

debug_assert_eq!(prev_value, 0, "No prior strong references should exist");

`

``

2334

`+

(*inner).strong.set(1);

`

``

2335

+

``

2336

`+

Rc::from_inner_in(init_ptr, alloc)

`

``

2337

`+

};

`

``

2338

+

``

2339

`+

// Strong references should collectively own a shared weak reference,

`

``

2340

`+

// so don't run the destructor for our old weak reference.

`

``

2341

`+

mem::forget(weak);

`

``

2342

`+

strong

`

``

2343

`+

}

`

``

2344

`+

}

`

``

2345

+

2315

2346

`#[cfg(not(no_global_oom_handling))]

`

2316

2347

`#[stable(feature = "rust1", since = "1.0.0")]

`

2317

2348

`impl<T: Default> Default for Rc {

`