rust/src/test/ui/lint/dead-code
bors 5ca596f486 Auto merge of #85556 - FabianWolff:issue-85071, r=estebank,jackh726
Warn about unreachable code following an expression with an uninhabited type

This pull request fixes #85071. The issue is that liveness analysis currently is "smarter" than reachability analysis when it comes to detecting uninhabited types: Unreachable code is detected during type checking, where full type information is not yet available. Therefore, the check for type inhabitedness is quite crude:
fc81ad22c4/compiler/rustc_typeck/src/check/expr.rs (L202-L205)

i.e. it only checks for `!`, but not other, non-trivially uninhabited types, such as empty enums, structs containing an uninhabited type, etc. By contrast, liveness analysis, which runs after type checking, can benefit from the more sophisticated `tcx.is_ty_uninhabited_from()`:
fc81ad22c4/compiler/rustc_passes/src/liveness.rs (L981)
fc81ad22c4/compiler/rustc_passes/src/liveness.rs (L996)

This can lead to confusing warnings when a variable is reported as unused, but the use of the variable is not reported as unreachable. For instance:
```rust
enum Foo {}
fn f() -> Foo {todo!()}

fn main() {
    let x = f();
    let _ = x;
}
```
currently leads to
```
warning: unused variable: `x`
 --> t1.rs:5:9
  |
5 |     let x = f();
  |         ^ help: if this is intentional, prefix it with an underscore: `_x`
  |
  = note: `#[warn(unused_variables)]` on by default

warning: 1 warning emitted
```
which is confusing, because `x` _appears_ to be used in line 6. With my changes, I get:
```
warning: unreachable expression
 --> t1.rs:6:13
  |
5 |     let x = f();
  |             --- any code following this expression is unreachable
6 |     let _ = x;
  |             ^ unreachable expression
  |
  = note: `#[warn(unreachable_code)]` on by default
note: this expression has type `Foo`, which is uninhabited
 --> t1.rs:5:13
  |
5 |     let x = f();
  |             ^^^

warning: unused variable: `x`
 --> t1.rs:5:9
  |
5 |     let x = f();
  |         ^ help: if this is intentional, prefix it with an underscore: `_x`
  |
  = note: `#[warn(unused_variables)]` on by default

warning: 2 warnings emitted
```
My implementation is slightly inelegant because unreachable code warnings can now be issued in two different places (during type checking and during liveness analysis), but I think it is the solution with the least amount of unnecessary code duplication, given that the new warning integrates nicely with liveness analysis, where unreachable code is already implicitly detected for the purpose of finding unused variables.
2021-08-24 01:36:09 +00:00
..
alias-in-pat.rs
anon-const-in-pat.rs Add a dead code test for using anon const in pattern 2021-08-15 18:17:21 +01:00
associated-type.rs
basic.rs
basic.stderr
closure-bang.rs
const-and-self.rs Do not mark unit variants as used when in path pattern 2021-01-23 00:00:00 +00:00
const-and-self.stderr Do not mark unit variants as used when in path pattern 2021-01-23 00:00:00 +00:00
empty-unused-enum.rs
empty-unused-enum.stderr
empty-unused-public-enum.rs
enum-variants.rs
impl-trait.rs
impl-trait.stderr
issue-85071-2.rs Warn about unreachable code following an expression with an uninhabited type 2021-05-21 18:30:36 +02:00
issue-85071-2.stderr Warn about unreachable code following an expression with an uninhabited type 2021-05-21 18:30:36 +02:00
issue-85071.rs Warn about unreachable code following an expression with an uninhabited type 2021-05-21 18:30:36 +02:00
issue-85071.stderr Warn about unreachable code following an expression with an uninhabited type 2021-05-21 18:30:36 +02:00
issue-85255.rs More tests for issue-85255 2021-05-16 10:18:28 +08:00
issue-85255.stderr More tests for issue-85255 2021-05-16 10:18:28 +08:00
leading-underscore.rs Update tests for extern block linting 2021-01-13 07:49:16 -05:00
lint-dead-code-1.rs
lint-dead-code-1.stderr
lint-dead-code-2.rs Remove #[main] attribute. 2021-04-16 13:04:02 +08:00
lint-dead-code-2.stderr
lint-dead-code-3.rs Update tests for extern block linting 2021-01-13 07:49:16 -05:00
lint-dead-code-3.stderr Update existing test cases. 2020-06-20 16:54:32 +10:00
lint-dead-code-4.rs
lint-dead-code-4.stderr
lint-dead-code-5.rs
lint-dead-code-5.stderr
lint-dead-code-6.rs Dead-code pass highlights too much of impl functions 2020-05-06 11:26:30 +02:00
lint-dead-code-6.stderr Dead-code pass highlights too much of impl functions 2020-05-06 11:26:30 +02:00
newline-span.rs
newline-span.stderr
self-assign.rs temporarily ignore a test until we reland PR 83171. 2021-07-21 23:03:06 -04:00
self-assign.stderr Warn about useless assignments of variables/fields to themselves 2021-07-14 16:29:35 +02:00
trait-impl.rs dead_code: look at trait impls even if they don't contain items 2020-09-22 22:13:58 +02:00
tuple-struct-field.rs
type-alias.rs
type-alias.stderr
type-in-foreign.rs Visit ForeignItems when marking dead code. 2020-12-08 08:07:55 +01:00
unused-enum.rs
unused-enum.stderr
unused-struct-variant.rs
unused-struct-variant.stderr
unused-variant-pub.rs
unused-variant.rs
unused-variant.stderr
with-core-crate.rs
with-core-crate.stderr
with-impl.rs