-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
More sophisticated span trimming for suggestions #137348
Conversation
This comment has been minimized.
This comment has been minimized.
d6579da
to
160905b
Compare
Some changes occurred in src/tools/clippy cc @rust-lang/clippy |
@@ -380,7 +403,12 @@ impl CodeSuggestion { | |||
// or deleted code in order to point at the correct column *after* substitution. | |||
let mut acc = 0; | |||
let mut only_capitalization = false; | |||
for part in &substitution.parts { | |||
for part in &mut substitution.parts { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We trim before we create highlights to avoid highlighting unchanged portions of the line, and to avoid random bugs (preexisting? #136958 (comment)) with how we render suggestions.
LL + Some(1), | ||
LL + Some(2), | ||
LL + Some(3) | ||
LL | for n in vec![ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This diff is a bit weird but 🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The +
on lines 200-202 were wrong anyways, the only thing that this PR is suggesting to change is adding .flatten()
.
The fact that we don't suggesting putting the ++++
under .flatten()
is because the suggestion span is multiline. That's unfortunate, but more difficult to fix.
LL ~ //! A very short summary. | ||
LL + //! | ||
LL | //! A very short summary. | ||
LL ~ //! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kinda a shame that this isn't rendered using a +
on the line, but it's pretty difficult to debug tbh.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if it is related to the finicky \n
handling from the previous line... But lets ignore for now.
| | ||
LL | return true | ||
| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Intrigued about this existing rendering issue...
LL | needlesArr.iter().fold(|x, y| { | ||
LL | | ||
LL ~ }, /* f */); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at these, we shorten the suggestion parts after we've determined what the suggestion "window" will be, which means that we display this with the "multiline" format, instead of just adding , /* f */
. That's unfortunate and I'll see if we can address it easily in this PR, but if not let's keep a ticket open for that investigation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I looked into this. I don't think it's fixable in this PR, because if we shorten the suggestion window, then we lose the necessary context and the suggestion renders really poorly, like:
LL + }, /* f */};
++++++++++
but with no preceding lines, which makes it really hard to know what the line being edited even is. This is even worse for other examples that changed.
If you want to look into this, then please do, but I don't think it should block this PR. It would be nice if someone cleaned up the suggestion window/highlight mode selection code.
help: consider returning the local binding `s` | ||
| | ||
LL ~ let s: String = if let Some(s) = opt_str { | ||
LL + s | ||
LL | let s: String = if let Some(s) = opt_str { | ||
LL ~ s | ||
LL ~ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like there might be something iffy, related to the other multiline "issues".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's the same root cause.
LL ~ fn deserialize_token<D: Deserializer<'a>>(_x: D, _y: &'a str) -> &'a str { | ||
LL + _y | ||
LL | fn deserialize_token<D: Deserializer<'a>>(_x: D, _y: &'a str) -> &'a str { | ||
LL ~ _y |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this case should absolutely be +
instead of ~
. (again, we can deal with this later, just marking for future reference)
.chars() | ||
.zip(suggestion.chars()) | ||
.take_while(|(c1, c2)| c1 == c2) | ||
.map(|(c, _)| c.len_utf8()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might interact poorly with with unicode codepoints that get "normalized" (rustc_errors::emitter::normalize_whitespace
) irrespective of their actual unicode rendering. This is very niche. I do not immediately know if emit_suggestion_default
does terminal output normalization. Intuitively, we might not want to do any because the user might be copy pasting from the terminal (instead of using rustfix). Either way, not a blocker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The source map (afaict) already uses the length of substrings to adjust spans. If this is a problem, then it's (afaict) already a problem 🤔.
.sum(); | ||
let original = &original[common_prefix..]; | ||
let suggestion = &suggestion[common_prefix..]; | ||
if suggestion.ends_with(original) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't you instead use original.chars().rev()
to do the same thing for the suffix as with the prefix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's simpler to just call ends_with
because we want to make sure that the "original" is a subset of the "suggestion". Otherwise, we'd need to do one more check that the trimmed original string is empty.
Love these changes. r=me with high prio, either addressing the suffix change or not. |
@bors r=estebank p=1 rollup |
More sophisticated span trimming for suggestions Previously rust-lang#136958 only cared about prefixes or suffixes. Now it detects more cases where a suggestion is "sandwiched" by unchanged code on the left or the right. Would be cool if we could detect several insertions, like `ACE` going to `ABCDE`, extracting `B` and `D`, but that seems unwieldy. r? `@estebank`
More sophisticated span trimming for suggestions Previously rust-lang#136958 only cared about prefixes or suffixes. Now it detects more cases where a suggestion is "sandwiched" by unchanged code on the left or the right. Would be cool if we could detect several insertions, like `ACE` going to `ABCDE`, extracting `B` and `D`, but that seems unwieldy. r? ``@estebank``
…iaskrgr Rollup of 8 pull requests Successful merges: - rust-lang#136458 (Do not deduplicate list of associated types provided by dyn principal) - rust-lang#136474 ([`compiletest`-related cleanups 3/7] Make the distinction between sources root vs test suite sources root in compiletest less confusing) - rust-lang#136592 (Make sure we don't overrun the stack in canonicalizer) - rust-lang#136787 (Remove `lifetime_capture_rules_2024` feature) - rust-lang#137180 (Give `global_asm` a fake body to store typeck results, represent `sym fn` as a hir expr to fix `sym fn` operands with lifetimes) - rust-lang#137257 (Ignore fake borrows for packed field check) - rust-lang#137348 (More sophisticated span trimming for suggestions) - rust-lang#137399 (fix ICE in layout computation with unnormalizable const) r? `@ghost` `@rustbot` modify labels: rollup
☀️ Test successful - checks-actions |
Finished benchmarking commit (dc37ff8): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)Results (secondary 4.8%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResults (primary -1.4%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 774s -> 772.814s (-0.15%) |
More sophisticated span trimming for suggestions Previously rust-lang#136958 only cared about prefixes or suffixes. Now it detects more cases where a suggestion is "sandwiched" by unchanged code on the left or the right. Would be cool if we could detect several insertions, like `ACE` going to `ABCDE`, extracting `B` and `D`, but that seems unwieldy. r? `@estebank`
Previously #136958 only cared about prefixes or suffixes. Now it detects more cases where a suggestion is "sandwiched" by unchanged code on the left or the right. Would be cool if we could detect several insertions, like
ACE
going toABCDE
, extractingB
andD
, but that seems unwieldy.r? @estebank