#![deny(unconditional_recursion)] #![allow(dead_code)] fn foo() { //~ ERROR function cannot return without recursing foo(); } fn bar() { if true { bar() } } fn baz() { //~ ERROR function cannot return without recursing if true { baz() } else { baz() } } fn qux() { loop {} } fn quz() -> bool { //~ ERROR function cannot return without recursing if true { while quz() {} true } else { loop { quz(); } } } // Trait method calls. trait Foo { fn bar(&self) { //~ ERROR function cannot return without recursing self.bar() } } impl Foo for Box { fn bar(&self) { //~ ERROR function cannot return without recursing loop { self.bar() } } } // Trait method call with integer fallback after method resolution. impl Foo for i32 { fn bar(&self) { //~ ERROR function cannot return without recursing 0.bar() } } impl Foo for u32 { fn bar(&self) { 0.bar() } } // Trait method calls via paths. trait Foo2 { fn bar(&self) { //~ ERROR function cannot return without recursing Foo2::bar(self) } } impl Foo2 for Box { fn bar(&self) { //~ ERROR function cannot return without recursing loop { Foo2::bar(self) } } } struct Baz; impl Baz { // Inherent method call. fn qux(&self) { //~ ERROR function cannot return without recursing self.qux(); } // Inherent method call via path. fn as_ref(&self) -> &Self { //~ ERROR function cannot return without recursing Baz::as_ref(self) } } // Trait method calls to impls via paths. impl Default for Baz { fn default() -> Baz { //~ ERROR function cannot return without recursing let x = Default::default(); x } } // Overloaded operators. impl std::ops::Deref for Baz { type Target = (); fn deref(&self) -> &() { //~ ERROR function cannot return without recursing &**self } } impl std::ops::Index for Baz { type Output = Baz; fn index(&self, x: usize) -> &Baz { //~ ERROR function cannot return without recursing &self[x] } } // Overloaded autoderef. struct Quux; impl std::ops::Deref for Quux { type Target = Baz; fn deref(&self) -> &Baz { //~ ERROR function cannot return without recursing self.as_ref() } } fn all_fine() { let _f = all_fine; } // issue 26333 trait Bar { fn method(&self, x: &T) { x.method(x) } } // Do not trigger on functions that may diverge instead of self-recursing (#54444) pub fn loops(x: bool) { if x { loops(x); } else { loop {} } } pub fn panics(x: bool) { if x { panics(!x); } else { panic!("panics"); } } pub fn unreachable1() { panic!(); unreachable1(); // WARN unreachable statement } pub fn unreachable2() { loop {} unreachable2(); // WARN unreachable statement } pub fn drop_and_replace(mut a: Option) { //~ ERROR function cannot return without recursing a = None; drop_and_replace(a); } // Calls are assumed to return normally. pub fn call() -> String { //~ ERROR function cannot return without recursing let s = String::new(); call(); s } // Arithmetic operations are assumed not to overflow. pub fn overflow_check(a: i32, b: i32) { //~ ERROR function cannot return without recursing let _ = a + b; overflow_check(a, b); } pub struct Point { pub x: f32, pub y: f32, } impl Default for Point { fn default() -> Self { //~ ERROR function cannot return without recursing Point { x: Default::default(), ..Default::default() } } } fn main() {}