diff options
Diffstat (limited to 'crates/ide/src')
-rw-r--r-- | crates/ide/src/inlay_hints.rs | 117 |
1 files changed, 81 insertions, 36 deletions
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 | } |