@@ -255,6 +255,8 @@ enum ImplTraitContext {
255255 } ,
256256 /// Impl trait in type aliases.
257257 TypeAliasesOpaqueTy ,
258+ /// Return-position `impl Trait` in trait definition
259+ InTrait ,
258260 /// `impl Trait` is not accepted in this position.
259261 Disallowed ( ImplTraitPosition ) ,
260262}
@@ -323,9 +325,17 @@ enum FnDeclKind {
323325}
324326
325327impl FnDeclKind {
326- fn impl_trait_return_allowed ( & self ) -> bool {
328+ fn impl_trait_return_allowed ( & self , tcx : TyCtxt < ' _ > ) -> bool {
327329 match self {
328330 FnDeclKind :: Fn | FnDeclKind :: Inherent => true ,
331+ FnDeclKind :: Impl if tcx. features ( ) . return_position_impl_trait_in_trait => true ,
332+ _ => false ,
333+ }
334+ }
335+
336+ fn impl_trait_in_trait_allowed ( & self , tcx : TyCtxt < ' _ > ) -> bool {
337+ match self {
338+ FnDeclKind :: Trait if tcx. features ( ) . return_position_impl_trait_in_trait => true ,
329339 _ => false ,
330340 }
331341 }
@@ -1346,6 +1356,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13461356 & mut nested_itctx,
13471357 )
13481358 }
1359+ ImplTraitContext :: InTrait => {
1360+ // FIXME(RPITIT): Should we use def_node_id here?
1361+ self . lower_impl_trait_in_trait ( span, def_node_id, bounds)
1362+ }
13491363 ImplTraitContext :: Universal => {
13501364 let span = t. span ;
13511365 let ident = Ident :: from_str_and_span ( & pprust:: ty_to_string ( t) , span) ;
@@ -1532,6 +1546,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15321546 hir:: TyKind :: OpaqueDef ( hir:: ItemId { def_id : opaque_ty_def_id } , lifetimes)
15331547 }
15341548
1549+ #[ tracing:: instrument( level = "debug" , skip( self ) ) ]
1550+ fn lower_impl_trait_in_trait (
1551+ & mut self ,
1552+ span : Span ,
1553+ opaque_ty_node_id : NodeId ,
1554+ bounds : & GenericBounds ,
1555+ ) -> hir:: TyKind < ' hir > {
1556+ let opaque_ty_def_id = self . local_def_id ( opaque_ty_node_id) ;
1557+ self . with_hir_id_owner ( opaque_ty_node_id, |lctx| {
1558+ // FIXME(RPITIT): This should be a more descriptive ImplTraitPosition, i.e. nested RPITIT
1559+ // FIXME(RPITIT): We _also_ should support this eventually
1560+ let hir_bounds = lctx
1561+ . lower_param_bounds ( bounds, ImplTraitContext :: Disallowed ( ImplTraitPosition :: Trait ) ) ;
1562+ let rpitit_placeholder = hir:: ImplTraitPlaceholder { bounds : hir_bounds } ;
1563+ let rpitit_item = hir:: Item {
1564+ def_id : opaque_ty_def_id,
1565+ ident : Ident :: empty ( ) ,
1566+ kind : hir:: ItemKind :: ImplTraitPlaceholder ( rpitit_placeholder) ,
1567+ span : lctx. lower_span ( span) ,
1568+ vis_span : lctx. lower_span ( span. shrink_to_lo ( ) ) ,
1569+ } ;
1570+ hir:: OwnerNode :: Item ( lctx. arena . alloc ( rpitit_item) )
1571+ } ) ;
1572+ hir:: TyKind :: ImplTraitInTrait ( hir:: ItemId { def_id : opaque_ty_def_id } )
1573+ }
1574+
15351575 /// Registers a new opaque type with the proper `NodeId`s and
15361576 /// returns the lowered node-ID for the opaque type.
15371577 fn generate_opaque_type (
@@ -1690,12 +1730,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16901730 match decl. output {
16911731 FnRetTy :: Ty ( ref ty) => {
16921732 let mut context = match fn_node_id {
1693- Some ( fn_node_id) if kind. impl_trait_return_allowed ( ) => {
1733+ Some ( fn_node_id) if kind. impl_trait_return_allowed ( self . tcx ) => {
16941734 let fn_def_id = self . local_def_id ( fn_node_id) ;
16951735 ImplTraitContext :: ReturnPositionOpaqueTy {
16961736 origin : hir:: OpaqueTyOrigin :: FnReturn ( fn_def_id) ,
16971737 }
16981738 }
1739+ Some ( _) if kind. impl_trait_in_trait_allowed ( self . tcx ) => {
1740+ ImplTraitContext :: InTrait
1741+ }
16991742 _ => ImplTraitContext :: Disallowed ( match kind {
17001743 FnDeclKind :: Fn | FnDeclKind :: Inherent => {
17011744 unreachable ! ( "fn should allow in-band lifetimes" )
0 commit comments