{"action":"created","comment":{"url":"https://api.github.com/repos/rust-lang/rust/pulls/comments/36695763","id":36695763,"diff_hunk":"@@ -0,0 +1,191 @@\n+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT\n+// file at the top-level directory of this distribution and at\n+// http://rust-lang.org/COPYRIGHT.\n+//\n+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n+// option. This file may not be copied, modified, or distributed\n+// except according to those terms.\n+\n+// The outlines relation `T: 'a` or `'a: 'b`.\n+\n+use middle::infer::InferCtxt;\n+use middle::ty::{self, RegionEscape, Ty};\n+\n+#[derive(Debug)]\n+pub enum Component<'tcx> {\n+    Region(ty::Region),\n+    Param(ty::ParamTy),\n+    UnresolvedInferenceVariable(ty::InferTy),\n+\n+    // Projections like `T::Foo` are tricky because a constraint like\n+    // `T::Foo: 'a` can be satisfied in so many ways. There may be a\n+    // where-clause that says `T::Foo: 'a`, or the defining trait may\n+    // include a bound like `type Foo: 'static`, or -- in the most\n+    // conservative way -- we can prove that `T: 'a` (more generally,\n+    // that all components in the projection outlive `'a`). This code\n+    // is not in a position to judge which is the best technique, so\n+    // we just product the projection as a component and leave it to\n+    // the consumer to decide (but see `EscapingProjection` below).\n+    Projection(ty::ProjectionTy<'tcx>),\n+\n+    // In the case where a projection has escaping regions -- meaning\n+    // regions bound within the type itself -- we always use\n+    // the most conservative rule, which requires that all components\n+    // outlive the bound. So for example if we had a type like this:\n+    //\n+    //     for<'a> Trait1<  <T as Trait2<'a,'b>>::Foo  >\n+    //                      ~~~~~~~~~~~~~~~~~~~~~~~~~\n+    //\n+    // then the inner projection (underlined) has an escaping region\n+    // `'a`. We consider that outer trait `'c` to meet a bound if `'b`\n+    // outlives `'b: 'c`, and we don't consider whether the trait\n+    // declares that `Foo: 'static` etc. Therefore, we just return the\n+    // free components of such a projection (in this case, `'b`).\n+    //\n+    // However, in the future, we may want to get smarter, and\n+    // actually return a \"higher-ranked projection\" here. Therefore,\n+    // we mark that these components are part of an escaping\n+    // projection, so that implied bounds code can avoid relying on\n+    // them. This gives us room to improve the regionck reasoning in\n+    // the future without breaking backwards compat.\n+    EscapingProjection(Vec<Component<'tcx>>),\n+\n+    RFC1214(Vec<Component<'tcx>>),\n+}\n+\n+/// Returns all the things that must outlive `'a` for the condition\n+/// `ty0: 'a` to hold.\n+pub fn components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,\n+                           ty0: Ty<'tcx>)\n+                           -> Vec<Component<'tcx>> {\n+    let mut components = vec![];\n+    compute_components(infcx, ty0, &mut components);\n+    debug!(\"outlives({:?}) = {:?}\", ty0, components);\n+    components\n+}\n+\n+fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,\n+                               ty0: Ty<'tcx>,\n+                               out: &mut Vec<Component<'tcx>>) {\n+    // Descend through the types, looking for the various \"base\"\n+    // components and collecting them into `out`. This is not written\n+    // with `collect()` because of the need to sometimes skip subtrees\n+    // in the `subtys` iterator (e.g., when encountering a\n+    // projection).\n+    let mut subtys = ty0.walk();\n+    while let Some(ty) = subtys.next() {\n+        match ty.sty {\n+            ty::TyClosure(_, ref substs) => {\n+                // FIXME(#27086). We do not accumulate from substs, since they\n+                // don't represent reachable data. This means that, in\n+                // practice, some of the lifetime parameters might not\n+                // be in scope when the body runs, so long as there is\n+                // no reachable data with that lifetime. For better or\n+                // worse, this is consistent with fn types, however,\n+                // which can also encapsulate data in this fashion\n+                // (though it's somewhat harder, and typically\n+                // requires virtual dispatch).\n+                //\n+                // Note that changing this (in a naive way, at least)\n+                // causes regressions for what appears to be perfectly\n+                // reasonable code like this:\n+                //\n+                // ```\n+                // fn foo<'a>(p: &Data<'a>) {\n+                //    bar(|q: &mut Parser| q.read_addr())\n+                // }\n+                // fn bar(p: Box<FnMut(&mut Parser)+'static>) {\n+                // }\n+                // ```\n+                //\n+                // Note that `p` (and `'a`) are not used in the\n+                // closure at all, but to meet the requirement that\n+                // the closure type `C: 'static` (so it can be coerced\n+                // to the object type), we get the requirement that\n+                // `'a: 'static` since `'a` appears in the closure\n+                // type `C`.\n+                //\n+                // A smarter fix might \"prune\" unused `func_substs` --\n+                // this would avoid breaking simple examples like\n+                // this, but would still break others (which might\n+                // indeed be invalid, depending on your POV). Pruning\n+                // would be a subtle process, since we have to see\n+                // what func/type parameters are used and unused,\n+                // taking into consideration UFCS and so forth.\n+\n+                for &upvar_ty in &substs.upvar_tys {\n+                    compute_components(infcx, upvar_ty, out);\n+                }\n+                subtys.skip_current_subtree();\n+            }\n+            ty::TyBareFn(..) | ty::TyTrait(..) => {\n+                subtys.skip_current_subtree();\n+                let temp = capture_components(infcx, ty);\n+                out.push(Component::RFC1214(temp));\n+            }\n+            ty::TyParam(p) => {\n+                out.push(Component::Param(p));\n+                subtys.skip_current_subtree();\n+            }\n+            ty::TyProjection(ref data) => {\n+                // For projections, we prefer to generate an\n+                // obligation like `<P0 as Trait<P1...Pn>>::Foo: 'a`,\n+                // because this gives the regionck more ways to prove\n+                // that it holds. However, regionck is not (at least\n+                // currently) prepared to deal with higher-ranked\n+                // regions that may appear in the\n+                // trait-ref. Therefore, if we see any higher-ranke\n+                // regions, we simply fallback to the most restrictive\n+                // rule, which requires that `Pi: 'a` for all `i`.\n+\n+                if !data.has_escaping_regions() {\n+                    // best case: no escaping reions, so push the\n+                    // projection and skip the subtree (thus\n+                    // generating no constraints for Pi).\n+                    out.push(Component::Projection(*data));\n+                } else {\n+                    // fallback case: continue walking through and\n+                    // constrain Pi.\n+                    let temp = capture_components(infcx, ty);\n+                    out.push(Component::EscapingProjection(temp));\n+                }\n+                subtys.skip_current_subtree();\n+            }\n+            ty::TyInfer(_) => {\n+                let ty = infcx.resolve_type_vars_if_possible(&ty);\n+                if let ty::TyInfer(infer_ty) = ty.sty {\n+                    out.push(Component::UnresolvedInferenceVariable(infer_ty));\n+                } else {\n+                    compute_components(infcx, ty, out);\n+                }\n+            }\n+            _ => {\n+                // for all other types, just constrain the regions and","path":"src/librustc/middle/outlives.rs","position":165,"original_position":165,"commit_id":"c8f7ee8a5d9c63b50b63f1ca2ba8974a9eca4ce0","original_commit_id":"c8f7ee8a5d9c63b50b63f1ca2ba8974a9eca4ce0","user":{"login":"arielb1","id":1830974,"avatar_url":"https://avatars.githubusercontent.com/u/1830974?v=3","gravatar_id":"","url":"https://api.github.com/users/arielb1","html_url":"https://github.com/arielb1","followers_url":"https://api.github.com/users/arielb1/followers","following_url":"https://api.github.com/users/arielb1/following{/other_user}","gists_url":"https://api.github.com/users/arielb1/gists{/gist_id}","starred_url":"https://api.github.com/users/arielb1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arielb1/subscriptions","organizations_url":"https://api.github.com/users/arielb1/orgs","repos_url":"https://api.github.com/users/arielb1/repos","events_url":"https://api.github.com/users/arielb1/events{/privacy}","received_events_url":"https://api.github.com/users/arielb1/received_events","type":"User","site_admin":false},"body":"I prefer to use a match instead of`Ty::walk`. It isn't so much longer in these cases, and it makes it harder to miss interesting variants, especially when new ones are added :-).","created_at":"2015-08-10T23:10:31Z","updated_at":"2015-08-10T23:10:31Z","html_url":"https://github.com/rust-lang/rust/pull/27641#discussion_r36695763","pull_request_url":"https://api.github.com/repos/rust-lang/rust/pulls/27641","_links":{"self":{"href":"https://api.github.com/repos/rust-lang/rust/pulls/comments/36695763"},"html":{"href":"https://github.com/rust-lang/rust/pull/27641#discussion_r36695763"},"pull_request":{"href":"https://api.github.com/repos/rust-lang/rust/pulls/27641"}}},"pull_request":{"url":"https://api.github.com/repos/rust-lang/rust/pulls/27641","id":42055798,"html_url":"https://github.com/rust-lang/rust/pull/27641","diff_url":"https://github.com/rust-lang/rust/pull/27641.diff","patch_url":"https://github.com/rust-lang/rust/pull/27641.patch","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/27641","number":27641,"state":"open","locked":false,"title":"Implement (most of) RFC 1214","user":{"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},"body":"This PR implements the majority of RFC 1214. In particular, it implements:\r\n\r\n- the new outlives relation\r\n- comprehensive WF checking\r\n\r\nFor the most part, new code receives warnings, not errors, though 3 regressions were found via a crater run. \r\n\r\nThere are some deviations from RFC 1214. Most notably:\r\n\r\n- we still consider implied bounds from fn ret; this intersects other soundness issues that I intend to address in detail in a follow-up RFC. Fixing this without breaking a lot of code probably requires rewriting compare-method somewhat (which is probably a good thing).\r\n- object types do not check trait bounds for fear of encountering `Self`; this was left as an unresolved question in RFC 1214, but ultimately feels inconsistent.\r\n\r\nBoth of those two issues are highlighted in the tracking issue, https://github.com/rust-lang/rust/issues/27579. #27579 also includes a testing matrix with new tests that I wrote -- these probably duplicate some existing tests, I tried to check but wasn't quite sure what to look for. I tried to be thorough in testing the WF relation, at least, but would welcome suggestions for missing tests.\r\n\r\nr? @nrc (or perhaps someone else?)","created_at":"2015-08-10T19:21:46Z","updated_at":"2015-08-10T23:10:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4d764690cee04ed8f2ee4404b3ab596b75498ddb","assignee":{"login":"nrc","id":762626,"avatar_url":"https://avatars.githubusercontent.com/u/762626?v=3","gravatar_id":"","url":"https://api.github.com/users/nrc","html_url":"https://github.com/nrc","followers_url":"https://api.github.com/users/nrc/followers","following_url":"https://api.github.com/users/nrc/following{/other_user}","gists_url":"https://api.github.com/users/nrc/gists{/gist_id}","starred_url":"https://api.github.com/users/nrc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nrc/subscriptions","organizations_url":"https://api.github.com/users/nrc/orgs","repos_url":"https://api.github.com/users/nrc/repos","events_url":"https://api.github.com/users/nrc/events{/privacy}","received_events_url":"https://api.github.com/users/nrc/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/rust-lang/rust/pulls/27641/commits","review_comments_url":"https://api.github.com/repos/rust-lang/rust/pulls/27641/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/27641/comments","statuses_url":"https://api.github.com/repos/rust-lang/rust/statuses/c8f7ee8a5d9c63b50b63f1ca2ba8974a9eca4ce0","head":{"label":"nikomatsakis:soundness-rfc-1214","ref":"soundness-rfc-1214","sha":"c8f7ee8a5d9c63b50b63f1ca2ba8974a9eca4ce0","user":{"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},"repo":{"id":1672543,"name":"rust","full_name":"nikomatsakis/rust","owner":{"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},"private":false,"html_url":"https://github.com/nikomatsakis/rust","description":"A work-in-progress programming language; not yet suitable for users","fork":true,"url":"https://api.github.com/repos/nikomatsakis/rust","forks_url":"https://api.github.com/repos/nikomatsakis/rust/forks","keys_url":"https://api.github.com/repos/nikomatsakis/rust/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nikomatsakis/rust/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nikomatsakis/rust/teams","hooks_url":"https://api.github.com/repos/nikomatsakis/rust/hooks","issue_events_url":"https://api.github.com/repos/nikomatsakis/rust/issues/events{/number}","events_url":"https://api.github.com/repos/nikomatsakis/rust/events","assignees_url":"https://api.github.com/repos/nikomatsakis/rust/assignees{/user}","branches_url":"https://api.github.com/repos/nikomatsakis/rust/branches{/branch}","tags_url":"https://api.github.com/repos/nikomatsakis/rust/tags","blobs_url":"https://api.github.com/repos/nikomatsakis/rust/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nikomatsakis/rust/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nikomatsakis/rust/git/refs{/sha}","trees_url":"https://api.github.com/repos/nikomatsakis/rust/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nikomatsakis/rust/statuses/{sha}","languages_url":"https://api.github.com/repos/nikomatsakis/rust/languages","stargazers_url":"https://api.github.com/repos/nikomatsakis/rust/stargazers","contributors_url":"https://api.github.com/repos/nikomatsakis/rust/contributors","subscribers_url":"https://api.github.com/repos/nikomatsakis/rust/subscribers","subscription_url":"https://api.github.com/repos/nikomatsakis/rust/subscription","commits_url":"https://api.github.com/repos/nikomatsakis/rust/commits{/sha}","git_commits_url":"https://api.github.com/repos/nikomatsakis/rust/git/commits{/sha}","comments_url":"https://api.github.com/repos/nikomatsakis/rust/comments{/number}","issue_comment_url":"https://api.github.com/repos/nikomatsakis/rust/issues/comments{/number}","contents_url":"https://api.github.com/repos/nikomatsakis/rust/contents/{+path}","compare_url":"https://api.github.com/repos/nikomatsakis/rust/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nikomatsakis/rust/merges","archive_url":"https://api.github.com/repos/nikomatsakis/rust/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nikomatsakis/rust/downloads","issues_url":"https://api.github.com/repos/nikomatsakis/rust/issues{/number}","pulls_url":"https://api.github.com/repos/nikomatsakis/rust/pulls{/number}","milestones_url":"https://api.github.com/repos/nikomatsakis/rust/milestones{/number}","notifications_url":"https://api.github.com/repos/nikomatsakis/rust/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nikomatsakis/rust/labels{/name}","releases_url":"https://api.github.com/repos/nikomatsakis/rust/releases{/id}","created_at":"2011-04-27T20:20:29Z","updated_at":"2014-07-10T00:11:47Z","pushed_at":"2015-08-10T19:15:18Z","git_url":"git://github.com/nikomatsakis/rust.git","ssh_url":"git@github.com:nikomatsakis/rust.git","clone_url":"https://github.com/nikomatsakis/rust.git","svn_url":"https://github.com/nikomatsakis/rust","homepage":"","size":325524,"stargazers_count":4,"watchers_count":4,"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":4,"default_branch":"master"}},"base":{"label":"rust-lang:master","ref":"master","sha":"96a1f40402cdd05d29d1f1c0b62001254db8dcf6","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-08-10T20:31:30Z","pushed_at":"2015-08-10T23:08:07Z","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":655893,"stargazers_count":12920,"watchers_count":12920,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":2506,"mirror_url":null,"open_issues_count":2176,"forks":2506,"open_issues":2176,"watchers":12920,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rust-lang/rust/pulls/27641"},"html":{"href":"https://github.com/rust-lang/rust/pull/27641"},"issue":{"href":"https://api.github.com/repos/rust-lang/rust/issues/27641"},"comments":{"href":"https://api.github.com/repos/rust-lang/rust/issues/27641/comments"},"review_comments":{"href":"https://api.github.com/repos/rust-lang/rust/pulls/27641/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/27641/commits"},"statuses":{"href":"https://api.github.com/repos/rust-lang/rust/statuses/c8f7ee8a5d9c63b50b63f1ca2ba8974a9eca4ce0"}}}}