Skip to content

Strengthen linear typing via #[must_use(dispose)] #2642

Open

Description

#[must_use] has a hole in its coverage. Suppose we have some code like this:

let transaction = Transaction::new(&kitchen)
    .catch_frogs(3)
    .set_gas_flow(2.5);
if transaction.is_boiling() {
    println!("How I love a nice bowl of frog soup!");
}

At this point, #[must_use] is satisfied merely because transaction has been inspected (via &self), but the call to transaction.commit() has been forgotten and there may be an error to rollback. What we want is for there to be a warning if the type has not been properly disposed of.

A type can be disposed of by destructuring, or by passing it off to another function.

Some consequences:

  1. mem::drop counts as disposal. It won't be infallible for the same reasons that Drop isn't infallible.
  2. Traits like trait Foo { fn foo(self) {} } would expose a hole. And it could be a blanket implementation.
  3. A method can ignore self by using let Self { .. } = self.

Result could be marked #[must_use(dispose)]. But I don't think it should be.

Alternatives

  • Do nothing, and change fn inspect(&self) -> bool to fn inspect(self) -> (Self, bool).
  • Do nothing.
  • Implement with clippy instead.
  • A different syntax, like #[must_dispose].
  • Make #[must_use] function like the proposed #[must_use(dispose)].
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-attributesProposals relating to attributesA-lintProposals relating to lints / warnings / clippy.A-typesystemType system related proposals & ideasT-langRelevant to the language team, which will review and decide on the RFC.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions