1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//! Durka's `unborrow!` macro.
/// Explicitly precompute a method's arguments before the call so that borrowck sees them the same
/// way that trans does.
///
/// Examples
/// =======
///
/// ```
/// # #[macro_use] extern crate unborrow;
/// # fn main() {
/// let mut v = vec![1, 2, 3];
///
/// // this line would cause an error because borrowck consider `v` borrowed by `reserve`
/// // during its parameter list
/// // v.reserve(v.capacity()); //~ERROR cannot borrow `v`
/// // but wrap the call in unborrow!() and it works!
/// unborrow!(v.reserve(v.capacity()));
/// assert!(v.capacity() >= 6);
/// assert_eq!(v, [1, 2, 3]);
///
/// // similar to the above, both v.len()-1 and v[0]+41 require borrowing `v` and we can't
/// // do that while borrowck thinks is is mutably borrowed by `insert`
/// // v.insert(v.len() - 1, v[0] + 41); //~ERROR cannot borrow `v`
/// // but wrap the call in unborrow!() and it works!
/// unborrow!(v.insert(v.len() - 1, v[0] + 41));
/// assert_eq!(v, [1, 2, 42, 3]);
///
/// // it also works for nested objects!
/// struct Wrapper { v: Vec<i32> }
/// let mut w = Wrapper { v: vec![1, 2, 3] };
/// unborrow!(w.v.reserve(w.v.capacity()));
///
/// // ...and with free functions! (the first argument is assumed to be the mutable borrow)
/// use std::mem;
/// unborrow!(mem::replace(&mut v, v.clone()));
///
/// # }
/// ```
;
// Parse an argument and continue parsing
// This is the key rule, assigning a name for the argument and generating the let statement.
=> ;
// Output stage for free functions.
// Assembles the let statements and variable names into a block which computes the arguments,
// calls the method, and returns its result.
=> ;
// Output stage for object methods.
=> ;
// =========================================================================================================
// PUBLIC RULES
// Macro entry point for object methods.
=> ;
// Macro entry point for free functions.
=> ;
}