From 8a8f0be9322af271537f609f18d15a437c8a1679 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Sat, 8 Dec 2018 23:10:01 +0100 Subject: [PATCH 1/2] remove test about multi-option lints --- .../skip-multi-option-lints.fixed.rs | 5 - tests/edge-cases/skip-multi-option-lints.json | 100 ------------------ tests/edge-cases/skip-multi-option-lints.rs | 5 - tests/edge_cases.rs | 12 --- 4 files changed, 122 deletions(-) delete mode 100644 tests/edge-cases/skip-multi-option-lints.fixed.rs delete mode 100644 tests/edge-cases/skip-multi-option-lints.json delete mode 100644 tests/edge-cases/skip-multi-option-lints.rs delete mode 100644 tests/edge_cases.rs diff --git a/tests/edge-cases/skip-multi-option-lints.fixed.rs b/tests/edge-cases/skip-multi-option-lints.fixed.rs deleted file mode 100644 index 9e12371..0000000 --- a/tests/edge-cases/skip-multi-option-lints.fixed.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - let xs = vec![String::from("foo")]; - let d: &Display = &xs; - println!("{}", d); -} diff --git a/tests/edge-cases/skip-multi-option-lints.json b/tests/edge-cases/skip-multi-option-lints.json deleted file mode 100644 index dc61ae6..0000000 --- a/tests/edge-cases/skip-multi-option-lints.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "message": "cannot find type `Display` in this scope", - "code": { - "code": "E0412", - "explanation": "\nThe type name used is not in scope.\n\nErroneous code examples:\n\n```compile_fail,E0412\nimpl Something {} // error: type name `Something` is not in scope\n\n// or:\n\ntrait Foo {\n fn bar(N); // error: type name `N` is not in scope\n}\n\n// or:\n\nfn foo(x: T) {} // type name `T` is not in scope\n```\n\nTo fix this error, please verify you didn't misspell the type name, you did\ndeclare it or imported it into the scope. Examples:\n\n```\nstruct Something;\n\nimpl Something {} // ok!\n\n// or:\n\ntrait Foo {\n type N;\n\n fn bar(_: Self::N); // ok!\n}\n\n// or:\n\nfn foo(x: T) {} // ok!\n```\n\nAnother case that causes this error is when a type is imported into a parent\nmodule. To fix this, you can follow the suggestion and use File directly or\n`use super::File;` which will import the types from the parent namespace. An\nexample that causes this error is below:\n\n```compile_fail,E0412\nuse std::fs::File;\n\nmod foo {\n fn some_function(f: File) {}\n}\n```\n\n```\nuse std::fs::File;\n\nmod foo {\n // either\n use super::File;\n // or\n // use std::fs::File;\n fn foo(f: File) {}\n}\n# fn main() {} // don't insert it for us; that'll break imports\n```\n" - }, - "level": "error", - "spans": [ - { - "file_name": "./tests/everything/skip-multi-option-lints.rs", - "byte_start": 64, - "byte_end": 71, - "line_start": 3, - "line_end": 3, - "column_start": 13, - "column_end": 20, - "is_primary": true, - "text": [ - { - "text": " let d: &Display = &xs;", - "highlight_start": 13, - "highlight_end": 20 - } - ], - "label": "not found in this scope", - "suggested_replacement": null, - "expansion": null - } - ], - "children": [ - { - "message": "possible candidates are found in other modules, you can import them into scope", - "code": null, - "level": "help", - "spans": [ - { - "file_name": "./tests/everything/skip-multi-option-lints.rs", - "byte_start": 0, - "byte_end": 0, - "line_start": 1, - "line_end": 1, - "column_start": 1, - "column_end": 1, - "is_primary": true, - "text": [ - { - "text": "fn main() {", - "highlight_start": 1, - "highlight_end": 1 - } - ], - "label": null, - "suggested_replacement": "use std::fmt::Display;\n\n", - "suggestion_applicability": "Unspecified", - "expansion": null - }, - { - "file_name": "./tests/everything/skip-multi-option-lints.rs", - "byte_start": 0, - "byte_end": 0, - "line_start": 1, - "line_end": 1, - "column_start": 1, - "column_end": 1, - "is_primary": true, - "text": [ - { - "text": "fn main() {", - "highlight_start": 1, - "highlight_end": 1 - } - ], - "label": null, - "suggested_replacement": "use std::path::Display;\n\n", - "suggestion_applicability": "Unspecified", - "expansion": null - } - ], - "children": [], - "rendered": null - } - ], - "rendered": "error[E0412]: cannot find type `Display` in this scope\n --> ./tests/everything/skip-multi-option-lints.rs:3:13\n |\n3 | let d: &Display = &xs;\n | ^^^^^^^ not found in this scope\nhelp: possible candidates are found in other modules, you can import them into scope\n |\n1 | use std::fmt::Display;\n |\n1 | use std::path::Display;\n |\n\n" -} -{ - "message": "aborting due to previous error", - "code": null, - "level": "error", - "spans": [], - "children": [], - "rendered": "error: aborting due to previous error\n\n" -} -{ - "message": "For more information about this error, try `rustc --explain E0412`.", - "code": null, - "level": "", - "spans": [], - "children": [], - "rendered": "For more information about this error, try `rustc --explain E0412`.\n" -} diff --git a/tests/edge-cases/skip-multi-option-lints.rs b/tests/edge-cases/skip-multi-option-lints.rs deleted file mode 100644 index 9e12371..0000000 --- a/tests/edge-cases/skip-multi-option-lints.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - let xs = vec![String::from("foo")]; - let d: &Display = &xs; - println!("{}", d); -} diff --git a/tests/edge_cases.rs b/tests/edge_cases.rs deleted file mode 100644 index 8848988..0000000 --- a/tests/edge_cases.rs +++ /dev/null @@ -1,12 +0,0 @@ -extern crate rustfix; -use std::collections::HashSet; -use std::fs; - -#[test] -fn multiple_fix_options_yield_no_suggestions() { - let json = fs::read_to_string("./tests/edge-cases/skip-multi-option-lints.json").unwrap(); - let expected_suggestions = - rustfix::get_suggestions_from_json(&json, &HashSet::new(), rustfix::Filter::Everything) - .unwrap(); - assert!(expected_suggestions.is_empty()); -} From 8e0d7c0d6c4fa16bf194d6d1609f59d81136b45d Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Wed, 6 Feb 2019 05:30:22 -0800 Subject: [PATCH 2/2] accept multi-part solutions/substitutions This is meant to be the resolution to #141 (and, in a way, rust-lang/rust#53934). We add two test fixtures demonstrating usage and correctness. The JSON comes from a locally-built non-master compiler featuring the change to the JSON emitter to support this. (Actually, one is from `--error-format pretty-json` and the other is from `--error-format json` and subsequent auto-formatting, but the difference in inter-string-literal newlines doesn't seem to matter.) --- src/lib.rs | 2 +- tests/everything/dot-dot-not-last.fixed.rs | 6 + tests/everything/dot-dot-not-last.json | 126 ++++++++++++++++ tests/everything/dot-dot-not-last.rs | 6 + .../explicit-outlives-multispan.fixed.rs | 11 ++ .../explicit-outlives-multispan.json | 136 ++++++++++++++++++ .../everything/explicit-outlives-multispan.rs | 11 ++ 7 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 tests/everything/dot-dot-not-last.fixed.rs create mode 100644 tests/everything/dot-dot-not-last.json create mode 100644 tests/everything/dot-dot-not-last.rs create mode 100644 tests/everything/explicit-outlives-multispan.fixed.rs create mode 100644 tests/everything/explicit-outlives-multispan.json create mode 100644 tests/everything/explicit-outlives-multispan.rs diff --git a/src/lib.rs b/src/lib.rs index 83f7e37..0cf4f34 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -184,7 +184,7 @@ pub fn collect_suggestions( }) .filter_map(collect_span) .collect(); - if replacements.len() == 1 { + if !replacements.is_empty() { Some(Solution { message: child.message.clone(), replacements, diff --git a/tests/everything/dot-dot-not-last.fixed.rs b/tests/everything/dot-dot-not-last.fixed.rs new file mode 100644 index 0000000..d7e5d84 --- /dev/null +++ b/tests/everything/dot-dot-not-last.fixed.rs @@ -0,0 +1,6 @@ +struct Point { x: isize, y: isize } + +fn main() { + let p = Point { x: 1, y: 2 }; + let Point { y, .. } = p; +} diff --git a/tests/everything/dot-dot-not-last.json b/tests/everything/dot-dot-not-last.json new file mode 100644 index 0000000..9ca657d --- /dev/null +++ b/tests/everything/dot-dot-not-last.json @@ -0,0 +1,126 @@ +{ + "message": "expected `}`, found `,`", + "code": null, + "level": "error", + "spans": [ + { + "file_name": "$DIR/issue-53934-multiple-parts.rs", + "byte_start": 166, + "byte_end": 167, + "line_start": 7, + "line_end": 7, + "column_start": 19, + "column_end": 20, + "is_primary": true, + "text": [ + { + "text": " let Point { .., y, } = p;", + "highlight_start": 19, + "highlight_end": 20 + } + ], + "label": "expected `}`", + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + }, + { + "file_name": "$DIR/issue-53934-multiple-parts.rs", + "byte_start": 164, + "byte_end": 167, + "line_start": 7, + "line_end": 7, + "column_start": 17, + "column_end": 20, + "is_primary": false, + "text": [ + { + "text": " let Point { .., y, } = p;", + "highlight_start": 17, + "highlight_end": 20 + } + ], + "label": "`..` must be at the end and cannot have a trailing comma", + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": [ + { + "message": "move the `..` to the end of the field list", + "code": null, + "level": "help", + "spans": [ + { + "file_name": "$DIR/issue-53934-multiple-parts.rs", + "byte_start": 164, + "byte_end": 168, + "line_start": 7, + "line_end": 7, + "column_start": 17, + "column_end": 21, + "is_primary": true, + "text": [ + { + "text": " let Point { .., y, } = p;", + "highlight_start": 17, + "highlight_end": 21 + } + ], + "label": null, + "suggested_replacement": "", + "suggestion_applicability": "MachineApplicable", + "expansion": null + }, + { + "file_name": "$DIR/issue-53934-multiple-parts.rs", + "byte_start": 171, + "byte_end": 172, + "line_start": 7, + "line_end": 7, + "column_start": 24, + "column_end": 25, + "is_primary": true, + "text": [ + { + "text": " let Point { .., y, } = p;", + "highlight_start": 24, + "highlight_end": 25 + } + ], + "label": null, + "suggested_replacement": ".. }", + "suggestion_applicability": "MachineApplicable", + "expansion": null + } + ], + "children": [], + "rendered": null + } + ], + "rendered": "error: expected `}`, found `,` + --> $DIR/issue-53934-multiple-parts.rs:7:19 + | +LL | let Point { .., y, } = p; + | --^ + | | | + | | expected `}` + | `..` must be at the end and cannot have a trailing comma +help: move the `..` to the end of the field list + | +LL | let Point { y, .. } = p; + | -- ^^^^ + +" +} +{ + "message": "aborting due to previous error", + "code": null, + "level": "error", + "spans": [], + "children": [], + "rendered": "error: aborting due to previous error + +" +} diff --git a/tests/everything/dot-dot-not-last.rs b/tests/everything/dot-dot-not-last.rs new file mode 100644 index 0000000..71f5390 --- /dev/null +++ b/tests/everything/dot-dot-not-last.rs @@ -0,0 +1,6 @@ +struct Point { x: isize, y: isize } + +fn main() { + let p = Point { x: 1, y: 2 }; + let Point { .., y, } = p; +} diff --git a/tests/everything/explicit-outlives-multispan.fixed.rs b/tests/everything/explicit-outlives-multispan.fixed.rs new file mode 100644 index 0000000..fdfed74 --- /dev/null +++ b/tests/everything/explicit-outlives-multispan.fixed.rs @@ -0,0 +1,11 @@ +#![allow(dead_code)] +#![deny(explicit_outlives_requirements)] + +use std::fmt::Debug; + +struct TeeOutlivesAyYooBeeIsDebug<'a, 'b, T, U: Debug> { + tee: &'a T, + yoo: &'b U +} + +fn main() {} diff --git a/tests/everything/explicit-outlives-multispan.json b/tests/everything/explicit-outlives-multispan.json new file mode 100644 index 0000000..661be86 --- /dev/null +++ b/tests/everything/explicit-outlives-multispan.json @@ -0,0 +1,136 @@ +{ + "message": "outlives requirements can be inferred", + "code": { + "code": "explicit_outlives_requirements", + "explanation": null + }, + "level": "error", + "spans": [ + { + "file_name": "/home/zmd/Code/rustfix/tests/everything/explicit-outlives-multispan.rs", + "byte_start": 128, + "byte_end": 132, + "line_start": 6, + "line_end": 6, + "column_start": 44, + "column_end": 48, + "is_primary": true, + "text": [ + { + "text": "struct TeeOutlivesAyYooBeeIsDebug<'a, 'b, T: 'a, U: 'b + Debug> {", + "highlight_start": 44, + "highlight_end": 48 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + }, + { + "file_name": "/home/zmd/Code/rustfix/tests/everything/explicit-outlives-multispan.rs", + "byte_start": 137, + "byte_end": 142, + "line_start": 6, + "line_end": 6, + "column_start": 53, + "column_end": 58, + "is_primary": true, + "text": [ + { + "text": "struct TeeOutlivesAyYooBeeIsDebug<'a, 'b, T: 'a, U: 'b + Debug> {", + "highlight_start": 53, + "highlight_end": 58 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": [ + { + "message": "lint level defined here", + "code": null, + "level": "note", + "spans": [ + { + "file_name": "/home/zmd/Code/rustfix/tests/everything/explicit-outlives-multispan.rs", + "byte_start": 29, + "byte_end": 59, + "line_start": 2, + "line_end": 2, + "column_start": 9, + "column_end": 39, + "is_primary": true, + "text": [ + { + "text": "#![deny(explicit_outlives_requirements)]", + "highlight_start": 9, + "highlight_end": 39 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": [], + "rendered": null + }, + { + "message": "remove these bounds", + "code": null, + "level": "help", + "spans": [ + { + "file_name": "/home/zmd/Code/rustfix/tests/everything/explicit-outlives-multispan.rs", + "byte_start": 128, + "byte_end": 132, + "line_start": 6, + "line_end": 6, + "column_start": 44, + "column_end": 48, + "is_primary": true, + "text": [ + { + "text": "struct TeeOutlivesAyYooBeeIsDebug<'a, 'b, T: 'a, U: 'b + Debug> {", + "highlight_start": 44, + "highlight_end": 48 + } + ], + "label": null, + "suggested_replacement": "", + "suggestion_applicability": "MachineApplicable", + "expansion": null + }, + { + "file_name": "/home/zmd/Code/rustfix/tests/everything/explicit-outlives-multispan.rs", + "byte_start": 137, + "byte_end": 142, + "line_start": 6, + "line_end": 6, + "column_start": 53, + "column_end": 58, + "is_primary": true, + "text": [ + { + "text": "struct TeeOutlivesAyYooBeeIsDebug<'a, 'b, T: 'a, U: 'b + Debug> {", + "highlight_start": 53, + "highlight_end": 58 + } + ], + "label": null, + "suggested_replacement": "", + "suggestion_applicability": "MachineApplicable", + "expansion": null + } + ], + "children": [], + "rendered": null + } + ], + "rendered": "error: outlives requirements can be inferred\n --> /home/zmd/Code/rustfix/tests/everything/explicit-outlives-multispan.rs:6:44\n |\n6 | struct TeeOutlivesAyYooBeeIsDebug<'a, 'b, T: 'a, U: 'b + Debug> {\n | ^^^^ ^^^^^\n |\nnote: lint level defined here\n --> /home/zmd/Code/rustfix/tests/everything/explicit-outlives-multispan.rs:2:9\n |\n2 | #![deny(explicit_outlives_requirements)]\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: remove these bounds\n |\n6 | struct TeeOutlivesAyYooBeeIsDebug<'a, 'b, T, U: Debug> {\n | -- --\n\n" +} diff --git a/tests/everything/explicit-outlives-multispan.rs b/tests/everything/explicit-outlives-multispan.rs new file mode 100644 index 0000000..c3d2656 --- /dev/null +++ b/tests/everything/explicit-outlives-multispan.rs @@ -0,0 +1,11 @@ +#![allow(dead_code)] +#![deny(explicit_outlives_requirements)] + +use std::fmt::Debug; + +struct TeeOutlivesAyYooBeeIsDebug<'a, 'b, T: 'a, U: 'b + Debug> { + tee: &'a T, + yoo: &'b U +} + +fn main() {}