Rust: The never type can be named despite its feature gate

Created on 25 Feb 2019  路  7Comments  路  Source: rust-lang/rust

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
A-stability C-bug T-compiler

Most helpful comment

Is this issue relevant again because of https://github.com/rust-lang/rust/pull/67224?

All 7 comments

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?

Was this page helpful?
0 / 5 - 0 ratings