Skip to content

Commit af46699

Browse files
committed
Remove Session.used_attrs and move logic to CheckAttrVisitor
Instead of updating global state to mark attributes as used, we now explicitly emit a warning when an attribute is used in an unsupported position. As a side effect, we are to emit more detailed warning messages (instead of just a generic "unused" message). `Session.check_name` is removed, since its only purpose was to mark the attribute as used. All of the callers are modified to use `Attribute.has_name` Additionally, `AttributeType::AssumedUsed` is removed - an 'assumed used' attribute is implemented by simply not performing any checks in `CheckAttrVisitor` for a particular attribute. We no longer emit unused attribute warnings for the `#[rustc_dummy]` attribute - it's an internal attribute used for tests, so it doesn't mark sense to treat it as 'unused'. With this commit, a large source of global untracked state is removed.
1 parent b6e334d commit af46699

File tree

62 files changed

+535
-739
lines changed

Some content is hidden

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

62 files changed

+535
-739
lines changed

Cargo.lock

+2
Original file line numberDiff line numberDiff line change
@@ -4115,10 +4115,12 @@ dependencies = [
41154115
"rustc_attr",
41164116
"rustc_data_structures",
41174117
"rustc_errors",
4118+
"rustc_feature",
41184119
"rustc_hir",
41194120
"rustc_index",
41204121
"rustc_lexer",
41214122
"rustc_middle",
4123+
"rustc_parse",
41224124
"rustc_serialize",
41234125
"rustc_session",
41244126
"rustc_span",

compiler/rustc_ast_lowering/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2281,7 +2281,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
22812281
synthetic: param
22822282
.attrs
22832283
.iter()
2284-
.filter(|attr| self.sess.check_name(attr, sym::rustc_synthetic))
2284+
.filter(|attr| attr.has_name(sym::rustc_synthetic))
22852285
.map(|_| hir::SyntheticTyParamKind::FromAttr)
22862286
.next(),
22872287
};

compiler/rustc_ast_passes/src/feature_gate.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
268268
gate_feature_fn!(self, has_feature, attr.span, name, descr);
269269
}
270270
// Check unstable flavors of the `#[doc]` attribute.
271-
if self.sess.check_name(attr, sym::doc) {
271+
if attr.has_name(sym::doc) {
272272
for nested_meta in attr.meta_item_list().unwrap_or_default() {
273273
macro_rules! gate_doc { ($($name:ident => $feature:ident)*) => {
274274
$(if nested_meta.has_name(sym::$name) {
@@ -287,7 +287,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
287287
}
288288

289289
// Check for unstable modifiers on `#[link(..)]` attribute
290-
if self.sess.check_name(attr, sym::link) {
290+
if attr.has_name(sym::link) {
291291
for nested_meta in attr.meta_item_list().unwrap_or_default() {
292292
if nested_meta.has_name(sym::modifiers) {
293293
gate_feature_post!(
@@ -709,7 +709,7 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
709709

710710
if !sess.opts.unstable_features.is_nightly_build() {
711711
let lang_features = &sess.features_untracked().declared_lang_features;
712-
for attr in krate.attrs.iter().filter(|attr| sess.check_name(attr, sym::feature)) {
712+
for attr in krate.attrs.iter().filter(|attr| attr.has_name(sym::feature)) {
713713
let mut err = struct_span_err!(
714714
sess.parse_sess.span_diagnostic,
715715
attr.span,

compiler/rustc_attr/src/builtin.rs

+9-16
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,6 @@ where
166166
continue; // not a stability level
167167
}
168168

169-
sess.mark_attr_used(attr);
170-
171169
let meta = attr.meta();
172170

173171
if attr.has_name(sym::rustc_promotable) {
@@ -636,8 +634,7 @@ where
636634
let diagnostic = &sess.parse_sess.span_diagnostic;
637635

638636
'outer: for attr in attrs_iter {
639-
if !(sess.check_name(attr, sym::deprecated) || sess.check_name(attr, sym::rustc_deprecated))
640-
{
637+
if !(attr.has_name(sym::deprecated) || attr.has_name(sym::rustc_deprecated)) {
641638
continue;
642639
}
643640

@@ -700,17 +697,17 @@ where
700697
continue 'outer;
701698
}
702699
}
703-
sym::note if sess.check_name(attr, sym::deprecated) => {
700+
sym::note if attr.has_name(sym::deprecated) => {
704701
if !get(mi, &mut note) {
705702
continue 'outer;
706703
}
707704
}
708-
sym::reason if sess.check_name(attr, sym::rustc_deprecated) => {
705+
sym::reason if attr.has_name(sym::rustc_deprecated) => {
709706
if !get(mi, &mut note) {
710707
continue 'outer;
711708
}
712709
}
713-
sym::suggestion if sess.check_name(attr, sym::rustc_deprecated) => {
710+
sym::suggestion if attr.has_name(sym::rustc_deprecated) => {
714711
if !get(mi, &mut suggestion) {
715712
continue 'outer;
716713
}
@@ -721,7 +718,7 @@ where
721718
meta.span(),
722719
AttrError::UnknownMetaItem(
723720
pprust::path_to_string(&mi.path),
724-
if sess.check_name(attr, sym::deprecated) {
721+
if attr.has_name(sym::deprecated) {
725722
&["since", "note"]
726723
} else {
727724
&["since", "reason", "suggestion"]
@@ -747,11 +744,11 @@ where
747744
}
748745
}
749746

750-
if suggestion.is_some() && sess.check_name(attr, sym::deprecated) {
747+
if suggestion.is_some() && attr.has_name(sym::deprecated) {
751748
unreachable!("only allowed on rustc_deprecated")
752749
}
753750

754-
if sess.check_name(attr, sym::rustc_deprecated) {
751+
if attr.has_name(sym::rustc_deprecated) {
755752
if since.is_none() {
756753
handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince);
757754
continue;
@@ -763,9 +760,7 @@ where
763760
}
764761
}
765762

766-
sess.mark_attr_used(&attr);
767-
768-
let is_since_rustc_version = sess.check_name(attr, sym::rustc_deprecated);
763+
let is_since_rustc_version = attr.has_name(sym::rustc_deprecated);
769764
depr = Some((Deprecation { since, note, suggestion, is_since_rustc_version }, attr.span));
770765
}
771766

@@ -816,7 +811,6 @@ pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
816811
let diagnostic = &sess.parse_sess.span_diagnostic;
817812
if attr.has_name(sym::repr) {
818813
if let Some(items) = attr.meta_item_list() {
819-
sess.mark_attr_used(attr);
820814
for item in items {
821815
let mut recognised = false;
822816
if item.is_word() {
@@ -1015,14 +1009,13 @@ pub enum TransparencyError {
10151009
}
10161010

10171011
pub fn find_transparency(
1018-
sess: &Session,
10191012
attrs: &[Attribute],
10201013
macro_rules: bool,
10211014
) -> (Transparency, Option<TransparencyError>) {
10221015
let mut transparency = None;
10231016
let mut error = None;
10241017
for attr in attrs {
1025-
if sess.check_name(attr, sym::rustc_macro_transparency) {
1018+
if attr.has_name(sym::rustc_macro_transparency) {
10261019
if let Some((_, old_span)) = transparency {
10271020
error = Some(TransparencyError::MultipleTransparencyAttrs(old_span, attr.span));
10281021
break;

compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -677,8 +677,6 @@ impl<'a> TraitDef<'a> {
677677
let self_type = cx.ty_path(path);
678678

679679
let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived));
680-
// Just mark it now since we know that it'll end up used downstream
681-
cx.sess.mark_attr_used(&attr);
682680
let opt_trait_ref = Some(trait_ref);
683681
let unused_qual = {
684682
let word = rustc_ast::attr::mk_nested_word_item(Ident::new(

compiler/rustc_builtin_macros/src/proc_macro_harness.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,11 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
260260
return;
261261
}
262262

263-
if self.sess.check_name(attr, sym::proc_macro_derive) {
263+
if attr.has_name(sym::proc_macro_derive) {
264264
self.collect_custom_derive(item, attr);
265-
} else if self.sess.check_name(attr, sym::proc_macro_attribute) {
265+
} else if attr.has_name(sym::proc_macro_attribute) {
266266
self.collect_attr_proc_macro(item);
267-
} else if self.sess.check_name(attr, sym::proc_macro) {
267+
} else if attr.has_name(sym::proc_macro) {
268268
self.collect_bang_proc_macro(item);
269269
};
270270

compiler/rustc_builtin_macros/src/test_harness.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,7 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> {
188188
let attrs = attrs
189189
.into_iter()
190190
.filter(|attr| {
191-
!self.sess.check_name(attr, sym::rustc_main)
192-
&& !self.sess.check_name(attr, sym::start)
191+
!attr.has_name(sym::rustc_main) && !attr.has_name(sym::start)
193192
})
194193
.chain(iter::once(allow_dead_code))
195194
.collect();

compiler/rustc_expand/src/config.rs

+13-56
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_ast::token::{DelimToken, Token, TokenKind};
55
use rustc_ast::tokenstream::{AttrAnnotatedTokenStream, AttrAnnotatedTokenTree};
66
use rustc_ast::tokenstream::{DelimSpan, Spacing};
77
use rustc_ast::tokenstream::{LazyTokenStream, TokenTree};
8-
use rustc_ast::{self as ast, AstLike, AttrItem, AttrStyle, Attribute, MetaItem};
8+
use rustc_ast::{self as ast, AstLike, AttrStyle, Attribute, MetaItem};
99
use rustc_attr as attr;
1010
use rustc_data_structures::fx::FxHashMap;
1111
use rustc_data_structures::map_in_place::MapInPlace;
@@ -14,7 +14,7 @@ use rustc_feature::{Feature, Features, State as FeatureState};
1414
use rustc_feature::{
1515
ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES, STABLE_REMOVED_FEATURES,
1616
};
17-
use rustc_parse::{parse_in, validate_attr};
17+
use rustc_parse::validate_attr;
1818
use rustc_session::parse::feature_err;
1919
use rustc_session::Session;
2020
use rustc_span::edition::{Edition, ALL_EDITIONS};
@@ -75,7 +75,7 @@ fn get_features(
7575
// Process the edition umbrella feature-gates first, to ensure
7676
// `edition_enabled_features` is completed before it's queried.
7777
for attr in krate_attrs {
78-
if !sess.check_name(attr, sym::feature) {
78+
if !attr.has_name(sym::feature) {
7979
continue;
8080
}
8181

@@ -108,7 +108,7 @@ fn get_features(
108108
}
109109

110110
for attr in krate_attrs {
111-
if !sess.check_name(attr, sym::feature) {
111+
if !attr.has_name(sym::feature) {
112112
continue;
113113
}
114114

@@ -237,11 +237,6 @@ macro_rules! configure {
237237
};
238238
}
239239

240-
const CFG_ATTR_GRAMMAR_HELP: &str = "#[cfg_attr(condition, attribute, other_attribute, ...)]";
241-
const CFG_ATTR_NOTE_REF: &str = "for more information, visit \
242-
<https://doc.rust-lang.org/reference/conditional-compilation.html\
243-
#the-cfg_attr-attribute>";
244-
245240
impl<'a> StripUnconfigured<'a> {
246241
pub fn configure<T: AstLike>(&mut self, mut node: T) -> Option<T> {
247242
self.process_cfg_attrs(&mut node);
@@ -349,19 +344,17 @@ impl<'a> StripUnconfigured<'a> {
349344
return vec![attr];
350345
}
351346

352-
let (cfg_predicate, expanded_attrs) = match self.parse_cfg_attr(&attr) {
353-
None => return vec![],
354-
Some(r) => r,
355-
};
347+
let (cfg_predicate, expanded_attrs) =
348+
match rustc_parse::parse_cfg_attr(&attr, &self.sess.parse_sess) {
349+
None => return vec![],
350+
Some(r) => r,
351+
};
356352

357353
// Lint on zero attributes in source.
358354
if expanded_attrs.is_empty() {
359355
return vec![attr];
360356
}
361357

362-
// At this point we know the attribute is considered used.
363-
self.sess.mark_attr_used(&attr);
364-
365358
if !attr::cfg_matches(&cfg_predicate, &self.sess.parse_sess, self.features) {
366359
return vec![];
367360
}
@@ -415,46 +408,10 @@ impl<'a> StripUnconfigured<'a> {
415408
.collect()
416409
}
417410

418-
fn parse_cfg_attr(&self, attr: &Attribute) -> Option<(MetaItem, Vec<(AttrItem, Span)>)> {
419-
match attr.get_normal_item().args {
420-
ast::MacArgs::Delimited(dspan, delim, ref tts) if !tts.is_empty() => {
421-
let msg = "wrong `cfg_attr` delimiters";
422-
validate_attr::check_meta_bad_delim(&self.sess.parse_sess, dspan, delim, msg);
423-
match parse_in(&self.sess.parse_sess, tts.clone(), "`cfg_attr` input", |p| {
424-
p.parse_cfg_attr()
425-
}) {
426-
Ok(r) => return Some(r),
427-
Err(mut e) => {
428-
e.help(&format!("the valid syntax is `{}`", CFG_ATTR_GRAMMAR_HELP))
429-
.note(CFG_ATTR_NOTE_REF)
430-
.emit();
431-
}
432-
}
433-
}
434-
_ => self.error_malformed_cfg_attr_missing(attr.span),
435-
}
436-
None
437-
}
438-
439-
fn error_malformed_cfg_attr_missing(&self, span: Span) {
440-
self.sess
441-
.parse_sess
442-
.span_diagnostic
443-
.struct_span_err(span, "malformed `cfg_attr` attribute input")
444-
.span_suggestion(
445-
span,
446-
"missing condition and attribute",
447-
CFG_ATTR_GRAMMAR_HELP.to_string(),
448-
Applicability::HasPlaceholders,
449-
)
450-
.note(CFG_ATTR_NOTE_REF)
451-
.emit();
452-
}
453-
454411
/// Determines if a node with the given attributes should be included in this configuration.
455412
fn in_cfg(&self, attrs: &[Attribute]) -> bool {
456413
attrs.iter().all(|attr| {
457-
if !is_cfg(self.sess, attr) {
414+
if !is_cfg(attr) {
458415
return true;
459416
}
460417
let meta_item = match validate_attr::parse_meta(&self.sess.parse_sess, attr) {
@@ -500,7 +457,7 @@ impl<'a> StripUnconfigured<'a> {
500457
//
501458
// N.B., this is intentionally not part of the visit_expr() function
502459
// in order for filter_map_expr() to be able to avoid this check
503-
if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(self.sess, a)) {
460+
if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(*a)) {
504461
let msg = "removing an expression is not supported in this position";
505462
self.sess.parse_sess.span_diagnostic.span_err(attr.span, msg);
506463
}
@@ -536,6 +493,6 @@ pub fn parse_cfg<'a>(meta_item: &'a MetaItem, sess: &Session) -> Option<&'a Meta
536493
}
537494
}
538495

539-
fn is_cfg(sess: &Session, attr: &Attribute) -> bool {
540-
sess.check_name(attr, sym::cfg)
496+
fn is_cfg(attr: &Attribute) -> bool {
497+
attr.has_name(sym::cfg)
541498
}

compiler/rustc_expand/src/expand.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -753,11 +753,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
753753
}
754754
}
755755
}
756-
SyntaxExtensionKind::NonMacroAttr { mark_used } => {
756+
SyntaxExtensionKind::NonMacroAttr { mark_used: _ } => {
757757
self.cx.expanded_inert_attrs.mark(&attr);
758-
if *mark_used {
759-
self.cx.sess.mark_attr_used(&attr);
760-
}
761758
item.visit_attrs(|attrs| attrs.insert(pos, attr));
762759
fragment_kind.expect_from_annotatables(iter::once(item))
763760
}

compiler/rustc_expand/src/mbe/macro_rules.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ pub fn compile_declarative_macro(
535535

536536
valid &= macro_check::check_meta_variables(&sess.parse_sess, def.id, def.span, &lhses, &rhses);
537537

538-
let (transparency, transparency_error) = attr::find_transparency(sess, &def.attrs, macro_rules);
538+
let (transparency, transparency_error) = attr::find_transparency(&def.attrs, macro_rules);
539539
match transparency_error {
540540
Some(TransparencyError::UnknownTransparency(value, span)) => {
541541
diag.span_err(span, &format!("unknown macro transparency: `{}`", value))

0 commit comments

Comments
 (0)