rust-lang / rust-lang/rust-analyzer

RFC: Add lifetime to existing type

Open
#17,247 0 comments 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-feature
Dominant language
Rust
Stars
16.9k
Forks
2.2k
Avg merge
1d 12h
Merged PRs (30d)
72

Description

One of the most painful refactoring chores in Rust is to add a lifetime to an existing type in a large codebase. I don't know if it's within the purview of rust-analyzer or not, but a code action on interacting with struct Foo to add a lifetime (or additional lifetime) 'a' that would find all references to Foo and replace them with Foo<'a> and all impl Foo or impl .. for Foo and replace them with impl<'a> Foo<'a>/impl<'a> ... for Foo<'a> would be an amazing time saver. For functions, I imagine a similar "spray and pray" approach of just tacking on a lifetime to every fn declaration to make it fn<'a> would work.

<sidebar>I'm not sure how much actionable validity analysis rust-analyzer would have access to in the middle of this process, but if there are places where Foo<'a> could be replaced with Foo<'_> and not trigger any borrow checker issues, that would be a less messy refactor and leave less things needing user attention afterwards.</sidebar>

Until this point, this is all rote AST find-and-replace. The question that arises is how "compilable" should the result be.

  • A proper approach would need to recursively add a lifetime 'a to types that now contain Foo<'a>. This could be automated, but there's no more "one size fits all" answer here because the user might want to coalesce 'a with an existing 'b or with 'static or what have you.
  • On the other hand, having a code action to add a lifetime makes it relatively easy to now recursively perform the same operation for existing types. It still needs work, the code won't compile or pass a cargo check at this point without manual user intervention, but there's less need for rust-analyzer to make its own guesses as to what the correct approach would be.

This is just a skeleton proposal for a new feature, and I admit to not having thought every aspect of this through. I am essentially expressing an LSP need that I have found myself lacking in comparison to some other extensive refactoring options that LSPs for other languages like C# or C++ make available (there are no direct one-to-one comparisons, but some extensive refactor options that go beyond what rust-analyzer currently does do exist).

(I have performed a search and did not find any relevant issues, though perhaps there is a different venue where such requests might be discussed normally.)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing rust-analyzer's existing code-action support and the proposed transformations for struct Foo, impl Foo, and fn declarations. Use cargo check to assess how far the automated refactoring can proceed, and define the intended behavior for recursively containing types and lifetime choices before implementation.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
devtools
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.