{"action":"created","comment":{"url":"https://api.github.com/repos/google/go-cmp/pulls/comments/177811939","pull_request_review_id":107755145,"id":177811939,"diff_hunk":"@@ -267,6 +281,23 @@ func (s *state) compareAny(vx, vy reflect.Value) {\n \t\t\ts.report(vx.IsNil() && vy.IsNil(), vx, vy)\n \t\t\treturn\n \t\t}\n+\n+\t\t// NOTE: It is incorrect to call s.curPtrs.Push here as a slice is\n+\t\t// functionally a collection of pointers, rather than a single pointer.\n+\t\t// The pointer checking logic must be handled on a per-element basis\n+\t\t// in s.compareArray.\n+\t\t//\n+\t\t// For example v[:0] and v[:1] have the same slice pointer,\n+\t\t// but they are clearly different values. Using the slice pointer\n+\t\t// violates the assumption that equal pointers implies equal values.\n+\t\t/*\n+\t\t\tif eq, visited := s.curPtrs.Push(vx, vy); visited {\n+\t\t\t\ts.report(eq, vx, vy)\n+\t\t\t\treturn\n+\t\t\t}\n+\t\t\tdefer s.curPtrs.Pop(vx, vy)\n+\t\t*/","path":"cmp/compare.go","position":83,"original_position":83,"commit_id":"c4a7dde01dd245580b5ec9c47f831572478f029e","original_commit_id":"c4a7dde01dd245580b5ec9c47f831572478f029e","user":{"login":"dsnet","id":6354026,"avatar_url":"https://avatars1.githubusercontent.com/u/6354026?v=4","gravatar_id":"","url":"https://api.github.com/users/dsnet","html_url":"https://github.com/dsnet","followers_url":"https://api.github.com/users/dsnet/followers","following_url":"https://api.github.com/users/dsnet/following{/other_user}","gists_url":"https://api.github.com/users/dsnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dsnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dsnet/subscriptions","organizations_url":"https://api.github.com/users/dsnet/orgs","repos_url":"https://api.github.com/users/dsnet/repos","events_url":"https://api.github.com/users/dsnet/events{/privacy}","received_events_url":"https://api.github.com/users/dsnet/received_events","type":"User","site_admin":false},"body":"Done.","created_at":"2018-03-28T16:34:28Z","updated_at":"2018-03-28T16:34:29Z","html_url":"https://github.com/google/go-cmp/pull/85#discussion_r177811939","pull_request_url":"https://api.github.com/repos/google/go-cmp/pulls/85","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/google/go-cmp/pulls/comments/177811939"},"html":{"href":"https://github.com/google/go-cmp/pull/85#discussion_r177811939"},"pull_request":{"href":"https://api.github.com/repos/google/go-cmp/pulls/85"}},"in_reply_to_id":177779549},"pull_request":{"url":"https://api.github.com/repos/google/go-cmp/pulls/85","id":177643790,"html_url":"https://github.com/google/go-cmp/pull/85","diff_url":"https://github.com/google/go-cmp/pull/85.diff","patch_url":"https://github.com/google/go-cmp/pull/85.patch","issue_url":"https://api.github.com/repos/google/go-cmp/issues/85","number":85,"state":"open","locked":false,"title":"Add support for comparing graphs","user":{"login":"dsnet","id":6354026,"avatar_url":"https://avatars1.githubusercontent.com/u/6354026?v=4","gravatar_id":"","url":"https://api.github.com/users/dsnet","html_url":"https://github.com/dsnet","followers_url":"https://api.github.com/users/dsnet/followers","following_url":"https://api.github.com/users/dsnet/following{/other_user}","gists_url":"https://api.github.com/users/dsnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dsnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dsnet/subscriptions","organizations_url":"https://api.github.com/users/dsnet/orgs","repos_url":"https://api.github.com/users/dsnet/repos","events_url":"https://api.github.com/users/dsnet/events{/privacy}","received_events_url":"https://api.github.com/users/dsnet/received_events","type":"User","site_admin":false},"body":"Previously, trying to call Equal on a graph would result in a stack-overflow\r\ndue to infinite recursion traversing cycles on a graph.\r\nWhile a vast majority of Go values are trees or acyclic graphs, there exist\r\na small number of cases where graph equality is required.\r\n\r\nAs such, we add cycle detection to Equal and define what it means for two graphs\r\nto be equal. Contrary to reflect.DeepEqual, which declares two graphs to be\r\nequal so long any cycle were encountered, we require two graphs to have\r\nequivalent graph structures.\r\n\r\nMathematically speaking, a graph G is a tuple (V, E) consisting of the set of\r\nvertices and edges in that graph. Graphs G1 and G2 are equal if V1 == V2,\r\nE1 == E2, and both have the same root vertex (entry point into the graph).\r\nWhen traversing G1 and G2, we remember a stack of previously visited edges\r\nES1 and ES2. If the current edge e1 is in ES1 or e2 is in ES2, then we know that\r\na cycle exists. The graphs have the same structure when the previously\r\nencountered edge ep1 and ep2 were encountered together.\r\nNote that edges and vertices unreachable from the root vertex are ignored.\r\n\r\nIn addition to adding cycle detection, we fix some other issues:\r\n* Fix formatting of cyclic data structures. It is not safe simply storing\r\nan uintptr as this assumes the runtime never has a moving GC. Instead, we should\r\nuse unsafe.Pointer, which the GC knows how to scan.\r\n* Since AppEngine cannot use unsafe, we continue to use uintptr in the \"purego\"\r\nenvironment. The pointer package creates an abstraction over opaque pointers.\r\n\r\nAppreciation goes to Eyal Posener (@posener), who proposed a different\r\n(but semantically equivalent) approach in #79, which served as inspiration.\r\n\r\nFixes #74","created_at":"2018-03-27T06:36:18Z","updated_at":"2018-03-28T16:34:29Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4e6f4cd1d610faf908aadae3d053fe5d006740b9","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/google/go-cmp/pulls/85/commits","review_comments_url":"https://api.github.com/repos/google/go-cmp/pulls/85/comments","review_comment_url":"https://api.github.com/repos/google/go-cmp/pulls/comments{/number}","comments_url":"https://api.github.com/repos/google/go-cmp/issues/85/comments","statuses_url":"https://api.github.com/repos/google/go-cmp/statuses/c4a7dde01dd245580b5ec9c47f831572478f029e","head":{"label":"google:cycles","ref":"cycles","sha":"c4a7dde01dd245580b5ec9c47f831572478f029e","user":{"login":"google","id":1342004,"avatar_url":"https://avatars1.githubusercontent.com/u/1342004?v=4","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"repo":{"id":96570421,"name":"go-cmp","full_name":"google/go-cmp","owner":{"login":"google","id":1342004,"avatar_url":"https://avatars1.githubusercontent.com/u/1342004?v=4","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/google/go-cmp","description":"Package for comparing Go values in tests","fork":false,"url":"https://api.github.com/repos/google/go-cmp","forks_url":"https://api.github.com/repos/google/go-cmp/forks","keys_url":"https://api.github.com/repos/google/go-cmp/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/go-cmp/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/go-cmp/teams","hooks_url":"https://api.github.com/repos/google/go-cmp/hooks","issue_events_url":"https://api.github.com/repos/google/go-cmp/issues/events{/number}","events_url":"https://api.github.com/repos/google/go-cmp/events","assignees_url":"https://api.github.com/repos/google/go-cmp/assignees{/user}","branches_url":"https://api.github.com/repos/google/go-cmp/branches{/branch}","tags_url":"https://api.github.com/repos/google/go-cmp/tags","blobs_url":"https://api.github.com/repos/google/go-cmp/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/go-cmp/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/go-cmp/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/go-cmp/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/go-cmp/statuses/{sha}","languages_url":"https://api.github.com/repos/google/go-cmp/languages","stargazers_url":"https://api.github.com/repos/google/go-cmp/stargazers","contributors_url":"https://api.github.com/repos/google/go-cmp/contributors","subscribers_url":"https://api.github.com/repos/google/go-cmp/subscribers","subscription_url":"https://api.github.com/repos/google/go-cmp/subscription","commits_url":"https://api.github.com/repos/google/go-cmp/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/go-cmp/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/go-cmp/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/go-cmp/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/go-cmp/contents/{+path}","compare_url":"https://api.github.com/repos/google/go-cmp/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/go-cmp/merges","archive_url":"https://api.github.com/repos/google/go-cmp/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/go-cmp/downloads","issues_url":"https://api.github.com/repos/google/go-cmp/issues{/number}","pulls_url":"https://api.github.com/repos/google/go-cmp/pulls{/number}","milestones_url":"https://api.github.com/repos/google/go-cmp/milestones{/number}","notifications_url":"https://api.github.com/repos/google/go-cmp/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/go-cmp/labels{/name}","releases_url":"https://api.github.com/repos/google/go-cmp/releases{/id}","deployments_url":"https://api.github.com/repos/google/go-cmp/deployments","created_at":"2017-07-07T19:28:22Z","updated_at":"2018-03-28T00:27:15Z","pushed_at":"2018-03-28T07:24:55Z","git_url":"git://github.com/google/go-cmp.git","ssh_url":"git@github.com:google/go-cmp.git","clone_url":"https://github.com/google/go-cmp.git","svn_url":"https://github.com/google/go-cmp","homepage":"","size":170,"stargazers_count":510,"watchers_count":510,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":19,"mirror_url":null,"archived":false,"open_issues_count":12,"license":{"key":"bsd-3-clause","name":"BSD 3-Clause \"New\" or \"Revised\" License","spdx_id":"BSD-3-Clause","url":"https://api.github.com/licenses/bsd-3-clause"},"forks":19,"open_issues":12,"watchers":510,"default_branch":"master"}},"base":{"label":"google:master","ref":"master","sha":"ee94d64345b1a47755c8120c313605a7cb657619","user":{"login":"google","id":1342004,"avatar_url":"https://avatars1.githubusercontent.com/u/1342004?v=4","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"repo":{"id":96570421,"name":"go-cmp","full_name":"google/go-cmp","owner":{"login":"google","id":1342004,"avatar_url":"https://avatars1.githubusercontent.com/u/1342004?v=4","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/google/go-cmp","description":"Package for comparing Go values in tests","fork":false,"url":"https://api.github.com/repos/google/go-cmp","forks_url":"https://api.github.com/repos/google/go-cmp/forks","keys_url":"https://api.github.com/repos/google/go-cmp/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/go-cmp/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/go-cmp/teams","hooks_url":"https://api.github.com/repos/google/go-cmp/hooks","issue_events_url":"https://api.github.com/repos/google/go-cmp/issues/events{/number}","events_url":"https://api.github.com/repos/google/go-cmp/events","assignees_url":"https://api.github.com/repos/google/go-cmp/assignees{/user}","branches_url":"https://api.github.com/repos/google/go-cmp/branches{/branch}","tags_url":"https://api.github.com/repos/google/go-cmp/tags","blobs_url":"https://api.github.com/repos/google/go-cmp/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/go-cmp/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/go-cmp/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/go-cmp/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/go-cmp/statuses/{sha}","languages_url":"https://api.github.com/repos/google/go-cmp/languages","stargazers_url":"https://api.github.com/repos/google/go-cmp/stargazers","contributors_url":"https://api.github.com/repos/google/go-cmp/contributors","subscribers_url":"https://api.github.com/repos/google/go-cmp/subscribers","subscription_url":"https://api.github.com/repos/google/go-cmp/subscription","commits_url":"https://api.github.com/repos/google/go-cmp/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/go-cmp/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/go-cmp/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/go-cmp/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/go-cmp/contents/{+path}","compare_url":"https://api.github.com/repos/google/go-cmp/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/go-cmp/merges","archive_url":"https://api.github.com/repos/google/go-cmp/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/go-cmp/downloads","issues_url":"https://api.github.com/repos/google/go-cmp/issues{/number}","pulls_url":"https://api.github.com/repos/google/go-cmp/pulls{/number}","milestones_url":"https://api.github.com/repos/google/go-cmp/milestones{/number}","notifications_url":"https://api.github.com/repos/google/go-cmp/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/go-cmp/labels{/name}","releases_url":"https://api.github.com/repos/google/go-cmp/releases{/id}","deployments_url":"https://api.github.com/repos/google/go-cmp/deployments","created_at":"2017-07-07T19:28:22Z","updated_at":"2018-03-28T00:27:15Z","pushed_at":"2018-03-28T07:24:55Z","git_url":"git://github.com/google/go-cmp.git","ssh_url":"git@github.com:google/go-cmp.git","clone_url":"https://github.com/google/go-cmp.git","svn_url":"https://github.com/google/go-cmp","homepage":"","size":170,"stargazers_count":510,"watchers_count":510,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":19,"mirror_url":null,"archived":false,"open_issues_count":12,"license":{"key":"bsd-3-clause","name":"BSD 3-Clause \"New\" or \"Revised\" License","spdx_id":"BSD-3-Clause","url":"https://api.github.com/licenses/bsd-3-clause"},"forks":19,"open_issues":12,"watchers":510,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/google/go-cmp/pulls/85"},"html":{"href":"https://github.com/google/go-cmp/pull/85"},"issue":{"href":"https://api.github.com/repos/google/go-cmp/issues/85"},"comments":{"href":"https://api.github.com/repos/google/go-cmp/issues/85/comments"},"review_comments":{"href":"https://api.github.com/repos/google/go-cmp/pulls/85/comments"},"review_comment":{"href":"https://api.github.com/repos/google/go-cmp/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/google/go-cmp/pulls/85/commits"},"statuses":{"href":"https://api.github.com/repos/google/go-cmp/statuses/c4a7dde01dd245580b5ec9c47f831572478f029e"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"dsnet"}}