Skip to content

Commit 3996209

Browse files
committedDec 25, 2024
Overhaul error messages for disallowed coverage attributes
1 parent 9124662 commit 3996209

File tree

6 files changed

+160
-75
lines changed

6 files changed

+160
-75
lines changed
 

‎compiler/rustc_passes/messages.ftl

+5-3
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,11 @@ passes_coroutine_on_non_closure =
112112
attribute should be applied to closures
113113
.label = not a closure
114114
115-
passes_coverage_not_fn_or_closure =
116-
attribute should be applied to a function definition or closure
117-
.label = not a function or closure
115+
passes_coverage_attribute_not_allowed =
116+
coverage attribute not allowed here
117+
.not_fn_impl_mod = not a function, impl block, or module
118+
.no_body = function has no body
119+
.help = coverage attribute can be applied to a function (with body), impl block, or module
118120
119121
passes_dead_codes =
120122
{ $multiple ->

‎compiler/rustc_passes/src/check_attr.rs

+19-6
Original file line numberDiff line numberDiff line change
@@ -432,21 +432,34 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
432432

433433
/// Checks that `#[coverage(..)]` is applied to a function/closure/method,
434434
/// or to an impl block or module.
435-
fn check_coverage(&self, attr: &Attribute, span: Span, target: Target) {
435+
fn check_coverage(&self, attr: &Attribute, target_span: Span, target: Target) {
436+
let mut not_fn_impl_mod = None;
437+
let mut no_body = None;
438+
436439
match target {
437440
Target::Fn
438441
| Target::Closure
439442
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent)
440443
| Target::Impl
441-
| Target::Mod => {}
444+
| Target::Mod => return,
445+
446+
// These are "functions", but they aren't allowed because they don't
447+
// have a body, so the usual explanation would be confusing.
448+
Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => {
449+
no_body = Some(target_span);
450+
}
442451

443452
_ => {
444-
self.dcx().emit_err(errors::CoverageNotFnOrClosure {
445-
attr_span: attr.span,
446-
defn_span: span,
447-
});
453+
not_fn_impl_mod = Some(target_span);
448454
}
449455
}
456+
457+
self.dcx().emit_err(errors::CoverageAttributeNotAllowed {
458+
attr_span: attr.span,
459+
not_fn_impl_mod,
460+
no_body,
461+
help: (),
462+
});
450463
}
451464

452465
/// Checks that `#[optimize(..)]` is applied to a function/closure/method,

‎compiler/rustc_passes/src/errors.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,21 @@ pub(crate) struct InlineNotFnOrClosure {
7171
pub defn_span: Span,
7272
}
7373

74+
/// "coverage attribute not allowed here"
7475
#[derive(Diagnostic)]
75-
#[diag(passes_coverage_not_fn_or_closure, code = E0788)]
76-
pub(crate) struct CoverageNotFnOrClosure {
76+
#[diag(passes_coverage_attribute_not_allowed, code = E0788)]
77+
pub(crate) struct CoverageAttributeNotAllowed {
7778
#[primary_span]
7879
pub attr_span: Span,
79-
#[label]
80-
pub defn_span: Span,
80+
/// "not a function, impl block, or module"
81+
#[label(passes_not_fn_impl_mod)]
82+
pub not_fn_impl_mod: Option<Span>,
83+
/// "function has no body"
84+
#[label(passes_no_body)]
85+
pub no_body: Option<Span>,
86+
/// "coverage attribute can be applied to a function (with body), impl block, or module"
87+
#[help]
88+
pub help: (),
8189
}
8290

8391
#[derive(Diagnostic)]

‎tests/ui/coverage-attr/allowed-positions.stderr

+68-34
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@ LL | let _closure_expr = #[coverage(off)] || ();
88
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
99
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1010

11-
error[E0788]: attribute should be applied to a function definition or closure
11+
error[E0788]: coverage attribute not allowed here
1212
--> $DIR/allowed-positions.rs:14:1
1313
|
1414
LL | #[coverage(off)]
1515
| ^^^^^^^^^^^^^^^^
1616
LL | type MyTypeAlias = ();
17-
| ---------------------- not a function or closure
17+
| ---------------------- not a function, impl block, or module
18+
|
19+
= help: coverage attribute can be applied to a function (with body), impl block, or module
1820

19-
error[E0788]: attribute should be applied to a function definition or closure
21+
error[E0788]: coverage attribute not allowed here
2022
--> $DIR/allowed-positions.rs:17:1
2123
|
2224
LL | #[coverage(off)]
@@ -27,9 +29,11 @@ LL | | const TRAIT_ASSOC_CONST: u32;
2729
... |
2830
LL | | fn trait_assoc_fn();
2931
LL | | }
30-
| |_- not a function or closure
32+
| |_- not a function, impl block, or module
33+
|
34+
= help: coverage attribute can be applied to a function (with body), impl block, or module
3135

32-
error[E0788]: attribute should be applied to a function definition or closure
36+
error[E0788]: coverage attribute not allowed here
3337
--> $DIR/allowed-positions.rs:61:1
3438
|
3539
LL | #[coverage(off)]
@@ -38,119 +42,149 @@ LL | / struct MyStruct {
3842
LL | | #[coverage(off)]
3943
LL | | field: u32,
4044
LL | | }
41-
| |_- not a function or closure
45+
| |_- not a function, impl block, or module
46+
|
47+
= help: coverage attribute can be applied to a function (with body), impl block, or module
4248

43-
error[E0788]: attribute should be applied to a function definition or closure
49+
error[E0788]: coverage attribute not allowed here
4450
--> $DIR/allowed-positions.rs:63:5
4551
|
4652
LL | #[coverage(off)]
4753
| ^^^^^^^^^^^^^^^^
4854
LL | field: u32,
49-
| ---------- not a function or closure
55+
| ---------- not a function, impl block, or module
56+
|
57+
= help: coverage attribute can be applied to a function (with body), impl block, or module
5058

51-
error[E0788]: attribute should be applied to a function definition or closure
59+
error[E0788]: coverage attribute not allowed here
5260
--> $DIR/allowed-positions.rs:88:5
5361
|
5462
LL | #[coverage(off)]
5563
| ^^^^^^^^^^^^^^^^
5664
LL | let _ = ();
57-
| ----------- not a function or closure
65+
| ----------- not a function, impl block, or module
66+
|
67+
= help: coverage attribute can be applied to a function (with body), impl block, or module
5868

59-
error[E0788]: attribute should be applied to a function definition or closure
69+
error[E0788]: coverage attribute not allowed here
6070
--> $DIR/allowed-positions.rs:94:5
6171
|
6272
LL | #[coverage(off)]
6373
| ^^^^^^^^^^^^^^^^
6474
LL | let _let_closure = || ();
65-
| ------------------------- not a function or closure
75+
| ------------------------- not a function, impl block, or module
76+
|
77+
= help: coverage attribute can be applied to a function (with body), impl block, or module
6678

67-
error[E0788]: attribute should be applied to a function definition or closure
79+
error[E0788]: coverage attribute not allowed here
6880
--> $DIR/allowed-positions.rs:110:9
6981
|
7082
LL | #[coverage(off)]
7183
| ^^^^^^^^^^^^^^^^
7284
LL | () => (),
73-
| -------- not a function or closure
85+
| -------- not a function, impl block, or module
86+
|
87+
= help: coverage attribute can be applied to a function (with body), impl block, or module
7488

75-
error[E0788]: attribute should be applied to a function definition or closure
89+
error[E0788]: coverage attribute not allowed here
7690
--> $DIR/allowed-positions.rs:114:5
7791
|
7892
LL | #[coverage(off)]
7993
| ^^^^^^^^^^^^^^^^
8094
LL | return ();
81-
| --------- not a function or closure
95+
| --------- not a function, impl block, or module
96+
|
97+
= help: coverage attribute can be applied to a function (with body), impl block, or module
8298

83-
error[E0788]: attribute should be applied to a function definition or closure
99+
error[E0788]: coverage attribute not allowed here
84100
--> $DIR/allowed-positions.rs:19:5
85101
|
86102
LL | #[coverage(off)]
87103
| ^^^^^^^^^^^^^^^^
88104
LL | const TRAIT_ASSOC_CONST: u32;
89-
| ----------------------------- not a function or closure
105+
| ----------------------------- not a function, impl block, or module
106+
|
107+
= help: coverage attribute can be applied to a function (with body), impl block, or module
90108

91-
error[E0788]: attribute should be applied to a function definition or closure
109+
error[E0788]: coverage attribute not allowed here
92110
--> $DIR/allowed-positions.rs:22:5
93111
|
94112
LL | #[coverage(off)]
95113
| ^^^^^^^^^^^^^^^^
96114
LL | type TraitAssocType;
97-
| -------------------- not a function or closure
115+
| -------------------- not a function, impl block, or module
116+
|
117+
= help: coverage attribute can be applied to a function (with body), impl block, or module
98118

99-
error[E0788]: attribute should be applied to a function definition or closure
119+
error[E0788]: coverage attribute not allowed here
100120
--> $DIR/allowed-positions.rs:25:5
101121
|
102122
LL | #[coverage(off)]
103123
| ^^^^^^^^^^^^^^^^
104124
LL | fn trait_method(&self);
105-
| ----------------------- not a function or closure
125+
| ----------------------- function has no body
126+
|
127+
= help: coverage attribute can be applied to a function (with body), impl block, or module
106128

107-
error[E0788]: attribute should be applied to a function definition or closure
129+
error[E0788]: coverage attribute not allowed here
108130
--> $DIR/allowed-positions.rs:31:5
109131
|
110132
LL | #[coverage(off)]
111133
| ^^^^^^^^^^^^^^^^
112134
LL | fn trait_assoc_fn();
113-
| -------------------- not a function or closure
135+
| -------------------- function has no body
136+
|
137+
= help: coverage attribute can be applied to a function (with body), impl block, or module
114138

115-
error[E0788]: attribute should be applied to a function definition or closure
139+
error[E0788]: coverage attribute not allowed here
116140
--> $DIR/allowed-positions.rs:39:5
117141
|
118142
LL | #[coverage(off)]
119143
| ^^^^^^^^^^^^^^^^
120144
LL | type TraitAssocType = Self;
121-
| --------------------------- not a function or closure
145+
| --------------------------- not a function, impl block, or module
146+
|
147+
= help: coverage attribute can be applied to a function (with body), impl block, or module
122148

123-
error[E0788]: attribute should be applied to a function definition or closure
149+
error[E0788]: coverage attribute not allowed here
124150
--> $DIR/allowed-positions.rs:56:5
125151
|
126152
LL | #[coverage(off)]
127153
| ^^^^^^^^^^^^^^^^
128154
LL | type T = impl Copy;
129-
| ------------------- not a function or closure
155+
| ------------------- not a function, impl block, or module
156+
|
157+
= help: coverage attribute can be applied to a function (with body), impl block, or module
130158

131-
error[E0788]: attribute should be applied to a function definition or closure
159+
error[E0788]: coverage attribute not allowed here
132160
--> $DIR/allowed-positions.rs:76:5
133161
|
134162
LL | #[coverage(off)]
135163
| ^^^^^^^^^^^^^^^^
136164
LL | static X: u32;
137-
| -------------- not a function or closure
165+
| -------------- not a function, impl block, or module
166+
|
167+
= help: coverage attribute can be applied to a function (with body), impl block, or module
138168

139-
error[E0788]: attribute should be applied to a function definition or closure
169+
error[E0788]: coverage attribute not allowed here
140170
--> $DIR/allowed-positions.rs:79:5
141171
|
142172
LL | #[coverage(off)]
143173
| ^^^^^^^^^^^^^^^^
144174
LL | type T;
145-
| ------- not a function or closure
175+
| ------- not a function, impl block, or module
176+
|
177+
= help: coverage attribute can be applied to a function (with body), impl block, or module
146178

147-
error[E0788]: attribute should be applied to a function definition or closure
179+
error[E0788]: coverage attribute not allowed here
148180
--> $DIR/allowed-positions.rs:82:5
149181
|
150182
LL | #[coverage(off)]
151183
| ^^^^^^^^^^^^^^^^
152184
LL | fn foreign_fn();
153-
| ---------------- not a function or closure
185+
| ---------------- function has no body
186+
|
187+
= help: coverage attribute can be applied to a function (with body), impl block, or module
154188

155189
error: aborting due to 18 previous errors
156190

‎tests/ui/coverage-attr/name-value.stderr

+28-14
Original file line numberDiff line numberDiff line change
@@ -154,16 +154,18 @@ LL | #[coverage(off)]
154154
LL | #[coverage(on)]
155155
|
156156

157-
error[E0788]: attribute should be applied to a function definition or closure
157+
error[E0788]: coverage attribute not allowed here
158158
--> $DIR/name-value.rs:21:1
159159
|
160160
LL | #[coverage = "off"]
161161
| ^^^^^^^^^^^^^^^^^^^
162162
...
163163
LL | struct MyStruct;
164-
| ---------------- not a function or closure
164+
| ---------------- not a function, impl block, or module
165+
|
166+
= help: coverage attribute can be applied to a function (with body), impl block, or module
165167

166-
error[E0788]: attribute should be applied to a function definition or closure
168+
error[E0788]: coverage attribute not allowed here
167169
--> $DIR/name-value.rs:35:1
168170
|
169171
LL | #[coverage = "off"]
@@ -174,52 +176,64 @@ LL | | #[coverage = "off"]
174176
... |
175177
LL | | type T;
176178
LL | | }
177-
| |_- not a function or closure
179+
| |_- not a function, impl block, or module
180+
|
181+
= help: coverage attribute can be applied to a function (with body), impl block, or module
178182

