Skip to content

Commit c807e2d

Browse files
committed
Parse unsafe attributes
1 parent 54692c3 commit c807e2d

File tree

18 files changed

+168
-26
lines changed

18 files changed

+168
-26
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ pub struct Crate {
489489
/// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`.
490490
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
491491
pub struct MetaItem {
492+
pub unsafety: Unsafe,
492493
pub path: Path,
493494
pub kind: MetaItemKind,
494495
pub span: Span,
@@ -2792,14 +2793,20 @@ pub struct NormalAttr {
27922793
impl NormalAttr {
27932794
pub fn from_ident(ident: Ident) -> Self {
27942795
Self {
2795-
item: AttrItem { path: Path::from_ident(ident), args: AttrArgs::Empty, tokens: None },
2796+
item: AttrItem {
2797+
unsafety: Unsafe::No,
2798+
path: Path::from_ident(ident),
2799+
args: AttrArgs::Empty,
2800+
tokens: None,
2801+
},
27962802
tokens: None,
27972803
}
27982804
}
27992805
}
28002806

28012807
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
28022808
pub struct AttrItem {
2809+
pub unsafety: Unsafe,
28032810
pub path: Path,
28042811
pub args: AttrArgs,
28052812
pub tokens: Option<LazyAttrTokenStream>,

compiler/rustc_ast/src/attr/mod.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! Functions dealing with attributes and meta items.
22
3-
use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute};
3+
use crate::ast::{
4+
AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute, Unsafe,
5+
};
46
use crate::ast::{DelimArgs, Expr, ExprKind, LitKind, MetaItemLit};
57
use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem, NormalAttr};
68
use crate::ast::{Path, PathSegment, DUMMY_NODE_ID};
@@ -227,7 +229,12 @@ impl AttrItem {
227229
}
228230

229231
pub fn meta(&self, span: Span) -> Option<MetaItem> {
230-
Some(MetaItem { path: self.path.clone(), kind: self.meta_kind()?, span })
232+
Some(MetaItem {
233+
unsafety: Unsafe::No,
234+
path: self.path.clone(),
235+
kind: self.meta_kind()?,
236+
span,
237+
})
231238
}
232239

233240
pub fn meta_kind(&self) -> Option<MetaItemKind> {
@@ -357,7 +364,8 @@ impl MetaItem {
357364
_ => path.span.hi(),
358365
};
359366
let span = path.span.with_hi(hi);
360-
Some(MetaItem { path, kind, span })
367+
// FIX THIS LATER
368+
Some(MetaItem { unsafety: Unsafe::No, path, kind, span })
361369
}
362370
}
363371

@@ -547,11 +555,12 @@ pub fn mk_doc_comment(
547555
pub fn mk_attr(
548556
g: &AttrIdGenerator,
549557
style: AttrStyle,
558+
unsafety: Unsafe,
550559
path: Path,
551560
args: AttrArgs,
552561
span: Span,
553562
) -> Attribute {
554-
mk_attr_from_item(g, AttrItem { path, args, tokens: None }, None, style, span)
563+
mk_attr_from_item(g, AttrItem { unsafety, path, args, tokens: None }, None, style, span)
555564
}
556565

557566
pub fn mk_attr_from_item(
@@ -569,15 +578,22 @@ pub fn mk_attr_from_item(
569578
}
570579
}
571580

572-
pub fn mk_attr_word(g: &AttrIdGenerator, style: AttrStyle, name: Symbol, span: Span) -> Attribute {
581+
pub fn mk_attr_word(
582+
g: &AttrIdGenerator,
583+
style: AttrStyle,
584+
unsafety: Unsafe,
585+
name: Symbol,
586+
span: Span,
587+
) -> Attribute {
573588
let path = Path::from_ident(Ident::new(name, span));
574589
let args = AttrArgs::Empty;
575-
mk_attr(g, style, path, args, span)
590+
mk_attr(g, style, unsafety, path, args, span)
576591
}
577592

578593
pub fn mk_attr_nested_word(
579594
g: &AttrIdGenerator,
580595
style: AttrStyle,
596+
unsafety: Unsafe,
581597
outer: Symbol,
582598
inner: Symbol,
583599
span: Span,
@@ -593,12 +609,13 @@ pub fn mk_attr_nested_word(
593609
delim: Delimiter::Parenthesis,
594610
tokens: inner_tokens,
595611
});
596-
mk_attr(g, style, path, attr_args, span)
612+
mk_attr(g, style, unsafety, path, attr_args, span)
597613
}
598614

599615
pub fn mk_attr_name_value_str(
600616
g: &AttrIdGenerator,
601617
style: AttrStyle,
618+
unsafety: Unsafe,
602619
name: Symbol,
603620
val: Symbol,
604621
span: Span,
@@ -613,7 +630,7 @@ pub fn mk_attr_name_value_str(
613630
});
614631
let path = Path::from_ident(Ident::new(name, span));
615632
let args = AttrArgs::Eq(span, AttrArgsEq::Ast(expr));
616-
mk_attr(g, style, path, args, span)
633+
mk_attr(g, style, unsafety, path, args, span)
617634
}
618635

619636
pub fn filter_by_name(attrs: &[Attribute], name: Symbol) -> impl Iterator<Item = &Attribute> {

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,10 @@ pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
646646
let Attribute { kind, id: _, style: _, span } = attr;
647647
match kind {
648648
AttrKind::Normal(normal) => {
649-
let NormalAttr { item: AttrItem { path, args, tokens }, tokens: attr_tokens } =
650-
&mut **normal;
649+
let NormalAttr {
650+
item: AttrItem { unsafety: _, path, args, tokens },
651+
tokens: attr_tokens,
652+
} = &mut **normal;
651653
vis.visit_path(path);
652654
visit_attr_args(args, vis);
653655
visit_lazy_tts(tokens, vis);
@@ -677,7 +679,7 @@ pub fn noop_visit_meta_list_item<T: MutVisitor>(li: &mut NestedMetaItem, vis: &m
677679
}
678680

679681
pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) {
680-
let MetaItem { path: _, kind, span } = mi;
682+
let MetaItem { unsafety: _, path: _, kind, span } = mi;
681683
match kind {
682684
MetaItemKind::Word => {}
683685
MetaItemKind::List(mis) => visit_thin_vec(mis, |mi| vis.visit_meta_list_item(mi)),
@@ -840,7 +842,7 @@ pub fn visit_nonterminal<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T
840842
token::NtLifetime(ident) => vis.visit_ident(ident),
841843
token::NtLiteral(expr) => vis.visit_expr(expr),
842844
token::NtMeta(item) => {
843-
let AttrItem { path, args, tokens } = item.deref_mut();
845+
let AttrItem { unsafety: _, path, args, tokens } = item.deref_mut();
844846
vis.visit_path(path);
845847
visit_attr_args(args, vis);
846848
visit_lazy_tts(tokens, vis);

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,6 +1790,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
17901790
let attr = attr::mk_attr_nested_word(
17911791
&self.tcx.sess.psess.attr_id_generator,
17921792
AttrStyle::Outer,
1793+
Unsafe::No,
17931794
sym::allow,
17941795
sym::unreachable_code,
17951796
self.lower_span(span),

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
908908
let kind = match attr.kind {
909909
AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr {
910910
item: AttrItem {
911+
unsafety: normal.item.unsafety,
911912
path: normal.item.path.clone(),
912913
args: self.lower_attr_args(&normal.item.args),
913914
tokens: None,

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
570570
gate_all!(postfix_match, "postfix match is experimental");
571571
gate_all!(mut_ref, "mutable by-reference bindings are experimental");
572572
gate_all!(precise_capturing, "precise captures on `impl Trait` are experimental");
573+
gate_all!(unsafe_attributes, "`#[unsafe()]` markers for attributes are experimental");
573574

574575
if !visitor.features.never_patterns {
575576
if let Some(spans) = spans.get(&sym::never_patterns) {

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree};
1616
use rustc_ast::util::classify;
1717
use rustc_ast::util::comments::{Comment, CommentStyle};
1818
use rustc_ast::util::parser;
19-
use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind};
19+
use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind, Unsafe};
2020
use rustc_ast::{attr, BindingMode, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term};
2121
use rustc_ast::{GenericArg, GenericBound, SelfKind};
2222
use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
@@ -245,6 +245,7 @@ pub fn print_crate<'a>(
245245
let fake_attr = attr::mk_attr_nested_word(
246246
g,
247247
ast::AttrStyle::Inner,
248+
Unsafe::No,
248249
sym::feature,
249250
sym::prelude_import,
250251
DUMMY_SP,
@@ -255,7 +256,8 @@ pub fn print_crate<'a>(
255256
// root, so this is not needed, and actually breaks things.
256257
if edition.is_rust_2015() {
257258
// `#![no_std]`
258-
let fake_attr = attr::mk_attr_word(g, ast::AttrStyle::Inner, sym::no_std, DUMMY_SP);
259+
let fake_attr =
260+
attr::mk_attr_word(g, ast::AttrStyle::Inner, Unsafe::No, sym::no_std, DUMMY_SP);
259261
s.print_attribute(&fake_attr);
260262
}
261263
}

compiler/rustc_builtin_macros/src/cmdline_attrs.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) {
1616
);
1717

1818
let start_span = parser.token.span;
19-
let AttrItem { path, args, tokens: _ } = match parser.parse_attr_item(false) {
19+
let AttrItem { unsafety, path, args, tokens: _ } = match parser.parse_attr_item(false) {
2020
Ok(ai) => ai,
2121
Err(err) => {
2222
err.emit();
@@ -32,6 +32,7 @@ pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) {
3232
krate.attrs.push(mk_attr(
3333
&psess.attr_id_generator,
3434
AttrStyle::Inner,
35+
unsafety,
3536
path,
3637
args,
3738
start_span.to(end_span),

compiler/rustc_builtin_macros/src/test_harness.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> {
202202
let allow_dead_code = attr::mk_attr_nested_word(
203203
&self.sess.psess.attr_id_generator,
204204
ast::AttrStyle::Outer,
205+
ast::Unsafe::No,
205206
sym::allow,
206207
sym::dead_code,
207208
self.def_site,

compiler/rustc_expand/src/build.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -690,20 +690,20 @@ impl<'a> ExtCtxt<'a> {
690690
// Builds `#[name]`.
691691
pub fn attr_word(&self, name: Symbol, span: Span) -> ast::Attribute {
692692
let g = &self.sess.psess.attr_id_generator;
693-
attr::mk_attr_word(g, ast::AttrStyle::Outer, name, span)
693+
attr::mk_attr_word(g, ast::AttrStyle::Outer, ast::Unsafe::No, name, span)
694694
}
695695

696696
// Builds `#[name = val]`.
697697
//
698698
// Note: `span` is used for both the identifier and the value.
699699
pub fn attr_name_value_str(&self, name: Symbol, val: Symbol, span: Span) -> ast::Attribute {
700700
let g = &self.sess.psess.attr_id_generator;
701-
attr::mk_attr_name_value_str(g, ast::AttrStyle::Outer, name, val, span)
701+
attr::mk_attr_name_value_str(g, ast::AttrStyle::Outer, ast::Unsafe::No, name, val, span)
702702
}
703703

704704
// Builds `#[outer(inner)]`.
705705
pub fn attr_nested_word(&self, outer: Symbol, inner: Symbol, span: Span) -> ast::Attribute {
706706
let g = &self.sess.psess.attr_id_generator;
707-
attr::mk_attr_nested_word(g, ast::AttrStyle::Outer, outer, inner, span)
707+
attr::mk_attr_nested_word(g, ast::AttrStyle::Outer, ast::Unsafe::No, outer, inner, span)
708708
}
709709
}

0 commit comments

Comments
 (0)