@@ -267,6 +267,9 @@ enum ImplTraitContext<'b, 'a> {
267
267
ReturnPositionOpaqueTy {
268
268
/// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
269
269
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 > ,
270
273
} ,
271
274
/// Impl trait in type aliases.
272
275
TypeAliasesOpaqueTy ,
@@ -303,7 +306,9 @@ impl<'a> ImplTraitContext<'_, 'a> {
303
306
use self :: ImplTraitContext :: * ;
304
307
match self {
305
308
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
+ }
307
312
TypeAliasesOpaqueTy => TypeAliasesOpaqueTy ,
308
313
Disallowed ( pos) => Disallowed ( * pos) ,
309
314
}
@@ -1072,7 +1077,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1072
1077
itctx : ImplTraitContext < ' _ , ' hir > ,
1073
1078
) -> hir:: GenericArg < ' hir > {
1074
1079
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 ) ) ,
1076
1081
ast:: GenericArg :: Type ( ty) => {
1077
1082
match ty. kind {
1078
1083
TyKind :: Infer if self . sess . features_untracked ( ) . generic_arg_infer => {
@@ -1179,7 +1184,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1179
1184
id : start,
1180
1185
}
1181
1186
} ) ;
1182
- let lifetime = self . lower_lifetime ( & region) ;
1187
+ let lifetime = self . lower_lifetime ( & region, itctx . reborrow ( ) ) ;
1183
1188
hir:: TyKind :: Rptr ( lifetime, self . lower_mt ( mt, itctx) )
1184
1189
}
1185
1190
TyKind :: BareFn ( ref f) => self . with_lifetime_binder ( t. id , |this| {
@@ -1239,7 +1244,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1239
1244
) => None ,
1240
1245
GenericBound :: Outlives ( ref lifetime) => {
1241
1246
if lifetime_bound. is_none ( ) {
1242
- lifetime_bound = Some ( this. lower_lifetime ( lifetime) ) ;
1247
+ lifetime_bound =
1248
+ Some ( this. lower_lifetime ( lifetime, itctx. reborrow ( ) ) ) ;
1243
1249
}
1244
1250
None
1245
1251
}
@@ -1254,17 +1260,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1254
1260
TyKind :: ImplTrait ( def_node_id, ref bounds) => {
1255
1261
let span = t. span ;
1256
1262
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
+ ) ,
1261
1277
ImplTraitContext :: TypeAliasesOpaqueTy => {
1262
1278
let nested_itctx = ImplTraitContext :: TypeAliasesOpaqueTy ;
1263
1279
self . lower_opaque_impl_trait (
1264
1280
span,
1265
1281
hir:: OpaqueTyOrigin :: TyAlias ,
1266
1282
def_node_id,
1267
- |this| this. lower_param_bounds ( bounds, nested_itctx) ,
1283
+ |this, itctx| this. lower_param_bounds ( bounds, itctx) ,
1284
+ nested_itctx,
1268
1285
)
1269
1286
}
1270
1287
ImplTraitContext :: Universal (
@@ -1299,6 +1316,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1299
1316
& GenericParamKind :: Type { default : None } ,
1300
1317
hir_bounds,
1301
1318
hir:: PredicateOrigin :: ImplTrait ,
1319
+ ImplTraitContext :: Universal (
1320
+ in_band_ty_params,
1321
+ in_band_ty_bounds,
1322
+ parent_def_id,
1323
+ ) ,
1302
1324
) {
1303
1325
in_band_ty_bounds. push ( preds)
1304
1326
}
@@ -1344,7 +1366,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1344
1366
span : Span ,
1345
1367
origin : hir:: OpaqueTyOrigin ,
1346
1368
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 > ,
1348
1371
) -> hir:: TyKind < ' hir > {
1349
1372
// Make sure we know that some funky desugaring has been going on here.
1350
1373
// This is a first: there is code in other places like for loop
@@ -1358,13 +1381,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1358
1381
let mut collected_lifetimes = FxHashMap :: default ( ) ;
1359
1382
self . with_hir_id_owner ( opaque_ty_node_id, |lctx| {
1360
1383
let hir_bounds = if origin == hir:: OpaqueTyOrigin :: TyAlias {
1361
- lower_bounds ( lctx)
1384
+ lower_bounds ( lctx, itctx . reborrow ( ) )
1362
1385
} 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
+ } )
1368
1389
} ;
1369
1390
debug ! ( ?collected_lifetimes) ;
1370
1391
@@ -1412,7 +1433,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1412
1433
|( _, ( span, _, p_name, res) ) | {
1413
1434
let id = self . resolver . next_node_id ( ) ;
1414
1435
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 ( ) ) ;
1416
1437
hir:: GenericArg :: Lifetime ( l)
1417
1438
} ,
1418
1439
) ) ;
@@ -1523,35 +1544,36 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1523
1544
}
1524
1545
} ) ) ;
1525
1546
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
+
1526
1567
let output = if let Some ( ret_id) = make_ret_async {
1527
1568
self . lower_async_fn_ret_ty (
1528
1569
& decl. output ,
1529
1570
in_band_ty_params. expect ( "`make_ret_async` but no `fn_def_id`" ) . 0 ,
1530
1571
ret_id,
1572
+ context,
1531
1573
)
1532
1574
} else {
1533
1575
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) ) ,
1555
1577
FnRetTy :: Default ( span) => hir:: FnRetTy :: DefaultReturn ( self . lower_span ( span) ) ,
1556
1578
}
1557
1579
} ;
@@ -1603,6 +1625,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1603
1625
output : & FnRetTy ,
1604
1626
fn_node_id : NodeId ,
1605
1627
opaque_ty_node_id : NodeId ,
1628
+ mut itctx : ImplTraitContext < ' _ , ' hir > ,
1606
1629
) -> hir:: FnRetTy < ' hir > {
1607
1630
let span = output. span ( ) ;
1608
1631
@@ -1765,7 +1788,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1765
1788
self . arena . alloc_from_iter ( captures. into_iter ( ) . map ( |( _, ( span, _, p_name, res) ) | {
1766
1789
let id = self . resolver . next_node_id ( ) ;
1767
1790
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 ( ) ) ;
1769
1792
hir:: GenericArg :: Lifetime ( l)
1770
1793
} ) ) ;
1771
1794
@@ -1794,6 +1817,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1794
1817
// generates.
1795
1818
let context = ImplTraitContext :: ReturnPositionOpaqueTy {
1796
1819
origin : hir:: OpaqueTyOrigin :: FnReturn ( fn_def_id) ,
1820
+ nested : None ,
1797
1821
} ;
1798
1822
self . lower_ty ( ty, context)
1799
1823
}
@@ -1828,19 +1852,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1828
1852
self . lower_trait_bound_modifier ( * modifier) ,
1829
1853
) ,
1830
1854
GenericBound :: Outlives ( lifetime) => {
1831
- hir:: GenericBound :: Outlives ( self . lower_lifetime ( lifetime) )
1855
+ hir:: GenericBound :: Outlives ( self . lower_lifetime ( lifetime, itctx ) )
1832
1856
}
1833
1857
}
1834
1858
}
1835
1859
1836
- fn lower_lifetime ( & mut self , l : & Lifetime ) -> hir:: Lifetime {
1860
+ fn lower_lifetime ( & mut self , l : & Lifetime , itctx : ImplTraitContext < ' _ , ' hir > ) -> hir:: Lifetime {
1837
1861
let span = self . lower_span ( l. ident . span ) ;
1838
1862
let ident = self . lower_ident ( l. ident ) ;
1839
1863
let res = self
1840
1864
. resolver
1841
1865
. get_lifetime_res ( l. id )
1842
1866
. 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 )
1844
1868
}
1845
1869
1846
1870
#[ tracing:: instrument( level = "debug" , skip( self ) ) ]
@@ -1850,6 +1874,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1850
1874
span : Span ,
1851
1875
ident : Ident ,
1852
1876
res : LifetimeRes ,
1877
+ itctx : ImplTraitContext < ' _ , ' hir > ,
1853
1878
) -> hir:: Lifetime {
1854
1879
debug ! ( ?self . captured_lifetimes) ;
1855
1880
let name = match res {
@@ -1858,21 +1883,40 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1858
1883
let p_name = ParamName :: Plain ( ident) ;
1859
1884
if let Some ( LifetimeCaptureContext { parent_def_id, captures, binders_to_ignore } ) =
1860
1885
& mut self . captured_lifetimes
1861
- && !binders_to_ignore. contains ( & binder)
1862
1886
{
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
+ ) ;
1874
1917
1875
- v. insert ( ( span, p_id, p_name, res) ) ;
1918
+ v. insert ( ( span, p_id, p_name, res) ) ;
1919
+ }
1876
1920
}
1877
1921
}
1878
1922
}
0 commit comments