@@ -620,6 +620,15 @@ impl UserIdentifiedItem {
620620}
621621
622622// Note: Also used by librustdoc, see PR #43348. Consider moving this struct elsewhere.
623+ //
624+ // FIXME: Currently the `everybody_loops` transformation is not applied to:
625+ // * `const fn`, due to issue #43636 that `loop` is not supported for const evaluation. We are
626+ // waiting for miri to fix that.
627+ // * `impl Trait`, due to issue #43869 that functions returning impl Trait cannot be diverging.
628+ // Solving this may require `!` to implement every trait, which relies on the an even more
629+ // ambitious form of the closed RFC #1637. See also [#34511].
630+ //
631+ // [#34511]: https://github.com/rust-lang/rust/issues/34511#issuecomment-322340401
623632pub struct ReplaceBodyWithLoop {
624633 within_static_or_const : bool ,
625634}
@@ -635,14 +644,34 @@ impl ReplaceBodyWithLoop {
635644 self . within_static_or_const = old_const;
636645 ret
637646 }
647+
648+ fn should_ignore_fn ( ret_ty : & ast:: FnDecl ) -> bool {
649+ if let ast:: FunctionRetTy :: Ty ( ref ty) = ret_ty. output {
650+ fn involves_impl_trait ( ty : & ast:: Ty ) -> bool {
651+ match ty. node {
652+ ast:: TyKind :: ImplTrait ( _) => true ,
653+ ast:: TyKind :: Slice ( ref subty) |
654+ ast:: TyKind :: Array ( ref subty, _) |
655+ ast:: TyKind :: Ptr ( ast:: MutTy { ty : ref subty, .. } ) |
656+ ast:: TyKind :: Rptr ( _, ast:: MutTy { ty : ref subty, .. } ) |
657+ ast:: TyKind :: Paren ( ref subty) => involves_impl_trait ( subty) ,
658+ ast:: TyKind :: Tup ( ref tys) => tys. iter ( ) . any ( |subty| involves_impl_trait ( subty) ) ,
659+ _ => false ,
660+ }
661+ }
662+ involves_impl_trait ( ty)
663+ } else {
664+ false
665+ }
666+ }
638667}
639668
640669impl fold:: Folder for ReplaceBodyWithLoop {
641670 fn fold_item_kind ( & mut self , i : ast:: ItemKind ) -> ast:: ItemKind {
642671 let is_const = match i {
643672 ast:: ItemKind :: Static ( ..) | ast:: ItemKind :: Const ( ..) => true ,
644- ast:: ItemKind :: Fn ( _ , _, ref constness, _, _, _) =>
645- constness. node == ast:: Constness :: Const ,
673+ ast:: ItemKind :: Fn ( ref decl , _, ref constness, _, _, _) =>
674+ constness. node == ast:: Constness :: Const || Self :: should_ignore_fn ( decl ) ,
646675 _ => false ,
647676 } ;
648677 self . run ( is_const, |s| fold:: noop_fold_item_kind ( i, s) )
@@ -651,8 +680,8 @@ impl fold::Folder for ReplaceBodyWithLoop {
651680 fn fold_trait_item ( & mut self , i : ast:: TraitItem ) -> SmallVector < ast:: TraitItem > {
652681 let is_const = match i. node {
653682 ast:: TraitItemKind :: Const ( ..) => true ,
654- ast:: TraitItemKind :: Method ( ast:: MethodSig { ref constness, .. } , _) =>
655- constness. node == ast:: Constness :: Const ,
683+ ast:: TraitItemKind :: Method ( ast:: MethodSig { ref decl , ref constness, .. } , _) =>
684+ constness. node == ast:: Constness :: Const || Self :: should_ignore_fn ( decl ) ,
656685 _ => false ,
657686 } ;
658687 self . run ( is_const, |s| fold:: noop_fold_trait_item ( i, s) )
@@ -661,8 +690,8 @@ impl fold::Folder for ReplaceBodyWithLoop {
661690 fn fold_impl_item ( & mut self , i : ast:: ImplItem ) -> SmallVector < ast:: ImplItem > {
662691 let is_const = match i. node {
663692 ast:: ImplItemKind :: Const ( ..) => true ,
664- ast:: ImplItemKind :: Method ( ast:: MethodSig { ref constness, .. } , _) =>
665- constness. node == ast:: Constness :: Const ,
693+ ast:: ImplItemKind :: Method ( ast:: MethodSig { ref decl , ref constness, .. } , _) =>
694+ constness. node == ast:: Constness :: Const || Self :: should_ignore_fn ( decl ) ,
666695 _ => false ,
667696 } ;
668697 self . run ( is_const, |s| fold:: noop_fold_impl_item ( i, s) )
0 commit comments