179-
error[E0788]: attribute should be applied to a function definition or closure
183+
error[E0788]: coverage attribute not allowed here
180184
--> $DIR/name-value.rs:39:5
181185
|
182186
LL | #[coverage = "off"]
183187
| ^^^^^^^^^^^^^^^^^^^
184188
...
185189
LL | const X: u32;
186-
| ------------- not a function or closure
190+
| ------------- not a function, impl block, or module
191+
|
192+
= help: coverage attribute can be applied to a function (with body), impl block, or module
187193

188-
error[E0788]: attribute should be applied to a function definition or closure
194+
error[E0788]: coverage attribute not allowed here
189195
--> $DIR/name-value.rs:44:5
190196
|
191197
LL | #[coverage = "off"]
192198
| ^^^^^^^^^^^^^^^^^^^
193199
...
194200
LL | type T;
195-
| ------- not a function or closure
201+
| ------- not a function, impl block, or module
202+
|
203+
= help: coverage attribute can be applied to a function (with body), impl block, or module
196204

197-
error[E0788]: attribute should be applied to a function definition or closure
205+
error[E0788]: coverage attribute not allowed here
198206
--> $DIR/name-value.rs:29:5
199207
|
200208
LL | #[coverage = "off"]
201209
| ^^^^^^^^^^^^^^^^^^^
202210
...
203211
LL | const X: u32 = 7;
204-
| ----------------- not a function or closure
212+
| ----------------- not a function, impl block, or module
213+
|
214+
= help: coverage attribute can be applied to a function (with body), impl block, or module
205215

