Skip to content

Structural search & replace of nested try!() causes corruption #11591

@deviant

Description

@deviant

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 another input.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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ssrstructural search & replaceC-bugCategory: bugS-actionableSomeone could pick this issue up and work on it right now

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions