Skip to content

single-use-lifetimes may remove attributes of wrong lifetime? #105031

@matthiaskrgr

Description

@matthiaskrgr

Given the following code:

#![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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsD-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions