Skip to content

Commit 8ca214f

Browse files
committed
Better inlay hints in 'for' loops
1 parent 03dcf51 commit 8ca214f

File tree

1 file changed

+49
-2
lines changed

1 file changed

+49
-2
lines changed

crates/ide/src/inlay_hints.rs

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ fn get_bind_pat_hints(
189189

190190
let ty = sema.type_of_pat(&pat.clone().into())?;
191191

192-
if should_not_display_type_hint(sema.db, &pat, &ty) {
192+
if should_not_display_type_hint(sema, &pat, &ty) {
193193
return None;
194194
}
195195

@@ -215,10 +215,12 @@ fn pat_is_enum_variant(db: &RootDatabase, bind_pat: &ast::IdentPat, pat_ty: &Typ
215215
}
216216

217217
fn should_not_display_type_hint(
218-
db: &RootDatabase,
218+
sema: &Semantics<RootDatabase>,
219219
bind_pat: &ast::IdentPat,
220220
pat_ty: &Type,
221221
) -> bool {
222+
let db = sema.db;
223+
222224
if pat_ty.is_unknown() {
223225
return true;
224226
}
@@ -249,6 +251,14 @@ fn should_not_display_type_hint(
249251
return it.condition().and_then(|condition| condition.pat()).is_some()
250252
&& pat_is_enum_variant(db, bind_pat, pat_ty);
251253
},
254+
ast::ForExpr(it) => {
255+
// We *should* display hint only if user provided "in {expr}" and we know the type of expr (and it's not unit).
256+
// Type of expr should be iterable.
257+
let type_is_known = |ty: Option<hir::Type>| ty.map(|ty| !ty.is_unit() && !ty.is_unknown()).unwrap_or(false);
258+
let should_display = it.in_token().is_some()
259+
&& it.iterable().map(|expr| type_is_known(sema.type_of_expr(&expr))).unwrap_or(false);
260+
return !should_display;
261+
},
252262
_ => (),
253263
}
254264
}
@@ -924,4 +934,41 @@ fn main() {
924934
"#]],
925935
);
926936
}
937+
938+
#[test]
939+
fn incomplete_for_no_hint() {
940+
check(
941+
r#"
942+
fn main() {
943+
let data = &[1i32, 2, 3];
944+
//^^^^ &[i32; _]
945+
for i
946+
}"#,
947+
);
948+
check(
949+
r#"
950+
fn main() {
951+
let data = &[1i32, 2, 3];
952+
//^^^^ &[i32; _]
953+
for i in
954+
955+
println!("Unit expr");
956+
}"#,
957+
);
958+
}
959+
960+
#[test]
961+
fn complete_for_hint() {
962+
check(
963+
r#"
964+
fn main() {
965+
let data = &[ 1, 2, 3 ];
966+
//^^^^ &[i32; _]
967+
for i in data.into_iter() {
968+
//^ &i32
969+
println!("{}", i);
970+
}
971+
}"#,
972+
);
973+
}
927974
}

0 commit comments

Comments
 (0)