use crate::records::clone_state::CloneState;
use crate::records::type_arena::TypeArena;
use crate::records::type_cloner::TypeCloner;
use crate::type_aliases::seen_type_packs_clone::SeenTypePacks as DenseSeenTypePacks;
use crate::type_aliases::seen_types_clone::SeenTypes as DenseSeenTypes;
use crate::type_aliases::type_id::TypeId;
use crate::type_aliases::type_pack_id::TypePackId;
use std::collections::HashMap;
pub(crate) fn with_clone_maps<R>(
seen_types: &mut DenseSeenTypes,
seen_type_packs: &mut DenseSeenTypePacks,
body: impl FnOnce(&mut HashMap<TypeId, TypeId>, &mut HashMap<TypePackId, TypePackId>) -> R,
) -> R {
let mut tys: HashMap<TypeId, TypeId> = seen_types.iter().map(|(k, v)| (*k, *v)).collect();
let mut tps: HashMap<TypePackId, TypePackId> =
seen_type_packs.iter().map(|(k, v)| (*k, *v)).collect();
let result = body(&mut tys, &mut tps);
for (k, v) in tys.iter() {
*seen_types.get_or_insert(*k) = *v;
}
for (k, v) in tps.iter() {
*seen_type_packs.get_or_insert(*k) = *v;
}
result
}
pub fn clone(type_id: TypeId, dest: &mut TypeArena, clone_state: &mut CloneState) -> TypeId {
if unsafe { (*type_id).persistent } {
return type_id;
}
let builtin_types = clone_state.builtin_types;
with_clone_maps(
&mut clone_state.seen_types,
&mut clone_state.seen_type_packs,
|tys, tps| {
let mut cloner = TypeCloner {
arena: dest as *mut TypeArena,
builtin_types,
queue: alloc::vec::Vec::new(),
types: tys as *mut HashMap<TypeId, TypeId>,
packs: tps as *mut HashMap<TypePackId, TypePackId>,
force_ty: core::ptr::null(),
force_tp: core::ptr::null(),
steps: 0,
replacement_for_null_scope: core::ptr::null_mut(),
skip_lazy_type_clone: false,
};
cloner.clone_type_id(type_id)
},
)
}