Skip to content

Commit 29c7a5c

Browse files
committed
check earlier for attributes that are placed in where predicate
1 parent c4b8026 commit 29c7a5c

8 files changed

Lines changed: 191 additions & 176 deletions

File tree

compiler/rustc_attr_parsing/src/errors.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_errors::MultiSpan;
12
use rustc_macros::{Diagnostic, Subdiagnostic};
23
use rustc_span::{Span, Symbol};
34

@@ -24,3 +25,11 @@ pub(crate) struct ItemFollowingInnerAttr {
2425
#[primary_span]
2526
pub span: Span,
2627
}
28+
29+
#[derive(Diagnostic)]
30+
#[diag("most attributes are not supported in `where` clauses")]
31+
#[help("only `#[cfg]` and `#[cfg_attr]` are supported")]
32+
pub(crate) struct UnsupportedAttributesInWhere {
33+
#[primary_span]
34+
pub span: MultiSpan,
35+
}

compiler/rustc_attr_parsing/src/interface.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,12 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
439439
}
440440
}
441441

442+
if !matches!(self.stage.should_emit(), ShouldEmit::Nothing)
443+
&& target == Target::WherePredicate
444+
{
445+
self.check_invalid_where_predicate_attrs(attributes.iter());
446+
}
447+
442448
attributes
443449
}
444450

compiler/rustc_attr_parsing/src/target_checking.rs

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
use std::borrow::Cow;
22

33
use rustc_ast::AttrStyle;
4-
use rustc_errors::{DiagArgValue, StashKey};
4+
use rustc_errors::{DiagArgValue, MultiSpan, StashKey};
55
use rustc_feature::Features;
6+
use rustc_hir::attrs::AttributeKind;
67
use rustc_hir::lints::AttributeLintKind;
7-
use rustc_hir::{AttrItem, MethodKind, Target};
8+
use rustc_hir::{AttrItem, Attribute, MethodKind, Target};
89
use rustc_span::{BytePos, Span, Symbol, sym};
910

1011
use crate::AttributeParser;
1112
use crate::context::{AcceptContext, Stage};
12-
use crate::errors::{InvalidAttrAtCrateLevel, ItemFollowingInnerAttr};
13+
use crate::errors::{
14+
InvalidAttrAtCrateLevel, ItemFollowingInnerAttr, UnsupportedAttributesInWhere,
15+
};
1316
use crate::session_diagnostics::InvalidTarget;
1417
use crate::target_checking::Policy::Allow;
1518

@@ -264,6 +267,32 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
264267
.ok()
265268
.flatten()
266269
}
270+
271+
pub(crate) fn check_invalid_where_predicate_attrs<'attr>(
272+
&self,
273+
attrs: impl IntoIterator<Item = &'attr Attribute>,
274+
) {
275+
// FIXME(where_clause_attrs): Currently, as the following check shows,
276+
// only `#[cfg]` and `#[cfg_attr]` are allowed, but it should be removed
277+
// if we allow more attributes (e.g., tool attributes and `allow/deny/warn`)
278+
// in where clauses. After that, this function would become useless.
279+
let spans = attrs
280+
.into_iter()
281+
// FIXME: We shouldn't need to special-case `doc`!
282+
.filter(|attr| {
283+
matches!(
284+
attr,
285+
Attribute::Parsed(AttributeKind::DocComment { .. } | AttributeKind::Doc(_))
286+
| Attribute::Unparsed(_)
287+
)
288+
})
289+
.map(|attr| attr.span())
290+
.collect::<Vec<_>>();
291+
if !spans.is_empty() {
292+
self.dcx()
293+
.emit_err(UnsupportedAttributesInWhere { span: MultiSpan::from_spans(spans) });
294+
}
295+
}
267296
}
268297

269298
/// Takes a list of `allowed_targets` for an attribute, and the `target` the attribute was applied to.

compiler/rustc_passes/src/check_attr.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1910,27 +1910,6 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
19101910
}
19111911

