Rollup merge of #139615 - nnethercote:rm-name_or_empty, r=jdonszelmann
Remove `name_or_empty` Another step towards #137978. r? ``@jdonszelmann``
This commit is contained in:
commit
540fb228af
42 changed files with 309 additions and 226 deletions
|
@ -305,8 +305,8 @@ impl MetaItem {
|
||||||
if let [PathSegment { ident, .. }] = self.path.segments[..] { Some(ident) } else { None }
|
if let [PathSegment { ident, .. }] = self.path.segments[..] { Some(ident) } else { None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name_or_empty(&self) -> Symbol {
|
pub fn name(&self) -> Option<Symbol> {
|
||||||
self.ident().unwrap_or_else(Ident::empty).name
|
self.ident().map(|ident| ident.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_name(&self, name: Symbol) -> bool {
|
pub fn has_name(&self, name: Symbol) -> bool {
|
||||||
|
@ -511,13 +511,14 @@ impl MetaItemInner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For a single-segment meta item, returns its name; otherwise, returns `None`.
|
/// For a single-segment meta item, returns its identifier; otherwise, returns `None`.
|
||||||
pub fn ident(&self) -> Option<Ident> {
|
pub fn ident(&self) -> Option<Ident> {
|
||||||
self.meta_item().and_then(|meta_item| meta_item.ident())
|
self.meta_item().and_then(|meta_item| meta_item.ident())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name_or_empty(&self) -> Symbol {
|
/// For a single-segment meta item, returns its name; otherwise, returns `None`.
|
||||||
self.ident().unwrap_or_else(Ident::empty).name
|
pub fn name(&self) -> Option<Symbol> {
|
||||||
|
self.ident().map(|ident| ident.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if this list item is a MetaItem with a name of `name`.
|
/// Returns `true` if this list item is a MetaItem with a name of `name`.
|
||||||
|
@ -738,9 +739,9 @@ pub trait AttributeExt: Debug {
|
||||||
fn id(&self) -> AttrId;
|
fn id(&self) -> AttrId;
|
||||||
|
|
||||||
/// For a single-segment attribute (i.e., `#[attr]` and not `#[path::atrr]`),
|
/// For a single-segment attribute (i.e., `#[attr]` and not `#[path::atrr]`),
|
||||||
/// return the name of the attribute, else return the empty identifier.
|
/// return the name of the attribute; otherwise, returns `None`.
|
||||||
fn name_or_empty(&self) -> Symbol {
|
fn name(&self) -> Option<Symbol> {
|
||||||
self.ident().unwrap_or_else(Ident::empty).name
|
self.ident().map(|ident| ident.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the meta item list, `#[attr(meta item list)]`
|
/// Get the meta item list, `#[attr(meta item list)]`
|
||||||
|
@ -752,7 +753,7 @@ pub trait AttributeExt: Debug {
|
||||||
/// Gets the span of the value literal, as string, when using `#[attr = value]`
|
/// Gets the span of the value literal, as string, when using `#[attr = value]`
|
||||||
fn value_span(&self) -> Option<Span>;
|
fn value_span(&self) -> Option<Span>;
|
||||||
|
|
||||||
/// For a single-segment attribute, returns its name; otherwise, returns `None`.
|
/// For a single-segment attribute, returns its ident; otherwise, returns `None`.
|
||||||
fn ident(&self) -> Option<Ident>;
|
fn ident(&self) -> Option<Ident>;
|
||||||
|
|
||||||
/// Checks whether the path of this attribute matches the name.
|
/// Checks whether the path of this attribute matches the name.
|
||||||
|
@ -770,6 +771,11 @@ pub trait AttributeExt: Debug {
|
||||||
self.ident().map(|x| x.name == name).unwrap_or(false)
|
self.ident().map(|x| x.name == name).unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn has_any_name(&self, names: &[Symbol]) -> bool {
|
||||||
|
names.iter().any(|&name| self.has_name(name))
|
||||||
|
}
|
||||||
|
|
||||||
/// get the span of the entire attribute
|
/// get the span of the entire attribute
|
||||||
fn span(&self) -> Span;
|
fn span(&self) -> Span;
|
||||||
|
|
||||||
|
@ -813,8 +819,8 @@ impl Attribute {
|
||||||
AttributeExt::id(self)
|
AttributeExt::id(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name_or_empty(&self) -> Symbol {
|
pub fn name(&self) -> Option<Symbol> {
|
||||||
AttributeExt::name_or_empty(self)
|
AttributeExt::name(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
|
pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
|
||||||
|
@ -846,6 +852,11 @@ impl Attribute {
|
||||||
AttributeExt::has_name(self, name)
|
AttributeExt::has_name(self, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn has_any_name(&self, names: &[Symbol]) -> bool {
|
||||||
|
AttributeExt::has_any_name(self, names)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn span(&self) -> Span {
|
pub fn span(&self) -> Span {
|
||||||
AttributeExt::span(self)
|
AttributeExt::span(self)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1310,7 +1310,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
// create a fake body so that the entire rest of the compiler doesn't have to deal with
|
// create a fake body so that the entire rest of the compiler doesn't have to deal with
|
||||||
// this as a special case.
|
// this as a special case.
|
||||||
return self.lower_fn_body(decl, contract, |this| {
|
return self.lower_fn_body(decl, contract, |this| {
|
||||||
if attrs.iter().any(|a| a.name_or_empty() == sym::rustc_intrinsic) {
|
if attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic)) {
|
||||||
let span = this.lower_span(span);
|
let span = this.lower_span(span);
|
||||||
let empty_block = hir::Block {
|
let empty_block = hir::Block {
|
||||||
hir_id: this.next_id(),
|
hir_id: this.next_id(),
|
||||||
|
|
|
@ -347,7 +347,7 @@ impl<'a> AstValidator<'a> {
|
||||||
sym::forbid,
|
sym::forbid,
|
||||||
sym::warn,
|
sym::warn,
|
||||||
];
|
];
|
||||||
!arr.contains(&attr.name_or_empty()) && rustc_attr_parsing::is_builtin_attr(*attr)
|
!attr.has_any_name(&arr) && rustc_attr_parsing::is_builtin_attr(*attr)
|
||||||
})
|
})
|
||||||
.for_each(|attr| {
|
.for_each(|attr| {
|
||||||
if attr.is_doc_comment() {
|
if attr.is_doc_comment() {
|
||||||
|
@ -947,8 +947,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
|
self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
|
||||||
self.check_defaultness(item.span, *defaultness);
|
self.check_defaultness(item.span, *defaultness);
|
||||||
|
|
||||||
let is_intrinsic =
|
let is_intrinsic = item.attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic));
|
||||||
item.attrs.iter().any(|a| a.name_or_empty() == sym::rustc_intrinsic);
|
|
||||||
if body.is_none() && !is_intrinsic {
|
if body.is_none() && !is_intrinsic {
|
||||||
self.dcx().emit_err(errors::FnWithoutBody {
|
self.dcx().emit_err(errors::FnWithoutBody {
|
||||||
span: item.span,
|
span: item.span,
|
||||||
|
|
|
@ -102,7 +102,7 @@ pub fn eval_condition(
|
||||||
};
|
};
|
||||||
|
|
||||||
match &cfg.kind {
|
match &cfg.kind {
|
||||||
MetaItemKind::List(mis) if cfg.name_or_empty() == sym::version => {
|
MetaItemKind::List(mis) if cfg.has_name(sym::version) => {
|
||||||
try_gate_cfg(sym::version, cfg.span, sess, features);
|
try_gate_cfg(sym::version, cfg.span, sess, features);
|
||||||
let (min_version, span) = match &mis[..] {
|
let (min_version, span) = match &mis[..] {
|
||||||
[MetaItemInner::Lit(MetaItemLit { kind: LitKind::Str(sym, ..), span, .. })] => {
|
[MetaItemInner::Lit(MetaItemLit { kind: LitKind::Str(sym, ..), span, .. })] => {
|
||||||
|
@ -149,18 +149,18 @@ pub fn eval_condition(
|
||||||
|
|
||||||
// The unwraps below may look dangerous, but we've already asserted
|
// The unwraps below may look dangerous, but we've already asserted
|
||||||
// that they won't fail with the loop above.
|
// that they won't fail with the loop above.
|
||||||
match cfg.name_or_empty() {
|
match cfg.name() {
|
||||||
sym::any => mis
|
Some(sym::any) => mis
|
||||||
.iter()
|
.iter()
|
||||||
// We don't use any() here, because we want to evaluate all cfg condition
|
// We don't use any() here, because we want to evaluate all cfg condition
|
||||||
// as eval_condition can (and does) extra checks
|
// as eval_condition can (and does) extra checks
|
||||||
.fold(false, |res, mi| res | eval_condition(mi, sess, features, eval)),
|
.fold(false, |res, mi| res | eval_condition(mi, sess, features, eval)),
|
||||||
sym::all => mis
|
Some(sym::all) => mis
|
||||||
.iter()
|
.iter()
|
||||||
// We don't use all() here, because we want to evaluate all cfg condition
|
// We don't use all() here, because we want to evaluate all cfg condition
|
||||||
// as eval_condition can (and does) extra checks
|
// as eval_condition can (and does) extra checks
|
||||||
.fold(true, |res, mi| res & eval_condition(mi, sess, features, eval)),
|
.fold(true, |res, mi| res & eval_condition(mi, sess, features, eval)),
|
||||||
sym::not => {
|
Some(sym::not) => {
|
||||||
let [mi] = mis.as_slice() else {
|
let [mi] = mis.as_slice() else {
|
||||||
dcx.emit_err(session_diagnostics::ExpectedOneCfgPattern { span: cfg.span });
|
dcx.emit_err(session_diagnostics::ExpectedOneCfgPattern { span: cfg.span });
|
||||||
return false;
|
return false;
|
||||||
|
@ -168,7 +168,7 @@ pub fn eval_condition(
|
||||||
|
|
||||||
!eval_condition(mi, sess, features, eval)
|
!eval_condition(mi, sess, features, eval)
|
||||||
}
|
}
|
||||||
sym::target => {
|
Some(sym::target) => {
|
||||||
if let Some(features) = features
|
if let Some(features) = features
|
||||||
&& !features.cfg_target_compact()
|
&& !features.cfg_target_compact()
|
||||||
{
|
{
|
||||||
|
|
|
@ -222,7 +222,7 @@ impl<'sess> AttributeParser<'sess> {
|
||||||
// if we're only looking for a single attribute,
|
// if we're only looking for a single attribute,
|
||||||
// skip all the ones we don't care about
|
// skip all the ones we don't care about
|
||||||
if let Some(expected) = self.parse_only {
|
if let Some(expected) = self.parse_only {
|
||||||
if attr.name_or_empty() != expected {
|
if !attr.has_name(expected) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ impl<'sess> AttributeParser<'sess> {
|
||||||
// that's expanded right? But no, sometimes, when parsing attributes on macros,
|
// that's expanded right? But no, sometimes, when parsing attributes on macros,
|
||||||
// we already use the lowering logic and these are still there. So, when `omit_doc`
|
// we already use the lowering logic and these are still there. So, when `omit_doc`
|
||||||
// is set we *also* want to ignore these
|
// is set we *also* want to ignore these
|
||||||
if omit_doc == OmitDoc::Skip && attr.name_or_empty() == sym::doc {
|
if omit_doc == OmitDoc::Skip && attr.has_name(sym::doc) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ impl<'sess> AttributeParser<'sess> {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
// // FIXME: make doc attributes go through a proper attribute parser
|
// // FIXME: make doc attributes go through a proper attribute parser
|
||||||
// ast::AttrKind::Normal(n) if n.name_or_empty() == sym::doc => {
|
// ast::AttrKind::Normal(n) if n.has_name(sym::doc) => {
|
||||||
// let p = GenericMetaItemParser::from_attr(&n, self.dcx());
|
// let p = GenericMetaItemParser::from_attr(&n, self.dcx());
|
||||||
//
|
//
|
||||||
// attributes.push(Attribute::Parsed(AttributeKind::DocComment {
|
// attributes.push(Attribute::Parsed(AttributeKind::DocComment {
|
||||||
|
|
|
@ -527,15 +527,14 @@ impl<'a> TraitDef<'a> {
|
||||||
item.attrs
|
item.attrs
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|a| {
|
.filter(|a| {
|
||||||
[
|
a.has_any_name(&[
|
||||||
sym::allow,
|
sym::allow,
|
||||||
sym::warn,
|
sym::warn,
|
||||||
sym::deny,
|
sym::deny,
|
||||||
sym::forbid,
|
sym::forbid,
|
||||||
sym::stable,
|
sym::stable,
|
||||||
sym::unstable,
|
sym::unstable,
|
||||||
]
|
])
|
||||||
.contains(&a.name_or_empty())
|
|
||||||
})
|
})
|
||||||
.cloned(),
|
.cloned(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -346,20 +346,26 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
||||||
no_sanitize_span = Some(attr.span());
|
no_sanitize_span = Some(attr.span());
|
||||||
if let Some(list) = attr.meta_item_list() {
|
if let Some(list) = attr.meta_item_list() {
|
||||||
for item in list.iter() {
|
for item in list.iter() {
|
||||||
match item.name_or_empty() {
|
match item.name() {
|
||||||
sym::address => {
|
Some(sym::address) => {
|
||||||
codegen_fn_attrs.no_sanitize |=
|
codegen_fn_attrs.no_sanitize |=
|
||||||
SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS
|
SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS
|
||||||
}
|
}
|
||||||
sym::cfi => codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI,
|
Some(sym::cfi) => codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI,
|
||||||
sym::kcfi => codegen_fn_attrs.no_sanitize |= SanitizerSet::KCFI,
|
Some(sym::kcfi) => codegen_fn_attrs.no_sanitize |= SanitizerSet::KCFI,
|
||||||
sym::memory => codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY,
|
Some(sym::memory) => {
|
||||||
sym::memtag => codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMTAG,
|
codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY
|
||||||
sym::shadow_call_stack => {
|
}
|
||||||
|
Some(sym::memtag) => {
|
||||||
|
codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMTAG
|
||||||
|
}
|
||||||
|
Some(sym::shadow_call_stack) => {
|
||||||
codegen_fn_attrs.no_sanitize |= SanitizerSet::SHADOWCALLSTACK
|
codegen_fn_attrs.no_sanitize |= SanitizerSet::SHADOWCALLSTACK
|
||||||
}
|
}
|
||||||
sym::thread => codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD,
|
Some(sym::thread) => {
|
||||||
sym::hwaddress => {
|
codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD
|
||||||
|
}
|
||||||
|
Some(sym::hwaddress) => {
|
||||||
codegen_fn_attrs.no_sanitize |= SanitizerSet::HWADDRESS
|
codegen_fn_attrs.no_sanitize |= SanitizerSet::HWADDRESS
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -420,9 +426,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let attrib_to_write = match meta_item.name_or_empty() {
|
let attrib_to_write = match meta_item.name() {
|
||||||
sym::prefix_nops => &mut prefix,
|
Some(sym::prefix_nops) => &mut prefix,
|
||||||
sym::entry_nops => &mut entry,
|
Some(sym::entry_nops) => &mut entry,
|
||||||
_ => {
|
_ => {
|
||||||
tcx.dcx().emit_err(errors::UnexpectedParameterName {
|
tcx.dcx().emit_err(errors::UnexpectedParameterName {
|
||||||
span: item.span(),
|
span: item.span(),
|
||||||
|
@ -786,8 +792,7 @@ impl<'a> MixedExportNameAndNoMangleState<'a> {
|
||||||
fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> {
|
fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> {
|
||||||
let attrs = tcx.get_attrs(id, sym::rustc_autodiff);
|
let attrs = tcx.get_attrs(id, sym::rustc_autodiff);
|
||||||
|
|
||||||
let attrs =
|
let attrs = attrs.filter(|attr| attr.has_name(sym::rustc_autodiff)).collect::<Vec<_>>();
|
||||||
attrs.filter(|attr| attr.name_or_empty() == sym::rustc_autodiff).collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// check for exactly one autodiff attribute on placeholder functions.
|
// check for exactly one autodiff attribute on placeholder functions.
|
||||||
// There should only be one, since we generate a new placeholder per ad macro.
|
// There should only be one, since we generate a new placeholder per ad macro.
|
||||||
|
|
|
@ -824,10 +824,10 @@ impl SyntaxExtension {
|
||||||
return Err(item.span);
|
return Err(item.span);
|
||||||
}
|
}
|
||||||
|
|
||||||
match item.name_or_empty() {
|
match item.name() {
|
||||||
sym::no => Ok(CollapseMacroDebuginfo::No),
|
Some(sym::no) => Ok(CollapseMacroDebuginfo::No),
|
||||||
sym::external => Ok(CollapseMacroDebuginfo::External),
|
Some(sym::external) => Ok(CollapseMacroDebuginfo::External),
|
||||||
sym::yes => Ok(CollapseMacroDebuginfo::Yes),
|
Some(sym::yes) => Ok(CollapseMacroDebuginfo::Yes),
|
||||||
_ => Err(item.path.span),
|
_ => Err(item.path.span),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2053,8 +2053,8 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
) -> Node::OutputTy {
|
) -> Node::OutputTy {
|
||||||
loop {
|
loop {
|
||||||
return match self.take_first_attr(&mut node) {
|
return match self.take_first_attr(&mut node) {
|
||||||
Some((attr, pos, derives)) => match attr.name_or_empty() {
|
Some((attr, pos, derives)) => match attr.name() {
|
||||||
sym::cfg => {
|
Some(sym::cfg) => {
|
||||||
let (res, meta_item) = self.expand_cfg_true(&mut node, attr, pos);
|
let (res, meta_item) = self.expand_cfg_true(&mut node, attr, pos);
|
||||||
if res {
|
if res {
|
||||||
continue;
|
continue;
|
||||||
|
@ -2071,7 +2071,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
}
|
}
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
sym::cfg_attr => {
|
Some(sym::cfg_attr) => {
|
||||||
self.expand_cfg_attr(&mut node, &attr, pos);
|
self.expand_cfg_attr(&mut node, &attr, pos);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2144,8 +2144,8 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
) {
|
) {
|
||||||
loop {
|
loop {
|
||||||
return match self.take_first_attr(node) {
|
return match self.take_first_attr(node) {
|
||||||
Some((attr, pos, derives)) => match attr.name_or_empty() {
|
Some((attr, pos, derives)) => match attr.name() {
|
||||||
sym::cfg => {
|
Some(sym::cfg) => {
|
||||||
let span = attr.span;
|
let span = attr.span;
|
||||||
if self.expand_cfg_true(node, attr, pos).0 {
|
if self.expand_cfg_true(node, attr, pos).0 {
|
||||||
continue;
|
continue;
|
||||||
|
@ -2154,7 +2154,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
node.expand_cfg_false(self, pos, span);
|
node.expand_cfg_false(self, pos, span);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
sym::cfg_attr => {
|
Some(sym::cfg_attr) => {
|
||||||
self.expand_cfg_attr(node, &attr, pos);
|
self.expand_cfg_attr(node, &attr, pos);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1237,7 +1237,7 @@ impl AttributeExt for Attribute {
|
||||||
Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => {
|
Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => {
|
||||||
Some((*comment, *kind))
|
Some((*comment, *kind))
|
||||||
}
|
}
|
||||||
Attribute::Unparsed(_) if self.name_or_empty() == sym::doc => {
|
Attribute::Unparsed(_) if self.has_name(sym::doc) => {
|
||||||
self.value_str().map(|s| (s, CommentKind::Line))
|
self.value_str().map(|s| (s, CommentKind::Line))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -1262,8 +1262,8 @@ impl Attribute {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn name_or_empty(&self) -> Symbol {
|
pub fn name(&self) -> Option<Symbol> {
|
||||||
AttributeExt::name_or_empty(self)
|
AttributeExt::name(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1301,6 +1301,11 @@ impl Attribute {
|
||||||
AttributeExt::has_name(self, name)
|
AttributeExt::has_name(self, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn has_any_name(&self, names: &[Symbol]) -> bool {
|
||||||
|
AttributeExt::has_any_name(self, names)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn span(&self) -> Span {
|
pub fn span(&self) -> Span {
|
||||||
AttributeExt::span(self)
|
AttributeExt::span(self)
|
||||||
|
|
|
@ -488,7 +488,7 @@ fn parse_never_type_options_attr(
|
||||||
item.span(),
|
item.span(),
|
||||||
format!(
|
format!(
|
||||||
"unknown or duplicate never type option: `{}` (supported: `fallback`, `diverging_block_default`)",
|
"unknown or duplicate never type option: `{}` (supported: `fallback`, `diverging_block_default`)",
|
||||||
item.name_or_empty()
|
item.name().unwrap()
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2334,8 +2334,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
let hir_id = self.fcx.tcx.local_def_id_to_hir_id(local_def_id);
|
let hir_id = self.fcx.tcx.local_def_id_to_hir_id(local_def_id);
|
||||||
let attrs = self.fcx.tcx.hir_attrs(hir_id);
|
let attrs = self.fcx.tcx.hir_attrs(hir_id);
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
if sym::doc == attr.name_or_empty() {
|
if attr.has_name(sym::doc) {
|
||||||
} else if sym::rustc_confusables == attr.name_or_empty() {
|
// do nothing
|
||||||
|
} else if attr.has_name(sym::rustc_confusables) {
|
||||||
let Some(confusables) = attr.meta_item_list() else {
|
let Some(confusables) = attr.meta_item_list() else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
@ -2355,7 +2356,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
for v in values {
|
for v in values {
|
||||||
if v.name_or_empty() != sym::alias {
|
if !v.has_name(sym::alias) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some(nested) = v.meta_item_list() {
|
if let Some(nested) = v.meta_item_list() {
|
||||||
|
|
|
@ -93,7 +93,7 @@ incremental_undefined_clean_dirty_assertions =
|
||||||
incremental_undefined_clean_dirty_assertions_item =
|
incremental_undefined_clean_dirty_assertions_item =
|
||||||
clean/dirty auto-assertions not yet defined for Node::Item.node={$kind}
|
clean/dirty auto-assertions not yet defined for Node::Item.node={$kind}
|
||||||
|
|
||||||
incremental_unknown_item = unknown item `{$name}`
|
incremental_unknown_rustc_clean_argument = unknown `rustc_clean` argument
|
||||||
|
|
||||||
incremental_unrecognized_depnode = unrecognized `DepNode` variant: {$name}
|
incremental_unrecognized_depnode = unrecognized `DepNode` variant: {$name}
|
||||||
|
|
||||||
|
|
|
@ -107,11 +107,10 @@ pub(crate) struct NotLoaded<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(incremental_unknown_item)]
|
#[diag(incremental_unknown_rustc_clean_argument)]
|
||||||
pub(crate) struct UnknownItem {
|
pub(crate) struct UnknownRustcCleanArgument {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub name: Symbol,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
|
|
@ -405,8 +405,7 @@ fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool {
|
||||||
debug!("check_config: searching for cfg {:?}", value);
|
debug!("check_config: searching for cfg {:?}", value);
|
||||||
cfg = Some(config.contains(&(value, None)));
|
cfg = Some(config.contains(&(value, None)));
|
||||||
} else if !(item.has_name(EXCEPT) || item.has_name(LOADED_FROM_DISK)) {
|
} else if !(item.has_name(EXCEPT) || item.has_name(LOADED_FROM_DISK)) {
|
||||||
tcx.dcx()
|
tcx.dcx().emit_err(errors::UnknownRustcCleanArgument { span: item.span() });
|
||||||
.emit_err(errors::UnknownItem { span: attr.span(), name: item.name_or_empty() });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ impl Level {
|
||||||
|
|
||||||
/// Converts an `Attribute` to a level.
|
/// Converts an `Attribute` to a level.
|
||||||
pub fn from_attr(attr: &impl AttributeExt) -> Option<(Self, Option<LintExpectationId>)> {
|
pub fn from_attr(attr: &impl AttributeExt) -> Option<(Self, Option<LintExpectationId>)> {
|
||||||
Self::from_symbol(attr.name_or_empty(), || Some(attr.id()))
|
attr.name().and_then(|name| Self::from_symbol(name, || Some(attr.id())))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a `Symbol` to a level.
|
/// Converts a `Symbol` to a level.
|
||||||
|
|
|
@ -226,8 +226,8 @@ impl<'tcx> Collector<'tcx> {
|
||||||
let mut wasm_import_module = None;
|
let mut wasm_import_module = None;
|
||||||
let mut import_name_type = None;
|
let mut import_name_type = None;
|
||||||
for item in items.iter() {
|
for item in items.iter() {
|
||||||
match item.name_or_empty() {
|
match item.name() {
|
||||||
sym::name => {
|
Some(sym::name) => {
|
||||||
if name.is_some() {
|
if name.is_some() {
|
||||||
sess.dcx().emit_err(errors::MultipleNamesInLink { span: item.span() });
|
sess.dcx().emit_err(errors::MultipleNamesInLink { span: item.span() });
|
||||||
continue;
|
continue;
|
||||||
|
@ -242,7 +242,7 @@ impl<'tcx> Collector<'tcx> {
|
||||||
}
|
}
|
||||||
name = Some((link_name, span));
|
name = Some((link_name, span));
|
||||||
}
|
}
|
||||||
sym::kind => {
|
Some(sym::kind) => {
|
||||||
if kind.is_some() {
|
if kind.is_some() {
|
||||||
sess.dcx().emit_err(errors::MultipleKindsInLink { span: item.span() });
|
sess.dcx().emit_err(errors::MultipleKindsInLink { span: item.span() });
|
||||||
continue;
|
continue;
|
||||||
|
@ -304,7 +304,7 @@ impl<'tcx> Collector<'tcx> {
|
||||||
};
|
};
|
||||||
kind = Some(link_kind);
|
kind = Some(link_kind);
|
||||||
}
|
}
|
||||||
sym::modifiers => {
|
Some(sym::modifiers) => {
|
||||||
if modifiers.is_some() {
|
if modifiers.is_some() {
|
||||||
sess.dcx()
|
sess.dcx()
|
||||||
.emit_err(errors::MultipleLinkModifiers { span: item.span() });
|
.emit_err(errors::MultipleLinkModifiers { span: item.span() });
|
||||||
|
@ -316,7 +316,7 @@ impl<'tcx> Collector<'tcx> {
|
||||||
};
|
};
|
||||||
modifiers = Some((link_modifiers, item.name_value_literal_span().unwrap()));
|
modifiers = Some((link_modifiers, item.name_value_literal_span().unwrap()));
|
||||||
}
|
}
|
||||||
sym::cfg => {
|
Some(sym::cfg) => {
|
||||||
if cfg.is_some() {
|
if cfg.is_some() {
|
||||||
sess.dcx().emit_err(errors::MultipleCfgs { span: item.span() });
|
sess.dcx().emit_err(errors::MultipleCfgs { span: item.span() });
|
||||||
continue;
|
continue;
|
||||||
|
@ -346,7 +346,7 @@ impl<'tcx> Collector<'tcx> {
|
||||||
}
|
}
|
||||||
cfg = Some(link_cfg.clone());
|
cfg = Some(link_cfg.clone());
|
||||||
}
|
}
|
||||||
sym::wasm_import_module => {
|
Some(sym::wasm_import_module) => {
|
||||||
if wasm_import_module.is_some() {
|
if wasm_import_module.is_some() {
|
||||||
sess.dcx().emit_err(errors::MultipleWasmImport { span: item.span() });
|
sess.dcx().emit_err(errors::MultipleWasmImport { span: item.span() });
|
||||||
continue;
|
continue;
|
||||||
|
@ -357,7 +357,7 @@ impl<'tcx> Collector<'tcx> {
|
||||||
};
|
};
|
||||||
wasm_import_module = Some((link_wasm_import_module, item.span()));
|
wasm_import_module = Some((link_wasm_import_module, item.span()));
|
||||||
}
|
}
|
||||||
sym::import_name_type => {
|
Some(sym::import_name_type) => {
|
||||||
if import_name_type.is_some() {
|
if import_name_type.is_some() {
|
||||||
sess.dcx()
|
sess.dcx()
|
||||||
.emit_err(errors::MultipleImportNameType { span: item.span() });
|
.emit_err(errors::MultipleImportNameType { span: item.span() });
|
||||||
|
|
|
@ -821,7 +821,9 @@ struct AnalyzeAttrState<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn analyze_attr(attr: &impl AttributeExt, state: &mut AnalyzeAttrState<'_>) -> bool {
|
fn analyze_attr(attr: &impl AttributeExt, state: &mut AnalyzeAttrState<'_>) -> bool {
|
||||||
let mut should_encode = false;
|
let mut should_encode = false;
|
||||||
if !rustc_feature::encode_cross_crate(attr.name_or_empty()) {
|
if let Some(name) = attr.name()
|
||||||
|
&& !rustc_feature::encode_cross_crate(name)
|
||||||
|
{
|
||||||
// Attributes not marked encode-cross-crate don't need to be encoded for downstream crates.
|
// Attributes not marked encode-cross-crate don't need to be encoded for downstream crates.
|
||||||
} else if attr.doc_str().is_some() {
|
} else if attr.doc_str().is_some() {
|
||||||
// We keep all doc comments reachable to rustdoc because they might be "imported" into
|
// We keep all doc comments reachable to rustdoc because they might be "imported" into
|
||||||
|
|
|
@ -103,8 +103,9 @@ fn parse_attribute(attr: &Attribute) -> MirPhase {
|
||||||
let mut dialect: Option<String> = None;
|
let mut dialect: Option<String> = None;
|
||||||
let mut phase: Option<String> = None;
|
let mut phase: Option<String> = None;
|
||||||
|
|
||||||
|
// Not handling errors properly for this internal attribute; will just abort on errors.
|
||||||
for nested in meta_items {
|
for nested in meta_items {
|
||||||
let name = nested.name_or_empty();
|
let name = nested.name().unwrap();
|
||||||
let value = nested.value_str().unwrap().as_str().to_string();
|
let value = nested.value_str().unwrap().as_str().to_string();
|
||||||
match name.as_str() {
|
match name.as_str() {
|
||||||
"dialect" => {
|
"dialect" => {
|
||||||
|
|
|
@ -485,7 +485,7 @@ fn construct_fn<'tcx>(
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(custom_mir_attr) =
|
if let Some(custom_mir_attr) =
|
||||||
tcx.hir_attrs(fn_id).iter().find(|attr| attr.name_or_empty() == sym::custom_mir)
|
tcx.hir_attrs(fn_id).iter().find(|attr| attr.has_name(sym::custom_mir))
|
||||||
{
|
{
|
||||||
return custom::build_custom_mir(
|
return custom::build_custom_mir(
|
||||||
tcx,
|
tcx,
|
||||||
|
|
|
@ -113,7 +113,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
|
||||||
apply_adjustments: tcx
|
apply_adjustments: tcx
|
||||||
.hir_attrs(hir_id)
|
.hir_attrs(hir_id)
|
||||||
.iter()
|
.iter()
|
||||||
.all(|attr| attr.name_or_empty() != rustc_span::sym::custom_mir),
|
.all(|attr| !attr.has_name(rustc_span::sym::custom_mir)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,27 +109,29 @@ impl RustcMirAttrs {
|
||||||
.flat_map(|attr| attr.meta_item_list().into_iter().flat_map(|v| v.into_iter()));
|
.flat_map(|attr| attr.meta_item_list().into_iter().flat_map(|v| v.into_iter()));
|
||||||
|
|
||||||
for attr in rustc_mir_attrs {
|
for attr in rustc_mir_attrs {
|
||||||
let attr_result = if attr.has_name(sym::borrowck_graphviz_postflow) {
|
let attr_result = match attr.name() {
|
||||||
Self::set_field(&mut ret.basename_and_suffix, tcx, &attr, |s| {
|
Some(name @ sym::borrowck_graphviz_postflow) => {
|
||||||
let path = PathBuf::from(s.to_string());
|
Self::set_field(&mut ret.basename_and_suffix, tcx, name, &attr, |s| {
|
||||||
match path.file_name() {
|
let path = PathBuf::from(s.to_string());
|
||||||
Some(_) => Ok(path),
|
match path.file_name() {
|
||||||
None => {
|
Some(_) => Ok(path),
|
||||||
tcx.dcx().emit_err(PathMustEndInFilename { span: attr.span() });
|
None => {
|
||||||
|
tcx.dcx().emit_err(PathMustEndInFilename { span: attr.span() });
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Some(name @ sym::borrowck_graphviz_format) => {
|
||||||
|
Self::set_field(&mut ret.formatter, tcx, name, &attr, |s| match s {
|
||||||
|
sym::two_phase => Ok(s),
|
||||||
|
_ => {
|
||||||
|
tcx.dcx().emit_err(UnknownFormatter { span: attr.span() });
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
}
|
||||||
} else if attr.has_name(sym::borrowck_graphviz_format) {
|
_ => Ok(()),
|
||||||
Self::set_field(&mut ret.formatter, tcx, &attr, |s| match s {
|
|
||||||
sym::two_phase => Ok(s),
|
|
||||||
_ => {
|
|
||||||
tcx.dcx().emit_err(UnknownFormatter { span: attr.span() });
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
};
|
};
|
||||||
|
|
||||||
result = result.and(attr_result);
|
result = result.and(attr_result);
|
||||||
|
@ -141,12 +143,12 @@ impl RustcMirAttrs {
|
||||||
fn set_field<T>(
|
fn set_field<T>(
|
||||||
field: &mut Option<T>,
|
field: &mut Option<T>,
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
|
name: Symbol,
|
||||||
attr: &ast::MetaItemInner,
|
attr: &ast::MetaItemInner,
|
||||||
mapper: impl FnOnce(Symbol) -> Result<T, ()>,
|
mapper: impl FnOnce(Symbol) -> Result<T, ()>,
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
if field.is_some() {
|
if field.is_some() {
|
||||||
tcx.dcx()
|
tcx.dcx().emit_err(DuplicateValuesFor { span: attr.span(), name });
|
||||||
.emit_err(DuplicateValuesFor { span: attr.span(), name: attr.name_or_empty() });
|
|
||||||
|
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
@ -156,7 +158,7 @@ impl RustcMirAttrs {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
tcx.dcx()
|
tcx.dcx()
|
||||||
.emit_err(RequiresAnArgument { span: attr.span(), name: attr.name_or_empty() });
|
.emit_err(RequiresAnArgument { span: attr.span(), name: attr.name().unwrap() });
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -404,7 +404,7 @@ passes_invalid_attr_at_crate_level =
|
||||||
passes_invalid_attr_at_crate_level_item =
|
passes_invalid_attr_at_crate_level_item =
|
||||||
the inner attribute doesn't annotate this {$kind}
|
the inner attribute doesn't annotate this {$kind}
|
||||||
|
|
||||||
passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]` argument
|
passes_invalid_macro_export_arguments = invalid `#[macro_export]` argument
|
||||||
|
|
||||||
passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments
|
passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments
|
||||||
|
|
||||||
|
@ -771,8 +771,8 @@ passes_unreachable_due_to_uninhabited = unreachable {$descr}
|
||||||
.label_orig = any code following this expression is unreachable
|
.label_orig = any code following this expression is unreachable
|
||||||
.note = this expression has type `{$ty}`, which is uninhabited
|
.note = this expression has type `{$ty}`, which is uninhabited
|
||||||
|
|
||||||
passes_unrecognized_field =
|
passes_unrecognized_argument =
|
||||||
unrecognized field name `{$name}`
|
unrecognized argument
|
||||||
|
|
||||||
passes_unstable_attr_for_already_stable_feature =
|
passes_unstable_attr_for_already_stable_feature =
|
||||||
can't mark as unstable using an already stable feature
|
can't mark as unstable using an already stable feature
|
||||||
|
|
|
@ -9,7 +9,7 @@ use rustc_span::sym;
|
||||||
use rustc_target::callconv::FnAbi;
|
use rustc_target::callconv::FnAbi;
|
||||||
|
|
||||||
use super::layout_test::ensure_wf;
|
use super::layout_test::ensure_wf;
|
||||||
use crate::errors::{AbiInvalidAttribute, AbiNe, AbiOf, UnrecognizedField};
|
use crate::errors::{AbiInvalidAttribute, AbiNe, AbiOf, UnrecognizedArgument};
|
||||||
|
|
||||||
pub fn test_abi(tcx: TyCtxt<'_>) {
|
pub fn test_abi(tcx: TyCtxt<'_>) {
|
||||||
if !tcx.features().rustc_attrs() {
|
if !tcx.features().rustc_attrs() {
|
||||||
|
@ -77,8 +77,8 @@ fn dump_abi_of_fn_item(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
|
||||||
// The `..` are the names of fields to dump.
|
// The `..` are the names of fields to dump.
|
||||||
let meta_items = attr.meta_item_list().unwrap_or_default();
|
let meta_items = attr.meta_item_list().unwrap_or_default();
|
||||||
for meta_item in meta_items {
|
for meta_item in meta_items {
|
||||||
match meta_item.name_or_empty() {
|
match meta_item.name() {
|
||||||
sym::debug => {
|
Some(sym::debug) => {
|
||||||
let fn_name = tcx.item_name(item_def_id.into());
|
let fn_name = tcx.item_name(item_def_id.into());
|
||||||
tcx.dcx().emit_err(AbiOf {
|
tcx.dcx().emit_err(AbiOf {
|
||||||
span: tcx.def_span(item_def_id),
|
span: tcx.def_span(item_def_id),
|
||||||
|
@ -88,8 +88,8 @@ fn dump_abi_of_fn_item(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
name => {
|
_ => {
|
||||||
tcx.dcx().emit_err(UnrecognizedField { span: meta_item.span(), name });
|
tcx.dcx().emit_err(UnrecognizedArgument { span: meta_item.span() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,8 +118,8 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
|
||||||
}
|
}
|
||||||
let meta_items = attr.meta_item_list().unwrap_or_default();
|
let meta_items = attr.meta_item_list().unwrap_or_default();
|
||||||
for meta_item in meta_items {
|
for meta_item in meta_items {
|
||||||
match meta_item.name_or_empty() {
|
match meta_item.name() {
|
||||||
sym::debug => {
|
Some(sym::debug) => {
|
||||||
let ty::FnPtr(sig_tys, hdr) = ty.kind() else {
|
let ty::FnPtr(sig_tys, hdr) = ty.kind() else {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
meta_item.span(),
|
meta_item.span(),
|
||||||
|
@ -138,7 +138,7 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
|
||||||
let fn_name = tcx.item_name(item_def_id.into());
|
let fn_name = tcx.item_name(item_def_id.into());
|
||||||
tcx.dcx().emit_err(AbiOf { span, fn_name, fn_abi: format!("{:#?}", abi) });
|
tcx.dcx().emit_err(AbiOf { span, fn_name, fn_abi: format!("{:#?}", abi) });
|
||||||
}
|
}
|
||||||
sym::assert_eq => {
|
Some(sym::assert_eq) => {
|
||||||
let ty::Tuple(fields) = ty.kind() else {
|
let ty::Tuple(fields) = ty.kind() else {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
meta_item.span(),
|
meta_item.span(),
|
||||||
|
@ -188,8 +188,8 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
name => {
|
_ => {
|
||||||
tcx.dcx().emit_err(UnrecognizedField { span: meta_item.span(), name });
|
tcx.dcx().emit_err(UnrecognizedArgument { span: meta_item.span() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -523,9 +523,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
fn check_no_sanitize(&self, attr: &Attribute, span: Span, target: Target) {
|
fn check_no_sanitize(&self, attr: &Attribute, span: Span, target: Target) {
|
||||||
if let Some(list) = attr.meta_item_list() {
|
if let Some(list) = attr.meta_item_list() {
|
||||||
for item in list.iter() {
|
for item in list.iter() {
|
||||||
let sym = item.name_or_empty();
|
let sym = item.name();
|
||||||
match sym {
|
match sym {
|
||||||
sym::address | sym::hwaddress => {
|
Some(s @ sym::address | s @ sym::hwaddress) => {
|
||||||
let is_valid =
|
let is_valid =
|
||||||
matches!(target, Target::Fn | Target::Method(..) | Target::Static);
|
matches!(target, Target::Fn | Target::Method(..) | Target::Static);
|
||||||
if !is_valid {
|
if !is_valid {
|
||||||
|
@ -533,7 +533,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
attr_span: item.span(),
|
attr_span: item.span(),
|
||||||
defn_span: span,
|
defn_span: span,
|
||||||
accepted_kind: "a function or static",
|
accepted_kind: "a function or static",
|
||||||
attr_str: sym.as_str(),
|
attr_str: s.as_str(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -544,7 +544,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
attr_span: item.span(),
|
attr_span: item.span(),
|
||||||
defn_span: span,
|
defn_span: span,
|
||||||
accepted_kind: "a function",
|
accepted_kind: "a function",
|
||||||
attr_str: sym.as_str(),
|
attr_str: &match sym {
|
||||||
|
Some(name) => name.to_string(),
|
||||||
|
None => "...".to_string(),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -561,12 +564,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
allowed_target: Target,
|
allowed_target: Target,
|
||||||
) {
|
) {
|
||||||
if target != allowed_target {
|
if target != allowed_target {
|
||||||
|
let path = attr.path();
|
||||||
|
let path: Vec<_> = path.iter().map(|s| s.as_str()).collect();
|
||||||
|
let attr_name = path.join("::");
|
||||||
self.tcx.emit_node_span_lint(
|
self.tcx.emit_node_span_lint(
|
||||||
UNUSED_ATTRIBUTES,
|
UNUSED_ATTRIBUTES,
|
||||||
hir_id,
|
hir_id,
|
||||||
attr.span(),
|
attr.span(),
|
||||||
errors::OnlyHasEffectOn {
|
errors::OnlyHasEffectOn {
|
||||||
attr_name: attr.name_or_empty(),
|
attr_name,
|
||||||
target_name: allowed_target.name().replace(' ', "_"),
|
target_name: allowed_target.name().replace(' ', "_"),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -589,7 +595,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
// * `#[track_caller]`
|
// * `#[track_caller]`
|
||||||
// * `#[test]`, `#[ignore]`, `#[should_panic]`
|
// * `#[test]`, `#[ignore]`, `#[should_panic]`
|
||||||
//
|
//
|
||||||
// NOTE: when making changes to this list, check that `error_codes/E0736.md` remains accurate
|
// NOTE: when making changes to this list, check that `error_codes/E0736.md` remains
|
||||||
|
// accurate.
|
||||||
const ALLOW_LIST: &[rustc_span::Symbol] = &[
|
const ALLOW_LIST: &[rustc_span::Symbol] = &[
|
||||||
// conditional compilation
|
// conditional compilation
|
||||||
sym::cfg_trace,
|
sym::cfg_trace,
|
||||||
|
@ -672,11 +679,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ALLOW_LIST.iter().any(|name| other_attr.has_name(*name)) {
|
if !other_attr.has_any_name(ALLOW_LIST) {
|
||||||
self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute {
|
self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute {
|
||||||
span: other_attr.span(),
|
span: other_attr.span(),
|
||||||
naked_span: attr.span(),
|
naked_span: attr.span(),
|
||||||
attr: other_attr.name_or_empty(),
|
attr: other_attr.name().unwrap(),
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1150,7 +1157,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
) {
|
) {
|
||||||
match target {
|
match target {
|
||||||
Target::Use | Target::ExternCrate => {
|
Target::Use | Target::ExternCrate => {
|
||||||
let do_inline = meta.name_or_empty() == sym::inline;
|
let do_inline = meta.has_name(sym::inline);
|
||||||
if let Some((prev_inline, prev_span)) = *specified_inline {
|
if let Some((prev_inline, prev_span)) = *specified_inline {
|
||||||
if do_inline != prev_inline {
|
if do_inline != prev_inline {
|
||||||
let mut spans = MultiSpan::from_spans(vec![prev_span, meta.span()]);
|
let mut spans = MultiSpan::from_spans(vec![prev_span, meta.span()]);
|
||||||
|
@ -1260,8 +1267,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
fn check_test_attr(&self, meta: &MetaItemInner, hir_id: HirId) {
|
fn check_test_attr(&self, meta: &MetaItemInner, hir_id: HirId) {
|
||||||
if let Some(metas) = meta.meta_item_list() {
|
if let Some(metas) = meta.meta_item_list() {
|
||||||
for i_meta in metas {
|
for i_meta in metas {
|
||||||
match (i_meta.name_or_empty(), i_meta.meta_item()) {
|
match (i_meta.name(), i_meta.meta_item()) {
|
||||||
(sym::attr | sym::no_crate_inject, _) => {}
|
(Some(sym::attr | sym::no_crate_inject), _) => {}
|
||||||
(_, Some(m)) => {
|
(_, Some(m)) => {
|
||||||
self.tcx.emit_node_span_lint(
|
self.tcx.emit_node_span_lint(
|
||||||
INVALID_DOC_ATTRIBUTES,
|
INVALID_DOC_ATTRIBUTES,
|
||||||
|
@ -1322,61 +1329,63 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
if let Some(list) = attr.meta_item_list() {
|
if let Some(list) = attr.meta_item_list() {
|
||||||
for meta in &list {
|
for meta in &list {
|
||||||
if let Some(i_meta) = meta.meta_item() {
|
if let Some(i_meta) = meta.meta_item() {
|
||||||
match i_meta.name_or_empty() {
|
match i_meta.name() {
|
||||||
sym::alias => {
|
Some(sym::alias) => {
|
||||||
if self.check_attr_not_crate_level(meta, hir_id, "alias") {
|
if self.check_attr_not_crate_level(meta, hir_id, "alias") {
|
||||||
self.check_doc_alias(meta, hir_id, target, aliases);
|
self.check_doc_alias(meta, hir_id, target, aliases);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::keyword => {
|
Some(sym::keyword) => {
|
||||||
if self.check_attr_not_crate_level(meta, hir_id, "keyword") {
|
if self.check_attr_not_crate_level(meta, hir_id, "keyword") {
|
||||||
self.check_doc_keyword(meta, hir_id);
|
self.check_doc_keyword(meta, hir_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::fake_variadic => {
|
Some(sym::fake_variadic) => {
|
||||||
if self.check_attr_not_crate_level(meta, hir_id, "fake_variadic") {
|
if self.check_attr_not_crate_level(meta, hir_id, "fake_variadic") {
|
||||||
self.check_doc_fake_variadic(meta, hir_id);
|
self.check_doc_fake_variadic(meta, hir_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::search_unbox => {
|
Some(sym::search_unbox) => {
|
||||||
if self.check_attr_not_crate_level(meta, hir_id, "fake_variadic") {
|
if self.check_attr_not_crate_level(meta, hir_id, "fake_variadic") {
|
||||||
self.check_doc_search_unbox(meta, hir_id);
|
self.check_doc_search_unbox(meta, hir_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::test => {
|
Some(sym::test) => {
|
||||||
if self.check_attr_crate_level(attr, meta, hir_id) {
|
if self.check_attr_crate_level(attr, meta, hir_id) {
|
||||||
self.check_test_attr(meta, hir_id);
|
self.check_test_attr(meta, hir_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::html_favicon_url
|
Some(
|
||||||
| sym::html_logo_url
|
sym::html_favicon_url
|
||||||
| sym::html_playground_url
|
| sym::html_logo_url
|
||||||
| sym::issue_tracker_base_url
|
| sym::html_playground_url
|
||||||
| sym::html_root_url
|
| sym::issue_tracker_base_url
|
||||||
| sym::html_no_source => {
|
| sym::html_root_url
|
||||||
|
| sym::html_no_source,
|
||||||
|
) => {
|
||||||
self.check_attr_crate_level(attr, meta, hir_id);
|
self.check_attr_crate_level(attr, meta, hir_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::cfg_hide => {
|
Some(sym::cfg_hide) => {
|
||||||
if self.check_attr_crate_level(attr, meta, hir_id) {
|
if self.check_attr_crate_level(attr, meta, hir_id) {
|
||||||
self.check_doc_cfg_hide(meta, hir_id);
|
self.check_doc_cfg_hide(meta, hir_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::inline | sym::no_inline => {
|
Some(sym::inline | sym::no_inline) => {
|
||||||
self.check_doc_inline(attr, meta, hir_id, target, specified_inline)
|
self.check_doc_inline(attr, meta, hir_id, target, specified_inline)
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::masked => self.check_doc_masked(attr, meta, hir_id, target),
|
Some(sym::masked) => self.check_doc_masked(attr, meta, hir_id, target),
|
||||||
|
|
||||||
sym::cfg | sym::hidden | sym::notable_trait => {}
|
Some(sym::cfg | sym::hidden | sym::notable_trait) => {}
|
||||||
|
|
||||||
sym::rust_logo => {
|
Some(sym::rust_logo) => {
|
||||||
if self.check_attr_crate_level(attr, meta, hir_id)
|
if self.check_attr_crate_level(attr, meta, hir_id)
|
||||||
&& !self.tcx.features().rustdoc_internals()
|
&& !self.tcx.features().rustdoc_internals()
|
||||||
{
|
{
|
||||||
|
@ -2299,7 +2308,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_macro_use(&self, hir_id: HirId, attr: &Attribute, target: Target) {
|
fn check_macro_use(&self, hir_id: HirId, attr: &Attribute, target: Target) {
|
||||||
let name = attr.name_or_empty();
|
let name = attr.name().unwrap();
|
||||||
match target {
|
match target {
|
||||||
Target::ExternCrate | Target::Mod => {}
|
Target::ExternCrate | Target::Mod => {}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -2331,12 +2340,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
attr.span(),
|
attr.span(),
|
||||||
errors::MacroExport::TooManyItems,
|
errors::MacroExport::TooManyItems,
|
||||||
);
|
);
|
||||||
} else if meta_item_list[0].name_or_empty() != sym::local_inner_macros {
|
} else if !meta_item_list[0].has_name(sym::local_inner_macros) {
|
||||||
self.tcx.emit_node_span_lint(
|
self.tcx.emit_node_span_lint(
|
||||||
INVALID_MACRO_EXPORT_ARGUMENTS,
|
INVALID_MACRO_EXPORT_ARGUMENTS,
|
||||||
hir_id,
|
hir_id,
|
||||||
meta_item_list[0].span(),
|
meta_item_list[0].span(),
|
||||||
errors::MacroExport::UnknownItem { name: meta_item_list[0].name_or_empty() },
|
errors::MacroExport::InvalidArgument,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2381,33 +2390,28 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warn on useless empty attributes.
|
// Warn on useless empty attributes.
|
||||||
let note = if (matches!(
|
let note = if attr.has_any_name(&[
|
||||||
attr.name_or_empty(),
|
sym::macro_use,
|
||||||
sym::macro_use
|
sym::allow,
|
||||||
| sym::allow
|
sym::expect,
|
||||||
| sym::expect
|
sym::warn,
|
||||||
| sym::warn
|
sym::deny,
|
||||||
| sym::deny
|
sym::forbid,
|
||||||
| sym::forbid
|
sym::feature,
|
||||||
| sym::feature
|
sym::target_feature,
|
||||||
| sym::target_feature
|
]) && attr.meta_item_list().is_some_and(|list| list.is_empty())
|
||||||
) && attr.meta_item_list().is_some_and(|list| list.is_empty()))
|
|
||||||
{
|
{
|
||||||
errors::UnusedNote::EmptyList { name: attr.name_or_empty() }
|
errors::UnusedNote::EmptyList { name: attr.name().unwrap() }
|
||||||
} else if matches!(
|
} else if attr.has_any_name(&[sym::allow, sym::warn, sym::deny, sym::forbid, sym::expect])
|
||||||
attr.name_or_empty(),
|
&& let Some(meta) = attr.meta_item_list()
|
||||||
sym::allow | sym::warn | sym::deny | sym::forbid | sym::expect
|
|
||||||
) && let Some(meta) = attr.meta_item_list()
|
|
||||||
&& let [meta] = meta.as_slice()
|
&& let [meta] = meta.as_slice()
|
||||||
&& let Some(item) = meta.meta_item()
|
&& let Some(item) = meta.meta_item()
|
||||||
&& let MetaItemKind::NameValue(_) = &item.kind
|
&& let MetaItemKind::NameValue(_) = &item.kind
|
||||||
&& item.path == sym::reason
|
&& item.path == sym::reason
|
||||||
{
|
{
|
||||||
errors::UnusedNote::NoLints { name: attr.name_or_empty() }
|
errors::UnusedNote::NoLints { name: attr.name().unwrap() }
|
||||||
} else if matches!(
|
} else if attr.has_any_name(&[sym::allow, sym::warn, sym::deny, sym::forbid, sym::expect])
|
||||||
attr.name_or_empty(),
|
&& let Some(meta) = attr.meta_item_list()
|
||||||
sym::allow | sym::warn | sym::deny | sym::forbid | sym::expect
|
|
||||||
) && let Some(meta) = attr.meta_item_list()
|
|
||||||
&& meta.iter().any(|meta| {
|
&& meta.iter().any(|meta| {
|
||||||
meta.meta_item().map_or(false, |item| item.path == sym::linker_messages)
|
meta.meta_item().map_or(false, |item| item.path == sym::linker_messages)
|
||||||
})
|
})
|
||||||
|
@ -2440,7 +2444,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if attr.name_or_empty() == sym::default_method_body_is_const {
|
} else if attr.has_name(sym::default_method_body_is_const) {
|
||||||
errors::UnusedNote::DefaultMethodBodyConst
|
errors::UnusedNote::DefaultMethodBodyConst
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
@ -2897,10 +2901,11 @@ fn check_duplicates(
|
||||||
if matches!(duplicates, WarnFollowingWordOnly) && !attr.is_word() {
|
if matches!(duplicates, WarnFollowingWordOnly) && !attr.is_word() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let attr_name = attr.name().unwrap();
|
||||||
match duplicates {
|
match duplicates {
|
||||||
DuplicatesOk => {}
|
DuplicatesOk => {}
|
||||||
WarnFollowing | FutureWarnFollowing | WarnFollowingWordOnly | FutureWarnPreceding => {
|
WarnFollowing | FutureWarnFollowing | WarnFollowingWordOnly | FutureWarnPreceding => {
|
||||||
match seen.entry(attr.name_or_empty()) {
|
match seen.entry(attr_name) {
|
||||||
Entry::Occupied(mut entry) => {
|
Entry::Occupied(mut entry) => {
|
||||||
let (this, other) = if matches!(duplicates, FutureWarnPreceding) {
|
let (this, other) = if matches!(duplicates, FutureWarnPreceding) {
|
||||||
let to_remove = entry.insert(attr.span());
|
let to_remove = entry.insert(attr.span());
|
||||||
|
@ -2927,7 +2932,7 @@ fn check_duplicates(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ErrorFollowing | ErrorPreceding => match seen.entry(attr.name_or_empty()) {
|
ErrorFollowing | ErrorPreceding => match seen.entry(attr_name) {
|
||||||
Entry::Occupied(mut entry) => {
|
Entry::Occupied(mut entry) => {
|
||||||
let (this, other) = if matches!(duplicates, ErrorPreceding) {
|
let (this, other) = if matches!(duplicates, ErrorPreceding) {
|
||||||
let to_remove = entry.insert(attr.span());
|
let to_remove = entry.insert(attr.span());
|
||||||
|
@ -2935,11 +2940,7 @@ fn check_duplicates(
|
||||||
} else {
|
} else {
|
||||||
(attr.span(), *entry.get())
|
(attr.span(), *entry.get())
|
||||||
};
|
};
|
||||||
tcx.dcx().emit_err(errors::UnusedMultiple {
|
tcx.dcx().emit_err(errors::UnusedMultiple { this, other, name: attr_name });
|
||||||
this,
|
|
||||||
other,
|
|
||||||
name: attr.name_or_empty(),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
Entry::Vacant(entry) => {
|
Entry::Vacant(entry) => {
|
||||||
entry.insert(attr.span());
|
entry.insert(attr.span());
|
||||||
|
|
|
@ -28,17 +28,17 @@ impl DebuggerVisualizerCollector<'_> {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let (visualizer_type, visualizer_path) =
|
let (visualizer_type, visualizer_path) = match (meta_item.name(), meta_item.value_str())
|
||||||
match (meta_item.name_or_empty(), meta_item.value_str()) {
|
{
|
||||||
(sym::natvis_file, Some(value)) => (DebuggerVisualizerType::Natvis, value),
|
(Some(sym::natvis_file), Some(value)) => (DebuggerVisualizerType::Natvis, value),
|
||||||
(sym::gdb_script_file, Some(value)) => {
|
(Some(sym::gdb_script_file), Some(value)) => {
|
||||||
(DebuggerVisualizerType::GdbPrettyPrinter, value)
|
(DebuggerVisualizerType::GdbPrettyPrinter, value)
|
||||||
}
|
}
|
||||||
(_, _) => {
|
(_, _) => {
|
||||||
self.sess.dcx().emit_err(DebugVisualizerInvalid { span: meta_item.span });
|
self.sess.dcx().emit_err(DebugVisualizerInvalid { span: meta_item.span });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let file = match resolve_path(&self.sess, visualizer_path.as_str(), attr.span) {
|
let file = match resolve_path(&self.sess, visualizer_path.as_str(), attr.span) {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
|
|
|
@ -756,7 +756,7 @@ pub(crate) enum MacroExport {
|
||||||
OnDeclMacro,
|
OnDeclMacro,
|
||||||
|
|
||||||
#[diag(passes_invalid_macro_export_arguments)]
|
#[diag(passes_invalid_macro_export_arguments)]
|
||||||
UnknownItem { name: Symbol },
|
InvalidArgument,
|
||||||
|
|
||||||
#[diag(passes_invalid_macro_export_arguments_too_many_items)]
|
#[diag(passes_invalid_macro_export_arguments_too_many_items)]
|
||||||
TooManyItems,
|
TooManyItems,
|
||||||
|
@ -1045,11 +1045,10 @@ pub(crate) struct AbiInvalidAttribute {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(passes_unrecognized_field)]
|
#[diag(passes_unrecognized_argument)]
|
||||||
pub(crate) struct UnrecognizedField {
|
pub(crate) struct UnrecognizedArgument {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub name: Symbol,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
@ -1433,7 +1432,7 @@ pub(crate) struct UselessAssignment<'a> {
|
||||||
#[derive(LintDiagnostic)]
|
#[derive(LintDiagnostic)]
|
||||||
#[diag(passes_only_has_effect_on)]
|
#[diag(passes_only_has_effect_on)]
|
||||||
pub(crate) struct OnlyHasEffectOn {
|
pub(crate) struct OnlyHasEffectOn {
|
||||||
pub attr_name: Symbol,
|
pub attr_name: String,
|
||||||
pub target_name: String,
|
pub target_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ use rustc_trait_selection::traits;
|
||||||
|
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
LayoutAbi, LayoutAlign, LayoutHomogeneousAggregate, LayoutInvalidAttribute, LayoutOf,
|
LayoutAbi, LayoutAlign, LayoutHomogeneousAggregate, LayoutInvalidAttribute, LayoutOf,
|
||||||
LayoutSize, UnrecognizedField,
|
LayoutSize, UnrecognizedArgument,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn test_layout(tcx: TyCtxt<'_>) {
|
pub fn test_layout(tcx: TyCtxt<'_>) {
|
||||||
|
@ -79,28 +79,28 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
|
||||||
// The `..` are the names of fields to dump.
|
// The `..` are the names of fields to dump.
|
||||||
let meta_items = attr.meta_item_list().unwrap_or_default();
|
let meta_items = attr.meta_item_list().unwrap_or_default();
|
||||||
for meta_item in meta_items {
|
for meta_item in meta_items {
|
||||||
match meta_item.name_or_empty() {
|
match meta_item.name() {
|
||||||
// FIXME: this never was about ABI and now this dump arg is confusing
|
// FIXME: this never was about ABI and now this dump arg is confusing
|
||||||
sym::abi => {
|
Some(sym::abi) => {
|
||||||
tcx.dcx().emit_err(LayoutAbi {
|
tcx.dcx().emit_err(LayoutAbi {
|
||||||
span,
|
span,
|
||||||
abi: format!("{:?}", ty_layout.backend_repr),
|
abi: format!("{:?}", ty_layout.backend_repr),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::align => {
|
Some(sym::align) => {
|
||||||
tcx.dcx().emit_err(LayoutAlign {
|
tcx.dcx().emit_err(LayoutAlign {
|
||||||
span,
|
span,
|
||||||
align: format!("{:?}", ty_layout.align),
|
align: format!("{:?}", ty_layout.align),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::size => {
|
Some(sym::size) => {
|
||||||
tcx.dcx()
|
tcx.dcx()
|
||||||
.emit_err(LayoutSize { span, size: format!("{:?}", ty_layout.size) });
|
.emit_err(LayoutSize { span, size: format!("{:?}", ty_layout.size) });
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::homogeneous_aggregate => {
|
Some(sym::homogeneous_aggregate) => {
|
||||||
tcx.dcx().emit_err(LayoutHomogeneousAggregate {
|
tcx.dcx().emit_err(LayoutHomogeneousAggregate {
|
||||||
span,
|
span,
|
||||||
homogeneous_aggregate: format!(
|
homogeneous_aggregate: format!(
|
||||||
|
@ -111,15 +111,15 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::debug => {
|
Some(sym::debug) => {
|
||||||
let normalized_ty = tcx.normalize_erasing_regions(typing_env, ty);
|
let normalized_ty = tcx.normalize_erasing_regions(typing_env, ty);
|
||||||
// FIXME: using the `Debug` impl here isn't ideal.
|
// FIXME: using the `Debug` impl here isn't ideal.
|
||||||
let ty_layout = format!("{:#?}", *ty_layout);
|
let ty_layout = format!("{:#?}", *ty_layout);
|
||||||
tcx.dcx().emit_err(LayoutOf { span, normalized_ty, ty_layout });
|
tcx.dcx().emit_err(LayoutOf { span, normalized_ty, ty_layout });
|
||||||
}
|
}
|
||||||
|
|
||||||
name => {
|
_ => {
|
||||||
tcx.dcx().emit_err(UnrecognizedField { span: meta_item.span(), name });
|
tcx.dcx().emit_err(UnrecognizedArgument { span: meta_item.span() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1186,6 +1186,7 @@ symbols! {
|
||||||
instruction_set,
|
instruction_set,
|
||||||
integer_: "integer", // underscore to avoid clashing with the function `sym::integer` below
|
integer_: "integer", // underscore to avoid clashing with the function `sym::integer` below
|
||||||
integral,
|
integral,
|
||||||
|
internal_features,
|
||||||
into_async_iter_into_iter,
|
into_async_iter_into_iter,
|
||||||
into_future,
|
into_future,
|
||||||
into_iter,
|
into_iter,
|
||||||
|
|
|
@ -788,7 +788,7 @@ impl Item {
|
||||||
}
|
}
|
||||||
_ => Some(rustc_hir_pretty::attribute_to_string(&tcx, attr)),
|
_ => Some(rustc_hir_pretty::attribute_to_string(&tcx, attr)),
|
||||||
}
|
}
|
||||||
} else if ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) {
|
} else if attr.has_any_name(ALLOWED_ATTRIBUTES) {
|
||||||
Some(
|
Some(
|
||||||
rustc_hir_pretty::attribute_to_string(&tcx, attr)
|
rustc_hir_pretty::attribute_to_string(&tcx, attr)
|
||||||
.replace("\\\n", "")
|
.replace("\\\n", "")
|
||||||
|
|
|
@ -412,9 +412,7 @@ pub(crate) fn run_global_ctxt(
|
||||||
// Process all of the crate attributes, extracting plugin metadata along
|
// Process all of the crate attributes, extracting plugin metadata along
|
||||||
// with the passes which we are supposed to run.
|
// with the passes which we are supposed to run.
|
||||||
for attr in krate.module.attrs.lists(sym::doc) {
|
for attr in krate.module.attrs.lists(sym::doc) {
|
||||||
let name = attr.name_or_empty();
|
if attr.is_word() && attr.has_name(sym::document_private_items) {
|
||||||
|
|
||||||
if attr.is_word() && name == sym::document_private_items {
|
|
||||||
ctxt.render_options.document_private = true;
|
ctxt.render_options.document_private = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -345,7 +345,7 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
|
||||||
fn check_item(item: &ast::Item, info: &mut ParseSourceInfo, crate_name: &Option<&str>) -> bool {
|
fn check_item(item: &ast::Item, info: &mut ParseSourceInfo, crate_name: &Option<&str>) -> bool {
|
||||||
let mut is_extern_crate = false;
|
let mut is_extern_crate = false;
|
||||||
if !info.has_global_allocator
|
if !info.has_global_allocator
|
||||||
&& item.attrs.iter().any(|attr| attr.name_or_empty() == sym::global_allocator)
|
&& item.attrs.iter().any(|attr| attr.has_name(sym::global_allocator))
|
||||||
{
|
{
|
||||||
info.has_global_allocator = true;
|
info.has_global_allocator = true;
|
||||||
}
|
}
|
||||||
|
@ -377,7 +377,7 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut prev_span_hi = 0;
|
let mut prev_span_hi = 0;
|
||||||
let not_crate_attrs = [sym::forbid, sym::allow, sym::warn, sym::deny, sym::expect];
|
let not_crate_attrs = &[sym::forbid, sym::allow, sym::warn, sym::deny, sym::expect];
|
||||||
let parsed = parser.parse_item(rustc_parse::parser::ForceCollect::No);
|
let parsed = parser.parse_item(rustc_parse::parser::ForceCollect::No);
|
||||||
|
|
||||||
let result = match parsed {
|
let result = match parsed {
|
||||||
|
@ -386,17 +386,13 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
|
||||||
&& let Some(ref body) = fn_item.body =>
|
&& let Some(ref body) = fn_item.body =>
|
||||||
{
|
{
|
||||||
for attr in &item.attrs {
|
for attr in &item.attrs {
|
||||||
let attr_name = attr.name_or_empty();
|
if attr.style == AttrStyle::Outer || attr.has_any_name(not_crate_attrs) {
|
||||||
|
|
||||||
if attr.style == AttrStyle::Outer || not_crate_attrs.contains(&attr_name) {
|
|
||||||
// There is one exception to these attributes:
|
// There is one exception to these attributes:
|
||||||
// `#![allow(internal_features)]`. If this attribute is used, we need to
|
// `#![allow(internal_features)]`. If this attribute is used, we need to
|
||||||
// consider it only as a crate-level attribute.
|
// consider it only as a crate-level attribute.
|
||||||
if attr_name == sym::allow
|
if attr.has_name(sym::allow)
|
||||||
&& let Some(list) = attr.meta_item_list()
|
&& let Some(list) = attr.meta_item_list()
|
||||||
&& list.iter().any(|sub_attr| {
|
&& list.iter().any(|sub_attr| sub_attr.has_name(sym::internal_features))
|
||||||
sub_attr.name_or_empty().as_str() == "internal_features"
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
push_to_s(&mut info.crate_attrs, source, attr.span, &mut prev_span_hi);
|
push_to_s(&mut info.crate_attrs, source, attr.span, &mut prev_span_hi);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -521,23 +521,23 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
||||||
// Crawl the crate attributes looking for attributes which control how we're
|
// Crawl the crate attributes looking for attributes which control how we're
|
||||||
// going to emit HTML
|
// going to emit HTML
|
||||||
for attr in krate.module.attrs.lists(sym::doc) {
|
for attr in krate.module.attrs.lists(sym::doc) {
|
||||||
match (attr.name_or_empty(), attr.value_str()) {
|
match (attr.name(), attr.value_str()) {
|
||||||
(sym::html_favicon_url, Some(s)) => {
|
(Some(sym::html_favicon_url), Some(s)) => {
|
||||||
layout.favicon = s.to_string();
|
layout.favicon = s.to_string();
|
||||||
}
|
}
|
||||||
(sym::html_logo_url, Some(s)) => {
|
(Some(sym::html_logo_url), Some(s)) => {
|
||||||
layout.logo = s.to_string();
|
layout.logo = s.to_string();
|
||||||
}
|
}
|
||||||
(sym::html_playground_url, Some(s)) => {
|
(Some(sym::html_playground_url), Some(s)) => {
|
||||||
playground = Some(markdown::Playground {
|
playground = Some(markdown::Playground {
|
||||||
crate_name: Some(krate.name(tcx)),
|
crate_name: Some(krate.name(tcx)),
|
||||||
url: s.to_string(),
|
url: s.to_string(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
(sym::issue_tracker_base_url, Some(s)) => {
|
(Some(sym::issue_tracker_base_url), Some(s)) => {
|
||||||
issue_tracker_base_url = Some(s.to_string());
|
issue_tracker_base_url = Some(s.to_string());
|
||||||
}
|
}
|
||||||
(sym::html_no_source, None) if attr.is_word() => {
|
(Some(sym::html_no_source), None) if attr.is_word() => {
|
||||||
include_sources = false;
|
include_sources = false;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -2363,14 +2363,14 @@ pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool {
|
||||||
cx.tcx
|
cx.tcx
|
||||||
.hir_attrs(hir::CRATE_HIR_ID)
|
.hir_attrs(hir::CRATE_HIR_ID)
|
||||||
.iter()
|
.iter()
|
||||||
.any(|attr| attr.name_or_empty() == sym::no_std)
|
.any(|attr| attr.has_name(sym::no_std))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool {
|
pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool {
|
||||||
cx.tcx
|
cx.tcx
|
||||||
.hir_attrs(hir::CRATE_HIR_ID)
|
.hir_attrs(hir::CRATE_HIR_ID)
|
||||||
.iter()
|
.iter()
|
||||||
.any(|attr| attr.name_or_empty() == sym::no_core)
|
.any(|attr| attr.has_name(sym::no_core))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if parent of a hir node is a trait implementation block.
|
/// Check if parent of a hir node is a trait implementation block.
|
||||||
|
|
|
@ -52,3 +52,6 @@ type TestAbiNeSign = (fn(i32), fn(u32)); //~ ERROR: ABIs are not compatible
|
||||||
|
|
||||||
#[rustc_abi(assert_eq)]
|
#[rustc_abi(assert_eq)]
|
||||||
type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); //~ ERROR: cannot be known at compilation time
|
type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); //~ ERROR: cannot be known at compilation time
|
||||||
|
|
||||||
|
#[rustc_abi("assert_eq")] //~ ERROR unrecognized argument
|
||||||
|
type Bad = u32;
|
||||||
|
|
|
@ -906,6 +906,12 @@ LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str)));
|
||||||
= help: the trait `Sized` is not implemented for `str`
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
= note: only the last element of a tuple may have a dynamically sized type
|
= note: only the last element of a tuple may have a dynamically sized type
|
||||||
|
|
||||||
|
error: unrecognized argument
|
||||||
|
--> $DIR/debug.rs:56:13
|
||||||
|
|
|
||||||
|
LL | #[rustc_abi("assert_eq")]
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions
|
error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions
|
||||||
--> $DIR/debug.rs:29:5
|
--> $DIR/debug.rs:29:5
|
||||||
|
|
|
|
||||||
|
@ -1004,6 +1010,6 @@ error: fn_abi_of(assoc_test) = FnAbi {
|
||||||
LL | fn assoc_test(&self) { }
|
LL | fn assoc_test(&self) { }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 11 previous errors
|
error: aborting due to 12 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -39,13 +39,17 @@
|
||||||
|
|
||||||
// Notably, `should_panic` is a `AttributeType::Normal` attribute that is checked separately.
|
// Notably, `should_panic` is a `AttributeType::Normal` attribute that is checked separately.
|
||||||
|
|
||||||
|
#![deny(unused_attributes)]
|
||||||
|
|
||||||
struct Foo {
|
struct Foo {
|
||||||
#[should_panic::skip]
|
#[should_panic::skip]
|
||||||
//~^ ERROR failed to resolve
|
//~^ ERROR failed to resolve
|
||||||
|
//~| ERROR `#[should_panic::skip]` only has an effect on functions
|
||||||
pub field: u8,
|
pub field: u8,
|
||||||
|
|
||||||
#[should_panic::a::b::c]
|
#[should_panic::a::b::c]
|
||||||
//~^ ERROR failed to resolve
|
//~^ ERROR failed to resolve
|
||||||
|
//~| ERROR `#[should_panic::a::b::c]` only has an effect on functions
|
||||||
pub field2: u8,
|
pub field2: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,39 @@
|
||||||
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `should_panic`
|
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `should_panic`
|
||||||
--> $DIR/check-builtin-attr-ice.rs:43:7
|
--> $DIR/check-builtin-attr-ice.rs:45:7
|
||||||
|
|
|
|
||||||
LL | #[should_panic::skip]
|
LL | #[should_panic::skip]
|
||||||
| ^^^^^^^^^^^^ use of unresolved module or unlinked crate `should_panic`
|
| ^^^^^^^^^^^^ use of unresolved module or unlinked crate `should_panic`
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `should_panic`
|
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `should_panic`
|
||||||
--> $DIR/check-builtin-attr-ice.rs:47:7
|
--> $DIR/check-builtin-attr-ice.rs:50:7
|
||||||
|
|
|
|
||||||
LL | #[should_panic::a::b::c]
|
LL | #[should_panic::a::b::c]
|
||||||
| ^^^^^^^^^^^^ use of unresolved module or unlinked crate `should_panic`
|
| ^^^^^^^^^^^^ use of unresolved module or unlinked crate `should_panic`
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `deny`
|
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `deny`
|
||||||
--> $DIR/check-builtin-attr-ice.rs:55:7
|
--> $DIR/check-builtin-attr-ice.rs:59:7
|
||||||
|
|
|
|
||||||
LL | #[deny::skip]
|
LL | #[deny::skip]
|
||||||
| ^^^^ use of unresolved module or unlinked crate `deny`
|
| ^^^^ use of unresolved module or unlinked crate `deny`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: `#[should_panic::skip]` only has an effect on functions
|
||||||
|
--> $DIR/check-builtin-attr-ice.rs:45:5
|
||||||
|
|
|
||||||
|
LL | #[should_panic::skip]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/check-builtin-attr-ice.rs:42:9
|
||||||
|
|
|
||||||
|
LL | #![deny(unused_attributes)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: `#[should_panic::a::b::c]` only has an effect on functions
|
||||||
|
--> $DIR/check-builtin-attr-ice.rs:50:5
|
||||||
|
|
|
||||||
|
LL | #[should_panic::a::b::c]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0433`.
|
For more information about this error, try `rustc --explain E0433`.
|
||||||
|
|
|
@ -10,11 +10,17 @@ note: the lint level is defined here
|
||||||
LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))]
|
LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `not_local_inner_macros` isn't a valid `#[macro_export]` argument
|
error: invalid `#[macro_export]` argument
|
||||||
--> $DIR/invalid_macro_export_argument.rs:13:16
|
--> $DIR/invalid_macro_export_argument.rs:13:16
|
||||||
|
|
|
|
||||||
LL | #[macro_export(not_local_inner_macros)]
|
LL | #[macro_export(not_local_inner_macros)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: invalid `#[macro_export]` argument
|
||||||
|
--> $DIR/invalid_macro_export_argument.rs:33:16
|
||||||
|
|
|
||||||
|
LL | #[macro_export("blah")]
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ macro_rules! a {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export(not_local_inner_macros)]
|
#[macro_export(not_local_inner_macros)]
|
||||||
//[deny]~^ ERROR `not_local_inner_macros` isn't a valid `#[macro_export]` argument
|
//[deny]~^ ERROR invalid `#[macro_export]` argument
|
||||||
macro_rules! b {
|
macro_rules! b {
|
||||||
() => ()
|
() => ()
|
||||||
}
|
}
|
||||||
|
@ -30,4 +30,10 @@ macro_rules! e {
|
||||||
() => ()
|
() => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export("blah")]
|
||||||
|
//[deny]~^ ERROR invalid `#[macro_export]` argument
|
||||||
|
macro_rules! f {
|
||||||
|
() => ()
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -38,3 +38,8 @@ fn valid() {}
|
||||||
|
|
||||||
#[no_sanitize(address)]
|
#[no_sanitize(address)]
|
||||||
static VALID : i32 = 0;
|
static VALID : i32 = 0;
|
||||||
|
|
||||||
|
#[no_sanitize("address")]
|
||||||
|
//~^ ERROR `#[no_sanitize(...)]` should be applied to a function
|
||||||
|
//~| ERROR invalid argument for `no_sanitize`
|
||||||
|
static VALID2 : i32 = 0;
|
||||||
|
|
|
@ -59,5 +59,22 @@ LL | #[no_sanitize(address, memory)]
|
||||||
LL | static INVALID : i32 = 0;
|
LL | static INVALID : i32 = 0;
|
||||||
| ------------------------- not a function
|
| ------------------------- not a function
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: `#[no_sanitize(...)]` should be applied to a function
|
||||||
|
--> $DIR/no-sanitize.rs:42:15
|
||||||
|
|
|
||||||
|
LL | #[no_sanitize("address")]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | static VALID2 : i32 = 0;
|
||||||
|
| ------------------------ not a function
|
||||||
|
|
||||||
|
error: invalid argument for `no_sanitize`
|
||||||
|
--> $DIR/no-sanitize.rs:42:15
|
||||||
|
|
|
||||||
|
LL | #[no_sanitize("address")]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread`
|
||||||
|
|
||||||
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue