Skip to content

Recursive call warning does not appear inside a match statement #94778

Open
@levkk

Description

@levkk

I tried this code:

#[derive(Copy, Clone)]
enum Test {
    ValueA,
    ValueB,
    #[allow(dead_code)]
    Any
}

impl PartialEq for Test {
    fn eq(&self, other: &Test) -> bool {
        match *self {
            Test::Any => true,
            _ => *self == *other,
        }
    }
}

#[allow(dead_code)]
#[derive(Copy, Clone)]
enum Test2 {
    ValueA,
    ValueB,
    Any
}

impl PartialEq for Test2 {
     fn eq(&self, other: &Test2) -> bool {
        *self == *other
    }
}

fn main() {
    let a = Test::ValueA;
    let b = Test::ValueB;
    
    println!("{}", a ==  b);
}

Rust Playground

I expected to see this happen: the compiler should of warned me that the implementation PartialEq for Test is recursive.

Instead, this happened: it compiled the implementation for Test without warnings and produced a stack overflow. Implementation for Test2 is included to show that it does produce a warning when the recursive call is made not inside a match statement.

Compiler output:

 Compiling so v0.1.0 (/home/lev/Projects/so)
warning: function cannot return without recursing
  --> src/main.rs:28:6
   |
28 |      fn eq(&self, other: &Test2) -> bool {
   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
29 |         *self == *other
   |         --------------- recursive call site
   |
   = note: `#[warn(unconditional_recursion)]` on by default
   = help: a `loop` may express intention better if this is on purpose

warning: `so` (bin "so") generated 1 warning

Meta

rustc --version --verbose:

rustc 1.59.0 (9d1b2106e 2022-02-23)
binary: rustc
commit-hash: 9d1b2106e23b1abd32fce1f17267604a5102f57a
commit-date: 2022-02-23
host: x86_64-unknown-linux-gnu
release: 1.59.0
LLVM version: 13.0.0
Backtrace

    Finished dev [unoptimized + debuginfo] target(s) in 0.16s
     Running `target/debug/so`

thread 'main' has overflowed its stack
fatal runtime error: stack overflow
Aborted

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-control-flowArea: Control flowA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.C-bugCategory: This is a bug.C-enhancementCategory: An issue proposing an enhancement or a PR with one.L-unconditional_recursionLint: unconditional_recursionT-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