Repository: rust
Issue: single-use-lifetimes may remove attributes of wrong lifetime?
Labels: A-diagnostics,T-compiler,D-invalid-suggestion

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.

If you cannot produce a minimal reproduction case (something that would work in
isolation), please provide the steps or even link to a repository that causes
the problematic output to occur.
-->

Given the following code: <!-- Please provide a link to play.rust-lang.org -->

```rust
#![feature(dropck_eyepatch)]

fn main() {
    // Since the second param to `D1` is may_dangle, it is legal for
    // the region of that parameter to end before the drop code for D1
    // is executed.
    (D1(&S1("ex1"), &S1("dang1"))).0;
}

#[derive(Debug)]
struct S1(&'static str);

#[derive(Debug)]
struct D1<'a, 'b>(&'a S1, &'b S1);

// The `#[may_dangle]` means that references of type `&'b _` may be
// invalid during the execution of this destructor; i.e. in this case
// the destructor code is not allowed to read or write `*self.1`, while
// it can read/write `*self.0`.
unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> {
    fn drop(&mut self) {
        println!("D1({:?}, _)", self.0);
    }
}
```

The current output is:

```
warning: lifetime parameter `'a` only used once
  --> src/main.rs:20:13
   |
20 | unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> {
   |             ^^ this lifetime...               -- ...is used only here
   |
   = note: requested on the command line with `-W single-use-lifetimes`
help: elide the single-use lifetime
   |
20 - unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> {
20 + unsafe impl<'b> Drop for D1<'_, 'b> {
   |

warning: lifetime parameter `'b` only used once
  --> src/main.rs:20:31
   |
20 | unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> {
   |                               ^^ this lifetime... -- ...is used only here
   |
help: elide the single-use lifetime
   |
20 - unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> {
20 + unsafe impl<'a> Drop for D1<'a, '_> {
```
It's trying to remove the attribute of lifetime `'b` when removing lifetime `'a`


and causes a compiler error all in all:


````
The following errors were reported:
warning: lifetime parameter `'a` only used once
  --> src/main.rs:20:13
   |
20 | unsafe impl<'a> Drop for D1<'a, '_> {
   |             ^^              -- ...is used only here
   |             |
   |             this lifetime...
   |
   = note: requested on the command line with `-W single-use-lifetimes`
help: elide the single-use lifetime
   |
20 - unsafe impl<'a> Drop for D1<'a, '_> {
20 + unsafe impl Drop for D1<'_, '_> {
   |

error[E0199]: implementing the trait `std::ops::Drop` is not unsafe
  --> src/main.rs:20:1
   |
20 | / unsafe impl<'a> Drop for D1<'a, '_> {
21 | |     fn drop(&mut self) {
22 | |         println!("D1({:?}, _)", self.0);
23 | |     }
24 | | }
   | |_^
   |
help: remove `unsafe` from this trait implementation
   |
20 - unsafe impl<'a> Drop for D1<'a, '_> {
20 + impl<'a> Drop for D1<'a, '_> {
   |

error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0199`.
Original diagnostics will follow.
````