Skip to content

Commit b9139d2

Browse files
committed
Auto merge of #57321 - petrochenkov:atokens, r=<try>
Implement basic input validation for built-in attributes + Stabilize `unrestricted_attribute_tokens` Based on #57272 --- In accordance with the plan in https://internals.rust-lang.org/t/unrestricted-attribute-tokens-feature-status/8561: - The correct top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is enforced for built-in attributes. - For non-built-in non-macro attributes: - The key-value form is restricted to bare minimum required to support what we support on stable - unsuffixed literals (#34981). - Arbitrary token streams in remaining forms (`#[attr(token_stream)]`, `#[attr{token_stream}]`, `#[attr[token_stream]]` ) are now allowed without a feature gate, like in macro attributes. This will close #55208 once completed. Need to go through crater first.
2 parents c0bbc39 + 3b37f15 commit b9139d2

File tree

161 files changed

+1563
-1599
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

161 files changed

+1563
-1599
lines changed

Diff for: src/librustc/diagnostics.rs

+2-35
Original file line numberDiff line numberDiff line change
@@ -1180,27 +1180,6 @@ fn main() {
11801180
```
11811181
"##,
11821182

1183-
E0296: r##"
1184-
This error indicates that the given recursion limit could not be parsed. Ensure
1185-
that the value provided is a positive integer between quotes.
1186-
1187-
Erroneous code example:
1188-
1189-
```compile_fail,E0296
1190-
#![recursion_limit]
1191-
1192-
fn main() {}
1193-
```
1194-
1195-
And a working example:
1196-
1197-
```
1198-
#![recursion_limit="1000"]
1199-
1200-
fn main() {}
1201-
```
1202-
"##,
1203-
12041183
E0308: r##"
12051184
This error occurs when the compiler was unable to infer the concrete type of a
12061185
variable. It can occur for several cases, the most common of which is a
@@ -2093,20 +2072,6 @@ trait Foo { }
20932072
```
20942073
"##,
20952074

2096-
E0702: r##"
2097-
This error indicates that a `#[non_exhaustive]` attribute had a value. The
2098-
`#[non_exhaustive]` should be empty.
2099-
2100-
Examples of erroneous code:
2101-
2102-
```compile_fail,E0702
2103-
# #![feature(non_exhaustive)]
2104-
2105-
#[non_exhaustive(anything)]
2106-
struct Foo;
2107-
```
2108-
"##,
2109-
21102075
E0718: r##"
21112076
This error indicates that a `#[lang = ".."]` attribute was placed
21122077
on the wrong type of item.
@@ -2138,6 +2103,7 @@ register_diagnostics! {
21382103
E0280, // requirement is not satisfied
21392104
E0284, // cannot resolve type
21402105
// E0285, // overflow evaluation builtin bounds
2106+
// E0296, // replaced with a generic attribute input check
21412107
// E0300, // unexpanded macro
21422108
// E0304, // expected signed integer constant
21432109
// E0305, // expected constant
@@ -2180,4 +2146,5 @@ register_diagnostics! {
21802146
E0709, // multiple different lifetimes used in arguments of `async fn`
21812147
E0710, // an unknown tool name found in scoped lint
21822148
E0711, // a feature has been declared with conflicting stability attributes
2149+
// E0702, // replaced with a generic attribute input check
21832150
}

Diff for: src/librustc/hir/check_attr.rs

-15
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,6 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
137137
return;
138138
}
139139
}
140-
141-
if attr.meta_item_list().is_some() || attr.value_str().is_some() {
142-
struct_span_err!(self.tcx.sess,
143-
attr.span,
144-
E0702,
145-
"attribute should be empty")
146-
.span_label(item.span, "not empty")
147-
.emit();
148-
}
149140
}
150141

151142
/// Check if the `#[marker]` attribute on an `item` is valid.
@@ -160,12 +151,6 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
160151
return;
161152
}
162153
}
163-
164-
if !attr.is_word() {
165-
self.tcx.sess
166-
.struct_span_err(attr.span, "attribute should be empty")
167-
.emit();
168-
}
169154
}
170155

171156
/// Check if the `#[repr]` attributes on `item` are valid.

Diff for: src/librustc/lint/levels.rs

