mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 16:44:33 +00:00
Remove pending recursive type IDs in glue
This commit is contained in:
parent
d7ef42612b
commit
fcb174cfa0
1 changed files with 14 additions and 46 deletions
|
@ -25,16 +25,6 @@ use std::fmt::Display;
|
||||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
pub struct TypeId(usize);
|
pub struct TypeId(usize);
|
||||||
|
|
||||||
impl TypeId {
|
|
||||||
/// Used when making recursive pointers, which need to temporarily
|
|
||||||
/// have *some* TypeId value until we later in the process determine
|
|
||||||
/// their real TypeId and can go back and fix them up.
|
|
||||||
pub(crate) const PENDING: Self = Self(usize::MAX);
|
|
||||||
|
|
||||||
/// When adding, we check for overflow based on whether we've exceeded this.
|
|
||||||
const MAX: Self = Self(Self::PENDING.0 - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Types {
|
pub struct Types {
|
||||||
// These are all indexed by TypeId
|
// These are all indexed by TypeId
|
||||||
|
@ -350,7 +340,8 @@ impl Types {
|
||||||
pub fn add_anonymous(&mut self, typ: RocType, layout: Layout<'_>) -> TypeId {
|
pub fn add_anonymous(&mut self, typ: RocType, layout: Layout<'_>) -> TypeId {
|
||||||
let id = TypeId(self.types.len());
|
let id = TypeId(self.types.len());
|
||||||
|
|
||||||
assert!(id.0 <= TypeId::MAX.0);
|
// Make sure we don't overflow
|
||||||
|
assert!(id.0 <= usize::MAX);
|
||||||
|
|
||||||
self.types.push(typ);
|
self.types.push(typ);
|
||||||
self.sizes
|
self.sizes
|
||||||
|
@ -599,7 +590,6 @@ pub struct Env<'a> {
|
||||||
interns: &'a Interns,
|
interns: &'a Interns,
|
||||||
struct_names: Structs,
|
struct_names: Structs,
|
||||||
enum_names: Enums,
|
enum_names: Enums,
|
||||||
pending_recursive_types: VecMap<TypeId, Layout<'a>>,
|
|
||||||
known_recursive_types: VecMap<Layout<'a>, TypeId>,
|
known_recursive_types: VecMap<Layout<'a>, TypeId>,
|
||||||
target: TargetInfo,
|
target: TargetInfo,
|
||||||
}
|
}
|
||||||
|
@ -617,7 +607,6 @@ impl<'a> Env<'a> {
|
||||||
interns,
|
interns,
|
||||||
struct_names: Default::default(),
|
struct_names: Default::default(),
|
||||||
enum_names: Default::default(),
|
enum_names: Default::default(),
|
||||||
pending_recursive_types: Default::default(),
|
|
||||||
known_recursive_types: Default::default(),
|
known_recursive_types: Default::default(),
|
||||||
layout_cache: LayoutCache::new(target),
|
layout_cache: LayoutCache::new(target),
|
||||||
target,
|
target,
|
||||||
|
@ -634,8 +623,6 @@ impl<'a> Env<'a> {
|
||||||
self.add_type(var, &mut types);
|
self.add_type(var, &mut types);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.resolve_pending_recursive_types(&mut types);
|
|
||||||
|
|
||||||
types
|
types
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,30 +634,6 @@ impl<'a> Env<'a> {
|
||||||
|
|
||||||
add_type_help(self, layout, var, None, types)
|
add_type_help(self, layout, var, None, types)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_pending_recursive_types(&mut self, types: &mut Types) {
|
|
||||||
// TODO if VecMap gets a drain() method, use that instead of doing take() and into_iter
|
|
||||||
let pending = core::mem::take(&mut self.pending_recursive_types);
|
|
||||||
|
|
||||||
for (type_id, layout) in pending.into_iter() {
|
|
||||||
let actual_type_id = self.known_recursive_types.get(&layout).unwrap_or_else(|| {
|
|
||||||
unreachable!(
|
|
||||||
"There was no known recursive TypeId for the pending recursive type {:?}",
|
|
||||||
layout
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
debug_assert!(
|
|
||||||
matches!(types.get_type(type_id), RocType::RecursivePointer(TypeId::PENDING)),
|
|
||||||
"The TypeId {:?} was registered as a pending recursive pointer, but was not stored in Types as one.",
|
|
||||||
type_id
|
|
||||||
);
|
|
||||||
|
|
||||||
// size and alignment shouldn't change; this is still
|
|
||||||
// a RecursivePointer, it's just pointing to something else.
|
|
||||||
types.replace(type_id, RocType::RecursivePointer(*actual_type_id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_type_help<'a>(
|
fn add_type_help<'a>(
|
||||||
|
@ -864,14 +827,19 @@ fn add_type_help<'a>(
|
||||||
Content::RangedNumber(_) => todo!(),
|
Content::RangedNumber(_) => todo!(),
|
||||||
Content::Error => todo!(),
|
Content::Error => todo!(),
|
||||||
Content::RecursionVar { structure, .. } => {
|
Content::RecursionVar { structure, .. } => {
|
||||||
let type_id = types.add_anonymous(RocType::RecursivePointer(TypeId::PENDING), layout);
|
// These variables are different, but the layouts should always be the same!
|
||||||
let structure_layout = env
|
debug_assert_eq!(
|
||||||
.layout_cache
|
layout,
|
||||||
|
env.layout_cache
|
||||||
.from_var(env.arena, *structure, subs)
|
.from_var(env.arena, *structure, subs)
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
env.pending_recursive_types
|
// Temporarily insert an empty tag union, just so we can get a TypeId.
|
||||||
.insert(type_id, structure_layout);
|
let type_id = types.add_anonymous(RocType::EmptyTagUnion, layout);
|
||||||
|
|
||||||
|
// Set the TypeId we got to be a RecursivePointer to itself
|
||||||
|
types.replace(type_id, RocType::RecursivePointer(type_id));
|
||||||
|
|
||||||
type_id
|
type_id
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue