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
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/// # NLL: 非词法作用域生命周期
///
/// 以下代码目前在 Rust 2015版本中 会出错,但是选择Rust 2018 edition将正常编译
///   可以去play.rust-lang.org选择2018 edtion版本尝试
///
/// Base usage: 案例1
/// ```rust
/// struct Foo;
///
/// impl Foo {
///     fn mutate_and_share(&mut self) -> &Self { &*self }
///     fn share(&self) {}
/// }
/// let mut foo = Foo;
/// let loan = foo.mutate_and_share();
/// foo.share();
/// ```
///
/// Base usage: 案例2
/// ```rust
/// fn foo<'a>(x: &'a str, y: &'a str) -> &'a str {
///     if x.len() % 2 == 0 {
///         x
///     } else {
///         y
///     }
/// }
/// fn main(){
///     let x = String::from("hello");
///     let z;
///     let y = String::from("world");
///     z = foo(&x, &y);
///     println!("{:?}", z);
/// }
/// ```
///
/// Base usage: 案例3
/// ```rust
/// fn capitalize(data: &mut [char]) {
///     // do something
/// }
/// fn bar() {
///     let mut data = vec!['a', 'b', 'c'];
///     let slice = &mut data[..]; // <-+ 'lifetime
///     capitalize(slice);         //   |
///     data.push('d'); // ERROR!  //   |
///     data.push('e'); // ERROR!  //   |
///     data.push('f'); // ERROR!  //   |
/// } // <------------------------------+
/// ```
///
/// Base usage: 案例4,目前NLL解决不了的问题
/// ```rust
/// fn get_default<'r,K:Hash+Eq+Copy,V:Default>(map: &'r mut HashMap<K,V>,
///                                             key: K)
///                                             -> &'r mut V {
///     match map.get_mut(&key) { // -------------+ 'r
///         Some(value) => value,              // |
///         None => {                          // |
///             map.insert(key, V::default()); // |
///             //  ^~~~~~ ERROR               // |
///             map.get_mut(&key).unwrap()     // |
///         }                                  // |
///     }                                      // |
/// }                                          // v
/// ```
///
/// Base usage: 案例4修正
/// ```rust
/// fn get_default2<'r,K:Hash+Eq+Copy,V:Default>(map: &'r mut HashMap<K,V>,
///                                              key: K)
///                                              -> &'r mut V {
///     if map.contains_key(&key) {
///     // ^~~~~~~~~~~~~~~~~~ 'n
///         return match map.get_mut(&key) { // + 'r
///             Some(value) => value,        // |
///             None => unreachable!()       // |
///         };                               // v
///     }
///
///     // At this point, `map.get_mut` was never
///     // called! (As opposed to having been called,
///     // but its result no longer being in use.)
///     map.insert(key, V::default()); // OK now.
///     map.get_mut(&key).unwrap()
/// }
/// ```
///
/// Base usage: 案例5 无限循环
/// ```rust
/// struct List<T> {
///     value: T,
///     next: Option<Box<List<T>>>,
/// }
///
/// fn to_refs<T>(mut list: &mut List<T>) -> Vec<&mut T> {
///     let mut result = vec![];
///     loop {
///         result.push(&mut list.value);
///         if let Some(n) = list.next.as_mut() {
///             list = n;
///         } else {
///             return result;
///         }
///     }
/// }
/// ```
///
/// Base usage: 案例6, NLL目前还未解决
/// ```rust
/// fn main() {
///     let mut x = vec![1];
///     x.push(x.pop().unwrap());
/// }
/// ```
pub fn borrow_ck_problem(){
    fn foo<'a>(x: &'a str, y: &'a str) -> &'a str {
        if x.len() % 2 == 0 {
            x
        } else {
            y
        }
    }
    fn main(){
        let x = String::from("hello");
        let y = String::from("world");
        let z;
        z = foo(&x, &y);
        println!("{:?}", z);
    }

}

/// # MIR 介绍
///
/// Base usage: 用于生成MIR
/// ```rust
/// fn main(){
///     let a = "hello".to_string();
///     let s = " world";
///     a.to_string() + s;
/// }
/// ```
///
/// Base usage: 生成的MIR
/// ```rust
/// // MIR 解释
/// fn main() -> (){
///     let mut _0: ();         // 返回值
///     scope 1 {              // 第一个变量产生的顶级作用域,会包裹其他变量
///     }
///     scope 2 {             // a自己的作用域
///         let _1: i32;
///     }
///     let mut _2: i32;        // 临时值
///     let mut _3: i32;
///     let mut _4: (i32, bool);
///
///     bb0: {                 // 基础块
///         StorageLive(_1);   // 语句,代表活跃,给LLVM用来分配栈空间
///         _1 = const 1i32;  // 赋值
///
///         StorageLive(_3);
///         _3 = _1;        // 使用临时变量
///         // 执行Add操作,具有防溢出检查,
///         // 其中move代表move语义,编译器会自己判断是不是Copy
///         _4 = CheckedAdd(move _3, const 2i32);
///         // 断言,溢出时抛出错误,并且流向bb1块,此为终止句
///         assert(!move (_4.1: bool), "attempt to add with overflow") -> bb1;
///     }
///
///     bb1: {            // 基础块
///         _2 = move (_4.0: i32);     // 赋值,move为右值默认语义
///         StorageDead(_3);    // 语句,代表不活跃,给LLVM用来分配栈空间
///         StorageDead(_1);
///         return;             // 返回
///     }
/// }
/// ```
pub fn mir_explain(){
    fn main(){
        let a = "hello".to_string();
        let s = " world";
        a.to_string() + s;
    }
}