Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ use rustc_abi::{CVariadicStatus, CanonAbi, ExternAbi, InterruptKind};
use rustc_ast::visit::{AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor, walk_list};
use rustc_ast::*;
use rustc_ast_pretty::pprust::{self, State};
use rustc_attr_parsing::validate_attr;
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::{DiagCtxtHandle, Diagnostic, LintBuffer};
use rustc_feature::Features;
Expand Down Expand Up @@ -1402,10 +1401,6 @@ fn validate_generic_param_order(dcx: DiagCtxtHandle<'_>, generics: &[GenericPara
}

impl Visitor<'_> for AstValidator<'_> {
fn visit_attribute(&mut self, attr: &Attribute) {
validate_attr::check_attr(&self.sess.psess, attr);
}

fn visit_ty(&mut self, ty: &Ty) {
self.visit_ty_common(ty);
self.walk_ty(ty)
Expand Down
16 changes: 15 additions & 1 deletion compiler/rustc_attr_parsing/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use crate::diagnostics::ParsedDescription;
use crate::generated::GeneratedAttrState;
use crate::parser::{AllowExprMetavar, ArgParser, PathParser, RefPathParser};
use crate::synthetic::SyntheticAttrState;
use crate::validate_attr::parse_meta;
use crate::{AttributeTemplate, ShouldEmit, diagnostics};

pub struct EmitAttribute(
Expand Down Expand Up @@ -359,7 +360,8 @@ impl<'sess> AttributeParser<'sess> {
n.item.path.segments.iter().map(|seg| seg.ident.name).collect::<Vec<_>>();
let inner_span = lower_span(n.item.span);

if let Some(accept) = ATTRIBUTE_PARSERS.accepters.get(parts.as_slice()) {
let accepter = ATTRIBUTE_PARSERS.accepters.get(parts.as_slice());
if let Some(accept) = accepter {
self.check_attribute_safety(
&attr_path,
inner_span,
Expand Down Expand Up @@ -492,6 +494,18 @@ impl<'sess> AttributeParser<'sess> {

attributes.push(attr);
};

if accepter.is_none()
&& let rustc_ast::AttrArgs::Eq { .. } = n.item.args
Comment thread
mejrs marked this conversation as resolved.
Resolved
{
// All key-value attributes are restricted to meta-item syntax.
match parse_meta(&self.sess.psess, &attr) {
Ok(_) => {}
Err(err) => {
err.emit();
}
}
}
}
}
}
Expand Down
51 changes: 1 addition & 50 deletions compiler/rustc_attr_parsing/src/validate_attr.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Meta-syntax validation logic of attributes for post-expansion.

use std::convert::identity;
use std::slice;

use rustc_ast::SyntheticAttr::CfgAttrTrace;
use rustc_ast::token::Delimiter;
Expand All @@ -12,61 +11,13 @@ use rustc_ast::{
};
use rustc_attr_ir::AttrPath;
use rustc_errors::{Applicability, Diagnostic, PResult};
use rustc_feature::BUILTIN_ATTRIBUTE_SET;
use rustc_lint_defs::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
use rustc_parse::parse_in;
use rustc_session::diagnostics::report_lit_error;
use rustc_session::parse::ParseSess;
use rustc_span::{Span, Symbol, sym};

use crate::{AttributeParser, AttributeTemplate, diagnostics as errors, template};

pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
use ast::SyntheticAttr::*;
match &attr.kind {
AttrKind::Normal(_) => {}
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_))
| AttrKind::DocComment(..)
| AttrKind::Generated(..) => return,
}

let builtin_attr_info = attr.name().and_then(|name| BUILTIN_ATTRIBUTE_SET.get(&name));

// Check input tokens for built-in and key-value attributes.
if let Some(name) = builtin_attr_info {
if AttributeParser::is_parsed_attribute(slice::from_ref(name)) {
return;
}
match parse_meta(psess, attr) {
// Don't check safety again, we just did that
Ok(meta) => {
// FIXME The only unparsed builtin attributes that are left are the lint attributes, so we can hardcode the template here
let lint_attrs = [sym::forbid, sym::allow, sym::warn, sym::deny, sym::expect];
assert!(lint_attrs.contains(name));

let template = template!(
List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
"https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
);
check_builtin_meta_item(psess, &meta, attr.style, *name, template, false)
}
Err(err) => {
err.emit();
}
}
} else {
let attr_item = attr.get_normal_item();
if let AttrArgs::Eq { .. } = attr_item.args {
// All key-value attributes are restricted to meta-item syntax.
match parse_meta(psess, attr) {
Ok(_) => {}
Err(err) => {
err.emit();
}
}
}
}
}
use crate::{AttributeTemplate, diagnostics as errors};

pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, MetaItem> {
let item = attr.get_normal_item();
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2235,7 +2235,6 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
let mut attrs = attrs.iter().peekable();
let mut span: Option<Span> = None;
while let Some(attr) = attrs.next() {
validate_attr::check_attr(&self.cx.sess.psess, attr);
AttributeParser::parse_limited_all(
self.cx.sess,
slice::from_ref(attr),
Expand Down
24 changes: 12 additions & 12 deletions tests/ui/attributes/issue-90873.stderr
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
error: attribute value must be a literal
--> $DIR/issue-90873.rs:1:6
|
LL | #![u=||{static d=||1;}]
| ^^^^^^^^^^^^^^^^^

error: attribute value must be a literal
--> $DIR/issue-90873.rs:6:6
|
LL | #![a={impl std::ops::Neg for i8 {}}]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: cannot find attribute `u` in this scope
--> $DIR/issue-90873.rs:1:4
|
Expand All @@ -22,6 +10,18 @@ error: cannot find attribute `a` in this scope
LL | #![a={impl std::ops::Neg for i8 {}}]
| ^

error: attribute value must be a literal
--> $DIR/issue-90873.rs:1:6
|
LL | #![u=||{static d=||1;}]
| ^^^^^^^^^^^^^^^^^

error: attribute value must be a literal
--> $DIR/issue-90873.rs:6:6
|
LL | #![a={impl std::ops::Neg for i8 {}}]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0601]: `main` function not found in crate `issue_90873`
--> $DIR/issue-90873.rs:6:37
|
Expand Down
24 changes: 12 additions & 12 deletions tests/ui/attributes/key-value-nested-attr-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,6 @@ error: `cfg` is not supported in this position
LL | #[clippy::insubstantial = #[cfg(true)] "insignificant"]
| ^^^^^^^^^^^^

error: this attribute is not allowed in this context
--> $DIR/key-value-nested-attr-fail.rs:51:24
|
LL | #[clippy::immaterial = #[allow(dead_code)] "incorporeal"]
| ^^^^^^^^^^^^^^^^^^^

error: this attribute is not allowed in this context
--> $DIR/key-value-nested-attr-fail.rs:59:9
|
LL | #[arg = #[allow(dead_code)] 0]
| ^^^^^^^^^^^^^^^^^^^

error: this attribute is not allowed in this context
--> $DIR/key-value-nested-attr-fail.rs:17:10
|
Expand Down Expand Up @@ -61,6 +49,18 @@ error: this attribute is not allowed in this context
LL | repr(Rust)
| ^^^^^^^^^^

error: this attribute is not allowed in this context
--> $DIR/key-value-nested-attr-fail.rs:51:24
|
LL | #[clippy::immaterial = #[allow(dead_code)] "incorporeal"]
| ^^^^^^^^^^^^^^^^^^^

error: this attribute is not allowed in this context
--> $DIR/key-value-nested-attr-fail.rs:59:9
|
LL | #[arg = #[allow(dead_code)] 0]
| ^^^^^^^^^^^^^^^^^^^

error: attribute value must be a literal
--> $DIR/key-value-nested-attr-fail.rs:65:25
|
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/attributes/unused-item-in-attr.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
error: attribute value must be a literal
--> $DIR/unused-item-in-attr.rs:1:7
|
LL | #[w = { extern crate alloc; }]
| ^^^^^^^^^^^^^^^^^^^^^^^

error: cannot find attribute `w` in this scope
--> $DIR/unused-item-in-attr.rs:1:3
|
LL | #[w = { extern crate alloc; }]
| ^

error: attribute value must be a literal
--> $DIR/unused-item-in-attr.rs:1:7
|
LL | #[w = { extern crate alloc; }]
| ^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

12 changes: 6 additions & 6 deletions tests/ui/consts/issue-90878-2.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
error: attribute value must be a literal
--> $DIR/issue-90878-2.rs:1:7
|
LL | #![l=|x|[b;x ]]
| ^^^^^^^^^

error: cannot find attribute `l` in this scope
--> $DIR/issue-90878-2.rs:1:5
|
LL | #![l=|x|[b;x ]]
| ^

error: attribute value must be a literal
--> $DIR/issue-90878-2.rs:1:7
|
LL | #![l=|x|[b;x ]]
| ^^^^^^^^^

error: aborting due to 2 previous errors

8 changes: 8 additions & 0 deletions tests/ui/diagnostic_namespace/invalid_lit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#[diagnostic::on_unimplemented = 1 + 1]
//~^ ERROR attribute value must be a literal
#[diagnostic::not_exist = 1 + 1]
//~^ ERROR attribute value must be a literal
//~| WARN unknown diagnostic attribute
fn main() {

}
22 changes: 22 additions & 0 deletions tests/ui/diagnostic_namespace/invalid_lit.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
error: attribute value must be a literal
--> $DIR/invalid_lit.rs:1:34
|
LL | #[diagnostic::on_unimplemented = 1 + 1]
| ^^^^^

error: attribute value must be a literal
--> $DIR/invalid_lit.rs:3:27
|
LL | #[diagnostic::not_exist = 1 + 1]
| ^^^^^

warning: unknown diagnostic attribute
--> $DIR/invalid_lit.rs:3:15
|
LL | #[diagnostic::not_exist = 1 + 1]
| ^^^^^^^^^
|
= note: `#[warn(unknown_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default

error: aborting due to 2 previous errors; 1 warning emitted

Loading