Commit graph

26 commits

Author SHA1 Message Date
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
Gary Guo
e62ecdc5a7 Add a dead code test for using anon const in pattern 2021-08-15 18:17:21 +01:00
Felix S. Klock II
ee2bb1f338 temporarily ignore a test until we reland PR 83171. 2021-07-21 23:03:06 -04:00
Felix S. Klock II
cf337d1119 Revert PR 81473 to resolve (on mainline) issues 81626 and 81658.
Revert "Add missing brace"

This reverts commit 85ad773049.

Revert "Simplify base_expr"

This reverts commit 899aae465e.

Revert "Warn write-only fields"

This reverts commit d3c69a4c0d.
2021-07-21 22:49:52 -04:00
Fabian Wolff
dc639c944a Warn about useless assignments of variables/fields to themselves 2021-07-14 16:29:35 +02:00
Fabian Wolff
2bcc759114 Warn about unreachable code following an expression with an uninhabited type 2021-05-21 18:30:36 +02:00
hi-rustin
2cb1ba3671 More tests for issue-85255 2021-05-16 10:18:28 +08:00
Fabian Wolff
46d55d6549 Warn about unused pub fields in non-pub structs 2021-05-15 13:06:17 +02:00
Charles Lew
fc357039f9 Remove #[main] attribute. 2021-04-16 13:04:02 +08:00
Tomasz Miąsko
343b673877 Consider auto derefs before warning about write only fields
Changes from 81473 extended the dead code lint with an ability to detect
fields that are written to but never read from. The implementation skips
over fields on the left hand side of an assignment, without marking them
as live.

A field access might involve an automatic dereference and de-facto read
the field. Conservatively mark expressions with deref adjustments as
live to avoid generating false positive warnings.
2021-02-19 00:00:00 +00:00
Seo Sanghyeon
d3c69a4c0d Warn write-only fields 2021-01-28 23:56:13 +09:00
Tomasz Miąsko
99a1dea1b7 Do not mark unit variants as used when in path pattern
Record that we are processing a pattern so that code responsible for
handling path resolution can correctly decide whether to mark it as
used or not.
2021-01-23 00:00:00 +00:00
Mark Rousskov
8a3edb1d66 Update tests for extern block linting 2021-01-13 07:49:16 -05:00
Camille GILLOT
37853f925f Visit ForeignItems when marking dead code. 2020-12-08 08:07:55 +01:00
Bastian Kauschke
438d229b25 dead_code: look at trait impls even if they don't contain items 2020-09-22 22:13:58 +02:00
jumbatm
c72a5dd9d3 Rename the lint to clashing_extern_declarations.
Also, run RustFmt on the clashing_extern_fn test case and update
stderrs.
2020-06-28 10:11:29 +10:00
jumbatm
556b7baca2 Update existing test cases.
- Allow ClashingExternDecl for lint-dead-code-3
- Update test case for #5791
- Update test case for #1866
- Update extern-abi-from-macro test case
2020-06-20 16:54:32 +10:00
mibac138
b6d5d1fb79 Dead-code pass highlights too much of impl functions 2020-05-06 11:26:30 +02:00
Eduard-Mihai Burtescu
d00f94ffc1 Remove redundant descr/descriptive_variant methods from HIR. 2020-04-24 13:44:08 -05:00
jakubadamw
f742afaca4 test for false "never constructed" warnings for Self:: variant paths 2020-04-19 21:57:35 +09:00
bors
5371ddf8c6 Auto merge of #68080 - varkor:declared-here, r=petrochenkov
Address inconsistency in using "is" with "declared here"

"is" was generally used for NLL diagnostics, but not other diagnostics. Using "is" makes the diagnostics sound more natural and readable, so it seems sensible to commit to them throughout.

r? @Centril
2020-01-31 15:13:51 +00:00
varkor
24a2929ed1 Normalise notes with the/is 2020-01-24 16:24:50 +00:00
Tomasz Miąsko
d915c016c9 Use check-pass mode for lint tests 2020-01-23 00:00:00 +00:00
cosine
bd63c594c2 Use "field is never read" instead of "field is never used" 2019-11-16 07:12:37 -05:00
Pi Lanningham
7985510e37 Use ident instead of def_span in dead-code pass
According to @estebank, def_span scans forward on the line until it finds a {,
and if it can't find one, fallse back to the span for the whole item.  This
was apparently written before the identifier span was explicitly tracked on
each node.

This means that if an unused function signature spans multiple lines, the
entire function (potentially hundreds of lines) gets flagged as dead code.
This could, for example, cause IDEs to add error squiggly's to the whole
function.

By using the span from the ident instead, we narrow the scope of this in
most cases.  In a wider sense, it's probably safe to use ident.span
instead of def_span in most locations throughout the whole code base,
but since this is my first contribution, I kept it small.

Some interesting points that came up while I was working on this:
 - I reorganized the tests a bit to bring some of the dead code ones all
   into the same location
 - A few tests were for things unrelated to dead code (like the
   path-lookahead for parens), so I added #![allow(dead_code)] and
   cleaned up the stderr file to reduce noise in the future
 - The same fix doesn't apply to const and static declarations.  I tried
   adding these cases to the match expression, but that created a much
   wider change to tests and error messages, so I left it off until I
   could get some code review to validate the approach.
2019-10-26 21:42:52 -04:00
Pi Lanningham
e063ddb12e Move dead_code related tests to test/ui/dead-code
This helps organize the tests better.  I also renamed several of the tests to remove redundant dead-code in the path, and better match what they're testing
2019-10-26 21:42:52 -04:00