-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Description
Today I hit a segfault caused by stack overflow that wasn't caught by the compiler. This only occurred in debug mode, not release.
Current Behavior
The cause was the following piece of code, which passes the compiler without emitting any warnings:
use std::fmt::{self, Display};
struct Foo;
impl Display for Foo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self, f)
}
}
As would be obvious to most people carefully reviewing this code, there's a clear case of unconditional recursion happening. We pass &self
to the same impl over and over.
Expected behavior
A similar case is already caught by the compiler: passing self
rather than &self
to the same impl. This triggers the "unconditional recursion" warning. I would've expected the &self
case to hit the same warning.
use std::fmt::{self, Display};
struct Foo;
impl Display for Foo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(self, f)
}
}
warning: function cannot return without recursing
--> src/lib.rs:6:5
|
6 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
7 | Display::fmt(self, f)
| --------------------- recursive call site
|
= note: `#[warn(unconditional_recursion)]` on by default
= help: a `loop` may express intention better if this is on purpose
It'd be nice if the &self
case would also emit diagnostics when detecting infinite recursion. Seeing a segfault occur in your program can be pretty scary. Added to that it wasn't triggering for us in release mode, and searching for "debug stack overflow rust" yields some pretty poor results (because "stack overflow" is also the name of a popular website, heh).
This seems like a case where we could probably use better diagnostics. Thanks!