{"action":"created","comment":{"url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/pulls/comments/240542790","pull_request_review_id":183592352,"id":240542790,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI0MDU0Mjc5MA==","diff_hunk":"@@ -0,0 +1,120 @@\n+# Data type validity requirements\n+\n+This discussion is meant to focus on the question: Which invariants derived from\n+types are there that the compiler expects to be *always* maintained, and\n+(equivalently) that unsafe code must *always* uphold (or else cause undefined\n+behavior)?  This is what is called \"validity invariant\" in\n+[Ralf's blog post](https://www.ralfj.de/blog/2018/08/22/two-kinds-of-invariants.html),\n+but we might also decide to change that name.\n+\n+### Interactions and constraints\n+\n+Choices of invariants interact, in particular, with layout optimizations: For\n+example, the fact that `Option<&T>` is pointer-sized relies on the fact that the\n+validity invariant for `&T` rules out `0x0`, and hence we can use that value as\n+signaling the `None` case.\n+\n+Moreover, the invariants are constrained by attributes that we emit when\n+generating LLVM IR.  For example, we emit `aligned` attributes pretty much any\n+time we can, which means it is probably a good idea to say that valid references\n+must be aligned.\n+\n+Finally, another consideration to take into account is that ruling out certain\n+behavior can be great for bug finding.  For example, if arithmetic overflow is\n+defined to have two's-complement-behavior, then bug finding tools can no longer\n+use overflow as an indication of a software bug.  (This is a real problem with\n+unsigned integer arithmetic in C/C++.)\n+\n+### Possible bit patterns\n+\n+The validity invariant of a type is, basically, a set of bit patterns that is\n+allowed to occur at that type.  (\"Basically\" because the invariant may also be\n+allowed to depend on memory.)  To discuss this properly, we need to first agree\n+on what \"bit patterns\" even are.  It is not enough to just consider sequences of\n+0 and 1, because we also need to take uninitialized data into account.  For the\n+purpose of this discussion, I think it is sufficient to consider every bit as\n+being either 0, 1 or uninitialized.\n+[That is not always sufficient](https://www.ralfj.de/blog/2018/07/24/pointers-and-bytes.html),\n+but I think we can mostly ignore the extra complications introduced by pointer\n+values.\n+\n+### Extent of \"always\"\n+\n+One point we will have to figure out is what exactly \"always\" means.  Thinking\n+in terms of a semantics for MIR, data most probably needs to be valid any time\n+it is copied, which primarily happens when executing assignment statements (the\n+other cases are passing of function arguments and return values).  However, it\n+is less clear whether merely creating a place without accessing the data inside\n+(such as in `&*x`) should require the data to be valid.\n+\n+The entire discussion here is only about validity invariants that have to hold\n+when the compiler considers a variable initialized.  For example, `let b: bool;`\n+is completely okay to not be initialized because the compiler knows about that;\n+`let b: bool = mem::uninitialized();` however copies uninitialized data at type\n+`bool` and hence violates `bool`'s validity invariant.\n+\n+## Goals\n+\n+* For every primitive type, determine which assumptions (if any) the compiler\n+  makes about values *not* occurring at that type (serving as a lower bound for\n+  what to declare invalid), and determine which popular patterns in unsafe code\n+  might create \"interesting\" values of this type that safe code cannot create on\n+  its own (serving as an upper bound for how much we want to declare invalid).\n+  Both of these bounds are soft, but informative.\n+* Based on that, map out a design space of invariants that seem reasonable.\n+* Determine when exactly the validity invariant is assumed to hold.\n+\n+## Active threads\n+\n+To start, we will create threads for each major category of types.\n+\n+* Integers and floating point types\n+  * Do we allow values that contain uninitialized bits?  If yes, what are the\n+    rules for arithmetic and logical operations involving uninitialized bits,\n+    e.g. in cases like `x * 0`?  There is also some interaction with bug finding\n+    here: tools can only flag uninitialized data at integer type as a bug if we\n+    do not allow that to happen in unsafe code.\n+\n+* Raw pointers\n+  * Do we allow values that contain uninitialized bits?\n+  * Are there any requirements on the metadata?\n+\n+* References\n+  * Presumably, references must be non-NULL.\n+  * They probably also must be aligned, but is that required every time a\n+    reference is taken?  Also see the [ongoing discussion in RFC 2582][RFC2582].\n+  * Can there ever be uninitialized bits in a reference?\n+  * Do they have to be dereferencable?  What exactly does that even mean?\n+  * Does `&[mut] T` have to point to data that is valid at `T`?  This interacts\n+    with the question of whether `&*x` is allowed when `x` is a well-aligned\n+    non-null dereferencable pointer that points to invalid data.\n+  * Out of scope: aliasing rules\n+\n+* Function pointers\n+  * Presumably, these must be non-NULL.  Anything else?  Can there ever be\n+    uninitialized bits?\n+\n+* Booleans\n+  * Is there anything to say besides: A `bool` must be `0x0` or `0x1`?  Do we\n+    allow the remaining bits to be uninitialized?\n+\n+* Unions\n+  * Do we make any restrictions here, or are unions just \"bags of bits\" that may\n+    contain anything?  That would mean we can do no layout optimizations.\n+\n+* Enums\n+  * Is there anything to say besides: The discriminant must be valid, and all\n+    fields of the active variant must be valid at their respective types?\n+  * The padding between fields can be anything, including uninitialized.\n+\n+* Structs, tuples, arrays and all other aggregates (closures, ...)\n+  * Is there anything to say besides: All fields must be valid at their\n+    respective types?\n+  * The padding between fields can be anything, including uninitialized.  It was","path":"active_discussion/validity.md","position":113,"original_position":113,"commit_id":"c65b87bfbce989ed5627dc369124d6f1fab5b8a8","original_commit_id":"c65b87bfbce989ed5627dc369124d6f1fab5b8a8","user":{"login":"gnzlbg","id":904614,"node_id":"MDQ6VXNlcjkwNDYxNA==","avatar_url":"https://avatars0.githubusercontent.com/u/904614?v=4","gravatar_id":"","url":"https://api.github.com/users/gnzlbg","html_url":"https://github.com/gnzlbg","followers_url":"https://api.github.com/users/gnzlbg/followers","following_url":"https://api.github.com/users/gnzlbg/following{/other_user}","gists_url":"https://api.github.com/users/gnzlbg/gists{/gist_id}","starred_url":"https://api.github.com/users/gnzlbg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gnzlbg/subscriptions","organizations_url":"https://api.github.com/users/gnzlbg/orgs","repos_url":"https://api.github.com/users/gnzlbg/repos","events_url":"https://api.github.com/users/gnzlbg/events{/privacy}","received_events_url":"https://api.github.com/users/gnzlbg/received_events","type":"User","site_admin":false},"body":"I always reasoned about closures as being equivalent to a `struct` that one could write by hand (and with `feature(fn_traits)` one actually can). The rules for building that struct, if they are ever specified, are part of the language, but the layout, validity, etc. of this struct would follow from the layout and validity invariants that we specify here for primitive types, `struct`s, etc. \r\n\r\nI would find it extremely weird if the same wouldn't be true for generators. That is, the exact type of the Generator would be unspecified, but this type would be a normal Rust type, e.g., a `struct` or an `union`, with normal Rust fields (`struct`, `union`s, primitive types, etc.).","created_at":"2018-12-11T10:00:59Z","updated_at":"2018-12-11T10:00:59Z","html_url":"https://github.com/rust-rfcs/unsafe-code-guidelines/pull/54#discussion_r240542790","pull_request_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/pulls/54","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/pulls/comments/240542790"},"html":{"href":"https://github.com/rust-rfcs/unsafe-code-guidelines/pull/54#discussion_r240542790"},"pull_request":{"href":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/pulls/54"}},"in_reply_to_id":240377906},"pull_request":{"url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/pulls/54","id":237401293,"node_id":"MDExOlB1bGxSZXF1ZXN0MjM3NDAxMjkz","html_url":"https://github.com/rust-rfcs/unsafe-code-guidelines/pull/54","diff_url":"https://github.com/rust-rfcs/unsafe-code-guidelines/pull/54.diff","patch_url":"https://github.com/rust-rfcs/unsafe-code-guidelines/pull/54.patch","issue_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/issues/54","number":54,"state":"open","locked":false,"title":"Area proposal: validity invariants","user":{"login":"RalfJung","id":330628,"node_id":"MDQ6VXNlcjMzMDYyOA==","avatar_url":"https://avatars1.githubusercontent.com/u/330628?v=4","gravatar_id":"","url":"https://api.github.com/users/RalfJung","html_url":"https://github.com/RalfJung","followers_url":"https://api.github.com/users/RalfJung/followers","following_url":"https://api.github.com/users/RalfJung/following{/other_user}","gists_url":"https://api.github.com/users/RalfJung/gists{/gist_id}","starred_url":"https://api.github.com/users/RalfJung/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RalfJung/subscriptions","organizations_url":"https://api.github.com/users/RalfJung/orgs","repos_url":"https://api.github.com/users/RalfJung/repos","events_url":"https://api.github.com/users/RalfJung/events{/privacy}","received_events_url":"https://api.github.com/users/RalfJung/received_events","type":"User","site_admin":false},"body":"Which invariants derived from types are there that the compiler expects to be *always* maintained, and (equivalently) that unsafe code must *always* uphold (or else cause undefined behavior)?  This is what is called \"validity invariant\" in [my blog post](https://www.ralfj.de/blog/2018/08/22/two-kinds-of-invariants.html).\r\n\r\n\r\n### Goals\r\n\r\n* For every primitive type, determine which assumptions (if any) the compiler   makes about values *not* occurring at that type (serving as a lower bound for   what to declare invalid), and determine which popular patterns in unsafe code   might create \"interesting\" values of this type that safe code cannot create on   its own (serving as an upper bound for how much we want to declare invalid).   Both of these bounds are soft, but informative.\r\n* Based on that, map out a design space of invariants that seem reasonable.\r\n* Determine when exactly the validity invariant is assumed to hold.\r\n","created_at":"2018-12-10T17:20:06Z","updated_at":"2018-12-11T10:00:59Z","closed_at":null,"merged_at":null,"merge_commit_sha":"58bcd0e8e356cf5c4fa05e884423646a1994278c","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/pulls/54/commits","review_comments_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/pulls/54/comments","review_comment_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/pulls/comments{/number}","comments_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/issues/54/comments","statuses_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/statuses/c65b87bfbce989ed5627dc369124d6f1fab5b8a8","head":{"label":"RalfJung:validity","ref":"validity","sha":"c65b87bfbce989ed5627dc369124d6f1fab5b8a8","user":{"login":"RalfJung","id":330628,"node_id":"MDQ6VXNlcjMzMDYyOA==","avatar_url":"https://avatars1.githubusercontent.com/u/330628?v=4","gravatar_id":"","url":"https://api.github.com/users/RalfJung","html_url":"https://github.com/RalfJung","followers_url":"https://api.github.com/users/RalfJung/followers","following_url":"https://api.github.com/users/RalfJung/following{/other_user}","gists_url":"https://api.github.com/users/RalfJung/gists{/gist_id}","starred_url":"https://api.github.com/users/RalfJung/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RalfJung/subscriptions","organizations_url":"https://api.github.com/users/RalfJung/orgs","repos_url":"https://api.github.com/users/RalfJung/repos","events_url":"https://api.github.com/users/RalfJung/events{/privacy}","received_events_url":"https://api.github.com/users/RalfJung/received_events","type":"User","site_admin":false},"repo":{"id":146740208,"node_id":"MDEwOlJlcG9zaXRvcnkxNDY3NDAyMDg=","name":"unsafe-code-guidelines","full_name":"RalfJung/unsafe-code-guidelines","private":false,"owner":{"login":"RalfJung","id":330628,"node_id":"MDQ6VXNlcjMzMDYyOA==","avatar_url":"https://avatars1.githubusercontent.com/u/330628?v=4","gravatar_id":"","url":"https://api.github.com/users/RalfJung","html_url":"https://github.com/RalfJung","followers_url":"https://api.github.com/users/RalfJung/followers","following_url":"https://api.github.com/users/RalfJung/following{/other_user}","gists_url":"https://api.github.com/users/RalfJung/gists{/gist_id}","starred_url":"https://api.github.com/users/RalfJung/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RalfJung/subscriptions","organizations_url":"https://api.github.com/users/RalfJung/orgs","repos_url":"https://api.github.com/users/RalfJung/repos","events_url":"https://api.github.com/users/RalfJung/events{/privacy}","received_events_url":"https://api.github.com/users/RalfJung/received_events","type":"User","site_admin":false},"html_url":"https://github.com/RalfJung/unsafe-code-guidelines","description":"Home for the Unsafe Code Guidelines effort.","fork":true,"url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines","forks_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/forks","keys_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/keys{/key_id}","collaborators_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/teams","hooks_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/hooks","issue_events_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/issues/events{/number}","events_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/events","assignees_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/assignees{/user}","branches_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/branches{/branch}","tags_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/tags","blobs_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/git/refs{/sha}","trees_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/git/trees{/sha}","statuses_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/statuses/{sha}","languages_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/languages","stargazers_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/stargazers","contributors_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/contributors","subscribers_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/subscribers","subscription_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/subscription","commits_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/commits{/sha}","git_commits_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/git/commits{/sha}","comments_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/comments{/number}","issue_comment_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/issues/comments{/number}","contents_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/contents/{+path}","compare_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/compare/{base}...{head}","merges_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/merges","archive_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/downloads","issues_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/issues{/number}","pulls_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/pulls{/number}","milestones_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/milestones{/number}","notifications_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/labels{/name}","releases_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/releases{/id}","deployments_url":"https://api.github.com/repos/RalfJung/unsafe-code-guidelines/deployments","created_at":"2018-08-30T11:31:41Z","updated_at":"2018-08-30T11:31:42Z","pushed_at":"2018-12-10T17:19:00Z","git_url":"git://github.com/RalfJung/unsafe-code-guidelines.git","ssh_url":"git@github.com:RalfJung/unsafe-code-guidelines.git","clone_url":"https://github.com/RalfJung/unsafe-code-guidelines.git","svn_url":"https://github.com/RalfJung/unsafe-code-guidelines","homepage":null,"size":79,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"rust-rfcs:master","ref":"master","sha":"fb2ef0cf239a92faee6bd333ec013a858c312ec7","user":{"login":"rust-rfcs","id":40280837,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQwMjgwODM3","avatar_url":"https://avatars3.githubusercontent.com/u/40280837?v=4","gravatar_id":"","url":"https://api.github.com/users/rust-rfcs","html_url":"https://github.com/rust-rfcs","followers_url":"https://api.github.com/users/rust-rfcs/followers","following_url":"https://api.github.com/users/rust-rfcs/following{/other_user}","gists_url":"https://api.github.com/users/rust-rfcs/gists{/gist_id}","starred_url":"https://api.github.com/users/rust-rfcs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rust-rfcs/subscriptions","organizations_url":"https://api.github.com/users/rust-rfcs/orgs","repos_url":"https://api.github.com/users/rust-rfcs/repos","events_url":"https://api.github.com/users/rust-rfcs/events{/privacy}","received_events_url":"https://api.github.com/users/rust-rfcs/received_events","type":"Organization","site_admin":false},"repo":{"id":139737011,"node_id":"MDEwOlJlcG9zaXRvcnkxMzk3MzcwMTE=","name":"unsafe-code-guidelines","full_name":"rust-rfcs/unsafe-code-guidelines","private":false,"owner":{"login":"rust-rfcs","id":40280837,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQwMjgwODM3","avatar_url":"https://avatars3.githubusercontent.com/u/40280837?v=4","gravatar_id":"","url":"https://api.github.com/users/rust-rfcs","html_url":"https://github.com/rust-rfcs","followers_url":"https://api.github.com/users/rust-rfcs/followers","following_url":"https://api.github.com/users/rust-rfcs/following{/other_user}","gists_url":"https://api.github.com/users/rust-rfcs/gists{/gist_id}","starred_url":"https://api.github.com/users/rust-rfcs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rust-rfcs/subscriptions","organizations_url":"https://api.github.com/users/rust-rfcs/orgs","repos_url":"https://api.github.com/users/rust-rfcs/repos","events_url":"https://api.github.com/users/rust-rfcs/events{/privacy}","received_events_url":"https://api.github.com/users/rust-rfcs/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/rust-rfcs/unsafe-code-guidelines","description":"Home for the Unsafe Code Guidelines effort.","fork":false,"url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines","forks_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/forks","keys_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/teams","hooks_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/hooks","issue_events_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/issues/events{/number}","events_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/events","assignees_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/assignees{/user}","branches_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/branches{/branch}","tags_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/tags","blobs_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/git/refs{/sha}","trees_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/statuses/{sha}","languages_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/languages","stargazers_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/stargazers","contributors_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/contributors","subscribers_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/subscribers","subscription_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/subscription","commits_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/commits{/sha}","git_commits_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/git/commits{/sha}","comments_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/comments{/number}","issue_comment_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/issues/comments{/number}","contents_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/contents/{+path}","compare_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/merges","archive_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/downloads","issues_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/issues{/number}","pulls_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/pulls{/number}","milestones_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/milestones{/number}","notifications_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/labels{/name}","releases_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/releases{/id}","deployments_url":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/deployments","created_at":"2018-07-04T15:06:32Z","updated_at":"2018-12-08T14:51:33Z","pushed_at":"2018-12-10T20:27:39Z","git_url":"git://github.com/rust-rfcs/unsafe-code-guidelines.git","ssh_url":"git@github.com:rust-rfcs/unsafe-code-guidelines.git","clone_url":"https://github.com/rust-rfcs/unsafe-code-guidelines.git","svn_url":"https://github.com/rust-rfcs/unsafe-code-guidelines","homepage":null,"size":83,"stargazers_count":54,"watchers_count":54,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"archived":false,"open_issues_count":29,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":8,"open_issues":29,"watchers":54,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/pulls/54"},"html":{"href":"https://github.com/rust-rfcs/unsafe-code-guidelines/pull/54"},"issue":{"href":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/issues/54"},"comments":{"href":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/issues/54/comments"},"review_comments":{"href":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/pulls/54/comments"},"review_comment":{"href":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/pulls/54/commits"},"statuses":{"href":"https://api.github.com/repos/rust-rfcs/unsafe-code-guidelines/statuses/c65b87bfbce989ed5627dc369124d6f1fab5b8a8"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"gnzlbg"}}