@@ -21,7 +21,7 @@ use hir_def::{
2121 lang_item:: LangItem ,
2222 nameres:: MacroSubNs ,
2323 resolver:: { HasResolver , Resolver , TypeNs , ValueNs , resolver_for_scope} ,
24- type_ref:: { Mutability , TypeRefId } ,
24+ type_ref:: { Mutability , TypeRef , TypeRefId } ,
2525} ;
2626use hir_expand:: {
2727 HirFileId , InFile ,
@@ -267,8 +267,11 @@ impl<'db> SourceAnalyzer<'db> {
267267 db : & ' db dyn HirDatabase ,
268268 ty : & ast:: Type ,
269269 ) -> Option < Type < ' db > > {
270+ let interner = DbInterner :: new_with ( db, None , None ) ;
271+
270272 let type_ref = self . type_id ( ty) ?;
271- let ty = TyLoweringContext :: new (
273+
274+ let mut ty = TyLoweringContext :: new (
272275 db,
273276 & self . resolver ,
274277 self . store ( ) ?,
@@ -279,6 +282,31 @@ impl<'db> SourceAnalyzer<'db> {
279282 LifetimeElisionKind :: Infer ,
280283 )
281284 . lower_ty ( type_ref) ;
285+
286+ // Try and substitute unknown types using InferenceResult
287+ if let Some ( infer) = self . infer ( )
288+ && let Some ( store) = self . store ( )
289+ {
290+ let mut inferred_types = vec ! [ ] ;
291+ TypeRef :: walk ( type_ref, store, & mut |type_ref_id, type_ref| {
292+ if matches ! ( type_ref, TypeRef :: Placeholder ) {
293+ inferred_types. push ( infer. type_of_type_placeholder ( type_ref_id) ) ;
294+ }
295+ } ) ;
296+ let mut inferred_types = inferred_types. into_iter ( ) ;
297+
298+ let substituted_ty = hir_ty:: next_solver:: fold:: fold_tys ( interner, ty, |ty| {
299+ if ty. is_ty_error ( ) { inferred_types. next ( ) . flatten ( ) . unwrap_or ( ty) } else { ty }
300+ } ) ;
301+
302+ // Only used the result if the placeholder and unknown type counts matched
303+ let success =
304+ inferred_types. next ( ) . is_none ( ) && !substituted_ty. references_non_lt_error ( ) ;
305+ if success {
306+ ty = substituted_ty;
307+ }
308+ }
309+
282310 Some ( Type :: new_with_resolver ( db, & self . resolver , ty) )
283311 }
284312
0 commit comments