Skip to content
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

use stable sort to sort multipart diagnostics #128852

Merged
merged 1 commit into from
Aug 9, 2024

Conversation

folkertdev
Copy link
Contributor

I think a stable sort should be used to sort the different parts of a multipart selection. The current unstable sort uses the text of the suggestion as a tie-breaker. That just doesn't seem right, and the order of the input is a better choice I think, because it gives the diagnostic author more control.

This came up when I was building a suggestion where

fn foo() {}

must be turned into an unsafe function, and an attribute must be added

#[target_feature(enable = "...")]
unsafe fn foo() {}

In this example, the two suggestions occur at the same position, but the order is extremely important: unsafe must come after the attribute. But the situation changes if there is a pub/pub(crate), and if the unsafe is already present. It just out that because of the suggestion text, there is no way for me to order the suggestions correctly.

This change probably should be tested, but are there tests of the diagnostics code itself in the tests?

r? @estebank

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 8, 2024
Copy link
Member

@compiler-errors compiler-errors left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this leave: [(s, "a"), (s, "b"), (s, "a"), (s, "b")] not deduplicated?

@compiler-errors
Copy link
Member

compiler-errors commented Aug 8, 2024

I would rather you do something like:

let seen = FxHashSet::default();
suggestions.retain(|(span, msg)| seen.insert(span.data(), msg.clone()));

If possible...?

Using span.data() should deduplicate source-equal spans, and using the msg as the part of the key in the seen allows us to deduplicate messages still.

@folkertdev
Copy link
Contributor Author

That seems to almost work, but I think it gets tripped up when macros are involved? when using

suggestion.sort_by_key(|(span, _)| *span);
let mut seen = crate::FxHashSet::default();
suggestion.retain(|(span, msg)| seen.insert((span.data(), msg.clone())));

I get this failure

failures:

---- [ui] tests/ui/macros/macro-span-issue-116502.rs stdout ----

when comparing to the previous solution (top/left) this new solution (bottom/right) does not deduplicate correctly:

