@@ -620,6 +620,15 @@ impl UserIdentifiedItem {
620
620
}
621
621
622
622
// 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
623
632
pub struct ReplaceBodyWithLoop {
624
633
within_static_or_const : bool ,
625
634
}
@@ -635,14 +644,34 @@ impl ReplaceBodyWithLoop {
635
644
self . within_static_or_const = old_const;
636
645
ret
637
646
}
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
+ }
638
667
}
639
668
640
669
impl fold:: Folder for ReplaceBodyWithLoop {
641
670
fn fold_item_kind ( & mut self , i : ast:: ItemKind ) -> ast:: ItemKind {
642
671
let is_const = match i {
643
672
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 ) ,
646
675
_ => false ,
647
676
} ;
648
677
self . run ( is_const, |s| fold:: noop_fold_item_kind ( i, s) )
@@ -651,8 +680,8 @@ impl fold::Folder for ReplaceBodyWithLoop {
651
680
fn fold_trait_item ( & mut self , i : ast:: TraitItem ) -> SmallVector < ast:: TraitItem > {
652
681
let is_const = match i. node {
653
682
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 ) ,
656
685
_ => false ,
657
686
} ;
658
687
self . run ( is_const, |s| fold:: noop_fold_trait_item ( i, s) )
@@ -661,8 +690,8 @@ impl fold::Folder for ReplaceBodyWithLoop {
661
690
fn fold_impl_item ( & mut self , i : ast:: ImplItem ) -> SmallVector < ast:: ImplItem > {
662
691
let is_const = match i. node {
663
692
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 ) ,
666
695
_ => false ,
667
696
} ;
668
697
self . run ( is_const, |s| fold:: noop_fold_impl_item ( i, s) )
0 commit comments