-2
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,6 @@ impl<'a> LintLevelsBuilder<'a> {
204204
let mut metas = if let Some(metas) = meta.meta_item_list() {
205205
metas
206206
} else {
207-
let mut err = bad_attr(meta.span);
208-
err.emit();
209207
continue;
210208
};
211209

Diff for: src/librustc/middle/recursion_limit.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,11 @@ use syntax::ast;
1111
use rustc_data_structures::sync::Once;
1212

1313
pub fn update_limits(sess: &Session, krate: &ast::Crate) {
14-
update_limit(sess, krate, &sess.recursion_limit, "recursion_limit",
15-
"recursion limit", 64);
16-
update_limit(sess, krate, &sess.type_length_limit, "type_length_limit",
17-
"type length limit", 1048576);
14+
update_limit(krate, &sess.recursion_limit, "recursion_limit", 64);
15+
update_limit(krate, &sess.type_length_limit, "type_length_limit", 1048576);
1816
}
1917

20-
fn update_limit(sess: &Session, krate: &ast::Crate, limit: &Once<usize>,
21-
name: &str, description: &str, default: usize) {
18+
fn update_limit(krate: &ast::Crate, limit: &Once<usize>, name: &str, default: usize) {
2219
for attr in &krate.attrs {
2320
if !attr.check_name(name) {
2421
continue;
@@ -30,10 +27,6 @@ fn update_limit(sess: &Session, krate: &ast::Crate, limit: &Once<usize>,
3027
return;
3128
}
3229
}
33-
34-
span_err!(sess, attr.span, E0296,
35-
"malformed {} attribute, expected #![{}=\"N\"]",
36-
description, name);
3730
}
3831
limit.set(default);
3932
}

Diff for: src/librustc/traits/on_unimplemented.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
157157
note: None,
158158
}))
159159
} else {
160-
return Err(parse_error(tcx, attr.span,
161-
"`#[rustc_on_unimplemented]` requires a value",
162-
"value required here",
163-
Some(r#"eg `#[rustc_on_unimplemented(message="foo")]`"#)));
160+
return Err(ErrorReported);
164161
};
165162
debug!("of_item({:?}/{:?}) = {:?}", trait_def_id, impl_def_id, result);
166163
result

Diff for: src/librustc/ty/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -2801,16 +2801,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
28012801
self.impl_polarity(def_id1) == self.impl_polarity(def_id2)
28022802
&& trait1_is_empty
28032803
&& trait2_is_empty
2804-
} else if self.features().marker_trait_attr {
2804+
} else {
28052805
let is_marker_impl = |def_id: DefId| -> bool {
28062806
let trait_ref = self.impl_trait_ref(def_id);
28072807
trait_ref.map_or(false, |tr| self.trait_def(tr.def_id).is_marker)
28082808
};
28092809
self.impl_polarity(def_id1) == self.impl_polarity(def_id2)
28102810
&& is_marker_impl(def_id1)
28112811
&& is_marker_impl(def_id2)
2812-
} else {
2813-
false
28142812
}
28152813
}
28162814

Diff for: src/librustc_driver/driver.rs

+11-20
Original file line numberDiff line numberDiff line change
@@ -1101,23 +1101,20 @@ where
11011101
ast_validation::check_crate(sess, &krate)
11021102
});
11031103

1104-
time(sess, "name resolution", || -> CompileResult {
1104+
time(sess, "name resolution", || {
11051105
resolver.resolve_crate(&krate);
1106-
Ok(())
1107-
})?;
1106+
});
11081107

11091108
// Needs to go *after* expansion to be able to check the results of macro expansion.
11101109
time(sess, "complete gated feature checking", || {
1111-
sess.track_errors(|| {
1112-
syntax::feature_gate::check_crate(
1113-
&krate,
1114-
&sess.parse_sess,
1115-
&sess.features_untracked(),
1116-
&attributes,
1117-
sess.opts.unstable_features,
1118-
);
1119-
})
1120-
})?;
1110+
syntax::feature_gate::check_crate(
1111+
&krate,
1112+
&sess.parse_sess,
1113+
&sess.features_untracked(),
1114+
&attributes,
1115+
sess.opts.unstable_features,
1116+
);
1117+
});
11211118

