We should lint when !-fallback results in questionable code

03407b0
Opened by Andrew Cann at 2021-12-29 03:55:50

An example is the following code:

#![feature(never_type)]

use std::error::Error;

pub trait Deserialize: Sized {
  fn deserialize() -> Result<Self, Box<Error>>;
}

impl Deserialize for ! {
  fn deserialize() -> Result<!, Box<Error>> {
    Err("oh geez")?;
    panic!()
  }
}

fn foo() -> Result<usize, Box<Error>> {
  Deserialize::deserialize()?;
  Ok(22)
}

Here, the type of Deserialize::deserialize()? defaults to !, making the Ok(22) unreachable. It might be unclear to users why the Ok(22) is unreachable since the !-fallback happens implicitly, so it would be good to point at it with an auxiliary note on the warning. eg. something like note: unconstrained type variable fell back to !

  1. Here, the type of Deserialize::deserialize()? defaults to !

    It appears this is no longer true:

    error[E0277]: the trait bound `(): Deserialize` is not satisfied
      --> src/lib.rs:17:3
       |
    17 |   Deserialize::deserialize()?;
       |   ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Deserialize` is not implemented for `()`
    

    Should this be considered a bug?

    @rustbot label +F-never_type

    Ben Reeves at 2021-12-29 03:55:48