Description
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
- "Warning: never used at all" falls under
- 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?
- For a single-use lifetime
- [] 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 fromvisit_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.
- This could be used, for example, to update some information in the
- 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.)