Reported by @xfix in https://github.com/rust-lang/rust/issues/33417#issuecomment-467053097.
trait MyTrait {
type Output;
}
impl<T> MyTrait for fn() -> T {
type Output = T;
}
type Void = <fn() -> ! as MyTrait>::Output;
fn main() {
let _a: Void;
}
The never type is unstable (https://github.com/rust-lang/rust/issues/35121) but the code above (which doesn鈥檛 use any feature gate) compiles in Rust 1.12.0 (which I think is the first with https://github.com/rust-lang/rust/pull/35162), 1.32.0, and 1.34.0-nightly (aadbc459b 2019-02-23). In 1.11.0, it errors with:
error: the trait bound `fn() -> !: MyTrait` is not satisfied [--explain E0277]
--> a.rs:12:13
|>
12 |> let _a: Void;
|> ^^^^
help: the following implementations were found:
help: <fn() -> T as MyTrait>
error: aborting due to previous error
This case can be reduced to the following:
fn foo() -> ! {
unimplemented!()
}
which is as a result of this // Do nothing special-case in the feature gate code:
https://github.com/rust-lang/rust/blob/b57fe74a27590289fd657614b8ad1f3eac8a7ad2/src/libsyntax/feature_gate.rs#L1825-L1833
This was intentionally added in https://github.com/rust-lang/rust/commit/4d1a30c92b50c5965ed26449758fca81bee15747.
@varkor that on its own is just a diverging function, which has been supported since Rust 1.0.0 (and probably long before).
@Nemo157: ah, I see. Originally, diverging functions were separate from the never type, but since they became unified, there's nothing to distinguish a diverging function from a function returning never. It seems unavoidable to have ! in potentially any position if we have it in some, because of tricks like this.
Idea: Could we emit a warning when encounter constructs such as the one in the issue description?
I'm curious what we can/should consider the bug here to be.
Specifically, in the absence of #![feature(never_type)], should we consider fn() -> ! to not be covered by the blanket impl impl<T> MyTrait for fn() -> T ?
(And maybe this question is going to be made irrelevant so soon that it need not be answered...)
Ah yes I think my previous question is made obsolete by PR #65355
Is this issue relevant again because of https://github.com/rust-lang/rust/pull/67224?
Most helpful comment
Is this issue relevant again because of https://github.com/rust-lang/rust/pull/67224?