@@ -255,6 +255,8 @@ enum ImplTraitContext {
255
255
} ,
256
256
/// Impl trait in type aliases.
257
257
TypeAliasesOpaqueTy ,
258
+ /// Return-position `impl Trait` in trait definition
259
+ InTrait ,
258
260
/// `impl Trait` is not accepted in this position.
259
261
Disallowed ( ImplTraitPosition ) ,
260
262
}
@@ -323,9 +325,17 @@ enum FnDeclKind {
323
325
}
324
326
325
327
impl FnDeclKind {
326
- fn impl_trait_return_allowed ( & self ) -> bool {
328
+ fn impl_trait_return_allowed ( & self , tcx : TyCtxt < ' _ > ) -> bool {
327
329
match self {
328
330
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 ,
329
339
_ => false ,
330
340
}
331
341
}
@@ -1346,6 +1356,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1346
1356
& mut nested_itctx,
1347
1357
)
1348
1358
}
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
+ }
1349
1363
ImplTraitContext :: Universal => {
1350
1364
let span = t. span ;
1351
1365
let ident = Ident :: from_str_and_span ( & pprust:: ty_to_string ( t) , span) ;
@@ -1532,6 +1546,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1532
1546
hir:: TyKind :: OpaqueDef ( hir:: ItemId { def_id : opaque_ty_def_id } , lifetimes)
1533
1547
}
1534
1548
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
+
1535
1575
/// Registers a new opaque type with the proper `NodeId`s and
1536
1576
/// returns the lowered node-ID for the opaque type.
1537
1577
fn generate_opaque_type (
@@ -1690,12 +1730,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1690
1730
match decl. output {
1691
1731
FnRetTy :: Ty ( ref ty) => {
1692
1732
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 ) => {
1694
1734
let fn_def_id = self . local_def_id ( fn_node_id) ;
1695
1735
ImplTraitContext :: ReturnPositionOpaqueTy {
1696
1736
origin : hir:: OpaqueTyOrigin :: FnReturn ( fn_def_id) ,
1697
1737
}
1698
1738
}
1739
+ Some ( _) if kind. impl_trait_in_trait_allowed ( self . tcx ) => {
1740
+ ImplTraitContext :: InTrait
1741
+ }
1699
1742
_ => ImplTraitContext :: Disallowed ( match kind {
1700
1743
FnDeclKind :: Fn | FnDeclKind :: Inherent => {
1701
1744
unreachable ! ( "fn should allow in-band lifetimes" )
0 commit comments