about summary refs log tree commit diff
path: root/src/tools/rustfmt
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-06-20 13:42:37 -0400
committerMichael Goulet <michael@errs.io>2024-06-23 10:57:10 -0400
commita426d6fdf020ac0ae54d8bf11924907d3a225116 (patch)
tree11ad6119489a2442ab2d1a977309634594925506 /src/tools/rustfmt
parentc3d7fb398569407350abe044e786bc7890c90397 (diff)
downloadrust-a426d6fdf020ac0ae54d8bf11924907d3a225116.tar.gz
rust-a426d6fdf020ac0ae54d8bf11924907d3a225116.zip
Implement use<> formatting in rustfmt
Diffstat (limited to 'src/tools/rustfmt')
-rw-r--r--src/tools/rustfmt/src/overflow.rs15
-rw-r--r--src/tools/rustfmt/src/spanned.rs9
-rw-r--r--src/tools/rustfmt/src/types.rs26
-rw-r--r--src/tools/rustfmt/tests/source/precise-capturing.rs9
-rw-r--r--src/tools/rustfmt/tests/target/precise-capturing.rs55
5 files changed, 105 insertions, 9 deletions
diff --git a/src/tools/rustfmt/src/overflow.rs b/src/tools/rustfmt/src/overflow.rs
index c44f3788d97..a1de71a35be 100644
--- a/src/tools/rustfmt/src/overflow.rs
+++ b/src/tools/rustfmt/src/overflow.rs
@@ -83,6 +83,7 @@ pub(crate) enum OverflowableItem<'a> {
     TuplePatField(&'a TuplePatField<'a>),
     Ty(&'a ast::Ty),
     Pat(&'a ast::Pat),
+    PreciseCapturingArg(&'a ast::PreciseCapturingArg),
 }
 
 impl<'a> Rewrite for OverflowableItem<'a> {
@@ -123,6 +124,7 @@ impl<'a> OverflowableItem<'a> {
             OverflowableItem::TuplePatField(pat) => f(*pat),
             OverflowableItem::Ty(ty) => f(*ty),
             OverflowableItem::Pat(pat) => f(*pat),
+            OverflowableItem::PreciseCapturingArg(arg) => f(*arg),
         }
     }
 
@@ -137,6 +139,9 @@ impl<'a> OverflowableItem<'a> {
                     matches!(meta_item.kind, ast::MetaItemKind::Word)
                 }
             },
+            // FIXME: Why don't we consider `SegmentParam` to be simple?
+            // FIXME: If we also fix `SegmentParam`, then we should apply the same
+            // heuristic to `PreciseCapturingArg`.
             _ => false,
         }
     }
@@ -244,7 +249,15 @@ macro_rules! impl_into_overflowable_item_for_rustfmt_types {
     }
 }
 
-impl_into_overflowable_item_for_ast_node!(Expr, GenericParam, NestedMetaItem, FieldDef, Ty, Pat);
+impl_into_overflowable_item_for_ast_node!(
+    Expr,
+    GenericParam,
+    NestedMetaItem,
+    FieldDef,
+    Ty,
+    Pat,
+    PreciseCapturingArg
+);
 impl_into_overflowable_item_for_rustfmt_types!([MacroArg], [SegmentParam, TuplePatField]);
 
 pub(crate) fn into_overflowable_list<'a, T>(
diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs
index 28911f8af1d..1ee691b4ade 100644
--- a/src/tools/rustfmt/src/spanned.rs
+++ b/src/tools/rustfmt/src/spanned.rs
@@ -203,3 +203,12 @@ impl Spanned for ast::NestedMetaItem {
         self.span()
     }
 }
+
+impl Spanned for ast::PreciseCapturingArg {
+    fn span(&self) -> Span {
+        match self {
+            ast::PreciseCapturingArg::Lifetime(lt) => lt.ident.span,
+            ast::PreciseCapturingArg::Arg(path, _) => path.span,
+        }
+    }
+}
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index c12f271bc5d..c0bf9482b11 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -177,6 +177,17 @@ impl<'a> Rewrite for SegmentParam<'a> {
     }
 }
 
