rust-lang / rust-lang/rust-analyzer
Structural search & replace of nested `try!()` causes corruption
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 16.9k
- Forks
- 2.2k
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 72
Description
rust-analyzer version: 2022-01-31
rustc version: 1.58.1
relevant settings: N/A
Given the following code:
// abcdefghijklmnopqrstuvwxyz
fn main() {
try!(try!("what"));
}
running
rust-analyzer ssr 'try!($expr) ==>> $expr?'
produces the following absurd result:
// abcdefghijklmnopqrstuvwxyz
fn main() {
ijklmn??;
}
I have observed the following properties:
- Varying the inner invocation's input changes how many characters from the initial 'i' is included.
- Inserting linebreaks before the comment slides the window to the right by a corresponding number of characters.
- Inserting linebreaks after the comment does nothing; nor does removing letters from the end of the comment.
- Removing the
?from the replacement rule (or adding more) does not change the corruption. - Adding things to the beginning of the replacement rule (for instance, wrapping it in parentheses) similarly has no effect.
- Wrapping the input with additional
try!()s consumes anotherinput.len()characters for each one you add, although no further?are added beyond the initial two.- This continues past the end of the comment, and will happily generate invalid code (e.g. half of an identifier).
This implies the replacement data is being taken from a location relative to the start of the file, rather than relative to the match itself. I have no idea why this is, and am not sufficiently familiar with rust-analyzer's internals to investigate it further, but knowing these things will probably help with tracking down the problem.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue with the provided nested try!() example and the rust-analyzer ssr command. Start by tracing the structural search-and-replace entry point and how replacement spans are calculated for nested matches. Done means nested replacements use the matched source text and no unrelated comment or file characters are inserted.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100