diff options
| author | bors <bors@rust-lang.org> | 2023-01-11 11:17:22 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-01-11 11:17:22 +0000 |
| commit | b22c152958eade17a71d899b29a2d39bcc77aa48 (patch) | |
| tree | ec6da75dc598a0a4086c0cc032c86d7241be1bc1 /tests/ui/lint/lint-unconditional-recursion.rs | |
| parent | 8ecaad85f61375b18e1667b51a3ef350121d2ca0 (diff) | |
| parent | 40ba0e84d53f605ccf01836e9c2d27892728ae81 (diff) | |
| download | rust-b22c152958eade17a71d899b29a2d39bcc77aa48.tar.gz rust-b22c152958eade17a71d899b29a2d39bcc77aa48.zip | |
Auto merge of #106458 - albertlarsan68:move-tests, r=jyn514
Move src/test to the root
See MCP at rust-lang/compiler-team#573
There may be more changes needed.
The first commit is just the move of the files:
You can check that the first commit did not do anything else than renames by running
```
git diff --diff-filter=r -M100% <rust-lang remote>/master <first commit hash>
```
The output should be empty, because the filter excludes renames, and the match threshold for qualifying a rename is 100%.
The second one is mostly a "find and replace" of `src/test` to `tests` and whatever is needed to make CI pass.
What is left to do:
---
- [x] Move directory
- [ ] Change references to `src/test`
- [x] Change references in-tree
- [ ] Change references in submodules / out-of-tree docs
- [x] Make CI pass:
- [x] Fix tidy
- [x] Fix tests
- [x] Bless tests if needed (shouldn't normally)
- [ ] Merge it !
Diffstat (limited to 'tests/ui/lint/lint-unconditional-recursion.rs')
| -rw-r--r-- | tests/ui/lint/lint-unconditional-recursion.rs | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/tests/ui/lint/lint-unconditional-recursion.rs b/tests/ui/lint/lint-unconditional-recursion.rs new file mode 100644 index 00000000000..ad052d36f20 --- /dev/null +++ b/tests/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() {} |
