Skip to content

Instantly share code, notes, and snippets.

@jviereck
Created March 2, 2015 13:10
Show Gist options
  • Save jviereck/181fec26c72cc7595f41 to your computer and use it in GitHub Desktop.
Save jviereck/181fec26c72cc7595f41 to your computer and use it in GitHub Desktop.
fn print_node_id(node_ref: &Node) {
println!("node.id={}", node_ref.id);
match node_ref.next {
Some(ref next) => {
println!("node.next.id={}", next.id);
}
None => {
println!("node.next=None");
}
}
}
struct Node<'a> {
id: isize,
next: Option<&'a mut Node<'a>>
}
fn main() {
let arena: TypedArena<Entry> = TypedArena::with_capacity(16us);
// Perform the allocations from the arena. Note the color
let a: &mut Node = arena.alloc(Node { id: 0, next: None });
let b: &mut Node = arena.alloc(Node { id: 1, next: None });
// Assining the mutable reference to a mutable reference with an associated
// color.
// QUESTION: In this setup, should the color be a property of the reference
// like `&#c mut Node`?
let a_0: &mut Node<#c> = a;
let a_1: &mut Node<#c> = a_0;
// Take a borrow of `b` with the same color as the `a_0` from above.
let b_0: &mut Node<#c> = b;
// Because the target and source of the following have the same colors
// the assignment doesn't cause the RHS to be marked as borrowed.
a_1.next = Some(b_0);
b_0.next = Some(a_0);
// Check if the references are setup correctly. Note that it is not possible
// to read from the `a` and the `b` variables here as they are marked as
// borrowed. However it is possible to use them to check for equality.
assert!(b_0.next == a);
assert!(a_0.next == b); // NOTE: Assigned to `a_1` above but they are the same objects.
{
// TODO: Borrow to a function.
}
// Let's see if a colorful node can be assigned to a node without a color.
let c: &mut Node = arena.alloc(Node { id: 2, next: None });
// The following assignment is allowed. Here are the intermediate steps
// on what is happening in details:
// - the `a_0` has type `&mut Node<#c>` and therefore has a different color
// as the `c` of type `&mut Node`.
// - the conversation between the different color types is done by
// "downcast" the color from `<#c>` to the empty color `<>`. This
// downcast causes all the `&mut Node<#c>` to be marked as borrowed.
// - the converted reference of `a_0` has now the correct type of
// `&mut Node` and can be assigned to `c.next`.
c.next = Some(a_0);
// NOTE: At this point all the nodes with color `<#c>` are borrowed due to
// the stored reference on `c.next`. From the transitivity of the
// borrow operation it follows, that `a` and `b` are borrowed now
// through the assignment to `c.next` as well.
// Is it possible to get hold of a new `&mut Node<#c>` at this point again?
// This should not be possible as it causes confusion with the other <#c>
// that are currently borrowed. Therefore, it is necessary to require, that
// a new color can only be introduced if no reference with the same color
// is borrowed at the current time.
//
// This does NOT work:
//
// let c_0: &mut Node<#c> = c;
//
// But the following works fine by choosing a new color to bind to:
let c_0: &mut Node<#d> = c;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment