mirror of
https://github.com/rust-lang/cargo
synced 2024-09-28 20:15:04 +00:00
Auto merge of #14092 - Alexendoo:rustfix-separate-suggestions, r=weihanglo
Add `CodeFix::apply_solution` and impl `Clone` ### What does this PR try to resolve? In Clippy we have a good few lints that produce mutually exclusive suggestions e.g. ``` error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:6:19 | LL | let _bad2 = b"\033[0m"; | ^^^^ | help: if an octal escape is intended, use a hex escape instead | LL | let _bad2 = b"\x1b[0m"; | ~~~~ help: if a null escape is intended, disambiguate using | LL | let _bad2 = b"\x0033[0m"; | ~~~~~~ ``` For these we have to disable rustfix tests since the suggestions are overlapping, this PR adds a method to `rustfix` that `ui_test` could use in order to produce multiple `.fixed` files, one for each alternative suggestion ### Additional information It does not work for for multiple suggestions coming from a single subdiagnostic ([`Diag::span_suggestions`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/diagnostic/struct.Diag.html#method.span_suggestions)) e.g. ``` help: consider importing one of these items | 1 + use std::collections::HashMap; | 1 + use ahash::HashMap; ``` Solving this would be blocked on https://github.com/rust-lang/rust/issues/53934, on the Clippy side we only have one use of `span_suggestions` however so it's still very useful without this The test cases use Clippy lints that I generated by setting the `parse_and_replace` test to use `clippy-driver` because of familiarity, if there's a rustc case that does multiple suggestions it would be good to go with that
This commit is contained in:
commit
99361c46e0
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -2943,7 +2943,7 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
|||
|
||||
[[package]]
|
||||
name = "rustfix"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"proptest",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "rustfix"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
authors = [
|
||||
"Pascal Hertleif <killercup@gmail.com>",
|
||||
"Oliver Schneider <oli-obk@users.noreply.github.com>",
|
||||
|
|
|
@ -213,6 +213,7 @@ pub fn collect_suggestions<S: ::std::hash::BuildHasher>(
|
|||
/// 1. Feeds the source of a file to [`CodeFix::new`].
|
||||
/// 2. Calls [`CodeFix::apply`] to apply suggestions to the source code.
|
||||
/// 3. Calls [`CodeFix::finish`] to get the "fixed" code.
|
||||
#[derive(Clone)]
|
||||
pub struct CodeFix {
|
||||
data: replace::Data,
|
||||
/// Whether or not the data has been modified.
|
||||
|
@ -230,12 +231,18 @@ impl CodeFix {
|
|||
|
||||
/// Applies a suggestion to the code.
|
||||
pub fn apply(&mut self, suggestion: &Suggestion) -> Result<(), Error> {
|
||||
for sol in &suggestion.solutions {
|
||||
for r in &sol.replacements {
|
||||
self.data
|
||||
.replace_range(r.snippet.range.clone(), r.replacement.as_bytes())?;
|
||||
self.modified = true;
|
||||
}
|
||||
for solution in &suggestion.solutions {
|
||||
self.apply_solution(solution)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Applies an individual solution from a [`Suggestion`].
|
||||
pub fn apply_solution(&mut self, solution: &Solution) -> Result<(), Error> {
|
||||
for r in &solution.replacements {
|
||||
self.data
|
||||
.replace_range(r.snippet.range.clone(), r.replacement.as_bytes())?;
|
||||
self.modified = true;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue