]> git.lizzy.rs Git - rust.git/blob - src/test/ui/lint/lint-unconditional-recursion.rs
Auto merge of #106349 - LeSeulArtichaut:dyn-star-tracking-issue, r=jackh726
[rust.git] / src / test / ui / lint / lint-unconditional-recursion.rs
1 #![deny(unconditional_recursion)]
2
3 #![allow(dead_code)]
4 fn foo() { //~ ERROR function cannot return without recursing
5     foo();
6 }
7
8 fn bar() {
9     if true {
10         bar()
11     }
12 }
13
14 fn baz() { //~ ERROR function cannot return without recursing
15     if true {
16         baz()
17     } else {
18         baz()
19     }
20 }
21
22 fn qux() {
23     loop {}
24 }
25
26 fn quz() -> bool { //~ ERROR function cannot return without recursing
27     if true {
28         while quz() {}
29         true
30     } else {
31         loop { quz(); }
32     }
33 }
34
35 // Trait method calls.
36 trait Foo {
37     fn bar(&self) { //~ ERROR function cannot return without recursing
38         self.bar()
39     }
40 }
41
42 impl Foo for Box<dyn Foo + 'static> {
43     fn bar(&self) { //~ ERROR function cannot return without recursing
44         loop {
45             self.bar()
46         }
47     }
48 }
49
50 // Trait method call with integer fallback after method resolution.
51 impl Foo for i32 {
52     fn bar(&self) { //~ ERROR function cannot return without recursing
53         0.bar()
54     }
55 }
56
57 impl Foo for u32 {
58     fn bar(&self) {
59         0.bar()
60     }
61 }
62
63 // Trait method calls via paths.
64 trait Foo2 {
65     fn bar(&self) { //~ ERROR function cannot return without recursing
66         Foo2::bar(self)
67     }
68 }
69
70 impl Foo2 for Box<dyn Foo2 + 'static> {
71     fn bar(&self) { //~ ERROR function cannot return without recursing
72         loop {
73             Foo2::bar(self)
74         }
75     }
76 }
77
78 struct Baz;
79 impl Baz {
80     // Inherent method call.
81     fn qux(&self) { //~ ERROR function cannot return without recursing
82         self.qux();
83     }
84
85     // Inherent method call via path.
86     fn as_ref(&self) -> &Self { //~ ERROR function cannot return without recursing
87         Baz::as_ref(self)
88     }
89 }
90
91 // Trait method calls to impls via paths.
92 impl Default for Baz {
93     fn default() -> Baz { //~ ERROR function cannot return without recursing
94         let x = Default::default();
95         x
96     }
97 }
98
99 // Overloaded operators.
100 impl std::ops::Deref for Baz {
101     type Target = ();
102     fn deref(&self) -> &() { //~ ERROR function cannot return without recursing
103         &**self
104     }
105 }
106
107 impl std::ops::Index<usize> for Baz {
108     type Output = Baz;
109     fn index(&self, x: usize) -> &Baz { //~ ERROR function cannot return without recursing
110         &self[x]
111     }
112 }
113
114 // Overloaded autoderef.
115 struct Quux;
116 impl std::ops::Deref for Quux {
117     type Target = Baz;
118     fn deref(&self) -> &Baz { //~ ERROR function cannot return without recursing
119         self.as_ref()
120     }
121 }
122
123 fn all_fine() {
124     let _f = all_fine;
125 }
126
127 // issue 26333
128 trait Bar {
129     fn method<T: Bar>(&self, x: &T) {
130         x.method(x)
131     }
132 }
133
134 // Do not trigger on functions that may diverge instead of self-recursing (#54444)
135
136 pub fn loops(x: bool) {
137     if x {
138         loops(x);
139     } else {
140         loop {}
141     }
142 }
143
144 pub fn panics(x: bool) {
145     if x {
146         panics(!x);
147     } else {
148         panic!("panics");
149     }
150 }
151
152 pub fn unreachable1() {
153     panic!();
154     unreachable1(); // WARN unreachable statement
155 }
156
157 pub fn unreachable2() {
158     loop {}
159     unreachable2(); // WARN unreachable statement
160 }
161
162 pub fn drop_and_replace(mut a: Option<String>) { //~ ERROR function cannot return without recursing
163     a = None;
164     drop_and_replace(a);
165 }
166
167 // Calls are assumed to return normally.
168 pub fn call() -> String { //~ ERROR function cannot return without recursing
169     let s = String::new();
170     call();
171     s
172 }
173
174 // Arithmetic operations are assumed not to overflow.
175 pub fn overflow_check(a: i32, b: i32) { //~ ERROR function cannot return without recursing
176     let _ = a + b;
177     overflow_check(a, b);
178 }
179
180 pub struct Point {
181     pub x: f32,
182     pub y: f32,
183 }
184
185 impl Default for Point {
186     fn default() -> Self { //~ ERROR function cannot return without recursing
187         Point {
188             x: Default::default(),
189             ..Default::default()
190         }
191     }
192 }
193
194 fn main() {}