From 49db8a5a999f0908b5bf74b88a2d72a4f4dddf48 Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Tue, 9 Jul 2024 19:06:49 -0500 Subject: [PATCH] Add toggle for `parse_meta_item` unsafe parsing This makes it possible for the `unsafe(...)` syntax to only be valid at the top level, and the `NestedMetaItem`s will automatically reject `unsafe(...)`. --- compiler/rustc_builtin_macros/messages.ftl | 3 - compiler/rustc_builtin_macros/src/cfg.rs | 3 +- compiler/rustc_builtin_macros/src/derive.rs | 13 +-- compiler/rustc_builtin_macros/src/errors.rs | 7 -- compiler/rustc_expand/src/config.rs | 4 +- compiler/rustc_interface/src/interface.rs | 5 +- compiler/rustc_parse/messages.ftl | 1 + compiler/rustc_parse/src/errors.rs | 1 + compiler/rustc_parse/src/parser/attr.rs | 21 ++++- compiler/rustc_parse/src/validate_attr.rs | 82 +++++++++---------- .../unsafe/derive-unsafe-attributes.rs | 8 +- .../unsafe/derive-unsafe-attributes.stderr | 59 +++++++++++-- .../unsafe/double-unsafe-attributes.stderr | 2 +- .../extraneous-unsafe-attributes.stderr | 16 ++-- .../unsafe/proc-unsafe-attributes.rs | 10 +++ .../unsafe/proc-unsafe-attributes.stderr | 77 +++++++++++++++-- .../ui/attributes/unsafe/unsafe-attributes.rs | 6 ++ .../unsafe/unsafe-safe-attribute.stderr | 2 +- .../unsafe-safe-attribute_diagnostic.stderr | 2 +- 19 files changed, 226 insertions(+), 96 deletions(-) diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index a30ab236213a0..ae3cce40f5daa 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -115,9 +115,6 @@ builtin_macros_derive_path_args_list = traits in `#[derive(...)]` don't accept a builtin_macros_derive_path_args_value = traits in `#[derive(...)]` don't accept values .suggestion = remove the value -builtin_macros_derive_unsafe_path = traits in `#[derive(...)]` don't accept `unsafe(...)` - .suggestion = remove the `unsafe(...)` - builtin_macros_env_not_defined = environment variable `{$var}` not defined at compile time .cargo = Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead .custom = use `std::env::var({$var_expr})` to read the variable at run time diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index ceb62230ece96..de198115fa00b 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -6,6 +6,7 @@ use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; use rustc_errors::PResult; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult}; +use rustc_parse::parser::attr::AllowLeadingUnsafe; use rustc_span::Span; use {rustc_ast as ast, rustc_attr as attr}; @@ -42,7 +43,7 @@ fn parse_cfg<'a>(cx: &ExtCtxt<'a>, span: Span, tts: TokenStream) -> PResult<'a, return Err(cx.dcx().create_err(errors::RequiresCfgPattern { span })); } - let cfg = p.parse_meta_item()?; + let cfg = p.parse_meta_item(AllowLeadingUnsafe::Yes)?; let _ = p.eat(&token::Comma); diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index c540ff4e1de82..57bddf0ab60ad 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -1,5 +1,5 @@ use rustc_ast as ast; -use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, Safety, StmtKind}; +use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind}; use rustc_expand::base::{ Annotatable, DeriveResolution, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier, }; @@ -62,7 +62,6 @@ impl MultiItemModifier for Expander { // Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the // paths. report_path_args(sess, meta); - report_unsafe_args(sess, meta); meta.path.clone() }) .map(|path| DeriveResolution { @@ -162,13 +161,3 @@ fn report_path_args(sess: &Session, meta: &ast::MetaItem) { } } } - -fn report_unsafe_args(sess: &Session, meta: &ast::MetaItem) { - match meta.unsafety { - Safety::Unsafe(span) => { - sess.dcx().emit_err(errors::DeriveUnsafePath { span }); - } - Safety::Default => {} - Safety::Safe(_) => unreachable!(), - } -} diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 0a4f07709c7fd..93fc9bcb9d206 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -297,13 +297,6 @@ pub(crate) struct DerivePathArgsValue { pub(crate) span: Span, } -#[derive(Diagnostic)] -#[diag(builtin_macros_derive_unsafe_path)] -pub(crate) struct DeriveUnsafePath { - #[primary_span] - pub(crate) span: Span, -} - #[derive(Diagnostic)] #[diag(builtin_macros_no_default_variant)] #[help] diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index d46ec7a9ac0fe..f6bf9f5e89f2f 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -8,7 +8,9 @@ use rustc_ast::tokenstream::{ use rustc_ast::{self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem, NodeId}; use rustc_attr as attr; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; -use rustc_feature::{AttributeSafety, Features, ACCEPTED_FEATURES, REMOVED_FEATURES, UNSTABLE_FEATURES}; +use rustc_feature::{ + AttributeSafety, Features, ACCEPTED_FEATURES, REMOVED_FEATURES, UNSTABLE_FEATURES, +}; use rustc_lint_defs::BuiltinLintDiag; use rustc_parse::validate_attr; use rustc_session::parse::feature_err; diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 886b043af2460..04e2b7d45dc93 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -15,6 +15,7 @@ use rustc_middle::ty; use rustc_middle::ty::CurrentGcx; use rustc_middle::util::Providers; use rustc_parse::new_parser_from_source_str; +use rustc_parse::parser::attr::AllowLeadingUnsafe; use rustc_query_impl::QueryCtxt; use rustc_query_system::query::print_query_stack; use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName}; @@ -67,7 +68,7 @@ pub(crate) fn parse_cfg(dcx: DiagCtxtHandle<'_>, cfgs: Vec) -> Cfg { } match new_parser_from_source_str(&psess, filename, s.to_string()) { - Ok(mut parser) => match parser.parse_meta_item() { + Ok(mut parser) => match parser.parse_meta_item(AllowLeadingUnsafe::No) { Ok(meta_item) if parser.token == token::Eof => { if meta_item.path.segments.len() != 1 { error!("argument key must be an identifier"); @@ -173,7 +174,7 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec) -> Ch } }; - let meta_item = match parser.parse_meta_item() { + let meta_item = match parser.parse_meta_item(AllowLeadingUnsafe::Yes) { Ok(meta_item) if parser.token == token::Eof => meta_item, Ok(..) => expected_error(), Err(err) => { diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 391a57917768d..e13306b9d9fe2 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -365,6 +365,7 @@ parse_inner_doc_comment_not_permitted = expected outer doc comment .sugg_change_inner_to_outer = to annotate the {$item}, change the doc comment from inner to outer style parse_invalid_attr_unsafe = `{$name}` is not an unsafe attribute + .label = this is not an unsafe attribute .suggestion = remove the `unsafe(...)` .note = extraneous unsafe is not allowed in attributes diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 1076280370815..e5b0dc804a5e8 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -3188,6 +3188,7 @@ pub(crate) struct DotDotRangeAttribute { #[note] pub struct InvalidAttrUnsafe { #[primary_span] + #[label] pub span: Span, pub name: Path, } diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 12b9414d1f760..f34ef071e21ec 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -31,6 +31,12 @@ enum OuterAttributeType { Attribute, } +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum AllowLeadingUnsafe { + Yes, + No, +} + impl<'a> Parser<'a> { /// Parses attributes that appear before an item. pub(super) fn parse_outer_attributes(&mut self) -> PResult<'a, AttrWrapper> { @@ -332,7 +338,7 @@ impl<'a> Parser<'a> { /// Parses `cfg_attr(pred, attr_item_list)` where `attr_item_list` is comma-delimited. pub fn parse_cfg_attr(&mut self) -> PResult<'a, (ast::MetaItem, Vec<(ast::AttrItem, Span)>)> { - let cfg_predicate = self.parse_meta_item()?; + let cfg_predicate = self.parse_meta_item(AllowLeadingUnsafe::No)?; self.expect(&token::Comma)?; // Presumably, the majority of the time there will only be one attr. @@ -368,7 +374,10 @@ impl<'a> Parser<'a> { /// MetaItem = SimplePath ( '=' UNSUFFIXED_LIT | '(' MetaSeq? ')' )? ; /// MetaSeq = MetaItemInner (',' MetaItemInner)* ','? ; /// ``` - pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> { + pub fn parse_meta_item( + &mut self, + unsafe_allowed: AllowLeadingUnsafe, + ) -> PResult<'a, ast::MetaItem> { // We can't use `maybe_whole` here because it would bump in the `None` // case, which we don't want. if let token::Interpolated(nt) = &self.token.kind @@ -384,7 +393,11 @@ impl<'a> Parser<'a> { } let lo = self.token.span; - let is_unsafe = self.eat_keyword(kw::Unsafe); + let is_unsafe = if unsafe_allowed == AllowLeadingUnsafe::Yes { + self.eat_keyword(kw::Unsafe) + } else { + false + }; let unsafety = if is_unsafe { let unsafe_span = self.prev_token.span; self.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span); @@ -427,7 +440,7 @@ impl<'a> Parser<'a> { Err(err) => err.cancel(), // we provide a better error below } - match self.parse_meta_item() { + match self.parse_meta_item(AllowLeadingUnsafe::No) { Ok(mi) => return Ok(ast::NestedMetaItem::MetaItem(mi)), Err(err) => err.cancel(), // we provide a better error below } diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index af2db17184086..a64c00f3b6cbc 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -163,53 +163,53 @@ pub fn check_attribute_safety( safety: AttributeSafety, attr: &Attribute, ) { - if features.unsafe_attributes { - let attr_item = attr.get_normal_item(); + if !features.unsafe_attributes { + return; + } - if safety == AttributeSafety::Unsafe { - if let ast::Safety::Default = attr_item.unsafety { - let path_span = attr_item.path.span; + let attr_item = attr.get_normal_item(); - // If the `attr_item`'s span is not from a macro, then just suggest - // wrapping it in `unsafe(...)`. Otherwise, we suggest putting the - // `unsafe(`, `)` right after and right before the opening and closing - // square bracket respectively. - let diag_span = if attr_item.span().can_be_used_for_suggestions() { - attr_item.span() - } else { - attr.span - .with_lo(attr.span.lo() + BytePos(2)) - .with_hi(attr.span.hi() - BytePos(1)) - }; + if safety == AttributeSafety::Unsafe { + if let ast::Safety::Default = attr_item.unsafety { + let path_span = attr_item.path.span; - if attr.span.at_least_rust_2024() { - psess.dcx().emit_err(errors::UnsafeAttrOutsideUnsafe { - span: path_span, - suggestion: errors::UnsafeAttrOutsideUnsafeSuggestion { - left: diag_span.shrink_to_lo(), - right: diag_span.shrink_to_hi(), - }, - }); - } else { - psess.buffer_lint( - UNSAFE_ATTR_OUTSIDE_UNSAFE, - path_span, - ast::CRATE_NODE_ID, - BuiltinLintDiag::UnsafeAttrOutsideUnsafe { - attribute_name_span: path_span, - sugg_spans: (diag_span.shrink_to_lo(), diag_span.shrink_to_hi()), - }, - ); - } - } - } else { - if let Safety::Unsafe(unsafe_span) = attr_item.unsafety { - psess.dcx().emit_err(errors::InvalidAttrUnsafe { - span: unsafe_span, - name: attr_item.path.clone(), + // If the `attr_item`'s span is not from a macro, then just suggest + // wrapping it in `unsafe(...)`. Otherwise, we suggest putting the + // `unsafe(`, `)` right after and right before the opening and closing + // square bracket respectively. + let diag_span = if attr_item.span().can_be_used_for_suggestions() { + attr_item.span() + } else { + attr.span.with_lo(attr.span.lo() + BytePos(2)).with_hi(attr.span.hi() - BytePos(1)) + }; + + if attr.span.at_least_rust_2024() { + psess.dcx().emit_err(errors::UnsafeAttrOutsideUnsafe { + span: path_span, + suggestion: errors::UnsafeAttrOutsideUnsafeSuggestion { + left: diag_span.shrink_to_lo(), + right: diag_span.shrink_to_hi(), + }, }); + } else { + psess.buffer_lint( + UNSAFE_ATTR_OUTSIDE_UNSAFE, + path_span, + ast::CRATE_NODE_ID, + BuiltinLintDiag::UnsafeAttrOutsideUnsafe { + attribute_name_span: path_span, + sugg_spans: (diag_span.shrink_to_lo(), diag_span.shrink_to_hi()), + }, + ); } } + } else { + if let Safety::Unsafe(unsafe_span) = attr_item.unsafety { + psess.dcx().emit_err(errors::InvalidAttrUnsafe { + span: unsafe_span, + name: attr_item.path.clone(), + }); + } } } diff --git a/tests/ui/attributes/unsafe/derive-unsafe-attributes.rs b/tests/ui/attributes/unsafe/derive-unsafe-attributes.rs index 7f0d6a0cf8b91..b8edb4aab907b 100644 --- a/tests/ui/attributes/unsafe/derive-unsafe-attributes.rs +++ b/tests/ui/attributes/unsafe/derive-unsafe-attributes.rs @@ -1,6 +1,12 @@ #![feature(unsafe_attributes)] -#[derive(unsafe(Debug))] //~ ERROR: traits in `#[derive(...)]` don't accept `unsafe(...)` +#[derive(unsafe(Debug))] +//~^ ERROR: expected identifier, found keyword `unsafe` +//~| ERROR: traits in `#[derive(...)]` don't accept arguments +//~| ERROR: expected identifier, found keyword `unsafe` +//~| ERROR: expected identifier, found keyword `unsafe` +//~| ERROR: cannot find derive macro `r#unsafe` in this scope +//~| ERROR: cannot find derive macro `r#unsafe` in this scope struct Foo; #[unsafe(derive(Debug))] //~ ERROR: is not an unsafe attribute diff --git a/tests/ui/attributes/unsafe/derive-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/derive-unsafe-attributes.stderr index 22010c61b5f52..c40a5512fd5cd 100644 --- a/tests/ui/attributes/unsafe/derive-unsafe-attributes.stderr +++ b/tests/ui/attributes/unsafe/derive-unsafe-attributes.stderr @@ -1,16 +1,65 @@ -error: traits in `#[derive(...)]` don't accept `unsafe(...)` +error: expected identifier, found keyword `unsafe` --> $DIR/derive-unsafe-attributes.rs:3:10 | LL | #[derive(unsafe(Debug))] - | ^^^^^^ + | ^^^^^^ expected identifier, found keyword + | +help: escape `unsafe` to use it as an identifier + | +LL | #[derive(r#unsafe(Debug))] + | ++ + +error: traits in `#[derive(...)]` don't accept arguments + --> $DIR/derive-unsafe-attributes.rs:3:16 + | +LL | #[derive(unsafe(Debug))] + | ^^^^^^^ help: remove the arguments error: `derive` is not an unsafe attribute - --> $DIR/derive-unsafe-attributes.rs:6:3 + --> $DIR/derive-unsafe-attributes.rs:12:3 | LL | #[unsafe(derive(Debug))] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes -error: aborting due to 2 previous errors +error: expected identifier, found keyword `unsafe` + --> $DIR/derive-unsafe-attributes.rs:3:10 + | +LL | #[derive(unsafe(Debug))] + | ^^^^^^ expected identifier, found keyword + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: escape `unsafe` to use it as an identifier + | +LL | #[derive(r#unsafe(Debug))] + | ++ + +error: expected identifier, found keyword `unsafe` + --> $DIR/derive-unsafe-attributes.rs:3:10 + | +LL | #[derive(unsafe(Debug))] + | ^^^^^^ expected identifier, found keyword + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: escape `unsafe` to use it as an identifier + | +LL | #[derive(r#unsafe(Debug))] + | ++ + +error: cannot find derive macro `r#unsafe` in this scope + --> $DIR/derive-unsafe-attributes.rs:3:10 + | +LL | #[derive(unsafe(Debug))] + | ^^^^^^ + +error: cannot find derive macro `r#unsafe` in this scope + --> $DIR/derive-unsafe-attributes.rs:3:10 + | +LL | #[derive(unsafe(Debug))] + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 7 previous errors diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr index ea82bac6df07b..950b2636993c1 100644 --- a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr +++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr @@ -13,7 +13,7 @@ error: `r#unsafe` is not an unsafe attribute --> $DIR/double-unsafe-attributes.rs:3:3 | LL | #[unsafe(unsafe(no_mangle))] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes diff --git a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr index a2e56087d1615..f39074b613d40 100644 --- a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr +++ b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr @@ -2,7 +2,7 @@ error: `cfg` is not an unsafe attribute --> $DIR/extraneous-unsafe-attributes.rs:5:3 | LL | #[unsafe(cfg(any()))] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes @@ -10,7 +10,7 @@ error: `cfg_attr` is not an unsafe attribute --> $DIR/extraneous-unsafe-attributes.rs:8:3 | LL | #[unsafe(cfg_attr(any(), allow(dead_code)))] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes @@ -18,7 +18,7 @@ error: `test` is not an unsafe attribute --> $DIR/extraneous-unsafe-attributes.rs:11:3 | LL | #[unsafe(test)] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes @@ -26,7 +26,7 @@ error: `ignore` is not an unsafe attribute --> $DIR/extraneous-unsafe-attributes.rs:14:3 | LL | #[unsafe(ignore = "test")] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes @@ -34,7 +34,7 @@ error: `should_panic` is not an unsafe attribute --> $DIR/extraneous-unsafe-attributes.rs:17:3 | LL | #[unsafe(should_panic(expected = "test"))] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes @@ -42,7 +42,7 @@ error: `macro_use` is not an unsafe attribute --> $DIR/extraneous-unsafe-attributes.rs:20:3 | LL | #[unsafe(macro_use)] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes @@ -50,7 +50,7 @@ error: `macro_export` is not an unsafe attribute --> $DIR/extraneous-unsafe-attributes.rs:22:7 | LL | #[unsafe(macro_export)] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes @@ -58,7 +58,7 @@ error: `used` is not an unsafe attribute --> $DIR/extraneous-unsafe-attributes.rs:28:3 | LL | #[unsafe(used)] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes diff --git a/tests/ui/attributes/unsafe/proc-unsafe-attributes.rs b/tests/ui/attributes/unsafe/proc-unsafe-attributes.rs index caf6c6dc8ffde..f29a5b3252b0a 100644 --- a/tests/ui/attributes/unsafe/proc-unsafe-attributes.rs +++ b/tests/ui/attributes/unsafe/proc-unsafe-attributes.rs @@ -13,6 +13,7 @@ pub fn b() {} #[proc_macro_derive(unsafe(Foo))] //~^ ERROR attribute is only usable with crates of the `proc-macro` crate type +//~| ERROR: expected identifier, found keyword `unsafe` pub fn c() {} #[unsafe(proc_macro_attribute)] @@ -24,4 +25,13 @@ pub fn d() {} //~^ ERROR: is not an unsafe attribute pub fn e() {} +#[unsafe(allow(unsafe(dead_code)))] +//~^ ERROR: is not an unsafe attribute +//~| ERROR: malformed lint attribute input +//~| ERROR: malformed lint attribute input +//~| ERROR: expected identifier, found keyword `unsafe` +//~| ERROR: malformed lint attribute input +//~| ERROR: malformed lint attribute input +pub fn f() {} + fn main() {} diff --git a/tests/ui/attributes/unsafe/proc-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/proc-unsafe-attributes.stderr index 346d2c2e9ae69..79d34d458bd6c 100644 --- a/tests/ui/attributes/unsafe/proc-unsafe-attributes.stderr +++ b/tests/ui/attributes/unsafe/proc-unsafe-attributes.stderr @@ -1,8 +1,22 @@ +error[E0452]: malformed lint attribute input + --> $DIR/proc-unsafe-attributes.rs:28:16 + | +LL | #[unsafe(allow(unsafe(dead_code)))] + | ^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/proc-unsafe-attributes.rs:28:16 + | +LL | #[unsafe(allow(unsafe(dead_code)))] + | ^^^^^^^^^^^^^^^^^ bad attribute argument + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `proc_macro` is not an unsafe attribute --> $DIR/proc-unsafe-attributes.rs:3:3 | LL | #[unsafe(proc_macro)] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes @@ -10,26 +24,56 @@ error: `proc_macro_derive` is not an unsafe attribute --> $DIR/proc-unsafe-attributes.rs:9:3 | LL | #[unsafe(proc_macro_derive(Foo))] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes +error: expected identifier, found keyword `unsafe` + --> $DIR/proc-unsafe-attributes.rs:14:21 + | +LL | #[proc_macro_derive(unsafe(Foo))] + | ^^^^^^ expected identifier, found keyword + | +help: escape `unsafe` to use it as an identifier + | +LL | #[proc_macro_derive(r#unsafe(Foo))] + | ++ + error: `proc_macro_attribute` is not an unsafe attribute - --> $DIR/proc-unsafe-attributes.rs:18:3 + --> $DIR/proc-unsafe-attributes.rs:19:3 | LL | #[unsafe(proc_macro_attribute)] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes error: `allow` is not an unsafe attribute - --> $DIR/proc-unsafe-attributes.rs:23:3 + --> $DIR/proc-unsafe-attributes.rs:24:3 | LL | #[unsafe(allow(dead_code))] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes +error: `allow` is not an unsafe attribute + --> $DIR/proc-unsafe-attributes.rs:28:3 + | +LL | #[unsafe(allow(unsafe(dead_code)))] + | ^^^^^^ this is not an unsafe attribute + | + = note: extraneous unsafe is not allowed in attributes + +error: expected identifier, found keyword `unsafe` + --> $DIR/proc-unsafe-attributes.rs:28:16 + | +LL | #[unsafe(allow(unsafe(dead_code)))] + | ^^^^^^ expected identifier, found keyword + | +help: escape `unsafe` to use it as an identifier + | +LL | #[unsafe(allow(r#unsafe(dead_code)))] + | ++ + error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type --> $DIR/proc-unsafe-attributes.rs:3:1 | @@ -49,10 +93,27 @@ LL | #[proc_macro_derive(unsafe(Foo))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/proc-unsafe-attributes.rs:18:1 + --> $DIR/proc-unsafe-attributes.rs:19:1 | LL | #[unsafe(proc_macro_attribute)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +error[E0452]: malformed lint attribute input + --> $DIR/proc-unsafe-attributes.rs:28:16 + | +LL | #[unsafe(allow(unsafe(dead_code)))] + | ^^^^^^^^^^^^^^^^^ bad attribute argument + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0452]: malformed lint attribute input + --> $DIR/proc-unsafe-attributes.rs:28:16 + | +LL | #[unsafe(allow(unsafe(dead_code)))] + | ^^^^^^^^^^^^^^^^^ bad attribute argument + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 15 previous errors +For more information about this error, try `rustc --explain E0452`. diff --git a/tests/ui/attributes/unsafe/unsafe-attributes.rs b/tests/ui/attributes/unsafe/unsafe-attributes.rs index e7620a18048e4..33a412add500c 100644 --- a/tests/ui/attributes/unsafe/unsafe-attributes.rs +++ b/tests/ui/attributes/unsafe/unsafe-attributes.rs @@ -4,4 +4,10 @@ #[unsafe(no_mangle)] fn a() {} +#[unsafe(export_name = "foo")] +fn b() {} + +#[cfg_attr(any(), unsafe(no_mangle))] +static VAR2: u32 = 1; + fn main() {} diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute.stderr b/tests/ui/attributes/unsafe/unsafe-safe-attribute.stderr index 0602af34e4f64..584b0ea797d0a 100644 --- a/tests/ui/attributes/unsafe/unsafe-safe-attribute.stderr +++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute.stderr @@ -2,7 +2,7 @@ error: `repr` is not an unsafe attribute --> $DIR/unsafe-safe-attribute.rs:3:3 | LL | #[unsafe(repr(C))] - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr index 584dacf4d8c91..26b5e4e37b931 100644 --- a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr +++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr @@ -2,7 +2,7 @@ error: `diagnostic::on_unimplemented` is not an unsafe attribute --> $DIR/unsafe-safe-attribute_diagnostic.rs:3:3 | LL | #[unsafe(diagnostic::on_unimplemented( - | ^^^^^^ + | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes