diff options
Diffstat (limited to '')
-rw-r--r-- | src/test/ui/lint/lint-unconditional-recursion.rs | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/src/test/ui/lint/lint-unconditional-recursion.rs b/src/test/ui/lint/lint-unconditional-recursion.rs new file mode 100644 index 000000000..ad052d36f --- /dev/null +++ b/src/test/ui/lint/lint-unconditional-recursion.rs @@ -0,0 +1,194 @@ +#![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() {} |