From 67f5dd1ef112c8a87bc3353793cf4c1cece10c2d Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Sat, 20 Apr 2024 23:54:50 -0500 Subject: [PATCH 01/14] Parse unsafe attributes --- compiler/rustc_ast/src/ast.rs | 9 ++- compiler/rustc_ast/src/attr/mod.rs | 33 ++++++++--- compiler/rustc_ast/src/mut_visit.rs | 10 ++-- compiler/rustc_ast_lowering/src/expr.rs | 1 + compiler/rustc_ast_lowering/src/lib.rs | 1 + compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_ast_pretty/src/pprust/state.rs | 6 +- .../rustc_builtin_macros/src/cmdline_attrs.rs | 3 +- .../rustc_builtin_macros/src/test_harness.rs | 1 + compiler/rustc_expand/src/build.rs | 6 +- compiler/rustc_expand/src/expand.rs | 8 ++- compiler/rustc_feature/src/builtin_attrs.rs | 56 ++++++++++++++++++- compiler/rustc_feature/src/unstable.rs | 1 + compiler/rustc_parse/src/parser/attr.rs | 35 +++++++++++- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + src/librustdoc/clean/cfg/tests.rs | 6 +- .../feature-gate-unsafe-attributes.rs | 8 +++ .../feature-gate-unsafe-attributes.stderr | 13 +++++ 19 files changed, 173 insertions(+), 27 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-unsafe-attributes.rs create mode 100644 tests/ui/feature-gates/feature-gate-unsafe-attributes.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 910fbb8769741..8cb49a1b7604e 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -488,6 +488,7 @@ pub struct Crate { /// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct MetaItem { + pub unsafety: Unsafe, pub path: Path, pub kind: MetaItemKind, pub span: Span, @@ -2823,7 +2824,12 @@ pub struct NormalAttr { impl NormalAttr { pub fn from_ident(ident: Ident) -> Self { Self { - item: AttrItem { path: Path::from_ident(ident), args: AttrArgs::Empty, tokens: None }, + item: AttrItem { + unsafety: Unsafe::No, + path: Path::from_ident(ident), + args: AttrArgs::Empty, + tokens: None, + }, tokens: None, } } @@ -2831,6 +2837,7 @@ impl NormalAttr { #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct AttrItem { + pub unsafety: Unsafe, pub path: Path, pub args: AttrArgs, // Tokens for the meta item, e.g. just the `foo` within `#[foo]` or `#![foo]`. diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index d5c9fc960c86b..62b7a2762194a 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -1,6 +1,8 @@ //! Functions dealing with attributes and meta items. -use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute}; +use crate::ast::{ + AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute, Unsafe, +}; use crate::ast::{DelimArgs, Expr, ExprKind, LitKind, MetaItemLit}; use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem, NormalAttr}; use crate::ast::{Path, PathSegment, DUMMY_NODE_ID}; @@ -238,7 +240,12 @@ impl AttrItem { } pub fn meta(&self, span: Span) -> Option { - Some(MetaItem { path: self.path.clone(), kind: self.meta_kind()?, span }) + Some(MetaItem { + unsafety: Unsafe::No, + path: self.path.clone(), + kind: self.meta_kind()?, + span, + }) } pub fn meta_kind(&self) -> Option { @@ -371,7 +378,8 @@ impl MetaItem { _ => path.span.hi(), }; let span = path.span.with_hi(hi); - Some(MetaItem { path, kind, span }) + // FIX THIS LATER + Some(MetaItem { unsafety: Unsafe::No, path, kind, span }) } } @@ -555,11 +563,12 @@ pub fn mk_doc_comment( pub fn mk_attr( g: &AttrIdGenerator, style: AttrStyle, + unsafety: Unsafe, path: Path, args: AttrArgs, span: Span, ) -> Attribute { - mk_attr_from_item(g, AttrItem { path, args, tokens: None }, None, style, span) + mk_attr_from_item(g, AttrItem { unsafety, path, args, tokens: None }, None, style, span) } pub fn mk_attr_from_item( @@ -577,15 +586,22 @@ pub fn mk_attr_from_item( } } -pub fn mk_attr_word(g: &AttrIdGenerator, style: AttrStyle, name: Symbol, span: Span) -> Attribute { +pub fn mk_attr_word( + g: &AttrIdGenerator, + style: AttrStyle, + unsafety: Unsafe, + name: Symbol, + span: Span, +) -> Attribute { let path = Path::from_ident(Ident::new(name, span)); let args = AttrArgs::Empty; - mk_attr(g, style, path, args, span) + mk_attr(g, style, unsafety, path, args, span) } pub fn mk_attr_nested_word( g: &AttrIdGenerator, style: AttrStyle, + unsafety: Unsafe, outer: Symbol, inner: Symbol, span: Span, @@ -601,12 +617,13 @@ pub fn mk_attr_nested_word( delim: Delimiter::Parenthesis, tokens: inner_tokens, }); - mk_attr(g, style, path, attr_args, span) + mk_attr(g, style, unsafety, path, attr_args, span) } pub fn mk_attr_name_value_str( g: &AttrIdGenerator, style: AttrStyle, + unsafety: Unsafe, name: Symbol, val: Symbol, span: Span, @@ -621,7 +638,7 @@ pub fn mk_attr_name_value_str( }); let path = Path::from_ident(Ident::new(name, span)); let args = AttrArgs::Eq(span, AttrArgsEq::Ast(expr)); - mk_attr(g, style, path, args, span) + mk_attr(g, style, unsafety, path, args, span) } pub fn filter_by_name(attrs: &[Attribute], name: Symbol) -> impl Iterator { diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index a04c648ac731f..dfe82309531b3 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -647,8 +647,10 @@ fn noop_visit_attribute(attr: &mut Attribute, vis: &mut T) { let Attribute { kind, id: _, style: _, span } = attr; match kind { AttrKind::Normal(normal) => { - let NormalAttr { item: AttrItem { path, args, tokens }, tokens: attr_tokens } = - &mut **normal; + let NormalAttr { + item: AttrItem { unsafety: _, path, args, tokens }, + tokens: attr_tokens, + } = &mut **normal; vis.visit_path(path); visit_attr_args(args, vis); visit_lazy_tts(tokens, vis); @@ -678,7 +680,7 @@ fn noop_visit_meta_list_item(li: &mut NestedMetaItem, vis: &mut T } fn noop_visit_meta_item(mi: &mut MetaItem, vis: &mut T) { - let MetaItem { path: _, kind, span } = mi; + let MetaItem { unsafety: _, path: _, kind, span } = mi; match kind { MetaItemKind::Word => {} MetaItemKind::List(mis) => visit_thin_vec(mis, |mi| vis.visit_meta_list_item(mi)), @@ -840,7 +842,7 @@ fn visit_nonterminal(nt: &mut token::Nonterminal, vis: &mut T) { token::NtTy(ty) => vis.visit_ty(ty), token::NtLiteral(expr) => vis.visit_expr(expr), token::NtMeta(item) => { - let AttrItem { path, args, tokens } = item.deref_mut(); + let AttrItem { unsafety: _, path, args, tokens } = item.deref_mut(); vis.visit_path(path); visit_attr_args(args, vis); visit_lazy_tts(tokens, vis); diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index eb206a09be313..5fbae6a34e5dc 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1801,6 +1801,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let attr = attr::mk_attr_nested_word( &self.tcx.sess.psess.attr_id_generator, AttrStyle::Outer, + Unsafe::No, sym::allow, sym::unreachable_code, self.lower_span(span), diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 023dc6d52c3eb..e4959853d3f42 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -911,6 +911,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let kind = match attr.kind { AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr { item: AttrItem { + unsafety: normal.item.unsafety, path: normal.item.path.clone(), args: self.lower_attr_args(&normal.item.args), tokens: None, diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index a9dca9b6a293b..764d942836c20 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -561,6 +561,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(mut_ref, "mutable by-reference bindings are experimental"); gate_all!(precise_capturing, "precise captures on `impl Trait` are experimental"); gate_all!(global_registration, "global registration is experimental"); + gate_all!(unsafe_attributes, "`#[unsafe()]` markers for attributes are experimental"); if !visitor.features.never_patterns { if let Some(spans) = spans.get(&sym::never_patterns) { diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index ca26b436b82ed..e3ccbbe391e0f 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -16,7 +16,7 @@ use rustc_ast::token::{self, BinOpToken, CommentKind, Delimiter, Nonterminal, To use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree}; use rustc_ast::util::classify; use rustc_ast::util::comments::{Comment, CommentStyle}; -use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind}; +use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind, Unsafe}; use rustc_ast::{attr, BindingMode, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term}; use rustc_ast::{GenericArg, GenericBound, SelfKind}; use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass}; @@ -249,6 +249,7 @@ pub fn print_crate<'a>( let fake_attr = attr::mk_attr_nested_word( g, ast::AttrStyle::Inner, + Unsafe::No, sym::feature, sym::prelude_import, DUMMY_SP, @@ -259,7 +260,8 @@ pub fn print_crate<'a>( // root, so this is not needed, and actually breaks things. if edition.is_rust_2015() { // `#![no_std]` - let fake_attr = attr::mk_attr_word(g, ast::AttrStyle::Inner, sym::no_std, DUMMY_SP); + let fake_attr = + attr::mk_attr_word(g, ast::AttrStyle::Inner, Unsafe::No, sym::no_std, DUMMY_SP); s.print_attribute(&fake_attr); } } diff --git a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs index e9b63b4abebb6..16184ec75113a 100644 --- a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs +++ b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs @@ -17,7 +17,7 @@ pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) { )); let start_span = parser.token.span; - let AttrItem { path, args, tokens: _ } = match parser.parse_attr_item(false) { + let AttrItem { unsafety, path, args, tokens: _ } = match parser.parse_attr_item(false) { Ok(ai) => ai, Err(err) => { err.emit(); @@ -33,6 +33,7 @@ pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) { krate.attrs.push(mk_attr( &psess.attr_id_generator, AttrStyle::Inner, + unsafety, path, args, start_span.to(end_span), diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 38ac2f15fe757..fec54cfe38fb0 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -203,6 +203,7 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> { let allow_dead_code = attr::mk_attr_nested_word( &self.sess.psess.attr_id_generator, ast::AttrStyle::Outer, + ast::Unsafe::No, sym::allow, sym::dead_code, self.def_site, diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index b3d41908260ed..9451102c010b1 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -666,7 +666,7 @@ impl<'a> ExtCtxt<'a> { // Builds `#[name]`. pub fn attr_word(&self, name: Symbol, span: Span) -> ast::Attribute { let g = &self.sess.psess.attr_id_generator; - attr::mk_attr_word(g, ast::AttrStyle::Outer, name, span) + attr::mk_attr_word(g, ast::AttrStyle::Outer, ast::Unsafe::No, name, span) } // Builds `#[name = val]`. @@ -674,12 +674,12 @@ impl<'a> ExtCtxt<'a> { // Note: `span` is used for both the identifier and the value. pub fn attr_name_value_str(&self, name: Symbol, val: Symbol, span: Span) -> ast::Attribute { let g = &self.sess.psess.attr_id_generator; - attr::mk_attr_name_value_str(g, ast::AttrStyle::Outer, name, val, span) + attr::mk_attr_name_value_str(g, ast::AttrStyle::Outer, ast::Unsafe::No, name, val, span) } // Builds `#[outer(inner)]`. pub fn attr_nested_word(&self, outer: Symbol, inner: Symbol, span: Span) -> ast::Attribute { let g = &self.sess.psess.attr_id_generator; - attr::mk_attr_nested_word(g, ast::AttrStyle::Outer, outer, inner, span) + attr::mk_attr_nested_word(g, ast::AttrStyle::Outer, ast::Unsafe::No, outer, inner, span) } } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index d8f0f221189ad..77cb617eb33a6 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -778,7 +778,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> { if let SyntaxExtensionKind::Derive(..) = ext { self.gate_proc_macro_input(&item); } - let meta = ast::MetaItem { kind: MetaItemKind::Word, span, path }; + // FIX THIS LATER + let meta = ast::MetaItem { + unsafety: ast::Unsafe::No, + kind: MetaItemKind::Word, + span, + path, + }; let items = match expander.expand(self.cx, span, &meta, item, is_const) { ExpandResult::Ready(items) => items, ExpandResult::Retry(item) => { diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 8b7e93fd55587..edfda9bf066ba 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -59,6 +59,17 @@ pub enum AttributeType { CrateLevel, } +#[derive(Copy, Clone, PartialEq, Debug)] +#[allow(dead_code)] +pub enum AttributeSafety { + /// Normal attribute that does not need `#[unsafe(...)]` + Normal, + + /// Unsafe attribute that requires safety obligations + /// to be discharged + Unsafe, +} + #[derive(Clone, Copy)] pub enum AttributeGate { /// Is gated by a given feature gate, reason @@ -177,6 +188,18 @@ macro_rules! ungated { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, + safety: AttributeSafety::Normal, + template: $tpl, + gate: Ungated, + duplicates: $duplicates, + } + }; + (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => { + BuiltinAttribute { + name: sym::$attr, + encode_cross_crate: $encode_cross_crate, + type_: $typ, + safety: AttributeSafety::Unsafe, template: $tpl, gate: Ungated, duplicates: $duplicates, @@ -190,6 +213,7 @@ macro_rules! gated { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, + safety: AttributeSafety::Normal, template: $tpl, duplicates: $duplicates, gate: Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)), @@ -200,6 +224,29 @@ macro_rules! gated { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, + safety: AttributeSafety::Normal, + template: $tpl, + duplicates: $duplicates, + gate: Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)), + } + }; + (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $msg:expr $(,)?) => { + BuiltinAttribute { + name: sym::$attr, + encode_cross_crate: $encode_cross_crate, + type_: $typ, + safety: AttributeSafety::Unsafe, + template: $tpl, + duplicates: $duplicates, + gate: Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)), + } + }; + (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $msg:expr $(,)?) => { + BuiltinAttribute { + name: sym::$attr, + encode_cross_crate: $encode_cross_crate, + type_: $typ, + safety: AttributeSafety::Unsafe, template: $tpl, duplicates: $duplicates, gate: Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)), @@ -228,6 +275,7 @@ macro_rules! rustc_attr { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, + safety: AttributeSafety::Normal, template: $tpl, duplicates: $duplicates, gate: Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs)), @@ -258,6 +306,7 @@ pub struct BuiltinAttribute { /// Otherwise, it can only be used in the local crate. pub encode_cross_crate: EncodeCrossCrate, pub type_: AttributeType, + pub safety: AttributeSafety, pub template: AttributeTemplate, pub duplicates: AttributeDuplicates, pub gate: AttributeGate, @@ -375,9 +424,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), ungated!(no_link, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), ungated!(repr, Normal, template!(List: "C"), DuplicatesOk, EncodeCrossCrate::No), - ungated!(export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No), - ungated!(link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No), - ungated!(no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), + ungated!(unsafe export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No), + ungated!(unsafe link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No), + ungated!(unsafe no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), ungated!(used, Normal, template!(Word, List: "compiler|linker"), WarnFollowing, EncodeCrossCrate::No), ungated!(link_ordinal, Normal, template!(List: "ordinal"), ErrorPreceding, EncodeCrossCrate::Yes), @@ -850,6 +899,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // FIXME: This can be `true` once we always use `tcx.is_diagnostic_item`. encode_cross_crate: EncodeCrossCrate::Yes, type_: Normal, + safety: AttributeSafety::Normal, template: template!(NameValueStr: "name"), duplicates: ErrorFollowing, gate: Gated( diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 8add2b9276142..83a50f017d3b4 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -623,6 +623,7 @@ declare_features! ( /// Allows unsafe on extern declarations and safety qualifiers over internal items. (unstable, unsafe_extern_blocks, "CURRENT_RUSTC_VERSION", Some(123743)), /// Allows unsized fn parameters. + (unstable, unsafe_attributes, "CURRENT_RUSTC_VERSION", Some(123757)), (unstable, unsized_fn_params, "1.49.0", Some(48055)), /// Allows unsized rvalues at arguments and parameters. (incomplete, unsized_locals, "1.30.0", Some(48055)), diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 4acc610d8c405..2dd19f6c20afc 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -7,7 +7,7 @@ use rustc_ast as ast; use rustc_ast::attr; use rustc_ast::token::{self, Delimiter}; use rustc_errors::{codes::*, Diag, PResult}; -use rustc_span::{sym, BytePos, Span}; +use rustc_span::{sym, symbol::kw, BytePos, Span}; use thin_vec::ThinVec; use tracing::debug; @@ -252,9 +252,23 @@ impl<'a> Parser<'a> { maybe_whole!(self, NtMeta, |attr| attr.into_inner()); let do_parse = |this: &mut Self| { + let is_unsafe = this.eat_keyword(kw::Unsafe); + let unsafety = if is_unsafe { + let unsafe_span = this.prev_token.span; + this.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span); + this.expect(&token::OpenDelim(Delimiter::Parenthesis))?; + + ast::Unsafe::Yes(unsafe_span) + } else { + ast::Unsafe::No + }; + let path = this.parse_path(PathStyle::Mod)?; let args = this.parse_attr_args()?; - Ok(ast::AttrItem { path, args, tokens: None }) + if is_unsafe { + this.expect(&token::CloseDelim(Delimiter::Parenthesis))?; + } + Ok(ast::AttrItem { unsafety, path, args, tokens: None }) }; // Attr items don't have attributes if capture_tokens { self.collect_tokens_no_attrs(do_parse) } else { do_parse(self) } @@ -375,10 +389,25 @@ impl<'a> Parser<'a> { } let lo = self.token.span; + let is_unsafe = self.eat_keyword(kw::Unsafe); + let unsafety = if is_unsafe { + let unsafe_span = self.prev_token.span; + self.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span); + self.expect(&token::OpenDelim(Delimiter::Parenthesis))?; + + ast::Unsafe::Yes(unsafe_span) + } else { + ast::Unsafe::No + }; + let path = self.parse_path(PathStyle::Mod)?; let kind = self.parse_meta_item_kind()?; + if is_unsafe { + self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; + } let span = lo.to(self.prev_token.span); - Ok(ast::MetaItem { path, kind, span }) + + Ok(ast::MetaItem { unsafety, path, kind, span }) } pub(crate) fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> { diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index b91ef1ae1f320..58342ff829071 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -42,6 +42,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) { pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, MetaItem> { let item = attr.get_normal_item(); Ok(MetaItem { + unsafety: item.unsafety, span: attr.span, path: item.path.clone(), kind: match &item.args { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index f530d1dd1d4bc..935942641677a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1962,6 +1962,7 @@ symbols! { unreachable_display, unreachable_macro, unrestricted_attribute_tokens, + unsafe_attributes, unsafe_block_in_unsafe_fn, unsafe_cell, unsafe_cell_raw_get, diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index 20bcf1abf417b..2579c15fc5fc9 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -1,6 +1,6 @@ use super::*; -use rustc_ast::{MetaItemLit, Path, StrStyle}; +use rustc_ast::{MetaItemLit, Path, StrStyle, Unsafe}; use rustc_span::create_default_session_globals_then; use rustc_span::symbol::{kw, Ident}; use rustc_span::DUMMY_SP; @@ -16,6 +16,7 @@ fn name_value_cfg(name: &str, value: &str) -> Cfg { fn dummy_meta_item_word(name: &str) -> MetaItem { MetaItem { + unsafety: Unsafe::No, path: Path::from_ident(Ident::from_str(name)), kind: MetaItemKind::Word, span: DUMMY_SP, @@ -25,6 +26,7 @@ fn dummy_meta_item_word(name: &str) -> MetaItem { fn dummy_meta_item_name_value(name: &str, symbol: Symbol, kind: LitKind) -> MetaItem { let lit = MetaItemLit { symbol, suffix: None, kind, span: DUMMY_SP }; MetaItem { + unsafety: Unsafe::No, path: Path::from_ident(Ident::from_str(name)), kind: MetaItemKind::NameValue(lit), span: DUMMY_SP, @@ -34,6 +36,7 @@ fn dummy_meta_item_name_value(name: &str, symbol: Symbol, kind: LitKind) -> Meta macro_rules! dummy_meta_item_list { ($name:ident, [$($list:ident),* $(,)?]) => { MetaItem { + unsafety: Unsafe::No, path: Path::from_ident(Ident::from_str(stringify!($name))), kind: MetaItemKind::List(thin_vec![ $( @@ -48,6 +51,7 @@ macro_rules! dummy_meta_item_list { ($name:ident, [$($list:expr),* $(,)?]) => { MetaItem { + unsafety: Unsafe::No, path: Path::from_ident(Ident::from_str(stringify!($name))), kind: MetaItemKind::List(thin_vec![ $( diff --git a/tests/ui/feature-gates/feature-gate-unsafe-attributes.rs b/tests/ui/feature-gates/feature-gate-unsafe-attributes.rs new file mode 100644 index 0000000000000..9eba415dda0e5 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-unsafe-attributes.rs @@ -0,0 +1,8 @@ +#[unsafe(no_mangle)] //~ ERROR [E0658] +extern "C" fn foo() { + +} + +fn main() { + foo(); +} diff --git a/tests/ui/feature-gates/feature-gate-unsafe-attributes.stderr b/tests/ui/feature-gates/feature-gate-unsafe-attributes.stderr new file mode 100644 index 0000000000000..dfcea756b02b6 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-unsafe-attributes.stderr @@ -0,0 +1,13 @@ +error[E0658]: `#[unsafe()]` markers for attributes are experimental + --> $DIR/feature-gate-unsafe-attributes.rs:1:3 + | +LL | #[unsafe(no_mangle)] + | ^^^^^^ + | + = note: see issue #123757 for more information + = help: add `#![feature(unsafe_attributes)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. From c4de986afa792fa910f255f6315c50b82275abf9 Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Tue, 23 Apr 2024 07:50:53 -0500 Subject: [PATCH 02/14] Disallow unsafe in derive --- compiler/rustc_builtin_macros/messages.ftl | 3 +++ compiler/rustc_builtin_macros/src/derive.rs | 12 +++++++++++- compiler/rustc_builtin_macros/src/errors.rs | 7 +++++++ compiler/rustc_expand/src/expand.rs | 3 ++- .../ui/attributes/unsafe/derive-unsafe-attributes.rs | 6 ++++++ .../unsafe/derive-unsafe-attributes.stderr | 8 ++++++++ 6 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 tests/ui/attributes/unsafe/derive-unsafe-attributes.rs create mode 100644 tests/ui/attributes/unsafe/derive-unsafe-attributes.stderr diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index a3d6a1c736072..2d1269e1b6ad8 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -110,6 +110,9 @@ 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/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index d14858e5c1db3..d70eaa617ca8a 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -2,7 +2,7 @@ use crate::cfg_eval::cfg_eval; use crate::errors; use rustc_ast as ast; -use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind}; +use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind, Unsafe}; use rustc_expand::base::{ Annotatable, DeriveResolution, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier, }; @@ -60,6 +60,7 @@ 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 { @@ -159,3 +160,12 @@ fn report_path_args(sess: &Session, meta: &ast::MetaItem) { } } } + +fn report_unsafe_args(sess: &Session, meta: &ast::MetaItem) { + match meta.unsafety { + Unsafe::Yes(span) => { + sess.dcx().emit_err(errors::DeriveUnsafePath { span }); + } + Unsafe::No => {} + } +} diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index d157703723beb..b14eb2b5ee600 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -295,6 +295,13 @@ 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/expand.rs b/compiler/rustc_expand/src/expand.rs index 77cb617eb33a6..dfef2540d29db 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -778,7 +778,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> { if let SyntaxExtensionKind::Derive(..) = ext { self.gate_proc_macro_input(&item); } - // FIX THIS LATER + // The `MetaItem` representing the trait to derive can't + // have an unsafe around it (as of now). let meta = ast::MetaItem { unsafety: ast::Unsafe::No, kind: MetaItemKind::Word, diff --git a/tests/ui/attributes/unsafe/derive-unsafe-attributes.rs b/tests/ui/attributes/unsafe/derive-unsafe-attributes.rs new file mode 100644 index 0000000000000..774ce86c0960c --- /dev/null +++ b/tests/ui/attributes/unsafe/derive-unsafe-attributes.rs @@ -0,0 +1,6 @@ +#![feature(unsafe_attributes)] + +#[derive(unsafe(Debug))] //~ ERROR: traits in `#[derive(...)]` don't accept `unsafe(...)` +struct Foo; + +fn main() {} diff --git a/tests/ui/attributes/unsafe/derive-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/derive-unsafe-attributes.stderr new file mode 100644 index 0000000000000..fc0daf16790a8 --- /dev/null +++ b/tests/ui/attributes/unsafe/derive-unsafe-attributes.stderr @@ -0,0 +1,8 @@ +error: traits in `#[derive(...)]` don't accept `unsafe(...)` + --> $DIR/derive-unsafe-attributes.rs:3:10 + | +LL | #[derive(unsafe(Debug))] + | ^^^^^^ + +error: aborting due to 1 previous error + From 6ec492fddea96012db4ec8473de3bb27718a25b3 Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Thu, 25 Apr 2024 11:12:02 -0500 Subject: [PATCH 03/14] Reorder `unsafe` macro cases --- compiler/rustc_feature/src/builtin_attrs.rs | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index edfda9bf066ba..8fa0c30173ef3 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -183,23 +183,23 @@ macro_rules! template { } macro_rules! ungated { - ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => { + (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, - safety: AttributeSafety::Normal, + safety: AttributeSafety::Unsafe, template: $tpl, gate: Ungated, duplicates: $duplicates, } }; - (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => { + ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, - safety: AttributeSafety::Unsafe, + safety: AttributeSafety::Normal, template: $tpl, gate: Ungated, duplicates: $duplicates, @@ -208,45 +208,45 @@ macro_rules! ungated { } macro_rules! gated { - ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $msg:expr $(,)?) => { + (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $msg:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, - safety: AttributeSafety::Normal, + safety: AttributeSafety::Unsafe, template: $tpl, duplicates: $duplicates, gate: Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)), } }; - ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $msg:expr $(,)?) => { + (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $msg:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, - safety: AttributeSafety::Normal, + safety: AttributeSafety::Unsafe, template: $tpl, duplicates: $duplicates, gate: Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)), } }; - (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $msg:expr $(,)?) => { + ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $msg:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, - safety: AttributeSafety::Unsafe, + safety: AttributeSafety::Normal, template: $tpl, duplicates: $duplicates, gate: Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)), } }; - (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $msg:expr $(,)?) => { + ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $msg:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, - safety: AttributeSafety::Unsafe, + safety: AttributeSafety::Normal, template: $tpl, duplicates: $duplicates, gate: Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)), From 48851d9adbd358a678e8ef8102d131aaa42884fc Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Sun, 28 Apr 2024 15:43:07 -0500 Subject: [PATCH 04/14] Add tests --- tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs | 7 +++++++ tests/ui/attributes/unsafe/unsafe-attributes.rs | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs create mode 100644 tests/ui/attributes/unsafe/unsafe-attributes.rs diff --git a/tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs b/tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs new file mode 100644 index 0000000000000..ce365d1a8b1c8 --- /dev/null +++ b/tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs @@ -0,0 +1,7 @@ +//@ build-pass +#![feature(unsafe_attributes)] + +#[cfg_attr(all(), unsafe(no_mangle))] +fn a() {} + +fn main() {} diff --git a/tests/ui/attributes/unsafe/unsafe-attributes.rs b/tests/ui/attributes/unsafe/unsafe-attributes.rs new file mode 100644 index 0000000000000..e7620a18048e4 --- /dev/null +++ b/tests/ui/attributes/unsafe/unsafe-attributes.rs @@ -0,0 +1,7 @@ +//@ build-pass +#![feature(unsafe_attributes)] + +#[unsafe(no_mangle)] +fn a() {} + +fn main() {} From 230b58febf78bb1680b4960d32350a7430a8aab5 Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Wed, 15 May 2024 18:52:08 -0500 Subject: [PATCH 05/14] Error on unsafe on non-unsafe attribute --- compiler/rustc_feature/src/builtin_attrs.rs | 4 ++++ compiler/rustc_feature/src/lib.rs | 4 ++-- compiler/rustc_passes/messages.ftl | 4 ++++ compiler/rustc_passes/src/check_attr.rs | 22 ++++++++++++++++++- compiler/rustc_passes/src/errors.rs | 11 +++++++++- .../unsafe/unsafe-safe-attribute.rs | 6 +++++ .../unsafe/unsafe-safe-attribute.stderr | 10 +++++++++ .../unsafe-safe-attribute_diagnostic.rs | 8 +++++++ .../unsafe-safe-attribute_diagnostic.stderr | 10 +++++++++ 9 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 tests/ui/attributes/unsafe/unsafe-safe-attribute.rs create mode 100644 tests/ui/attributes/unsafe/unsafe-safe-attribute.stderr create mode 100644 tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs create mode 100644 tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 8fa0c30173ef3..f901f5c8c41ad 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1146,6 +1146,10 @@ pub fn is_valid_for_get_attr(name: Symbol) -> bool { }) } +pub fn is_unsafe_attr(name: Symbol) -> bool { + BUILTIN_ATTRIBUTE_MAP.get(&name).is_some_and(|attr| attr.safety == AttributeSafety::Unsafe) +} + pub static BUILTIN_ATTRIBUTE_MAP: LazyLock> = LazyLock::new(|| { let mut map = FxHashMap::default(); diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 9cbf836ec76f0..9db9073e2f02f 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -123,8 +123,8 @@ pub use accepted::ACCEPTED_FEATURES; pub use builtin_attrs::AttributeDuplicates; pub use builtin_attrs::{ deprecated_attributes, encode_cross_crate, find_gated_cfg, is_builtin_attr_name, - is_valid_for_get_attr, AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute, - GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP, + is_unsafe_attr, is_valid_for_get_attr, AttributeGate, AttributeTemplate, AttributeType, + BuiltinAttribute, GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP, }; pub use removed::REMOVED_FEATURES; pub use unstable::{Features, INCOMPATIBLE_FEATURES, UNSTABLE_FEATURES}; diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index d850644bb452f..07c82065a80d1 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -384,6 +384,10 @@ passes_invalid_attr_at_crate_level = passes_invalid_attr_at_crate_level_item = the inner attribute doesn't annotate this {$kind} +passes_invalid_attr_unsafe = `{$name}` is not an unsafe attribute + .suggestion = remove the `unsafe(...)` + .note = extraneous unsafe is not allowed in attributes + passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]` argument passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 39cb48c1af3aa..d826eacbd1565 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -10,7 +10,9 @@ use rustc_ast::{MetaItemKind, MetaItemLit, NestedMetaItem}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::StashKey; use rustc_errors::{Applicability, DiagCtxt, IntoDiagArg, MultiSpan}; -use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; +use rustc_feature::{ + is_unsafe_attr, AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP, +}; use rustc_hir::def_id::LocalModDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self as hir}; @@ -114,6 +116,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let mut seen = FxHashMap::default(); let attrs = self.tcx.hir().attrs(hir_id); for attr in attrs { + self.check_unsafe_attr(attr); + match attr.path().as_slice() { [sym::diagnostic, sym::do_not_recommend] => { self.check_do_not_recommend(attr.span, hir_id, target) @@ -308,6 +312,22 @@ impl<'tcx> CheckAttrVisitor<'tcx> { true } + + /// Checks if `unsafe()` is applied to an invalid attribute. + fn check_unsafe_attr(&self, attr: &Attribute) { + if !attr.is_doc_comment() { + let attr_item = attr.get_normal_item(); + if let ast::Unsafe::Yes(unsafe_span) = attr_item.unsafety { + if !is_unsafe_attr(attr.name_or_empty()) { + self.dcx().emit_err(errors::InvalidAttrUnsafe { + span: unsafe_span, + name: attr_item.path.clone(), + }); + } + } + } + } + /// Checks if `#[diagnostic::on_unimplemented]` is applied to a trait definition fn check_diagnostic_on_unimplemented( &self, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 7fdd9924b513e..a935f1ad7d351 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -4,7 +4,7 @@ use std::{ }; use crate::fluent_generated as fluent; -use rustc_ast::Label; +use rustc_ast::{ast, Label}; use rustc_errors::{ codes::*, Applicability, Diag, DiagCtxt, DiagSymbolList, Diagnostic, EmissionGuarantee, Level, MultiSpan, SubdiagMessageOp, Subdiagnostic, @@ -863,6 +863,15 @@ pub struct InvalidAttrAtCrateLevel { pub item: Option, } +#[derive(Diagnostic)] +#[diag(passes_invalid_attr_unsafe)] +#[note] +pub struct InvalidAttrUnsafe { + #[primary_span] + pub span: Span, + pub name: ast::Path, +} + #[derive(Clone, Copy)] pub struct ItemFollowingInnerAttr { pub span: Span, diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute.rs b/tests/ui/attributes/unsafe/unsafe-safe-attribute.rs new file mode 100644 index 0000000000000..67db36afd2e69 --- /dev/null +++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute.rs @@ -0,0 +1,6 @@ +#![feature(unsafe_attributes)] + +#[unsafe(repr(C))] //~ ERROR: is not an unsafe attribute +struct Foo {} + +fn main() {} diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute.stderr b/tests/ui/attributes/unsafe/unsafe-safe-attribute.stderr new file mode 100644 index 0000000000000..0602af34e4f64 --- /dev/null +++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute.stderr @@ -0,0 +1,10 @@ +error: `repr` is not an unsafe attribute + --> $DIR/unsafe-safe-attribute.rs:3:3 + | +LL | #[unsafe(repr(C))] + | ^^^^^^ + | + = note: extraneous unsafe is not allowed in attributes + +error: aborting due to 1 previous error + diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs new file mode 100644 index 0000000000000..ff2eb61b40538 --- /dev/null +++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs @@ -0,0 +1,8 @@ +#![feature(unsafe_attributes)] + +#[unsafe(diagnostic::on_unimplemented( //~ ERROR: is not an unsafe attribute + message = "testing", +))] +trait Foo {} + +fn main() {} diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr new file mode 100644 index 0000000000000..584dacf4d8c91 --- /dev/null +++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr @@ -0,0 +1,10 @@ +error: `diagnostic::on_unimplemented` is not an unsafe attribute + --> $DIR/unsafe-safe-attribute_diagnostic.rs:3:3 + | +LL | #[unsafe(diagnostic::on_unimplemented( + | ^^^^^^ + | + = note: extraneous unsafe is not allowed in attributes + +error: aborting due to 1 previous error + From 68719e0bda178103a3e4af0dc1e7df45f1d9dd00 Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Thu, 16 May 2024 01:41:55 -0500 Subject: [PATCH 06/14] Fix doc comment --- compiler/rustc_feature/src/unstable.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 83a50f017d3b4..4688624f310b2 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -622,8 +622,9 @@ declare_features! ( (incomplete, unnamed_fields, "1.74.0", Some(49804)), /// Allows unsafe on extern declarations and safety qualifiers over internal items. (unstable, unsafe_extern_blocks, "CURRENT_RUSTC_VERSION", Some(123743)), - /// Allows unsized fn parameters. + /// Allows unsafe attributes. (unstable, unsafe_attributes, "CURRENT_RUSTC_VERSION", Some(123757)), + /// Allows unsized fn parameters. (unstable, unsized_fn_params, "1.49.0", Some(48055)), /// Allows unsized rvalues at arguments and parameters. (incomplete, unsized_locals, "1.30.0", Some(48055)), From b82c5249961a6bd3ecacb98c68f9090892ec2615 Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Thu, 16 May 2024 02:08:26 -0500 Subject: [PATCH 07/14] Add double unsafe test --- .../unsafe/double-unsafe-attributes.rs | 9 +++++++ .../unsafe/double-unsafe-attributes.stderr | 27 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tests/ui/attributes/unsafe/double-unsafe-attributes.rs create mode 100644 tests/ui/attributes/unsafe/double-unsafe-attributes.stderr diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.rs b/tests/ui/attributes/unsafe/double-unsafe-attributes.rs new file mode 100644 index 0000000000000..a6c0ea578f25a --- /dev/null +++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.rs @@ -0,0 +1,9 @@ +#![feature(unsafe_attributes)] + +#[unsafe(unsafe(no_mangle))] +//~^ ERROR expected identifier, found keyword `unsafe` +//~| ERROR cannot find attribute `r#unsafe` in this scope +//~| ERROR `r#unsafe` is not an unsafe attribute +fn a() {} + +fn main() {} diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr new file mode 100644 index 0000000000000..1c07a5bf8baa0 --- /dev/null +++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr @@ -0,0 +1,27 @@ +error: expected identifier, found keyword `unsafe` + --> $DIR/double-unsafe-attributes.rs:3:10 + | +LL | #[unsafe(unsafe(no_mangle))] + | ^^^^^^ expected identifier, found keyword + | +help: escape `unsafe` to use it as an identifier + | +LL | #[unsafe(r#unsafe(no_mangle))] + | ++ + +error: cannot find attribute `r#unsafe` in this scope + --> $DIR/double-unsafe-attributes.rs:3:10 + | +LL | #[unsafe(unsafe(no_mangle))] + | ^^^^^^ + +error: `r#unsafe` is not an unsafe attribute + --> $DIR/double-unsafe-attributes.rs:3:3 + | +LL | #[unsafe(unsafe(no_mangle))] + | ^^^^^^ + | + = note: extraneous unsafe is not allowed in attributes + +error: aborting due to 3 previous errors + From 87be1bae73586eaf917790f10ac2240186cb7b2b Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Tue, 21 May 2024 08:37:05 -0500 Subject: [PATCH 08/14] Fix build --- compiler/rustc_ast/src/ast.rs | 6 +++--- compiler/rustc_ast/src/attr/mod.rs | 14 +++++++------- compiler/rustc_ast_lowering/src/expr.rs | 2 +- compiler/rustc_ast_pretty/src/pprust/state.rs | 6 +++--- compiler/rustc_builtin_macros/src/derive.rs | 6 +++--- compiler/rustc_builtin_macros/src/test_harness.rs | 2 +- compiler/rustc_expand/src/build.rs | 6 +++--- compiler/rustc_expand/src/expand.rs | 2 +- compiler/rustc_parse/src/parser/attr.rs | 8 ++++---- compiler/rustc_passes/src/check_attr.rs | 2 +- src/librustdoc/clean/cfg/tests.rs | 10 +++++----- 11 files changed, 32 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 8cb49a1b7604e..957c4d7c698f9 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -488,7 +488,7 @@ pub struct Crate { /// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct MetaItem { - pub unsafety: Unsafe, + pub unsafety: Safety, pub path: Path, pub kind: MetaItemKind, pub span: Span, @@ -2825,7 +2825,7 @@ impl NormalAttr { pub fn from_ident(ident: Ident) -> Self { Self { item: AttrItem { - unsafety: Unsafe::No, + unsafety: Safety::Default, path: Path::from_ident(ident), args: AttrArgs::Empty, tokens: None, @@ -2837,7 +2837,7 @@ impl NormalAttr { #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct AttrItem { - pub unsafety: Unsafe, + pub unsafety: Safety, pub path: Path, pub args: AttrArgs, // Tokens for the meta item, e.g. just the `foo` within `#[foo]` or `#![foo]`. diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 62b7a2762194a..ed1b4733820e9 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -1,7 +1,7 @@ //! Functions dealing with attributes and meta items. use crate::ast::{ - AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute, Unsafe, + AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute, Safety, }; use crate::ast::{DelimArgs, Expr, ExprKind, LitKind, MetaItemLit}; use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem, NormalAttr}; @@ -241,7 +241,7 @@ impl AttrItem { pub fn meta(&self, span: Span) -> Option { Some(MetaItem { - unsafety: Unsafe::No, + unsafety: Safety::Default, path: self.path.clone(), kind: self.meta_kind()?, span, @@ -379,7 +379,7 @@ impl MetaItem { }; let span = path.span.with_hi(hi); // FIX THIS LATER - Some(MetaItem { unsafety: Unsafe::No, path, kind, span }) + Some(MetaItem { unsafety: Safety::Default, path, kind, span }) } } @@ -563,7 +563,7 @@ pub fn mk_doc_comment( pub fn mk_attr( g: &AttrIdGenerator, style: AttrStyle, - unsafety: Unsafe, + unsafety: Safety, path: Path, args: AttrArgs, span: Span, @@ -589,7 +589,7 @@ pub fn mk_attr_from_item( pub fn mk_attr_word( g: &AttrIdGenerator, style: AttrStyle, - unsafety: Unsafe, + unsafety: Safety, name: Symbol, span: Span, ) -> Attribute { @@ -601,7 +601,7 @@ pub fn mk_attr_word( pub fn mk_attr_nested_word( g: &AttrIdGenerator, style: AttrStyle, - unsafety: Unsafe, + unsafety: Safety, outer: Symbol, inner: Symbol, span: Span, @@ -623,7 +623,7 @@ pub fn mk_attr_nested_word( pub fn mk_attr_name_value_str( g: &AttrIdGenerator, style: AttrStyle, - unsafety: Unsafe, + unsafety: Safety, name: Symbol, val: Symbol, span: Span, diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 5fbae6a34e5dc..554f9f0985862 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1801,7 +1801,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let attr = attr::mk_attr_nested_word( &self.tcx.sess.psess.attr_id_generator, AttrStyle::Outer, - Unsafe::No, + Safety::Default, sym::allow, sym::unreachable_code, self.lower_span(span), diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index e3ccbbe391e0f..54d642f6a0ffd 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -16,7 +16,7 @@ use rustc_ast::token::{self, BinOpToken, CommentKind, Delimiter, Nonterminal, To use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree}; use rustc_ast::util::classify; use rustc_ast::util::comments::{Comment, CommentStyle}; -use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind, Unsafe}; +use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind, Safety}; use rustc_ast::{attr, BindingMode, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term}; use rustc_ast::{GenericArg, GenericBound, SelfKind}; use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass}; @@ -249,7 +249,7 @@ pub fn print_crate<'a>( let fake_attr = attr::mk_attr_nested_word( g, ast::AttrStyle::Inner, - Unsafe::No, + Safety::Default, sym::feature, sym::prelude_import, DUMMY_SP, @@ -261,7 +261,7 @@ pub fn print_crate<'a>( if edition.is_rust_2015() { // `#![no_std]` let fake_attr = - attr::mk_attr_word(g, ast::AttrStyle::Inner, Unsafe::No, sym::no_std, DUMMY_SP); + attr::mk_attr_word(g, ast::AttrStyle::Inner, Safety::Default, sym::no_std, DUMMY_SP); s.print_attribute(&fake_attr); } } diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index d70eaa617ca8a..dea668ff8f4b3 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -2,7 +2,7 @@ use crate::cfg_eval::cfg_eval; use crate::errors; use rustc_ast as ast; -use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind, Unsafe}; +use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind, Safety}; use rustc_expand::base::{ Annotatable, DeriveResolution, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier, }; @@ -163,9 +163,9 @@ fn report_path_args(sess: &Session, meta: &ast::MetaItem) { fn report_unsafe_args(sess: &Session, meta: &ast::MetaItem) { match meta.unsafety { - Unsafe::Yes(span) => { + Safety::Unsafe(span) => { sess.dcx().emit_err(errors::DeriveUnsafePath { span }); } - Unsafe::No => {} + Safety::Default => {} } } diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index fec54cfe38fb0..ba4e5cfd13070 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -203,7 +203,7 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> { let allow_dead_code = attr::mk_attr_nested_word( &self.sess.psess.attr_id_generator, ast::AttrStyle::Outer, - ast::Unsafe::No, + ast::Safety::Default, sym::allow, sym::dead_code, self.def_site, diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 9451102c010b1..e513e61f4d1e0 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -666,7 +666,7 @@ impl<'a> ExtCtxt<'a> { // Builds `#[name]`. pub fn attr_word(&self, name: Symbol, span: Span) -> ast::Attribute { let g = &self.sess.psess.attr_id_generator; - attr::mk_attr_word(g, ast::AttrStyle::Outer, ast::Unsafe::No, name, span) + attr::mk_attr_word(g, ast::AttrStyle::Outer, ast::Safety::Default, name, span) } // Builds `#[name = val]`. @@ -674,12 +674,12 @@ impl<'a> ExtCtxt<'a> { // Note: `span` is used for both the identifier and the value. pub fn attr_name_value_str(&self, name: Symbol, val: Symbol, span: Span) -> ast::Attribute { let g = &self.sess.psess.attr_id_generator; - attr::mk_attr_name_value_str(g, ast::AttrStyle::Outer, ast::Unsafe::No, name, val, span) + attr::mk_attr_name_value_str(g, ast::AttrStyle::Outer, ast::Safety::Default, name, val, span) } // Builds `#[outer(inner)]`. pub fn attr_nested_word(&self, outer: Symbol, inner: Symbol, span: Span) -> ast::Attribute { let g = &self.sess.psess.attr_id_generator; - attr::mk_attr_nested_word(g, ast::AttrStyle::Outer, ast::Unsafe::No, outer, inner, span) + attr::mk_attr_nested_word(g, ast::AttrStyle::Outer, ast::Safety::Default, outer, inner, span) } } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index dfef2540d29db..c28a09eb57c77 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -781,7 +781,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { // The `MetaItem` representing the trait to derive can't // have an unsafe around it (as of now). let meta = ast::MetaItem { - unsafety: ast::Unsafe::No, + unsafety: ast::Safety::Default, kind: MetaItemKind::Word, span, path, diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 2dd19f6c20afc..58fef9b6c4562 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -258,9 +258,9 @@ impl<'a> Parser<'a> { this.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span); this.expect(&token::OpenDelim(Delimiter::Parenthesis))?; - ast::Unsafe::Yes(unsafe_span) + ast::Safety::Unsafe(unsafe_span) } else { - ast::Unsafe::No + ast::Safety::Default }; let path = this.parse_path(PathStyle::Mod)?; @@ -395,9 +395,9 @@ impl<'a> Parser<'a> { self.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span); self.expect(&token::OpenDelim(Delimiter::Parenthesis))?; - ast::Unsafe::Yes(unsafe_span) + ast::Safety::Unsafe(unsafe_span) } else { - ast::Unsafe::No + ast::Safety::Default }; let path = self.parse_path(PathStyle::Mod)?; diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d826eacbd1565..29bc165159d8d 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -317,7 +317,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { fn check_unsafe_attr(&self, attr: &Attribute) { if !attr.is_doc_comment() { let attr_item = attr.get_normal_item(); - if let ast::Unsafe::Yes(unsafe_span) = attr_item.unsafety { + if let ast::Safety::Unsafe(unsafe_span) = attr_item.unsafety { if !is_unsafe_attr(attr.name_or_empty()) { self.dcx().emit_err(errors::InvalidAttrUnsafe { span: unsafe_span, diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index 2579c15fc5fc9..56a10f9fb9c2e 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -1,6 +1,6 @@ use super::*; -use rustc_ast::{MetaItemLit, Path, StrStyle, Unsafe}; +use rustc_ast::{MetaItemLit, Path, StrStyle, Safety}; use rustc_span::create_default_session_globals_then; use rustc_span::symbol::{kw, Ident}; use rustc_span::DUMMY_SP; @@ -16,7 +16,7 @@ fn name_value_cfg(name: &str, value: &str) -> Cfg { fn dummy_meta_item_word(name: &str) -> MetaItem { MetaItem { - unsafety: Unsafe::No, + unsafety: Safety::Default, path: Path::from_ident(Ident::from_str(name)), kind: MetaItemKind::Word, span: DUMMY_SP, @@ -26,7 +26,7 @@ fn dummy_meta_item_word(name: &str) -> MetaItem { fn dummy_meta_item_name_value(name: &str, symbol: Symbol, kind: LitKind) -> MetaItem { let lit = MetaItemLit { symbol, suffix: None, kind, span: DUMMY_SP }; MetaItem { - unsafety: Unsafe::No, + unsafety: Safety::Default, path: Path::from_ident(Ident::from_str(name)), kind: MetaItemKind::NameValue(lit), span: DUMMY_SP, @@ -36,7 +36,7 @@ fn dummy_meta_item_name_value(name: &str, symbol: Symbol, kind: LitKind) -> Meta macro_rules! dummy_meta_item_list { ($name:ident, [$($list:ident),* $(,)?]) => { MetaItem { - unsafety: Unsafe::No, + unsafety: Safety::Default, path: Path::from_ident(Ident::from_str(stringify!($name))), kind: MetaItemKind::List(thin_vec![ $( @@ -51,7 +51,7 @@ macro_rules! dummy_meta_item_list { ($name:ident, [$($list:expr),* $(,)?]) => { MetaItem { - unsafety: Unsafe::No, + unsafety: Safety::Default, path: Path::from_ident(Ident::from_str(stringify!($name))), kind: MetaItemKind::List(thin_vec![ $( From 8aa2553b509b8ea033560aedebe0df7c1d8ca42c Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Mon, 27 May 2024 11:41:41 -0500 Subject: [PATCH 09/14] Change comment to FIXME --- compiler/rustc_ast/src/attr/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index ed1b4733820e9..676a2377c3b35 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -378,7 +378,9 @@ impl MetaItem { _ => path.span.hi(), }; let span = path.span.with_hi(hi); - // FIX THIS LATER + // FIXME: This parses `unsafe()` not as unsafe attribute syntax in `MetaItem`, + // but as a parenthesized list. This (and likely `MetaItem`) should be changed in + // such a way that builtin macros don't accept extraneous `unsafe()`. Some(MetaItem { unsafety: Safety::Default, path, kind, span }) } } From 15f8ffe371debffe922d8dde74918a2d14acc1fd Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Mon, 27 May 2024 11:45:32 -0500 Subject: [PATCH 10/14] Fix formatting --- compiler/rustc_ast_pretty/src/pprust/state.rs | 9 +++++++-- compiler/rustc_builtin_macros/src/derive.rs | 2 +- compiler/rustc_expand/src/build.rs | 18 ++++++++++++++++-- compiler/rustc_passes/src/check_attr.rs | 1 - src/librustdoc/clean/cfg/tests.rs | 2 +- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 54d642f6a0ffd..f32b63a39f0ac 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -260,8 +260,13 @@ pub fn print_crate<'a>( // root, so this is not needed, and actually breaks things. if edition.is_rust_2015() { // `#![no_std]` - let fake_attr = - attr::mk_attr_word(g, ast::AttrStyle::Inner, Safety::Default, sym::no_std, DUMMY_SP); + let fake_attr = attr::mk_attr_word( + g, + ast::AttrStyle::Inner, + Safety::Default, + sym::no_std, + DUMMY_SP, + ); s.print_attribute(&fake_attr); } } diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index dea668ff8f4b3..eed7fea11c19c 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -2,7 +2,7 @@ use crate::cfg_eval::cfg_eval; use crate::errors; use rustc_ast as ast; -use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind, Safety}; +use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, Safety, StmtKind}; use rustc_expand::base::{ Annotatable, DeriveResolution, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier, }; diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index e513e61f4d1e0..37dfd8305126a 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -674,12 +674,26 @@ impl<'a> ExtCtxt<'a> { // Note: `span` is used for both the identifier and the value. pub fn attr_name_value_str(&self, name: Symbol, val: Symbol, span: Span) -> ast::Attribute { let g = &self.sess.psess.attr_id_generator; - attr::mk_attr_name_value_str(g, ast::AttrStyle::Outer, ast::Safety::Default, name, val, span) + attr::mk_attr_name_value_str( + g, + ast::AttrStyle::Outer, + ast::Safety::Default, + name, + val, + span, + ) } // Builds `#[outer(inner)]`. pub fn attr_nested_word(&self, outer: Symbol, inner: Symbol, span: Span) -> ast::Attribute { let g = &self.sess.psess.attr_id_generator; - attr::mk_attr_nested_word(g, ast::AttrStyle::Outer, ast::Safety::Default, outer, inner, span) + attr::mk_attr_nested_word( + g, + ast::AttrStyle::Outer, + ast::Safety::Default, + outer, + inner, + span, + ) } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 29bc165159d8d..6ce7c41acc8ff 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -312,7 +312,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { true } - /// Checks if `unsafe()` is applied to an invalid attribute. fn check_unsafe_attr(&self, attr: &Attribute) { if !attr.is_doc_comment() { diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index 56a10f9fb9c2e..2857f74c744f5 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -1,6 +1,6 @@ use super::*; -use rustc_ast::{MetaItemLit, Path, StrStyle, Safety}; +use rustc_ast::{MetaItemLit, Path, Safety, StrStyle}; use rustc_span::create_default_session_globals_then; use rustc_span::symbol::{kw, Ident}; use rustc_span::DUMMY_SP; From 1cc4e8c73393137709080ce9b91c3996c62ad1f9 Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Mon, 27 May 2024 11:46:19 -0500 Subject: [PATCH 11/14] Add unsafe to `ffi_pure` and `ffi_const` --- compiler/rustc_feature/src/builtin_attrs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index f901f5c8c41ad..1cea9cccd9139 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -535,11 +535,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), gated!( - ffi_pure, Normal, template!(Word), WarnFollowing, + unsafe ffi_pure, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, experimental!(ffi_pure) ), gated!( - ffi_const, Normal, template!(Word), WarnFollowing, + unsafe ffi_const, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, experimental!(ffi_const) ), gated!( From 453093b7918dee3dda3b6a5bfe707a931013facd Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Thu, 6 Jun 2024 20:36:23 -0500 Subject: [PATCH 12/14] Remove extraneous attribute --- compiler/rustc_feature/src/builtin_attrs.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 1cea9cccd9139..9b5e4e50d3ca8 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -60,7 +60,6 @@ pub enum AttributeType { } #[derive(Copy, Clone, PartialEq, Debug)] -#[allow(dead_code)] pub enum AttributeSafety { /// Normal attribute that does not need `#[unsafe(...)]` Normal, From f83cdbd2e0f6ce2a10f1475b16ada9fff5c094d4 Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Thu, 6 Jun 2024 20:42:20 -0500 Subject: [PATCH 13/14] Fix ordering --- compiler/rustc_feature/src/unstable.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 4688624f310b2..d67422849d8a6 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -620,10 +620,10 @@ declare_features! ( (unstable, type_changing_struct_update, "1.58.0", Some(86555)), /// Allows unnamed fields of struct and union type (incomplete, unnamed_fields, "1.74.0", Some(49804)), - /// Allows unsafe on extern declarations and safety qualifiers over internal items. - (unstable, unsafe_extern_blocks, "CURRENT_RUSTC_VERSION", Some(123743)), /// Allows unsafe attributes. (unstable, unsafe_attributes, "CURRENT_RUSTC_VERSION", Some(123757)), + /// Allows unsafe on extern declarations and safety qualifiers over internal items. + (unstable, unsafe_extern_blocks, "CURRENT_RUSTC_VERSION", Some(123743)), /// Allows unsized fn parameters. (unstable, unsized_fn_params, "1.49.0", Some(48055)), /// Allows unsized rvalues at arguments and parameters. From f9104f0dfb531581aa96b19b333835351a566b04 Mon Sep 17 00:00:00 2001 From: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com> Date: Thu, 6 Jun 2024 20:54:51 -0500 Subject: [PATCH 14/14] Handle safe case --- compiler/rustc_builtin_macros/src/derive.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index eed7fea11c19c..b5cbfdf0ec6e4 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -167,5 +167,6 @@ fn report_unsafe_args(sess: &Session, meta: &ast::MetaItem) { sess.dcx().emit_err(errors::DeriveUnsafePath { span }); } Safety::Default => {} + Safety::Safe(_) => unreachable!(), } }