Skip to content

Commit

Permalink
WIP: start fixing drop issues
Browse files Browse the repository at this point in the history
  • Loading branch information
yorickpeterse committed Dec 8, 2024
1 parent 6db033d commit 4da407c
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 86 deletions.
23 changes: 8 additions & 15 deletions compiler/src/mir/specialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,7 @@ fn shapes_compatible_with_bounds(
// This ultimately ensures that we don't try to specialize some
// method over e.g. `Option[Int32]` where it's exected `Int32`
// implements a certain trait when it doesn't.
let ins = match shape {
Shape::Stack(v) | Shape::StackMut(v) | Shape::StackRef(v) => v,
_ => continue,
};
let Some(ins) = shape.as_stack_instance() else { continue };

if !TypeChecker::new(db).class_compatible_with_bound(ins, bound) {
return false;
Expand Down Expand Up @@ -1340,13 +1337,11 @@ impl<'a, 'b, 'c> ExpandDrop<'a, 'b, 'c> {
| Shape::Float(_)
| Shape::Nil
| Shape::Boolean
| Shape::Pointer => {
| Shape::Pointer
| Shape::Copy(_) => {
self.ignore_value(block_id, after_id);
}
Shape::Stack(t) if t.instance_of().is_copy_type(self.db) => {
self.ignore_value(block_id, after_id);
}
Shape::Stack(_) => {
Shape::Inline(_) => {
self.drop_owned(block_id, after_id, val, ins.dropper, loc);
}
Shape::Mut | Shape::Ref => {
Expand All @@ -1358,7 +1353,7 @@ impl<'a, 'b, 'c> ExpandDrop<'a, 'b, 'c> {
Shape::Owned => {
self.drop_owned(block_id, after_id, val, ins.dropper, loc);
}
Shape::StackRef(t) | Shape::StackMut(t) => {
Shape::InlineRef(t) | Shape::InlineMut(t) => {
self.drop_stack_borrow(block_id, after_id, val, t, loc);
}
}
Expand Down Expand Up @@ -1542,7 +1537,8 @@ impl<'a, 'b, 'c> ExpandBorrow<'a, 'b, 'c> {
| Shape::Float(_)
| Shape::Nil
| Shape::Boolean
| Shape::Pointer => {
| Shape::Pointer
| Shape::Copy(_) => {
// These values should be left as-is.
}
Shape::Mut | Shape::Ref | Shape::Owned => {
Expand All @@ -1551,10 +1547,7 @@ impl<'a, 'b, 'c> ExpandBorrow<'a, 'b, 'c> {
Shape::Atomic | Shape::String => {
self.block_mut(block_id).increment_atomic(val, loc);
}
Shape::Stack(t) if t.instance_of().is_copy_type(self.db) => {
// Nothing to do
}
Shape::Stack(t) | Shape::StackRef(t) | Shape::StackMut(t) => {
Shape::Inline(t) | Shape::InlineRef(t) | Shape::InlineMut(t) => {
self.borrow_inline_type(block_id, val, t, loc);
}
}
Expand Down
36 changes: 21 additions & 15 deletions compiler/src/symbol_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,26 @@ pub(crate) fn format_shape(db: &Database, shape: Shape, buf: &mut String) {
Shape::Atomic => write!(buf, "a"),
Shape::Nil => write!(buf, "n"),
Shape::Pointer => write!(buf, "p"),
Shape::Stack(ins) => {
let _ = write!(buf, "SO{}.", ins.instance_of().module(db).name(db));
Shape::Copy(ins) => {
let _ = write!(buf, "C{}.", ins.instance_of().module(db).name(db));

format_class_name(db, ins.instance_of(), buf);
Ok(())
}
Shape::StackRef(ins) => {
let _ = write!(buf, "SR{}.", ins.instance_of().module(db).name(db));
Shape::Inline(ins) => {
let _ = write!(buf, "IO{}.", ins.instance_of().module(db).name(db));

format_class_name(db, ins.instance_of(), buf);
Ok(())
}
Shape::StackMut(ins) => {
let _ = write!(buf, "SM{}.", ins.instance_of().module(db).name(db));
Shape::InlineRef(ins) => {
let _ = write!(buf, "IR{}.", ins.instance_of().module(db).name(db));

format_class_name(db, ins.instance_of(), buf);
Ok(())
}
Shape::InlineMut(ins) => {
let _ = write!(buf, "IM{}.", ins.instance_of().module(db).name(db));

format_class_name(db, ins.instance_of(), buf);
Ok(())
Expand Down Expand Up @@ -212,17 +218,17 @@ mod tests {
&mut db,
vec![
Shape::Int(64, Sign::Signed),
Shape::Stack(ClassInstance::new(cls2)),
Shape::Inline(ClassInstance::new(cls2)),
],
);
cls2.set_shapes(&mut db, vec![Shape::String]);
cls3.set_shapes(
&mut db,
vec![Shape::StackRef(ClassInstance::new(cls2))],
vec![Shape::InlineRef(ClassInstance::new(cls2))],
);
cls4.set_shapes(
&mut db,
vec![Shape::StackMut(ClassInstance::new(cls2))],
vec![Shape::InlineMut(ClassInstance::new(cls2))],
);

assert_eq!(name(&db, Shape::Owned), "o");
Expand All @@ -237,16 +243,16 @@ mod tests {
assert_eq!(name(&db, Shape::Nil), "n");
assert_eq!(name(&db, Shape::Pointer), "p");
assert_eq!(
name(&db, Shape::Stack(ClassInstance::new(cls1))),
"SOa.b.c.A#i64SOa.b.c.B#s"
name(&db, Shape::Inline(ClassInstance::new(cls1))),
"IOa.b.c.A#i64IOa.b.c.B#s"
);
assert_eq!(
name(&db, Shape::StackMut(ClassInstance::new(cls3))),
"SMa.b.c.C#SRa.b.c.B#s"
name(&db, Shape::InlineMut(ClassInstance::new(cls3))),
"IMa.b.c.C#IRa.b.c.B#s"
);
assert_eq!(
name(&db, Shape::StackRef(ClassInstance::new(cls4))),
"SRa.b.c.D#SMa.b.c.B#s"
name(&db, Shape::InlineRef(ClassInstance::new(cls4))),
"IRa.b.c.D#IMa.b.c.B#s"
);
}
}
88 changes: 53 additions & 35 deletions types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2041,15 +2041,15 @@ impl ClassInstance {
STRING_ID => Shape::String,
_ if self.instance_of.kind(db).is_atomic() => Shape::Atomic,
_ if self.instance_of.is_copy_type(db) => {
Shape::Stack(self.interned(db, interned))
Shape::Copy(self.interned(db, interned))
}
_ if self.instance_of.is_inline_type(db) => {
let ins = self.interned(db, interned);

match default {
Shape::Mut => Shape::StackMut(ins),
Shape::Ref => Shape::StackRef(ins),
_ => Shape::Stack(ins),
Shape::Mut => Shape::InlineMut(ins),
Shape::Ref => Shape::InlineRef(ins),
_ => Shape::Inline(ins),
}
}
_ => default,
Expand Down Expand Up @@ -3926,14 +3926,17 @@ pub enum Shape {
/// integers
Pointer,

/// A stack allocated value type.
Copy(ClassInstance),

/// A stack allocated, owned type.
Stack(ClassInstance),
Inline(ClassInstance),

/// An immutable borrow of an inline type.
StackRef(ClassInstance),
InlineRef(ClassInstance),

/// A mutable borrow of an inline type.
StackMut(ClassInstance),
InlineMut(ClassInstance),
}

impl Shape {
Expand All @@ -3954,6 +3957,16 @@ impl Shape {
_ => false,
}
}

pub fn as_stack_instance(self) -> Option<ClassInstance> {
match self {
Shape::Copy(v)
| Shape::Inline(v)
| Shape::InlineMut(v)
| Shape::InlineRef(v) => Some(v),
_ => None,
}
}
}

impl PartialEq for Shape {
Expand All @@ -3971,9 +3984,10 @@ impl PartialEq for Shape {
(Nil, Nil) => true,
(Atomic, Atomic) => true,
(Pointer, Pointer) => true,
(Stack(a), Stack(b)) => a.instance_of == b.instance_of,
(StackRef(a), StackRef(b)) => a.instance_of == b.instance_of,
(StackMut(a), StackMut(b)) => a.instance_of == b.instance_of,
(Copy(a), Copy(b)) => a.instance_of == b.instance_of,
(Inline(a), Inline(b)) => a.instance_of == b.instance_of,
(InlineRef(a), InlineRef(b)) => a.instance_of == b.instance_of,
(InlineMut(a), InlineMut(b)) => a.instance_of == b.instance_of,
_ => false,
}
}
Expand Down Expand Up @@ -4001,18 +4015,22 @@ impl Hash for Shape {
Nil => state.write_u8(7),
Atomic => state.write_u8(8),
Pointer => state.write_u8(9),
Stack(i) => {
Copy(i) => {
state.write_u8(10);
i.instance_of.hash(state);
}
StackRef(i) => {
Inline(i) => {
state.write_u8(11);
i.instance_of.hash(state);
}
StackMut(i) => {
InlineRef(i) => {
state.write_u8(12);
i.instance_of.hash(state);
}
InlineMut(i) => {
state.write_u8(13);
i.instance_of.hash(state);
}
}
}
}
Expand Down Expand Up @@ -7031,27 +7049,27 @@ mod tests {
);
assert_eq!(
owned(instance(cls2)).shape(&db, &mut inter, &shapes),
Shape::Stack(ClassInstance::new(cls2))
Shape::Copy(ClassInstance::new(cls2))
);
assert_eq!(
mutable(instance(cls2)).shape(&db, &mut inter, &shapes),
Shape::Stack(ClassInstance::new(cls2))
Shape::Copy(ClassInstance::new(cls2))
);
assert_eq!(
immutable(instance(cls2)).shape(&db, &mut inter, &shapes),
Shape::Stack(ClassInstance::new(cls2))
Shape::Copy(ClassInstance::new(cls2))
);
assert_eq!(
owned(instance(cls3)).shape(&db, &mut inter, &shapes),
Shape::Stack(ClassInstance::new(cls3))
Shape::Inline(ClassInstance::new(cls3))
);
assert_eq!(
mutable(instance(cls3)).shape(&db, &mut inter, &shapes),
Shape::StackMut(ClassInstance::new(cls3))
Shape::InlineMut(ClassInstance::new(cls3))
);
assert_eq!(
immutable(instance(cls3)).shape(&db, &mut inter, &shapes),
Shape::StackRef(ClassInstance::new(cls3))
Shape::InlineRef(ClassInstance::new(cls3))
);
}

Expand Down Expand Up @@ -7186,20 +7204,20 @@ mod tests {
ClassInstance { instance_of: ClassId(1), type_arguments: 10 };
let ins3 = ClassInstance { instance_of: ClassId(2), type_arguments: 0 };

assert_eq!(Shape::Stack(ins1), Shape::Stack(ins2));
assert_ne!(Shape::Stack(ins1), Shape::Stack(ins3));
assert_ne!(Shape::Stack(ins1), Shape::StackRef(ins2));
assert_ne!(Shape::Stack(ins1), Shape::StackMut(ins2));
assert_eq!(Shape::Inline(ins1), Shape::Inline(ins2));
assert_ne!(Shape::Inline(ins1), Shape::Inline(ins3));
assert_ne!(Shape::Inline(ins1), Shape::InlineRef(ins2));
assert_ne!(Shape::Inline(ins1), Shape::InlineMut(ins2));

assert_eq!(Shape::StackRef(ins1), Shape::StackRef(ins2));
assert_ne!(Shape::StackRef(ins1), Shape::StackRef(ins3));
assert_ne!(Shape::StackRef(ins1), Shape::StackMut(ins2));
assert_ne!(Shape::StackRef(ins1), Shape::Stack(ins2));
assert_eq!(Shape::InlineRef(ins1), Shape::InlineRef(ins2));
assert_ne!(Shape::InlineRef(ins1), Shape::InlineRef(ins3));
assert_ne!(Shape::InlineRef(ins1), Shape::InlineMut(ins2));
assert_ne!(Shape::InlineRef(ins1), Shape::Inline(ins2));

assert_eq!(Shape::StackMut(ins1), Shape::StackMut(ins2));
assert_ne!(Shape::StackMut(ins1), Shape::StackMut(ins3));
assert_ne!(Shape::StackMut(ins1), Shape::StackRef(ins2));
assert_ne!(Shape::StackMut(ins1), Shape::Stack(ins2));
assert_eq!(Shape::InlineMut(ins1), Shape::InlineMut(ins2));
assert_ne!(Shape::InlineMut(ins1), Shape::InlineMut(ins3));
assert_ne!(Shape::InlineMut(ins1), Shape::InlineRef(ins2));
assert_ne!(Shape::InlineMut(ins1), Shape::Inline(ins2));
}

#[test]
Expand All @@ -7211,12 +7229,12 @@ mod tests {
let ins3 = ClassInstance { instance_of: ClassId(2), type_arguments: 0 };

assert_eq!(
state.hash_one(Shape::Stack(ins1)),
state.hash_one(Shape::Stack(ins2)),
state.hash_one(Shape::Inline(ins1)),
state.hash_one(Shape::Inline(ins2)),
);
assert_ne!(
state.hash_one(Shape::Stack(ins1)),
state.hash_one(Shape::Stack(ins3)),
state.hash_one(Shape::Inline(ins1)),
state.hash_one(Shape::Inline(ins3)),
);
}
}
Loading

0 comments on commit 4da407c

Please sign in to comment.