Rollup merge of #126754 - compiler-errors:use-rustfmt, r=calebcartwright
Implement `use<>` formatting in rustfmt This PR implements formatting for precise-capturing `use<>` syntax as proposed in https://github.com/rust-lang/rust/pull/126753. The syntax is implemented as-if the `use<>` bound were a trait bound but with the `use` keyword as its path segment identifier. I opted to develop this in the rust-lang/rust tree since I'm not certain when the next rustfmt subtree sync is going to be, and I'd rather not block landing nightly support for `use<>` on something I have no control over. If ``@rust-lang/rustfmt`` would rather I move this PR over to that repository, then I would at least like to know when the next rustfmt->rust subtree sync is going to be, since stabilizing `precise_capturing` without formatting will be disruptive. This implementation is otherwise rather straightforward. Tracking: - https://github.com/rust-lang/rust/issues/123432
This commit is contained in:
commit
bd0a886b7e
@ -83,6 +83,7 @@ pub(crate) enum OverflowableItem<'a> {
|
|||||||
TuplePatField(&'a TuplePatField<'a>),
|
TuplePatField(&'a TuplePatField<'a>),
|
||||||
Ty(&'a ast::Ty),
|
Ty(&'a ast::Ty),
|
||||||
Pat(&'a ast::Pat),
|
Pat(&'a ast::Pat),
|
||||||
|
PreciseCapturingArg(&'a ast::PreciseCapturingArg),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Rewrite for OverflowableItem<'a> {
|
impl<'a> Rewrite for OverflowableItem<'a> {
|
||||||
@ -123,6 +124,7 @@ pub(crate) fn map<F, T>(&self, f: F) -> T
|
|||||||
OverflowableItem::TuplePatField(pat) => f(*pat),
|
OverflowableItem::TuplePatField(pat) => f(*pat),
|
||||||
OverflowableItem::Ty(ty) => f(*ty),
|
OverflowableItem::Ty(ty) => f(*ty),
|
||||||
OverflowableItem::Pat(pat) => f(*pat),
|
OverflowableItem::Pat(pat) => f(*pat),
|
||||||
|
OverflowableItem::PreciseCapturingArg(arg) => f(*arg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,6 +139,9 @@ pub(crate) fn is_simple(&self) -> bool {
|
|||||||
matches!(meta_item.kind, ast::MetaItemKind::Word)
|
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,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,7 +249,15 @@ fn into_overflowable_item(&'a self) -> OverflowableItem<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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]);
|
impl_into_overflowable_item_for_rustfmt_types!([MacroArg], [SegmentParam, TuplePatField]);
|
||||||
|
|
||||||
pub(crate) fn into_overflowable_list<'a, T>(
|
pub(crate) fn into_overflowable_list<'a, T>(
|
||||||
|
@ -203,3 +203,12 @@ fn span(&self) -> Span {
|
|||||||
self.span()
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
26
src/types.rs
26
src/types.rs
@ -177,6 +177,17 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
impl Rewrite for ast::AssocItemConstraint {
|
||||||
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
|
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
|
||||||
use ast::AssocItemConstraintKind::{Bound, Equality};
|
use ast::AssocItemConstraintKind::{Bound, Equality};
|
||||||
@ -564,9 +575,10 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
|
|||||||
.map(|s| format!("{constness}{asyncness}{polarity}{s}"))
|
.map(|s| format!("{constness}{asyncness}{polarity}{s}"))
|
||||||
.map(|s| if has_paren { format!("({})", s) } else { 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),
|
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 {
|
fn is_generic_bounds_in_order(generic_bounds: &[ast::GenericBound]) -> bool {
|
||||||
let is_trait = |b: &ast::GenericBound| match b {
|
let is_trait = |b: &ast::GenericBound| match b {
|
||||||
ast::GenericBound::Outlives(..) => false,
|
ast::GenericBound::Outlives(..) => false,
|
||||||
ast::GenericBound::Trait(..) => true,
|
ast::GenericBound::Trait(..) | ast::GenericBound::Use(..) => true,
|
||||||
// FIXME(precise_capturing): This ordering fn should be reworked.
|
|
||||||
ast::GenericBound::Use(..) => false,
|
|
||||||
};
|
};
|
||||||
let is_lifetime = |b: &ast::GenericBound| !is_trait(b);
|
let is_lifetime = |b: &ast::GenericBound| !is_trait(b);
|
||||||
let last_trait_index = generic_bounds.iter().rposition(is_trait);
|
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 generic_bounds_in_order = is_generic_bounds_in_order(items);
|
||||||
let is_bound_extendable = |s: &str, b: &ast::GenericBound| match b {
|
let is_bound_extendable = |s: &str, b: &ast::GenericBound| match b {
|
||||||
ast::GenericBound::Outlives(..) => true,
|
ast::GenericBound::Outlives(..) => true,
|
||||||
ast::GenericBound::Trait(..) => last_line_extendable(s),
|
// We treat `use<>` like a trait bound here.
|
||||||
// FIXME(precise_capturing): This ordering fn should be reworked.
|
ast::GenericBound::Trait(..) | ast::GenericBound::Use(..) => last_line_extendable(s),
|
||||||
ast::GenericBound::Use(..) => true,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Whether a GenericBound item is a PathSegment segment that includes internal array
|
// 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,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
9
tests/source/precise-capturing.rs
Normal file
9
tests/source/precise-capturing.rs
Normal file
@ -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 {}
|
55
tests/target/precise-capturing.rs
Normal file
55
tests/target/precise-capturing.rs
Normal file
@ -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 {
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user