Skip to content

Commit 8984438

Browse files
ytmimicalebcartwright
authored andcommitted
Honor #[rustfmt::skip::attributes(derive)] attribute
Fixes 5270 Previously, rustfmt only checked the `merge_derives` configuration value to determine if it should merge_derives. This lead to derives being merged even when annotated with the `rustfmt::skip` attribute. Now, rustfmt also checks if derives are explicitly being skipped in the current context via the `rustfmt::skip` attribute.
1 parent 0dba01a commit 8984438

File tree

4 files changed

+189
-1
lines changed

4 files changed

+189
-1
lines changed

src/attr.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,10 @@ impl Rewrite for [ast::Attribute] {
389389
let mut attrs = self;
390390
let mut result = String::new();
391391

392+
// Determine if the source text is annotated with `#[rustfmt::skip::attributes(derive)]`
393+
// or `#![rustfmt::skip::attributes(derive)]`
394+
let skip_derives = context.skip_context.skip_attribute("derive");
395+
392396
// This is not just a simple map because we need to handle doc comments
393397
// (where we take as many doc comment attributes as possible) and possibly
394398
// merging derives into a single attribute.
@@ -431,7 +435,7 @@ impl Rewrite for [ast::Attribute] {
431435
}
432436

433437
// Handle derives if we will merge them.
434-
if context.config.merge_derives() && is_derive(&attrs[0]) {
438+
if !skip_derives && context.config.merge_derives() && is_derive(&attrs[0]) {
435439
let derives = take_while_with_pred(context, attrs, is_derive);
436440
let derive_str = format_derive(derives, shape, context)?;
437441
result.push_str(&derive_str);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// rustfmt-merge_derives:true
2+
3+
#[rustfmt::skip::attributes(derive)]
4+
#[allow(dead_code)]
5+
#[derive(StructField)]
6+
#[derive(Clone)]
7+
struct DoNotMergeDerives {
8+
field: String,
9+
}
10+
11+
#[allow(dead_code)]
12+
#[derive(StructField)]
13+
#[rustfmt::skip::attributes(derive)]
14+
#[derive(Clone)]
15+
struct DoNotMergeDerivesSkipInMiddle {
16+
field: String,
17+
}
18+
19+
#[allow(dead_code)]
20+
#[derive(StructField)]
21+
#[derive(Clone)]
22+
#[rustfmt::skip::attributes(derive)]
23+
struct DoNotMergeDerivesSkipAtEnd {
24+
field: String,
25+
}
26+
27+
#[allow(dead_code)]
28+
#[derive(StructField)]
29+
#[derive(Clone)]
30+
struct MergeDerives {
31+
field: String,
32+
}
33+
34+
mod inner_attribute_derive_skip {
35+
#![rustfmt::skip::attributes(derive)]
36+
37+
#[allow(dead_code)]
38+
#[derive(StructField)]
39+
#[derive(Clone)]
40+
struct DoNotMergeDerives {
41+
field: String,
42+
}
43+
}
44+
45+
#[rustfmt::skip::attributes(derive)]
46+
mod outer_attribute_derive_skip {
47+
#[allow(dead_code)]
48+
#[derive(StructField)]
49+
#[derive(Clone)]
50+
struct DoNotMergeDerives {
51+
field: String,
52+
}
53+
}
54+
55+
mod no_derive_skip {
56+
#[allow(dead_code)]
57+
#[derive(StructField)]
58+
#[derive(Clone)]
59+
struct MergeDerives {
60+
field: String,
61+
}
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// rustfmt-merge_derives:false
2+
3+
#[rustfmt::skip::attributes(derive)]
4+
#[allow(dead_code)]
5+
#[derive(StructField)]
6+
#[derive(Clone)]
7+
struct DoNotMergeDerives {
8+
field: String,
9+
}
10+
11+
#[allow(dead_code)]
12+
#[derive(StructField)]
13+
#[rustfmt::skip::attributes(derive)]
14+
#[derive(Clone)]
15+
struct DoNotMergeDerivesSkipInMiddle {
16+
field: String,
17+
}
18+
19+
#[allow(dead_code)]
20+
#[derive(StructField)]
21+
#[derive(Clone)]
22+
#[rustfmt::skip::attributes(derive)]
23+
struct DoNotMergeDerivesSkipAtEnd {
24+
field: String,
25+
}
26+
27+
#[allow(dead_code)]
28+
#[derive(StructField)]
29+
#[derive(Clone)]
30+
struct MergeDerives {
31+
field: String,
32+
}
33+
34+
mod inner_attribute_derive_skip {
35+
#![rustfmt::skip::attributes(derive)]
36+
37+
#[allow(dead_code)]
38+
#[derive(StructField)]
39+
#[derive(Clone)]
40+
struct DoNotMergeDerives {
41+
field: String,
42+
}
43+
}
44+
45+
#[rustfmt::skip::attributes(derive)]
46+
mod outer_attribute_derive_skip {
47+
#[allow(dead_code)]
48+
#[derive(StructField)]
49+
#[derive(Clone)]
50+
struct DoNotMergeDerives {
51+
field: String,
52+
}
53+
}
54+
55+
mod no_derive_skip {
56+
#[allow(dead_code)]
57+
#[derive(StructField)]
58+
#[derive(Clone)]
59+
struct MergeDerives {
60+
field: String,
61+
}
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// rustfmt-merge_derives:true
2+
3+
#[rustfmt::skip::attributes(derive)]
4+
#[allow(dead_code)]
5+
#[derive(StructField)]
6+
#[derive(Clone)]
7+
struct DoNotMergeDerives {
8+
field: String,
9+
}
10+
11+
#[allow(dead_code)]
12+
#[derive(StructField)]
13+
#[rustfmt::skip::attributes(derive)]
14+
#[derive(Clone)]
15+
struct DoNotMergeDerivesSkipInMiddle {
16+
field: String,
17+
}
18+
19+
#[allow(dead_code)]
20+
#[derive(StructField)]
21+
#[derive(Clone)]
22+
#[rustfmt::skip::attributes(derive)]
23+
struct DoNotMergeDerivesSkipAtEnd {
24+
field: String,
25+
}
26+
27+
#[allow(dead_code)]
28+
#[derive(StructField, Clone)]
29+
struct MergeDerives {
30+
field: String,
31+
}
32+
33+
mod inner_attribute_derive_skip {
34+
#![rustfmt::skip::attributes(derive)]
35+
36+
#[allow(dead_code)]
37+
#[derive(StructField)]
38+
#[derive(Clone)]
39+
struct DoNotMergeDerives {
40+
field: String,
41+
}
42+
}
43+
44+
#[rustfmt::skip::attributes(derive)]
45+
mod outer_attribute_derive_skip {
46+
#[allow(dead_code)]
47+
#[derive(StructField)]
48+
#[derive(Clone)]
49+
struct DoNotMergeDerives {
50+
field: String,
51+
}
52+
}
53+
54+
mod no_derive_skip {
55+
#[allow(dead_code)]
56+
#[derive(StructField, Clone)]
57+
struct MergeDerives {
58+
field: String,
59+
}
60+
}

0 commit comments

Comments
 (0)