| #![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<dyn Foo + 'static> { |
| 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<dyn Foo2 + 'static> { |
| 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<usize> 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<T: Bar>(&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<String>) { //~ 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() {} |