{"action":"created","comment":{"url":"https://api.github.com/repos/rust-lang/rfcs/pulls/comments/167411378","pull_request_review_id":95633655,"id":167411378,"diff_hunk":"@@ -0,0 +1,232 @@\n+- Feature Name: safe_unsafe_trait_methods\n+- Start Date: 2018-01-30\n+- RFC PR: (leave this empty)\n+- Rust Issue: (leave this empty)\n+\n+# Summary\n+[summary]: #summary\n+\n+This RFC allows safe implementations of `unsafe` trait methods.\n+An `impl` may implement a trait with methods marked as `unsafe` without\n+marking the methods in the `impl` as `unsafe`. This is referred to as\n+*overconstraining* the method in the `impl`. When the trait's `unsafe`\n+method is called on a specific type where the method is known to be safe,\n+that call does not require an `unsafe` block.\n+\n+# Motivation","path":"text/0000-safe-unsafe-trait-methods.md","position":16,"original_position":16,"commit_id":"29c527bf702b53345439635c982a46cc6915f8a5","original_commit_id":"29c527bf702b53345439635c982a46cc6915f8a5","user":{"login":"cramertj","id":5963049,"avatar_url":"https://avatars1.githubusercontent.com/u/5963049?v=4","gravatar_id":"","url":"https://api.github.com/users/cramertj","html_url":"https://github.com/cramertj","followers_url":"https://api.github.com/users/cramertj/followers","following_url":"https://api.github.com/users/cramertj/following{/other_user}","gists_url":"https://api.github.com/users/cramertj/gists{/gist_id}","starred_url":"https://api.github.com/users/cramertj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cramertj/subscriptions","organizations_url":"https://api.github.com/users/cramertj/orgs","repos_url":"https://api.github.com/users/cramertj/repos","events_url":"https://api.github.com/users/cramertj/events{/privacy}","received_events_url":"https://api.github.com/users/cramertj/received_events","type":"User","site_admin":false},"body":"@sfackler This RFC was motivated in part by the upcoming changes to `futures-rs` that will allow immovable future types. In short, the original plan was to land something like this:\r\n\r\n```rust\r\ntrait Future {\r\n    trait Item;\r\n    trait Error;\r\n    unsafe fn poll_immovable(&mut self) -> Poll<Self::Item, Self::Error>;\r\n}\r\n\r\ntrait MovableFuture: Future {\r\n    fn poll(&mut self) -> Poll<Self::Item, Self::Error>;\r\n}\r\n```\r\n\r\nThis RFC would make it possible to implement `Future` without writing `unsafe`, which makes it easier to validate that `Future` impls are sound. The `Future` trait could also offer a custom-derive `#[derive(MovableFuture)]` which would expand to this:\r\n\r\n```rust\r\nimpl MovableFuture for MyType {\r\n    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {\r\n        self.poll_immovable()\r\n    |\r\n}\r\n```\r\n\r\nNote that the call to `poll_immovable` is not wrapped in an `unsafe` block. This will produce a compiler error iff the impl of `poll_immovable` is `unsafe`, but will work just fine for safe impls.\r\n\r\nIn @withoutboats's blog series, they and @eddyb discovered that `fn anchored_poll(self: Anchor<&mut Self>)` could be used to avoid the `unsafe poll_immovable`. Unfortunately, `anchored_poll` isn't object-safe (because of `arbitrary_self_types`), so we still need an underlying `poll_immovable` function under the hood.\r\n\r\nThere was also a suggestion to use `trait ImmovableFuture` and `trait Future` with `impl<T> ImmovableFuture for T where T: Future`. Unfortunately, this approach requires specialization in order to not conflict with impls like this:\r\n\r\n```rust\r\nstruct MyFutureCombinator<T> { .... }\r\n\r\nimpl<T> Future for MyFutureCombinator<T> where T: Future { ... }\r\nimpl<T> ImmovableFuture for MyFutureCombinator<T> where T: ImmovableFuture { ... }\r\n```\r\n\r\nThis all brings us back to `trait Future` and `trait MovableFuture: Future`, where `Future::poll_immovable` is `unsafe`. We want to be able to implement the trait safely, and this RFC would make that possible.","created_at":"2018-02-10T21:17:07Z","updated_at":"2018-02-10T21:17:07Z","html_url":"https://github.com/rust-lang/rfcs/pull/2316#discussion_r167411378","pull_request_url":"https://api.github.com/repos/rust-lang/rfcs/pulls/2316","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/comments/167411378"},"html":{"href":"https://github.com/rust-lang/rfcs/pull/2316#discussion_r167411378"},"pull_request":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/2316"}},"in_reply_to_id":164906460},"pull_request":{"url":"https://api.github.com/repos/rust-lang/rfcs/pulls/2316","id":166119904,"html_url":"https://github.com/rust-lang/rfcs/pull/2316","diff_url":"https://github.com/rust-lang/rfcs/pull/2316.diff","patch_url":"https://github.com/rust-lang/rfcs/pull/2316.patch","issue_url":"https://api.github.com/repos/rust-lang/rfcs/issues/2316","number":2316,"state":"open","locked":false,"title":"RFC: Overconstraining and omitting `unsafe` in impls of `unsafe` trait methods","user":{"login":"Centril","id":855702,"avatar_url":"https://avatars2.githubusercontent.com/u/855702?v=4","gravatar_id":"","url":"https://api.github.com/users/Centril","html_url":"https://github.com/Centril","followers_url":"https://api.github.com/users/Centril/followers","following_url":"https://api.github.com/users/Centril/following{/other_user}","gists_url":"https://api.github.com/users/Centril/gists{/gist_id}","starred_url":"https://api.github.com/users/Centril/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Centril/subscriptions","organizations_url":"https://api.github.com/users/Centril/orgs","repos_url":"https://api.github.com/users/Centril/repos","events_url":"https://api.github.com/users/Centril/events{/privacy}","received_events_url":"https://api.github.com/users/Centril/received_events","type":"User","site_admin":false},"body":"### [Rendered](https://github.com/Centril/rfcs/blob/rfc/safe-unsafe-trait-methods/text/0000-safe-unsafe-trait-methods.md)\r\n\r\n-----------------------\r\n\r\nThis RFC allows safe implementations of `unsafe` trait methods. An `impl` may implement a trait with methods marked as `unsafe` without marking the methods in the `impl` as `unsafe`. This is referred to as\r\n*overconstraining* the method in the `impl`. When the trait's `unsafe` method is called on a specific type where the method is known to be safe, that call does not require an `unsafe` block.\r\n\r\nA simple example:\r\n\r\n```rust\r\ntrait Foo { unsafe fn foo_computation(&self) -> u8; }\r\nstruct Bar;\r\nimpl Foo for Bar {\r\n    // unsafe <-- Not necessary anymore.\r\n    fn foo_computation(&self) -> u8 { 0 }\r\n}\r\nfn main() {\r\n    // unsafe { <-- no unsafe needed!\r\n    let val = Bar{}.foo_computation();\r\n    // other stuff..\r\n    // }\r\n}\r\n```\r\n\r\n-----------------------\r\n\r\nThis RFC was written in collaboration with @cramertj whom it was my pleasure to work with.\r\n\r\ncc @withoutboats @aturon ","created_at":"2018-01-30T22:50:56Z","updated_at":"2018-02-10T21:17:07Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3d6355273e27b1661d484dfd89141a3cbce02887","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":211667886,"url":"https://api.github.com/repos/rust-lang/rfcs/labels/T-lang","name":"T-lang","color":"bfd4f2","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/rust-lang/rfcs/pulls/2316/commits","review_comments_url":"https://api.github.com/repos/rust-lang/rfcs/pulls/2316/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/2316/comments","statuses_url":"https://api.github.com/repos/rust-lang/rfcs/statuses/29c527bf702b53345439635c982a46cc6915f8a5","head":{"label":"Centril:rfc/safe-unsafe-trait-methods","ref":"rfc/safe-unsafe-trait-methods","sha":"29c527bf702b53345439635c982a46cc6915f8a5","user":{"login":"Centril","id":855702,"avatar_url":"https://avatars2.githubusercontent.com/u/855702?v=4","gravatar_id":"","url":"https://api.github.com/users/Centril","html_url":"https://github.com/Centril","followers_url":"https://api.github.com/users/Centril/followers","following_url":"https://api.github.com/users/Centril/following{/other_user}","gists_url":"https://api.github.com/users/Centril/gists{/gist_id}","starred_url":"https://api.github.com/users/Centril/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Centril/subscriptions","organizations_url":"https://api.github.com/users/Centril/orgs","repos_url":"https://api.github.com/users/Centril/repos","events_url":"https://api.github.com/users/Centril/events{/privacy}","received_events_url":"https://api.github.com/users/Centril/received_events","type":"User","site_admin":false},"repo":{"id":103166643,"name":"rfcs","full_name":"Centril/rfcs","owner":{"login":"Centril","id":855702,"avatar_url":"https://avatars2.githubusercontent.com/u/855702?v=4","gravatar_id":"","url":"https://api.github.com/users/Centril","html_url":"https://github.com/Centril","followers_url":"https://api.github.com/users/Centril/followers","following_url":"https://api.github.com/users/Centril/following{/other_user}","gists_url":"https://api.github.com/users/Centril/gists{/gist_id}","starred_url":"https://api.github.com/users/Centril/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Centril/subscriptions","organizations_url":"https://api.github.com/users/Centril/orgs","repos_url":"https://api.github.com/users/Centril/repos","events_url":"https://api.github.com/users/Centril/events{/privacy}","received_events_url":"https://api.github.com/users/Centril/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Centril/rfcs","description":"RFCs for changes to Rust","fork":true,"url":"https://api.github.com/repos/Centril/rfcs","forks_url":"https://api.github.com/repos/Centril/rfcs/forks","keys_url":"https://api.github.com/repos/Centril/rfcs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Centril/rfcs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Centril/rfcs/teams","hooks_url":"https://api.github.com/repos/Centril/rfcs/hooks","issue_events_url":"https://api.github.com/repos/Centril/rfcs/issues/events{/number}","events_url":"https://api.github.com/repos/Centril/rfcs/events","assignees_url":"https://api.github.com/repos/Centril/rfcs/assignees{/user}","branches_url":"https://api.github.com/repos/Centril/rfcs/branches{/branch}","tags_url":"https://api.github.com/repos/Centril/rfcs/tags","blobs_url":"https://api.github.com/repos/Centril/rfcs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Centril/rfcs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Centril/rfcs/git/refs{/sha}","trees_url":"https://api.github.com/repos/Centril/rfcs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Centril/rfcs/statuses/{sha}","languages_url":"https://api.github.com/repos/Centril/rfcs/languages","stargazers_url":"https://api.github.com/repos/Centril/rfcs/stargazers","contributors_url":"https://api.github.com/repos/Centril/rfcs/contributors","subscribers_url":"https://api.github.com/repos/Centril/rfcs/subscribers","subscription_url":"https://api.github.com/repos/Centril/rfcs/subscription","commits_url":"https://api.github.com/repos/Centril/rfcs/commits{/sha}","git_commits_url":"https://api.github.com/repos/Centril/rfcs/git/commits{/sha}","comments_url":"https://api.github.com/repos/Centril/rfcs/comments{/number}","issue_comment_url":"https://api.github.com/repos/Centril/rfcs/issues/comments{/number}","contents_url":"https://api.github.com/repos/Centril/rfcs/contents/{+path}","compare_url":"https://api.github.com/repos/Centril/rfcs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Centril/rfcs/merges","archive_url":"https://api.github.com/repos/Centril/rfcs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Centril/rfcs/downloads","issues_url":"https://api.github.com/repos/Centril/rfcs/issues{/number}","pulls_url":"https://api.github.com/repos/Centril/rfcs/pulls{/number}","milestones_url":"https://api.github.com/repos/Centril/rfcs/milestones{/number}","notifications_url":"https://api.github.com/repos/Centril/rfcs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Centril/rfcs/labels{/name}","releases_url":"https://api.github.com/repos/Centril/rfcs/releases{/id}","deployments_url":"https://api.github.com/repos/Centril/rfcs/deployments","created_at":"2017-09-11T17:28:49Z","updated_at":"2017-09-10T06:26:55Z","pushed_at":"2018-02-06T00:12:08Z","git_url":"git://github.com/Centril/rfcs.git","ssh_url":"git@github.com:Centril/rfcs.git","clone_url":"https://github.com/Centril/rfcs.git","svn_url":"https://github.com/Centril/rfcs","homepage":"","size":5119,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"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-lang:master","ref":"master","sha":"f6004d6d6350dcbc1a9bf6ab502d9beddb1c9c0f","user":{"login":"rust-lang","id":5430905,"avatar_url":"https://avatars1.githubusercontent.com/u/5430905?v=4","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://avatars1.githubusercontent.com/u/5430905?v=4","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}","deployments_url":"https://api.github.com/repos/rust-lang/rfcs/deployments","created_at":"2014-03-07T21:29:00Z","updated_at":"2018-02-10T11:28:24Z","pushed_at":"2018-02-10T13:16:10Z","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":"http://rust-lang.github.io/rfcs/","size":12648,"stargazers_count":1323,"watchers_count":1323,"language":"Shell","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":562,"mirror_url":null,"archived":false,"open_issues_count":753,"license":null,"forks":562,"open_issues":753,"watchers":1323,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/2316"},"html":{"href":"https://github.com/rust-lang/rfcs/pull/2316"},"issue":{"href":"https://api.github.com/repos/rust-lang/rfcs/issues/2316"},"comments":{"href":"https://api.github.com/repos/rust-lang/rfcs/issues/2316/comments"},"review_comments":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/2316/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/2316/commits"},"statuses":{"href":"https://api.github.com/repos/rust-lang/rfcs/statuses/29c527bf702b53345439635c982a46cc6915f8a5"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"cramertj"}}