+impl Rewrite for ast::PreciseCapturingArg {
+    fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        match self {
+            ast::PreciseCapturingArg::Lifetime(lt) => lt.rewrite(context, shape),
+            ast::PreciseCapturingArg::Arg(p, _) => {
+                rewrite_path(context, PathContext::Type, &None, p, shape)
+            }
+        }
+    }
+}
+
 impl Rewrite for ast::AssocItemConstraint {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
         use ast::AssocItemConstraintKind::{Bound, Equality};
@@ -564,9 +575,10 @@ impl Rewrite for ast::GenericBound {
                     .map(|s| format!("{constness}{asyncness}{polarity}{s}"))
                     .map(|s| if has_paren { format!("({})", s) } else { s })
             }
+            ast::GenericBound::Use(ref args, span) => {
+                overflow::rewrite_with_angle_brackets(context, "use", args.iter(), shape, span)
+            }
             ast::GenericBound::Outlives(ref lifetime) => lifetime.rewrite(context, shape),
-            // FIXME(precise_capturing): Should implement formatting before stabilization.
-            ast::GenericBound::Use(..) => None,
         }
     }
 }
@@ -933,9 +945,7 @@ fn rewrite_bare_fn(
 fn is_generic_bounds_in_order(generic_bounds: &[ast::GenericBound]) -> bool {
     let is_trait = |b: &ast::GenericBound| match b {
         ast::GenericBound::Outlives(..) => false,
-        ast::GenericBound::Trait(..) => true,
-        // FIXME(precise_capturing): This ordering fn should be reworked.
-        ast::GenericBound::Use(..) => false,
+        ast::GenericBound::Trait(..) | ast::GenericBound::Use(..) => true,
     };
     let is_lifetime = |b: &ast::GenericBound| !is_trait(b);
     let last_trait_index = generic_bounds.iter().rposition(is_trait);
@@ -969,9 +979,8 @@ fn join_bounds_inner(
     let generic_bounds_in_order = is_generic_bounds_in_order(items);
     let is_bound_extendable = |s: &str, b: &ast::GenericBound| match b {
         ast::GenericBound::Outlives(..) => true,
-        ast::GenericBound::Trait(..) => last_line_extendable(s),
-        // FIXME(precise_capturing): This ordering fn should be reworked.
-        ast::GenericBound::Use(..) => true,
+        // We treat `use<>` like a trait bound here.
+        ast::GenericBound::Trait(..) | ast::GenericBound::Use(..) => last_line_extendable(s),
     };
 
     // Whether a GenericBound item is a PathSegment segment that includes internal array
@@ -993,6 +1002,7 @@ fn join_bounds_inner(
                 }
             }
         }
+        ast::GenericBound::Use(args, _) => args.len() > 1,
         _ => false,
     };
 
diff --git a/src/tools/rustfmt/tests/source/precise-capturing.rs b/src/tools/rustfmt/tests/source/precise-capturing.rs
new file mode 100644
index 00000000000..b61cceeffe8
--- /dev/null
+++ b/src/tools/rustfmt/tests/source/precise-capturing.rs
@@ -0,0 +1,9 @@
+fn hello() -> impl
+use<'a> + Sized {}
+
+fn all_three() -> impl Sized + use<'a> + 'a;
+
+fn pathological() -> impl use<'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a,
+'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a,
+'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 
+'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a> + Sized {}
diff --git a/src/tools/rustfmt/tests/target/precise-capturing.rs b/src/tools/rustfmt/tests/target/precise-capturing.rs
new file mode 100644
index 00000000000..d21374f44c1
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/precise-capturing.rs
@@ -0,0 +1,55 @@
+fn hello() -> impl use<'a> + Sized {}
+
+fn all_three() -> impl Sized + use<'a> + 'a;
+
+fn pathological() -> impl use<
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+    'a,
+> + Sized {
+}