@@ -1358,7 +1358,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1358
1358
}
1359
1359
ImplTraitContext :: InTrait => {
1360
1360
// FIXME(RPITIT): Should we use def_node_id here?
1361
- self . lower_impl_trait_in_trait ( span, def_node_id, bounds)
1361
+ self . lower_impl_trait_in_trait ( span, def_node_id, |lctx| {
1362
+ lctx. lower_param_bounds (
1363
+ bounds,
1364
+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: Trait ) ,
1365
+ )
1366
+ } )
1362
1367
}
1363
1368
ImplTraitContext :: Universal => {
1364
1369
let span = t. span ;
@@ -1546,19 +1551,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1546
1551
hir:: TyKind :: OpaqueDef ( hir:: ItemId { def_id : opaque_ty_def_id } , lifetimes)
1547
1552
}
1548
1553
1549
- #[ tracing :: instrument( level = "debug" , skip( self ) ) ]
1554
+ #[ instrument( level = "debug" , skip( self , lower_bounds ) ) ]
1550
1555
fn lower_impl_trait_in_trait (
1551
1556
& mut self ,
1552
1557
span : Span ,
1553
1558
opaque_ty_node_id : NodeId ,
1554
- bounds : & GenericBounds ,
1559
+ lower_bounds : impl FnOnce ( & mut Self ) -> hir :: GenericBounds < ' hir > ,
1555
1560
) -> hir:: TyKind < ' hir > {
1556
1561
let opaque_ty_def_id = self . local_def_id ( opaque_ty_node_id) ;
1557
1562
self . with_hir_id_owner ( opaque_ty_node_id, |lctx| {
1558
1563
// FIXME(RPITIT): This should be a more descriptive ImplTraitPosition, i.e. nested RPITIT
1559
1564
// FIXME(RPITIT): We _also_ should support this eventually
1560
- let hir_bounds = lctx
1561
- . lower_param_bounds ( bounds, ImplTraitContext :: Disallowed ( ImplTraitPosition :: Trait ) ) ;
1565
+ let hir_bounds = lower_bounds ( lctx) ;
1562
1566
let rpitit_placeholder = hir:: ImplTraitPlaceholder { bounds : hir_bounds } ;
1563
1567
let rpitit_item = hir:: Item {
1564
1568
def_id : opaque_ty_def_id,
@@ -1719,18 +1723,44 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1719
1723
} ) ) ;
1720
1724
1721
1725
let output = if let Some ( ( ret_id, span) ) = make_ret_async {
1722
- if !self . tcx . features ( ) . return_position_impl_trait_in_trait {
1723
- self . tcx . sess . emit_feature_err (
1724
- TraitFnAsync { fn_span, span } ,
1725
- sym:: return_position_impl_trait_in_trait,
1726
- ) ;
1726
+ match kind {
1727
+ FnDeclKind :: Trait => {
1728
+ if !kind. impl_trait_in_trait_allowed ( self . tcx ) {
1729
+ self . tcx
1730
+ . sess
1731
+ . create_feature_err (
1732
+ TraitFnAsync { fn_span, span } ,
1733
+ sym:: return_position_impl_trait_in_trait,
1734
+ )
1735
+ . emit ( ) ;
1736
+ }
1737
+ self . lower_async_fn_ret_ty_in_trait (
1738
+ & decl. output ,
1739
+ fn_node_id. expect ( "`make_ret_async` but no `fn_def_id`" ) ,
1740
+ ret_id,
1741
+ )
1742
+ }
1743
+ _ => {
1744
+ if !kind. impl_trait_return_allowed ( self . tcx ) {
1745
+ if kind == FnDeclKind :: Impl {
1746
+ self . tcx
1747
+ . sess
1748
+ . create_feature_err (
1749
+ TraitFnAsync { fn_span, span } ,
1750
+ sym:: return_position_impl_trait_in_trait,
1751
+ )
1752
+ . emit ( ) ;
1753
+ } else {
1754
+ self . tcx . sess . emit_err ( TraitFnAsync { fn_span, span } ) ;
1755
+ }
1756
+ }
1757
+ self . lower_async_fn_ret_ty (
1758
+ & decl. output ,
1759
+ fn_node_id. expect ( "`make_ret_async` but no `fn_def_id`" ) ,
1760
+ ret_id,
1761
+ )
1762
+ }
1727
1763
}
1728
-
1729
- self . lower_async_fn_ret_ty (
1730
- & decl. output ,
1731
- fn_node_id. expect ( "`make_ret_async` but no `fn_def_id`" ) ,
1732
- ret_id,
1733
- )
1734
1764
} else {
1735
1765
match decl. output {
1736
1766
FnRetTy :: Ty ( ref ty) => {
@@ -2020,6 +2050,36 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2020
2050
hir:: FnRetTy :: Return ( self . arena . alloc ( opaque_ty) )
2021
2051
}
2022
2052
2053
+ // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
2054
+ // combined with the following definition of `OpaqueTy`:
2055
+ //
2056
+ // type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
2057
+ //
2058
+ // `output`: unlowered output type (`T` in `-> T`)
2059
+ // `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
2060
+ // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
2061
+ #[ instrument( level = "debug" , skip( self ) ) ]
2062
+ fn lower_async_fn_ret_ty_in_trait (
2063
+ & mut self ,
2064
+ output : & FnRetTy ,
2065
+ fn_node_id : NodeId ,
2066
+ opaque_ty_node_id : NodeId ,
2067
+ ) -> hir:: FnRetTy < ' hir > {
2068
+ let span = output. span ( ) ;
2069
+
2070
+ let opaque_ty_span = self . mark_span_with_reason ( DesugaringKind :: Async , span, None ) ;
2071
+
2072
+ let fn_def_id = self . local_def_id ( fn_node_id) ;
2073
+
2074
+ let kind = self . lower_impl_trait_in_trait ( output. span ( ) , opaque_ty_node_id, |lctx| {
2075
+ let bound =
2076
+ lctx. lower_async_fn_output_type_to_future_bound ( output, fn_def_id, output. span ( ) ) ;
2077
+ arena_vec ! [ lctx; bound]
2078
+ } ) ;
2079
+ let opaque_ty = self . ty ( opaque_ty_span, kind) ;
2080
+ hir:: FnRetTy :: Return ( self . arena . alloc ( opaque_ty) )
2081
+ }
2082
+
2023
2083
/// Transforms `-> T` into `Future<Output = T>`.
2024
2084
fn lower_async_fn_output_type_to_future_bound (
2025
2085
& mut self ,
0 commit comments