Skip to content

Commit 48dbf19

Browse files
authored
Merge pull request #324 from Muscraft/fix-suggestion-span-eol
fix: Show full line when patch span is points to line end
2 parents 450b2ea + 3a561d4 commit 48dbf19

File tree

2 files changed

+189
-6
lines changed

2 files changed

+189
-6
lines changed

src/renderer/source_map.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ impl<'a> SourceMap<'a> {
130130
}
131131
lines.push(line_info);
132132
}
133+
134+
if lines.is_empty() && !self.lines.is_empty() {
135+
lines.push(self.lines.last().unwrap());
136+
}
137+
133138
lines
134139
}
135140

tests/formatter.rs

Lines changed: 184 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3577,6 +3577,184 @@ fn empty_span_start_line() {
35773577
assert_data_eq!(renderer.render(input), expected_unicode);
35783578
}
35793579

3580+
#[test]
3581+
fn suggestion_span_line_end() {
3582+
let source = r#"#![allow(unused)]
3583+
fn main() {
3584+
[1, 2, 3].into_iter().for_each(|n| { *n; });
3585+
}
3586+
"#;
3587+
3588+
let long_title1 ="this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021";
3589+
let long_title2 = "for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>";
3590+
let long_title3 = "or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value";
3591+
3592+
let input = &[
3593+
Level::WARNING
3594+
.primary_title(long_title1)
3595+
.element(
3596+
Snippet::source(source)
3597+
.path("lint_example.rs")
3598+
.annotation(AnnotationKind::Primary.span(40..49)),
3599+
)
3600+
.element(Level::WARNING.message("this changes meaning in Rust 2021"))
3601+
.element(Level::NOTE.message(long_title2))
3602+
.element(Level::NOTE.message("`#[warn(array_into_iter)]` on by default")),
3603+
Level::HELP
3604+
.secondary_title("use `.iter()` instead of `.into_iter()` to avoid ambiguity")
3605+
.element(
3606+
Snippet::source(source)
3607+
.path("lint_example.rs")
3608+
.line_start(3)
3609+
.patch(Patch::new(40..49, "iter")),
3610+
),
3611+
Level::HELP.secondary_title(long_title3).element(
3612+
Snippet::source(source)
3613+
.path("lint_example.rs")
3614+
.line_start(3)
3615+
.patch(Patch::new(74..74, " // Span after line end")),
3616+
),
3617+
];
3618+
3619+
let expected_ascii = str![[r#"
3620+
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
3621+
--> lint_example.rs:3:11
3622+
|
3623+
3 | [1, 2, 3].into_iter().for_each(|n| { *n; });
3624+
| ^^^^^^^^^
3625+
|
3626+
= warning: this changes meaning in Rust 2021
3627+
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
3628+
= note: `#[warn(array_into_iter)]` on by default
3629+
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
3630+
|
3631+
5 - [1, 2, 3].into_iter().for_each(|n| { *n; });
3632+
5 + [1, 2, 3].iter().for_each(|n| { *n; });
3633+
|
3634+
help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
3635+
|
3636+
5 | [1, 2, 3].into_iter().for_each(|n| { *n; }); // Span after line end
3637+
| ++++++++++++++++++++++
3638+
"#]];
3639+
let renderer = Renderer::plain();
3640+
assert_data_eq!(renderer.render(input), expected_ascii);
3641+
3642+
let expected_unicode = str![[r#"
3643+
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
3644+
╭▸ lint_example.rs:3:11
3645+
3646+
3 │ [1, 2, 3].into_iter().for_each(|n| { *n; });
3647+
│ ━━━━━━━━━
3648+
3649+
├ warning: this changes meaning in Rust 2021
3650+
├ note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
3651+
╰ note: `#[warn(array_into_iter)]` on by default
3652+
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
3653+
╭╴
3654+
5 - [1, 2, 3].into_iter().for_each(|n| { *n; });
3655+
5 + [1, 2, 3].iter().for_each(|n| { *n; });
3656+
╰╴
3657+
help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
3658+
╭╴
3659+
5 │ [1, 2, 3].into_iter().for_each(|n| { *n; }); // Span after line end
3660+
╰╴ ++++++++++++++++++++++
3661+
"#]];
3662+
let renderer = renderer.decor_style(DecorStyle::Unicode);
3663+
assert_data_eq!(renderer.render(input), expected_unicode);
3664+
}
3665+
3666+
#[test]
3667+
fn suggestion_span_source_end() {
3668+
let snippet_source = r#"#![allow(unused)]
3669+
fn main() {
3670+
[1, 2, 3].into_iter().for_each(|n| { *n; });
3671+
}
3672+
"#;
3673+
3674+
let suggestion_source = r#"[1, 2, 3].into_iter().for_each(|n| { *n; });
3675+
"#;
3676+
3677+
let long_title1 ="this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021";
3678+
let long_title2 = "for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>";
3679+
let long_title3 = "or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value";
3680+
3681+
let input = &[
3682+
Level::WARNING
3683+
.primary_title(long_title1)
3684+
.element(
3685+
Snippet::source(snippet_source)
3686+
.path("lint_example.rs")
3687+
.annotation(AnnotationKind::Primary.span(40..49)),
3688+
)
3689+
.element(Level::WARNING.message("this changes meaning in Rust 2021"))
3690+
.element(Level::NOTE.message(long_title2))
3691+
.element(Level::NOTE.message("`#[warn(array_into_iter)]` on by default")),
3692+
Level::HELP
3693+
.secondary_title("use `.iter()` instead of `.into_iter()` to avoid ambiguity")
3694+
.element(
3695+
Snippet::source(suggestion_source)
3696+
.path("lint_example.rs")
3697+
.line_start(3)
3698+
.patch(Patch::new(10..19, "iter")),
3699+
),
3700+
Level::HELP.secondary_title(long_title3).element(
3701+
Snippet::source(suggestion_source)
3702+
.path("lint_example.rs")
3703+
.line_start(3)
3704+
.patch(Patch::new(
3705+
suggestion_source.len()..suggestion_source.len(),
3706+
" // Span after line end",
3707+
)),
3708+
),
3709+
];
3710+
3711+
let expected_ascii = str![[r#"
3712+
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
3713+
--> lint_example.rs:3:11
3714+
|
3715+
3 | [1, 2, 3].into_iter().for_each(|n| { *n; });
3716+
| ^^^^^^^^^
3717+
|
3718+
= warning: this changes meaning in Rust 2021
3719+
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
3720+
= note: `#[warn(array_into_iter)]` on by default
3721+
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
3722+
|
3723+
3 - [1, 2, 3].into_iter().for_each(|n| { *n; });
3724+
3 + [1, 2, 3].iter().for_each(|n| { *n; });
3725+
|
3726+
help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
3727+
|
3728+
3 | [1, 2, 3].into_iter().for_each(|n| { *n; }); // Span after line end
3729+
| ++++++++++++++++++++++
3730+
"#]];
3731+
let renderer = Renderer::plain();
3732+
assert_data_eq!(renderer.render(input), expected_ascii);
3733+
3734+
let expected_unicode = str![[r#"
3735+
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
3736+
╭▸ lint_example.rs:3:11
3737+
3738+
3 │ [1, 2, 3].into_iter().for_each(|n| { *n; });
3739+
│ ━━━━━━━━━
3740+
3741+
├ warning: this changes meaning in Rust 2021
3742+
├ note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
3743+
╰ note: `#[warn(array_into_iter)]` on by default
3744+
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
3745+
╭╴
3746+
3 - [1, 2, 3].into_iter().for_each(|n| { *n; });
3747+
3 + [1, 2, 3].iter().for_each(|n| { *n; });
3748+
╰╴
3749+
help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
3750+
╭╴
3751+
3 │ [1, 2, 3].into_iter().for_each(|n| { *n; }); // Span after line end
3752+
╰╴ ++++++++++++++++++++++
3753+
"#]];
3754+
let renderer = renderer.decor_style(DecorStyle::Unicode);
3755+
assert_data_eq!(renderer.render(input), expected_unicode);
3756+
}
3757+
35803758
#[test]
35813759
fn suggestion_span_one_bigger_than_source() {
35823760
let snippet_source = r#"#![allow(unused)]
@@ -3617,7 +3795,7 @@ fn main() {
36173795
.line_start(3)
36183796
.patch(Patch::new(
36193797
suggestion_source.len() + 1..suggestion_source.len() + 1,
3620-
"IntoIterator::into_iter(",
3798+
" // Span after line end",
36213799
)),
36223800
),
36233801
];
@@ -3639,8 +3817,8 @@ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
36393817
|
36403818
help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
36413819
|
3642-
3 | IntoIterator::into_iter(
3643-
|
3820+
3 | [1, 2, 3].into_iter().for_each(|n| { *n; }); // Span after line end
3821+
| ++++++++++++++++++++++
36443822
"#]];
36453823
let renderer = Renderer::plain();
36463824
assert_data_eq!(renderer.render(input), expected_ascii);
@@ -3662,8 +3840,8 @@ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
36623840
╰╴
36633841
help: or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
36643842
╭╴
3665-
3 │ IntoIterator::into_iter(
3666-
╰╴
3843+
3 │ [1, 2, 3].into_iter().for_each(|n| { *n; }); // Span after line end
3844+
╰╴ ++++++++++++++++++++++
36673845
"#]];
36683846
let renderer = renderer.decor_style(DecorStyle::Unicode);
36693847
assert_data_eq!(renderer.render(input), expected_unicode);
@@ -3709,7 +3887,7 @@ fn main() {
37093887
.line_start(3)
37103888
.patch(Patch::new(
37113889
suggestion_source.len() + 2..suggestion_source.len() + 2,
3712-
"IntoIterator::into_iter(",
3890+
" // Span after line end",
37133891
)),
37143892
),
37153893
];

0 commit comments

Comments
 (0)