TMI: Destructors
May. 15th, 2012 10:20 pmYesterday and today, I worked on adding destructors to classes. A destructor is a method that can't be named directly, to which the compiler inserts a call whenever the memory for the class is about to be freed (so, whenever its reference count becomes zero). Here's a super simple example of a class with a destructor:
class shrinky_pointer {
let i: @@mut int;
fn look_at() -> int { ret **(self.i); }
new(i: @@mut int) { self.i = i; }
drop { **(self.i) -= 1; }
}
This is a class with one field, a pointer to a pointer to an integer. When the class is freed, the integer gets decremented by one. Since in this case, i is declared with @, there may be other pointers to the contents of the box. One would hope there are, since otherwise the effects that the destructor (written drop, which is a keyword) has would be unobservable.
Rust already has special syntax, called "resources", for classes that just have a constructor and a destructor, without having any methods or fields: for example:
resource shrinky_pointer(i: @mut int) { *i -= 1; }
In this case, there's an implicit constructor that sets i's value in the self record to whatever value of i shrinky_pointer (really, its constructor) gets called with; and a destructor that decrements the contents.
The goal of adding destructors to classes is to get rid of the resource form, since classes are strictly more powerful.
Adding destructors was pretty straightforward, since most of the code was already there and it was just a question of making sure it gets invoked from the code that deals with classes, if the class type in question has a destructor (unlike constructors, destructors are optional). Now I'm in the process of porting the resources tests to use classes. I got through the first few pretty easily, but a test called resource-cycle is giving me trouble. More tomorrow when I can keep my eyes open.
In the meeting today, we also agreed that I would rewrite the resolver (the pass that determines what definition each name refers to). My plan is to finish destructors and then move on to that; I'd wanted to work on incremental recompilation, but that can wait.