diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2016-05-19 21:21:05 +0530 |
|---|---|---|
| committer | Manish Goregaokar <manishsmail@gmail.com> | 2016-05-19 21:21:05 +0530 |
| commit | e4f33d5ae789b6081b73a125d3a847cd5d43b5c8 (patch) | |
| tree | fa186c7c5138d0ed015741b69791a1b95f5bb60c | |
| parent | c9ca735a7b34cbe38e8ccc58d89d7a49c5b68ee2 (diff) | |
| parent | 64feba03d76641a8eb290f3f8409d6be04b3fe11 (diff) | |
| download | rust-e4f33d5ae789b6081b73a125d3a847cd5d43b5c8.tar.gz rust-e4f33d5ae789b6081b73a125d3a847cd5d43b5c8.zip | |
Rollup merge of #33611 - vvanders:master, r=steveklabnik
Add a note about Higher-Ranked Trait Bounds in docs on Closures. I hit a snag with lifetimes a few days ago and it wasn't until @birkenfeld pointed out Higher-Ranked Trait Bounds that I was able to solve the issue involving lifetimes on closure traits. This adds a small section in the book so that other users can find it. r? @steveklabnik
| -rw-r--r-- | src/doc/book/closures.md | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/doc/book/closures.md b/src/doc/book/closures.md index d81619b647f..e690f4edd47 100644 --- a/src/doc/book/closures.md +++ b/src/doc/book/closures.md @@ -319,6 +319,53 @@ assert_eq!(3, answer); Now we take a trait object, a `&Fn`. And we have to make a reference to our closure when we pass it to `call_with_one`, so we use `&||`. +A quick note about closures that use explicit lifetimes. Sometimes you might have a closure +that takes a reference like so: + +``` +fn call_with_ref<F>(some_closure:F) -> i32 + where F: Fn(&i32) -> i32 { + + let mut value = 0; + some_closure(&value) +} +``` + +Normally you can specify the lifetime of the parameter to our closure. We +could annotate it on the function declaration: + +```ignore +fn call_with_ref<'a, F>(some_closure:F) -> i32 + where F: Fn(&'a 32) -> i32 { +``` + +However this presents a problem with in our case. When you specify the explict +lifetime on a function it binds that lifetime to the *entire* scope of the function +instead of just the invocation scope of our closure. This means that the borrow checker +will see a mutable reference in the same lifetime as our immutable reference and fail +to compile. + +In order to say that we only need the lifetime to be valid for the invocation scope +of the closure we can use Higher-Ranked Trait Bounds with the `for<...>` syntax: + +```ignore +fn call_with_ref<F>(some_closure:F) -> i32 + where F: for<'a> Fn(&'a 32) -> i32 { +``` + +This lets the Rust compiler find the minimum lifetime to invoke our closure and +satisfy the borrow checker's rules. Our function then compiles and excutes as we +expect. + +``` +fn call_with_ref<F>(some_closure:F) -> i32 + where F: for<'a> Fn(&'a i32) -> i32 { + + let mut value = 0; + some_closure(&value) +} +``` + # Function pointers and closures A function pointer is kind of like a closure that has no environment. As such, |
