Skip to content

Invalid note: "the function expects a value to always be returned, but loops might run zero times" #122561

Closed
@GuillaumeGomez

Description

@GuillaumeGomez

Code

fn is_function_block(cx: &LateContext<'_>, mut expr_hir_id: HirId) -> bool {
    for i in 0.. {
        // We get the parent block.
        if let Some(scope_id) = cx.tcx.hir().get_enclosing_scope(expr_hir_id)
            && let Node::Block(block) = cx.tcx.hir().hir_node(scope_id)
            // We check that there is no statements in the block.
            && block.stmts.is_empty()
            // We check that the return statements is the current expression.
            && let Some(expr) = block.expr
            && expr_hir_id == expr.hir_id
        {
            expr_hir_id = expr.hir_id;
        } else {
            return i != 0;
        }
    }
}

Current output

32 |   fn is_function_block(cx: &LateContext<'_>, mut expr_hir_id: HirId) -> bool {
   |                                                                         ---- expected `bool` because of return type
33 | /     for i in 0.. {
34 | |         // We get the parent block.
35 | |         if let Some(scope_id) = cx.tcx.hir().get_enclosing_scope(expr_hir_id)
36 | |             && let Node::Block(block) = cx.tcx.hir().hir_node(scope_id)
...  |
46 | |         }
47 | |     }
   | |_____^ expected `bool`, found `()`
   |
note: the function expects a value to always be returned, but loops might run zero times
  --> clippy_lints/src/transmute/missing_transmute_annotations.rs:33:5
   |
33 |     for i in 0.. {
   |     ^^^^^^^^^^^^ this might have zero elements to iterate on
...
45 |             return i != 0;
   |             ------------- if the loop doesn't execute, this value would never get returned
help: return a value for the case when the loop has zero elements to iterate on
   |
47 ~     }
48 +     /* `bool` value */
   |
help: otherwise consider changing the return type to account for that possibility
   |
32 ~ fn is_function_block(cx: &LateContext<'_>, mut expr_hir_id: HirId) -> Option<bool> {
33 |     for i in 0.. {
 ...
44 |         } else {
45 ~             return Some(i != 0);
46 |         }
47 ~     }
48 +     None

Desired output

It should not emit a warning in this case since the range can never not iterate

Rationale and extra context

No response

Other cases

No response

Rust Version

rustc 1.78.0-nightly (7d3702e47 2024-03-06)
binary: rustc
commit-hash: 7d3702e472b99be0f5de6608dd87af1df8f99428
commit-date: 2024-03-06
host: x86_64-unknown-linux-gnu
release: 1.78.0-nightly
LLVM version: 18.1.0

Anything else?

No response

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsD-confusingDiagnostics: Confusing error or lint that should be reworked.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions