{"action":"created","comment":{"url":"https://api.github.com/repos/rust-lang/rfcs/pulls/comments/34996389","id":34996389,"diff_hunk":"@@ -0,0 +1,401 @@\n+- Feature Name: bang_type\n+- Start Date: 2015-07-19\n+- RFC PR: (leave this empty)\n+- Rust Issue: (leave this empty)\n+\n+# Summary\n+\n+Promote `!` to be a full-fledged type equivalent to an `enum` with no variants.\n+\n+# Motivation\n+\n+To understand the motivation for this it's necessary to understand the concept\n+of empty types. An empty type is a type with no inhabitants, ie. a type for\n+which there is nothing of that type. For example consider the type `enum Never\n+{}`. This type has no constructors and therefore can never be instantiated. It is empty, in the sense that there are no values of type `Never`. Note\n+that `Never` is not equivalent to `()` or `struct Foo {}` each of which have\n+exactly one inhabitant. Empty types have some interesting properties that may\n+be unfamiliar to programmers who have not encountered them before.\n+\n+  * They never exist at runtime.\n+    Because there is no way to create one.\n+\n+  * They have no logical machine-level representation.\n+    One way to think about this is to consider the number of bits required to\n+    store a value of a given type. A value of type `bool` can be in two\n+    possible states (`true` and `false`). Therefore to specify which state a\n+    `bool` is in we need `log2(2) ==> 1` bit of information. A value of type\n+    `()` can only be in one possible state (`()`). Therefore to specify which\n+    state a `()` is in we need `log2(1) ==> 0` bits of information. A value of\n+    type `Never` has no possible states it can be in. Therefore to ask which of\n+    these states it is in is a meaningless question and we have `log2(0) ==>\n+    undefined` (or `-∞`). Having no representation is not problematic as safe\n+    code never has reason nor ability to handle data of an empty type (as such\n+    data can never exist). In practice, Rust currently treats empty types as\n+    having size 0.\n+\n+  * Code that handles them never executes.\n+    Because there is no value that it could execute with. Therefore, having a\n+    `Never` in scope is a static guarantee that a piece of code will never be\n+    run.\n+\n+  * They represent the return type of functions that don't return.\n+    For a function that never returns, such as `exit`, the set of all values it\n+    may return is the empty set. That is to say, the type of all values it may\n+    return is the type of no inhabitants, ie. `Never` or anything equivalent to\n+    it.\n+\n+  * They can be converted to any other type.\n+    To specify a function `A -> B` we need to specify a return value in `B` for\n+    every possible argument in `A`. For example, an expression that converts\n+    `bool -> T` needs to specify a return value for both possible arguments\n+    `true` and `false`:\n+\n+    ```rust\n+    let foo: &'static str = match x {\n+      true  => \"some_value\",\n+      false => \"some_other_value\",\n+    };\n+    ```\n+\n+    Likewise, an expression to convert `() -> T` needs to specify one value,\n+    the value corresponding to `()`:\n+\n+    ```rust\n+    let foo: &'static str = match x {\n+      ()  => \"some_value\",\n+    };\n+    ```\n+\n+    And following this pattern, to convert `Never -> T` we need to specify a\n+    `T` for every possible `Never`. Of which there are none:\n+\n+    ```rust\n+    let foo: &'static str = match x {\n+    };\n+    ```\n+\n+    Reading this, it may be tempting to ask the question \"what is the value of\n+    `foo` then?\". Remember that this depends on the value of `x`. As there are\n+    no possible values of `x` it's a meaningless question and besides, the\n+    fact that `x` has type `Never` gives us a static guarantee that the match\n+    block will never be executed.\n+\n+Here's some example code that uses `Never`. This is legal rust code that you\n+can run today.\n+\n+```rust\n+use std::process::exit;\n+\n+// Our empty type\n+enum Never {}\n+\n+// A diverging function with an ordinary return type\n+fn wrap_exit() -> Never {\n+    exit(0);\n+}\n+\n+// we can use a `Never` value to diverge without using unsafe code or calling\n+// any diverging intrinsics\n+fn diverge_from_never(n: Never) -> ! {\n+  match n {\n+  }\n+}\n+\n+fn main() {\n+    let x: Never = wrap_exit();\n+    // `x` is in scope, everything below here is dead code.\n+\n+    let y: String = match x {\n+        // no match cases as `Never` has no variants\n+    };\n+\n+    // we can still use `y` though\n+    println!(\"Our string is: {}\", y);\n+\n+    // we can use `x` to diverge\n+    diverge_from_never(x)\n+}\n+```\n+\n+This RFC proposes that we allow `!` to be used directly, as a type, rather than\n+using `Never` (or equivalent) in it's place. Under this RFC, the above code\n+could more simply be written.\n+\n+```rust\n+use std::process::exit;\n+\n+fn main() {\n+    let x: ! = exit(0);\n+    // `x` is in scope, everything below here is dead code.\n+\n+    let y: String = match x {\n+        // no match cases as `Never` has no variants\n+    };\n+\n+    // we can still use `y` though\n+    println!(\"Our string is: {}\", y);\n+\n+    // we can use `x` to diverge\n+    x\n+}\n+```\n+\n+So why do this? AFAICS there are 3 main reasons\n+\n+  * **It removes one superfluous concept from the language and allows diverging\n+    functions to be used in generic code.**\n+\n+    Currently, Rust's functions can be divided into two kinds: those that\n+    return a regular type and those that use the `-> !` syntax to mark\n+    themselves as diverging. This division is unnecessary and means that\n+    functions of the latter kind don't play well with generic code.\n+\n+    For example: you want to use a diverging function where something expects a\n+    `Fn() -> T`\n+\n+    ```rust\n+    fn foo() -> !;\n+    fn call_a_fn<T, F: Fn() -> T>(f: F) -> T;\n+\n+    call_a_fn(foo) // ERROR!\n+    ```\n+\n+    Or maybe you want to use a diverging function to implement a trait method\n+    that returns an associated type:\n+\n+    ```rust\n+    trait Zog {\n+        type Output\n+        fn zog() -> Output;\n+    };\n+\n+    impl Zog for T {\n+        type Output = !;                    // ERROR!\n+        fn zog() -> ! { panic!(\"aaah!\") };  // ERROR!\n+    }\n+    ```\n+\n+    The workaround in these cases is to define a type like `Never` and use it\n+    in place of `!`. You can then define functions `wrap_foo` and `unwrap_zog`\n+    similar to the functions `wrap_exit` and `diverge_from_never` defined\n+    earlier. It would be nice if this workaround wasn't necessary.\n+\n+  * **It creates a standard empty type for use throughout rust code.**\n+\n+    Empty types are useful for more than just marking functions as diverging.\n+    When used in an enum variant they prevent the variant from ever being\n+    instantiated. One major use case for this is if a method needs to return a\n+    `Result<T, E>` to satisfy a trait but we know that the method will always\n+    succeed.\n+\n+    For example, here's a saner implementation of `FromStr` for `String` than\n+    currently exists in `libstd`.\n+\n+    ```rust\n+    impl FromStr for String {\n+        type Err = !;\n+        \n+        fn from_str(s: &str) -> Result<String, !> {\n+            Ok(String::from(s))\n+        }\n+    }\n+    ```\n+\n+    This result can then be safely unwrapped to a `String` without using\n+    code-smelly things like `unreachable!()` which often mask bugs in code.\n+\n+    ```rust\n+    let r: Result<String, !> = FromStr::from_str(\"hello\");\n+    let s = match r {\n+        Ok(s)   => s,\n+        Err(e)  => match e {},\n+    }\n+    ```\n+\n+    Empty types can also be used when someone needs a dummy type to implement a\n+    trait. Because `!` can be converted to any other type it has a trivial\n+    implementation of any trait whose only associated items are non-static\n+    methods. The impl simply matches on self for every method.\n+\n+    Example:\n+\n+    ```rust\n+    trait ToSocketAddr {\n+        fn to_socket_addr(&self) -> IoResult<SocketAddr>;\n+        fn to_socket_addr_all(&self) -> IoResult<Vec<SocketAddr>>;\n+    }\n+\n+    impl ToSocketAddr for ! {\n+        fn to_socket_addr(&self) -> IoResult<SocketAddr> {\n+            match self {}\n+        }\n+\n+        fn to_socket_addr_all(&self) -> IoResult<Vec<SocketAddr>> {\n+            match self {}\n+        }\n+    }\n+    ```\n+\n+    All possible implementations of this trait for `!` are equivalent. This is\n+    because any two functions that take a `!` argument and return the same type\n+    are equivalent - they return the same result for the same arguments and\n+    have the same effects (because they are uncallable).\n+\n+    Suppose someone wants to call `fn foo<T: SomeTrait>(arg: Option<T>)` with\n+    `None`. They need to choose a type for `T` so they can pass `None::<T>` as\n+    the argument. However there may be no sensible default type to use for `T`\n+    or, worse, they may not have any types at their disposal that implement\n+    `SomeTrait`. As the user in this case is only using `None`, a sensible\n+    choice for `T` would be a type such that `Option<T>` can ony be `None`, ie.\n+    it would be nice to use `!`. If `!` has a trivial implementation of\n+    `SomeTrait` then the choice of `T` is truly irrelevant as this means `foo`\n+    doesn't use any associated types/lifetimes/constants or static methods of\n+    `T` and is therefore unable to distinguish `None::<A>` from `None::<B>`.\n+    With this RFC, the user could `impl SomeTrait for !` (if `SomeTrait`'s\n+    author hasn't done so already) and call `foo(None::<!>)`.\n+\n+    Currently, `Never` can be used for all the above purposes. It's useful\n+    enough that @reem has written a package for it\n+    [here](https://github.com/reem/rust-void) where it is named `Void`. I've also\n+    invented it independently for my own projects and probably other people\n+    have aswell. However `!` can be extended logically to cover all the above\n+    use cases. Doing so would standardise the concept and prevent different\n+    people reimplementing it under different names.\n+\n+  * **Because it's the correct thing to do.**\n+\n+    The empty type is such a fundamental concept that - given that it already\n+    exists in the form of empty enums - it warrants having a canonical form of\n+    it built-into the language. For example, `return` and `break` expressions\n+    should logically be typed `!` but currently seem to be typed `()`. (There\n+    is some code in the compiler that assigns type `()` to diverging\n+    expressions because it doesn't have a sensible type to assign to them).\n+    This means we can write stuff like this:\n+\n+    ```rust\n+    match break {\n+      ()  => ...  // huh? Where did that `()` come from?\n+    }\n+    ```\n+\n+    But not this:\n+\n+    ```rust\n+    match break {} // whaddaya mean non-exhaustive patterns?\n+    ```\n+\n+    This is just weird and should be fixed.\n+\n+I suspect the reason that `!` isn't already treated as a canonical empty type\n+is just most people's unfamilarity with empty types. To draw a parallel in\n+history: in C `void` is in essence a type like any other. However it can't be\n+used in all the normal positions where a type can be used. This breaks generic\n+code (eg. `T foo(); T val = foo()` where `T == void`) and forces one to use\n+workarounds such as defining `struct Void {}` and wrapping `void`-returning\n+functions:\n+\n+In the early days of programming having a type that contained no data probably\n+seemed pointless. After all, there's no point in having a `void` typed function\n+argument or a vector of `void`s. So `void` was treated as merely a special\n+syntax for denoting a function as returning no value resulting in a language\n+that was more broken and complicated than it needed to be.\n+\n+Fifty years later, Rust, building on decades of experience, decides to fix C's\n+shortsightedness and bring `void` into the type system in the form of the empty\n+tuple `()`. Rust also introduces coproduct types (in the form of enums),\n+allowing programmers to work with uninhabited types (such as `Never`). However\n+rust also introduces a special syntax for denoting a function as never\n+returning: `fn() -> !`. Here, `!` is in essence a type like any other. However\n+it can't be used in all the normal positions where a type can be used. This\n+breaks generic code (eg. `fn() -> T; let val: T = foo()` where `T == !`) and\n+forces one to use workarounds such as defining `enum Never {}` and wrapping\n+`!`-returning functions.\n+\n+To be clear, `!` has a meaning in any situation that any other type does. A `!`\n+function argument makes a function uncallable, a `Vec<!>` is a vector that can\n+never contain an element, a `!` enum variant makes the variant guaranteed never\n+to occur and so forth. It might seem pointless to use a `!` function argument\n+or a `Vec<!>` (just as it would be pointless to use a `()` function argument or\n+a `Vec<()>`), but that's no reason to disallow it. And generic code sometimes\n+requires it.\n+\n+Rust already has empty types in the form of empty enums. Any code that could be\n+written with this RFC's `!` can already be written by swapping out `!` with\n+`Never` (sans implicit casts, see below). So if this RFC could create any\n+issues for the language (such as making it unsound or complicating the\n+compiler) then these issues would already exist for `Never`.\n+\n+# Detailed design\n+\n+Add a type `!` to Rust. `!` behaves like an empty enum except that it can be\n+implicitly cast to any other type. ie. the following code is acceptable:\n+\n+```rust\n+let r: Result<i32, !> = Ok(23);\n+let i = match r {\n+    Ok(i)   => i,\n+    Err(e)  => e, // e is cast to i32\n+}\n+```\n+\n+Implicit casting is necessary for backwards-compatibility so that code like the\n+following will continue to compile:\n+\n+```rust\n+let i: i32 = match some_bool {\n+    true  => 23,\n+    false => panic!(\"aaah!\"), // an expression of type `!`, gets cast to `i32`\n+}\n+\n+match break {\n+    ()  => 23,  // matching with a `()` forces the match argument to be cast to type `()`\n+}\n+```\n+\n+In the compiler, remove the distinctions that treat diverging and converging\n+expressions as two different kinds of things (eg. stuff like `FnConverging` vs\n+`FnDiverging`). Use the type system to do things like reachability analysis.\n+\n+Add an implementation for `!` of any trait that it can trivially implement. Add\n+methods to `Result<T, !>` and `Result<!, E>` for safely extracting the inner\n+value. Name these methods along the lines of `unwrap_nopanic`, `safe_unwrap` or\n+something.\n+\n+# Drawbacks\n+\n+Someone would have to implement this.\n+\n+# Alternatives\n+\n+  * Don't do this.\n+  * Move @reem's `Void` type into `libcore`. This would create a standard empty\n+    type and make it available for use in the standard libraries. If we were to\n+    do this it might be an idea to rename `Void` to something else (`Never`,\n+    `Empty` and `Mu` have all been suggested). Although `Void` has some\n+    precedence in languages like Haskell and Idris the name is likely to trip\n+    up people coming from a C/Java et al. background as `Void` is *not* `void`\n+    but it can be easy to confuse the two.\n+\n+# Unresolved questions\n+\n+Apparently, rust used to have something similar to this but it was removed.\n+There are still a few references to `ty_bot` in the compiler. Why was this\n+taken out? Note that if there any arguments for not having type `!` in the\n+language they should apply equally well to `Never`/`Void` so I assume the old\n+`ty_bot` was trying to be something crazier than this RFC's `!` (such as a\n+subtype of all types, given the name). Could someone who was around back then\n+clarify this?","path":"text/0000-bang-type.md","position":388,"original_position":388,"commit_id":"4cb013799daf74889321ab382d2e1a7975c4bb07","original_commit_id":"58baeaa1dcc97216215c5f2bcda7627a88665455","user":{"login":"eddyb","id":77424,"avatar_url":"https://avatars.githubusercontent.com/u/77424?v=3","gravatar_id":"","url":"https://api.github.com/users/eddyb","html_url":"https://github.com/eddyb","followers_url":"https://api.github.com/users/eddyb/followers","following_url":"https://api.github.com/users/eddyb/following{/other_user}","gists_url":"https://api.github.com/users/eddyb/gists{/gist_id}","starred_url":"https://api.github.com/users/eddyb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eddyb/subscriptions","organizations_url":"https://api.github.com/users/eddyb/orgs","repos_url":"https://api.github.com/users/eddyb/repos","events_url":"https://api.github.com/users/eddyb/events{/privacy}","received_events_url":"https://api.github.com/users/eddyb/received_events","type":"User","site_admin":false},"body":"@canndrew The tag of `Option<T>` can be `u8` (`u1`, really), `u16`, `u32` or `u64`, depending on alignment requirements for `T`.\r\nWhat would you do, encode `Option<!>` as `0u64`? Then what about `Result<T, !>` vs `Result<!, E>` vs `Result<T, E>`?","created_at":"2015-07-20T13:55:08Z","updated_at":"2015-07-20T13:55:08Z","html_url":"https://github.com/rust-lang/rfcs/pull/1216#discussion_r34996389","pull_request_url":"https://api.github.com/repos/rust-lang/rfcs/pulls/1216","_links":{"self":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/comments/34996389"},"html":{"href":"https://github.com/rust-lang/rfcs/pull/1216#discussion_r34996389"},"pull_request":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/1216"}}},"pull_request":{"url":"https://api.github.com/repos/rust-lang/rfcs/pulls/1216","id":40304497,"html_url":"https://github.com/rust-lang/rfcs/pull/1216","diff_url":"https://github.com/rust-lang/rfcs/pull/1216.diff","patch_url":"https://github.com/rust-lang/rfcs/pull/1216.patch","issue_url":"https://api.github.com/repos/rust-lang/rfcs/issues/1216","number":1216,"state":"open","locked":false,"title":"Promote `!` to a type.","user":{"login":"canndrew","id":5555066,"avatar_url":"https://avatars.githubusercontent.com/u/5555066?v=3","gravatar_id":"","url":"https://api.github.com/users/canndrew","html_url":"https://github.com/canndrew","followers_url":"https://api.github.com/users/canndrew/followers","following_url":"https://api.github.com/users/canndrew/following{/other_user}","gists_url":"https://api.github.com/users/canndrew/gists{/gist_id}","starred_url":"https://api.github.com/users/canndrew/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/canndrew/subscriptions","organizations_url":"https://api.github.com/users/canndrew/orgs","repos_url":"https://api.github.com/users/canndrew/repos","events_url":"https://api.github.com/users/canndrew/events{/privacy}","received_events_url":"https://api.github.com/users/canndrew/received_events","type":"User","site_admin":false},"body":"Promote `!` to be a full-fledged type equivalent to an `enum` with no variants.\r\n\r\n[Rendered](https://github.com/canndrew/rfcs/blob/bang_type/text/0000-bang-type.md)","created_at":"2015-07-19T07:27:48Z","updated_at":"2015-07-20T13:55:08Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ac3ab31af7af8f4d42bbdc9b75386b5d49934b1c","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/rust-lang/rfcs/pulls/1216/commits","review_comments_url":"https://api.github.com/repos/rust-lang/rfcs/pulls/1216/comments","review_comment_url":"https://api.github.com/repos/rust-lang/rfcs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/rust-lang/rfcs/issues/1216/comments","statuses_url":"https://api.github.com/repos/rust-lang/rfcs/statuses/4cb013799daf74889321ab382d2e1a7975c4bb07","head":{"label":"canndrew:bang_type","ref":"bang_type","sha":"4cb013799daf74889321ab382d2e1a7975c4bb07","user":{"login":"canndrew","id":5555066,"avatar_url":"https://avatars.githubusercontent.com/u/5555066?v=3","gravatar_id":"","url":"https://api.github.com/users/canndrew","html_url":"https://github.com/canndrew","followers_url":"https://api.github.com/users/canndrew/followers","following_url":"https://api.github.com/users/canndrew/following{/other_user}","gists_url":"https://api.github.com/users/canndrew/gists{/gist_id}","starred_url":"https://api.github.com/users/canndrew/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/canndrew/subscriptions","organizations_url":"https://api.github.com/users/canndrew/orgs","repos_url":"https://api.github.com/users/canndrew/repos","events_url":"https://api.github.com/users/canndrew/events{/privacy}","received_events_url":"https://api.github.com/users/canndrew/received_events","type":"User","site_admin":false},"repo":{"id":26679419,"name":"rfcs","full_name":"canndrew/rfcs","owner":{"login":"canndrew","id":5555066,"avatar_url":"https://avatars.githubusercontent.com/u/5555066?v=3","gravatar_id":"","url":"https://api.github.com/users/canndrew","html_url":"https://github.com/canndrew","followers_url":"https://api.github.com/users/canndrew/followers","following_url":"https://api.github.com/users/canndrew/following{/other_user}","gists_url":"https://api.github.com/users/canndrew/gists{/gist_id}","starred_url":"https://api.github.com/users/canndrew/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/canndrew/subscriptions","organizations_url":"https://api.github.com/users/canndrew/orgs","repos_url":"https://api.github.com/users/canndrew/repos","events_url":"https://api.github.com/users/canndrew/events{/privacy}","received_events_url":"https://api.github.com/users/canndrew/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/canndrew/rfcs","description":"RFCs for changes to Rust","fork":true,"url":"https://api.github.com/repos/canndrew/rfcs","forks_url":"https://api.github.com/repos/canndrew/rfcs/forks","keys_url":"https://api.github.com/repos/canndrew/rfcs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/canndrew/rfcs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/canndrew/rfcs/teams","hooks_url":"https://api.github.com/repos/canndrew/rfcs/hooks","issue_events_url":"https://api.github.com/repos/canndrew/rfcs/issues/events{/number}","events_url":"https://api.github.com/repos/canndrew/rfcs/events","assignees_url":"https://api.github.com/repos/canndrew/rfcs/assignees{/user}","branches_url":"https://api.github.com/repos/canndrew/rfcs/branches{/branch}","tags_url":"https://api.github.com/repos/canndrew/rfcs/tags","blobs_url":"https://api.github.com/repos/canndrew/rfcs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/canndrew/rfcs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/canndrew/rfcs/git/refs{/sha}","trees_url":"https://api.github.com/repos/canndrew/rfcs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/canndrew/rfcs/statuses/{sha}","languages_url":"https://api.github.com/repos/canndrew/rfcs/languages","stargazers_url":"https://api.github.com/repos/canndrew/rfcs/stargazers","contributors_url":"https://api.github.com/repos/canndrew/rfcs/contributors","subscribers_url":"https://api.github.com/repos/canndrew/rfcs/subscribers","subscription_url":"https://api.github.com/repos/canndrew/rfcs/subscription","commits_url":"https://api.github.com/repos/canndrew/rfcs/commits{/sha}","git_commits_url":"https://api.github.com/repos/canndrew/rfcs/git/commits{/sha}","comments_url":"https://api.github.com/repos/canndrew/rfcs/comments{/number}","issue_comment_url":"https://api.github.com/repos/canndrew/rfcs/issues/comments{/number}","contents_url":"https://api.github.com/repos/canndrew/rfcs/contents/{+path}","compare_url":"https://api.github.com/repos/canndrew/rfcs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/canndrew/rfcs/merges","archive_url":"https://api.github.com/repos/canndrew/rfcs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/canndrew/rfcs/downloads","issues_url":"https://api.github.com/repos/canndrew/rfcs/issues{/number}","pulls_url":"https://api.github.com/repos/canndrew/rfcs/pulls{/number}","milestones_url":"https://api.github.com/repos/canndrew/rfcs/milestones{/number}","notifications_url":"https://api.github.com/repos/canndrew/rfcs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/canndrew/rfcs/labels{/name}","releases_url":"https://api.github.com/repos/canndrew/rfcs/releases{/id}","created_at":"2014-11-15T12:37:10Z","updated_at":"2014-11-13T12:11:13Z","pushed_at":"2015-07-20T09:54:07Z","git_url":"git://github.com/canndrew/rfcs.git","ssh_url":"git@github.com:canndrew/rfcs.git","clone_url":"https://github.com/canndrew/rfcs.git","svn_url":"https://github.com/canndrew/rfcs","homepage":"","size":1868,"stargazers_count":0,"watchers_count":0,"language":null,"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":0,"default_branch":"master"}},"base":{"label":"rust-lang:master","ref":"master","sha":"e2c36eb144f21428cbffcc6fdd28a4f6decee133","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":17527989,"name":"rfcs","full_name":"rust-lang/rfcs","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/rfcs","description":"RFCs for changes to Rust","fork":false,"url":"https://api.github.com/repos/rust-lang/rfcs","forks_url":"https://api.github.com/repos/rust-lang/rfcs/forks","keys_url":"https://api.github.com/repos/rust-lang/rfcs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rust-lang/rfcs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rust-lang/rfcs/teams","hooks_url":"https://api.github.com/repos/rust-lang/rfcs/hooks","issue_events_url":"https://api.github.com/repos/rust-lang/rfcs/issues/events{/number}","events_url":"https://api.github.com/repos/rust-lang/rfcs/events","assignees_url":"https://api.github.com/repos/rust-lang/rfcs/assignees{/user}","branches_url":"https://api.github.com/repos/rust-lang/rfcs/branches{/branch}","tags_url":"https://api.github.com/repos/rust-lang/rfcs/tags","blobs_url":"https://api.github.com/repos/rust-lang/rfcs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rust-lang/rfcs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rust-lang/rfcs/git/refs{/sha}","trees_url":"https://api.github.com/repos/rust-lang/rfcs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rust-lang/rfcs/statuses/{sha}","languages_url":"https://api.github.com/repos/rust-lang/rfcs/languages","stargazers_url":"https://api.github.com/repos/rust-lang/rfcs/stargazers","contributors_url":"https://api.github.com/repos/rust-lang/rfcs/contributors","subscribers_url":"https://api.github.com/repos/rust-lang/rfcs/subscribers","subscription_url":"https://api.github.com/repos/rust-lang/rfcs/subscription","commits_url":"https://api.github.com/repos/rust-lang/rfcs/commits{/sha}","git_commits_url":"https://api.github.com/repos/rust-lang/rfcs/git/commits{/sha}","comments_url":"https://api.github.com/repos/rust-lang/rfcs/comments{/number}","issue_comment_url":"https://api.github.com/repos/rust-lang/rfcs/issues/comments{/number}","contents_url":"https://api.github.com/repos/rust-lang/rfcs/contents/{+path}","compare_url":"https://api.github.com/repos/rust-lang/rfcs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rust-lang/rfcs/merges","archive_url":"https://api.github.com/repos/rust-lang/rfcs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rust-lang/rfcs/downloads","issues_url":"https://api.github.com/repos/rust-lang/rfcs/issues{/number}","pulls_url":"https://api.github.com/repos/rust-lang/rfcs/pulls{/number}","milestones_url":"https://api.github.com/repos/rust-lang/rfcs/milestones{/number}","notifications_url":"https://api.github.com/repos/rust-lang/rfcs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rust-lang/rfcs/labels{/name}","releases_url":"https://api.github.com/repos/rust-lang/rfcs/releases{/id}","created_at":"2014-03-07T21:29:00Z","updated_at":"2015-07-20T08:19:18Z","pushed_at":"2015-07-20T09:54:08Z","git_url":"git://github.com/rust-lang/rfcs.git","ssh_url":"git@github.com:rust-lang/rfcs.git","clone_url":"https://github.com/rust-lang/rfcs.git","svn_url":"https://github.com/rust-lang/rfcs","homepage":"","size":11086,"stargazers_count":412,"watchers_count":412,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":220,"mirror_url":null,"open_issues_count":540,"forks":220,"open_issues":540,"watchers":412,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/1216"},"html":{"href":"https://github.com/rust-lang/rfcs/pull/1216"},"issue":{"href":"https://api.github.com/repos/rust-lang/rfcs/issues/1216"},"comments":{"href":"https://api.github.com/repos/rust-lang/rfcs/issues/1216/comments"},"review_comments":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/1216/comments"},"review_comment":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/1216/commits"},"statuses":{"href":"https://api.github.com/repos/rust-lang/rfcs/statuses/4cb013799daf74889321ab382d2e1a7975c4bb07"}}}}