Repository: rust
Issue: Cannot Drop A Closure With Non Copy Captures Confusing Error
Labels: A-borrow-checker,C-bug

The All Mighty Borrow Checker appears to not allow you to drop a closure that accepts a lifetime as an argument, when a pointer to that closure has the same lifetime. I believe this to be a bug, because when you remove the drop call (`drop(func);`), Rust already *does the same thing implicitly* at the end of the block, without error.

[Here's the minimum replicatale error I have found.](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=1230155bb5c76079465d91027830e8c6)
```rust
type LifetimeBound<'r> = &'r dyn Fn(&'r ());

fn main() {
    // This creates a string.
	let capture = String::new();
	// This moves string into a closure.
	let func = move |_| drop(&capture);
	// This forces func to implement Fn(PhantomData<&'r ()>), where 'r lasts as
	// long as func does.
	let func_ref_bound: LifetimeBound = &func;
	// 'r ends here, because the reference with the lifetime 'r is dropped.
	drop(func_ref_bound);
	// Should be able to drop, there are no more references to func.
	drop(func);
}
```

## Expected Result & Actual Result
I expected that using `drop` on `func` is the same thing as letting `func` fall out of scope; it's what happens inside `drop` anyway.

I expected the above code to act and compile exactly the same as 
[this code](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=909b6dc4721ad6e8cc9fbae6d05f0e36). It compiles perfectly.
```rust
type LifetimeBound<'r> = &'r dyn Fn(&'r ());

fn main() {
	let capture = String::new();
	let func = move |_| drop(&capture);
	let func_ref_bound: LifetimeBound = &func;
	drop(func_ref_bound);
}
```

Instead, compilation error E0505 is emitted;
```
error[E0505]: cannot move out of `func` because it is borrowed
  --> src/main.rs:14:7
   |
10 |     let func_ref_bound: LifetimeBound = &func;
   |                                         ----- borrow of `func` occurs here
...
14 |     drop(func);
   |          ^^^^
   |          |
   |          move out of `func` occurs here
   |          borrow later used here

error: aborting due to previous error
```

## Meta
I use both stable and nightly, this is the version of both of them.

Stable;
```
rustc 1.54.0 (a178d0322 2021-07-26)
binary: rustc
commit-hash: a178d0322ce20e33eac124758e837cbd80a6f633
commit-date: 2021-07-26
host: x86_64-unknown-linux-gnu
release: 1.54.0
LLVM version: 12.0.1
```

Nightly;
```
rustc 1.56.0-nightly (ad981d58e 2021-08-08)
binary: rustc
commit-hash: ad981d58e1ca16bcf4072577934630deb11c5e14
commit-date: 2021-08-08
host: x86_64-unknown-linux-gnu
release: 1.56.0-nightly
LLVM version: 12.0.1
```

Both compilers have this issue.

## Quirks
This is quite the weird bug, there are multiple ways to suppress it but they all don't make sense. These are all the ways people in the Rust Language Discord server found to fix it, but they don't really help explain the bug at all.
- Add a type to the closure argument `|_: PhantomData<&()>|`
- Make the captured variable something copyable `let capture = ();`

## Why Fix?
I believe this bug should be fixed because The All Mighty Borrow Checker has been given too much power, and is now starting to use it against us. 😜 No, I believe this bug should be fixed because writing calls to drop for each variable at the end of the function in reverse order is, as I've been told, exactly the same as if you hadn't. On top of that, it is extremely confusing, especially in situations where you may need to manually change the order in which things drop, like the situation I came from. Even if this bug is null, the error message should still be changed, as it is misleading.