@@ -267,6 +267,9 @@ enum ImplTraitContext<'b, 'a> {
267267 ReturnPositionOpaqueTy {
268268 /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
269269 origin : hir:: OpaqueTyOrigin ,
270+ /// Whether this is nested in another return position opaque type
271+ /// `None` if we aren't in any return position opaque type yet.
272+ nested : Option < bool > ,
270273 } ,
271274 /// Impl trait in type aliases.
272275 TypeAliasesOpaqueTy ,
@@ -303,7 +306,9 @@ impl<'a> ImplTraitContext<'_, 'a> {
303306 use self :: ImplTraitContext :: * ;
304307 match self {
305308 Universal ( params, bounds, parent) => Universal ( params, bounds, * parent) ,
306- ReturnPositionOpaqueTy { origin } => ReturnPositionOpaqueTy { origin : * origin } ,
309+ ReturnPositionOpaqueTy { origin, nested } => {
310+ ReturnPositionOpaqueTy { origin : * origin, nested : * nested }
311+ }
307312 TypeAliasesOpaqueTy => TypeAliasesOpaqueTy ,
308313 Disallowed ( pos) => Disallowed ( * pos) ,
309314 }
@@ -1072,7 +1077,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
10721077 itctx : ImplTraitContext < ' _ , ' hir > ,
10731078 ) -> hir:: GenericArg < ' hir > {
10741079 match arg {
1075- ast:: GenericArg :: Lifetime ( lt) => GenericArg :: Lifetime ( self . lower_lifetime ( & lt) ) ,
1080+ ast:: GenericArg :: Lifetime ( lt) => GenericArg :: Lifetime ( self . lower_lifetime ( & lt, itctx ) ) ,
10761081 ast:: GenericArg :: Type ( ty) => {
10771082 match ty. kind {
10781083 TyKind :: Infer if self . sess . features_untracked ( ) . generic_arg_infer => {
@@ -1179,7 +1184,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11791184 id : start,
11801185 }
11811186 } ) ;
1182- let lifetime = self . lower_lifetime ( & region) ;
1187+ let lifetime = self . lower_lifetime ( & region, itctx . reborrow ( ) ) ;
11831188 hir:: TyKind :: Rptr ( lifetime, self . lower_mt ( mt, itctx) )
11841189 }
11851190 TyKind :: BareFn ( ref f) => self . with_lifetime_binder ( t. id , |this| {
@@ -1239,7 +1244,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12391244 ) => None ,
12401245 GenericBound :: Outlives ( ref lifetime) => {
12411246 if lifetime_bound. is_none ( ) {
1242- lifetime_bound = Some ( this. lower_lifetime ( lifetime) ) ;
1247+ lifetime_bound =
1248+ Some ( this. lower_lifetime ( lifetime, itctx. reborrow ( ) ) ) ;
12431249 }
12441250 None
12451251 }
@@ -1254,17 +1260,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12541260 TyKind :: ImplTrait ( def_node_id, ref bounds) => {
12551261 let span = t. span ;
12561262 match itctx {
1257- ImplTraitContext :: ReturnPositionOpaqueTy { origin } => self
1258- . lower_opaque_impl_trait ( span, origin, def_node_id, |this| {
1259- this. lower_param_bounds ( bounds, itctx)
1260- } ) ,
1263+ ImplTraitContext :: ReturnPositionOpaqueTy { origin, nested } => self
1264+ . lower_opaque_impl_trait (
1265+ span,
1266+ origin,
1267+ def_node_id,
1268+ |this, itctx| this. lower_param_bounds ( bounds, itctx) ,
1269+ ImplTraitContext :: ReturnPositionOpaqueTy {
1270+ origin,
1271+ nested : match nested {
1272+ Some ( _) => Some ( true ) ,
1273+ None => Some ( false ) ,
1274+ } ,
1275+ } ,
1276+ ) ,
12611277 ImplTraitContext :: TypeAliasesOpaqueTy => {
12621278 let nested_itctx = ImplTraitContext :: TypeAliasesOpaqueTy ;
12631279 self . lower_opaque_impl_trait (
12641280 span,
12651281 hir:: OpaqueTyOrigin :: TyAlias ,
12661282 def_node_id,
1267- |this| this. lower_param_bounds ( bounds, nested_itctx) ,
1283+ |this, itctx| this. lower_param_bounds ( bounds, itctx) ,
1284+ nested_itctx,
12681285 )
12691286 }
12701287 ImplTraitContext :: Universal (
@@ -1299,6 +1316,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12991316 & GenericParamKind :: Type { default : None } ,
13001317 hir_bounds,
13011318 hir:: PredicateOrigin :: ImplTrait ,
1319+ ImplTraitContext :: Universal (
1320+ in_band_ty_params,
1321+ in_band_ty_bounds,
1322+ parent_def_id,
1323+ ) ,
13021324 ) {
13031325 in_band_ty_bounds. push ( preds)
13041326 }
@@ -1344,7 +1366,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13441366 span : Span ,
13451367 origin : hir:: OpaqueTyOrigin ,
13461368 opaque_ty_node_id : NodeId ,
1347- lower_bounds : impl FnOnce ( & mut Self ) -> hir:: GenericBounds < ' hir > ,
1369+ lower_bounds : impl FnOnce ( & mut Self , ImplTraitContext < ' _ , ' hir > ) -> hir:: GenericBounds < ' hir > ,
1370+ mut itctx : ImplTraitContext < ' _ , ' hir > ,
13481371 ) -> hir:: TyKind < ' hir > {
13491372 // Make sure we know that some funky desugaring has been going on here.
13501373 // This is a first: there is code in other places like for loop
@@ -1358,13 +1381,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13581381 let mut collected_lifetimes = FxHashMap :: default ( ) ;
13591382 self . with_hir_id_owner ( opaque_ty_node_id, |lctx| {
13601383 let hir_bounds = if origin == hir:: OpaqueTyOrigin :: TyAlias {
1361- lower_bounds ( lctx)
1384+ lower_bounds ( lctx, itctx . reborrow ( ) )
13621385 } else {
1363- lctx. while_capturing_lifetimes (
1364- opaque_ty_def_id,
1365- & mut collected_lifetimes,
1366- lower_bounds,
1367- )
1386+ lctx. while_capturing_lifetimes ( opaque_ty_def_id, & mut collected_lifetimes, |lctx| {
1387+ lower_bounds ( lctx, itctx. reborrow ( ) )
1388+ } )
13681389 } ;
13691390 debug ! ( ?collected_lifetimes) ;
13701391
@@ -1412,7 +1433,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
14121433 |( _, ( span, _, p_name, res) ) | {
14131434 let id = self . resolver . next_node_id ( ) ;
14141435 let ident = Ident :: new ( p_name. ident ( ) . name , span) ;
1415- let l = self . new_named_lifetime_with_res ( id, span, ident, res) ;
1436+ let l = self . new_named_lifetime_with_res ( id, span, ident, res, itctx . reborrow ( ) ) ;
14161437 hir:: GenericArg :: Lifetime ( l)
14171438 } ,
14181439 ) ) ;
@@ -1523,35 +1544,36 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15231544 }
15241545 } ) ) ;
15251546
1547+ let context = match in_band_ty_params {
1548+ Some ( ( node_id, _, _) ) if kind. impl_trait_return_allowed ( ) => {
1549+ let fn_def_id = self . resolver . local_def_id ( node_id) ;
1550+ ImplTraitContext :: ReturnPositionOpaqueTy {
1551+ origin : hir:: OpaqueTyOrigin :: FnReturn ( fn_def_id) ,
1552+ nested : None ,
1553+ }
1554+ }
1555+ _ => ImplTraitContext :: Disallowed ( match kind {
1556+ FnDeclKind :: Fn | FnDeclKind :: Inherent => {
1557+ unreachable ! ( "fn should allow in-band lifetimes" )
1558+ }
1559+ FnDeclKind :: ExternFn => ImplTraitPosition :: ExternFnReturn ,
1560+ FnDeclKind :: Closure => ImplTraitPosition :: ClosureReturn ,
1561+ FnDeclKind :: Pointer => ImplTraitPosition :: PointerReturn ,
1562+ FnDeclKind :: Trait => ImplTraitPosition :: TraitReturn ,
1563+ FnDeclKind :: Impl => ImplTraitPosition :: ImplReturn ,
1564+ } ) ,
1565+ } ;
1566+
15261567 let output = if let Some ( ret_id) = make_ret_async {
15271568 self . lower_async_fn_ret_ty (
15281569 & decl. output ,
15291570 in_band_ty_params. expect ( "`make_ret_async` but no `fn_def_id`" ) . 0 ,
15301571 ret_id,
1572+ context,
15311573 )
15321574 } else {
15331575 match decl. output {
1534- FnRetTy :: Ty ( ref ty) => {
1535- let context = match in_band_ty_params {
1536- Some ( ( node_id, _, _) ) if kind. impl_trait_return_allowed ( ) => {
1537- let fn_def_id = self . resolver . local_def_id ( node_id) ;
1538- ImplTraitContext :: ReturnPositionOpaqueTy {
1539- origin : hir:: OpaqueTyOrigin :: FnReturn ( fn_def_id) ,
1540- }
1541- }
1542- _ => ImplTraitContext :: Disallowed ( match kind {
1543- FnDeclKind :: Fn | FnDeclKind :: Inherent => {
1544- unreachable ! ( "fn should allow in-band lifetimes" )
1545- }
1546- FnDeclKind :: ExternFn => ImplTraitPosition :: ExternFnReturn ,
1547- FnDeclKind :: Closure => ImplTraitPosition :: ClosureReturn ,
1548- FnDeclKind :: Pointer => ImplTraitPosition :: PointerReturn ,
1549- FnDeclKind :: Trait => ImplTraitPosition :: TraitReturn ,
1550- FnDeclKind :: Impl => ImplTraitPosition :: ImplReturn ,
1551- } ) ,
1552- } ;
1553- hir:: FnRetTy :: Return ( self . lower_ty ( ty, context) )
1554- }
1576+ FnRetTy :: Ty ( ref ty) => hir:: FnRetTy :: Return ( self . lower_ty ( ty, context) ) ,
15551577 FnRetTy :: Default ( span) => hir:: FnRetTy :: DefaultReturn ( self . lower_span ( span) ) ,
15561578 }
15571579 } ;
@@ -1603,6 +1625,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16031625 output : & FnRetTy ,
16041626 fn_node_id : NodeId ,
16051627 opaque_ty_node_id : NodeId ,
1628+ mut itctx : ImplTraitContext < ' _ , ' hir > ,
16061629 ) -> hir:: FnRetTy < ' hir > {
16071630 let span = output. span ( ) ;
16081631
@@ -1765,7 +1788,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17651788 self . arena . alloc_from_iter ( captures. into_iter ( ) . map ( |( _, ( span, _, p_name, res) ) | {
17661789 let id = self . resolver . next_node_id ( ) ;
17671790 let ident = Ident :: new ( p_name. ident ( ) . name , span) ;
1768- let l = self . new_named_lifetime_with_res ( id, span, ident, res) ;
1791+ let l = self . new_named_lifetime_with_res ( id, span, ident, res, itctx . reborrow ( ) ) ;
17691792 hir:: GenericArg :: Lifetime ( l)
17701793 } ) ) ;
17711794
@@ -1794,6 +1817,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17941817 // generates.
17951818 let context = ImplTraitContext :: ReturnPositionOpaqueTy {
17961819 origin : hir:: OpaqueTyOrigin :: FnReturn ( fn_def_id) ,
1820+ nested : None ,
17971821 } ;
17981822 self . lower_ty ( ty, context)
17991823 }
@@ -1828,19 +1852,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18281852 self . lower_trait_bound_modifier ( * modifier) ,
18291853 ) ,
18301854 GenericBound :: Outlives ( lifetime) => {
1831- hir:: GenericBound :: Outlives ( self . lower_lifetime ( lifetime) )
1855+ hir:: GenericBound :: Outlives ( self . lower_lifetime ( lifetime, itctx ) )
18321856 }
18331857 }
18341858 }
18351859
1836- fn lower_lifetime ( & mut self , l : & Lifetime ) -> hir:: Lifetime {
1860+ fn lower_lifetime ( & mut self , l : & Lifetime , itctx : ImplTraitContext < ' _ , ' hir > ) -> hir:: Lifetime {
18371861 let span = self . lower_span ( l. ident . span ) ;
18381862 let ident = self . lower_ident ( l. ident ) ;
18391863 let res = self
18401864 . resolver
18411865 . get_lifetime_res ( l. id )
18421866 . unwrap_or_else ( || panic ! ( "Missing resolution for lifetime {:?} at {:?}" , l, span) ) ;
1843- self . new_named_lifetime_with_res ( l. id , span, ident, res)
1867+ self . new_named_lifetime_with_res ( l. id , span, ident, res, itctx )
18441868 }
18451869
18461870 #[ tracing:: instrument( level = "debug" , skip( self ) ) ]
@@ -1850,6 +1874,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18501874 span : Span ,
18511875 ident : Ident ,
18521876 res : LifetimeRes ,
1877+ itctx : ImplTraitContext < ' _ , ' hir > ,
18531878 ) -> hir:: Lifetime {
18541879 debug ! ( ?self . captured_lifetimes) ;
18551880 let name = match res {
@@ -1858,21 +1883,40 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18581883 let p_name = ParamName :: Plain ( ident) ;
18591884 if let Some ( LifetimeCaptureContext { parent_def_id, captures, binders_to_ignore } ) =
18601885 & mut self . captured_lifetimes
1861- && !binders_to_ignore. contains ( & binder)
18621886 {
1863- match captures. entry ( param) {
1864- Entry :: Occupied ( _) => { }
1865- Entry :: Vacant ( v) => {
1866- let p_id = self . resolver . next_node_id ( ) ;
1867- self . resolver . create_def (
1868- * parent_def_id,
1869- p_id,
1870- DefPathData :: LifetimeNs ( p_name. ident ( ) . name ) ,
1871- ExpnId :: root ( ) ,
1872- span. with_parent ( None ) ,
1873- ) ;
1887+ if binders_to_ignore. contains ( & binder) {
1888+ match itctx {
1889+ ImplTraitContext :: ReturnPositionOpaqueTy {
1890+ nested : Some ( true ) , ..
1891+ }
1892+ | ImplTraitContext :: TypeAliasesOpaqueTy => {
1893+ let mut err = self . sess . struct_span_err (
1894+ span,
1895+ "higher kinded lifetime bounds on nested opaque types are not supported yet" ,
1896+ ) ;
1897+ if let Some ( & ( span, _, _, _) ) = captures. get ( & param) {
1898+ err. span_note ( span, "lifetime declared here" ) ;
1899+ }
1900+ err. help ( "See https://github.com/rust-lang/rust/issues/96194 for further details" ) ;
1901+ err. emit ( ) ;
1902+ }
1903+ _ => { }
1904+ }
1905+ } else {
1906+ match captures. entry ( param) {
1907+ Entry :: Occupied ( _) => { }
1908+ Entry :: Vacant ( v) => {
1909+ let p_id = self . resolver . next_node_id ( ) ;
1910+ self . resolver . create_def (
1911+ * parent_def_id,
1912+ p_id,
1913+ DefPathData :: LifetimeNs ( p_name. ident ( ) . name ) ,
1914+ ExpnId :: root ( ) ,
1915+ span. with_parent ( None ) ,
1916+ ) ;
18741917
1875- v. insert ( ( span, p_id, p_name, res) ) ;
1918+ v. insert ( ( span, p_id, p_name, res) ) ;
1919+ }
18761920 }
18771921 }
18781922 }
0 commit comments