11221119
// Lower ast -> hir.
11231120
// First, we need to collect the dep_graph.
@@ -1530,13 +1527,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
15301527
}
15311528
None
15321529
}
1533-
None => {
1534-
session
1535-
.struct_span_err(a.span, "`crate_type` requires a value")
1536-
.note("for example: `#![crate_type=\"lib\"]`")
1537-
.emit();
1538-
None
1539-
}
1530+
None => None
15401531
}
15411532
} else {
15421533
None

Diff for: src/librustc_lint/builtin.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ use syntax::ast::Expr;
3535
use syntax::attr;
3636
use syntax::source_map::Spanned;
3737
use syntax::edition::Edition;
38-
use syntax::feature_gate::{AttributeGate, AttributeType, Stability, deprecated_attributes};
38+
use syntax::feature_gate::{AttributeGate, AttributeMeta, AttributeType};
39+
use syntax::feature_gate::{Stability, deprecated_attributes};
3940
use syntax_pos::{BytePos, Span, SyntaxContext};
4041
use syntax::symbol::keywords;
4142
use syntax::errors::{Applicability, DiagnosticBuilder};
@@ -752,7 +753,7 @@ impl EarlyLintPass for BadRepr {
752753
pub struct DeprecatedAttr {
753754
// This is not free to compute, so we want to keep it around, rather than
754755
// compute it for every attribute.
755-
depr_attrs: Vec<&'static (&'static str, AttributeType, AttributeGate)>,
756+
depr_attrs: Vec<&'static (&'static str, AttributeType, AttributeMeta::Type, AttributeGate)>,
756757
}
757758

