Skip to content

Commit ab692e6

Browse files
authored
Merge pull request #215 from Muscraft/multiline-reorder
fix: Match rustc's multiline reordering
2 parents e14a69d + c8041fe commit ab692e6

File tree

3 files changed

+101
-11
lines changed

3 files changed

+101
-11
lines changed

src/renderer/source_map.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,7 @@ impl<'a> SourceMap<'a> {
194194
let mut primary_spans = vec![];
195195

196196
// Find overlapping multiline annotations, put them at different depths
197-
multiline_annotations
198-
.sort_by_key(|ml| (ml.start.line, usize::MAX - ml.end.line, ml.start.byte));
197+
multiline_annotations.sort_by_key(|ml| (ml.start.line, usize::MAX - ml.end.line));
199198
for ann in multiline_annotations.clone() {
200199
if ann.kind.is_primary() {
201200
primary_spans.push((ann.start, ann.end));

tests/formatter.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -887,15 +887,15 @@ bar = { version = "0.1.0", optional = true }
887887
error: unused optional dependency
888888
|
889889
4 | bar = { version = "0.1.0", optional = true }
890-
| _________^__________________--------------^
891-
| | | |
892-
| |_________| This should also be long but not too long
890+
| __________^__________________--------------^
891+
| | | |
892+
| | _________| This should also be long but not too long
893893
| ||
894894
5 | || this is another line
895895
6 | || so is this
896896
7 | || bar = { version = "0.1.0", optional = true }
897897
| ||_________________________^________________^ I need this to be really long so I can test overlaps
898-
| |__________________________|
898+
| |_________________________|
899899
| I need this to be really long so I can test overlaps
900900
"#]];
901901
let renderer = Renderer::plain();
@@ -940,16 +940,16 @@ this is another line
940940
error: unused optional dependency
941941
|
942942
4 | bar = { version = "0.1.0", optional = true }
943-
| __________^__________________--------------^
944-
| | | |
945-
| |__________| This should also be long but not too long
943+
| ___________^__________________--------------^
944+
| | | |
945+
| | __________| This should also be long but not too long
946946
| ||
947947
5 | || this is another line
948948
| || ____^
949949
6 | ||| so is this
950950
7 | ||| bar = { version = "0.1.0", optional = true }
951951
| |||_________________________^________________^ I need this to be really long so I can test overlaps
952-
| |_|_________________________|
952+
| ||_________________________|
953953
| | I need this to be really long so I can test overlaps
954954
8 | | this is another line
955955
| |____^ I need this to be really long so I can test overlaps

tests/rustc_tests.rs

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//!
33
//! [parser-tests]: https://github.com/rust-lang/rust/blob/894f7a4ba6554d3797404bbf550d9919df060b97/compiler/rustc_parse/src/parser/tests.rs
44
5-
use annotate_snippets::{AnnotationKind, Group, Level, Origin, Renderer, Snippet};
5+
use annotate_snippets::{AnnotationKind, Group, Level, Origin, Patch, Renderer, Snippet};
66

77
use annotate_snippets::renderer::OutputTheme;
88
use snapbox::{assert_data_eq, str};
@@ -2020,3 +2020,94 @@ LL | ... = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...0, 0, 0, 0, 0, 0, 0, 0, 0
20202020
.term_width(120);
20212021
assert_data_eq!(renderer.render(input), expected);
20222022
}
2023+
2024+
#[test]
2025+
fn lint_map_unit_fn() {
2026+
// tests/ui/lint/lint_map_unit_fn.rs
2027+
let source = r#"#![deny(map_unit_fn)]
2028+
2029+
fn foo(items: &mut Vec<u8>) {
2030+
items.sort();
2031+
}
2032+
2033+
fn main() {
2034+
let mut x: Vec<Vec<u8>> = vec![vec![0, 2, 1], vec![5, 4, 3]];
2035+
x.iter_mut().map(foo);
2036+
//~^ ERROR `Iterator::map` call that discard the iterator's values
2037+
x.iter_mut().map(|items| {
2038+
//~^ ERROR `Iterator::map` call that discard the iterator's values
2039+
items.sort();
2040+
});
2041+
let f = |items: &mut Vec<u8>| {
2042+
items.sort();
2043+
};
2044+
x.iter_mut().map(f);
2045+
//~^ ERROR `Iterator::map` call that discard the iterator's values
2046+
}
2047+
"#;
2048+
2049+
let input = Level::ERROR
2050+
.header("`Iterator::map` call that discard the iterator's values")
2051+
.group(
2052+
Group::new()
2053+
.element(
2054+
Snippet::source(source)
2055+
.origin("$DIR/lint_map_unit_fn.rs")
2056+
.fold(true)
2057+
.annotation(AnnotationKind::Context.span(271..278).label(
2058+
"this function returns `()`, which is likely not what you wanted",
2059+
))
2060+
.annotation(
2061+
AnnotationKind::Context
2062+
.span(271..379)
2063+
.label("called `Iterator::map` with callable that returns `()`"),
2064+
)
2065+
.annotation(
2066+
AnnotationKind::Context
2067+
.span(267..380)
2068+
.label("after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items")
2069+
)
2070+
.annotation(AnnotationKind::Primary.span(267..380)),
2071+
)
2072+
.element(
2073+
Level::NOTE.title("`Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated")),
2074+
)
2075+
.group(
2076+
Group::new()
2077+
.element(Level::HELP.title("you might have meant to use `Iterator::for_each`"))
2078+
.element(
2079+
Snippet::source(source)
2080+
.origin("$DIR/lint_map_unit_fn.rs")
2081+
.fold(true)
2082+
.patch(Patch::new(267..270, r#"for_each"#)),
2083+
),
2084+
);
2085+
2086+
let expected = str![[r#"
2087+
error: `Iterator::map` call that discard the iterator's values
2088+
--> $DIR/lint_map_unit_fn.rs:11:18
2089+
|
2090+
LL | x.iter_mut().map(|items| {
2091+
| ^ -------
2092+
| | |
2093+
| ____________________|___this function returns `()`, which is likely not what you wanted
2094+
| | __________________|
2095+
| | |
2096+
LL | | | //~^ ERROR `Iterator::map` call that discard the iterator's values
2097+
LL | | | items.sort();
2098+
LL | | | });
2099+
| | | -^ after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items
2100+
| | |_____||
2101+
| |_______|
2102+
| called `Iterator::map` with callable that returns `()`
2103+
|
2104+
= note: `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated
2105+
help: you might have meant to use `Iterator::for_each`
2106+
|
2107+
LL - x.iter_mut().map(|items| {
2108+
LL + x.iter_mut().for_each(|items| {
2109+
|
2110+
"#]];
2111+
let renderer = Renderer::plain().anonymized_line_numbers(true);
2112+
assert_data_eq!(renderer.render(input), expected);
2113+
}

0 commit comments

Comments
 (0)