use alloc::borrow::ToOwned;
use alloc::boxed::Box;
use alloc::format;
use alloc::string::{String, ToString};
use alloc::vec;
use alloc::vec::Vec;
use core::mem;
use crate::rustc_arena::TypedArena;
use crate::rustc_span::ErrorGuaranteed;
use crate::rustc_middle::ty::TyCtxt;
pub trait ArenaCached<'tcx>: Sized {
type Provided;
type Allocated: 'tcx;
fn alloc_in_arena(
tcx: TyCtxt<'tcx>,
typed_arena: &'tcx TypedArena<Self::Allocated>,
value: Self::Provided,
) -> Self;
}
impl<'tcx, T> ArenaCached<'tcx> for &'tcx T {
type Provided = T;
type Allocated = T;
fn alloc_in_arena(tcx: TyCtxt<'tcx>, typed_arena: &'tcx TypedArena<T>, value: T) -> Self {
do_alloc(tcx, typed_arena, value)
}
}
impl<'tcx, T> ArenaCached<'tcx> for Option<&'tcx T> {
type Provided = Option<T>;
type Allocated = T;
fn alloc_in_arena(
tcx: TyCtxt<'tcx>,
typed_arena: &'tcx TypedArena<T>,
value: Option<T>,
) -> Self {
value.map(|value| do_alloc(tcx, typed_arena, value))
}
}
impl<'tcx, T> ArenaCached<'tcx> for Result<&'tcx T, ErrorGuaranteed> {
type Provided = Result<T, ErrorGuaranteed>;
type Allocated = T;
fn alloc_in_arena(
tcx: TyCtxt<'tcx>,
typed_arena: &'tcx TypedArena<T>,
value: Result<T, ErrorGuaranteed>,
) -> Self {
value.map(|value| do_alloc(tcx, typed_arena, value))
}
}
fn do_alloc<'tcx, T>(tcx: TyCtxt<'tcx>, typed_arena: &'tcx TypedArena<T>, value: T) -> &'tcx T {
if mem::needs_drop::<T>() { typed_arena.alloc(value) } else { tcx.arena.dropless.alloc(value) }
}