Replace infallible name_or_empty
methods with fallible name
methods.
I'm removing empty identifiers everywhere, because in practice they always mean "no identifier" rather than "empty identifier". (An empty identifier is impossible.) It's better to use `Option` to mean "no identifier" because you then can't forget about the "no identifier" possibility. Some specifics: - When testing an attribute for a single name, the commit uses the `has_name` method. - When testing an attribute for multiple names, the commit uses the new `has_any_name` method. - When using `match` on an attribute, the match arms now have `Some` on them. In the tests, we now avoid printing empty identifiers by not printing the identifier in the `error:` line at all, instead letting the carets point out the problem.
This commit is contained in:
parent
7e1f2f9c54
commit
2fef0a30ae
40 changed files with 217 additions and 203 deletions
|
@ -305,8 +305,8 @@ impl MetaItem {
|
|||
if let [PathSegment { ident, .. }] = self.path.segments[..] { Some(ident) } else { None }
|
||||
}
|
||||
|
||||
pub fn name_or_empty(&self) -> Symbol {
|
||||
self.ident().unwrap_or_else(Ident::empty).name
|
||||
pub fn name(&self) -> Option<Symbol> {
|
||||
self.ident().map(|ident| ident.name)
|
||||
}
|
||||
|
||||
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> {
|
||||
self.meta_item().and_then(|meta_item| meta_item.ident())
|
||||
}
|
||||
|
||||
pub fn name_or_empty(&self) -> Symbol {
|
||||
self.ident().unwrap_or_else(Ident::empty).name
|
||||
/// For a single-segment meta item, returns its name; otherwise, returns `None`.
|
||||
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`.
|
||||
|
@ -738,9 +739,9 @@ pub trait AttributeExt: Debug {
|
|||
fn id(&self) -> AttrId;
|
||||
|
||||
/// For a single-segment attribute (i.e., `#[attr]` and not `#[path::atrr]`),
|
||||
/// return the name of the attribute, else return the empty identifier.
|
||||
fn name_or_empty(&self) -> Symbol {
|
||||
self.ident().unwrap_or_else(Ident::empty).name
|
||||
/// return the name of the attribute; otherwise, returns `None`.
|
||||
fn name(&self) -> Option<Symbol> {
|
||||
self.ident().map(|ident| ident.name)
|
||||
}
|
||||
|
||||
/// 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]`
|
||||
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>;
|
||||
|
||||
/// 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)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn has_any_name(&self, names: &[Symbol]) -> bool {
|
||||
names.iter().any(|&name| self.has_name(name))
|
||||
}
|
||||
|
||||
/// get the span of the entire attribute
|
||||
fn span(&self) -> Span;
|
||||
|
||||
|
@ -813,8 +819,8 @@ impl Attribute {
|
|||
AttributeExt::id(self)
|
||||
}
|
||||
|
||||
pub fn name_or_empty(&self) -> Symbol {
|
||||
AttributeExt::name_or_empty(self)
|
||||
pub fn name(&self) -> Option<Symbol> {
|
||||
AttributeExt::name(self)
|
||||
}
|
||||
|
||||
pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
|
||||
|
@ -846,6 +852,11 @@ impl Attribute {
|
|||
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 {
|
||||
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
|
||||
// this as a special case.
|
||||
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 empty_block = hir::Block {
|
||||
hir_id: this.next_id(),
|
||||
|
|
|
@ -347,7 +347,7 @@ impl<'a> AstValidator<'a> {
|
|||
sym::forbid,
|
||||
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| {
|
||||
if attr.is_doc_comment() {
|
||||
|
@ -945,8 +945,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
self.visit_attrs_vis_ident(&item.attrs, &item.vis, ident);
|
||||
self.check_defaultness(item.span, *defaultness);
|
||||
|
||||
let is_intrinsic =
|
||||
item.attrs.iter().any(|a| a.name_or_empty() == sym::rustc_intrinsic);
|
||||
let is_intrinsic = item.attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic));
|
||||
if body.is_none() && !is_intrinsic {
|
||||
self.dcx().emit_err(errors::FnWithoutBody {
|
||||
span: item.span,
|
||||
|
|
|
@ -117,7 +117,7 @@ pub fn eval_condition(
|
|||
};
|
||||
|
||||
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);
|
||||
let (min_version, span) = match &mis[..] {
|
||||
[MetaItemInner::Lit(MetaItemLit { kind: LitKind::Str(sym, ..), span, .. })] => {
|
||||
|
@ -164,18 +164,18 @@ pub fn eval_condition(
|
|||
|
||||
// The unwraps below may look dangerous, but we've already asserted
|
||||
// that they won't fail with the loop above.
|
||||
match cfg.name_or_empty() {
|
||||
sym::any => mis
|
||||
match cfg.name() {
|
||||
Some(sym::any) => mis
|
||||
.iter()
|
||||
// We don't use any() here, because we want to evaluate all cfg condition
|
||||
// as eval_condition can (and does) extra checks
|
||||
.fold(false, |res, mi| res | eval_condition(mi, sess, features, eval)),
|
||||
sym::all => mis
|
||||
Some(sym::all) => mis
|
||||
.iter()
|
||||
// We don't use all() here, because we want to evaluate all cfg condition
|
||||
// as eval_condition can (and does) extra checks
|
||||
.fold(true, |res, mi| res & eval_condition(mi, sess, features, eval)),
|
||||
sym::not => {
|
||||
Some(sym::not) => {
|
||||
let [mi] = mis.as_slice() else {
|
||||
dcx.emit_err(session_diagnostics::ExpectedOneCfgPattern { span: cfg.span });
|
||||
return false;
|
||||
|
@ -183,7 +183,7 @@ pub fn eval_condition(
|
|||
|
||||
!eval_condition(mi, sess, features, eval)
|
||||
}
|
||||
sym::target => {
|
||||
Some(sym::target) => {
|
||||
if let Some(features) = features
|
||||
&& !features.cfg_target_compact()
|
||||
{
|
||||
|
|
|
@ -222,7 +222,7 @@ impl<'sess> AttributeParser<'sess> {
|
|||
// if we're only looking for a single attribute,
|
||||
// skip all the ones we don't care about
|
||||
if let Some(expected) = self.parse_only {
|
||||
if attr.name_or_empty() != expected {
|
||||
if !attr.has_name(expected) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ impl<'sess> AttributeParser<'sess> {
|
|||
// 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`
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -250,7 +250,7 @@ impl<'sess> AttributeParser<'sess> {
|
|||
}))
|
||||
}
|
||||
// // 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());
|
||||
//
|
||||
// attributes.push(Attribute::Parsed(AttributeKind::DocComment {
|
||||
|
|
|
@ -527,15 +527,14 @@ impl<'a> TraitDef<'a> {
|
|||
item.attrs
|
||||
.iter()
|
||||
.filter(|a| {
|
||||
[
|
||||
a.has_any_name(&[
|
||||
sym::allow,
|
||||
sym::warn,
|
||||
sym::deny,
|
||||
sym::forbid,
|
||||
sym::stable,
|
||||
sym::unstable,
|
||||
]
|
||||
.contains(&a.name_or_empty())
|
||||
])
|
||||
})
|
||||
.cloned(),
|
||||
);
|
||||
|
|
|
@ -345,20 +345,26 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
no_sanitize_span = Some(attr.span());
|
||||
if let Some(list) = attr.meta_item_list() {
|
||||
for item in list.iter() {
|
||||
match item.name_or_empty() {
|
||||
sym::address => {
|
||||
match item.name() {
|
||||
Some(sym::address) => {
|
||||
codegen_fn_attrs.no_sanitize |=
|
||||
SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS
|
||||
}
|
||||
sym::cfi => codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI,
|
||||
sym::kcfi => codegen_fn_attrs.no_sanitize |= SanitizerSet::KCFI,
|
||||
sym::memory => codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY,
|
||||
sym::memtag => codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMTAG,
|
||||
sym::shadow_call_stack => {
|
||||
Some(sym::cfi) => codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI,
|
||||
Some(sym::kcfi) => codegen_fn_attrs.no_sanitize |= SanitizerSet::KCFI,
|
||||
Some(sym::memory) => {
|
||||
codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY
|
||||
}
|
||||
Some(sym::memtag) => {
|
||||
codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMTAG
|
||||
}
|
||||
Some(sym::shadow_call_stack) => {
|
||||
codegen_fn_attrs.no_sanitize |= SanitizerSet::SHADOWCALLSTACK
|
||||
}
|
||||
sym::thread => codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD,
|
||||
sym::hwaddress => {
|
||||
Some(sym::thread) => {
|
||||
codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD
|
||||
}
|
||||
Some(sym::hwaddress) => {
|
||||
codegen_fn_attrs.no_sanitize |= SanitizerSet::HWADDRESS
|
||||
}
|
||||
_ => {
|
||||
|
@ -419,9 +425,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
continue;
|
||||
};
|
||||
|
||||
let attrib_to_write = match meta_item.name_or_empty() {
|
||||
sym::prefix_nops => &mut prefix,
|
||||
sym::entry_nops => &mut entry,
|
||||
let attrib_to_write = match meta_item.name() {
|
||||
Some(sym::prefix_nops) => &mut prefix,
|
||||
Some(sym::entry_nops) => &mut entry,
|
||||
_ => {
|
||||
tcx.dcx().emit_err(errors::UnexpectedParameterName {
|
||||
span: item.span(),
|
||||
|
@ -785,8 +791,7 @@ impl<'a> MixedExportNameAndNoMangleState<'a> {
|
|||
fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> {
|
||||
let attrs = tcx.get_attrs(id, sym::rustc_autodiff);
|
||||
|
||||
let attrs =
|
||||
attrs.filter(|attr| attr.name_or_empty() == sym::rustc_autodiff).collect::<Vec<_>>();
|
||||
let attrs = attrs.filter(|attr| attr.has_name(sym::rustc_autodiff)).collect::<Vec<_>>();
|
||||
|
||||
// check for exactly one autodiff attribute on placeholder functions.
|
||||
// There should only be one, since we generate a new placeholder per ad macro.
|
||||
|
|
|
@ -824,10 +824,10 @@ impl SyntaxExtension {
|
|||
return Err(item.span);
|
||||
}
|
||||
|
||||
match item.name_or_empty() {
|
||||
sym::no => Ok(CollapseMacroDebuginfo::No),
|
||||
sym::external => Ok(CollapseMacroDebuginfo::External),
|
||||
sym::yes => Ok(CollapseMacroDebuginfo::Yes),
|
||||
match item.name() {
|
||||
Some(sym::no) => Ok(CollapseMacroDebuginfo::No),
|
||||
Some(sym::external) => Ok(CollapseMacroDebuginfo::External),
|
||||
Some(sym::yes) => Ok(CollapseMacroDebuginfo::Yes),
|
||||
_ => Err(item.path.span),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2053,8 +2053,8 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||
) -> Node::OutputTy {
|
||||
loop {
|
||||
return match self.take_first_attr(&mut node) {
|
||||
Some((attr, pos, derives)) => match attr.name_or_empty() {
|
||||
sym::cfg => {
|
||||
Some((attr, pos, derives)) => match attr.name() {
|
||||
Some(sym::cfg) => {
|
||||
let (res, meta_item) = self.expand_cfg_true(&mut node, attr, pos);
|
||||
if res {
|
||||
continue;
|
||||
|
@ -2071,7 +2071,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||
}
|
||||
Default::default()
|
||||
}
|
||||
sym::cfg_attr => {
|
||||
Some(sym::cfg_attr) => {
|
||||
self.expand_cfg_attr(&mut node, &attr, pos);
|
||||
continue;
|
||||
}
|
||||
|
@ -2144,8 +2144,8 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||
) {
|
||||
loop {
|
||||
return match self.take_first_attr(node) {
|
||||
Some((attr, pos, derives)) => match attr.name_or_empty() {
|
||||
sym::cfg => {
|
||||
Some((attr, pos, derives)) => match attr.name() {
|
||||
Some(sym::cfg) => {
|
||||
let span = attr.span;
|
||||
if self.expand_cfg_true(node, attr, pos).0 {
|
||||
continue;
|
||||
|
@ -2154,7 +2154,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||
node.expand_cfg_false(self, pos, span);
|
||||
continue;
|
||||
}
|
||||
sym::cfg_attr => {
|
||||
Some(sym::cfg_attr) => {
|
||||
self.expand_cfg_attr(node, &attr, pos);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1237,7 +1237,7 @@ impl AttributeExt for Attribute {
|
|||
Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => {
|
||||
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))
|
||||
}
|
||||
_ => None,
|
||||
|
@ -1262,8 +1262,8 @@ impl Attribute {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn name_or_empty(&self) -> Symbol {
|
||||
AttributeExt::name_or_empty(self)
|
||||
pub fn name(&self) -> Option<Symbol> {
|
||||
AttributeExt::name(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -1301,6 +1301,11 @@ impl Attribute {
|
|||
AttributeExt::has_name(self, name)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn has_any_name(&self, names: &[Symbol]) -> bool {
|
||||
AttributeExt::has_any_name(self, names)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn span(&self) -> Span {
|
||||
AttributeExt::span(self)
|
||||
|
|
|
@ -488,7 +488,7 @@ fn parse_never_type_options_attr(
|
|||
item.span(),
|
||||
format!(
|
||||
"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 attrs = self.fcx.tcx.hir_attrs(hir_id);
|
||||
for attr in attrs {
|
||||
if sym::doc == attr.name_or_empty() {
|
||||
} else if sym::rustc_confusables == attr.name_or_empty() {
|
||||
if attr.has_name(sym::doc) {
|
||||
// do nothing
|
||||
} else if attr.has_name(sym::rustc_confusables) {
|
||||
let Some(confusables) = attr.meta_item_list() else {
|
||||
continue;
|
||||
};
|
||||
|
@ -2355,7 +2356,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
continue;
|
||||
};
|
||||
for v in values {
|
||||
if v.name_or_empty() != sym::alias {
|
||||
if !v.has_name(sym::alias) {
|
||||
continue;
|
||||
}
|
||||
if let Some(nested) = v.meta_item_list() {
|
||||
|
|
|
@ -93,7 +93,7 @@ incremental_undefined_clean_dirty_assertions =
|
|||
incremental_undefined_clean_dirty_assertions_item =
|
||||
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}
|
||||
|
||||
|
|
|
@ -107,11 +107,10 @@ pub(crate) struct NotLoaded<'a> {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_unknown_item)]
|
||||
pub(crate) struct UnknownItem {
|
||||
#[diag(incremental_unknown_rustc_clean_argument)]
|
||||
pub(crate) struct UnknownRustcCleanArgument {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
|
@ -405,8 +405,7 @@ fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool {
|
|||
debug!("check_config: searching for cfg {:?}", value);
|
||||
cfg = Some(config.contains(&(value, None)));
|
||||
} else if !(item.has_name(EXCEPT) || item.has_name(LOADED_FROM_DISK)) {
|
||||
tcx.dcx()
|
||||
.emit_err(errors::UnknownItem { span: attr.span(), name: item.name_or_empty() });
|
||||
tcx.dcx().emit_err(errors::UnknownRustcCleanArgument { span: item.span() });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -249,7 +249,7 @@ impl Level {
|
|||
|
||||
/// Converts an `Attribute` to a level.
|
||||
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.
|
||||
|
|
|
@ -226,8 +226,8 @@ impl<'tcx> Collector<'tcx> {
|
|||
let mut wasm_import_module = None;
|
||||
let mut import_name_type = None;
|
||||
for item in items.iter() {
|
||||
match item.name_or_empty() {
|
||||
sym::name => {
|
||||
match item.name() {
|
||||
Some(sym::name) => {
|
||||
if name.is_some() {
|
||||
sess.dcx().emit_err(errors::MultipleNamesInLink { span: item.span() });
|
||||
continue;
|
||||
|
@ -242,7 +242,7 @@ impl<'tcx> Collector<'tcx> {
|
|||
}
|
||||
name = Some((link_name, span));
|
||||
}
|
||||
sym::kind => {
|
||||
Some(sym::kind) => {
|
||||
if kind.is_some() {
|
||||
sess.dcx().emit_err(errors::MultipleKindsInLink { span: item.span() });
|
||||
continue;
|
||||
|
@ -304,7 +304,7 @@ impl<'tcx> Collector<'tcx> {
|
|||
};
|
||||
kind = Some(link_kind);
|
||||
}
|
||||
sym::modifiers => {
|
||||
Some(sym::modifiers) => {
|
||||
if modifiers.is_some() {
|
||||
sess.dcx()
|
||||
.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()));
|
||||
}
|
||||
sym::cfg => {
|
||||
Some(sym::cfg) => {
|
||||
if cfg.is_some() {
|
||||
sess.dcx().emit_err(errors::MultipleCfgs { span: item.span() });
|
||||
continue;
|
||||
|
@ -346,7 +346,7 @@ impl<'tcx> Collector<'tcx> {
|
|||
}
|
||||
cfg = Some(link_cfg.clone());
|
||||
}
|
||||
sym::wasm_import_module => {
|
||||
Some(sym::wasm_import_module) => {
|
||||
if wasm_import_module.is_some() {
|
||||
sess.dcx().emit_err(errors::MultipleWasmImport { span: item.span() });
|
||||
continue;
|
||||
|
@ -357,7 +357,7 @@ impl<'tcx> Collector<'tcx> {
|
|||
};
|
||||
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() {
|
||||
sess.dcx()
|
||||
.emit_err(errors::MultipleImportNameType { span: item.span() });
|
||||
|
|
|
@ -821,7 +821,9 @@ struct AnalyzeAttrState<'a> {
|
|||
#[inline]
|
||||
fn analyze_attr(attr: &impl AttributeExt, state: &mut AnalyzeAttrState<'_>) -> bool {
|
||||
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.
|
||||
} else if attr.doc_str().is_some() {
|
||||
// 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 phase: Option<String> = None;
|
||||
|
||||
// Not handling errors properly for this internal attribute; will just abort on errors.
|
||||
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();
|
||||
match name.as_str() {
|
||||
"dialect" => {
|
||||
|
|
|
@ -485,7 +485,7 @@ fn construct_fn<'tcx>(
|
|||
};
|
||||
|
||||
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(
|
||||
tcx,
|
||||
|
|
|
@ -113,7 +113,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
|
|||
apply_adjustments: tcx
|
||||
.hir_attrs(hir_id)
|
||||
.iter()
|
||||
.all(|attr| attr.name_or_empty() != rustc_span::sym::custom_mir),
|
||||
.all(|attr| !attr.has_name(rustc_span::sym::custom_mir)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -144,9 +144,10 @@ impl RustcMirAttrs {
|
|||
attr: &ast::MetaItemInner,
|
||||
mapper: impl FnOnce(Symbol) -> Result<T, ()>,
|
||||
) -> Result<(), ()> {
|
||||
// Unwrapping the name is safe because this is only called when `has_name` has succeeded.
|
||||
if field.is_some() {
|
||||
tcx.dcx()
|
||||
.emit_err(DuplicateValuesFor { span: attr.span(), name: attr.name_or_empty() });
|
||||
.emit_err(DuplicateValuesFor { span: attr.span(), name: attr.name().unwrap() });
|
||||
|
||||
return Err(());
|
||||
}
|
||||
|
@ -156,7 +157,7 @@ impl RustcMirAttrs {
|
|||
Ok(())
|
||||
} else {
|
||||
tcx.dcx()
|
||||
.emit_err(RequiresAnArgument { span: attr.span(), name: attr.name_or_empty() });
|
||||
.emit_err(RequiresAnArgument { span: attr.span(), name: attr.name().unwrap() });
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -404,7 +404,7 @@ passes_invalid_attr_at_crate_level =
|
|||
passes_invalid_attr_at_crate_level_item =
|
||||
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
|
||||
|
||||
|
@ -771,8 +771,8 @@ passes_unreachable_due_to_uninhabited = unreachable {$descr}
|
|||
.label_orig = any code following this expression is unreachable
|
||||
.note = this expression has type `{$ty}`, which is uninhabited
|
||||
|
||||
passes_unrecognized_field =
|
||||
unrecognized field name `{$name}`
|
||||
passes_unrecognized_argument =
|
||||
unrecognized argument
|
||||
|
||||
passes_unstable_attr_for_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 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<'_>) {
|
||||
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.
|
||||
let meta_items = attr.meta_item_list().unwrap_or_default();
|
||||
for meta_item in meta_items {
|
||||
match meta_item.name_or_empty() {
|
||||
sym::debug => {
|
||||
match meta_item.name() {
|
||||
Some(sym::debug) => {
|
||||
let fn_name = tcx.item_name(item_def_id.into());
|
||||
tcx.dcx().emit_err(AbiOf {
|
||||
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();
|
||||
for meta_item in meta_items {
|
||||
match meta_item.name_or_empty() {
|
||||
sym::debug => {
|
||||
match meta_item.name() {
|
||||
Some(sym::debug) => {
|
||||
let ty::FnPtr(sig_tys, hdr) = ty.kind() else {
|
||||
span_bug!(
|
||||
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());
|
||||
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 {
|
||||
span_bug!(
|
||||
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) {
|
||||
if let Some(list) = attr.meta_item_list() {
|
||||
for item in list.iter() {
|
||||
let sym = item.name_or_empty();
|
||||
let sym = item.name();
|
||||
match sym {
|
||||
sym::address | sym::hwaddress => {
|
||||
Some(s @ sym::address | s @ sym::hwaddress) => {
|
||||
let is_valid =
|
||||
matches!(target, Target::Fn | Target::Method(..) | Target::Static);
|
||||
if !is_valid {
|
||||
|
@ -533,7 +533,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
attr_span: item.span(),
|
||||
defn_span: span,
|
||||
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(),
|
||||
defn_span: span,
|
||||
accepted_kind: "a function",
|
||||
attr_str: sym.as_str(),
|
||||
attr_str: &match sym {
|
||||
Some(name) => name.to_string(),
|
||||
None => "...".to_string(),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -592,7 +595,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
// * `#[track_caller]`
|
||||
// * `#[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] = &[
|
||||
// conditional compilation
|
||||
sym::cfg_trace,
|
||||
|
@ -675,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 {
|
||||
span: other_attr.span(),
|
||||
naked_span: attr.span(),
|
||||
attr: other_attr.name_or_empty(),
|
||||
attr: other_attr.name().unwrap(),
|
||||
});
|
||||
|
||||
return;
|
||||
|
@ -1153,7 +1157,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
) {
|
||||
match target {
|
||||
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 do_inline != prev_inline {
|
||||
let mut spans = MultiSpan::from_spans(vec![prev_span, meta.span()]);
|
||||
|
@ -1263,8 +1267,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
fn check_test_attr(&self, meta: &MetaItemInner, hir_id: HirId) {
|
||||
if let Some(metas) = meta.meta_item_list() {
|
||||
for i_meta in metas {
|
||||
match (i_meta.name_or_empty(), i_meta.meta_item()) {
|
||||
(sym::attr | sym::no_crate_inject, _) => {}
|
||||
match (i_meta.name(), i_meta.meta_item()) {
|
||||
(Some(sym::attr | sym::no_crate_inject), _) => {}
|
||||
(_, Some(m)) => {
|
||||
self.tcx.emit_node_span_lint(
|
||||
INVALID_DOC_ATTRIBUTES,
|
||||
|
@ -1325,61 +1329,63 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
if let Some(list) = attr.meta_item_list() {
|
||||
for meta in &list {
|
||||
if let Some(i_meta) = meta.meta_item() {
|
||||
match i_meta.name_or_empty() {
|
||||
sym::alias => {
|
||||
match i_meta.name() {
|
||||
Some(sym::alias) => {
|
||||
if self.check_attr_not_crate_level(meta, hir_id, "alias") {
|
||||
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") {
|
||||
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") {
|
||||
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") {
|
||||
self.check_doc_search_unbox(meta, hir_id);
|
||||
}
|
||||
}
|
||||
|
||||
sym::test => {
|
||||
Some(sym::test) => {
|
||||
if self.check_attr_crate_level(attr, meta, hir_id) {
|
||||
self.check_test_attr(meta, hir_id);
|
||||
}
|
||||
}
|
||||
|
||||
sym::html_favicon_url
|
||||
| sym::html_logo_url
|
||||
| sym::html_playground_url
|
||||
| sym::issue_tracker_base_url
|
||||
| sym::html_root_url
|
||||
| sym::html_no_source => {
|
||||
Some(
|
||||
sym::html_favicon_url
|
||||
| sym::html_logo_url
|
||||
| sym::html_playground_url
|
||||
| sym::issue_tracker_base_url
|
||||
| sym::html_root_url
|
||||
| sym::html_no_source,
|
||||
) => {
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
&& !self.tcx.features().rustdoc_internals()
|
||||
{
|
||||
|
@ -2302,7 +2308,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
|
||||
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 {
|
||||
Target::ExternCrate | Target::Mod => {}
|
||||
_ => {
|
||||
|
@ -2334,12 +2340,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
attr.span(),
|
||||
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(
|
||||
INVALID_MACRO_EXPORT_ARGUMENTS,
|
||||
hir_id,
|
||||
meta_item_list[0].span(),
|
||||
errors::MacroExport::UnknownItem { name: meta_item_list[0].name_or_empty() },
|
||||
errors::MacroExport::InvalidArgument,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
@ -2384,33 +2390,28 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
|
||||
// Warn on useless empty attributes.
|
||||
let note = if (matches!(
|
||||
attr.name_or_empty(),
|
||||
sym::macro_use
|
||||
| sym::allow
|
||||
| sym::expect
|
||||
| sym::warn
|
||||
| sym::deny
|
||||
| sym::forbid
|
||||
| sym::feature
|
||||
| sym::target_feature
|
||||
) && attr.meta_item_list().is_some_and(|list| list.is_empty()))
|
||||
let note = if attr.has_any_name(&[
|
||||
sym::macro_use,
|
||||
sym::allow,
|
||||
sym::expect,
|
||||
sym::warn,
|
||||
sym::deny,
|
||||
sym::forbid,
|
||||
sym::feature,
|
||||
sym::target_feature,
|
||||
]) && attr.meta_item_list().is_some_and(|list| list.is_empty())
|
||||
{
|
||||
errors::UnusedNote::EmptyList { name: attr.name_or_empty() }
|
||||
} else if matches!(
|
||||
attr.name_or_empty(),
|
||||
sym::allow | sym::warn | sym::deny | sym::forbid | sym::expect
|
||||
) && let Some(meta) = attr.meta_item_list()
|
||||
errors::UnusedNote::EmptyList { name: attr.name().unwrap() }
|
||||
} else if attr.has_any_name(&[sym::allow, sym::warn, sym::deny, sym::forbid, sym::expect])
|
||||
&& let Some(meta) = attr.meta_item_list()
|
||||
&& let [meta] = meta.as_slice()
|
||||
&& let Some(item) = meta.meta_item()
|
||||
&& let MetaItemKind::NameValue(_) = &item.kind
|
||||
&& item.path == sym::reason
|
||||
{
|
||||
errors::UnusedNote::NoLints { name: attr.name_or_empty() }
|
||||
} else if matches!(
|
||||
attr.name_or_empty(),
|
||||
sym::allow | sym::warn | sym::deny | sym::forbid | sym::expect
|
||||
) && let Some(meta) = attr.meta_item_list()
|
||||
errors::UnusedNote::NoLints { name: attr.name().unwrap() }
|
||||
} else if attr.has_any_name(&[sym::allow, sym::warn, sym::deny, sym::forbid, sym::expect])
|
||||
&& let Some(meta) = attr.meta_item_list()
|
||||
&& meta.iter().any(|meta| {
|
||||
meta.meta_item().map_or(false, |item| item.path == sym::linker_messages)
|
||||
})
|
||||
|
@ -2443,7 +2444,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
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
|
||||
} else {
|
||||
return;
|
||||
|
@ -2900,10 +2901,11 @@ fn check_duplicates(
|
|||
if matches!(duplicates, WarnFollowingWordOnly) && !attr.is_word() {
|
||||
return;
|
||||
}
|
||||
let attr_name = attr.name().unwrap();
|
||||
match duplicates {
|
||||
DuplicatesOk => {}
|
||||
WarnFollowing | FutureWarnFollowing | WarnFollowingWordOnly | FutureWarnPreceding => {
|
||||
match seen.entry(attr.name_or_empty()) {
|
||||
match seen.entry(attr_name) {
|
||||
Entry::Occupied(mut entry) => {
|
||||
let (this, other) = if matches!(duplicates, FutureWarnPreceding) {
|
||||
let to_remove = entry.insert(attr.span());
|
||||
|
@ -2930,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) => {
|
||||
let (this, other) = if matches!(duplicates, ErrorPreceding) {
|
||||
let to_remove = entry.insert(attr.span());
|
||||
|
@ -2938,11 +2940,7 @@ fn check_duplicates(
|
|||
} else {
|
||||
(attr.span(), *entry.get())
|
||||
};
|
||||
tcx.dcx().emit_err(errors::UnusedMultiple {
|
||||
this,
|
||||
other,
|
||||
name: attr.name_or_empty(),
|
||||
});
|
||||
tcx.dcx().emit_err(errors::UnusedMultiple { this, other, name: attr_name });
|
||||
}
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(attr.span());
|
||||
|
|
|
@ -28,17 +28,17 @@ impl DebuggerVisualizerCollector<'_> {
|
|||
return;
|
||||
};
|
||||
|
||||
let (visualizer_type, visualizer_path) =
|
||||
match (meta_item.name_or_empty(), meta_item.value_str()) {
|
||||
(sym::natvis_file, Some(value)) => (DebuggerVisualizerType::Natvis, value),
|
||||
(sym::gdb_script_file, Some(value)) => {
|
||||
(DebuggerVisualizerType::GdbPrettyPrinter, value)
|
||||
}
|
||||
(_, _) => {
|
||||
self.sess.dcx().emit_err(DebugVisualizerInvalid { span: meta_item.span });
|
||||
return;
|
||||
}
|
||||
};
|
||||
let (visualizer_type, visualizer_path) = match (meta_item.name(), meta_item.value_str())
|
||||
{
|
||||
(Some(sym::natvis_file), Some(value)) => (DebuggerVisualizerType::Natvis, value),
|
||||
(Some(sym::gdb_script_file), Some(value)) => {
|
||||
(DebuggerVisualizerType::GdbPrettyPrinter, value)
|
||||
}
|
||||
(_, _) => {
|
||||
self.sess.dcx().emit_err(DebugVisualizerInvalid { span: meta_item.span });
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let file = match resolve_path(&self.sess, visualizer_path.as_str(), attr.span) {
|
||||
Ok(file) => file,
|
||||
|
|
|
@ -756,7 +756,7 @@ pub(crate) enum MacroExport {
|
|||
OnDeclMacro,
|
||||
|
||||
#[diag(passes_invalid_macro_export_arguments)]
|
||||
UnknownItem { name: Symbol },
|
||||
InvalidArgument,
|
||||
|
||||
#[diag(passes_invalid_macro_export_arguments_too_many_items)]
|
||||
TooManyItems,
|
||||
|
@ -1045,11 +1045,10 @@ pub(crate) struct AbiInvalidAttribute {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_unrecognized_field)]
|
||||
pub(crate) struct UnrecognizedField {
|
||||
#[diag(passes_unrecognized_argument)]
|
||||
pub(crate) struct UnrecognizedArgument {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
|
@ -13,7 +13,7 @@ use rustc_trait_selection::traits;
|
|||
|
||||
use crate::errors::{
|
||||
LayoutAbi, LayoutAlign, LayoutHomogeneousAggregate, LayoutInvalidAttribute, LayoutOf,
|
||||
LayoutSize, UnrecognizedField,
|
||||
LayoutSize, UnrecognizedArgument,
|
||||
};
|
||||
|
||||
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.
|
||||
let meta_items = attr.meta_item_list().unwrap_or_default();
|
||||
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
|
||||
sym::abi => {
|
||||
Some(sym::abi) => {
|
||||
tcx.dcx().emit_err(LayoutAbi {
|
||||
span,
|
||||
abi: format!("{:?}", ty_layout.backend_repr),
|
||||
});
|
||||
}
|
||||
|
||||
sym::align => {
|
||||
Some(sym::align) => {
|
||||
tcx.dcx().emit_err(LayoutAlign {
|
||||
span,
|
||||
align: format!("{:?}", ty_layout.align),
|
||||
});
|
||||
}
|
||||
|
||||
sym::size => {
|
||||
Some(sym::size) => {
|
||||
tcx.dcx()
|
||||
.emit_err(LayoutSize { span, size: format!("{:?}", ty_layout.size) });
|
||||
}
|
||||
|
||||
sym::homogeneous_aggregate => {
|
||||
Some(sym::homogeneous_aggregate) => {
|
||||
tcx.dcx().emit_err(LayoutHomogeneousAggregate {
|
||||
span,
|
||||
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);
|
||||
// FIXME: using the `Debug` impl here isn't ideal.
|
||||
let ty_layout = format!("{:#?}", *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() });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1185,6 +1185,7 @@ symbols! {
|
|||
instruction_set,
|
||||
integer_: "integer", // underscore to avoid clashing with the function `sym::integer` below
|
||||
integral,
|
||||
internal_features,
|
||||
into_async_iter_into_iter,
|
||||
into_future,
|
||||
into_iter,
|
||||
|
|
|
@ -788,7 +788,7 @@ impl Item {
|
|||
}
|
||||
_ => 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(
|
||||
rustc_hir_pretty::attribute_to_string(&tcx, attr)
|
||||
.replace("\\\n", "")
|
||||
|
|
|
@ -412,9 +412,7 @@ pub(crate) fn run_global_ctxt(
|
|||
// Process all of the crate attributes, extracting plugin metadata along
|
||||
// with the passes which we are supposed to run.
|
||||
for attr in krate.module.attrs.lists(sym::doc) {
|
||||
let name = attr.name_or_empty();
|
||||
|
||||
if attr.is_word() && name == sym::document_private_items {
|
||||
if attr.is_word() && attr.has_name(sym::document_private_items) {
|
||||
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 {
|
||||
let mut is_extern_crate = false;
|
||||
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;
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ fn parse_source(source: &str, crate_name: &Option<&str>) -> Result<ParseSourceIn
|
|||
}
|
||||
|
||||
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 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 =>
|
||||
{
|
||||
for attr in &item.attrs {
|
||||
let attr_name = attr.name_or_empty();
|
||||
|
||||
if attr.style == AttrStyle::Outer || not_crate_attrs.contains(&attr_name) {
|
||||
if attr.style == AttrStyle::Outer || attr.has_any_name(not_crate_attrs) {
|
||||
// There is one exception to these attributes:
|
||||
// `#![allow(internal_features)]`. If this attribute is used, we need to
|
||||
// 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()
|
||||
&& list.iter().any(|sub_attr| {
|
||||
sub_attr.name_or_empty().as_str() == "internal_features"
|
||||
})
|
||||
&& list.iter().any(|sub_attr| sub_attr.has_name(sym::internal_features))
|
||||
{
|
||||
push_to_s(&mut info.crate_attrs, source, attr.span, &mut prev_span_hi);
|
||||
} else {
|
||||
|
|
|
@ -521,23 +521,23 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
|||
// Crawl the crate attributes looking for attributes which control how we're
|
||||
// going to emit HTML
|
||||
for attr in krate.module.attrs.lists(sym::doc) {
|
||||
match (attr.name_or_empty(), attr.value_str()) {
|
||||
(sym::html_favicon_url, Some(s)) => {
|
||||
match (attr.name(), attr.value_str()) {
|
||||
(Some(sym::html_favicon_url), Some(s)) => {
|
||||
layout.favicon = s.to_string();
|
||||
}
|
||||
(sym::html_logo_url, Some(s)) => {
|
||||
(Some(sym::html_logo_url), Some(s)) => {
|
||||
layout.logo = s.to_string();
|
||||
}
|
||||
(sym::html_playground_url, Some(s)) => {
|
||||
(Some(sym::html_playground_url), Some(s)) => {
|
||||
playground = Some(markdown::Playground {
|
||||
crate_name: Some(krate.name(tcx)),
|
||||
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());
|
||||
}
|
||||
(sym::html_no_source, None) if attr.is_word() => {
|
||||
(Some(sym::html_no_source), None) if attr.is_word() => {
|
||||
include_sources = false;
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
@ -2363,14 +2363,14 @@ pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool {
|
|||
cx.tcx
|
||||
.hir_attrs(hir::CRATE_HIR_ID)
|
||||
.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 {
|
||||
cx.tcx
|
||||
.hir_attrs(hir::CRATE_HIR_ID)
|
||||
.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.
|
||||
|
|
|
@ -53,5 +53,5 @@ type TestAbiNeSign = (fn(i32), fn(u32)); //~ ERROR: ABIs are not compatible
|
|||
#[rustc_abi(assert_eq)]
|
||||
type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); //~ ERROR: cannot be known at compilation time
|
||||
|
||||
#[rustc_abi("assert_eq")] //~ ERROR unrecognized field name ``
|
||||
#[rustc_abi("assert_eq")] //~ ERROR unrecognized argument
|
||||
type Bad = u32;
|
||||
|
|
|
@ -906,7 +906,7 @@ LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str)));
|
|||
= help: the trait `Sized` is not implemented for `str`
|
||||
= note: only the last element of a tuple may have a dynamically sized type
|
||||
|
||||
error: unrecognized field name ``
|
||||
error: unrecognized argument
|
||||
--> $DIR/debug.rs:56:13
|
||||
|
|
||||
LL | #[rustc_abi("assert_eq")]
|
||||
|
|
|
@ -10,13 +10,13 @@ note: the lint level is defined here
|
|||
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
|
||||
|
|
||||
LL | #[macro_export(not_local_inner_macros)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `` isn't a valid `#[macro_export]` argument
|
||||
error: invalid `#[macro_export]` argument
|
||||
--> $DIR/invalid_macro_export_argument.rs:33:16
|
||||
|
|
||||
LL | #[macro_export("blah")]
|
||||
|
|
|
@ -11,7 +11,7 @@ macro_rules! a {
|
|||
}
|
||||
|
||||
#[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 {
|
||||
() => ()
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ macro_rules! e {
|
|||
}
|
||||
|
||||
#[macro_export("blah")]
|
||||
//[deny]~^ ERROR `` isn't a valid `#[macro_export]` argument
|
||||
//[deny]~^ ERROR invalid `#[macro_export]` argument
|
||||
macro_rules! f {
|
||||
() => ()
|
||||
}
|
||||
|
|
|
@ -40,6 +40,6 @@ fn valid() {}
|
|||
static VALID : i32 = 0;
|
||||
|
||||
#[no_sanitize("address")]
|
||||
//~^ ERROR `#[no_sanitize()]` should be applied to a function
|
||||
//~^ ERROR `#[no_sanitize(...)]` should be applied to a function
|
||||
//~| ERROR invalid argument for `no_sanitize`
|
||||
static VALID2 : i32 = 0;
|
||||
|
|
|
@ -59,7 +59,7 @@ LL | #[no_sanitize(address, memory)]
|
|||
LL | static INVALID : i32 = 0;
|
||||
| ------------------------- not a function
|
||||
|
||||
error: `#[no_sanitize()]` should be applied to a function
|
||||
error: `#[no_sanitize(...)]` should be applied to a function
|
||||
--> $DIR/no-sanitize.rs:42:15
|
||||
|
|
||||
LL | #[no_sanitize("address")]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue