diff options
author | Igor Aleksanov <[email protected]> | 2020-09-13 18:24:04 +0100 |
---|---|---|
committer | Igor Aleksanov <[email protected]> | 2020-10-03 06:30:25 +0100 |
commit | 8ca214fbfbd2058140764bf12005a9281a121601 (patch) | |
tree | 4da7bda151a3c88013140b1942a22f892cc7bb21 | |
parent | 03dcf5111ad23700335d25ef02749666bbd08cca (diff) |
Better inlay hints in 'for' loops
-rw-r--r-- | crates/ide/src/inlay_hints.rs | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 0afe5f8fd..60dc74d41 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs | |||
@@ -189,7 +189,7 @@ fn get_bind_pat_hints( | |||
189 | 189 | ||
190 | let ty = sema.type_of_pat(&pat.clone().into())?; | 190 | let ty = sema.type_of_pat(&pat.clone().into())?; |
191 | 191 | ||
192 | if should_not_display_type_hint(sema.db, &pat, &ty) { | 192 | if should_not_display_type_hint(sema, &pat, &ty) { |
193 | return None; | 193 | return None; |
194 | } | 194 | } |
195 | 195 | ||
@@ -215,10 +215,12 @@ fn pat_is_enum_variant(db: &RootDatabase, bind_pat: &ast::IdentPat, pat_ty: &Typ | |||
215 | } | 215 | } |
216 | 216 | ||
217 | fn should_not_display_type_hint( | 217 | fn should_not_display_type_hint( |
218 | db: &RootDatabase, | 218 | sema: &Semantics<RootDatabase>, |
219 | bind_pat: &ast::IdentPat, | 219 | bind_pat: &ast::IdentPat, |
220 | pat_ty: &Type, | 220 | pat_ty: &Type, |
221 | ) -> bool { | 221 | ) -> bool { |
222 | let db = sema.db; | ||
223 | |||
222 | if pat_ty.is_unknown() { | 224 | if pat_ty.is_unknown() { |
223 | return true; | 225 | return true; |
224 | } | 226 | } |
@@ -249,6 +251,14 @@ fn should_not_display_type_hint( | |||
249 | return it.condition().and_then(|condition| condition.pat()).is_some() | 251 | return it.condition().and_then(|condition| condition.pat()).is_some() |
250 | && pat_is_enum_variant(db, bind_pat, pat_ty); | 252 | && pat_is_enum_variant(db, bind_pat, pat_ty); |
251 | }, | 253 | }, |
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 | }, | ||
252 | _ => (), | 262 | _ => (), |
253 | } | 263 | } |
254 | } | 264 | } |
@@ -924,4 +934,41 @@ fn main() { | |||
924 | "#]], | 934 | "#]], |
925 | ); | 935 | ); |
926 | } | 936 | } |
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 | } | ||
927 | } | 974 | } |