diff options
Diffstat (limited to 'crates/ide')
-rw-r--r-- | crates/ide/src/completion/complete_postfix/format_like.rs | 2 | ||||
-rw-r--r-- | crates/ide/src/completion/complete_unqualified_path.rs | 20 | ||||
-rw-r--r-- | crates/ide/src/completion/completion_context.rs | 5 | ||||
-rw-r--r-- | crates/ide/src/inlay_hints.rs | 132 |
4 files changed, 141 insertions, 18 deletions
diff --git a/crates/ide/src/completion/complete_postfix/format_like.rs b/crates/ide/src/completion/complete_postfix/format_like.rs index 0287fc803..81c33bf3a 100644 --- a/crates/ide/src/completion/complete_postfix/format_like.rs +++ b/crates/ide/src/completion/complete_postfix/format_like.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | // Feature: Postfix completion for `format`-like strings. | 1 | // Feature: Format String Completion. |
2 | // | 2 | // |
3 | // `"Result {result} is {2 + 2}"` is expanded to the `"Result {} is {}", result, 2 + 2`. | 3 | // `"Result {result} is {2 + 2}"` is expanded to the `"Result {} is {}", result, 2 + 2`. |
4 | // | 4 | // |
diff --git a/crates/ide/src/completion/complete_unqualified_path.rs b/crates/ide/src/completion/complete_unqualified_path.rs index 2010d9a2f..8b6757195 100644 --- a/crates/ide/src/completion/complete_unqualified_path.rs +++ b/crates/ide/src/completion/complete_unqualified_path.rs | |||
@@ -267,6 +267,26 @@ fn quux() { <|> } | |||
267 | ); | 267 | ); |
268 | } | 268 | } |
269 | 269 | ||
270 | /// Regression test for issue #6091. | ||
271 | #[test] | ||
272 | fn correctly_completes_module_items_prefixed_with_underscore() { | ||
273 | check_edit( | ||
274 | "_alpha", | ||
275 | r#" | ||
276 | fn main() { | ||
277 | _<|> | ||
278 | } | ||
279 | fn _alpha() {} | ||
280 | "#, | ||
281 | r#" | ||
282 | fn main() { | ||
283 | _alpha()$0 | ||
284 | } | ||
285 | fn _alpha() {} | ||
286 | "#, | ||
287 | ) | ||
288 | } | ||
289 | |||
270 | #[test] | 290 | #[test] |
271 | fn completes_extern_prelude() { | 291 | fn completes_extern_prelude() { |
272 | check( | 292 | check( |
diff --git a/crates/ide/src/completion/completion_context.rs b/crates/ide/src/completion/completion_context.rs index 101be8eb5..8dea8a4bf 100644 --- a/crates/ide/src/completion/completion_context.rs +++ b/crates/ide/src/completion/completion_context.rs | |||
@@ -221,10 +221,11 @@ impl<'a> CompletionContext<'a> { | |||
221 | Some(ctx) | 221 | Some(ctx) |
222 | } | 222 | } |
223 | 223 | ||
224 | // The range of the identifier that is being completed. | 224 | /// The range of the identifier that is being completed. |
225 | pub(crate) fn source_range(&self) -> TextRange { | 225 | pub(crate) fn source_range(&self) -> TextRange { |
226 | // check kind of macro-expanded token, but use range of original token | 226 | // check kind of macro-expanded token, but use range of original token |
227 | if self.token.kind() == IDENT || self.token.kind().is_keyword() { | 227 | let kind = self.token.kind(); |
228 | if kind == IDENT || kind == UNDERSCORE || kind.is_keyword() { | ||
228 | mark::hit!(completes_if_prefix_is_keyword); | 229 | mark::hit!(completes_if_prefix_is_keyword); |
229 | self.original_token.text_range() | 230 | self.original_token.text_range() |
230 | } else { | 231 | } else { |
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 0afe5f8fd..1d7e8de56 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,15 @@ 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 | return it.in_token().is_none() || | ||
258 | it.iterable() | ||
259 | .and_then(|iterable_expr|sema.type_of_expr(&iterable_expr)) | ||
260 | .map(|iterable_ty| iterable_ty.is_unknown() || iterable_ty.is_unit()) | ||
261 | .unwrap_or(true) | ||
262 | }, | ||
252 | _ => (), | 263 | _ => (), |
253 | } | 264 | } |
254 | } | 265 | } |
@@ -496,19 +507,6 @@ fn main() { | |||
496 | } | 507 | } |
497 | 508 | ||
498 | #[test] | 509 | #[test] |
499 | fn for_expression() { | ||
500 | check( | ||
501 | r#" | ||
502 | fn main() { | ||
503 | let mut start = 0; | ||
504 | //^^^^^^^^^ i32 | ||
505 | for increment in 0..2 { start += increment; } | ||
506 | //^^^^^^^^^ i32 | ||
507 | }"#, | ||
508 | ); | ||
509 | } | ||
510 | |||
511 | #[test] | ||
512 | fn if_expr() { | 510 | fn if_expr() { |
513 | check( | 511 | check( |
514 | r#" | 512 | r#" |
@@ -924,4 +922,108 @@ fn main() { | |||
924 | "#]], | 922 | "#]], |
925 | ); | 923 | ); |
926 | } | 924 | } |
925 | |||
926 | #[test] | ||
927 | fn incomplete_for_no_hint() { | ||
928 | check( | ||
929 | r#" | ||
930 | fn main() { | ||
931 | let data = &[1i32, 2, 3]; | ||
932 | //^^^^ &[i32; _] | ||
933 | for i | ||
934 | }"#, | ||
935 | ); | ||
936 | check( | ||
937 | r#" | ||
938 | //- /main.rs crate:main deps:core | ||
939 | pub struct Vec<T> {} | ||
940 | |||
941 | impl<T> Vec<T> { | ||
942 | pub fn new() -> Self { Vec {} } | ||
943 | pub fn push(&mut self, t: T) {} | ||
944 | } | ||
945 | |||
946 | impl<T> IntoIterator for Vec<T> { | ||
947 | type Item=T; | ||
948 | } | ||
949 | |||
950 | fn main() { | ||
951 | let mut data = Vec::new(); | ||
952 | //^^^^^^^^ Vec<&str> | ||
953 | data.push("foo"); | ||
954 | for i in | ||
955 | |||
956 | println!("Unit expr"); | ||
957 | } | ||
958 | |||
959 | //- /core.rs crate:core | ||
960 | #[prelude_import] use iter::*; | ||
961 | mod iter { | ||
962 | trait IntoIterator { | ||
963 | type Item; | ||
964 | } | ||
965 | } | ||
966 | //- /alloc.rs crate:alloc deps:core | ||
967 | mod collections { | ||
968 | struct Vec<T> {} | ||
969 | impl<T> Vec<T> { | ||
970 | fn new() -> Self { Vec {} } | ||
971 | fn push(&mut self, t: T) { } | ||
972 | } | ||
973 | impl<T> IntoIterator for Vec<T> { | ||
974 | type Item=T; | ||
975 | } | ||
976 | } | ||
977 | "#, | ||
978 | ); | ||
979 | } | ||
980 | |||
981 | #[test] | ||
982 | fn complete_for_hint() { | ||
983 | check( | ||
984 | r#" | ||
985 | //- /main.rs crate:main deps:core | ||
986 | pub struct Vec<T> {} | ||
987 | |||
988 | impl<T> Vec<T> { | ||
989 | pub fn new() -> Self { Vec {} } | ||
990 | pub fn push(&mut self, t: T) {} | ||
991 | } | ||
992 | |||
993 | impl<T> IntoIterator for Vec<T> { | ||
994 | type Item=T; | ||
995 | } | ||
996 | |||
997 | fn main() { | ||
998 | let mut data = Vec::new(); | ||
999 | //^^^^^^^^ Vec<&str> | ||
1000 | data.push("foo"); | ||
1001 | for i in data { | ||
1002 | //^ &str | ||
1003 | let z = i; | ||
1004 | //^ &str | ||
1005 | } | ||
1006 | } | ||
1007 | |||
1008 | //- /core.rs crate:core | ||
1009 | #[prelude_import] use iter::*; | ||
1010 | mod iter { | ||
1011 | trait IntoIterator { | ||
1012 | type Item; | ||
1013 | } | ||
1014 | } | ||
1015 | //- /alloc.rs crate:alloc deps:core | ||
1016 | mod collections { | ||
1017 | struct Vec<T> {} | ||
1018 | impl<T> Vec<T> { | ||
1019 | fn new() -> Self { Vec {} } | ||
1020 | fn push(&mut self, t: T) { } | ||
1021 | } | ||
1022 | impl<T> IntoIterator for Vec<T> { | ||
1023 | type Item=T; | ||
1024 | } | ||
1025 | } | ||
1026 | "#, | ||
1027 | ); | ||
1028 | } | ||
927 | } | 1029 | } |