206-
error[E0788]: attribute should be applied to a function definition or closure
216+
error[E0788]: coverage attribute not allowed here
207217
--> $DIR/name-value.rs:53:5
208218
|
209219
LL | #[coverage = "off"]
210220
| ^^^^^^^^^^^^^^^^^^^
211221
...
212222
LL | const X: u32 = 8;
213-
| ----------------- not a function or closure
223+
| ----------------- not a function, impl block, or module
224+
|
225+
= help: coverage attribute can be applied to a function (with body), impl block, or module
214226

215-
error[E0788]: attribute should be applied to a function definition or closure
227+
error[E0788]: coverage attribute not allowed here
216228
--> $DIR/name-value.rs:58:5
217229
|
218230
LL | #[coverage = "off"]
219231
| ^^^^^^^^^^^^^^^^^^^
220232
...
221233
LL | type T = ();
222-
| ------------ not a function or closure
234+
| ------------ not a function, impl block, or module
235+
|
236+
= help: coverage attribute can be applied to a function (with body), impl block, or module
223237

224238
error: aborting due to 19 previous errors
225239

‎tests/ui/coverage-attr/word-only.stderr

+28-14
Original file line numberDiff line numberDiff line change
@@ -154,16 +154,18 @@ LL | #[coverage(off)]
154154
LL | #[coverage(on)]
155155
|
156156