758759
impl DeprecatedAttr {
@@ -771,7 +772,7 @@ impl LintPass for DeprecatedAttr {
771772

772773
impl EarlyLintPass for DeprecatedAttr {
773774
fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
774-
for &&(n, _, ref g) in &self.depr_attrs {
775+
for &&(n, _, _, ref g) in &self.depr_attrs {
775776
if attr.name() == n {
776777
if let &AttributeGate::Gated(Stability::Deprecated(link, suggestion),
777778
ref name,

Diff for: src/librustc_lint/unused.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
232232
fn check_attribute(&mut self, cx: &LateContext, attr: &ast::Attribute) {
233233
debug!("checking attribute: {:?}", attr);
234234
// Note that check_name() marks the attribute as used if it matches.
235-
for &(ref name, ty, _) in BUILTIN_ATTRIBUTES {
235+
for &(ref name, ty, ..) in BUILTIN_ATTRIBUTES {
236236
match ty {
237237
AttributeType::Whitelisted if attr.check_name(name) => {
238238
debug!("{:?} is Whitelisted", name);
@@ -256,7 +256,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
256256
cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
257257
// Is it a builtin attribute that must be used at the crate level?
258258
let known_crate = BUILTIN_ATTRIBUTES.iter()
259-
.find(|&&(builtin, ty, _)| name == builtin && ty == AttributeType::CrateLevel)
259+
.find(|&&(builtin, ty, ..)| name == builtin && ty == AttributeType::CrateLevel)
260260
.is_some();
261261

262262
// Has a plugin registered this attribute as one that must be used at

Diff for: src/librustc_plugin/load.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,7 @@ pub fn load_plugins(sess: &Session,
5050

5151
let plugins = match attr.meta_item_list() {
5252
Some(xs) => xs,
53-
None => {
54-
call_malformed_plugin_attribute(sess, attr.span);
55-
continue;
56-
}
53+
None => continue,
5754
};
5855

5956
for plugin in plugins {

Diff for: src/librustc_typeck/collect.rs

+1-14
Original file line numberDiff line numberDiff line change
@@ -2134,12 +2134,7 @@ fn from_target_feature(
21342134
) {
21352135
let list = match attr.meta_item_list() {
21362136
Some(list) => list,
2137-
None => {
2138-
let msg = "#[target_feature] attribute must be of the form \
2139-
#[target_feature(..)]";
2140-
tcx.sess.span_err(attr.span, &msg);
2141-
return;
2142-
}
2137+
None => return,
21432138
};
21442139
let rust_features = tcx.features();
21452140
for item in list {
@@ -2337,14 +2332,6 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen
23372332
).emit();
23382333
}
23392334
codegen_fn_attrs.export_name = Some(s);
2340-
} else {
2341-
struct_span_err!(
2342-
tcx.sess,
2343-
attr.span,
2344-
E0558,
2345-
"`export_name` attribute has invalid format"
2346-
).span_label(attr.span, "did you mean #[export_name=\"*\"]?")
2347-
.emit();
23482335
}
23492336
} else if attr.check_name("target_feature") {
23502337
if tcx.fn_sig(id).unsafety() == Unsafety::Normal {

Diff for: src/librustc_typeck/diagnostics.rs

+1-23
Original file line numberDiff line numberDiff line change
@@ -3785,29 +3785,6 @@ For more information about the inline attribute, https:
37853785
read://doc.rust-lang.org/reference.html#inline-attributes
37863786
"##,
37873787

3788-
E0558: r##"
3789-
The `export_name` attribute was malformed.
3790-
3791-
Erroneous code example:
3792-
3793-
```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
3794-
#[export_name] // error: `export_name` attribute has invalid format
3795-
pub fn something() {}
3796-
3797-
fn main() {}
3798-
```
3799-
3800-
The `export_name` attribute expects a string in order to determine the name of
3801-
the exported symbol. Example:
3802-
3803-
```
3804-
#[export_name = "some_function"] // ok!
3805-
pub fn something() {}
3806-
3807-
fn main() {}
3808-
```
3809-
"##,
3810-
38113788
E0559: r##"
38123789
An unknown field was specified into an enum's structure variant.
38133790
@@ -4881,6 +4858,7 @@ register_diagnostics! {
48814858
// E0372, // coherence not object safe
48824859
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
48834860
// between structures with the same definition
4861+
// E0558, // replaced with a generic attribute input check
48844862
E0533, // `{}` does not name a unit variant, unit struct or a constant
48854863
// E0563, // cannot determine a type for this `impl Trait`: {} // removed in 6383de15
48864864
E0564, // only named lifetimes are allowed in `impl Trait`,

Diff for: src/libsyntax/attr/builtin.rs

-3
Original file line numberDiff line numberDiff line change
@@ -436,9 +436,6 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
436436
}
437437
_ => unreachable!()
438438
}
439-
} else {
440-
span_err!(diagnostic, attr.span(), E0548, "incorrect stability attribute type");
441-
continue
442439
}
443440
}
444441

Diff for: src/libsyntax/config.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,9 @@ impl<'a> StripUnconfigured<'a> {
187187
true
188188
};
189189

190-
let meta_item = if let Some(meta_item) = attr.meta() {
191-
meta_item
192-
} else {
193-
// Not a well-formed meta-item. Why? We don't know.
194-
return error(attr.span, "`cfg` is not a well-formed meta-item",
195-
"#[cfg(/* predicate */)]");
190+
let meta_item = match attr.parse_meta(self.sess) {
191+
Ok(meta_item) => meta_item,
192+
Err(mut err) => { err.emit(); return true; }
196193
};
197194
let nested_meta_items = if let Some(nested_meta_items) = meta_item.meta_item_list() {
198195
nested_meta_items

Diff for: src/libsyntax/diagnostic_list.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -389,12 +389,12 @@ register_diagnostics! {
389389
E0545, // incorrect 'issue'
390390
E0546, // missing 'feature'
391391
E0547, // missing 'issue'
392-
E0548, // incorrect stability attribute type
392+
// E0548, // replaced with a generic attribute input check
393393
E0549, // rustc_deprecated attribute must be paired with either stable or unstable attribute
394394
E0550, // multiple deprecated attributes
395395
E0551, // incorrect meta item
396396
E0553, // multiple rustc_const_unstable attributes
397-
E0555, // malformed feature attribute, expected #![feature(...)]
397+
// E0555, // replaced with a generic attribute input check
398398
E0556, // malformed feature, expected just one word
399399
E0584, // file for module `..` found at both .. and ..
400400
E0629, // missing 'feature' (rustc_const_unstable)

Diff for: src/libsyntax/ext/derive.rs

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ pub fn collect_derives(cx: &mut ExtCtxt, attrs: &mut Vec<ast::Attribute>) -> Vec
1515
if attr.path != "derive" {
1616
return true;
1717
}
18+
if !attr.is_meta_item_list() {
19+
cx.span_err(attr.span, "attribute must be of the form `#[derive(...)]`");
20+
return false;
21+
}
1822

1923
match attr.parse_list(cx.parse_sess,
2024
|parser| parser.parse_path_allowing_meta(PathStyle::Mod)) {

0 commit comments

Comments
 (0)