@@ -35,14 +35,14 @@ trait RegionExt {
35
35
36
36
impl RegionExt for ResolvedArg {
37
37
fn early ( param : & GenericParam < ' _ > ) -> ( LocalDefId , ResolvedArg ) {
38
- debug ! ( "Region ::early: def_id={:?}" , param. def_id) ;
38
+ debug ! ( "ResolvedArg ::early: def_id={:?}" , param. def_id) ;
39
39
( param. def_id , ResolvedArg :: EarlyBound ( param. def_id . to_def_id ( ) ) )
40
40
}
41
41
42
42
fn late ( idx : u32 , param : & GenericParam < ' _ > ) -> ( LocalDefId , ResolvedArg ) {
43
43
let depth = ty:: INNERMOST ;
44
44
debug ! (
45
- "Region ::late: idx={:?}, param={:?} depth={:?} def_id={:?}" ,
45
+ "ResolvedArg ::late: idx={:?}, param={:?} depth={:?} def_id={:?}" ,
46
46
idx, param, depth, param. def_id,
47
47
) ;
48
48
( param. def_id , ResolvedArg :: LateBound ( depth, idx, param. def_id . to_def_id ( ) ) )
@@ -278,13 +278,25 @@ fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBou
278
278
rl
279
279
}
280
280
281
- fn late_region_as_bound_region ( tcx : TyCtxt < ' _ > , region : & ResolvedArg ) -> ty:: BoundVariableKind {
282
- match region {
281
+ fn late_arg_as_bound_arg < ' tcx > (
282
+ tcx : TyCtxt < ' tcx > ,
283
+ arg : & ResolvedArg ,
284
+ param : & GenericParam < ' tcx > ,
285
+ ) -> ty:: BoundVariableKind {
286
+ match arg {
283
287
ResolvedArg :: LateBound ( _, _, def_id) => {
284
288
let name = tcx. hir ( ) . name ( tcx. hir ( ) . local_def_id_to_hir_id ( def_id. expect_local ( ) ) ) ;
285
- ty:: BoundVariableKind :: Region ( ty:: BrNamed ( * def_id, name) )
289
+ match param. kind {
290
+ GenericParamKind :: Lifetime { .. } => {
291
+ ty:: BoundVariableKind :: Region ( ty:: BrNamed ( * def_id, name) )
292
+ }
293
+ GenericParamKind :: Type { .. } => {
294
+ ty:: BoundVariableKind :: Ty ( ty:: BoundTyKind :: Param ( * def_id, name) )
295
+ }
296
+ GenericParamKind :: Const { .. } => ty:: BoundVariableKind :: Const ,
297
+ }
286
298
}
287
- _ => bug ! ( "{:?} is not a late argument" , region ) ,
299
+ _ => bug ! ( "{:?} is not a late argument" , arg ) ,
288
300
}
289
301
}
290
302
@@ -391,11 +403,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
391
403
let ( bound_vars, binders) : ( FxIndexMap < LocalDefId , ResolvedArg > , Vec < _ > ) =
392
404
bound_generic_params
393
405
. iter ( )
394
- . filter ( |param| matches ! ( param. kind, GenericParamKind :: Lifetime { .. } ) )
395
406
. enumerate ( )
396
407
. map ( |( late_bound_idx, param) | {
397
408
let pair = ResolvedArg :: late ( late_bound_idx as u32 , param) ;
398
- let r = late_region_as_bound_region ( self . tcx , & pair. 1 ) ;
409
+ let r = late_arg_as_bound_arg ( self . tcx , & pair. 1 , param ) ;
399
410
( pair, r)
400
411
} )
401
412
. unzip ( ) ;
@@ -481,7 +492,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
481
492
}
482
493
}
483
494
hir:: ItemKind :: OpaqueTy ( hir:: OpaqueTy {
484
- origin : hir:: OpaqueTyOrigin :: FnReturn ( _ ) | hir:: OpaqueTyOrigin :: AsyncFn ( _ ) ,
495
+ origin : hir:: OpaqueTyOrigin :: FnReturn ( parent ) | hir:: OpaqueTyOrigin :: AsyncFn ( parent ) ,
485
496
generics,
486
497
..
487
498
} ) => {
@@ -490,26 +501,24 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
490
501
let mut bound_vars = FxIndexMap :: default ( ) ;
491
502
debug ! ( ?generics. params) ;
492
503
for param in generics. params {
493
- match param. kind {
494
- GenericParamKind :: Lifetime { .. } => {
495
- let ( def_id, reg) = ResolvedArg :: early ( & param) ;
496
- bound_vars. insert ( def_id, reg) ;
497
- }
498
- GenericParamKind :: Type { .. } | GenericParamKind :: Const { .. } => { }
499
- }
504
+ let ( def_id, reg) = ResolvedArg :: early ( & param) ;
505
+ bound_vars. insert ( def_id, reg) ;
500
506
}
501
507
502
- let scope = Scope :: Binder {
503
- hir_id : item. hir_id ( ) ,
504
- bound_vars,
505
- s : self . scope ,
506
- scope_type : BinderScopeType :: Normal ,
507
- where_bound_origin : None ,
508
- } ;
508
+ let scope = Scope :: Root { opt_parent_item : Some ( parent) } ;
509
509
self . with ( scope, |this| {
510
- let scope = Scope :: TraitRefBoundary { s : this. scope } ;
511
- this. with ( scope, |this| intravisit:: walk_item ( this, item) )
512
- } ) ;
510
+ let scope = Scope :: Binder {
511
+ hir_id : item. hir_id ( ) ,
512
+ bound_vars,
513
+ s : this. scope ,
514
+ scope_type : BinderScopeType :: Normal ,
515
+ where_bound_origin : None ,
516
+ } ;
517
+ this. with ( scope, |this| {
518
+ let scope = Scope :: TraitRefBoundary { s : this. scope } ;
519
+ this. with ( scope, |this| intravisit:: walk_item ( this, item) )
520
+ } ) ;
521
+ } )
513
522
}
514
523
hir:: ItemKind :: TyAlias ( _, generics)
515
524
| hir:: ItemKind :: Enum ( _, generics)
@@ -519,14 +528,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
519
528
| hir:: ItemKind :: TraitAlias ( generics, ..)
520
529
| hir:: ItemKind :: Impl ( & hir:: Impl { generics, .. } ) => {
521
530
// These kinds of items have only early-bound lifetime parameters.
522
- let bound_vars = generics
523
- . params
524
- . iter ( )
525
- . filter_map ( |param| match param. kind {
526
- GenericParamKind :: Lifetime { .. } => Some ( ResolvedArg :: early ( param) ) ,
527
- GenericParamKind :: Type { .. } | GenericParamKind :: Const { .. } => None ,
528
- } )
529
- . collect ( ) ;
531
+ let bound_vars = generics. params . iter ( ) . map ( ResolvedArg :: early) . collect ( ) ;
530
532
self . record_late_bound_vars ( item. hir_id ( ) , vec ! [ ] ) ;
531
533
let scope = Scope :: Binder {
532
534
hir_id : item. hir_id ( ) ,
@@ -568,11 +570,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
568
570
let ( bound_vars, binders) : ( FxIndexMap < LocalDefId , ResolvedArg > , Vec < _ > ) = c
569
571
. generic_params
570
572
. iter ( )
571
- . filter ( |param| matches ! ( param. kind, GenericParamKind :: Lifetime { .. } ) )
572
573
. enumerate ( )
573
574
. map ( |( late_bound_idx, param) | {
574
575
let pair = ResolvedArg :: late ( late_bound_idx as u32 , param) ;
575
- let r = late_region_as_bound_region ( self . tcx , & pair. 1 ) ;
576
+ let r = late_arg_as_bound_arg ( self . tcx , & pair. 1 , param ) ;
576
577
( pair, r)
577
578
} )
578
579
. unzip ( ) ;
@@ -725,14 +726,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
725
726
}
726
727
Type ( bounds, ty) => {
727
728
let generics = & trait_item. generics ;
728
- let bound_vars = generics
729
- . params
730
- . iter ( )
731
- . filter_map ( |param| match param. kind {
732
- GenericParamKind :: Lifetime { .. } => Some ( ResolvedArg :: early ( param) ) ,
733
- GenericParamKind :: Type { .. } | GenericParamKind :: Const { .. } => None ,
734
- } )
735
- . collect ( ) ;
729
+ let bound_vars = generics. params . iter ( ) . map ( ResolvedArg :: early) . collect ( ) ;
736
730
self . record_late_bound_vars ( trait_item. hir_id ( ) , vec ! [ ] ) ;
737
731
let scope = Scope :: Binder {
738
732
hir_id : trait_item. hir_id ( ) ,
@@ -771,14 +765,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
771
765
} ) ,
772
766
Type ( ty) => {
773
767
let generics = & impl_item. generics ;
774
- let bound_vars: FxIndexMap < LocalDefId , ResolvedArg > = generics
775
- . params
776
- . iter ( )
777
- . filter_map ( |param| match param. kind {
778
- GenericParamKind :: Lifetime { .. } => Some ( ResolvedArg :: early ( param) ) ,
779
- GenericParamKind :: Const { .. } | GenericParamKind :: Type { .. } => None ,
780
- } )
781
- . collect ( ) ;
768
+ let bound_vars: FxIndexMap < LocalDefId , ResolvedArg > =
769
+ generics. params . iter ( ) . map ( ResolvedArg :: early) . collect ( ) ;
782
770
self . record_late_bound_vars ( impl_item. hir_id ( ) , vec ! [ ] ) ;
783
771
let scope = Scope :: Binder {
784
772
hir_id : impl_item. hir_id ( ) ,
@@ -819,13 +807,16 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
819
807
}
820
808
}
821
809
822
- fn visit_path ( & mut self , path : & hir:: Path < ' tcx > , _ : hir:: HirId ) {
810
+ fn visit_path ( & mut self , path : & hir:: Path < ' tcx > , hir_id : hir:: HirId ) {
823
811
for ( i, segment) in path. segments . iter ( ) . enumerate ( ) {
824
812
let depth = path. segments . len ( ) - i - 1 ;
825
813
if let Some ( args) = segment. args {
826
814
self . visit_segment_args ( path. res , depth, args) ;
827
815
}
828
816
}
817
+ if let Res :: Def ( DefKind :: TyParam | DefKind :: ConstParam , param_def_id) = path. res {
818
+ self . resolve_type_ref ( param_def_id. expect_local ( ) , hir_id) ;
819
+ }
829
820
}
830
821
831
822
fn visit_fn (
@@ -874,24 +865,17 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
874
865
origin,
875
866
..
876
867
} ) => {
877
- let bound_vars: FxIndexMap < LocalDefId , ResolvedArg > =
868
+
869
+ let ( bound_vars, binders) : ( FxIndexMap < LocalDefId , ResolvedArg > , Vec < _ > ) =
878
870
bound_generic_params
879
- . iter ( )
880
- . filter ( |param| {
881
- matches ! ( param. kind, GenericParamKind :: Lifetime { .. } )
882
- } )
883
- . enumerate ( )
884
- . map ( |( late_bound_idx, param) | {
885
- ResolvedArg :: late ( late_bound_idx as u32 , param)
886
- } )
887
- . collect ( ) ;
888
- let binders: Vec < _ > =
889
- bound_vars
890
- . iter ( )
891
- . map ( |( _, region) | {
892
- late_region_as_bound_region ( this. tcx , region)
893
- } )
894
- . collect ( ) ;
871
+ . iter ( )
872
+ . enumerate ( )
873
+ . map ( |( late_bound_idx, param) | {
874
+ let pair = ResolvedArg :: late ( late_bound_idx as u32 , param) ;
875
+ let r = late_arg_as_bound_arg ( this. tcx , & pair. 1 , param) ;
876
+ ( pair, r)
877
+ } )
878
+ . unzip ( ) ;
895
879
this. record_late_bound_vars ( hir_id, binders. clone ( ) ) ;
896
880
// Even if there are no lifetimes defined here, we still wrap it in a binder
897
881
// scope. If there happens to be a nested poly trait ref (an error), that
@@ -989,14 +973,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
989
973
990
974
let initial_bound_vars = binders. len ( ) as u32 ;
991
975
let mut bound_vars: FxIndexMap < LocalDefId , ResolvedArg > = FxIndexMap :: default ( ) ;
992
- let binders_iter = trait_ref
993
- . bound_generic_params
994
- . iter ( )
995
- . filter ( |param| matches ! ( param. kind, GenericParamKind :: Lifetime { .. } ) )
996
- . enumerate ( )
997
- . map ( |( late_bound_idx, param) | {
976
+ let binders_iter =
977
+ trait_ref. bound_generic_params . iter ( ) . enumerate ( ) . map ( |( late_bound_idx, param) | {
998
978
let pair = ResolvedArg :: late ( initial_bound_vars + late_bound_idx as u32 , param) ;
999
- let r = late_region_as_bound_region ( self . tcx , & pair. 1 ) ;
979
+ let r = late_arg_as_bound_arg ( self . tcx , & pair. 1 , param ) ;
1000
980
bound_vars. insert ( pair. 0 , pair. 1 ) ;
1001
981
r
1002
982
} ) ;
@@ -1121,17 +1101,19 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1121
1101
let bound_vars: FxIndexMap < LocalDefId , ResolvedArg > = generics
1122
1102
. params
1123
1103
. iter ( )
1124
- . filter_map ( |param| match param. kind {
1104
+ . map ( |param| match param. kind {
1125
1105
GenericParamKind :: Lifetime { .. } => {
1126
1106
if self . tcx . is_late_bound ( param. hir_id ) {
1127
1107
let late_bound_idx = named_late_bound_vars;
1128
1108
named_late_bound_vars += 1 ;
1129
- Some ( ResolvedArg :: late ( late_bound_idx, param) )
1109
+ ResolvedArg :: late ( late_bound_idx, param)
1130
1110
} else {
1131
- Some ( ResolvedArg :: early ( param) )
1111
+ ResolvedArg :: early ( param)
1132
1112
}
1133
1113
}
1134
- GenericParamKind :: Type { .. } | GenericParamKind :: Const { .. } => None ,
1114
+ GenericParamKind :: Type { .. } | GenericParamKind :: Const { .. } => {
1115
+ ResolvedArg :: early ( param)
1116
+ }
1135
1117
} )
1136
1118
. collect ( ) ;
1137
1119
@@ -1145,7 +1127,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1145
1127
. enumerate ( )
1146
1128
. map ( |( late_bound_idx, param) | {
1147
1129
let pair = ResolvedArg :: late ( late_bound_idx as u32 , param) ;
1148
- late_region_as_bound_region ( self . tcx , & pair. 1 )
1130
+ late_arg_as_bound_arg ( self . tcx , & pair. 1 , param )
1149
1131
} )
1150
1132
. collect ( ) ;
1151
1133
self . record_late_bound_vars ( hir_id, binders) ;
@@ -1182,7 +1164,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1182
1164
Scope :: Root { opt_parent_item } => {
1183
1165
if let Some ( parent_item) = opt_parent_item
1184
1166
&& let parent_generics = self . tcx . generics_of ( parent_item)
1185
- && parent_generics. param_def_id_to_index . contains_key ( & region_def_id. to_def_id ( ) )
1167
+ && parent_generics. param_def_id_to_index ( self . tcx , region_def_id. to_def_id ( ) ) . is_some ( )
1186
1168
{
1187
1169
break Some ( ResolvedArg :: EarlyBound ( region_def_id. to_def_id ( ) ) ) ;
1188
1170
}
@@ -1334,6 +1316,61 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1334
1316
) ;
1335
1317
}
1336
1318
1319
+ fn resolve_type_ref ( & mut self , param_def_id : LocalDefId , hir_id : hir:: HirId ) {
1320
+ // Walk up the scope chain, tracking the number of fn scopes
1321
+ // that we pass through, until we find a lifetime with the
1322
+ // given name or we run out of scopes.
1323
+ // search.
1324
+ let mut late_depth = 0 ;
1325
+ let mut scope = self . scope ;
1326
+ let result = loop {
1327
+ match * scope {
1328
+ Scope :: Body { s, .. } => {
1329
+ scope = s;
1330
+ }
1331
+
1332
+ Scope :: Root { opt_parent_item } => {
1333
+ if let Some ( parent_item) = opt_parent_item
1334
+ && let parent_generics = self . tcx . generics_of ( parent_item)
1335
+ && parent_generics. param_def_id_to_index ( self . tcx , param_def_id. to_def_id ( ) ) . is_some ( )
1336
+ {
1337
+ break Some ( ResolvedArg :: EarlyBound ( param_def_id. to_def_id ( ) ) ) ;
1338
+ }
1339
+ break None ;
1340
+ }
1341
+
1342
+ Scope :: Binder { ref bound_vars, scope_type, s, .. } => {
1343
+ if let Some ( & def) = bound_vars. get ( & param_def_id) {
1344
+ break Some ( def. shifted ( late_depth) ) ;
1345
+ }
1346
+ match scope_type {
1347
+ BinderScopeType :: Normal => late_depth += 1 ,
1348
+ BinderScopeType :: Concatenating => { }
1349
+ }
1350
+ scope = s;
1351
+ }
1352
+
1353
+ Scope :: Elision { s, .. }
1354
+ | Scope :: ObjectLifetimeDefault { s, .. }
1355
+ | Scope :: Supertrait { s, .. }
1356
+ | Scope :: TraitRefBoundary { s, .. } => {
1357
+ scope = s;
1358
+ }
1359
+ }
1360
+ } ;
1361
+
1362
+ if let Some ( def) = result {
1363
+ self . map . defs . insert ( hir_id, def) ;
1364
+ return ;
1365
+ }
1366
+
1367
+ span_bug ! (
1368
+ self . tcx. hir( ) . span( hir_id) ,
1369
+ "could not resolve {param_def_id:?}, scopes: {:#?}" ,
1370
+ self . scope
1371
+ ) ;
1372
+ }
1373
+
1337
1374
#[ instrument( level = "debug" , skip( self ) ) ]
1338
1375
fn visit_segment_args (
1339
1376
& mut self ,
0 commit comments