rustc_borrowck::DIAGNOSTICS [] [src]

pub const DIAGNOSTICS: [(&'static str, &'static str); 17usize] = [("E0373",
  "\nThis error occurs when an attempt is made to use data captured by a closure,\nwhen that data may no longer exist. It\'s most commonly seen when attempting to\nreturn a closure:\n\n```compile_fail\nfn foo() -> Box<Fn(u32) -> u32> {\n    let x = 0u32;\n    Box::new(|y| x + y)\n}\n```\n\nNotice that `x` is stack-allocated by `foo()`. By default, Rust captures\nclosed-over data by reference. This means that once `foo()` returns, `x` no\nlonger exists. An attempt to access `x` within the closure would thus be\nunsafe.\n\nAnother situation where this might be encountered is when spawning threads:\n\n```compile_fail\nfn foo() {\n    let x = 0u32;\n    let y = 1u32;\n\n    let thr = std::thread::spawn(|| {\n        x + y\n    });\n}\n```\n\nSince our new thread runs in parallel, the stack frame containing `x` and `y`\nmay well have disappeared by the time we try to use them. Even if we call\n`thr.join()` within foo (which blocks until `thr` has completed, ensuring the\nstack frame won\'t disappear), we will not succeed: the compiler cannot prove\nthat this behaviour is safe, and so won\'t let us do it.\n\nThe solution to this problem is usually to switch to using a `move` closure.\nThis approach moves (or copies, where possible) data into the closure, rather\nthan taking references to it. For example:\n\n```\nfn foo() -> Box<Fn(u32) -> u32> {\n    let x = 0u32;\n    Box::new(move |y| x + y)\n}\n```\n\nNow that the closure has its own copy of the data, there\'s no need to worry\nabout safety.\n"),
 ("E0381",
  "\nIt is not allowed to use or capture an uninitialized variable. For example:\n\n```compile_fail\nfn main() {\n    let x: i32;\n    let y = x; // error, use of possibly uninitialized variable\n}\n```\n\nTo fix this, ensure that any declared variables are initialized before being\nused. Example:\n\n```\nfn main() {\n    let x: i32 = 0;\n    let y = x; // ok!\n}\n```\n"),
 ("E0382",
  "\nThis error occurs when an attempt is made to use a variable after its contents\nhave been moved elsewhere. For example:\n\n```compile_fail\nstruct MyStruct { s: u32 }\n\nfn main() {\n    let mut x = MyStruct{ s: 5u32 };\n    let y = x;\n    x.s = 6;\n    println!(\"{}\", x.s);\n}\n```\n\nSince `MyStruct` is a type that is not marked `Copy`, the data gets moved out\nof `x` when we set `y`. This is fundamental to Rust\'s ownership system: outside\nof workarounds like `Rc`, a value cannot be owned by more than one variable.\n\nIf we own the type, the easiest way to address this problem is to implement\n`Copy` and `Clone` on it, as shown below. This allows `y` to copy the\ninformation in `x`, while leaving the original version owned by `x`. Subsequent\nchanges to `x` will not be reflected when accessing `y`.\n\n```\n#[derive(Copy, Clone)]\nstruct MyStruct { s: u32 }\n\nfn main() {\n    let mut x = MyStruct{ s: 5u32 };\n    let y = x;\n    x.s = 6;\n    println!(\"{}\", x.s);\n}\n```\n\nAlternatively, if we don\'t control the struct\'s definition, or mutable shared\nownership is truly required, we can use `Rc` and `RefCell`:\n\n```\nuse std::cell::RefCell;\nuse std::rc::Rc;\n\nstruct MyStruct { s: u32 }\n\nfn main() {\n    let mut x = Rc::new(RefCell::new(MyStruct{ s: 5u32 }));\n    let y = x.clone();\n    x.borrow_mut().s = 6;\n    println!(\"{}\", x.borrow().s);\n}\n```\n\nWith this approach, x and y share ownership of the data via the `Rc` (reference\ncount type). `RefCell` essentially performs runtime borrow checking: ensuring\nthat at most one writer or multiple readers can access the data at any one time.\n\nIf you wish to learn more about ownership in Rust, start with the chapter in the\nBook:\n\nhttps://doc.rust-lang.org/book/ownership.html\n"),
 ("E0383",
  "\nThis error occurs when an attempt is made to partially reinitialize a\nstructure that is currently uninitialized.\n\nFor example, this can happen when a drop has taken place:\n\n```compile_fail\nstruct Foo {\n    a: u32,\n}\n\nlet mut x = Foo { a: 1 };\ndrop(x); // `x` is now uninitialized\nx.a = 2; // error, partial reinitialization of uninitialized structure `t`\n```\n\nThis error can be fixed by fully reinitializing the structure in question:\n\n```\nstruct Foo {\n    a: u32,\n}\n\nlet mut x = Foo { a: 1 };\ndrop(x);\nx = Foo { a: 2 };\n```\n"),
 ("E0384",
  "\nThis error occurs when an attempt is made to reassign an immutable variable.\nFor example:\n\n```compile_fail\nfn main(){\n    let x = 3;\n    x = 5; // error, reassignment of immutable variable\n}\n```\n\nBy default, variables in Rust are immutable. To fix this error, add the keyword\n`mut` after the keyword `let` when declaring the variable. For example:\n\n```\nfn main(){\n    let mut x = 3;\n    x = 5;\n}\n```\n"),
 ("E0386",
  "\nThis error occurs when an attempt is made to mutate the target of a mutable\nreference stored inside an immutable container.\n\nFor example, this can happen when storing a `&mut` inside an immutable `Box`:\n\n```compile_fail\nlet mut x: i64 = 1;\nlet y: Box<_> = Box::new(&mut x);\n**y = 2; // error, cannot assign to data in an immutable container\n```\n\nThis error can be fixed by making the container mutable:\n\n```\nlet mut x: i64 = 1;\nlet mut y: Box<_> = Box::new(&mut x);\n**y = 2;\n```\n\nIt can also be fixed by using a type with interior mutability, such as `Cell`\nor `RefCell`:\n\n```\nuse std::cell::Cell;\n\nlet x: i64 = 1;\nlet y: Box<Cell<_>> = Box::new(Cell::new(x));\ny.set(2);\n```\n"),
 ("E0387",
  "\nThis error occurs when an attempt is made to mutate or mutably reference data\nthat a closure has captured immutably. Examples of this error are shown below:\n\n```compile_fail\n// Accepts a function or a closure that captures its environment immutably.\n// Closures passed to foo will not be able to mutate their closed-over state.\nfn foo<F: Fn()>(f: F) { }\n\n// Attempts to mutate closed-over data. Error message reads:\n// `cannot assign to data in a captured outer variable...`\nfn mutable() {\n    let mut x = 0u32;\n    foo(|| x = 2);\n}\n\n// Attempts to take a mutable reference to closed-over data.  Error message\n// reads: `cannot borrow data mutably in a captured outer variable...`\nfn mut_addr() {\n    let mut x = 0u32;\n    foo(|| { let y = &mut x; });\n}\n```\n\nThe problem here is that foo is defined as accepting a parameter of type `Fn`.\nClosures passed into foo will thus be inferred to be of type `Fn`, meaning that\nthey capture their context immutably.\n\nIf the definition of `foo` is under your control, the simplest solution is to\ncapture the data mutably. This can be done by defining `foo` to take FnMut\nrather than Fn:\n\n```\nfn foo<F: FnMut()>(f: F) { }\n```\n\nAlternatively, we can consider using the `Cell` and `RefCell` types to achieve\ninterior mutability through a shared reference. Our example\'s `mutable`\nfunction could be redefined as below:\n\n```\nuse std::cell::Cell;\n\nfn foo<F: Fn()>(f: F) { }\n\nfn mutable() {\n    let x = Cell::new(0u32);\n    foo(|| x.set(2));\n}\n```\n\nYou can read more about cell types in the API documentation:\n\nhttps://doc.rust-lang.org/std/cell/\n"),
 ("E0389",
  "\nAn attempt was made to mutate data using a non-mutable reference. This\ncommonly occurs when attempting to assign to a non-mutable reference of a\nmutable reference (`&(&mut T)`).\n\nExample of erroneous code:\n\n```compile_fail\nstruct FancyNum {\n    num: u8\n}\n\nfn main() {\n    let mut fancy = FancyNum{ num: 5 };\n    let fancy_ref = &(&mut fancy);\n    fancy_ref.num = 6; // error: cannot assign to data in a `&` reference\n    println!(\"{}\", fancy_ref.num);\n}\n```\n\nHere, `&mut fancy` is mutable, but `&(&mut fancy)` is not. Creating an\nimmutable reference to a value borrows it immutably. There can be multiple\nreferences of type `&(&mut T)` that point to the same value, so they must be\nimmutable to prevent multiple mutable references to the same value.\n\nTo fix this, either remove the outer reference:\n\n```\nstruct FancyNum {\n    num: u8\n}\n\nfn main() {\n    let mut fancy = FancyNum{ num: 5 };\n\n    let fancy_ref = &mut fancy;\n    // `fancy_ref` is now &mut FancyNum, rather than &(&mut FancyNum)\n\n    fancy_ref.num = 6; // No error!\n\n    println!(\"{}\", fancy_ref.num);\n}\n```\n\nOr make the outer reference mutable:\n\n```\nstruct FancyNum {\n    num: u8\n}\n\nfn main() {\n    let mut fancy = FancyNum{ num: 5 };\n\n    let fancy_ref = &mut (&mut fancy);\n    // `fancy_ref` is now &mut(&mut FancyNum), rather than &(&mut FancyNum)\n\n    fancy_ref.num = 6; // No error!\n\n    println!(\"{}\", fancy_ref.num);\n}\n```\n"),
 ("E0499",
  "\nA variable was borrowed as mutable more than once. Erroneous code example:\n\n```compile_fail\nlet mut i = 0;\nlet mut x = &mut i;\nlet mut a = &mut i;\n// error: cannot borrow `i` as mutable more than once at a time\n```\n\nPlease note that in rust, you can either have many immutable references, or one\nmutable reference. Take a look at\nhttps://doc.rust-lang.org/stable/book/references-and-borrowing.html for more\ninformation. Example:\n\n\n```\nlet mut i = 0;\nlet mut x = &mut i; // ok!\n\n// or:\nlet mut i = 0;\nlet a = &i; // ok!\nlet b = &i; // still ok!\nlet c = &i; // still ok!\n```\n"),
 ("E0500",
  "\nA borrowed variable was used in another closure. Example of erroneous code:\n\n```compile_fail\nfn you_know_nothing(jon_snow: &mut i32) {\n    let nights_watch = || {\n        *jon_snow = 2;\n    };\n    let starks = || {\n        *jon_snow = 3; // error: closure requires unique access to `jon_snow`\n                       //        but it is already borrowed\n    };\n}\n```\n\nIn here, `jon_snow` is already borrowed by the `nights_watch` closure, so it\ncannot be borrowed by the `starks` closure at the same time. To fix this issue,\nyou can put the closure in its own scope:\n\n```\nfn you_know_nothing(jon_snow: &mut i32) {\n    {\n        let nights_watch = || {\n            *jon_snow = 2;\n        };\n    } // At this point, `jon_snow` is free.\n    let starks = || {\n        *jon_snow = 3;\n    };\n}\n```\n\nOr, if the type implements the `Clone` trait, you can clone it between\nclosures:\n\n```\nfn you_know_nothing(jon_snow: &mut i32) {\n    let mut jon_copy = jon_snow.clone();\n    let nights_watch = || {\n        jon_copy = 2;\n    };\n    let starks = || {\n        *jon_snow = 3;\n    };\n}\n```\n"),
 ("E0501",
  "\nThis error indicates that a mutable variable is being used while it is still\ncaptured by a closure. Because the closure has borrowed the variable, it is not\navailable for use until the closure goes out of scope.\n\nNote that a capture will either move or borrow a variable, but in this\nsituation, the closure is borrowing the variable. Take a look at\nhttp://rustbyexample.com/fn/closures/capture.html for more information about\ncapturing.\n\nExample of erroneous code:\n\n```compile_fail\nfn inside_closure(x: &mut i32) {\n    // Actions which require unique access\n}\n\nfn outside_closure(x: &mut i32) {\n    // Actions which require unique access\n}\n\nfn foo(a: &mut i32) {\n    let bar = || {\n        inside_closure(a)\n    };\n    outside_closure(a); // error: cannot borrow `*a` as mutable because previous\n                        //        closure requires unique access.\n}\n```\n\nTo fix this error, you can place the closure in its own scope:\n\n```\nfn inside_closure(x: &mut i32) {}\nfn outside_closure(x: &mut i32) {}\n\nfn foo(a: &mut i32) {\n    {\n        let bar = || {\n            inside_closure(a)\n        };\n    } // borrow on `a` ends.\n    outside_closure(a); // ok!\n}\n```\n\nOr you can pass the variable as a parameter to the closure:\n\n```\nfn inside_closure(x: &mut i32) {}\nfn outside_closure(x: &mut i32) {}\n\nfn foo(a: &mut i32) {\n    let bar = |s: &mut i32| {\n        inside_closure(s)\n    };\n    outside_closure(a);\n    bar(a);\n}\n```\n\nIt may be possible to define the closure later:\n\n```\nfn inside_closure(x: &mut i32) {}\nfn outside_closure(x: &mut i32) {}\n\nfn foo(a: &mut i32) {\n    outside_closure(a);\n    let bar = || {\n        inside_closure(a)\n    };\n}\n```\n"),
 ("E0502",
  "\nThis error indicates that you are trying to borrow a variable as mutable when it\nhas already been borrowed as immutable.\n\nExample of erroneous code:\n\n```compile_fail\nfn bar(x: &mut i32) {}\nfn foo(a: &mut i32) {\n    let ref y = a; // a is borrowed as immutable.\n    bar(a); // error: cannot borrow `*a` as mutable because `a` is also borrowed\n            //        as immutable\n}\n```\nTo fix this error, ensure that you don\'t have any other references to the\nvariable before trying to access it mutably:\n```\nfn bar(x: &mut i32) {}\nfn foo(a: &mut i32) {\n    bar(a);\n    let ref y = a; // ok!\n}\n```\nFor more information on the rust ownership system, take a look at\nhttps://doc.rust-lang.org/stable/book/references-and-borrowing.html.\n"),
 ("E0504",
  "\nThis error occurs when an attempt is made to move a borrowed variable into a\nclosure.\n\nExample of erroneous code:\n\n```compile_fail\nstruct FancyNum {\n    num: u8\n}\n\nfn main() {\n    let fancy_num = FancyNum { num: 5 };\n    let fancy_ref = &fancy_num;\n\n    let x = move || {\n        println!(\"child function: {}\", fancy_num.num);\n        // error: cannot move `fancy_num` into closure because it is borrowed\n    };\n\n    x();\n    println!(\"main function: {}\", fancy_ref.num);\n}\n```\n\nHere, `fancy_num` is borrowed by `fancy_ref` and so cannot be moved into\nthe closure `x`. There is no way to move a value into a closure while it is\nborrowed, as that would invalidate the borrow.\n\nIf the closure can\'t outlive the value being moved, try using a reference\nrather than moving:\n\n```\nstruct FancyNum {\n    num: u8\n}\n\nfn main() {\n    let fancy_num = FancyNum { num: 5 };\n    let fancy_ref = &fancy_num;\n\n    let x = move || {\n        // fancy_ref is usable here because it doesn\'t move `fancy_num`\n        println!(\"child function: {}\", fancy_ref.num);\n    };\n\n    x();\n\n    println!(\"main function: {}\", fancy_num.num);\n}\n```\n\nIf the value has to be borrowed and then moved, try limiting the lifetime of\nthe borrow using a scoped block:\n\n```\nstruct FancyNum {\n    num: u8\n}\n\nfn main() {\n    let fancy_num = FancyNum { num: 5 };\n\n    {\n        let fancy_ref = &fancy_num;\n        println!(\"main function: {}\", fancy_ref.num);\n        // `fancy_ref` goes out of scope here\n    }\n\n    let x = move || {\n        // `fancy_num` can be moved now (no more references exist)\n        println!(\"child function: {}\", fancy_num.num);\n    };\n\n    x();\n}\n```\n\nIf the lifetime of a reference isn\'t enough, such as in the case of threading,\nconsider using an `Arc` to create a reference-counted value:\n\n```\nuse std::sync::Arc;\nuse std::thread;\n\nstruct FancyNum {\n    num: u8\n}\n\nfn main() {\n    let fancy_ref1 = Arc::new(FancyNum { num: 5 });\n    let fancy_ref2 = fancy_ref1.clone();\n\n    let x = thread::spawn(move || {\n        // `fancy_ref1` can be moved and has a `\'static` lifetime\n        println!(\"child thread: {}\", fancy_ref1.num);\n    });\n\n    x.join().expect(\"child thread should finish\");\n    println!(\"main thread: {}\", fancy_ref2.num);\n}\n```\n"),
 ("E0506",
  "\nThis error occurs when an attempt is made to assign to a borrowed value.\n\nExample of erroneous code:\n\n```compile_fail\nstruct FancyNum {\n    num: u8\n}\n\nfn main() {\n    let mut fancy_num = FancyNum { num: 5 };\n    let fancy_ref = &fancy_num;\n    fancy_num = FancyNum { num: 6 };\n    // error: cannot assign to `fancy_num` because it is borrowed\n\n    println!(\"Num: {}, Ref: {}\", fancy_num.num, fancy_ref.num);\n}\n```\n\nBecause `fancy_ref` still holds a reference to `fancy_num`, `fancy_num` can\'t\nbe assigned to a new value as it would invalidate the reference.\n\nAlternatively, we can move out of `fancy_num` into a second `fancy_num`:\n\n```\nstruct FancyNum {\n    num: u8\n}\n\nfn main() {\n    let mut fancy_num = FancyNum { num: 5 };\n    let moved_num = fancy_num;\n    fancy_num = FancyNum { num: 6 };\n\n    println!(\"Num: {}, Moved num: {}\", fancy_num.num, moved_num.num);\n}\n```\n\nIf the value has to be borrowed, try limiting the lifetime of the borrow using\na scoped block:\n\n```\nstruct FancyNum {\n    num: u8\n}\n\nfn main() {\n    let mut fancy_num = FancyNum { num: 5 };\n\n    {\n        let fancy_ref = &fancy_num;\n        println!(\"Ref: {}\", fancy_ref.num);\n    }\n\n    // Works because `fancy_ref` is no longer in scope\n    fancy_num = FancyNum { num: 6 };\n    println!(\"Num: {}\", fancy_num.num);\n}\n```\n\nOr by moving the reference into a function:\n\n```\nstruct FancyNum {\n    num: u8\n}\n\nfn main() {\n    let mut fancy_num = FancyNum { num: 5 };\n\n    print_fancy_ref(&fancy_num);\n\n    // Works because function borrow has ended\n    fancy_num = FancyNum { num: 6 };\n    println!(\"Num: {}\", fancy_num.num);\n}\n\nfn print_fancy_ref(fancy_ref: &FancyNum){\n    println!(\"Ref: {}\", fancy_ref.num);\n}\n```\n"),
 ("E0505",
  "\nA value was moved out while it was still borrowed.\nErroneous code example:\n\n```compile_fail\nstruct Value {}\n\nfn eat(val: Value) {}\n\nfn main() {\n    let x = Value{};\n    {\n        let _ref_to_val: &Value = &x;\n        eat(x);\n    }\n}\n```\n\nHere, the function `eat` takes the ownership of `x`. However,\n`x` cannot be moved because it was borrowed to `_ref_to_val`.\nTo fix that you can do few different things:\n\n* Try to avoid moving the variable.\n* Release borrow before move.\n* Implement the `Copy` trait on the type.\n\nExamples:\n\n```\nstruct Value {}\n\nfn eat(val: &Value) {}\n\nfn main() {\n    let x = Value{};\n    {\n        let _ref_to_val: &Value = &x;\n        eat(&x); // pass by reference, if it\'s possible\n    }\n}\n```\n\nOr:\n\n```\nstruct Value {}\n\nfn eat(val: Value) {}\n\nfn main() {\n    let x = Value{};\n    {\n        let _ref_to_val: &Value = &x;\n    }\n    eat(x); // release borrow and then move it.\n}\n```\n\nOr:\n\n```\n#[derive(Clone, Copy)] // implement Copy trait\nstruct Value {}\n\nfn eat(val: Value) {}\n\nfn main() {\n    let x = Value{};\n    {\n        let _ref_to_val: &Value = &x;\n        eat(x); // it will be copied here.\n    }\n}\n```\n\nYou can find more information about borrowing in the rust-book:\nhttp://doc.rust-lang.org/stable/book/references-and-borrowing.html\n"),
 ("E0507",
  "\nYou tried to move out of a value which was borrowed. Erroneous code example:\n\n```compile_fail\nuse std::cell::RefCell;\n\nstruct TheDarkKnight;\n\nimpl TheDarkKnight {\n    fn nothing_is_true(self) {}\n}\n\nfn main() {\n    let x = RefCell::new(TheDarkKnight);\n\n    x.borrow().nothing_is_true(); // error: cannot move out of borrowed content\n}\n```\n\nHere, the `nothing_is_true` method takes the ownership of `self`. However,\n`self` cannot be moved because `.borrow()` only provides an `&TheDarkKnight`,\nwhich is a borrow of the content owned by the `RefCell`. To fix this error,\nyou have three choices:\n\n* Try to avoid moving the variable.\n* Somehow reclaim the ownership.\n* Implement the `Copy` trait on the type.\n\nExamples:\n\n```\nuse std::cell::RefCell;\n\nstruct TheDarkKnight;\n\nimpl TheDarkKnight {\n    fn nothing_is_true(&self) {} // First case, we don\'t take ownership\n}\n\nfn main() {\n    let x = RefCell::new(TheDarkKnight);\n\n    x.borrow().nothing_is_true(); // ok!\n}\n```\n\nOr:\n\n```\nuse std::cell::RefCell;\n\nstruct TheDarkKnight;\n\nimpl TheDarkKnight {\n    fn nothing_is_true(self) {}\n}\n\nfn main() {\n    let x = RefCell::new(TheDarkKnight);\n    let x = x.into_inner(); // we get back ownership\n\n    x.nothing_is_true(); // ok!\n}\n```\n\nOr:\n\n```\nuse std::cell::RefCell;\n\n#[derive(Clone, Copy)] // we implement the Copy trait\nstruct TheDarkKnight;\n\nimpl TheDarkKnight {\n    fn nothing_is_true(self) {}\n}\n\nfn main() {\n    let x = RefCell::new(TheDarkKnight);\n\n    x.borrow().nothing_is_true(); // ok!\n}\n```\n\nMoving out of a member of a mutably borrowed struct is fine if you put something\nback. `mem::replace` can be used for that:\n\n```ignore\nstruct TheDarkKnight;\n\nimpl TheDarkKnight {\n    fn nothing_is_true(self) {}\n}\n\nstruct Batcave {\n    knight: TheDarkKnight\n}\n\nfn main() {\n    use std::mem;\n\n    let mut cave = Batcave {\n        knight: TheDarkKnight\n    };\n    let borrowed = &mut cave;\n\n    borrowed.knight.nothing_is_true(); // E0507\n    mem::replace(&mut borrowed.knight, TheDarkKnight).nothing_is_true(); // ok!\n}\n```\n\nYou can find more information about borrowing in the rust-book:\nhttp://doc.rust-lang.org/stable/book/references-and-borrowing.html\n"),
 ("E0509",
  "\nThis error occurs when an attempt is made to move out of a value whose type\nimplements the `Drop` trait.\n\nExample of erroneous code:\n\n```compile_fail\nstruct FancyNum {\n    num: usize\n}\n\nstruct DropStruct {\n    fancy: FancyNum\n}\n\nimpl Drop for DropStruct {\n    fn drop(&mut self) {\n        // Destruct DropStruct, possibly using FancyNum\n    }\n}\n\nfn main() {\n    let drop_struct = DropStruct{fancy: FancyNum{num: 5}};\n    let fancy_field = drop_struct.fancy; // Error E0509\n    println!(\"Fancy: {}\", fancy_field.num);\n    // implicit call to `drop_struct.drop()` as drop_struct goes out of scope\n}\n```\n\nHere, we tried to move a field out of a struct of type `DropStruct` which\nimplements the `Drop` trait. However, a struct cannot be dropped if one or\nmore of its fields have been moved.\n\nStructs implementing the `Drop` trait have an implicit destructor that gets\ncalled when they go out of scope. This destructor may use the fields of the\nstruct, so moving out of the struct could make it impossible to run the\ndestructor. Therefore, we must think of all values whose type implements the\n`Drop` trait as single units whose fields cannot be moved.\n\nThis error can be fixed by creating a reference to the fields of a struct,\nenum, or tuple using the `ref` keyword:\n\n```\nstruct FancyNum {\n    num: usize\n}\n\nstruct DropStruct {\n    fancy: FancyNum\n}\n\nimpl Drop for DropStruct {\n    fn drop(&mut self) {\n        // Destruct DropStruct, possibly using FancyNum\n    }\n}\n\nfn main() {\n    let drop_struct = DropStruct{fancy: FancyNum{num: 5}};\n    let ref fancy_field = drop_struct.fancy; // No more errors!\n    println!(\"Fancy: {}\", fancy_field.num);\n    // implicit call to `drop_struct.drop()` as drop_struct goes out of scope\n}\n```\n\nNote that this technique can also be used in the arms of a match expression:\n\n```\nstruct FancyNum {\n    num: usize\n}\n\nenum DropEnum {\n    Fancy(FancyNum)\n}\n\nimpl Drop for DropEnum {\n    fn drop(&mut self) {\n        // Destruct DropEnum, possibly using FancyNum\n    }\n}\n\nfn main() {\n    // Creates and enum of type `DropEnum`, which implements `Drop`\n    let drop_enum = DropEnum::Fancy(FancyNum{num: 10});\n    match drop_enum {\n        // Creates a reference to the inside of `DropEnum::Fancy`\n        DropEnum::Fancy(ref fancy_field) => // No error!\n            println!(\"It was fancy-- {}!\", fancy_field.num),\n    }\n    // implicit call to `drop_enum.drop()` as drop_enum goes out of scope\n}\n```\n")]
Unstable (rustc_private)