Skip to content

Commit eb20fdf

Browse files
committed
rustfmt impl restriction
1 parent ce2dae3 commit eb20fdf

File tree

4 files changed

+54
-3
lines changed

4 files changed

+54
-3
lines changed

src/tools/rustfmt/src/items.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,7 @@ pub(crate) fn format_trait(
11721172
unreachable!();
11731173
};
11741174
let ast::Trait {
1175-
impl_restriction: _,
1175+
ref impl_restriction,
11761176
is_auto,
11771177
safety,
11781178
ident,
@@ -1183,8 +1183,9 @@ pub(crate) fn format_trait(
11831183

11841184
let mut result = String::with_capacity(128);
11851185
let header = format!(
1186-
"{}{}{}trait ",
1186+
"{}{}{}{}trait ",
11871187
format_visibility(context, &item.vis),
1188+
format_restriction("impl", context, impl_restriction),
11881189
format_safety(safety),
11891190
format_auto(is_auto),
11901191
);

src/tools/rustfmt/src/utils.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_ast::ast::{
44
self, Attribute, MetaItem, MetaItemInner, MetaItemKind, NodeId, Path, Visibility,
55
VisibilityKind,
66
};
7-
use rustc_ast::{YieldKind, ptr};
7+
use rustc_ast::{Restriction, RestrictionKind, YieldKind, ptr};
88
use rustc_ast_pretty::pprust;
99
use rustc_span::{BytePos, LocalExpnId, Span, Symbol, SyntaxContext, sym, symbol};
1010
use unicode_width::UnicodeWidthStr;
@@ -74,6 +74,35 @@ pub(crate) fn format_visibility(
7474
}
7575
}
7676

77+
// Does not allocate in the common (implied) case.
78+
pub(crate) fn format_restriction(
79+
kw: &'static str,
80+
context: &RewriteContext<'_>,
81+
restriction: &Restriction,
82+
) -> String {
83+
match restriction.kind {
84+
RestrictionKind::Unrestricted => format!("{kw} "),
85+
RestrictionKind::Restricted {
86+
ref path,
87+
id: _,
88+
shorthand,
89+
} => {
90+
let Path { ref segments, .. } = **path;
91+
let mut segments_iter = segments.iter().map(|seg| rewrite_ident(context, seg.ident));
92+
if path.is_global() && segments_iter.next().is_none() {
93+
panic!("non-global path in {kw}(restricted)?");
94+
}
95+
// FIXME use `segments_iter.intersperse("::").collect::<String>()` once
96+
// `#![feature(iter_intersperse)]` is re-stabilized.
97+
let path = itertools::join(segments_iter, "::");
98+
let in_str = if shorthand { "" } else { "in " };
99+
100+
format!("{kw}({in_str}{path}) ")
101+
}
102+
RestrictionKind::Implied => String::new(),
103+
}
104+
}
105+
77106
#[inline]
78107
pub(crate) fn format_coro(coroutine_kind: &ast::CoroutineKind) -> &'static str {
79108
match coroutine_kind {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
pub
2+
impl(crate)
3+
trait Foo {}
4+
5+
pub impl
6+
( in
7+
crate )
8+
trait
9+
Bar
10+
{}
11+
12+
pub
13+
impl ( in foo
14+
::
15+
bar )
16+
trait Baz {}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pub impl(crate) trait Foo {}
2+
3+
pub impl(in crate) trait Bar {}
4+
5+
pub impl(in foo::bar) trait Baz {}

0 commit comments

Comments
 (0)