157-
error[E0788]: attribute should be applied to a function definition or closure
157+
error[E0788]: coverage attribute not allowed here
158158
--> $DIR/word-only.rs:21:1
159159
|
160160
LL | #[coverage]
161161
| ^^^^^^^^^^^
162162
...
163163
LL | struct MyStruct;
164-
| ---------------- not a function or closure
164+
| ---------------- not a function, impl block, or module
165+
|
166+
= help: coverage attribute can be applied to a function (with body), impl block, or module
165167

166-
error[E0788]: attribute should be applied to a function definition or closure
168+
error[E0788]: coverage attribute not allowed here
167169
--> $DIR/word-only.rs:35:1
168170
|
169171
LL | #[coverage]
@@ -174,52 +176,64 @@ LL | | #[coverage]
174176
... |
175177
LL | | type T;
176178
LL | | }
177-
| |_- not a function or closure
179+
| |_- not a function, impl block, or module
180+
|
181+
= help: coverage attribute can be applied to a function (with body), impl block, or module
178182

179-
error[E0788]: attribute should be applied to a function definition or closure
183+
error[E0788]: coverage attribute not allowed here
180184
--> $DIR/word-only.rs:39:5
181185
|
182186
LL | #[coverage]
183187
| ^^^^^^^^^^^
184188
...
185189
LL | const X: u32;
186-
| ------------- not a function or closure
190+
| ------------- not a function, impl block, or module
191+
|
192+
= help: coverage attribute can be applied to a function (with body), impl block, or module
187193

