diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/assists/src/utils.rs | 41 | ||||
-rw-r--r-- | crates/ide/src/inlay_hints.rs | 117 |
2 files changed, 115 insertions, 43 deletions
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index b341453d4..92b3c3b00 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs | |||
@@ -281,21 +281,34 @@ impl FamousDefs<'_, '_> { | |||
281 | pub const FIXTURE: &'static str = r#"//- /libcore.rs crate:core | 281 | pub const FIXTURE: &'static str = r#"//- /libcore.rs crate:core |
282 | pub mod convert { | 282 | pub mod convert { |
283 | pub trait From<T> { | 283 | pub trait From<T> { |
284 | fn from(T) -> Self; | 284 | fn from(t: T) -> Self; |
285 | } | 285 | } |
286 | } | 286 | } |
287 | 287 | ||
288 | pub mod iter { | 288 | pub mod iter { |
289 | pub use self::traits::{collect::IntoIterator, iterator::Iterator}; | 289 | pub use self::traits::{collect::IntoIterator, iterator::Iterator}; |
290 | mod traits { | 290 | mod traits { |
291 | mod iterator { | 291 | pub(crate) mod iterator { |
292 | use crate::option::Option; | 292 | use crate::option::Option; |
293 | pub trait Iterator { | 293 | pub trait Iterator { |
294 | type Item; | 294 | type Item; |
295 | fn next(&mut self) -> Option<Self::Item>; | 295 | fn next(&mut self) -> Option<Self::Item>; |
296 | fn by_ref(&mut self) -> &mut Self { | ||
297 | self | ||
298 | } | ||
299 | fn take(self, n: usize) -> crate::iter::Take<Self> { | ||
300 | crate::iter::Take { inner: self } | ||
301 | } | ||
302 | } | ||
303 | |||
304 | impl<I: Iterator> Iterator for &mut I { | ||
305 | type Item = I::Item; | ||
306 | fn next(&mut self) -> Option<I::Item> { | ||
307 | (**self).next() | ||
308 | } | ||
296 | } | 309 | } |
297 | } | 310 | } |
298 | mod collect { | 311 | pub(crate) mod collect { |
299 | pub trait IntoIterator { | 312 | pub trait IntoIterator { |
300 | type Item; | 313 | type Item; |
301 | } | 314 | } |
@@ -303,21 +316,35 @@ pub mod iter { | |||
303 | } | 316 | } |
304 | 317 | ||
305 | pub use self::sources::*; | 318 | pub use self::sources::*; |
306 | mod sources { | 319 | pub(crate) mod sources { |
307 | use super::Iterator; | 320 | use super::Iterator; |
321 | use crate::option::Option::{self, *}; | ||
308 | pub struct Repeat<A> { | 322 | pub struct Repeat<A> { |
309 | element: A, | 323 | element: A, |
310 | } | 324 | } |
311 | 325 | ||
312 | pub fn repeat<T: Clone>(elt: T) -> Repeat<T> { | 326 | pub fn repeat<T>(elt: T) -> Repeat<T> { |
313 | Repeat { element: elt } | 327 | Repeat { element: elt } |
314 | } | 328 | } |
315 | 329 | ||
316 | impl<A: Clone> Iterator for Repeat<A> { | 330 | impl<A> Iterator for Repeat<A> { |
317 | type Item = A; | 331 | type Item = A; |
318 | 332 | ||
319 | fn next(&mut self) -> Option<A> { | 333 | fn next(&mut self) -> Option<A> { |
320 | Some(self.element.clone()) | 334 | None |
335 | } | ||
336 | } | ||
337 | } | ||
338 | |||
339 | pub use self::adapters::*; | ||
340 | pub(crate) mod adapters { | ||
341 | use super::Iterator; | ||
342 | use crate::option::Option::{self, *}; | ||
343 | pub struct Take<I> { pub(crate) inner: I } | ||
344 | impl<I> Iterator for Take<I> where I: Iterator { | ||
345 | type Item = <I as Iterator>::Item; | ||
346 | fn next(&mut self) -> Option<<I as Iterator>::Item> { | ||
347 | None | ||
321 | } | 348 | } |
322 | } | 349 | } |
323 | } | 350 | } |
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 31a6a1be8..279d02541 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs | |||
@@ -126,11 +126,12 @@ fn get_chaining_hints( | |||
126 | } | 126 | } |
127 | } | 127 | } |
128 | } | 128 | } |
129 | let label = ty.display_truncated(sema.db, config.max_length).to_string(); | ||
130 | acc.push(InlayHint { | 129 | acc.push(InlayHint { |
131 | range: expr.syntax().text_range(), | 130 | range: expr.syntax().text_range(), |
132 | kind: InlayKind::ChainingHint, | 131 | kind: InlayKind::ChainingHint, |
133 | label: label.into(), | 132 | label: hint_iterator(sema, config, &ty).unwrap_or_else(|| { |
133 | ty.display_truncated(sema.db, config.max_length).to_string().into() | ||
134 | }), | ||
134 | }); | 135 | }); |
135 | } | 136 | } |
136 | Some(()) | 137 | Some(()) |
@@ -193,17 +194,12 @@ fn get_bind_pat_hints( | |||
193 | if should_not_display_type_hint(sema, &pat, &ty) { | 194 | if should_not_display_type_hint(sema, &pat, &ty) { |
194 | return None; | 195 | return None; |
195 | } | 196 | } |
196 | 197 | acc.push(InlayHint { | |
197 | let db = sema.db; | 198 | range: pat.syntax().text_range(), |
198 | if let Some(hint) = hint_iterator(sema, config, &ty, pat.clone()) { | 199 | kind: InlayKind::TypeHint, |
199 | acc.push(hint); | 200 | label: hint_iterator(sema, config, &ty) |
200 | } else { | 201 | .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string().into()), |
201 | acc.push(InlayHint { | 202 | }); |
202 | range: pat.syntax().text_range(), | ||
203 | kind: InlayKind::TypeHint, | ||
204 | label: ty.display_truncated(db, config.max_length).to_string().into(), | ||
205 | }); | ||
206 | } | ||
207 | 203 | ||
208 | Some(()) | 204 | Some(()) |
209 | } | 205 | } |
@@ -213,8 +209,7 @@ fn hint_iterator( | |||
213 | sema: &Semantics<RootDatabase>, | 209 | sema: &Semantics<RootDatabase>, |
214 | config: &InlayHintsConfig, | 210 | config: &InlayHintsConfig, |
215 | ty: &Type, | 211 | ty: &Type, |
216 | pat: ast::IdentPat, | 212 | ) -> Option<SmolStr> { |
217 | ) -> Option<InlayHint> { | ||
218 | let db = sema.db; | 213 | let db = sema.db; |
219 | let strukt = ty.as_adt()?; | 214 | let strukt = ty.as_adt()?; |
220 | let krate = strukt.krate(db)?; | 215 | let krate = strukt.krate(db)?; |
@@ -244,11 +239,7 @@ fn hint_iterator( | |||
244 | .max_length | 239 | .max_length |
245 | .map(|len| len.saturating_sub(LABEL_START.len() + LABEL_END.len())), | 240 | .map(|len| len.saturating_sub(LABEL_START.len() + LABEL_END.len())), |
246 | ); | 241 | ); |
247 | return Some(InlayHint { | 242 | return Some(format!("{}{}{}", LABEL_START, ty_display, LABEL_END).into()); |
248 | range: pat.syntax().text_range(), | ||
249 | kind: InlayKind::TypeHint, | ||
250 | label: format!("{}{}{}", LABEL_START, ty_display, LABEL_END).into(), | ||
251 | }); | ||
252 | } | 243 | } |
253 | } | 244 | } |
254 | 245 | ||
@@ -412,7 +403,8 @@ mod tests { | |||
412 | } | 403 | } |
413 | 404 | ||
414 | fn check_with_config(config: InlayHintsConfig, ra_fixture: &str) { | 405 | fn check_with_config(config: InlayHintsConfig, ra_fixture: &str) { |
415 | let ra_fixture = format!("{}\n{}", ra_fixture, FamousDefs::FIXTURE); | 406 | let ra_fixture = |
407 | format!("//- /main.rs crate:main deps:core\n{}\n{}", ra_fixture, FamousDefs::FIXTURE); | ||
416 | let (analysis, file_id) = fixture::file(&ra_fixture); | 408 | let (analysis, file_id) = fixture::file(&ra_fixture); |
417 | let expected = extract_annotations(&*analysis.file_text(file_id).unwrap()); | 409 | let expected = extract_annotations(&*analysis.file_text(file_id).unwrap()); |
418 | let inlay_hints = analysis.inlay_hints(file_id, &config).unwrap(); | 410 | let inlay_hints = analysis.inlay_hints(file_id, &config).unwrap(); |
@@ -422,7 +414,9 @@ mod tests { | |||
422 | } | 414 | } |
423 | 415 | ||
424 | fn check_expect(config: InlayHintsConfig, ra_fixture: &str, expect: Expect) { | 416 | fn check_expect(config: InlayHintsConfig, ra_fixture: &str, expect: Expect) { |
425 | let (analysis, file_id) = fixture::file(ra_fixture); | 417 | let ra_fixture = |
418 | format!("//- /main.rs crate:main deps:core\n{}\n{}", ra_fixture, FamousDefs::FIXTURE); | ||
419 | let (analysis, file_id) = fixture::file(&ra_fixture); | ||
426 | let inlay_hints = analysis.inlay_hints(file_id, &config).unwrap(); | 420 | let inlay_hints = analysis.inlay_hints(file_id, &config).unwrap(); |
427 | expect.assert_debug_eq(&inlay_hints) | 421 | expect.assert_debug_eq(&inlay_hints) |
428 | } | 422 | } |
@@ -854,12 +848,12 @@ fn main() { | |||
854 | expect![[r#" | 848 | expect![[r#" |
855 | [ | 849 | [ |
856 | InlayHint { | 850 | InlayHint { |
857 | range: 147..172, | 851 | range: 148..173, |
858 | kind: ChainingHint, | 852 | kind: ChainingHint, |
859 | label: "B", | 853 | label: "B", |
860 | }, | 854 | }, |
861 | InlayHint { | 855 | InlayHint { |
862 | range: 147..154, | 856 | range: 148..155, |
863 | kind: ChainingHint, | 857 | kind: ChainingHint, |
864 | label: "A", | 858 | label: "A", |
865 | }, | 859 | }, |
@@ -920,12 +914,12 @@ fn main() { | |||
920 | expect![[r#" | 914 | expect![[r#" |
921 | [ | 915 | [ |
922 | InlayHint { | 916 | InlayHint { |
923 | range: 143..190, | 917 | range: 144..191, |
924 | kind: ChainingHint, | 918 | kind: ChainingHint, |
925 | label: "C", | 919 | label: "C", |
926 | }, | 920 | }, |
927 | InlayHint { | 921 | InlayHint { |
928 | range: 143..179, | 922 | range: 144..180, |
929 | kind: ChainingHint, | 923 | kind: ChainingHint, |
930 | label: "B", | 924 | label: "B", |
931 | }, | 925 | }, |
@@ -965,12 +959,12 @@ fn main() { | |||
965 | expect![[r#" | 959 | expect![[r#" |
966 | [ | 960 | [ |
967 | InlayHint { | 961 | InlayHint { |
968 | range: 246..283, | 962 | range: 247..284, |
969 | kind: ChainingHint, | 963 | kind: ChainingHint, |
970 | label: "B<X<i32, bool>>", | 964 | label: "B<X<i32, bool>>", |
971 | }, | 965 | }, |
972 | InlayHint { | 966 | InlayHint { |
973 | range: 246..265, | 967 | range: 247..266, |
974 | kind: ChainingHint, | 968 | kind: ChainingHint, |
975 | label: "A<X<i32, bool>>", | 969 | label: "A<X<i32, bool>>", |
976 | }, | 970 | }, |
@@ -991,7 +985,6 @@ fn main() { | |||
991 | ); | 985 | ); |
992 | check( | 986 | check( |
993 | r#" | 987 | r#" |
994 | //- /main.rs crate:main deps:core | ||
995 | pub struct Vec<T> {} | 988 | pub struct Vec<T> {} |
996 | 989 | ||
997 | impl<T> Vec<T> { | 990 | impl<T> Vec<T> { |
@@ -1031,7 +1024,6 @@ mod collections { | |||
1031 | fn complete_for_hint() { | 1024 | fn complete_for_hint() { |
1032 | check( | 1025 | check( |
1033 | r#" | 1026 | r#" |
1034 | //- /main.rs crate:main deps:core | ||
1035 | pub struct Vec<T> {} | 1027 | pub struct Vec<T> {} |
1036 | 1028 | ||
1037 | impl<T> Vec<T> { | 1029 | impl<T> Vec<T> { |
@@ -1078,7 +1070,6 @@ mod collections { | |||
1078 | max_length: None, | 1070 | max_length: None, |
1079 | }, | 1071 | }, |
1080 | r#" | 1072 | r#" |
1081 | //- /main.rs crate:main | ||
1082 | pub struct Vec<T> {} | 1073 | pub struct Vec<T> {} |
1083 | 1074 | ||
1084 | impl<T> Vec<T> { | 1075 | impl<T> Vec<T> { |
@@ -1108,12 +1099,11 @@ fn main() { | |||
1108 | InlayHintsConfig { | 1099 | InlayHintsConfig { |
1109 | parameter_hints: false, | 1100 | parameter_hints: false, |
1110 | type_hints: true, | 1101 | type_hints: true, |
1111 | chaining_hints: true, | 1102 | chaining_hints: false, |
1112 | max_length: None, | 1103 | max_length: None, |
1113 | }, | 1104 | }, |
1114 | r#" | 1105 | r#" |
1115 | //- /main.rs crate:main deps:std | 1106 | use core::iter; |
1116 | use std::iter; | ||
1117 | 1107 | ||
1118 | struct MyIter; | 1108 | struct MyIter; |
1119 | 1109 | ||
@@ -1132,12 +1122,67 @@ fn main() { | |||
1132 | fn generic<T: Clone>(t: T) { | 1122 | fn generic<T: Clone>(t: T) { |
1133 | let _x = iter::repeat(t); | 1123 | let _x = iter::repeat(t); |
1134 | //^^ impl Iterator<Item = T> | 1124 | //^^ impl Iterator<Item = T> |
1125 | let _chained = iter::repeat(t).take(10); | ||
1126 | //^^^^^^^^ impl Iterator<Item = T> | ||
1127 | } | ||
1128 | } | ||
1129 | "#, | ||
1130 | ); | ||
1131 | } | ||
1132 | |||
1133 | #[test] | ||
1134 | fn shorten_iterator_chaining_hints() { | ||
1135 | check_expect( | ||
1136 | InlayHintsConfig { | ||
1137 | parameter_hints: false, | ||
1138 | type_hints: false, | ||
1139 | chaining_hints: true, | ||
1140 | max_length: None, | ||
1141 | }, | ||
1142 | r#" | ||
1143 | use core::iter; | ||
1144 | |||
1145 | struct MyIter; | ||
1146 | |||
1147 | impl Iterator for MyIter { | ||
1148 | type Item = (); | ||
1149 | fn next(&mut self) -> Option<Self::Item> { | ||
1150 | None | ||
1135 | } | 1151 | } |
1136 | } | 1152 | } |
1137 | 1153 | ||
1138 | //- /std.rs crate:std deps:core | 1154 | fn main() { |
1139 | use core::*; | 1155 | let _x = MyIter.by_ref() |
1156 | .take(5) | ||
1157 | .by_ref() | ||
1158 | .take(5) | ||
1159 | .by_ref(); | ||
1160 | } | ||
1140 | "#, | 1161 | "#, |
1162 | expect![[r#" | ||
1163 | [ | ||
1164 | InlayHint { | ||
1165 | range: 175..242, | ||
1166 | kind: ChainingHint, | ||
1167 | label: "impl Iterator<Item = ()>", | ||
1168 | }, | ||
1169 | InlayHint { | ||
1170 | range: 175..225, | ||
1171 | kind: ChainingHint, | ||
1172 | label: "&mut Take<&mut MyIter>", | ||
1173 | }, | ||
1174 | InlayHint { | ||
1175 | range: 175..207, | ||
1176 | kind: ChainingHint, | ||
1177 | label: "impl Iterator<Item = ()>", | ||
1178 | }, | ||
1179 | InlayHint { | ||
1180 | range: 175..190, | ||
1181 | kind: ChainingHint, | ||
1182 | label: "&mut MyIter", | ||
1183 | }, | ||
1184 | ] | ||
1185 | "#]], | ||
1141 | ); | 1186 | ); |
1142 | } | 1187 | } |
1143 | } | 1188 | } |