| 
 | 1 | +use annotate_snippets::{AnnotationKind, Group, Level, Origin, Patch, Renderer, Snippet};  | 
 | 2 | + | 
 | 3 | +use snapbox::{assert_data_eq, file};  | 
 | 4 | + | 
 | 5 | +#[test]  | 
 | 6 | +fn case() {  | 
 | 7 | +    let source = r#"// Make sure suggestion for removal of a span that covers multiple lines is properly highlighted.  | 
 | 8 | +//@ compile-flags: --error-format=human --color=always  | 
 | 9 | +//@ edition:2018  | 
 | 10 | +//@ only-linux  | 
 | 11 | +// ignore-tidy-tab  | 
 | 12 | +// We use `\t` instead of spaces for indentation to ensure that the highlighting logic properly  | 
 | 13 | +// accounts for replaced characters (like we do for `\t` with `    `). The naïve way of highlighting  | 
 | 14 | +// could be counting chars of the original code, instead of operating on the code as it is being  | 
 | 15 | +// displayed.  | 
 | 16 | +use std::collections::{HashMap, HashSet};  | 
 | 17 | +fn foo() -> Vec<(bool, HashSet<u8>)> {  | 
 | 18 | +	let mut hm = HashMap::<bool, Vec<HashSet<u8>>>::new();  | 
 | 19 | +	hm.into_iter()  | 
 | 20 | +		.map(|(is_true, ts)| {  | 
 | 21 | +			ts.into_iter()  | 
 | 22 | +				.map(|t| {  | 
 | 23 | +					(  | 
 | 24 | +						is_true,  | 
 | 25 | +						t,  | 
 | 26 | +					)  | 
 | 27 | +				}).flatten()  | 
 | 28 | +		})  | 
 | 29 | +		.flatten()  | 
 | 30 | +		.collect()  | 
 | 31 | +}  | 
 | 32 | +fn bar() -> Vec<(bool, HashSet<u8>)> {  | 
 | 33 | +	let mut hm = HashMap::<bool, Vec<HashSet<u8>>>::new();  | 
 | 34 | +	hm.into_iter()  | 
 | 35 | +		.map(|(is_true, ts)| {  | 
 | 36 | +			ts.into_iter()  | 
 | 37 | +				.map(|t| (is_true, t))  | 
 | 38 | +				.flatten()  | 
 | 39 | +		})  | 
 | 40 | +		.flatten()  | 
 | 41 | +		.collect()  | 
 | 42 | +}  | 
 | 43 | +fn baz() -> Vec<(bool, HashSet<u8>)> {  | 
 | 44 | +	let mut hm = HashMap::<bool, Vec<HashSet<u8>>>::new();  | 
 | 45 | +	hm.into_iter()  | 
 | 46 | +		.map(|(is_true, ts)| {  | 
 | 47 | +			ts.into_iter().map(|t| {  | 
 | 48 | +				(is_true, t)  | 
 | 49 | +			}).flatten()  | 
 | 50 | +		})  | 
 | 51 | +		.flatten()  | 
 | 52 | +		.collect()  | 
 | 53 | +}  | 
 | 54 | +fn bay() -> Vec<(bool, HashSet<u8>)> {  | 
 | 55 | +	let mut hm = HashMap::<bool, Vec<HashSet<u8>>>::new();  | 
 | 56 | +	hm.into_iter()  | 
 | 57 | +		.map(|(is_true, ts)| {  | 
 | 58 | +			ts.into_iter()  | 
 | 59 | +				.map(|t| (is_true, t)).flatten()  | 
 | 60 | +		})  | 
 | 61 | +		.flatten()  | 
 | 62 | +		.collect()  | 
 | 63 | +}  | 
 | 64 | +fn main() {}  | 
 | 65 | +"#;  | 
 | 66 | + | 
 | 67 | +    let input = Level::ERROR  | 
 | 68 | +        .header("`(bool, HashSet<u8>)` is not an iterator")  | 
 | 69 | +        .id("E0277")  | 
 | 70 | +        .group(  | 
 | 71 | +            Group::new()  | 
 | 72 | +                .element(  | 
 | 73 | +                    Snippet::source(source)  | 
 | 74 | +                        .origin("$DIR/multiline-removal-suggestion.rs")  | 
 | 75 | +                        .fold(true)  | 
 | 76 | +                        .annotation(  | 
 | 77 | +                            AnnotationKind::Primary  | 
 | 78 | +                                .span(769..776)  | 
 | 79 | +                                .label("`(bool, HashSet<u8>)` is not an iterator"),  | 
 | 80 | +                        ),  | 
 | 81 | +                )  | 
 | 82 | +                .element(  | 
 | 83 | +                    Level::HELP  | 
 | 84 | +                        .title("the trait `Iterator` is not implemented for `(bool, HashSet<u8>)`"),  | 
 | 85 | +                )  | 
 | 86 | +                .element(  | 
 | 87 | +                    Level::NOTE  | 
 | 88 | +                        .title("required for `(bool, HashSet<u8>)` to implement `IntoIterator`"),  | 
 | 89 | +                ),  | 
 | 90 | +        )  | 
 | 91 | +        .group(  | 
 | 92 | +            Group::new()  | 
 | 93 | +                .element(Level::NOTE.title("required by a bound in `flatten`"))  | 
 | 94 | +                .element(  | 
 | 95 | +                    Origin::new("/rustc/FAKE_PREFIX/library/core/src/iter/traits/iterator.rs")  | 
 | 96 | +                        .line(1556)  | 
 | 97 | +                        .char_column(4),  | 
 | 98 | +                ),  | 
 | 99 | +        )  | 
 | 100 | +        .group(  | 
 | 101 | +            Group::new()  | 
 | 102 | +                .element(Level::HELP.title("consider removing this method call, as the receiver has type `std::vec::IntoIter<HashSet<u8>>` and `std::vec::IntoIter<HashSet<u8>>: Iterator` trivially holds"))  | 
 | 103 | +                .element(  | 
 | 104 | +                    Snippet::source(source)  | 
 | 105 | +                        .origin("$DIR/multiline-removal-suggestion.rs")  | 
 | 106 | +                        .fold(true)  | 
 | 107 | +                        .patch(Patch::new(708..768, "")),  | 
 | 108 | +                ),  | 
 | 109 | +        );  | 
 | 110 | +    let expected = file!["multiline_removal_suggestion.term.svg"];  | 
 | 111 | +    let renderer = Renderer::styled();  | 
 | 112 | +    assert_data_eq!(renderer.render(input), expected);  | 
 | 113 | +}  | 
0 commit comments