left: [
    (/home/folkertdev/rust/rust/tests/ui/macros/macro-span-issue-116502.rs:7:13: 7:14 (#4), "U"), 
    (/home/folkertdev/rust/rust/tests/ui/macros/macro-span-issue-116502.rs:10:13: 10:23 (#0), "<U>")
]
 right: [
    (/home/folkertdev/rust/rust/tests/ui/macros/macro-span-issue-116502.rs:7:13: 7:14 (#4), "U"), 
    (/home/folkertdev/rust/rust/tests/ui/macros/macro-span-issue-116502.rs:7:13: 7:14 (#5), "U"), 
    (/home/folkertdev/rust/rust/tests/ui/macros/macro-span-issue-116502.rs:7:13: 7:14 (#6), "U"), 
    (/home/folkertdev/rust/rust/tests/ui/macros/macro-span-issue-116502.rs:10:13: 10:23 (#0), "<U>")
]

so this may need something slightly different from span.data()?

btw the sorting is needed for just 2 test cases:

failures:
    [ui] tests/ui/moves/nested-loop-moved-value-wrong-continue.rs
    [ui] tests/ui/moves/recreating-value-in-loop-condition.rs

@folkertdev
Copy link
Contributor Author

this works

        suggestion.sort_by_key(|(span, _)| *span);
        let mut seen = crate::FxHashSet::default();
        suggestion.retain(|(span, msg)| {
            seen.insert((
                {
                    let mut data = span.data();
                    data.ctxt = rustc_span::hygiene::SyntaxContext::root();
                    data
                },
                msg.clone(),
            ))
        });

is that too hacky?

@compiler-errors
Copy link
Member

compiler-errors commented Aug 8, 2024

Sorry, I guess you really should be doing something like:

let mut seen = crate::FxHashSet::default();
suggestion.retain(|(span, msg)| seen.insert((span.lo(), span.hi(), msg.clone())));

To ignore the syntax context.

@compiler-errors
Copy link
Member

Also, you don't need to be sorting or deduplicating if you use this approach. That's the whole point of the retain call :)

@folkertdev folkertdev force-pushed the multipart-suggestion-stable-sort branch from d1dc694 to 38874a6 Compare August 9, 2024 07:45
Comment on lines -1127 to +1128
(parent.span, "value".to_string()),
(span.shrink_to_lo(), format!("let mut value = {value};{indent}")),
(parent.span, "value".to_string()),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@compiler-errors the sorting also matters for at which line the error is reported. In this one case, that actually caused issues. I've swapped the spans here now to preserve the current error message.

@compiler-errors
Copy link
Member

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Aug 9, 2024

📌 Commit 38874a6 has been approved by compiler-errors

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 9, 2024
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Aug 9, 2024
…able-sort, r=compiler-errors

use stable sort to sort multipart diagnostics

I think a stable sort should be used to sort the different parts of a multipart selection. The current unstable sort uses the text of the suggestion as a tie-breaker. That just doesn't seem right, and the order of the input is a better choice I think, because it gives the diagnostic author more control.

This came up when I was building a suggestion where

```rust
fn foo() {}
```

must be turned into an unsafe function, and an attribute must be added

```rust
#[target_feature(enable = "...")]
unsafe fn foo() {}
```

In this example, the two suggestions occur at the same position, but the order is extremely important: unsafe must come after the attribute. But the situation changes if there is a pub/pub(crate), and if the unsafe is already present. It just out that because of the suggestion text, there is no way for me to order the suggestions correctly.

This change probably should be tested, but are there tests of the diagnostics code itself in the tests?

r? `@estebank`
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Aug 9, 2024
…able-sort, r=compiler-errors

use stable sort to sort multipart diagnostics

I think a stable sort should be used to sort the different parts of a multipart selection. The current unstable sort uses the text of the suggestion as a tie-breaker. That just doesn't seem right, and the order of the input is a better choice I think, because it gives the diagnostic author more control.

This came up when I was building a suggestion where

```rust
fn foo() {}
```

must be turned into an unsafe function, and an attribute must be added

```rust
#[target_feature(enable = "...")]
unsafe fn foo() {}
```

In this example, the two suggestions occur at the same position, but the order is extremely important: unsafe must come after the attribute. But the situation changes if there is a pub/pub(crate), and if the unsafe is already present. It just out that because of the suggestion text, there is no way for me to order the suggestions correctly.

This change probably should be tested, but are there tests of the diagnostics code itself in the tests?

r? ``@estebank``
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 9, 2024
…iaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang#128815 (Add `Steal::is_stolen()`)
 - rust-lang#128817 (VxWorks code refactored )
 - rust-lang#128822 (add `builder-config` into tarball sources)
 - rust-lang#128838 (rustdoc: do not run doctests with invalid langstrings)
 - rust-lang#128852 (use stable sort to sort multipart diagnostics)
 - rust-lang#128859 (Fix the name of signal 19 in library/std/src/sys/pal/unix/process/process_unix/tests.rs for mips/sparc linux)
 - rust-lang#128864 (Use `SourceMap::end_point` instead of `- BytePos(1)` in arg removal suggestion)
 - rust-lang#128865 (Ensure let stmt compound assignment removal suggestion respect codepoint boundaries)
 - rust-lang#128874 (Disable verbose bootstrap command failure logging by default)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 2066002 into rust-lang:master Aug 9, 2024
6 checks passed
@rustbot rustbot added this to the 1.82.0 milestone Aug 9, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Aug 9, 2024
Rollup merge of rust-lang#128852 - folkertdev:multipart-suggestion-stable-sort, r=compiler-errors

use stable sort to sort multipart diagnostics

I think a stable sort should be used to sort the different parts of a multipart selection. The current unstable sort uses the text of the suggestion as a tie-breaker. That just doesn't seem right, and the order of the input is a better choice I think, because it gives the diagnostic author more control.

This came up when I was building a suggestion where

```rust
fn foo() {}
```

must be turned into an unsafe function, and an attribute must be added

```rust
#[target_feature(enable = "...")]
unsafe fn foo() {}
```

In this example, the two suggestions occur at the same position, but the order is extremely important: unsafe must come after the attribute. But the situation changes if there is a pub/pub(crate), and if the unsafe is already present. It just out that because of the suggestion text, there is no way for me to order the suggestions correctly.

This change probably should be tested, but are there tests of the diagnostics code itself in the tests?

r? ```@estebank```
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 9, 2024
…llaumeGomez

Rollup of 8 pull requests

Successful merges:

 - rust-lang#128815 (Add `Steal::is_stolen()`)
 - rust-lang#128822 (add `builder-config` into tarball sources)
 - rust-lang#128838 (rustdoc: do not run doctests with invalid langstrings)
 - rust-lang#128852 (use stable sort to sort multipart diagnostics)
 - rust-lang#128859 (Fix the name of signal 19 in library/std/src/sys/pal/unix/process/process_unix/tests.rs for mips/sparc linux)
 - rust-lang#128864 (Use `SourceMap::end_point` instead of `- BytePos(1)` in arg removal suggestion)
 - rust-lang#128865 (Ensure let stmt compound assignment removal suggestion respect codepoint boundaries)
 - rust-lang#128874 (Disable verbose bootstrap command failure logging by default)

r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants