Skip to content

Commit 326e321

Browse files
committed
Implment #[cfg] and #[cfg_attr] in where clauses
1 parent 35f9799 commit 326e321

File tree

3 files changed

+151
-7
lines changed

3 files changed

+151
-7
lines changed

src/spanned.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ implement_spanned!(ast::ExprField);
5858
implement_spanned!(ast::ForeignItem);
5959
implement_spanned!(ast::Item);
6060
implement_spanned!(ast::Local);
61+
implement_spanned!(ast::WherePredicate);
6162

6263
impl Spanned for ast::Stmt {
6364
fn span(&self) -> Span {
@@ -149,12 +150,6 @@ impl Spanned for ast::FieldDef {
149150
}
150151
}
151152

152-
impl Spanned for ast::WherePredicate {
153-
fn span(&self) -> Span {
154-
self.span
155-
}
156-
}
157-
158153
impl Spanned for ast::FnRetTy {
159154
fn span(&self) -> Span {
160155
match *self {

src/types.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,8 +463,9 @@ impl Rewrite for ast::WherePredicate {
463463
}
464464

465465
fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
466+
let attrs_str = self.attrs.rewrite_result(context, shape)?;
466467
// FIXME: dead spans?
467-
let result = match self.kind {
468+
let pred_str = &match self.kind {
468469
ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
469470
ref bound_generic_params,
470471
ref bounded_ty,
@@ -499,6 +500,38 @@ impl Rewrite for ast::WherePredicate {
499500
}
500501
};
501502

503+
let mut result = String::with_capacity(attrs_str.len() + pred_str.len() + 1);
504+
result.push_str(&attrs_str);
505+
let pred_start = self.span.lo();
506+
let line_len = last_line_width(&attrs_str) + 1 + first_line_width(&pred_str);
507+
if let Some(last_attr) = self.attrs.last().filter(|last_attr| {
508+
contains_comment(context.snippet(mk_sp(last_attr.span.hi(), pred_start)))
509+
}) {
510+
result = combine_strs_with_missing_comments(
511+
context,
512+
&result,
513+
&pred_str,
514+
mk_sp(last_attr.span.hi(), pred_start),
515+
Shape {
516+
width: shape.width.min(context.config.inline_attribute_width()),
517+
..shape
518+
},
519+
!last_attr.is_doc_comment(),
520+
)?;
521+
} else {
522+
if !self.attrs.is_empty() {
523+
if context.config.inline_attribute_width() < line_len
524+
|| self.attrs.len() > 1
525+
|| self.attrs.last().is_some_and(|a| a.is_doc_comment())
526+
{
527+
result.push_str(&shape.indent.to_string_with_newline(context.config));
528+
} else {
529+
result.push(' ');
530+
}
531+
}
532+
result.push_str(&pred_str);
533+
}
534+
502535
Ok(result)
503536
}
504537
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// rustfmt-inline_attribute_width: 40
2+
3+
#![crate_type = "lib"]
4+
#![feature(cfg_attribute_in_where)]
5+
use std::marker::PhantomData;
6+
7+
#[cfg(a)]
8+
trait TraitA {}
9+
10+
#[cfg(b)]
11+
trait TraitB {}
12+
13+
trait A<T>
14+
where
15+
#[cfg = a_very_long_attribute_name]
16+
T: TraitA,
17+
#[cfg = another_very_long_attribute_name]
18+
T: TraitB,
19+
{
20+
type B<U>
21+
where
22+
#[cfg = a]
23+
// line comment after the attribute
24+
U: TraitA,
25+
#[cfg = b]
26+
/* block comment after the attribute */
27+
U: TraitB,
28+
#[cfg = a] // short
29+
U: TraitA,
30+
#[cfg = b] /* short */ U: TraitB;
31+
32+
fn foo<U>(&self)
33+
where
34+
/// line doc comment before the attribute
35+
U: TraitA,
36+
/** line doc block comment before the attribute */
37+
U: TraitB;
38+
}
39+
40+
impl<T> A<T> for T
41+
where
42+
#[doc = "line doc before the attribute"]
43+
T: TraitA,
44+
/** short doc */
45+
T: TraitB,
46+
{
47+
type B<U>
48+
= ()
49+
where
50+
#[doc = "short"] U: TraitA,
51+
#[doc = "short"]
52+
#[cfg = a]
53+
U: TraitB;
54+
55+
fn foo<U>(&self)
56+
where
57+
#[cfg = a]
58+
#[cfg = b]
59+
U: TraitA,
60+
/// line doc
61+
#[cfg = c]
62+
U: TraitB,
63+
{
64+
}
65+
}
66+
67+
struct C<T>
68+
where
69+
#[cfg = a] T: TraitA,
70+
#[cfg = b] T: TraitB,
71+
{
72+
_t: PhantomData<T>,
73+
}
74+
75+
union D<T>
76+
where
77+
#[cfg = a] T: TraitA,
78+
#[cfg = b] T: TraitB,
79+
{
80+
_t: PhantomData<T>,
81+
}
82+
83+
enum E<T>
84+
where
85+
#[cfg = a] T: TraitA,
86+
#[cfg = b] T: TraitB,
87+
{
88+
E(PhantomData<T>),
89+
}
90+
91+
#[allow(type_alias_bounds)]
92+
type F<T>
93+
where
94+
#[cfg = a] T: TraitA,
95+
#[cfg = b] T: TraitB,
96+
= T;
97+
98+
impl<T> C<T>
99+
where
100+
#[cfg = a] T: TraitA,
101+
#[cfg = b] T: TraitB,
102+
{
103+
fn new<U>()
104+
where
105+
#[cfg = a] U: TraitA,
106+
#[cfg = b] U: TraitB,
107+
{
108+
}
109+
}
110+
111+
fn foo<T>()
112+
where
113+
#[cfg = a] T: TraitA,
114+
#[cfg = b] T: TraitB,
115+
{
116+
}

0 commit comments

Comments
 (0)