Report the unsafe_attr_outside_unsafe lint at the closest node
This commit is contained in:
parent
74a17fd049
commit
f4e1ec111c
5 changed files with 39 additions and 8 deletions
|
|
@ -828,7 +828,7 @@ fn validate_generic_param_order(dcx: DiagCtxtHandle<'_>, generics: &[GenericPara
|
|||
|
||||
impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
fn visit_attribute(&mut self, attr: &Attribute) {
|
||||
validate_attr::check_attr(&self.sess.psess, attr);
|
||||
validate_attr::check_attr(&self.sess.psess, attr, self.lint_node_id);
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: &'a Ty) {
|
||||
|
|
|
|||
|
|
@ -274,7 +274,12 @@ impl<'a> StripUnconfigured<'a> {
|
|||
/// is in the original source file. Gives a compiler error if the syntax of
|
||||
/// the attribute is incorrect.
|
||||
pub(crate) fn expand_cfg_attr(&self, cfg_attr: &Attribute, recursive: bool) -> Vec<Attribute> {
|
||||
validate_attr::check_attribute_safety(&self.sess.psess, AttributeSafety::Normal, &cfg_attr);
|
||||
validate_attr::check_attribute_safety(
|
||||
&self.sess.psess,
|
||||
AttributeSafety::Normal,
|
||||
&cfg_attr,
|
||||
ast::CRATE_NODE_ID,
|
||||
);
|
||||
|
||||
// A trace attribute left in AST in place of the original `cfg_attr` attribute.
|
||||
// It can later be used by lints or other diagnostics.
|
||||
|
|
|
|||
|
|
@ -1983,7 +1983,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||
let mut span: Option<Span> = None;
|
||||
while let Some(attr) = attrs.next() {
|
||||
rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.sess, features);
|
||||
validate_attr::check_attr(&self.cx.sess.psess, attr);
|
||||
validate_attr::check_attr(
|
||||
&self.cx.sess.psess,
|
||||
attr,
|
||||
self.cx.current_expansion.lint_node_id,
|
||||
);
|
||||
|
||||
let current_span = if let Some(sp) = span { sp.to(attr.span) } else { attr.span };
|
||||
span = Some(current_span);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
use rustc_ast::token::Delimiter;
|
||||
use rustc_ast::tokenstream::DelimSpan;
|
||||
use rustc_ast::{
|
||||
self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, Safety,
|
||||
self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, NodeId,
|
||||
Safety,
|
||||
};
|
||||
use rustc_errors::{Applicability, FatalError, PResult};
|
||||
use rustc_feature::{AttributeSafety, AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
|
||||
|
|
@ -15,7 +16,7 @@ use rustc_span::{Span, Symbol, sym};
|
|||
|
||||
use crate::{errors, parse_in};
|
||||
|
||||
pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
|
||||
pub fn check_attr(psess: &ParseSess, attr: &Attribute, id: NodeId) {
|
||||
if attr.is_doc_comment() || attr.has_name(sym::cfg_trace) || attr.has_name(sym::cfg_attr_trace)
|
||||
{
|
||||
return;
|
||||
|
|
@ -26,7 +27,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
|
|||
|
||||
// All non-builtin attributes are considered safe
|
||||
let safety = attr_info.map(|x| x.safety).unwrap_or(AttributeSafety::Normal);
|
||||
check_attribute_safety(psess, safety, attr);
|
||||
check_attribute_safety(psess, safety, attr, id);
|
||||
|
||||
// Check input tokens for built-in and key-value attributes.
|
||||
match attr_info {
|
||||
|
|
@ -154,7 +155,12 @@ fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaIte
|
|||
}
|
||||
}
|
||||
|
||||
pub fn check_attribute_safety(psess: &ParseSess, safety: AttributeSafety, attr: &Attribute) {
|
||||
pub fn check_attribute_safety(
|
||||
psess: &ParseSess,
|
||||
safety: AttributeSafety,
|
||||
attr: &Attribute,
|
||||
id: NodeId,
|
||||
) {
|
||||
let attr_item = attr.get_normal_item();
|
||||
|
||||
if let AttributeSafety::Unsafe { unsafe_since } = safety {
|
||||
|
|
@ -185,7 +191,7 @@ pub fn check_attribute_safety(psess: &ParseSess, safety: AttributeSafety, attr:
|
|||
psess.buffer_lint(
|
||||
UNSAFE_ATTR_OUTSIDE_UNSAFE,
|
||||
path_span,
|
||||
ast::CRATE_NODE_ID,
|
||||
id,
|
||||
BuiltinLintDiag::UnsafeAttrOutsideUnsafe {
|
||||
attribute_name_span: path_span,
|
||||
sugg_spans: (diag_span.shrink_to_lo(), diag_span.shrink_to_hi()),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
//@ check-pass
|
||||
//@ edition: 2021
|
||||
//
|
||||
// Anti-regression test for https://github.com/rust-lang/rust/issues/140602
|
||||
// where the generated warning couldn't be allowed due too being attached to
|
||||
// the wrong AST node.
|
||||
|
||||
#![deny(unsafe_attr_outside_unsafe)]
|
||||
|
||||
#[allow(unsafe_attr_outside_unsafe)]
|
||||
mod generated {
|
||||
#[no_mangle]
|
||||
fn _generated_foo() {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue