Skip to content

Commit e64c553

Browse files
committed
fix: single_range_in_vec_init for explicit Range
1 parent 8ed05ab commit e64c553

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

clippy_lints/src/single_range_in_vec_init.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
22
use clippy_utils::higher::VecArgs;
33
use clippy_utils::macros::root_macro_call_first_node;
4-
use clippy_utils::source::SpanRangeExt;
4+
use clippy_utils::source::{SpanRangeExt, snippet_with_context};
55
use clippy_utils::ty::implements_trait;
66
use clippy_utils::{is_no_std_crate, sym};
77
use rustc_ast::{LitIntType, LitKind, UintTy};
@@ -91,14 +91,17 @@ impl LateLintPass<'_> for SingleRangeInVecInit {
9191
};
9292

9393
if cx.tcx.qpath_is_lang_item(qpath, LangItem::Range)
94+
&& !start.expr.span.eq_ctxt(inner_expr.span)
9495
&& let ty = cx.typeck_results().expr_ty(start.expr)
9596
&& let Some(snippet) = span.get_source_text(cx)
9697
// `is_from_proc_macro` will skip any `vec![]`. Let's not!
9798
&& snippet.starts_with(suggested_type.starts_with())
9899
&& snippet.ends_with(suggested_type.ends_with())
99-
&& let Some(start_snippet) = start.span.get_source_text(cx)
100-
&& let Some(end_snippet) = end.span.get_source_text(cx)
101100
{
101+
let mut applicability = Applicability::MaybeIncorrect;
102+
let (start_snippet, _) = snippet_with_context(cx, start.expr.span, span.ctxt(), "..", &mut applicability);
103+
let (end_snippet, _) = snippet_with_context(cx, end.expr.span, span.ctxt(), "..", &mut applicability);
104+
102105
let should_emit_every_value = if let Some(step_def_id) = cx.tcx.get_diagnostic_item(sym::range_step)
103106
&& implements_trait(cx, ty, step_def_id, &[])
104107
{

tests/ui/single_range_in_vec_init.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,20 @@ fn main() {
6666
vec![0..200];
6767
}
6868
}
69+
70+
fn issue16042() {
71+
use std::ops::Range;
72+
73+
let input = vec![Range { start: 0, end: 5 }];
74+
}
75+
76+
fn issue16044() {
77+
macro_rules! as_i32 {
78+
($x:expr) => {
79+
$x as i32
80+
};
81+
}
82+
83+
let input = vec![0..as_i32!(10)];
84+
//~^ single_range_in_vec_init
85+
}

tests/ui/single_range_in_vec_init.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,5 +160,17 @@ LL - vec![0..200isize];
160160
LL + (0..200isize).collect::<std::vec::Vec<isize>>();
161161
|
162162

163-
error: aborting due to 10 previous errors
163+
error: a `Vec` of `Range` that is only one element
164+
--> tests/ui/single_range_in_vec_init.rs:83:17
165+
|
166+
LL | let input = vec![0..as_i32!(10)];
167+
| ^^^^^^^^^^^^^^^^^^^^
168+
|
169+
help: if you wanted a `Vec` that contains the entire range, try
170+
|
171+
LL - let input = vec![0..as_i32!(10)];
172+
LL + let input = (0..as_i32!(10)).collect::<std::vec::Vec<i32>>();
173+
|
174+
175+
error: aborting due to 11 previous errors
164176

0 commit comments

Comments
 (0)