aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2020-10-07 10:30:42 +0100
committerLukas Wirth <[email protected]>2020-10-07 10:30:42 +0100
commit209e9b9926d27ac71bc054bfdd48888e5d7d6d1a (patch)
treee7d872d62a03021f29ce4cf92e5382bec7532fe8
parentc133651e0a613d4833bba1c1f229222d060e2ba8 (diff)
Shorten iterator chain hints
-rw-r--r--crates/assists/src/utils.rs41
-rw-r--r--crates/ide/src/inlay_hints.rs117
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
282pub mod convert { 282pub 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
288pub mod iter { 288pub 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
995pub struct Vec<T> {} 988pub struct Vec<T> {}
996 989
997impl<T> Vec<T> { 990impl<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
1035pub struct Vec<T> {} 1027pub struct Vec<T> {}
1036 1028
1037impl<T> Vec<T> { 1029impl<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
1082pub struct Vec<T> {} 1073pub struct Vec<T> {}
1083 1074
1084impl<T> Vec<T> { 1075impl<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 1106use core::iter;
1116use std::iter;
1117 1107
1118struct MyIter; 1108struct 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#"
1143use core::iter;
1144
1145struct MyIter;
1146
1147impl 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 1154fn main() {
1139use 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}