{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rfcs/issues/1825","repository_url":"https://api.github.com/repos/rust-lang/rfcs","labels_url":"https://api.github.com/repos/rust-lang/rfcs/issues/1825/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rfcs/issues/1825/comments","events_url":"https://api.github.com/repos/rust-lang/rfcs/issues/1825/events","html_url":"https://github.com/rust-lang/rfcs/issues/1825","id":196876608,"number":1825,"title":"Make `<T as Trait>::U == V` always succeed if `<T as Trait>::U` is `!`","user":{"login":"spinda","id":7958605,"avatar_url":"https://avatars.githubusercontent.com/u/7958605?v=3","gravatar_id":"","url":"https://api.github.com/users/spinda","html_url":"https://github.com/spinda","followers_url":"https://api.github.com/users/spinda/followers","following_url":"https://api.github.com/users/spinda/following{/other_user}","gists_url":"https://api.github.com/users/spinda/gists{/gist_id}","starred_url":"https://api.github.com/users/spinda/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spinda/subscriptions","organizations_url":"https://api.github.com/users/spinda/orgs","repos_url":"https://api.github.com/users/spinda/repos","events_url":"https://api.github.com/users/spinda/events{/privacy}","received_events_url":"https://api.github.com/users/spinda/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":13,"created_at":"2016-12-21T08:47:42Z","updated_at":"2016-12-24T00:07:04Z","closed_at":null,"body":"Using `#![feature(never_type)]` from [RFC 1216](https://github.com/rust-lang/rust/issues/35121), I'd like to write a [`Future`](http://alexcrichton.com/futures-rs/futures/future/trait.Future.html) instance for `!`, so that the following compiles:\r\n\r\n```rust\r\n#![feature(never_type)]\r\n\r\nuse futures::future::Future;\r\nuse std::io::Error;\r\n\r\nfn main() {\r\n    // the type of `panic!()` doesn't matter as the function call is unreachable\r\n    i_take_a_future(panic!());\r\n}\r\n\r\nfn i_take_a_future<F>(f: F)\r\n    where F: Future<Item = u8, Error = Error>\r\n{\r\n    // do whatever with the future\r\n}\r\n```\r\n\r\nAs described in RFC 1216, any trait whose only associated items are methods has a trivial instance for `!`: just fill in every method body with `match self {}`. `Future`, however, has two associated types, `Item` and `Error`. Definitions reproduced from `futures-rs`:\r\n\r\n```rust\r\ntrait Future {\r\n    type Item;\r\n    type Error;\r\n    \r\n    fn poll(&mut self) -> Poll<Self::Item, Self::Error>;\r\n}\r\n\r\ntype Poll<T, E> = Result<Async<T>, E>;\r\n\r\nenum Async<T> {\r\n    Ready(T),\r\n    NotReady,\r\n}\r\n```\r\n\r\nA `Future` instance for `!` can be written as follows:\r\n\r\n```rust\r\n\r\nimpl Future for ! {\r\n    type Item = !;\r\n    type Error = !;\r\n    \r\n    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {\r\n        match self {}\r\n    }\r\n}\r\n```\r\n\r\nThis works in nightly Rust, but the instance isn't very useful, as it can only be used where `Item` and `Error` are expected to be `!`. Trying the initial example produces a type match error:\r\n\r\n```\r\nerror[E0271]: type mismatch resolving `<! as Future>::Item == u8`\r\n  --> <anon>\r\n   |\r\n   |     i_take_a_future(panic!());\r\n   |     ^^^^^^^^^^^^^^^ expected !, found u8\r\n   |\r\n   = note: expected type `!`\r\n   = note:    found type `u8`\r\n   = note: required by `i_take_a_future`\r\n\r\nerror[E0271]: type mismatch resolving `<! as Future>::Error == std::io::Error`\r\n  --> <anon>\r\n   |\r\n   |     i_take_a_future(panic!());\r\n   |     ^^^^^^^^^^^^^^^ expected !, found struct `std::io::Error`\r\n   |\r\n   = note: expected type `!`\r\n   = note:    found type `std::io::Error`\r\n   = note: required by `i_take_a_future`\r\n```\r\n\r\nAs far as I can tell, it would be safe for any `<T as Trait>::U == V` to match successfully if `<T as Trait>::U` is `!`, in the same way that expressions of type `!` can implicitly cast cast to any type, because a value of type `!` can never actually be produced."},"comment":{"url":"https://api.github.com/repos/rust-lang/rfcs/issues/comments/269058858","html_url":"https://github.com/rust-lang/rfcs/issues/1825#issuecomment-269058858","issue_url":"https://api.github.com/repos/rust-lang/rfcs/issues/1825","id":269058858,"user":{"login":"aturon","id":709807,"avatar_url":"https://avatars.githubusercontent.com/u/709807?v=3","gravatar_id":"","url":"https://api.github.com/users/aturon","html_url":"https://github.com/aturon","followers_url":"https://api.github.com/users/aturon/followers","following_url":"https://api.github.com/users/aturon/following{/other_user}","gists_url":"https://api.github.com/users/aturon/gists{/gist_id}","starred_url":"https://api.github.com/users/aturon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aturon/subscriptions","organizations_url":"https://api.github.com/users/aturon/orgs","repos_url":"https://api.github.com/users/aturon/repos","events_url":"https://api.github.com/users/aturon/events{/privacy}","received_events_url":"https://api.github.com/users/aturon/received_events","type":"User","site_admin":false},"created_at":"2016-12-24T00:07:04Z","updated_at":"2016-12-24T00:07:04Z","body":"@canndrew That should work. My guess is that there's just some poor interaction between how specialization was written and the addition of `!` as a type. Feel free to open a dedicated bug and assign me, though it'll likely be a while before I can get to it."}}
{"actor":{"display_login":"aturon"}}