Skip to content

Commit 6d35c67

Browse files
committed
Fix convert_iter_for_each_to_for doctest
1 parent e505752 commit 6d35c67

File tree

2 files changed

+56
-15
lines changed

2 files changed

+56
-15
lines changed

crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs

+45-11
Original file line numberDiff line numberDiff line change
@@ -11,37 +11,45 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
1111
// Converts an Iterator::for_each function into a for loop.
1212
//
1313
// ```
14+
// # //- /lib.rs crate:core
15+
// # pub mod iter { pub mod traits { pub mod iterator { pub trait Iterator {} } } }
16+
// # pub struct SomeIter;
17+
// # impl self::iter::traits::iterator::Iterator for SomeIter {}
18+
// # //- /lib.rs crate:main deps:core
19+
// # use core::SomeIter;
1420
// fn main() {
15-
// let vec = vec![(1, 2), (2, 3), (3, 4)];
16-
// x.iter().for_each(|(x, y)| {
21+
// let iter = SomeIter;
22+
// iter.for_each$0(|(x, y)| {
1723
// println!("x: {}, y: {}", x, y);
1824
// });
1925
// }
2026
// ```
2127
// ->
2228
// ```
29+
// # use core::SomeIter;
2330
// fn main() {
24-
// let vec = vec![(1, 2), (2, 3), (3, 4)];
25-
// for (x, y) in x.iter() {
31+
// let iter = SomeIter;
32+
// for (x, y) in iter {
2633
// println!("x: {}, y: {}", x, y);
2734
// }
2835
// }
2936
// ```
37+
3038
pub(crate) fn convert_iter_for_each_to_for(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
3139
let method = ctx.find_node_at_offset::<ast::MethodCallExpr>()?;
32-
let stmt = method.syntax().parent().and_then(ast::ExprStmt::cast);
3340

3441
let closure = match method.arg_list()?.args().next()? {
3542
ast::Expr::ClosureExpr(expr) => expr,
3643
_ => return None,
3744
};
3845

39-
let (method, receiver) = validate_method_call_expr(&ctx.sema, method)?;
46+
let (method, receiver) = validate_method_call_expr(ctx, method)?;
4047

4148
let param_list = closure.param_list()?;
4249
let param = param_list.params().next()?.pat()?;
4350
let body = closure.body()?;
4451

52+
let stmt = method.syntax().parent().and_then(ast::ExprStmt::cast);
4553
let syntax = stmt.as_ref().map_or(method.syntax(), |stmt| stmt.syntax());
4654

4755
acc.add(
@@ -65,13 +73,18 @@ pub(crate) fn convert_iter_for_each_to_for(acc: &mut Assists, ctx: &AssistContex
6573
}
6674

6775
fn validate_method_call_expr(
68-
sema: &hir::Semantics<ide_db::RootDatabase>,
76+
ctx: &AssistContext,
6977
expr: ast::MethodCallExpr,
7078
) -> Option<(ast::Expr, ast::Expr)> {
71-
if expr.name_ref()?.text() != "for_each" {
79+
let name_ref = expr.name_ref()?;
80+
if name_ref.syntax().text_range().intersect(ctx.frange.range).is_none()
81+
|| name_ref.text() != "for_each"
82+
{
7283
return None;
7384
}
7485

86+
let sema = &ctx.sema;
87+
7588
let receiver = expr.receiver()?;
7689
let expr = ast::Expr::MethodCallExpr(expr);
7790

@@ -85,7 +98,7 @@ fn validate_method_call_expr(
8598

8699
#[cfg(test)]
87100
mod tests {
88-
use crate::tests::{check_assist, check_assist_not_applicable};
101+
use crate::tests::{self, check_assist};
89102

90103
use super::*;
91104

@@ -112,6 +125,16 @@ impl Empty {
112125
check_assist(convert_iter_for_each_to_for, before, after);
113126
}
114127

128+
fn check_assist_not_applicable(before: &str) {
129+
let before = &format!(
130+
"//- /main.rs crate:main deps:core,empty_iter{}{}{}",
131+
before,
132+
EMPTY_ITER_FIXTURE,
133+
FamousDefs::FIXTURE,
134+
);
135+
tests::check_assist_not_applicable(convert_iter_for_each_to_for, before);
136+
}
137+
115138
#[test]
116139
fn test_for_each_in_method_stmt() {
117140
check_assist_with_fixtures(
@@ -201,13 +224,24 @@ fn main() {
201224
"#,
202225
)
203226
}
227+
204228
#[test]
205229
fn test_for_each_not_applicable() {
206230
check_assist_not_applicable(
207-
convert_iter_for_each_to_for,
208231
r#"
209232
fn main() {
210-
value.$0for_each(|x| println!("{}", x));
233+
().$0for_each(|x| println!("{}", x));
234+
}"#,
235+
)
236+
}
237+
238+
#[test]
239+
fn test_for_each_not_applicable_invalid_cursor_pos() {
240+
check_assist_not_applicable(
241+
r#"
242+
use empty_iter::*;
243+
fn main() {
244+
Empty.iter().for_each(|(x, y)| $0println!("x: {}, y: {}", x, y));
211245
}"#,
212246
)
213247
}

crates/ide_assists/src/tests/generated.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -210,17 +210,24 @@ fn doctest_convert_iter_for_each_to_for() {
210210
check_doc_test(
211211
"convert_iter_for_each_to_for",
212212
r#####"
213+
//- /lib.rs crate:core
214+
pub mod iter { pub mod traits { pub mod iterator { pub trait Iterator {} } } }
215+
pub struct SomeIter;
216+
impl self::iter::traits::iterator::Iterator for SomeIter {}
217+
//- /lib.rs crate:main deps:core
218+
use core::SomeIter;
213219
fn main() {
214-
let vec = vec![(1, 2), (2, 3), (3, 4)];
215-
x.iter().for_each(|(x, y)| {
220+
let iter = SomeIter;
221+
iter.for_each$0(|(x, y)| {
216222
println!("x: {}, y: {}", x, y);
217223
});
218224
}
219225
"#####,
220226
r#####"
227+
use core::SomeIter;
221228
fn main() {
222-
let vec = vec![(1, 2), (2, 3), (3, 4)];
223-
for (x, y) in x.iter() {
229+
let iter = SomeIter;
230+
for (x, y) in iter {
224231
println!("x: {}, y: {}", x, y);
225232
}
226233
}

0 commit comments

Comments
 (0)