Skip to content

In-band lifetimes: Lint against single-use lifetime names #44752

Open
@nikomatsakis

Description

@nikomatsakis

Once support for '_ lands in #44691, the next step for #44524 is to implement a lint that warns against "single use" lifetime names.

Current status

The lint is partially implemented but needs to be completed. Here is a checklist:

  • Issue warnings at the right times; this gist provides a comprehensive test case.
    • "Warning: never used at all" falls under unused_lifetimes
  • For each warning, issue a suggested fix:
    • For a single-use lifetime 'a appearing in &'a T, suggest &T
    • For a single-use lifetime 'a appearing in any other place, suggest '_
    • One challenge: the binder must be removed too
      • cc @estebank -- is it possible to give suggested fixes that make changes to multiple spots at once? I guess that might just be multiple suggestions?
  • [] We'll know this is really done when we can enable by default in rustc crates and apply rustfix with suggestions

Older Background

The idea is that an explicit name like 'a should only be used (at least in a function or impl) to link together two things. Otherwise, you should just use '_ to indicate that the lifetime is not linked to anything.

Until #15872 is closed, we should only lint for single-use lifetime names that are bound in functions. Once #15872 is closed, we can also lint against those found in impl headers.

We can detect cases where a lint is valid by modifying the resolve_lifetimes code:

  • This code basically walks over the HIR and resolves all lifetime names.
  • It maintains a stack of scopes indicating what names are valid.
  • The function with() is used to push new scopes on the stack. It is also given a closure which will execute with the new name bindings in scope.
    • with() gets called for impls and other kinds of items from here; for methods and functions in particular it is called from visit_early_late).
  • Once a name is in scope, resolve_lifetime_ref() is called to resolve an actual reference to a named lifetime.
    • This could be used, for example, to update some information in the Scope, e.g. counting how many times a particular lifetime was referenced.
  • Then, before with() returns, we could scan the lifetimes and check for those that were only referenced 1 time (or 0 times...) and issue a lint warning.

(There are some directions for how to add a lint under the header "Issuing future compatibility warnings" in the rustc-bug-fix-procedure page on forge -- we can skip the "future compatibility" parts here.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lifetimesArea: Lifetimes / regionsA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCE-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.F-lint-single_use_lifetimes`single_use_lifetimes` lintS-tracking-design-concernsStatus: There are blocking design concerns.S-tracking-impl-incompleteStatus: The implementation is incomplete.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions