Skip to content
This repository was 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
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
@@ -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,
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
@@ -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";
}

@@ -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)?;

@@ -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() {
@@ -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()))?;