@@ -887,11 +887,37 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
887887 }
888888 }
889889
890+ fn visit_qpath ( & mut self , qpath : & ' tcx hir:: QPath < ' tcx > , id : HirId , _: Span ) {
891+ match qpath {
892+ hir:: QPath :: Resolved ( maybe_qself, path) => {
893+ if let Some ( qself) = maybe_qself {
894+ // FIXME: Temporary -- actually resolve OLD and get ResolvedArg for OLD
895+ let scope = Scope :: ObjectLifetimeDefault { lifetime : None , s : self . scope } ;
896+ self . with ( scope, |this| this. visit_ty_unambig ( qself) ) ;
897+ }
898+ self . visit_path ( path, id)
899+ }
900+ hir:: QPath :: TypeRelative ( qself, segment) => {
901+ // Resolving object lifetime defaults for type-relative paths requires type-dependent
902+ // resolution which we don't do here.
903+ // FIXME: How feasible would it be to track type-dependent defs here in RBVs?
904+ let scope = Scope :: ObjectLifetimeDefault { lifetime : None , s : self . scope } ;
905+ self . with ( scope, |this| {
906+ this. visit_ty_unambig ( qself) ;
907+ this. visit_path_segment ( segment)
908+ } ) ;
909+ }
910+ hir:: QPath :: LangItem ( ..) => { }
911+ }
912+ }
913+
914+ // FIXME: We need to overwrite `visit_qself` to properly handle qselves:
915+ // We need to intro a fresh Scope::ObjectLifetimeDefault { … } for them!
916+
890917 fn visit_path ( & mut self , path : & hir:: Path < ' tcx > , hir_id : HirId ) {
891- for ( i, segment) in path. segments . iter ( ) . enumerate ( ) {
892- let depth = path. segments . len ( ) - i - 1 ;
918+ for ( index, segment) in path. segments . iter ( ) . enumerate ( ) {
893919 if let Some ( args) = segment. args {
894- self . visit_segment_args ( path. res , depth , args) ;
920+ self . visit_segment_args ( path, index , args) ;
895921 }
896922 }
897923 if let Res :: Def ( DefKind :: TyParam | DefKind :: ConstParam , param_def_id) = path. res {
@@ -1611,8 +1637,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
16111637 #[ instrument( level = "debug" , skip( self ) ) ]
16121638 fn visit_segment_args (
16131639 & mut self ,
1614- res : Res ,
1615- depth : usize ,
1640+ path : & hir :: Path < ' tcx > ,
1641+ index : usize ,
16161642 generic_args : & ' tcx hir:: GenericArgs < ' tcx > ,
16171643 ) {
16181644 if let Some ( ( inputs, output) ) = generic_args. paren_sugar_inputs_output ( ) {
@@ -1626,19 +1652,23 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
16261652 }
16271653 }
16281654
1629- // Figure out if this is a type/trait segment,
1630- // which requires object lifetime defaults.
1631- let type_def_id = match res {
1632- Res :: Def ( DefKind :: AssocTy , def_id) if depth == 1 => Some ( self . tcx . parent ( def_id) ) ,
1633- Res :: Def ( DefKind :: Variant , def_id) if depth == 0 => Some ( self . tcx . parent ( def_id) ) ,
1634- Res :: Def (
1635- DefKind :: Struct
1636- | DefKind :: Union
1637- | DefKind :: Enum
1638- | DefKind :: TyAlias
1639- | DefKind :: Trait ,
1640- def_id,
1641- ) if depth == 0 => Some ( def_id) ,
1655+ // Figure out if this is a type/trait segment, which requires object lifetime defaults.
1656+ let depth = path. segments . len ( ) - index - 1 ;
1657+ let type_def_id = match ( path. res , depth) {
1658+ ( Res :: Def ( DefKind :: AssocTy , def_id) , 1 ) => Some ( self . tcx . parent ( def_id) ) ,
1659+ ( Res :: Def ( DefKind :: Variant , def_id) , 0 ) => Some ( self . tcx . parent ( def_id) ) ,
1660+ (
1661+ Res :: Def (
1662+ DefKind :: Struct
1663+ | DefKind :: Union
1664+ | DefKind :: Enum
1665+ | DefKind :: TyAlias
1666+ | DefKind :: Trait
1667+ | DefKind :: AssocTy ,
1668+ def_id,
1669+ ) ,
1670+ 0 ,
1671+ ) => Some ( def_id) ,
16421672 _ => None ,
16431673 } ;
16441674
@@ -1683,9 +1713,6 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
16831713 let rbv = & self . rbv ;
16841714 let generics = self . tcx . generics_of ( def_id) ;
16851715
1686- // `type_def_id` points to an item, so there is nothing to inherit generics from.
1687- debug_assert_eq ! ( generics. parent_count, 0 ) ;
1688-
16891716 let set_to_region = |set : ObjectLifetimeDefault | match set {
16901717 ObjectLifetimeDefault :: Empty => {
16911718 if in_body {
@@ -1696,12 +1723,31 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
16961723 }
16971724 ObjectLifetimeDefault :: Static => Some ( ResolvedArg :: StaticLifetime ) ,
16981725 ObjectLifetimeDefault :: Param ( param_def_id) => {
1699- // This index can be used with `generic_args` since `parent_count == 0`.
1700- let index = generics. param_def_id_to_index [ & param_def_id] as usize ;
1701- generic_args. args . get ( index) . and_then ( |arg| match arg {
1702- GenericArg :: Lifetime ( lt) => rbv. defs . get ( & lt. hir_id . local_id ) . copied ( ) ,
1703- _ => None ,
1704- } )
1726+ fn param_to_depth_and_index (
1727+ generics : & ty:: Generics ,
1728+ tcx : TyCtxt < ' _ > ,
1729+ def_id : DefId ,
1730+ ) -> ( usize , usize ) {
1731+ if let Some ( & index) = generics. param_def_id_to_index . get ( & def_id) {
1732+ let has_self = generics. parent . is_none ( ) && generics. has_self ;
1733+ ( 0 , index as usize - generics. parent_count - has_self as usize )
1734+ } else if let Some ( parent) = generics. parent {
1735+ let parent = tcx. generics_of ( parent) ;
1736+ let ( index, depth) = param_to_depth_and_index ( parent, tcx, def_id) ;
1737+ ( depth + 1 , index)
1738+ } else {
1739+ unreachable ! ( )
1740+ }
1741+ }
1742+
1743+ let ( depth, index) = param_to_depth_and_index ( generics, self . tcx , param_def_id) ;
1744+ path. segments [ path. segments . len ( ) - depth - 1 ]
1745+ . args
1746+ . and_then ( |args| args. args . get ( index) )
1747+ . and_then ( |arg| match arg {
1748+ GenericArg :: Lifetime ( lt) => rbv. defs . get ( & lt. hir_id . local_id ) . copied ( ) ,
1749+ _ => None ,
1750+ } )
17051751 }
17061752 ObjectLifetimeDefault :: Ambiguous => None ,
17071753 } ;
0 commit comments