@@ -35,14 +35,14 @@ trait RegionExt {
3535
3636impl RegionExt for ResolvedArg {
3737 fn early ( param : & GenericParam < ' _ > ) -> ( LocalDefId , ResolvedArg ) {
38- debug ! ( "Region ::early: def_id={:?}" , param. def_id) ;
38+ debug ! ( "ResolvedArg ::early: def_id={:?}" , param. def_id) ;
3939 ( param. def_id , ResolvedArg :: EarlyBound ( param. def_id . to_def_id ( ) ) )
4040 }
4141
4242 fn late ( idx : u32 , param : & GenericParam < ' _ > ) -> ( LocalDefId , ResolvedArg ) {
4343 let depth = ty:: INNERMOST ;
4444 debug ! (
45- "Region ::late: idx={:?}, param={:?} depth={:?} def_id={:?}" ,
45+ "ResolvedArg ::late: idx={:?}, param={:?} depth={:?} def_id={:?}" ,
4646 idx, param, depth, param. def_id,
4747 ) ;
4848 ( 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
278278 rl
279279}
280280
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 {
283287 ResolvedArg :: LateBound ( _, _, def_id) => {
284288 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+ }
286298 }
287- _ => bug ! ( "{:?} is not a late argument" , region ) ,
299+ _ => bug ! ( "{:?} is not a late argument" , arg ) ,
288300 }
289301}
290302
@@ -391,11 +403,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
391403 let ( bound_vars, binders) : ( FxIndexMap < LocalDefId , ResolvedArg > , Vec < _ > ) =
392404 bound_generic_params
393405 . iter ( )
394- . filter ( |param| matches ! ( param. kind, GenericParamKind :: Lifetime { .. } ) )
395406 . enumerate ( )
396407 . map ( |( late_bound_idx, param) | {
397408 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 ) ;
399410 ( pair, r)
400411 } )
401412 . unzip ( ) ;
@@ -481,7 +492,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
481492 }
482493 }
483494 hir:: ItemKind :: OpaqueTy ( hir:: OpaqueTy {
484- origin : hir:: OpaqueTyOrigin :: FnReturn ( _ ) | hir:: OpaqueTyOrigin :: AsyncFn ( _ ) ,
495+ origin : hir:: OpaqueTyOrigin :: FnReturn ( parent ) | hir:: OpaqueTyOrigin :: AsyncFn ( parent ) ,
485496 generics,
486497 ..
487498 } ) => {
@@ -490,26 +501,24 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
490501 let mut bound_vars = FxIndexMap :: default ( ) ;
491502 debug ! ( ?generics. params) ;
492503 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) ;
500506 }
501507
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) } ;
509509 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+ } )
513522 }
514523 hir:: ItemKind :: TyAlias ( _, generics)
515524 | hir:: ItemKind :: Enum ( _, generics)
@@ -519,14 +528,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
519528 | hir:: ItemKind :: TraitAlias ( generics, ..)
520529 | hir:: ItemKind :: Impl ( & hir:: Impl { generics, .. } ) => {
521530 // 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 ( ) ;
530532 self . record_late_bound_vars ( item. hir_id ( ) , vec ! [ ] ) ;
531533 let scope = Scope :: Binder {
532534 hir_id : item. hir_id ( ) ,
@@ -568,11 +570,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
568570 let ( bound_vars, binders) : ( FxIndexMap < LocalDefId , ResolvedArg > , Vec < _ > ) = c
569571 . generic_params
570572 . iter ( )
571- . filter ( |param| matches ! ( param. kind, GenericParamKind :: Lifetime { .. } ) )
572573 . enumerate ( )
573574 . map ( |( late_bound_idx, param) | {
574575 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 ) ;
576577 ( pair, r)
577578 } )
578579 . unzip ( ) ;
@@ -725,14 +726,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
725726 }
726727 Type ( bounds, ty) => {
727728 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 ( ) ;
736730 self . record_late_bound_vars ( trait_item. hir_id ( ) , vec ! [ ] ) ;
737731 let scope = Scope :: Binder {
738732 hir_id : trait_item. hir_id ( ) ,
@@ -771,14 +765,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
771765 } ) ,
772766 Type ( ty) => {
773767 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 ( ) ;
782770 self . record_late_bound_vars ( impl_item. hir_id ( ) , vec ! [ ] ) ;
783771 let scope = Scope :: Binder {
784772 hir_id : impl_item. hir_id ( ) ,
@@ -819,13 +807,16 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
819807 }
820808 }
821809
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 ) {
823811 for ( i, segment) in path. segments . iter ( ) . enumerate ( ) {
824812 let depth = path. segments . len ( ) - i - 1 ;
825813 if let Some ( args) = segment. args {
826814 self . visit_segment_args ( path. res , depth, args) ;
827815 }
828816 }
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+ }
829820 }
830821
831822 fn visit_fn (
@@ -874,24 +865,17 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
874865 origin,
875866 ..
876867 } ) => {
877- let bound_vars: FxIndexMap < LocalDefId , ResolvedArg > =
868+
869+ let ( bound_vars, binders) : ( FxIndexMap < LocalDefId , ResolvedArg > , Vec < _ > ) =
878870 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 ( ) ;
895879 this. record_late_bound_vars ( hir_id, binders. clone ( ) ) ;
896880 // Even if there are no lifetimes defined here, we still wrap it in a binder
897881 // 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> {
989973
990974 let initial_bound_vars = binders. len ( ) as u32 ;
991975 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) | {
998978 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 ) ;
1000980 bound_vars. insert ( pair. 0 , pair. 1 ) ;
1001981 r
1002982 } ) ;
@@ -1121,17 +1101,19 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
11211101 let bound_vars: FxIndexMap < LocalDefId , ResolvedArg > = generics
11221102 . params
11231103 . iter ( )
1124- . filter_map ( |param| match param. kind {
1104+ . map ( |param| match param. kind {
11251105 GenericParamKind :: Lifetime { .. } => {
11261106 if self . tcx . is_late_bound ( param. hir_id ) {
11271107 let late_bound_idx = named_late_bound_vars;
11281108 named_late_bound_vars += 1 ;
1129- Some ( ResolvedArg :: late ( late_bound_idx, param) )
1109+ ResolvedArg :: late ( late_bound_idx, param)
11301110 } else {
1131- Some ( ResolvedArg :: early ( param) )
1111+ ResolvedArg :: early ( param)
11321112 }
11331113 }
1134- GenericParamKind :: Type { .. } | GenericParamKind :: Const { .. } => None ,
1114+ GenericParamKind :: Type { .. } | GenericParamKind :: Const { .. } => {
1115+ ResolvedArg :: early ( param)
1116+ }
11351117 } )
11361118 . collect ( ) ;
11371119
@@ -1145,7 +1127,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
11451127 . enumerate ( )
11461128 . map ( |( late_bound_idx, param) | {
11471129 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 )
11491131 } )
11501132 . collect ( ) ;
11511133 self . record_late_bound_vars ( hir_id, binders) ;
@@ -1182,7 +1164,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
11821164 Scope :: Root { opt_parent_item } => {
11831165 if let Some ( parent_item) = opt_parent_item
11841166 && 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 ( )
11861168 {
11871169 break Some ( ResolvedArg :: EarlyBound ( region_def_id. to_def_id ( ) ) ) ;
11881170 }
@@ -1334,6 +1316,61 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
13341316 ) ;
13351317 }
13361318
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+
13371374 #[ instrument( level = "debug" , skip( self ) ) ]
13381375 fn visit_segment_args (
13391376 & mut self ,
0 commit comments