@@ -41,7 +41,7 @@ use hir_def::{
4141 layout:: Integer ,
4242 resolver:: { HasResolver , ResolveValueResult , Resolver , TypeNs , ValueNs } ,
4343 signatures:: { ConstSignature , StaticSignature } ,
44- type_ref:: { ConstRef , LifetimeRefId , TypeRefId } ,
44+ type_ref:: { ConstRef , LifetimeRefId , TypeRef , TypeRefId } ,
4545} ;
4646use hir_expand:: { mod_path:: ModPath , name:: Name } ;
4747use indexmap:: IndexSet ;
@@ -60,6 +60,7 @@ use triomphe::Arc;
6060
6161use crate :: {
6262 ImplTraitId , IncorrectGenericsLenKind , PathLoweringDiagnostic , TargetFeatures ,
63+ collect_type_inference_vars,
6364 db:: { HirDatabase , InternedClosureId , InternedOpaqueTyId } ,
6465 infer:: {
6566 coerce:: { CoerceMany , DynamicCoerceMany } ,
@@ -497,6 +498,7 @@ pub struct InferenceResult<'db> {
497498 /// unresolved or missing subpatterns or subpatterns of mismatched types.
498499 pub ( crate ) type_of_pat : ArenaMap < PatId , Ty < ' db > > ,
499500 pub ( crate ) type_of_binding : ArenaMap < BindingId , Ty < ' db > > ,
501+ pub ( crate ) type_of_type_placeholder : ArenaMap < TypeRefId , Ty < ' db > > ,
500502 pub ( crate ) type_of_opaque : FxHashMap < InternedOpaqueTyId , Ty < ' db > > ,
501503 pub ( crate ) type_mismatches : FxHashMap < ExprOrPatId , TypeMismatch < ' db > > ,
502504 /// Whether there are any type-mismatching errors in the result.
@@ -542,6 +544,7 @@ impl<'db> InferenceResult<'db> {
542544 type_of_expr : Default :: default ( ) ,
543545 type_of_pat : Default :: default ( ) ,
544546 type_of_binding : Default :: default ( ) ,
547+ type_of_type_placeholder : Default :: default ( ) ,
545548 type_of_opaque : Default :: default ( ) ,
546549 type_mismatches : Default :: default ( ) ,
547550 has_errors : Default :: default ( ) ,
@@ -606,6 +609,12 @@ impl<'db> InferenceResult<'db> {
606609 _ => None ,
607610 } )
608611 }
612+ pub fn placeholder_types ( & self ) -> impl Iterator < Item = ( TypeRefId , & Ty < ' db > ) > {
613+ self . type_of_type_placeholder . iter ( )
614+ }
615+ pub fn type_of_type_placeholder ( & self , type_ref : TypeRefId ) -> Option < Ty < ' db > > {
616+ self . type_of_type_placeholder . get ( type_ref) . copied ( )
617+ }
609618 pub fn closure_info ( & self , closure : InternedClosureId ) -> & ( Vec < CapturedItem < ' db > > , FnTrait ) {
610619 self . closure_info . get ( & closure) . unwrap ( )
611620 }
@@ -1014,6 +1023,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
10141023 type_of_expr,
10151024 type_of_pat,
10161025 type_of_binding,
1026+ type_of_type_placeholder,
10171027 type_of_opaque,
10181028 type_mismatches,
10191029 has_errors,
@@ -1046,6 +1056,11 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
10461056 * has_errors = * has_errors || ty. references_non_lt_error ( ) ;
10471057 }
10481058 type_of_binding. shrink_to_fit ( ) ;
1059+ for ty in type_of_type_placeholder. values_mut ( ) {
1060+ * ty = table. resolve_completely ( * ty) ;
1061+ * has_errors = * has_errors || ty. references_non_lt_error ( ) ;
1062+ }
1063+ type_of_type_placeholder. shrink_to_fit ( ) ;
10491064 type_of_opaque. shrink_to_fit ( ) ;
10501065
10511066 * has_errors |= !type_mismatches. is_empty ( ) ;
@@ -1285,6 +1300,10 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
12851300 self . result . type_of_pat . insert ( pat, ty) ;
12861301 }
12871302
1303+ fn write_type_placeholder_ty ( & mut self , type_ref : TypeRefId , ty : Ty < ' db > ) {
1304+ self . result . type_of_type_placeholder . insert ( type_ref, ty) ;
1305+ }
1306+
12881307 fn write_binding_ty ( & mut self , id : BindingId , ty : Ty < ' db > ) {
12891308 self . result . type_of_binding . insert ( id, ty) ;
12901309 }
@@ -1333,7 +1352,27 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
13331352 ) -> Ty < ' db > {
13341353 let ty = self
13351354 . with_ty_lowering ( store, type_source, lifetime_elision, |ctx| ctx. lower_ty ( type_ref) ) ;
1336- self . process_user_written_ty ( ty)
1355+ let ty = self . process_user_written_ty ( ty) ;
1356+
1357+ // Record the association from placeholders' TypeRefId to type variables.
1358+ // We only record them if their number matches. This assumes TypeRef::walk and TypeVisitable process the items in the same order.
1359+ let type_variables = collect_type_inference_vars ( & ty) ;
1360+ let mut placeholder_ids = vec ! [ ] ;
1361+ TypeRef :: walk ( type_ref, store, & mut |type_ref_id, type_ref| {
1362+ if matches ! ( type_ref, TypeRef :: Placeholder ) {
1363+ placeholder_ids. push ( type_ref_id) ;
1364+ }
1365+ } ) ;
1366+
1367+ if placeholder_ids. len ( ) == type_variables. len ( ) {
1368+ for ( placeholder_id, type_variable) in
1369+ placeholder_ids. into_iter ( ) . zip ( type_variables. into_iter ( ) )
1370+ {
1371+ self . write_type_placeholder_ty ( placeholder_id, type_variable) ;
1372+ }
1373+ }
1374+
1375+ ty
13371376 }
13381377
13391378 pub ( crate ) fn make_body_ty ( & mut self , type_ref : TypeRefId ) -> Ty < ' db > {
0 commit comments