1- use hir:: { known, Adt , AssocItem , Callable , HirDisplay , ModuleDef , Semantics , Type } ;
1+ use assists:: utils:: FamousDefs ;
2+ use hir:: { known, Adt , AssocItem , Callable , HirDisplay , Semantics , Type } ;
23use ide_db:: RootDatabase ;
34use stdx:: to_lower_snake_case;
45use syntax:: {
@@ -194,7 +195,7 @@ fn get_bind_pat_hints(
194195 }
195196
196197 let db = sema. db ;
197- if let Some ( hint) = hint_iterator ( db , config, & ty, pat. clone ( ) ) {
198+ if let Some ( hint) = hint_iterator ( sema , config, & ty, pat. clone ( ) ) {
198199 acc. push ( hint) ;
199200 } else {
200201 acc. push ( InlayHint {
@@ -209,45 +210,44 @@ fn get_bind_pat_hints(
209210
210211/// Checks if the type is an Iterator from std::iter and replaces its hint with an `impl Iterator<Item = Ty>`.
211212fn hint_iterator (
212- db : & RootDatabase ,
213+ sema : & Semantics < RootDatabase > ,
213214 config : & InlayHintsConfig ,
214215 ty : & Type ,
215216 pat : ast:: IdentPat ,
216217) -> Option < InlayHint > {
218+ let db = sema. db ;
217219 let strukt = ty. as_adt ( ) ?;
218220 let krate = strukt. krate ( db) ?;
219- let module = strukt. module ( db) ;
220221 if krate. declaration_name ( db) . as_deref ( ) != Some ( "core" ) {
221222 return None ;
222223 }
223- let module = module
224+ // assert this type comes from `core::iter`
225+ strukt
226+ . module ( db)
224227 . path_to_root ( db)
225228 . into_iter ( )
226229 . rev ( )
227230 . find ( |module| module. name ( db) == Some ( known:: iter) ) ?;
228- let iter_trait = module. scope ( db, None ) . into_iter ( ) . find_map ( |( name, def) | match def {
229- hir:: ScopeDef :: ModuleDef ( ModuleDef :: Trait ( r#trait) ) if name == known:: Iterator => {
230- Some ( r#trait)
231- }
232- _ => None ,
233- } ) ?;
231+ let iter_trait = FamousDefs ( sema, krate) . core_iter_Iterator ( ) ?;
234232 if ty. impls_trait ( db, iter_trait, & [ ] ) {
235233 let assoc_type_item = iter_trait. items ( db) . into_iter ( ) . find_map ( |item| match item {
236234 AssocItem :: TypeAlias ( alias) if alias. name ( db) == known:: Item => Some ( alias) ,
237235 _ => None ,
238236 } ) ?;
239237 if let Some ( ty) = ty. normalize_trait_assoc_type ( db, iter_trait, & [ ] , assoc_type_item) {
238+ const LABEL_START : & str = "impl Iterator<Item = " ;
239+ const LABEL_END : & str = ">" ;
240+
241+ let ty_display = ty. display_truncated (
242+ db,
243+ config
244+ . max_length
245+ . map ( |len| len. saturating_sub ( LABEL_START . len ( ) + LABEL_END . len ( ) ) ) ,
246+ ) ;
240247 return Some ( InlayHint {
241248 range : pat. syntax ( ) . text_range ( ) ,
242249 kind : InlayKind :: TypeHint ,
243- label : format ! (
244- "impl Iterator<Item = {}>" ,
245- ty. display_truncated(
246- db,
247- config. max_length. map( |len| len - 22 /*len of the template string above*/ )
248- )
249- )
250- . into ( ) ,
250+ label : format ! ( "{}{}{}" , LABEL_START , ty_display, LABEL_END ) . into ( ) ,
251251 } ) ;
252252 }
253253 }
@@ -401,6 +401,7 @@ fn get_callable(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<Call
401401
402402#[ cfg( test) ]
403403mod tests {
404+ use assists:: utils:: FamousDefs ;
404405 use expect_test:: { expect, Expect } ;
405406 use test_utils:: extract_annotations;
406407
@@ -1124,15 +1125,26 @@ fn main() {
11241125 chaining_hints : true ,
11251126 max_length : None ,
11261127 } ,
1127- r#"
1128+ & format ! (
1129+ "{}\n {}\n " ,
1130+ r#"
11281131//- /main.rs crate:main deps:std
11291132use std::{Option::{self, Some, None}, iter};
11301133
1134+ struct MyIter;
1135+
1136+ impl iter::Iterator for MyIter {
1137+ type Item = ();
1138+ fn next(&mut self) -> Option<Self::Item> {
1139+ None
1140+ }
1141+ }
1142+
11311143fn main() {
1144+ let _x = MyIter;
1145+ //^^ MyIter
11321146 let _x = iter::repeat(0);
11331147 //^^ impl Iterator<Item = i32>
1134- let _y = iter::Chain(iter::repeat(0), iter::repeat(0));
1135- //^^ impl Iterator<Item = i32>
11361148 fn generic<T: Clone>(t: T) {
11371149 let _x = iter::repeat(t);
11381150 //^^ impl Iterator<Item = T>
@@ -1141,42 +1153,9 @@ fn main() {
11411153
11421154//- /std.rs crate:std deps:core
11431155use core::*;
1144-
1145- //- /core.rs crate:core
1146- pub enum Option<T> {
1147- Some(T),
1148- None
1149- }
1150-
1151- pub mod iter {
1152- pub use self::traits::iterator::Iterator;
1153- pub mod traits { pub mod iterator {
1154- pub trait Iterator {
1155- type Item;
1156- }
1157- } }
1158-
1159- pub use self::sources::*;
1160- pub mod sources {
1161- use super::Iterator;
1162- pub struct Repeat<T: Clone>(pub T);
1163-
1164- pub fn repeat<T: Clone>(t: T) -> Repeat<T> {
1165- Repeat(f)
1166- }
1167-
1168- impl<T: Clone> Iterator for Repeat<T> {
1169- type Item = T;
1170- }
1171-
1172- pub struct Chain<A, B>(pub A, pub B);
1173-
1174- impl<T, A, B> Iterator for Chain<A, B> where A: Iterator<Item = T>, B: Iterator<Item = T> {
1175- type Item = T;
1176- }
1177- }
1178- }
11791156"# ,
1157+ FamousDefs :: FIXTURE
1158+ ) ,
11801159 ) ;
11811160 }
11821161}
0 commit comments