19121912
fn visit_where_predicate(&mut self, where_predicate: &'tcx hir::WherePredicate<'tcx>) {
1913-
// FIXME(where_clause_attrs): Currently, as the following check shows,
1914-
// only `#[cfg]` and `#[cfg_attr]` are allowed, but it should be removed
1915-
// if we allow more attributes (e.g., tool attributes and `allow/deny/warn`)
1916-
// in where clauses. After that, only `self.check_attributes` should be enough.
1917-
let spans = self
1918-
.tcx
1919-
.hir_attrs(where_predicate.hir_id)
1920-
.iter()
1921-
// FIXME: We shouldn't need to special-case `doc`!
1922-
.filter(|attr| {
1923-
matches!(
1924-
attr,
1925-
Attribute::Parsed(AttributeKind::DocComment { .. } | AttributeKind::Doc(_))
1926-
| Attribute::Unparsed(_)
1927-
)
1928-
})
1929-
.map(|attr| attr.span())
1930-
.collect::<Vec<_>>();
1931-
if !spans.is_empty() {
1932-
self.tcx.dcx().emit_err(errors::UnsupportedAttributesInWhere { span: spans.into() });
1933-
}
19341913
self.check_attributes(
19351914
where_predicate.hir_id,
19361915
where_predicate.span,

compiler/rustc_passes/src/errors.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,14 +1150,6 @@ pub(crate) struct RustcConstStableIndirectPairing {
11501150
pub span: Span,
11511151
}
11521152

1153-
#[derive(Diagnostic)]
1154-
#[diag("most attributes are not supported in `where` clauses")]
1155-
#[help("only `#[cfg]` and `#[cfg_attr]` are supported")]
1156-
pub(crate) struct UnsupportedAttributesInWhere {
1157-
#[primary_span]
1158-
pub span: MultiSpan,
1159-
}
1160-
11611153
#[derive(Diagnostic)]
11621154
pub(crate) enum UnexportableItem<'a> {
11631155
#[diag("{$descr}'s are not exportable")]

tests/ui/where-clauses/cfg_attribute.a.stderr

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -93,194 +93,194 @@ LL | #[rustfmt::skip] ():,
9393
= help: only `#[cfg]` and `#[cfg_attr]` are supported
9494

9595
error: most attributes are not supported in `where` clauses
96-
--> $DIR/cfg_attribute.rs:65:5
96+
--> $DIR/cfg_attribute.rs:42:9
9797
|
98-
LL | #[derive(Clone)] ():,
99-
| ^^^^^^^^^^^^^^^^
98+
LL | #[derive(Clone)] ():,
99+
| ^^^^^^^^^^^^^^^^
100100
|
101101
= help: only `#[cfg]` and `#[cfg_attr]` are supported
102102

103103
error: most attributes are not supported in `where` clauses
104-
--> $DIR/cfg_attribute.rs:68:5
104+
--> $DIR/cfg_attribute.rs:45:9
105105
|
106-
LL | #[rustfmt::skip] ():,
107-
| ^^^^^^^^^^^^^^^^
106+
LL | #[rustfmt::skip] ():;
107+
| ^^^^^^^^^^^^^^^^
108108
|
109109
= help: only `#[cfg]` and `#[cfg_attr]` are supported
110110

111111
error: most attributes are not supported in `where` clauses
112-
--> $DIR/cfg_attribute.rs:99:5
112+
--> $DIR/cfg_attribute.rs:53:9
113113
|
114-
LL | #[derive(Clone)] ():,
115-
| ^^^^^^^^^^^^^^^^
114+
LL | #[derive(Clone)] ():,
115+
| ^^^^^^^^^^^^^^^^
116116
|
117117
= help: only `#[cfg]` and `#[cfg_attr]` are supported
118118

119119
error: most attributes are not supported in `where` clauses
120-
--> $DIR/cfg_attribute.rs:102:5
120+
--> $DIR/cfg_attribute.rs:56:9
121121
|
122-
LL | #[rustfmt::skip] ():,
123-
| ^^^^^^^^^^^^^^^^
122+
LL | #[rustfmt::skip] ():;
123+
| ^^^^^^^^^^^^^^^^
124124
|
125125
= help: only `#[cfg]` and `#[cfg_attr]` are supported
126126

127127
error: most attributes are not supported in `where` clauses
128-
--> $DIR/cfg_attribute.rs:113:5
128+
--> $DIR/cfg_attribute.rs:65:5
129129
|
130130
LL | #[derive(Clone)] ():,
131131
| ^^^^^^^^^^^^^^^^
132132
|
133133
= help: only `#[cfg]` and `#[cfg_attr]` are supported
134134

135135
error: most attributes are not supported in `where` clauses
136-
--> $DIR/cfg_attribute.rs:116:5
136+
--> $DIR/cfg_attribute.rs:68:5
137137
|
138138
LL | #[rustfmt::skip] ():,
139139
| ^^^^^^^^^^^^^^^^
140140
|
141141
= help: only `#[cfg]` and `#[cfg_attr]` are supported
142142

143143
error: most attributes are not supported in `where` clauses
144-
--> $DIR/cfg_attribute.rs:128:5
144+
--> $DIR/cfg_attribute.rs:75:9
145145
|
146-
LL | #[derive(Clone)] ():,
147-
| ^^^^^^^^^^^^^^^^
146+
LL | #[derive(Clone)] ():,
147+
| ^^^^^^^^^^^^^^^^
148148
|
149149
= help: only `#[cfg]` and `#[cfg_attr]` are supported
150150

151151
error: most attributes are not supported in `where` clauses
152-
--> $DIR/cfg_attribute.rs:131:5
152+
--> $DIR/cfg_attribute.rs:78:9
153153
|
154-
LL | #[rustfmt::skip] ():,
155-
| ^^^^^^^^^^^^^^^^
154+
LL | #[rustfmt::skip] ():;
155+
| ^^^^^^^^^^^^^^^^
156156
|
157157
= help: only `#[cfg]` and `#[cfg_attr]` are supported
158158

159159
error: most attributes are not supported in `where` clauses
160-
--> $DIR/cfg_attribute.rs:143:5
160+
--> $DIR/cfg_attribute.rs:86:9
161161
|
162-
LL | #[derive(Clone)] ():,
163-
| ^^^^^^^^^^^^^^^^
162+
LL | #[derive(Clone)] ():,
163+
| ^^^^^^^^^^^^^^^^
164164
|
165165
= help: only `#[cfg]` and `#[cfg_attr]` are supported
166166

167167
error: most attributes are not supported in `where` clauses
168-
--> $DIR/cfg_attribute.rs:146:5
168+
--> $DIR/cfg_attribute.rs:89:9
169169
|
170-
LL | #[rustfmt::skip] ():,
171-
| ^^^^^^^^^^^^^^^^
170+
LL | #[rustfmt::skip] ():,
171+
| ^^^^^^^^^^^^^^^^
172172
|
173173
= help: only `#[cfg]` and `#[cfg_attr]` are supported
174174

175175
error: most attributes are not supported in `where` clauses
176-
--> $DIR/cfg_attribute.rs:154:5
176+
--> $DIR/cfg_attribute.rs:99:5
177177
|
178178
LL | #[derive(Clone)] ():,
179179
| ^^^^^^^^^^^^^^^^
180180
|
181181
= help: only `#[cfg]` and `#[cfg_attr]` are supported
182182

183183
error: most attributes are not supported in `where` clauses
184-
--> $DIR/cfg_attribute.rs:157:5
184+
--> $DIR/cfg_attribute.rs:102:5
185185
|
186186
LL | #[rustfmt::skip] ():,
187187
| ^^^^^^^^^^^^^^^^
188188
|
189189
= help: only `#[cfg]` and `#[cfg_attr]` are supported
190190

191191
error: most attributes are not supported in `where` clauses
192-
--> $DIR/cfg_attribute.rs:177:5
192+
--> $DIR/cfg_attribute.rs:113:5
193193
|
194194
LL | #[derive(Clone)] ():,
195195
| ^^^^^^^^^^^^^^^^
196196
|
197197
= help: only `#[cfg]` and `#[cfg_attr]` are supported
198198

199199
error: most attributes are not supported in `where` clauses
200-
--> $DIR/cfg_attribute.rs:180:5
200+
--> $DIR/cfg_attribute.rs:116:5
201201
|
202202
LL | #[rustfmt::skip] ():,
203203
| ^^^^^^^^^^^^^^^^
204204
|
205205
= help: only `#[cfg]` and `#[cfg_attr]` are supported
206206

207207
error: most attributes are not supported in `where` clauses
208-
--> $DIR/cfg_attribute.rs:42:9
208+
--> $DIR/cfg_attribute.rs:128:5
209209
|
210-
LL | #[derive(Clone)] ():,
211-
| ^^^^^^^^^^^^^^^^
210+
LL | #[derive(Clone)] ():,
211+
| ^^^^^^^^^^^^^^^^
212212
|
213213
= help: only `#[cfg]` and `#[cfg_attr]` are supported
214214

215215
error: most attributes are not supported in `where` clauses
216-
--> $DIR/cfg_attribute.rs:45:9
216+
--> $DIR/cfg_attribute.rs:131:5
217217
|
218-
LL | #[rustfmt::skip] ():;
219-
| ^^^^^^^^^^^^^^^^
218+
LL | #[rustfmt::skip] ():,
219+
| ^^^^^^^^^^^^^^^^
220220
|
221221
= help: only `#[cfg]` and `#[cfg_attr]` are supported
222222

223223
error: most attributes are not supported in `where` clauses
224-
--> $DIR/cfg_attribute.rs:53:9
224+
--> $DIR/cfg_attribute.rs:143:5
225225
|
226-
LL | #[derive(Clone)] ():,
227-
| ^^^^^^^^^^^^^^^^
226+
LL | #[derive(Clone)] ():,
227+
| ^^^^^^^^^^^^^^^^
228228
|
229229
= help: only `#[cfg]` and `#[cfg_attr]` are supported
230230

231231
error: most attributes are not supported in `where` clauses
232-
--> $DIR/cfg_attribute.rs:56:9
232+
--> $DIR/cfg_attribute.rs:146:5
233233
|
234-
LL | #[rustfmt::skip] ():;
235-
| ^^^^^^^^^^^^^^^^
234+
LL | #[rustfmt::skip] ():,
235+
| ^^^^^^^^^^^^^^^^
236236
|
237237
= help: only `#[cfg]` and `#[cfg_attr]` are supported
238238

239239
error: most attributes are not supported in `where` clauses
240-
--> $DIR/cfg_attribute.rs:75:9
240+
--> $DIR/cfg_attribute.rs:154:5
241241
|
242-
LL | #[derive(Clone)] ():,
243-
| ^^^^^^^^^^^^^^^^
242+
LL | #[derive(Clone)] ():,
243+
| ^^^^^^^^^^^^^^^^
244244
|
245245
= help: only `#[cfg]` and `#[cfg_attr]` are supported
246246

247247
error: most attributes are not supported in `where` clauses
248-
--> $DIR/cfg_attribute.rs:78:9
248+
--> $DIR/cfg_attribute.rs:157:5
249249
|
250-
LL | #[rustfmt::skip] ():;
251-
| ^^^^^^^^^^^^^^^^
250+
LL | #[rustfmt::skip] ():,
251+
| ^^^^^^^^^^^^^^^^
252252
|
253253
= help: only `#[cfg]` and `#[cfg_attr]` are supported
254254

255255
error: most attributes are not supported in `where` clauses
256-
--> $DIR/cfg_attribute.rs:86:9
256+
--> $DIR/cfg_attribute.rs:164:9
257257
|
258258
LL | #[derive(Clone)] ():,
259259
| ^^^^^^^^^^^^^^^^
260260
|
261261
= help: only `#[cfg]` and `#[cfg_attr]` are supported
262262

263263
error: most attributes are not supported in `where` clauses
264-
--> $DIR/cfg_attribute.rs:89:9
264+
--> $DIR/cfg_attribute.rs:167:9
265265
|
266266
LL | #[rustfmt::skip] ():,
267267
| ^^^^^^^^^^^^^^^^
268268
|
269269
= help: only `#[cfg]` and `#[cfg_attr]` are supported
270270

271271
error: most attributes are not supported in `where` clauses
272-
--> $DIR/cfg_attribute.rs:164:9
272+
--> $DIR/cfg_attribute.rs:177:5
273273
|
274-
LL | #[derive(Clone)] ():,
275-
| ^^^^^^^^^^^^^^^^
274+
LL | #[derive(Clone)] ():,
275+
| ^^^^^^^^^^^^^^^^
276276
|
277277
= help: only `#[cfg]` and `#[cfg_attr]` are supported
278278

279279
error: most attributes are not supported in `where` clauses
280-
--> $DIR/cfg_attribute.rs:167:9
280+
--> $DIR/cfg_attribute.rs:180:5
281281
|
282-
LL | #[rustfmt::skip] ():,
283-
| ^^^^^^^^^^^^^^^^
282+
LL | #[rustfmt::skip] ():,
283+
| ^^^^^^^^^^^^^^^^
284284
|
285285
= help: only `#[cfg]` and `#[cfg_attr]` are supported
286286

0 commit comments

Comments
 (0)