Created
March 2, 2015 13:10
-
-
Save jviereck/181fec26c72cc7595f41 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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