{"action":"created","comment":{"url":"https://api.github.com/repos/rust-lang/rust/pulls/comments/27040935","id":27040935,"diff_hunk":"@@ -1,214 +1,510 @@\n % Closures\n \n-So far, we've made lots of functions in Rust, but we've given them all names.\n-Rust also allows us to create anonymous functions. Rust's anonymous\n-functions are called *closures*. By themselves, closures aren't all that\n-interesting, but when you combine them with functions that take closures as\n-arguments, really powerful things are possible.\n+Rust has not only named functions, but anonymous functions as well. Anonymous\n+functions that have an associated environment are called 'closures,' and Rust\n+has a really great implementation of them, as we'll see.\n \n-Let's make a closure:\n+# Syntax\n \n-```{rust}\n-let add_one = |x| { 1 + x };\n+Closures look like this:\n \n-println!(\"The sum of 5 plus 1 is {}.\", add_one(5));\n+```rust\n+let plus_one = |x| x + 1;\n+\n+assert_eq!(2, plus_one(1));\n+```\n+\n+We create a binding, `plus_one`, and assign it to a closure. The closure's\n+arguments go between the pipes (`|`), and the body is an expression, in this\n+case, `x + 1`. Remember that `{ }` is an expression, so we can have multi-line\n+closures too:\n+\n+```rust\n+let plus_two = |x| {\n+    let mut result = x;\n+\n+    result += 1;\n+    result += 1;\n+\n+    result\n+};\n+\n+assert_eq!(4, plus_two(2));\n ```\n \n-We create a closure using the `|...| { ... }` syntax, and then we create a\n-binding so we can use it later. Note that we call the function using the\n-binding name and two parentheses, just like we would for a named function.\n+You'll notice a few things about closures that are a bit different than regular\n+functions defined with `fn`. The first of which is that we did not need to\n+annotate the types of arguments the closure takes or the values it returns. We\n+can:\n \n-Let's compare syntax. The two are pretty close:\n+```rust\n+let plus_one = |x: i32| -> i32 x + 1;\n \n-```{rust}\n-let add_one = |x: i32| -> i32 { 1 + x };\n-fn  add_one   (x: i32) -> i32 { 1 + x }\n+assert_eq!(2, plus_one(1));\n ```\n \n-As you may have noticed, closures infer their argument and return types, so you\n-don't need to declare one. This is different from named functions, which\n-default to returning unit (`()`).\n+But we don't have to. Why is this? Basically, it was chosen for ergonomic reasons.\n+While specifying the full type for named functions is helpful, closures aren't going\n+to, for example, appear in Rustdoc output somewhere. They don't cause the kinds of\n+error-at-a-distance that inferring named function types can. In practice, it\n+works well.\n \n-There's one big difference between a closure and named functions, and it's in\n-the name: a closure \"closes over its environment.\" What does that mean? It means\n-this:\n+The second is that the syntax is similar, but a bit different. I've added spaces\n+here to make them look a little closer:\n \n-```{rust}\n+```rust\n+fn  plus_1 (  x: i32 ) -> i32 { x + 1 }\n+let plus_2 = |x: i32 | -> i32 { x + 1 };\n+let plus_3 = |x      |          x + 1  ;\n+```\n+\n+Small differences, but they're similar in ways.\n+\n+# Closures and their environment\n+\n+As we said, closures are called such because they 'close over their environment.' It\n+looks like this:\n+\n+```rust\n+let num = 5;\n+let plus_num = |x| x + num;\n+\n+assert_eq!(10, plus_num(5));\n+```\n+\n+This closure, `plus_num`, refers to a `let` binding in its scope: `num`. More\n+specifically, it borrows the binding. If we do something that would conflict\n+with that binding, we get an error. Like this one:\n+\n+```rust,ignore\n+let mut num = 5;\n+let plus_num = |x| x + num;\n+\n+let y = &mut num;\n+```\n+\n+Which errors with:\n+\n+```text\n+error: cannot borrow `num` as mutable because it is also borrowed as immutable\n+    let y = &mut num;\n+                 ^~~\n+note: previous borrow of `num` occurs here due to use in closure; the immutable\n+  borrow prevents subsequent moves or mutable borrows of `num` until the borrow\n+  ends\n+    let plus_num = |x| x + num;\n+                   ^~~~~~~~~~~\n+note: previous borrow ends here\n fn main() {\n-    let x: i32 = 5;\n+    let mut num = 5;\n+    let plus_num = |x| x + num;\n+    \n+    let y = &mut num;\n+}\n+^\n+```\n+\n+A verbose yet helpful error message! As it says, we can't take a mutable borrow\n+on `num` because the closure is already borrowing it. If we let the closure go\n+out of scope, we can:\n+\n+```rust\n+let mut num = 5;\n+{\n+    let plus_num = |x| x + num;\n+\n+} // plus_num goes out of scope, borrow of num ends\n+\n+let y = &mut num;\n+```\n+\n+If your closure requires it, however, Rust will take ownership and move\n+the environment instead:\n \n-    let printer = || { println!(\"x is: {}\", x); };\n+```rust,ignore\n+let nums = vec![1, 2, 3];\n \n-    printer(); // prints \"x is: 5\"\n+let takes_nums = || nums;\n+\n+println!(\"{:?}\", nums);\n+```\n+\n+This gives us:\n+\n+```text\n+note: `nums` moved into closure environment here because it has type\n+  `[closure(()) -> collections::vec::Vec<i32>]`, which is non-copyable\n+let takes_nums = || nums;\n+                    ^~~~~~~\n+```\n+\n+`Vec<T>` has ownership over its contents, and therefore, when we refer to it\n+in our closure, we have to take ownership of `nums`. It's the same as if we'd\n+passed `nums` to a function that took ownership of it.\n+\n+## `move` closures\n+\n+We can force our closure to take ownership of its environment with the `move`\n+keyword:\n+\n+```rust\n+let num = 5;\n+\n+let owns_num = move |x| x + num;\n+```\n+\n+Now, even though the keyword is `move`, the variables follow normal move semantics.\n+In this case, `5` implements `Copy`, and so `owns_num` takes ownership of a copy\n+of `num`. So what's the difference?\n+\n+```rust\n+let mut num = 5;\n+\n+{ \n+    let mut add_num = |x| num += x;\n+\n+    add_num(5);\n }\n+\n+assert_eq!(10, num);\n ```\n \n-The `||` syntax means this is an anonymous closure that takes no arguments.\n-Without it, we'd just have a block of code in `{}`s.\n+So in this case, our closure took a mutable reference to `num`, and then when\n+we called `add_num`, it mutated the underlying value, as we'd expect.\n \n-In other words, a closure has access to variables in the scope where it's\n-defined. The closure borrows any variables it uses, so this will error:\n+If we change to a `move` closure, it's different:\n \n-```{rust,ignore}\n-fn main() {\n-    let mut x: i32 = 5;\n+```rust\n+let mut num = 5;\n \n-    let printer = || { println!(\"x is: {}\", x); };\n+{ \n+    let mut add_num = move |x| num += x;\n \n-    x = 6; // error: cannot assign to `x` because it is borrowed\n+    add_num(5);\n }\n+\n+assert_eq!(5, num);\n ```\n \n-## Moving closures\n+We only get `5`. Rather than taking a mutable borrow out on our `num`, we took\n+ownership of a copy.\n+\n+Another way to think about `move` closures: they give a closure its own stack\n+frame.  Without `move`, a closure may be tied to the stack frame that created\n+it, while a `move` closure is self-contained. This means that you cannot\n+generally return a non-`move` closure from a function, for example.\n+\n+But before we talk about taking and returning closures, we should talk some more\n+about the way that closures are implemented. As a systems language, Rust gives\n+you tons of control over what your code does, and closures are no different.\n \n-Rust has a second type of closure, called a *moving closure*. Moving\n-closures are indicated using the `move` keyword (e.g., `move || x *\n-x`). The difference between a moving closure and an ordinary closure\n-is that a moving closure always takes ownership of all variables that\n-it uses. Ordinary closures, in contrast, just create a reference into\n-the enclosing stack frame. Moving closures are most useful with Rust's\n-concurrency features, and so we'll just leave it at this for\n-now. We'll talk about them more in the \"Concurrency\" chapter of the book.\n+# Closure implementation\n \n-## Accepting closures as arguments\n+Rust's implementation of closures is a bit different than other languages. They\n+are effectively syntax sugar for traits. You'll want to make sure to have read\n+the [traits chapter][traits] before this one, as well as the chapter on [static\n+and dynamic dispatch][dispatch], which talks about trait objects.\n \n-Closures are most useful as an argument to another function. Here's an example:\n+[traits]: traits.html\n+[dispatch]: static-and-dynamic-dispatch.html\n \n-```{rust}\n-fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 {\n-    f(x) + f(x)\n+Got all that? Good.\n+\n+The key to understanding how closures work under the hood is something a bit\n+strange: `()` is an overloadable operator. From this, everything else clicks\n+into place. In Rust, we use the trait system to overload operators. `()` is no\n+different. We have three separate traits to overload `()` with:\n+\n+```rust\n+# mod foo {\n+pub trait Fn<Args> {\n+    type Output;\n+\n+    extern \"rust-call\" fn call(&self, args: Args) -> Self::Output;\n }\n \n-fn main() {\n-    let square = |x: i32| { x * x };\n+pub trait FnMut<Args> {\n+    type Output;\n+\n+    extern \"rust-call\" fn call_mut(&mut self, args: Args) -> Self::Output;\n+}\n \n-    twice(5, square); // evaluates to 50\n+pub trait FnOnce<Args> {\n+    type Output;\n+\n+    extern \"rust-call\" fn call_once(self, args: Args) -> Self::Output;\n }\n+# }\n ```\n \n-Let's break the example down, starting with `main`:\n+You'll notice that the primary difference between the three is `self`: `Fn`\n+takes `&self`, `FnMut` takes `Mut self`, and `FnOnce` takes `self`. This\n+covers all three kinds of `self` via the usual method call syntax. But we've\n+split them up into three traits, rather than having a single one. This gives\n+us a large amount of control over what kind of closures we can take.\n+\n+The `|| {}` syntax for closures is sugar for these three traits. For example,\n+when you create a closure like this:\n \n-```{rust}\n-let square = |x: i32| { x * x };\n+```rust\n+let num = 5;\n+let add_num = |x| x + num;\n+\n+add_num(1);\n ```\n \n-We've seen this before. We make a closure that takes an integer, and returns\n-its square.\n+Rust desugars that code to this code:\n \n-```{rust}\n-# fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 { f(x) + f(x) }\n-# let square = |x: i32| { x * x };\n-twice(5, square); // evaluates to 50\n ```\n+# #![feature(unboxed_closures)]\n \n-This line is more interesting. Here, we call our function, `twice`, and we pass\n-it two arguments: an integer, `5`, and our closure, `square`. This is just like\n-passing any other two variable bindings to a function, but if you've never\n-worked with closures before, it can seem a little complex. Just think: \"I'm\n-passing two variables: one is an i32, and one is a function.\"\n+struct ClosureEnvironment<'env> {\n+    num: &'env i32\n+}\n \n-Next, let's look at how `twice` is defined:\n+impl<'env> Fn<(i32,)> for ClosureEnvironment<'env> {\n+    type Output = i32;\n \n-```{rust,ignore}\n-fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 {\n+    extern \"rust-call\" fn call(&self, (x,): (i32,)) -> i32 {\n+        x + *self.num\n+    }\n+}\n+# fn main() {\n+let num = 5;\n+let env = ClosureEnvironment { num: &num };\n+\n+env.call((1,));\n+# }\n ```\n \n-`twice` takes two arguments, `x` and `f`. That's why we called it with two\n-arguments. `x` is an `i32`, we've done that a ton of times. `f` is a function,\n-though, and that function takes an `i32` and returns an `i32`. This is\n-what the requirement `Fn(i32) -> i32` for the type parameter `F` says.\n-Now `F` represents *any* function that takes an `i32` and returns an `i32`.\n+Whew! We create a new struct, `ClosureEnvironment`, and then implement `Fn` for\n+it. Instead of the `|| {}` syntax, we make a new `ClosureEnvironment` and then\n+call `call()` on it.\n+\n+Rust will generate a new `struct` and implement the correct `Fn`, `FnMut`, or\n+`FnOnce` trait for each closure you write. This means the name won't literally\n+be `ClosureEnvironment`, as it's unique per closure.\n \n-This is the most complicated function signature we've seen yet! Give it a read\n-a few times until you can see how it works. It takes a teeny bit of practice, and\n-then it's easy. The good news is that this kind of passing a closure around\n-can be very efficient. With all the type information available at compile-time\n-the compiler can do wonders.\n+# Taking closures as arguments\n \n-Finally, `twice` returns an `i32` as well.\n+Now that we know that closures are traits, we already know how to accept and\n+return closures: just like any other trait!\n \n-Okay, let's look at the body of `twice`:\n+This also means that we can choose static vs dynamic dispatch as well. First,\n+let's write a function which takes a closure, calls it, and returns the\n+result:\n \n-```{rust}\n-fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 {\n-  f(x) + f(x)\n+```rust\n+fn call_with_one<F>(some_closure: F) -> i32\n+    where F : Fn(i32) -> i32 {\n+\n+  some_closure(1)\n }\n+\n+let answer = call_with_one(|x| x + 2);\n+\n+assert_eq!(3, answer);\n ```\n \n-Since our closure is named `f`, we can call it just like we called our closures\n-before, and we pass in our `x` argument to each one, hence the name `twice`.\n+We pass our closure, `|x| x + 2`, to `call_with_one`. It just does what it\n+suggests: it calls the closure, giving it `1` as an argument.\n \n-If you do the math, `(5 * 5) + (5 * 5) == 50`, so that's the output we get.\n+Let's examine the signature of `call_with_one` in more depth:\n \n-Play around with this concept until you're comfortable with it. Rust's standard\n-library uses lots of closures where appropriate, so you'll be using\n-this technique a lot.\n+```rust\n+fn call_with_one<F>(some_closure: F) -> i32\n+#    where F : Fn(i32) -> i32 {\n+# some_closure(1) }\n+```\n \n-If we didn't want to give `square` a name, we could just define it inline.\n-This example is the same as the previous one:\n+We take one parameter, and it has the type `F`. We also return a `i32`. This part\n+isn't interesting. The next part is:\n \n-```{rust}\n-fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 {\n-    f(x) + f(x)\n-}\n+```rust\n+# fn call_with_one<F>(some_closure: F) -> i32\n+    where F : Fn(i32) -> i32 {\n+# some_closure(1) }\n+```\n \n-fn main() {\n-    twice(5, |x: i32| { x * x }); // evaluates to 50\n+Because `Fn` is a trait, we can bound our generic with it. In this case, our closure\n+takes a `i32` as an argument and returns an `i32`, and so the generic bound we use\n+is `Fn(i32) -> i32`.\n+\n+There's one other key point here: because we're bounding a generic with a\n+trait, this will get monomorphized, and therefore, we'll be doing static\n+dispatch into the closure. That's pretty neat. In many langauges, closures are\n+inherently heap allocated, and will always involve dynamic dispatch. In Rust,\n+we can stack allocate our closure environment, and statically dispatch the call.\n+\n+Of course, if we want dynamic dispatch, we can get that too. A trait object\n+handles this case, as usual:\n+\n+```rust\n+fn call_with_one(some_closure: &Fn(i32) -> i32) -> i32 {\n+  some_closure(1)","path":"src/doc/trpl/closures.md","position":442,"original_position":442,"commit_id":"a7aaa789a015f57a6b123112d557e2e588e68edb","original_commit_id":"a7aaa789a015f57a6b123112d557e2e588e68edb","user":{"login":"steveklabnik","id":27786,"avatar_url":"https://avatars.githubusercontent.com/u/27786?v=3","gravatar_id":"","url":"https://api.github.com/users/steveklabnik","html_url":"https://github.com/steveklabnik","followers_url":"https://api.github.com/users/steveklabnik/followers","following_url":"https://api.github.com/users/steveklabnik/following{/other_user}","gists_url":"https://api.github.com/users/steveklabnik/gists{/gist_id}","starred_url":"https://api.github.com/users/steveklabnik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/steveklabnik/subscriptions","organizations_url":"https://api.github.com/users/steveklabnik/orgs","repos_url":"https://api.github.com/users/steveklabnik/repos","events_url":"https://api.github.com/users/steveklabnik/events{/privacy}","received_events_url":"https://api.github.com/users/steveklabnik/received_events","type":"User","site_admin":false},"body":"roger","created_at":"2015-03-24T15:48:49Z","updated_at":"2015-03-24T15:48:49Z","html_url":"https://github.com/rust-lang/rust/pull/23568#discussion_r27040935","pull_request_url":"https://api.github.com/repos/rust-lang/rust/pulls/23568","_links":{"self":{"href":"https://api.github.com/repos/rust-lang/rust/pulls/comments/27040935"},"html":{"href":"https://github.com/rust-lang/rust/pull/23568#discussion_r27040935"},"pull_request":{"href":"https://api.github.com/repos/rust-lang/rust/pulls/23568"}}},"pull_request":{"url":"https://api.github.com/repos/rust-lang/rust/pulls/23568","id":31654045,"html_url":"https://github.com/rust-lang/rust/pull/23568","diff_url":"https://github.com/rust-lang/rust/pull/23568.diff","patch_url":"https://github.com/rust-lang/rust/pull/23568.patch","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/23568","number":23568,"state":"open","locked":false,"title":"Re-write closures chapter","user":{"login":"steveklabnik","id":27786,"avatar_url":"https://avatars.githubusercontent.com/u/27786?v=3","gravatar_id":"","url":"https://api.github.com/users/steveklabnik","html_url":"https://github.com/steveklabnik","followers_url":"https://api.github.com/users/steveklabnik/followers","following_url":"https://api.github.com/users/steveklabnik/following{/other_user}","gists_url":"https://api.github.com/users/steveklabnik/gists{/gist_id}","starred_url":"https://api.github.com/users/steveklabnik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/steveklabnik/subscriptions","organizations_url":"https://api.github.com/users/steveklabnik/orgs","repos_url":"https://api.github.com/users/steveklabnik/repos","events_url":"https://api.github.com/users/steveklabnik/events{/privacy}","received_events_url":"https://api.github.com/users/steveklabnik/received_events","type":"User","site_admin":false},"body":"[rendered](https://github.com/steveklabnik/rust/blob/closure_docs/src/doc/trpl/closures.md)\r\n\r\nr? @nikomatsakis ","created_at":"2015-03-20T21:36:06Z","updated_at":"2015-03-24T15:48:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0be72546fdf7c58492b2b20551b0dd6a4d73810d","assignee":{"login":"nikomatsakis","id":155238,"avatar_url":"https://avatars.githubusercontent.com/u/155238?v=3","gravatar_id":"","url":"https://api.github.com/users/nikomatsakis","html_url":"https://github.com/nikomatsakis","followers_url":"https://api.github.com/users/nikomatsakis/followers","following_url":"https://api.github.com/users/nikomatsakis/following{/other_user}","gists_url":"https://api.github.com/users/nikomatsakis/gists{/gist_id}","starred_url":"https://api.github.com/users/nikomatsakis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nikomatsakis/subscriptions","organizations_url":"https://api.github.com/users/nikomatsakis/orgs","repos_url":"https://api.github.com/users/nikomatsakis/repos","events_url":"https://api.github.com/users/nikomatsakis/events{/privacy}","received_events_url":"https://api.github.com/users/nikomatsakis/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/rust-lang/rust/pulls/23568/commits","review_comments_url":"https://api.github.com/repos/rust-lang/rust/pulls/23568/comments","review_comment_url":"https://api.github.com/repos/rust-lang/rust/pulls/comments{/number}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/23568/comments","statuses_url":"https://api.github.com/repos/rust-lang/rust/statuses/a7aaa789a015f57a6b123112d557e2e588e68edb","head":{"label":"steveklabnik:closure_docs","ref":"closure_docs","sha":"a7aaa789a015f57a6b123112d557e2e588e68edb","user":{"login":"steveklabnik","id":27786,"avatar_url":"https://avatars.githubusercontent.com/u/27786?v=3","gravatar_id":"","url":"https://api.github.com/users/steveklabnik","html_url":"https://github.com/steveklabnik","followers_url":"https://api.github.com/users/steveklabnik/followers","following_url":"https://api.github.com/users/steveklabnik/following{/other_user}","gists_url":"https://api.github.com/users/steveklabnik/gists{/gist_id}","starred_url":"https://api.github.com/users/steveklabnik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/steveklabnik/subscriptions","organizations_url":"https://api.github.com/users/steveklabnik/orgs","repos_url":"https://api.github.com/users/steveklabnik/repos","events_url":"https://api.github.com/users/steveklabnik/events{/privacy}","received_events_url":"https://api.github.com/users/steveklabnik/received_events","type":"User","site_admin":false},"repo":{"id":7349289,"name":"rust","full_name":"steveklabnik/rust","owner":{"login":"steveklabnik","id":27786,"avatar_url":"https://avatars.githubusercontent.com/u/27786?v=3","gravatar_id":"","url":"https://api.github.com/users/steveklabnik","html_url":"https://github.com/steveklabnik","followers_url":"https://api.github.com/users/steveklabnik/followers","following_url":"https://api.github.com/users/steveklabnik/following{/other_user}","gists_url":"https://api.github.com/users/steveklabnik/gists{/gist_id}","starred_url":"https://api.github.com/users/steveklabnik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/steveklabnik/subscriptions","organizations_url":"https://api.github.com/users/steveklabnik/orgs","repos_url":"https://api.github.com/users/steveklabnik/repos","events_url":"https://api.github.com/users/steveklabnik/events{/privacy}","received_events_url":"https://api.github.com/users/steveklabnik/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/steveklabnik/rust","description":"a safe, concurrent, practical language","fork":true,"url":"https://api.github.com/repos/steveklabnik/rust","forks_url":"https://api.github.com/repos/steveklabnik/rust/forks","keys_url":"https://api.github.com/repos/steveklabnik/rust/keys{/key_id}","collaborators_url":"https://api.github.com/repos/steveklabnik/rust/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/steveklabnik/rust/teams","hooks_url":"https://api.github.com/repos/steveklabnik/rust/hooks","issue_events_url":"https://api.github.com/repos/steveklabnik/rust/issues/events{/number}","events_url":"https://api.github.com/repos/steveklabnik/rust/events","assignees_url":"https://api.github.com/repos/steveklabnik/rust/assignees{/user}","branches_url":"https://api.github.com/repos/steveklabnik/rust/branches{/branch}","tags_url":"https://api.github.com/repos/steveklabnik/rust/tags","blobs_url":"https://api.github.com/repos/steveklabnik/rust/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/steveklabnik/rust/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/steveklabnik/rust/git/refs{/sha}","trees_url":"https://api.github.com/repos/steveklabnik/rust/git/trees{/sha}","statuses_url":"https://api.github.com/repos/steveklabnik/rust/statuses/{sha}","languages_url":"https://api.github.com/repos/steveklabnik/rust/languages","stargazers_url":"https://api.github.com/repos/steveklabnik/rust/stargazers","contributors_url":"https://api.github.com/repos/steveklabnik/rust/contributors","subscribers_url":"https://api.github.com/repos/steveklabnik/rust/subscribers","subscription_url":"https://api.github.com/repos/steveklabnik/rust/subscription","commits_url":"https://api.github.com/repos/steveklabnik/rust/commits{/sha}","git_commits_url":"https://api.github.com/repos/steveklabnik/rust/git/commits{/sha}","comments_url":"https://api.github.com/repos/steveklabnik/rust/comments{/number}","issue_comment_url":"https://api.github.com/repos/steveklabnik/rust/issues/comments{/number}","contents_url":"https://api.github.com/repos/steveklabnik/rust/contents/{+path}","compare_url":"https://api.github.com/repos/steveklabnik/rust/compare/{base}...{head}","merges_url":"https://api.github.com/repos/steveklabnik/rust/merges","archive_url":"https://api.github.com/repos/steveklabnik/rust/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/steveklabnik/rust/downloads","issues_url":"https://api.github.com/repos/steveklabnik/rust/issues{/number}","pulls_url":"https://api.github.com/repos/steveklabnik/rust/pulls{/number}","milestones_url":"https://api.github.com/repos/steveklabnik/rust/milestones{/number}","notifications_url":"https://api.github.com/repos/steveklabnik/rust/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/steveklabnik/rust/labels{/name}","releases_url":"https://api.github.com/repos/steveklabnik/rust/releases{/id}","created_at":"2012-12-28T03:07:04Z","updated_at":"2015-03-23T18:43:45Z","pushed_at":"2015-03-24T14:53:02Z","git_url":"git://github.com/steveklabnik/rust.git","ssh_url":"git@github.com:steveklabnik/rust.git","clone_url":"https://github.com/steveklabnik/rust.git","svn_url":"https://github.com/steveklabnik/rust","homepage":"http://www.rust-lang.org","size":260386,"stargazers_count":2,"watchers_count":2,"language":"Rust","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":2,"default_branch":"master"}},"base":{"label":"rust-lang:master","ref":"master","sha":"3900c089a1305f06c6dbb15d07127b4e3a8f040c","user":{"login":"rust-lang","id":5430905,"avatar_url":"https://avatars.githubusercontent.com/u/5430905?v=3","gravatar_id":"","url":"https://api.github.com/users/rust-lang","html_url":"https://github.com/rust-lang","followers_url":"https://api.github.com/users/rust-lang/followers","following_url":"https://api.github.com/users/rust-lang/following{/other_user}","gists_url":"https://api.github.com/users/rust-lang/gists{/gist_id}","starred_url":"https://api.github.com/users/rust-lang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rust-lang/subscriptions","organizations_url":"https://api.github.com/users/rust-lang/orgs","repos_url":"https://api.github.com/users/rust-lang/repos","events_url":"https://api.github.com/users/rust-lang/events{/privacy}","received_events_url":"https://api.github.com/users/rust-lang/received_events","type":"Organization","site_admin":false},"repo":{"id":724712,"name":"rust","full_name":"rust-lang/rust","owner":{"login":"rust-lang","id":5430905,"avatar_url":"https://avatars.githubusercontent.com/u/5430905?v=3","gravatar_id":"","url":"https://api.github.com/users/rust-lang","html_url":"https://github.com/rust-lang","followers_url":"https://api.github.com/users/rust-lang/followers","following_url":"https://api.github.com/users/rust-lang/following{/other_user}","gists_url":"https://api.github.com/users/rust-lang/gists{/gist_id}","starred_url":"https://api.github.com/users/rust-lang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rust-lang/subscriptions","organizations_url":"https://api.github.com/users/rust-lang/orgs","repos_url":"https://api.github.com/users/rust-lang/repos","events_url":"https://api.github.com/users/rust-lang/events{/privacy}","received_events_url":"https://api.github.com/users/rust-lang/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/rust-lang/rust","description":"a safe, concurrent, practical language","fork":false,"url":"https://api.github.com/repos/rust-lang/rust","forks_url":"https://api.github.com/repos/rust-lang/rust/forks","keys_url":"https://api.github.com/repos/rust-lang/rust/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rust-lang/rust/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rust-lang/rust/teams","hooks_url":"https://api.github.com/repos/rust-lang/rust/hooks","issue_events_url":"https://api.github.com/repos/rust-lang/rust/issues/events{/number}","events_url":"https://api.github.com/repos/rust-lang/rust/events","assignees_url":"https://api.github.com/repos/rust-lang/rust/assignees{/user}","branches_url":"https://api.github.com/repos/rust-lang/rust/branches{/branch}","tags_url":"https://api.github.com/repos/rust-lang/rust/tags","blobs_url":"https://api.github.com/repos/rust-lang/rust/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rust-lang/rust/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rust-lang/rust/git/refs{/sha}","trees_url":"https://api.github.com/repos/rust-lang/rust/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rust-lang/rust/statuses/{sha}","languages_url":"https://api.github.com/repos/rust-lang/rust/languages","stargazers_url":"https://api.github.com/repos/rust-lang/rust/stargazers","contributors_url":"https://api.github.com/repos/rust-lang/rust/contributors","subscribers_url":"https://api.github.com/repos/rust-lang/rust/subscribers","subscription_url":"https://api.github.com/repos/rust-lang/rust/subscription","commits_url":"https://api.github.com/repos/rust-lang/rust/commits{/sha}","git_commits_url":"https://api.github.com/repos/rust-lang/rust/git/commits{/sha}","comments_url":"https://api.github.com/repos/rust-lang/rust/comments{/number}","issue_comment_url":"https://api.github.com/repos/rust-lang/rust/issues/comments{/number}","contents_url":"https://api.github.com/repos/rust-lang/rust/contents/{+path}","compare_url":"https://api.github.com/repos/rust-lang/rust/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rust-lang/rust/merges","archive_url":"https://api.github.com/repos/rust-lang/rust/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rust-lang/rust/downloads","issues_url":"https://api.github.com/repos/rust-lang/rust/issues{/number}","pulls_url":"https://api.github.com/repos/rust-lang/rust/pulls{/number}","milestones_url":"https://api.github.com/repos/rust-lang/rust/milestones{/number}","notifications_url":"https://api.github.com/repos/rust-lang/rust/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rust-lang/rust/labels{/name}","releases_url":"https://api.github.com/repos/rust-lang/rust/releases{/id}","created_at":"2010-06-16T20:39:03Z","updated_at":"2015-03-24T13:49:58Z","pushed_at":"2015-03-24T15:45:57Z","git_url":"git://github.com/rust-lang/rust.git","ssh_url":"git@github.com:rust-lang/rust.git","clone_url":"https://github.com/rust-lang/rust.git","svn_url":"https://github.com/rust-lang/rust","homepage":"http://www.rust-lang.org","size":517218,"stargazers_count":9819,"watchers_count":9819,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1906,"mirror_url":null,"open_issues_count":2113,"forks":1906,"open_issues":2113,"watchers":9819,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rust-lang/rust/pulls/23568"},"html":{"href":"https://github.com/rust-lang/rust/pull/23568"},"issue":{"href":"https://api.github.com/repos/rust-lang/rust/issues/23568"},"comments":{"href":"https://api.github.com/repos/rust-lang/rust/issues/23568/comments"},"review_comments":{"href":"https://api.github.com/repos/rust-lang/rust/pulls/23568/comments"},"review_comment":{"href":"https://api.github.com/repos/rust-lang/rust/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/rust-lang/rust/pulls/23568/commits"},"statuses":{"href":"https://api.github.com/repos/rust-lang/rust/statuses/a7aaa789a015f57a6b123112d557e2e588e68edb"}}}}