-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove Session.used_attrs
and move logic to CheckAttrVisitor
#87739
Conversation
r? @wesleywiser (rust-highfive has picked a reviewer for you, use r? to override) |
☔ The latest upstream changes (presumably #87568) made this pull request unmergeable. Please resolve the merge conflicts. |
0d06da4
to
fe702a4
Compare
☔ The latest upstream changes (presumably #85296) made this pull request unmergeable. Please resolve the merge conflicts. |
// Don't warn on `automatically_derived` - a custom derive | ||
// could reasonally annotate anything that it emits with | ||
// this attribute |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a behavior change. Do we need a signoff of some kind to do this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This attribute is pretty under-specified - it seems to suppress a handful of lints, which aren't documented anywhere. I think the best approach would be to warn when it's used on a non-impl (since impls are the only places where we currently check for it).
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.
fe702a4
to
62aea8c
Compare
@wesleywiser I've addressed your comments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great to me!
@bors r+ |
📌 Commit 62aea8c has been approved by |
☀️ Test successful - checks-actions |
let check_name = |attr, sym| tcx.sess.check_name(attr, sym); | ||
let check_name = |attr: &Attribute, sym| attr.has_name(sym); | ||
if let Some(name) = weak_lang_items::link_name(check_name, &attrs) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be inlined into weak_lang_items::link_name
? I'm guessing it only took a closure because the Session
type wasn't available or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Posted #92702 to clean this up.
pub fn is_proc_macro_attr(&self, attr: &Attribute) -> bool { | ||
[sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive] | ||
.iter() | ||
.any(|kind| self.check_name(attr, *kind)) | ||
.any(|kind| attr.has_name(*kind)) | ||
} | ||
|
||
pub fn contains_name(&self, attrs: &[Attribute], name: Symbol) -> bool { | ||
attrs.iter().any(|item| self.check_name(item, name)) | ||
attrs.iter().any(|item| item.has_name(name)) | ||
} | ||
|
||
pub fn find_by_name<'a>( | ||
&'a self, | ||
attrs: &'a [Attribute], | ||
name: Symbol, | ||
) -> Option<&'a Attribute> { | ||
attrs.iter().find(|attr| self.check_name(attr, name)) | ||
attrs.iter().find(|attr| attr.has_name(name)) | ||
} | ||
|
||
pub fn filter_by_name<'a>( | ||
&'a self, | ||
attrs: &'a [Attribute], | ||
name: Symbol, | ||
) -> impl Iterator<Item = &'a Attribute> { | ||
attrs.iter().filter(move |attr| self.check_name(attr, name)) | ||
attrs.iter().filter(move |attr| attr.has_name(name)) | ||
} | ||
|
||
pub fn first_attr_value_str_by_name( | ||
&self, | ||
attrs: &[Attribute], | ||
name: Symbol, | ||
) -> Option<Symbol> { | ||
attrs.iter().find(|at| self.check_name(at, name)).and_then(|at| at.value_str()) | ||
attrs.iter().find(|at| at.has_name(name)).and_then(|at| at.value_str()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do any of these methods need to be on Session
, or can they be moved back to being on the attributes themselves?
let check_name = |attr, sym| self.tcx.sess.check_name(attr, sym); | ||
let check_name = |attr: &Attribute, sym| attr.has_name(sym); | ||
if let Some((value, span)) = extract(check_name, &attrs) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here as with the weak lang items, I'm guessing?
fn check_stability_promotable(&self, attr: &Attribute, _span: &Span, target: Target) -> bool { | ||
match target { | ||
Target::Expression => { | ||
self.tcx | ||
.sess | ||
.struct_span_err(attr.span, "attribute cannot be applied to an expression") | ||
.emit(); | ||
false | ||
} | ||
_ => true, | ||
} | ||
} | ||
|
||
fn check_deprecated(&self, hir_id: HirId, attr: &Attribute, _span: &Span, target: Target) { | ||
match target { | ||
Target::Closure | Target::Expression | Target::Statement | Target::Arm => { | ||
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { | ||
lint.build("attribute is ignored here").emit(); | ||
}); | ||
} | ||
_ => {} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't these checks have lists of allowed Target
s, as opposed to disallowed Target
s?
| sym::rustc_const_stable | ||
| sym::unstable | ||
| sym::stable | ||
| sym::rustc_promotable => self.check_stability_promotable(&attr, span, target), | ||
_ => true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're handling all the builtin attributes, shouldn't we disallow unknown attributes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this could be an exhaustive match
over an enum
generated by rustc_feature::builtin_attrs
? So that there's no way it can go out of sync.
Noted in rust-lang#87739 (review), lang_items::extract no longer needs to take a closure.
…etrochenkov Clean up lang_items::extract Noted in rust-lang#87739 (review), lang_items::extract no longer needs to take a closure.
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 markthe attribute as used. All of the callers are modified to use
Attribute.has_name
Additionally,
AttributeType::AssumedUsed
is removed - an 'assumedused' 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.