{"action":"created","comment":{"url":"https://api.github.com/repos/rust-lang/rfcs/pulls/comments/26937727","id":26937727,"diff_hunk":"@@ -0,0 +1,96 @@\n+- Feature Name: reformed_fn_pointers\n+- Start Date: 2015-03-21\n+- RFC PR: (leave this empty)\n+- Rust Issue: (leave this empty)\n+\n+# Summary\n+\n+Repurpose Rust's current function pointer types to denote \"incomplete function items\", and introduce function reference types and new function pointer types, so that function references/pointers work more like value references/pointers.\n+\n+This is based on [RFC 883](https://github.com/rust-lang/rfcs/pull/883) and related discussions, where the following design is already largely agreed upon, but the author of RFC 883 doesn't have time to revise it. Therefore, this RFC is created to push for the changes.\n+\n+# Motivation\n+\n+Currently in Rust, there are two kinds of types that represent functions:\n+\n+1. Function item types: the types of function items, `fn(arg_list) -> ret_type {foo}`s.\n+2. Function pointer types: the types of pointers to functions, `fn(arg_list) -> ret_type`s.\n+\n+Though called \"function pointers\", the function pointer types are considered *value* types (not reference/pointer types) by the language, which has the following problems:\n+\n+1. Inconsistencies in the language, especially when it comes to FFI codes that deal with nullable foreign function pointers. \n+2. There is currently no easy way to express the lifetime constraint on a function pointer to a non-`'static` function, which in particular makes it harder to implement type-safe JIT-ed functions/hot-loaded plugins in the future.\n+\n+Thus, this RFC proposes the following solution.\n+\n+# Detailed design\n+\n+Repurpose current function pointer types to denote \"incomplete function items\". Introduce function reference types of the form `&fn(arg_list) -> ret_type` and new function pointer types of the form `*const fn(arg_list) -> ret_type`.\n+\n+In the following section, `fn{f}`s, `fn`s, `&fn`s and `*const fn`s denote function item types, current function pointer types, function reference types and new function pointer types, respectively. Those types are considered \"compatible\" if their `(arg_list) -> ret_type` parts match.\n+\n+The following rules will apply:\n+\n+1. `fn{f}`s are still function item types, or \"function handles/proxies/values\", whose representations and semantics remain unchanged.\n+2. `fn`s are no longer function pointer types, but types representing \"incomplete function items\", which are unsized statically and zero-sized dynamically.\n+3. `&fn`s are function reference types, DST pointers with auxiliary data of type `()`, and work like other references.\n+4. `*const fn`s are raw function pointer types that work as normally expected, and casting between compatible `&fn`s and `*const fn`s is valid.\n+5. There are no `&mut fn`s, also no `*mut fn`s.","path":"text/0000-reformed-fn-pointers.md","position":38,"original_position":38,"commit_id":"ed90b31cd8faf987eb1d21a6dafbb982e3bc2d6a","original_commit_id":"ed90b31cd8faf987eb1d21a6dafbb982e3bc2d6a","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":"as I mentioned, you can't prevent such types, but that's ok","created_at":"2015-03-23T13:57:07Z","updated_at":"2015-03-23T13:57:07Z","html_url":"https://github.com/rust-lang/rfcs/pull/996#discussion_r26937727","pull_request_url":"https://api.github.com/repos/rust-lang/rfcs/pulls/996","_links":{"self":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/comments/26937727"},"html":{"href":"https://github.com/rust-lang/rfcs/pull/996#discussion_r26937727"},"pull_request":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/996"}}},"pull_request":{"url":"https://api.github.com/repos/rust-lang/rfcs/pulls/996","id":31667963,"html_url":"https://github.com/rust-lang/rfcs/pull/996","diff_url":"https://github.com/rust-lang/rfcs/pull/996.diff","patch_url":"https://github.com/rust-lang/rfcs/pull/996.patch","issue_url":"https://api.github.com/repos/rust-lang/rfcs/issues/996","number":996,"state":"open","locked":false,"title":"RFC: Function pointers reform","user":{"login":"CloudiDust","id":30068,"avatar_url":"https://avatars.githubusercontent.com/u/30068?v=3","gravatar_id":"","url":"https://api.github.com/users/CloudiDust","html_url":"https://github.com/CloudiDust","followers_url":"https://api.github.com/users/CloudiDust/followers","following_url":"https://api.github.com/users/CloudiDust/following{/other_user}","gists_url":"https://api.github.com/users/CloudiDust/gists{/gist_id}","starred_url":"https://api.github.com/users/CloudiDust/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CloudiDust/subscriptions","organizations_url":"https://api.github.com/users/CloudiDust/orgs","repos_url":"https://api.github.com/users/CloudiDust/repos","events_url":"https://api.github.com/users/CloudiDust/events{/privacy}","received_events_url":"https://api.github.com/users/CloudiDust/received_events","type":"User","site_admin":false},"body":"Repurpose Rust's current function pointer types to denote \"incomplete function items\", and introduce function reference types and new function pointer types, so that function references/pointers work more like value references/pointers.\r\n\r\nThis is based on #883 and related discussions, where the design is already largely agreed upon. The author of #883, @Ericson2314 is too busy to update that RFC, so this RFC is created.\r\n\r\n[Rendered](https://github.com/CloudiDust/rfcs/blob/reformed-fn-pointers/text/0000-reformed-fn-pointers.md)","created_at":"2015-03-21T07:58:05Z","updated_at":"2015-03-23T13:57:07Z","closed_at":null,"merged_at":null,"merge_commit_sha":"bc3cc57d89b63cb637e672c10d94a28ce37b5172","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/rust-lang/rfcs/pulls/996/commits","review_comments_url":"https://api.github.com/repos/rust-lang/rfcs/pulls/996/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/996/comments","statuses_url":"https://api.github.com/repos/rust-lang/rfcs/statuses/ed90b31cd8faf987eb1d21a6dafbb982e3bc2d6a","head":{"label":"CloudiDust:reformed-fn-pointers","ref":"reformed-fn-pointers","sha":"ed90b31cd8faf987eb1d21a6dafbb982e3bc2d6a","user":{"login":"CloudiDust","id":30068,"avatar_url":"https://avatars.githubusercontent.com/u/30068?v=3","gravatar_id":"","url":"https://api.github.com/users/CloudiDust","html_url":"https://github.com/CloudiDust","followers_url":"https://api.github.com/users/CloudiDust/followers","following_url":"https://api.github.com/users/CloudiDust/following{/other_user}","gists_url":"https://api.github.com/users/CloudiDust/gists{/gist_id}","starred_url":"https://api.github.com/users/CloudiDust/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CloudiDust/subscriptions","organizations_url":"https://api.github.com/users/CloudiDust/orgs","repos_url":"https://api.github.com/users/CloudiDust/repos","events_url":"https://api.github.com/users/CloudiDust/events{/privacy}","received_events_url":"https://api.github.com/users/CloudiDust/received_events","type":"User","site_admin":false},"repo":{"id":23272570,"name":"rfcs","full_name":"CloudiDust/rfcs","owner":{"login":"CloudiDust","id":30068,"avatar_url":"https://avatars.githubusercontent.com/u/30068?v=3","gravatar_id":"","url":"https://api.github.com/users/CloudiDust","html_url":"https://github.com/CloudiDust","followers_url":"https://api.github.com/users/CloudiDust/followers","following_url":"https://api.github.com/users/CloudiDust/following{/other_user}","gists_url":"https://api.github.com/users/CloudiDust/gists{/gist_id}","starred_url":"https://api.github.com/users/CloudiDust/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CloudiDust/subscriptions","organizations_url":"https://api.github.com/users/CloudiDust/orgs","repos_url":"https://api.github.com/users/CloudiDust/repos","events_url":"https://api.github.com/users/CloudiDust/events{/privacy}","received_events_url":"https://api.github.com/users/CloudiDust/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/CloudiDust/rfcs","description":"RFCs for changes to Rust","fork":true,"url":"https://api.github.com/repos/CloudiDust/rfcs","forks_url":"https://api.github.com/repos/CloudiDust/rfcs/forks","keys_url":"https://api.github.com/repos/CloudiDust/rfcs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CloudiDust/rfcs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CloudiDust/rfcs/teams","hooks_url":"https://api.github.com/repos/CloudiDust/rfcs/hooks","issue_events_url":"https://api.github.com/repos/CloudiDust/rfcs/issues/events{/number}","events_url":"https://api.github.com/repos/CloudiDust/rfcs/events","assignees_url":"https://api.github.com/repos/CloudiDust/rfcs/assignees{/user}","branches_url":"https://api.github.com/repos/CloudiDust/rfcs/branches{/branch}","tags_url":"https://api.github.com/repos/CloudiDust/rfcs/tags","blobs_url":"https://api.github.com/repos/CloudiDust/rfcs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CloudiDust/rfcs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CloudiDust/rfcs/git/refs{/sha}","trees_url":"https://api.github.com/repos/CloudiDust/rfcs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CloudiDust/rfcs/statuses/{sha}","languages_url":"https://api.github.com/repos/CloudiDust/rfcs/languages","stargazers_url":"https://api.github.com/repos/CloudiDust/rfcs/stargazers","contributors_url":"https://api.github.com/repos/CloudiDust/rfcs/contributors","subscribers_url":"https://api.github.com/repos/CloudiDust/rfcs/subscribers","subscription_url":"https://api.github.com/repos/CloudiDust/rfcs/subscription","commits_url":"https://api.github.com/repos/CloudiDust/rfcs/commits{/sha}","git_commits_url":"https://api.github.com/repos/CloudiDust/rfcs/git/commits{/sha}","comments_url":"https://api.github.com/repos/CloudiDust/rfcs/comments{/number}","issue_comment_url":"https://api.github.com/repos/CloudiDust/rfcs/issues/comments{/number}","contents_url":"https://api.github.com/repos/CloudiDust/rfcs/contents/{+path}","compare_url":"https://api.github.com/repos/CloudiDust/rfcs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CloudiDust/rfcs/merges","archive_url":"https://api.github.com/repos/CloudiDust/rfcs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CloudiDust/rfcs/downloads","issues_url":"https://api.github.com/repos/CloudiDust/rfcs/issues{/number}","pulls_url":"https://api.github.com/repos/CloudiDust/rfcs/pulls{/number}","milestones_url":"https://api.github.com/repos/CloudiDust/rfcs/milestones{/number}","notifications_url":"https://api.github.com/repos/CloudiDust/rfcs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CloudiDust/rfcs/labels{/name}","releases_url":"https://api.github.com/repos/CloudiDust/rfcs/releases{/id}","created_at":"2014-08-24T03:53:11Z","updated_at":"2014-08-22T05:10:20Z","pushed_at":"2015-03-23T13:24:04Z","git_url":"git://github.com/CloudiDust/rfcs.git","ssh_url":"git@github.com:CloudiDust/rfcs.git","clone_url":"https://github.com/CloudiDust/rfcs.git","svn_url":"https://github.com/CloudiDust/rfcs","homepage":"","size":1954,"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":"int-to-intx"}},"base":{"label":"rust-lang:master","ref":"master","sha":"e4a774f89d97bd6264ef3b8e4e676cafbc20059c","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-03-21T08:19:26Z","pushed_at":"2015-03-23T13:24:05Z","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":10211,"stargazers_count":287,"watchers_count":287,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":178,"mirror_url":null,"open_issues_count":476,"forks":178,"open_issues":476,"watchers":287,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/996"},"html":{"href":"https://github.com/rust-lang/rfcs/pull/996"},"issue":{"href":"https://api.github.com/repos/rust-lang/rfcs/issues/996"},"comments":{"href":"https://api.github.com/repos/rust-lang/rfcs/issues/996/comments"},"review_comments":{"href":"https://api.github.com/repos/rust-lang/rfcs/pulls/996/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/996/commits"},"statuses":{"href":"https://api.github.com/repos/rust-lang/rfcs/statuses/ed90b31cd8faf987eb1d21a6dafbb982e3bc2d6a"}}}}