188-
error[E0788]: attribute should be applied to a function definition or closure
194+
error[E0788]: coverage attribute not allowed here
189195
--> $DIR/word-only.rs:44:5
190196
|
191197
LL | #[coverage]
192198
| ^^^^^^^^^^^
193199
...
194200
LL | type T;
195-
| ------- not a function or closure
201+
| ------- not a function, impl block, or module
202+
|
203+
= help: coverage attribute can be applied to a function (with body), impl block, or module
196204

197-
error[E0788]: attribute should be applied to a function definition or closure
205+
error[E0788]: coverage attribute not allowed here
198206
--> $DIR/word-only.rs:29:5
199207
|
200208
LL | #[coverage]
201209
| ^^^^^^^^^^^
202210
...
203211
LL | const X: u32 = 7;
204-
| ----------------- not a function or closure
212+
| ----------------- not a function, impl block, or module
213+
|
214+
= help: coverage attribute can be applied to a function (with body), impl block, or module
205215

206-
error[E0788]: attribute should be applied to a function definition or closure
216+
error[E0788]: coverage attribute not allowed here
207217
--> $DIR/word-only.rs:53:5
208218
|
209219
LL | #[coverage]
210220
| ^^^^^^^^^^^
211221
...
212222
LL | const X: u32 = 8;
213-
| ----------------- not a function or closure
223+
| ----------------- not a function, impl block, or module
224+
|
225+
= help: coverage attribute can be applied to a function (with body), impl block, or module
214226

215-
error[E0788]: attribute should be applied to a function definition or closure
227+
error[E0788]: coverage attribute not allowed here
216228
--> $DIR/word-only.rs:58:5
217229
|
218230
LL | #[coverage]
219231
| ^^^^^^^^^^^
220232
...
221233
LL | type T = ();
222-
| ------------ not a function or closure
234+
| ------------ not a function, impl block, or module
235+
|
236+
= help: coverage attribute can be applied to a function (with body), impl block, or module
223237

224238
error: aborting due to 19 previous errors
225239

0 commit comments

Comments
 (0)
Please sign in to comment.