Skip to content
This repository has been archived by the owner on Nov 24, 2023. It is now read-only.

Allow multiple solutions in a suggestion #155

Merged
merged 4 commits into from
Dec 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ pub fn collect_suggestions<S: ::std::hash::BuildHasher>(
})
.filter_map(collect_span)
.collect();
if replacements.len() == 1 {
if replacements.len() >= 1 {
Some(Solution {
message: child.message.clone(),
replacements,
Expand Down
5 changes: 0 additions & 5 deletions tests/edge-cases/skip-multi-option-lints.fixed.rs

This file was deleted.

100 changes: 0 additions & 100 deletions tests/edge-cases/skip-multi-option-lints.json

This file was deleted.

5 changes: 0 additions & 5 deletions tests/edge-cases/skip-multi-option-lints.rs

This file was deleted.

12 changes: 0 additions & 12 deletions tests/edge_cases.rs

This file was deleted.

5 changes: 5 additions & 0 deletions tests/everything/multiple-solutions.fixed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use std::collections::{HashSet};

fn main() {
let _: HashSet<()>;
}
114 changes: 114 additions & 0 deletions tests/everything/multiple-solutions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
{
"message": "unused imports: `HashMap`, `VecDeque`",
"code": {
"code": "unused_imports",
"explanation": null
},
"level": "warning",
"spans": [
{
"file_name": "src/main.rs",
"byte_start": 23,
"byte_end": 30,
"line_start": 1,
"line_end": 1,
"column_start": 24,
"column_end": 31,
"is_primary": true,
"text": [
{
"text": "use std::collections::{HashMap, HashSet, VecDeque};",
"highlight_start": 24,
"highlight_end": 31
}
],
"label": null,
"suggested_replacement": null,
"suggestion_applicability": null,
"expansion": null
},
{
"file_name": "src/main.rs",
"byte_start": 41,
"byte_end": 49,
"line_start": 1,
"line_end": 1,
"column_start": 42,
"column_end": 50,
"is_primary": true,
"text": [
{
"text": "use std::collections::{HashMap, HashSet, VecDeque};",
"highlight_start": 42,
"highlight_end": 50
}
],
"label": null,
"suggested_replacement": null,
"suggestion_applicability": null,
"expansion": null
}
],
"children": [
{
"message": "#[warn(unused_imports)] on by default",
"code": null,
"level": "note",
"spans": [],
"children": [],
"rendered": null
},
{
"message": "remove the unused imports",
"code": null,
"level": "help",
"spans": [
{
"file_name": "src/main.rs",
"byte_start": 23,
"byte_end": 32,
"line_start": 1,
"line_end": 1,
"column_start": 24,
"column_end": 33,
"is_primary": true,
"text": [
{
"text": "use std::collections::{HashMap, HashSet, VecDeque};",
"highlight_start": 24,
"highlight_end": 33
}
],
"label": null,
"suggested_replacement": "",
"suggestion_applicability": "MachineApplicable",
"expansion": null
},
{
"file_name": "src/main.rs",
"byte_start": 39,
"byte_end": 49,
"line_start": 1,
"line_end": 1,
"column_start": 40,
"column_end": 50,
"is_primary": true,
"text": [
{
"text": "use std::collections::{HashMap, HashSet, VecDeque};",
"highlight_start": 40,
"highlight_end": 50
}
],
"label": null,
"suggested_replacement": "",
"suggestion_applicability": "MachineApplicable",
"expansion": null
}
],
"children": [],
"rendered": null
}
],
"rendered": "warning: unused imports: `HashMap`, `VecDeque`\n --> src/main.rs:1:24\n |\n1 | use std::collections::{HashMap, HashSet, VecDeque};\n | ^^^^^^^ ^^^^^^^^\n |\n = note: #[warn(unused_imports)] on by default\nhelp: remove the unused imports\n |\n1 | use std::collections::{HashSet};\n | -- --\n\n"
}
5 changes: 5 additions & 0 deletions tests/everything/multiple-solutions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use std::collections::{HashMap, HashSet, VecDeque};

fn main() {
let _: HashSet<()>;
}
50 changes: 4 additions & 46 deletions tests/parse_and_replace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ mod fixmode {

mod settings {
// can be set as env var to debug
pub const CHECK_JSON: &str = "RUSTFIX_TEST_CHECK_JSON";
pub const RECORD_JSON: &str = "RUSTFIX_TEST_RECORD_JSON";
pub const RECORD_FIXED_RUST: &str = "RUSTFIX_TEST_RECORD_FIXED_RUST";
}

Expand Down Expand Up @@ -62,20 +60,6 @@ fn compile(file: &Path, mode: &str) -> Result<Output, Error> {
Ok(res)
}

fn compile_and_get_json_errors(file: &Path, mode: &str) -> Result<String, Error> {
let res = compile(file, mode)?;
let stderr = String::from_utf8(res.stderr)?;

match res.status.code() {
Some(0) | Some(1) | Some(101) => Ok(stderr),
_ => Err(format_err!(
"failed with status {:?}: {}",
res.status.code(),
stderr
)),
}
}

fn compiles_without_errors(file: &Path, mode: &str) -> Result<(), Error> {
let res = compile(file, mode)?;

Expand Down Expand Up @@ -122,7 +106,8 @@ fn diff(expected: &str, actual: &str) -> String {
write!(
&mut res,
"differences found (+ == actual, - == expected):\n"
).unwrap();
)
.unwrap();
different = true;
}
for diff in diff.lines() {
Expand All @@ -149,39 +134,12 @@ fn test_rustfix_with_file<P: AsRef<Path>>(file: P, mode: &str) -> Result<(), Err

debug!("next up: {:?}", file);
let code = read_file(file).context(format!("could not read {}", file.display()))?;
let errors = compile_and_get_json_errors(file, mode)
.context(format!("could compile {}", file.display()))?;
let errors = read_file(&json_file)
.with_context(|_| format!("could not load json suggestions for {}", file.display()))?;
let suggestions =
rustfix::get_suggestions_from_json(&errors, &HashSet::new(), filter_suggestions)
.context("could not load suggestions")?;

if std::env::var(settings::RECORD_JSON).is_ok() {
use std::io::Write;
let mut recorded_json = fs::File::create(&file.with_extension("recorded.json")).context(
format!("could not create recorded.json for {}", file.display()),
)?;
recorded_json.write_all(errors.as_bytes())?;
}

if std::env::var(settings::CHECK_JSON).is_ok() {
let expected_json = read_file(&json_file).context(format!(
"could not load json fixtures for {}",
file.display()
))?;
let expected_suggestions =
rustfix::get_suggestions_from_json(&expected_json, &HashSet::new(), filter_suggestions)
.context("could not load expected suggesitons")?;

ensure!(
expected_suggestions == suggestions,
"got unexpected suggestions from clippy:\n{}",
diff(
&format!("{:?}", expected_suggestions),
&format!("{:?}", suggestions)
)
);
}

let fixed = apply_suggestions(&code, &suggestions)
.context(format!("could not apply suggestions to {}", file.display()))?;

Expand Down