@@ -1358,7 +1358,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13581358 }
13591359 ImplTraitContext :: InTrait => {
13601360 // 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+ } )
13621367 }
13631368 ImplTraitContext :: Universal => {
13641369 let span = t. span ;
@@ -1546,19 +1551,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15461551 hir:: TyKind :: OpaqueDef ( hir:: ItemId { def_id : opaque_ty_def_id } , lifetimes)
15471552 }
15481553
1549- #[ tracing :: instrument( level = "debug" , skip( self ) ) ]
1554+ #[ instrument( level = "debug" , skip( self , lower_bounds ) ) ]
15501555 fn lower_impl_trait_in_trait (
15511556 & mut self ,
15521557 span : Span ,
15531558 opaque_ty_node_id : NodeId ,
1554- bounds : & GenericBounds ,
1559+ lower_bounds : impl FnOnce ( & mut Self ) -> hir :: GenericBounds < ' hir > ,
15551560 ) -> hir:: TyKind < ' hir > {
15561561 let opaque_ty_def_id = self . local_def_id ( opaque_ty_node_id) ;
15571562 self . with_hir_id_owner ( opaque_ty_node_id, |lctx| {
15581563 // FIXME(RPITIT): This should be a more descriptive ImplTraitPosition, i.e. nested RPITIT
15591564 // 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) ;
15621566 let rpitit_placeholder = hir:: ImplTraitPlaceholder { bounds : hir_bounds } ;
15631567 let rpitit_item = hir:: Item {
15641568 def_id : opaque_ty_def_id,
@@ -1719,18 +1723,44 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17191723 } ) ) ;
17201724
17211725 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+ }
17271763 }
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- )
17341764 } else {
17351765 match decl. output {
17361766 FnRetTy :: Ty ( ref ty) => {
@@ -2020,6 +2050,36 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20202050 hir:: FnRetTy :: Return ( self . arena . alloc ( opaque_ty) )
20212051 }
20222052
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+
20232083 /// Transforms `-> T` into `Future<Output = T>`.
20242084 fn lower_async_fn_output_type_to_future_bound (
20252085 & mut self ,
0 commit comments