diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 86f7e14996488..8602d159ba960 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -166,7 +166,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { // ``` let hints: Vec<_> = item.attrs .iter() - .filter(|attr| attr.name() == "repr") + .filter(|attr| attr.check_name("repr")) .filter_map(|attr| attr.meta_item_list()) .flatten() .collect(); @@ -177,7 +177,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { let mut is_transparent = false; for hint in &hints { - let name = if let Some(name) = hint.name() { + let name = if let Some(name) = hint.ident_str() { name } else { // Invalid repr hint like repr(42). We don't check for unrecognized hints here @@ -185,7 +185,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { continue; }; - let (article, allowed_targets) = match &*name.as_str() { + let (article, allowed_targets) = match name { "C" | "align" => { is_c |= name == "C"; if target != Target::Struct && @@ -233,7 +233,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { _ => continue, }; self.emit_repr_error( - hint.span, + hint.span(), item.span, &format!("attribute should be applied to {}", allowed_targets), &format!("not {} {}", article, allowed_targets), @@ -242,7 +242,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { // Just point at all repr hints if there are any incompatibilities. // This is not ideal, but tracking precisely which ones are at fault is a huge hassle. - let hint_spans = hints.iter().map(|hint| hint.span); + let hint_spans = hints.iter().map(|hint| hint.span()); // Error on repr(transparent, ). if is_transparent && hints.len() > 1 { @@ -313,7 +313,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { fn check_used(&self, item: &hir::Item, target: Target) { for attr in &item.attrs { - if attr.name() == "used" && target != Target::Static { + if attr.check_name("used") && target != Target::Static { self.tcx.sess .span_err(attr.span, "attribute must be applied to a `static` variable"); } diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index f34423ccca655..496ccc888b61a 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -197,7 +197,8 @@ impl<'a> HashStable> for [ast::Attribute] { let filtered: SmallVec<[&ast::Attribute; 8]> = self .iter() .filter(|attr| { - !attr.is_sugared_doc && !hcx.is_ignored_attr(attr.name()) + !attr.is_sugared_doc && + !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name)) }) .collect(); @@ -224,7 +225,7 @@ impl<'a> HashStable> for ast::Attribute { hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { // Make sure that these have been filtered out. - debug_assert!(!hcx.is_ignored_attr(self.name())); + debug_assert!(!self.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))); debug_assert!(!self.is_sugared_doc); let ast::Attribute { @@ -359,15 +360,13 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>( } } -impl_stable_hash_for_spanned!(::syntax::ast::NestedMetaItemKind); - -impl_stable_hash_for!(enum ::syntax::ast::NestedMetaItemKind { +impl_stable_hash_for!(enum ::syntax::ast::NestedMetaItem { MetaItem(meta_item), Literal(lit) }); impl_stable_hash_for!(struct ::syntax::ast::MetaItem { - ident, + path, node, span }); diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index 3c6635c034131..19e899ceb421f 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -194,7 +194,7 @@ impl<'a> LintLevelsBuilder<'a> { struct_span_err!(sess, span, E0452, "malformed lint attribute") }; for attr in attrs { - let level = match Level::from_str(&attr.name().as_str()) { + let level = match attr.ident_str().and_then(|name| Level::from_str(name)) { None => continue, Some(lvl) => lvl, }; @@ -221,7 +221,7 @@ impl<'a> LintLevelsBuilder<'a> { match item.node { ast::MetaItemKind::Word => {} // actual lint names handled later ast::MetaItemKind::NameValue(ref name_value) => { - if item.ident == "reason" { + if item.path == "reason" { // found reason, reslice meta list to exclude it metas = &metas[0..metas.len()-1]; // FIXME (#55112): issue unused-attributes lint if we thereby @@ -255,13 +255,13 @@ impl<'a> LintLevelsBuilder<'a> { } for li in metas { - let word = match li.word() { - Some(word) => word, - None => { - let mut err = bad_attr(li.span); + let meta_item = match li.meta_item() { + Some(meta_item) if meta_item.is_word() => meta_item, + _ => { + let mut err = bad_attr(li.span()); if let Some(item) = li.meta_item() { if let ast::MetaItemKind::NameValue(_) = item.node { - if item.ident == "reason" { + if item.path == "reason" { err.help("reason in lint attribute must come last"); } } @@ -270,26 +270,27 @@ impl<'a> LintLevelsBuilder<'a> { continue; } }; - let tool_name = if let Some(lint_tool) = word.is_scoped() { - if !attr::is_known_lint_tool(lint_tool) { + let tool_name = if meta_item.path.segments.len() > 1 { + let tool_ident = meta_item.path.segments[0].ident; + if !attr::is_known_lint_tool(tool_ident) { span_err!( sess, - lint_tool.span, + tool_ident.span, E0710, "an unknown tool name found in scoped lint: `{}`", - word.ident + meta_item.path ); continue; } - Some(lint_tool.as_str()) + Some(tool_ident.as_str()) } else { None }; - let name = word.name(); + let name = meta_item.path.segments.last().expect("empty lint name").ident.name; match store.check_lint_name(&name.as_str(), tool_name) { CheckLintNameResult::Ok(ids) => { - let src = LintSource::Node(name, li.span, reason); + let src = LintSource::Node(name, li.span(), reason); for id in ids { specs.insert(*id, (level, src)); } @@ -300,7 +301,7 @@ impl<'a> LintLevelsBuilder<'a> { Ok(ids) => { let complete_name = &format!("{}::{}", tool_name.unwrap(), name); let src = LintSource::Node( - Symbol::intern(complete_name), li.span, reason + Symbol::intern(complete_name), li.span(), reason ); for id in ids { specs.insert(*id, (level, src)); @@ -322,18 +323,18 @@ impl<'a> LintLevelsBuilder<'a> { lint, lvl, src, - Some(li.span.into()), + Some(li.span().into()), &msg, ); err.span_suggestion( - li.span, + li.span(), "change it to", new_lint_name.to_string(), Applicability::MachineApplicable, ).emit(); let src = LintSource::Node( - Symbol::intern(&new_lint_name), li.span, reason + Symbol::intern(&new_lint_name), li.span(), reason ); for id in ids { specs.insert(*id, (level, src)); @@ -360,11 +361,11 @@ impl<'a> LintLevelsBuilder<'a> { lint, level, src, - Some(li.span.into()), + Some(li.span().into()), &msg); if let Some(new_name) = renamed { err.span_suggestion( - li.span, + li.span(), "use the new name", new_name, Applicability::MachineApplicable @@ -383,12 +384,12 @@ impl<'a> LintLevelsBuilder<'a> { lint, level, src, - Some(li.span.into()), + Some(li.span().into()), &msg); if let Some(suggestion) = suggestion { db.span_suggestion( - li.span, + li.span(), "did you mean", suggestion.to_string(), Applicability::MachineApplicable, diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index c01b0ae2ccc1d..b1ff66eb64fa6 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -724,7 +724,7 @@ pub fn struct_lint_level<'a>(sess: &'a Session, pub fn maybe_lint_level_root(tcx: TyCtxt<'_, '_, '_>, id: hir::HirId) -> bool { let attrs = tcx.hir().attrs_by_hir_id(id); for attr in attrs { - if Level::from_str(&attr.name().as_str()).is_some() { + if attr.ident_str().and_then(Level::from_str).is_some() { return true; } } diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs index 9d15b0543cb41..237b00db575a9 100644 --- a/src/librustc/middle/lib_features.rs +++ b/src/librustc/middle/lib_features.rs @@ -65,9 +65,9 @@ impl<'a, 'tcx> LibFeatureCollector<'a, 'tcx> { for meta in metas { if let Some(mi) = meta.meta_item() { // Find the `feature = ".."` meta-item. - match (&*mi.name().as_str(), mi.value_str()) { - ("feature", val) => feature = val, - ("since", val) => since = val, + match (mi.ident_str(), mi.value_str()) { + (Some("feature"), val) => feature = val, + (Some("since"), val) => since = val, _ => {} } } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 0a2a375e1b2c1..2664d6eaa2857 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -194,11 +194,12 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> { } else { // Emit errors for non-staged-api crates. for attr in attrs { - let tag = attr.name(); - if tag == "unstable" || tag == "stable" || tag == "rustc_deprecated" { - attr::mark_used(attr); - self.tcx.sess.span_err(attr.span(), "stability attributes may not be used \ - outside of the standard library"); + if let Some(tag) = attr.ident_str() { + if tag == "unstable" || tag == "stable" || tag == "rustc_deprecated" { + attr::mark_used(attr); + self.tcx.sess.span_err(attr.span, "stability attributes may not be used \ + outside of the standard library"); + } } } diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index ff18678f091b9..0ae7c10cf5630 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1839,7 +1839,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec) -> FxHashSet<(String, Option { - if meta_item.ident.segments.len() != 1 { + if meta_item.path.segments.len() != 1 { error!("argument key must be an identifier"); } match &meta_item.node { @@ -1850,7 +1850,8 @@ pub fn parse_cfgspecs(cfgspecs: Vec) -> FxHashSet<(String, Option { - return (meta_item.name(), meta_item.value_str()); + let ident = meta_item.ident().expect("multi-segment cfg key"); + return (ident.name, meta_item.value_str()); } } } diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index fc0058a1df5ff..d0acaf674ae74 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -107,7 +107,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { { if let Some(items) = item.meta_item_list() { if let Ok(subcommand) = - Self::parse(tcx, trait_def_id, &items, item.span, false) + Self::parse(tcx, trait_def_id, &items, item.span(), false) { subcommands.push(subcommand); } else { @@ -118,7 +118,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { } // nothing found - parse_error(tcx, item.span, + parse_error(tcx, item.span(), "this attribute must have a valid value", "expected value here", Some(r#"eg `#[rustc_on_unimplemented(message="foo")]`"#)); @@ -177,10 +177,12 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { for command in self.subcommands.iter().chain(Some(self)).rev() { if let Some(ref condition) = command.condition { if !attr::eval_condition(condition, &tcx.sess.parse_sess, &mut |c| { - options.contains(&( - c.name().as_str().to_string(), - c.value_str().map(|s| s.as_str().to_string()) - )) + c.ident_str().map_or(false, |name| { + options.contains(&( + name.to_string(), + c.value_str().map(|s| s.as_str().to_string()) + )) + }) }) { debug!("evaluate: skipping {:?} due to condition", command); continue diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index c7b6f37fe29db..6d708b8d458ad 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -683,7 +683,7 @@ impl RustcDefaultCalls { let mut cfgs = sess.parse_sess.config.iter().filter_map(|&(name, ref value)| { let gated_cfg = GatedCfg::gate(&ast::MetaItem { - ident: ast::Path::from_ident(ast::Ident::with_empty_ctxt(name)), + path: ast::Path::from_ident(ast::Ident::with_empty_ctxt(name)), node: ast::MetaItemKind::Word, span: DUMMY_SP, }); diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index 9fe9a60b9aaa9..c964f4cb19b8b 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -99,12 +99,12 @@ impl<'a, 'tcx> IfThisChanged<'a, 'tcx> { fn argument(&self, attr: &ast::Attribute) -> Option { let mut value = None; for list_item in attr.meta_item_list().unwrap_or_default() { - match list_item.word() { - Some(word) if value.is_none() => - value = Some(word.name()), + match list_item.ident() { + Some(ident) if list_item.is_word() && value.is_none() => + value = Some(ident.name), _ => // FIXME better-encapsulate meta_item (don't directly access `node`) - span_bug!(list_item.span(), "unexpected meta-item {:?}", list_item.node), + span_bug!(list_item.span(), "unexpected meta-item {:?}", list_item), } } value diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs index 5cbb412052dda..2c83501c86f52 100644 --- a/src/librustc_incremental/assert_module_sources.rs +++ b/src/librustc_incremental/assert_module_sources.rs @@ -153,7 +153,7 @@ impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> { return value; } else { self.tcx.sess.span_fatal( - item.span, + item.span(), &format!("associated value expected for `{}`", name)); } } diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 633e61a0034ab..5551cf6b3b604 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -430,13 +430,13 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> { if DepNode::has_label_string(label) { if out.contains(label) { self.tcx.sess.span_fatal( - item.span, + item.span(), &format!("dep-node label `{}` is repeated", label)); } out.insert(label.to_string()); } else { self.tcx.sess.span_fatal( - item.span, + item.span(), &format!("dep-node label `{}` not recognized", label)); } } @@ -576,13 +576,13 @@ fn expect_associated_value(tcx: TyCtxt<'_, '_, '_>, item: &NestedMetaItem) -> as if let Some(value) = item.value_str() { value } else { - let msg = if let Some(name) = item.name() { + let msg = if let Some(name) = item.ident_str() { format!("associated value expected for `{}`", name) } else { "expected an associated value".to_string() }; - tcx.sess.span_fatal(item.span, &msg); + tcx.sess.span_fatal(item.span(), &msg); } } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 7a7c49e460428..80c5eeeeac345 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -760,7 +760,7 @@ impl LintPass for DeprecatedAttr { impl EarlyLintPass for DeprecatedAttr { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) { for &&(n, _, _, ref g) in &self.depr_attrs { - if attr.name() == n { + if attr.ident_str() == Some(n) { if let &AttributeGate::Gated(Stability::Deprecated(link, suggestion), ref name, ref reason, @@ -831,7 +831,7 @@ impl UnusedDocComment { let span = sugared_span.take().unwrap_or_else(|| attr.span); - if attr.name() == "doc" { + if attr.check_name("doc") { let mut err = cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, "unused doc comment"); err.span_label( diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 7d61547527f76..648cae30da6c8 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -267,19 +267,21 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes { } } - let name = attr.name(); + let name = attr.ident_str(); if !attr::is_used(attr) { debug!("Emitting warning for: {:?}", attr); cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute"); // Is it a builtin attribute that must be used at the crate level? let known_crate = BUILTIN_ATTRIBUTES.iter() - .find(|&&(builtin, ty, ..)| name == builtin && ty == AttributeType::CrateLevel) + .find(|&&(builtin, ty, ..)| { + name == Some(builtin) && ty == AttributeType::CrateLevel + }) .is_some(); // Has a plugin registered this attribute as one that must be used at // the crate level? let plugin_crate = plugin_attributes.iter() - .find(|&&(ref x, t)| name == &**x && AttributeType::CrateLevel == t) + .find(|&&(ref x, t)| name == Some(x) && AttributeType::CrateLevel == t) .is_some(); if known_crate || plugin_crate { let msg = match attr.style { diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index 23898387cba46..80786992cd956 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -76,7 +76,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> { k => { struct_span_err!(self.tcx.sess, m.span, E0458, "unknown kind: `{}`", k) - .span_label(item.span, "unknown kind").emit(); + .span_label(item.span(), "unknown kind").emit(); cstore::NativeUnknown } }; diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index 03f8ac6743617..af2cd8f979a11 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -146,7 +146,7 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitD } else { sess.span_err( item.span, - &format!("{} attribute requires a path", item.ident)); + &format!("{} attribute requires a path", item.path)); return None; } } diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs index 7fe3f5a36d850..373bcf7f0e2f3 100644 --- a/src/librustc_passes/layout_test.rs +++ b/src/librustc_passes/layout_test.rs @@ -53,9 +53,7 @@ impl<'a, 'tcx> VarianceTest<'a, 'tcx> { // The `..` are the names of fields to dump. let meta_items = attr.meta_item_list().unwrap_or_default(); for meta_item in meta_items { - let name = meta_item.word().map(|mi| mi.name().as_str()); - let name = name.as_ref().map(|s| &s[..]).unwrap_or(""); - + let name = meta_item.ident_str().unwrap_or(""); match name { "abi" => { self.tcx @@ -88,7 +86,7 @@ impl<'a, 'tcx> VarianceTest<'a, 'tcx> { _ => { self.tcx.sess.span_err( - meta_item.span, + meta_item.span(), &format!("unrecognized field name `{}`", name), ); } diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs index 1b88cf05f40d5..bd11e0ce8023a 100644 --- a/src/librustc_plugin/load.rs +++ b/src/librustc_plugin/load.rs @@ -56,10 +56,10 @@ pub fn load_plugins(sess: &Session, for plugin in plugins { // plugins must have a name and can't be key = value - match plugin.name() { + match plugin.ident_str() { Some(name) if !plugin.is_value_str() => { let args = plugin.meta_item_list().map(ToOwned::to_owned); - loader.load_plugin(plugin.span, &name.as_str(), args.unwrap_or_default()); + loader.load_plugin(plugin.span(), name, args.unwrap_or_default()); }, _ => call_malformed_plugin_attribute(sess, attr.span), } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 5c9927011a707..12b87b9c9aa18 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -463,10 +463,9 @@ impl<'a> Resolver<'a> { if let Some(attr) = attr::find_by_name(&item.attrs, "proc_macro_derive") { if let Some(trait_attr) = attr.meta_item_list().and_then(|list| list.get(0).cloned()) { - if let Some(ident) = trait_attr.name().map(Ident::with_empty_ctxt) { - let sp = trait_attr.span; + if let Some(ident) = trait_attr.ident() { let def = Def::Macro(def.def_id(), MacroKind::ProcMacroStub); - self.define(parent, ident, MacroNS, (def, vis, sp, expansion)); + self.define(parent, ident, MacroNS, (def, vis, ident.span, expansion)); } } } @@ -812,14 +811,14 @@ impl<'a> Resolver<'a> { break; } MetaItemKind::List(nested_metas) => for nested_meta in nested_metas { - match nested_meta.word() { - Some(word) => single_imports.push((word.name(), word.span)), - None => ill_formed(nested_meta.span), + match nested_meta.ident() { + Some(ident) if nested_meta.is_word() => single_imports.push(ident), + _ => ill_formed(nested_meta.span()), } } MetaItemKind::NameValue(..) => ill_formed(meta.span), } - None => ill_formed(attr.span()), + None => ill_formed(attr.span), } } } @@ -850,23 +849,23 @@ impl<'a> Resolver<'a> { self.legacy_import_macro(ident.name, imported_binding, span, allow_shadowing); }); } else { - for (name, span) in single_imports.iter().cloned() { - let ident = Ident::with_empty_ctxt(name); + for ident in single_imports.iter().cloned() { let result = self.resolve_ident_in_module( ModuleOrUniformRoot::Module(module), ident, MacroNS, None, false, - span, + ident.span, ); if let Ok(binding) = result { - let directive = macro_use_directive(span); + let directive = macro_use_directive(ident.span); self.potentially_unused_imports.push(directive); let imported_binding = self.import(binding, directive); - self.legacy_import_macro(name, imported_binding, span, allow_shadowing); + self.legacy_import_macro(ident.name, imported_binding, + ident.span, allow_shadowing); } else { - span_err!(self.session, span, E0469, "imported macro not found"); + span_err!(self.session, ident.span, E0469, "imported macro not found"); } } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index afe658767f327..10e9613bf21a2 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2326,7 +2326,7 @@ fn from_target_feature( if !item.check_name("enable") { let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \ currently"; - tcx.sess.span_err(item.span, &msg); + tcx.sess.span_err(item.span(), &msg); continue; } @@ -2336,7 +2336,7 @@ fn from_target_feature( None => { let msg = "#[target_feature] attribute must be of the form \ #[target_feature(enable = \"..\")]"; - tcx.sess.span_err(item.span, &msg); + tcx.sess.span_err(item.span(), &msg); continue; } }; @@ -2352,7 +2352,7 @@ fn from_target_feature( this target", feature ); - let mut err = tcx.sess.struct_span_err(item.span, &msg); + let mut err = tcx.sess.struct_span_err(item.span(), &msg); if feature.starts_with("+") { let valid = whitelist.contains_key(&feature[1..]); @@ -2387,7 +2387,7 @@ fn from_target_feature( feature_gate::emit_feature_err( &tcx.sess.parse_sess, feature_gate.as_ref().unwrap(), - item.span, + item.span(), feature_gate::GateIssue::Language, &format!("the target feature `{}` is currently unstable", feature), ); @@ -2549,7 +2549,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen } else { span_err!( tcx.sess.diagnostic(), - items[0].span, + items[0].span(), E0535, "invalid argument" ); @@ -2583,7 +2583,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen } else if list_contains_name(&items[..], "speed") { OptimizeAttr::Speed } else { - err(items[0].span, "invalid argument"); + err(items[0].span(), "invalid argument"); OptimizeAttr::None } } diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 45e1ea2d3a39d..69445451503cc 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -8,7 +8,7 @@ use std::fmt::{self, Write}; use std::ops; use syntax::symbol::Symbol; -use syntax::ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind, LitKind}; +use syntax::ast::{MetaItem, MetaItemKind, NestedMetaItem, LitKind}; use syntax::parse::ParseSess; use syntax::feature_gate::Features; @@ -41,9 +41,9 @@ pub struct InvalidCfgError { impl Cfg { /// Parses a `NestedMetaItem` into a `Cfg`. fn parse_nested(nested_cfg: &NestedMetaItem) -> Result { - match nested_cfg.node { - NestedMetaItemKind::MetaItem(ref cfg) => Cfg::parse(cfg), - NestedMetaItemKind::Literal(ref lit) => Err(InvalidCfgError { + match nested_cfg { + NestedMetaItem::MetaItem(ref cfg) => Cfg::parse(cfg), + NestedMetaItem::Literal(ref lit) => Err(InvalidCfgError { msg: "unexpected literal", span: lit.span, }), @@ -58,7 +58,13 @@ impl Cfg { /// If the content is not properly formatted, it will return an error indicating what and where /// the error is. pub fn parse(cfg: &MetaItem) -> Result { - let name = cfg.name(); + let name = match cfg.ident() { + Some(ident) => ident.name, + None => return Err(InvalidCfgError { + msg: "expected a single identifier", + span: cfg.span + }), + }; match cfg.node { MetaItemKind::Word => Ok(Cfg::Cfg(name, None)), MetaItemKind::NameValue(ref lit) => match lit.node { @@ -424,7 +430,7 @@ mod test { fn dummy_meta_item_word(name: &str) -> MetaItem { MetaItem { - ident: Path::from_ident(Ident::from_str(name)), + path: Path::from_ident(Ident::from_str(name)), node: MetaItemKind::Word, span: DUMMY_SP, } @@ -433,12 +439,12 @@ mod test { macro_rules! dummy_meta_item_list { ($name:ident, [$($list:ident),* $(,)?]) => { MetaItem { - ident: Path::from_ident(Ident::from_str(stringify!($name))), + path: Path::from_ident(Ident::from_str(stringify!($name))), node: MetaItemKind::List(vec![ $( - dummy_spanned(NestedMetaItemKind::MetaItem( + NestedMetaItem::MetaItem( dummy_meta_item_word(stringify!($list)), - )), + ), )* ]), span: DUMMY_SP, @@ -447,10 +453,10 @@ mod test { ($name:ident, [$($list:expr),* $(,)?]) => { MetaItem { - ident: Path::from_ident(Ident::from_str(stringify!($name))), + path: Path::from_ident(Ident::from_str(stringify!($name))), node: MetaItemKind::List(vec![ $( - dummy_spanned(NestedMetaItemKind::MetaItem($list)), + NestedMetaItem::MetaItem($list), )* ]), span: DUMMY_SP, @@ -587,7 +593,7 @@ mod test { assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all"))); let mi = MetaItem { - ident: Path::from_ident(Ident::from_str("all")), + path: Path::from_ident(Ident::from_str("all")), node: MetaItemKind::NameValue(dummy_spanned(LitKind::Str( Symbol::intern("done"), StrStyle::Cooked, @@ -622,7 +628,7 @@ mod test { fn test_parse_err() { with_globals(|| { let mi = MetaItem { - ident: Path::from_ident(Ident::from_str("foo")), + path: Path::from_ident(Ident::from_str("foo")), node: MetaItemKind::NameValue(dummy_spanned(LitKind::Bool(false))), span: DUMMY_SP, }; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c80fd8fcd812f..3aea661f6bec5 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -492,7 +492,7 @@ impl Item { pub fn is_non_exhaustive(&self) -> bool { self.attrs.other_attrs.iter() - .any(|a| a.name().as_str() == "non_exhaustive") + .any(|a| a.check_name("non_exhaustive")) } /// Returns a documentation-level item type from the item. @@ -777,15 +777,15 @@ pub struct Attributes { impl Attributes { /// Extracts the content from an attribute `#[doc(cfg(content))]`. fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> { - use syntax::ast::NestedMetaItemKind::MetaItem; + use syntax::ast::NestedMetaItem::MetaItem; if let ast::MetaItemKind::List(ref nmis) = mi.node { if nmis.len() == 1 { - if let MetaItem(ref cfg_mi) = nmis[0].node { + if let MetaItem(ref cfg_mi) = nmis[0] { if cfg_mi.check_name("cfg") { if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.node { if cfg_nmis.len() == 1 { - if let MetaItem(ref content_mi) = cfg_nmis[0].node { + if let MetaItem(ref content_mi) = cfg_nmis[0] { return Some(content_mi); } } @@ -3683,7 +3683,7 @@ impl Clean> for doctree::ExternCrate { fn clean(&self, cx: &DocContext<'_>) -> Vec { let please_inline = self.vis.node.is_pub() && self.attrs.iter().any(|a| { - a.name() == "doc" && match a.meta_item_list() { + a.check_name("doc") && match a.meta_item_list() { Some(l) => attr::list_contains_name(&l, "inline"), None => false, } @@ -3722,7 +3722,7 @@ impl Clean> for doctree::Import { // #[doc(no_inline)] attribute is present. // Don't inline doc(hidden) imports so they can be stripped at a later stage. let mut denied = !self.vis.node.is_pub() || self.attrs.iter().any(|a| { - a.name() == "doc" && match a.meta_item_list() { + a.check_name("doc") && match a.meta_item_list() { Some(l) => attr::list_contains_name(&l, "no_inline") || attr::list_contains_name(&l, "hidden"), None => false, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 47dbbc20980ba..dca6458c701c5 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -521,8 +521,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt for attr in krate.module.as_ref().unwrap().attrs.lists("doc") { let diag = ctxt.sess().diagnostic(); - let name = attr.name().map(|s| s.as_str()); - let name = name.as_ref().map(|s| &s[..]); + let name = attr.ident_str(); if attr.is_word() { if name == Some("no_default_passes") { report_deprecated_attr("no_default_passes", diag); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 5109e775ebf81..b3a816d17f56c 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -562,8 +562,7 @@ pub fn run(mut krate: clean::Crate, // going to emit HTML if let Some(attrs) = krate.module.as_ref().map(|m| &m.attrs) { for attr in attrs.lists("doc") { - let name = attr.name().map(|s| s.as_str()); - match (name.as_ref().map(|s| &s[..]), attr.value_str()) { + match (attr.ident_str(), attr.value_str()) { (Some("html_favicon_url"), Some(s)) => { scx.layout.favicon = s.to_string(); } @@ -3714,19 +3713,19 @@ fn item_enum(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item, } fn render_attribute(attr: &ast::MetaItem) -> Option { - let name = attr.name(); + let path = attr.path.to_string(); if attr.is_word() { - Some(name.to_string()) + Some(path) } else if let Some(v) = attr.value_str() { - Some(format!("{} = {:?}", name, v.as_str())) + Some(format!("{} = {:?}", path, v.as_str())) } else if let Some(values) = attr.meta_item_list() { let display: Vec<_> = values.iter().filter_map(|attr| { attr.meta_item().and_then(|mi| render_attribute(mi)) }).collect(); if display.len() > 0 { - Some(format!("{}({})", name, display.join(", "))) + Some(format!("{}({})", path, display.join(", "))) } else { None } @@ -3750,8 +3749,7 @@ fn render_attributes(w: &mut fmt::Formatter<'_>, it: &clean::Item) -> fmt::Resul let mut attrs = String::new(); for attr in &it.attrs.other_attrs { - let name = attr.name(); - if !ATTRIBUTE_WHITELIST.contains(&&*name.as_str()) { + if !attr.ident_str().map_or(false, |name| ATTRIBUTE_WHITELIST.contains(&name)) { continue; } if let Some(s) = render_attribute(&attr.meta().unwrap()) { diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 0c99f6ddeddf1..b4db121fb530a 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -178,9 +178,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { Some(kind) => { let name = if kind == MacroKind::Derive { item.attrs.lists("proc_macro_derive") - .filter_map(|mi| mi.name()) + .filter_map(|mi| mi.ident()) .next() .expect("proc-macro derives require a name") + .name } else { name }; @@ -193,8 +194,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { if let Some(list) = mi.meta_item_list() { for inner_mi in list { - if let Some(name) = inner_mi.name() { - helpers.push(name); + if let Some(ident) = inner_mi.ident() { + helpers.push(ident.name); } } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a01a5bb0a3638..1a0da73880cfc 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -443,14 +443,11 @@ pub struct Crate { pub span: Span, } -/// A spanned compile-time attribute list item. -pub type NestedMetaItem = Spanned; - /// Possible values inside of compile-time attribute lists. /// /// E.g., the '..' in `#[name(..)]`. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] -pub enum NestedMetaItemKind { +pub enum NestedMetaItem { /// A full MetaItem, for recursive meta items. MetaItem(MetaItem), /// A literal. @@ -464,7 +461,7 @@ pub enum NestedMetaItemKind { /// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct MetaItem { - pub ident: Path, + pub path: Path, pub node: MetaItemKind, pub span: Span, } @@ -2207,7 +2204,7 @@ pub struct Item { impl Item { /// Return the span that encompasses the attributes. pub fn span_with_attributes(&self) -> Span { - self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span())) + self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span)) } } diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index f7a000935caf0..cdfb83c6e56c8 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -1,6 +1,6 @@ //! Parsing and validation of builtin attributes -use crate::ast::{self, Attribute, MetaItem, Name, NestedMetaItemKind}; +use crate::ast::{self, Attribute, MetaItem, NestedMetaItem}; use crate::feature_gate::{Features, GatedCfg}; use crate::parse::ParseSess; @@ -10,8 +10,8 @@ use syntax_pos::{symbol::Symbol, Span}; use super::{mark_used, MetaItemKind}; enum AttrError { - MultipleItem(Name), - UnknownMetaItem(Name, &'static [&'static str]), + MultipleItem(String), + UnknownMetaItem(String, &'static [&'static str]), MissingSince, MissingFeature, MultipleStabilityLevels, @@ -155,10 +155,7 @@ pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> bool { attrs.iter().any(|item| { item.check_name("feature") && item.meta_item_list().map(|list| { - list.iter().any(|mi| { - mi.word().map(|w| w.name() == feature_name) - .unwrap_or(false) - }) + list.iter().any(|mi| mi.is_word() && mi.check_name(feature_name)) }).unwrap_or(false) }) } @@ -206,7 +203,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, let meta = meta.as_ref().unwrap(); let get = |meta: &MetaItem, item: &mut Option| { if item.is_some() { - handle_errors(sess, meta.span, AttrError::MultipleItem(meta.name())); + handle_errors(sess, meta.span, AttrError::MultipleItem(meta.path.to_string())); return false } if let Some(v) = meta.value_str() { @@ -225,9 +222,9 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, )+ for meta in metas { if let Some(mi) = meta.meta_item() { - match &*mi.name().as_str() { + match mi.ident_str() { $( - stringify!($name) + Some(stringify!($name)) => if !get(mi, &mut $name) { continue 'outer }, )+ _ => { @@ -235,7 +232,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, handle_errors( sess, mi.span, - AttrError::UnknownMetaItem(mi.name(), expected), + AttrError::UnknownMetaItem(mi.path.to_string(), expected), ); continue 'outer } @@ -243,7 +240,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, } else { handle_errors( sess, - meta.span, + meta.span(), AttrError::UnsupportedLiteral( "unsupported literal", false, @@ -255,7 +252,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, } } - match &*meta.name().as_str() { + match meta.ident_str().expect("not a stability level") { "rustc_deprecated" => { if rustc_depr.is_some() { span_err!(diagnostic, item_sp, E0540, @@ -274,11 +271,11 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, }) } (None, _) => { - handle_errors(sess, attr.span(), AttrError::MissingSince); + handle_errors(sess, attr.span, AttrError::MissingSince); continue } _ => { - span_err!(diagnostic, attr.span(), E0543, "missing 'reason'"); + span_err!(diagnostic, attr.span, E0543, "missing 'reason'"); continue } } @@ -294,13 +291,13 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, if let Some(feature) = feature { rustc_const_unstable = Some(feature); } else { - span_err!(diagnostic, attr.span(), E0629, "missing 'feature'"); + span_err!(diagnostic, attr.span, E0629, "missing 'feature'"); continue } } "unstable" => { if stab.is_some() { - handle_errors(sess, attr.span(), AttrError::MultipleStabilityLevels); + handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels); break } @@ -309,16 +306,16 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, let mut issue = None; for meta in metas { if let Some(mi) = meta.meta_item() { - match &*mi.name().as_str() { - "feature" => if !get(mi, &mut feature) { continue 'outer }, - "reason" => if !get(mi, &mut reason) { continue 'outer }, - "issue" => if !get(mi, &mut issue) { continue 'outer }, + match mi.ident_str() { + Some("feature") => if !get(mi, &mut feature) { continue 'outer }, + Some("reason") => if !get(mi, &mut reason) { continue 'outer }, + Some("issue") => if !get(mi, &mut issue) { continue 'outer }, _ => { handle_errors( sess, - meta.span, + meta.span(), AttrError::UnknownMetaItem( - mi.name(), + mi.path.to_string(), &["feature", "reason", "issue"] ), ); @@ -328,7 +325,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, } else { handle_errors( sess, - meta.span, + meta.span(), AttrError::UnsupportedLiteral( "unsupported literal", false, @@ -347,7 +344,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, if let Ok(issue) = issue.as_str().parse() { issue } else { - span_err!(diagnostic, attr.span(), E0545, + span_err!(diagnostic, attr.span, E0545, "incorrect 'issue'"); continue } @@ -360,42 +357,44 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, }) } (None, _, _) => { - handle_errors(sess, attr.span(), AttrError::MissingFeature); + handle_errors(sess, attr.span, AttrError::MissingFeature); continue } _ => { - span_err!(diagnostic, attr.span(), E0547, "missing 'issue'"); + span_err!(diagnostic, attr.span, E0547, "missing 'issue'"); continue } } } "stable" => { if stab.is_some() { - handle_errors(sess, attr.span(), AttrError::MultipleStabilityLevels); + handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels); break } let mut feature = None; let mut since = None; for meta in metas { - match &meta.node { - NestedMetaItemKind::MetaItem(mi) => { - match &*mi.name().as_str() { - "feature" => if !get(mi, &mut feature) { continue 'outer }, - "since" => if !get(mi, &mut since) { continue 'outer }, + match meta { + NestedMetaItem::MetaItem(mi) => { + match mi.ident_str() { + Some("feature") => + if !get(mi, &mut feature) { continue 'outer }, + Some("since") => + if !get(mi, &mut since) { continue 'outer }, _ => { handle_errors( sess, - meta.span, + meta.span(), AttrError::UnknownMetaItem( - mi.name(), &["since", "note"], + mi.path.to_string(), &["since", "note"], ), ); continue 'outer } } }, - NestedMetaItemKind::Literal(lit) => { + NestedMetaItem::Literal(lit) => { handle_errors( sess, lit.span, @@ -422,11 +421,11 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, }) } (None, _) => { - handle_errors(sess, attr.span(), AttrError::MissingFeature); + handle_errors(sess, attr.span, AttrError::MissingFeature); continue } _ => { - handle_errors(sess, attr.span(), AttrError::MissingSince); + handle_errors(sess, attr.span, AttrError::MissingSince); continue } } @@ -483,8 +482,8 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat gated_cfg.check_and_emit(sess, feats); } let error = |span, msg| { sess.span_diagnostic.span_err(span, msg); true }; - if cfg.ident.segments.len() != 1 { - return error(cfg.ident.span, "`cfg` predicate key must be an identifier"); + if cfg.path.segments.len() != 1 { + return error(cfg.path.span, "`cfg` predicate key must be an identifier"); } match &cfg.node { MetaItemKind::List(..) => { @@ -502,7 +501,8 @@ pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Feat true } MetaItemKind::NameValue(..) | MetaItemKind::Word => { - sess.config.contains(&(cfg.name(), cfg.value_str())) + let ident = cfg.ident().expect("multi-segment cfg predicate"); + sess.config.contains(&(ident.name, cfg.value_str())) } } }) @@ -520,7 +520,7 @@ pub fn eval_condition(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F) if !mi.is_meta_item() { handle_errors( sess, - mi.span, + mi.span(), AttrError::UnsupportedLiteral( "unsupported literal", false @@ -532,14 +532,14 @@ pub fn eval_condition(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F) // The unwraps below may look dangerous, but we've already asserted // that they won't fail with the loop above. - match &*cfg.name().as_str() { - "any" => mis.iter().any(|mi| { + match cfg.ident_str() { + Some("any") => mis.iter().any(|mi| { eval_condition(mi.meta_item().unwrap(), sess, eval) }), - "all" => mis.iter().all(|mi| { + Some("all") => mis.iter().all(|mi| { eval_condition(mi.meta_item().unwrap(), sess, eval) }), - "not" => { + Some("not") => { if mis.len() != 1 { span_err!(sess.span_diagnostic, cfg.span, E0536, "expected 1 cfg-pattern"); return false; @@ -547,8 +547,9 @@ pub fn eval_condition(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F) !eval_condition(mis[0].meta_item().unwrap(), sess, eval) }, - p => { - span_err!(sess.span_diagnostic, cfg.span, E0537, "invalid predicate `{}`", p); + _ => { + span_err!(sess.span_diagnostic, cfg.span, E0537, + "invalid predicate `{}`", cfg.path); false } } @@ -602,7 +603,9 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess, MetaItemKind::List(list) => { let get = |meta: &MetaItem, item: &mut Option| { if item.is_some() { - handle_errors(sess, meta.span, AttrError::MultipleItem(meta.name())); + handle_errors( + sess, meta.span, AttrError::MultipleItem(meta.path.to_string()) + ); return false } if let Some(v) = meta.value_str() { @@ -630,22 +633,23 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess, let mut since = None; let mut note = None; for meta in list { - match &meta.node { - NestedMetaItemKind::MetaItem(mi) => { - match &*mi.name().as_str() { - "since" => if !get(mi, &mut since) { continue 'outer }, - "note" => if !get(mi, &mut note) { continue 'outer }, + match meta { + NestedMetaItem::MetaItem(mi) => { + match mi.ident_str() { + Some("since") => if !get(mi, &mut since) { continue 'outer }, + Some("note") => if !get(mi, &mut note) { continue 'outer }, _ => { handle_errors( sess, - meta.span, - AttrError::UnknownMetaItem(mi.name(), &["since", "note"]), + meta.span(), + AttrError::UnknownMetaItem(mi.path.to_string(), + &["since", "note"]), ); continue 'outer } } } - NestedMetaItemKind::Literal(lit) => { + NestedMetaItem::Literal(lit) => { handle_errors( sess, lit.span, @@ -714,7 +718,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec { if !item.is_meta_item() { handle_errors( sess, - item.span, + item.span(), AttrError::UnsupportedLiteral( "meta item in `repr` must be an identifier", false, @@ -724,19 +728,13 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec { } let mut recognised = false; - if let Some(mi) = item.word() { - let word = &*mi.name().as_str(); - let hint = match word { - "C" => Some(ReprC), - "packed" => Some(ReprPacked(1)), - "simd" => Some(ReprSimd), - "transparent" => Some(ReprTransparent), - _ => match int_type_of_word(word) { - Some(ity) => Some(ReprInt(ity)), - None => { - None - } - } + if item.is_word() { + let hint = match item.ident_str() { + Some("C") => Some(ReprC), + Some("packed") => Some(ReprPacked(1)), + Some("simd") => Some(ReprSimd), + Some("transparent") => Some(ReprTransparent), + name => name.and_then(|name| int_type_of_word(name)).map(ReprInt), }; if let Some(h) = hint { @@ -777,20 +775,20 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec { }; } if let Some(literal_error) = literal_error { - span_err!(diagnostic, item.span, E0589, + span_err!(diagnostic, item.span(), E0589, "invalid `repr(align)` attribute: {}", literal_error); } } else { if let Some(meta_item) = item.meta_item() { - if meta_item.name() == "align" { + if meta_item.check_name("align") { if let MetaItemKind::NameValue(ref value) = meta_item.node { recognised = true; - let mut err = struct_span_err!(diagnostic, item.span, E0693, + let mut err = struct_span_err!(diagnostic, item.span(), E0693, "incorrect `repr(align)` attribute format"); match value.node { ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => { err.span_suggestion( - item.span, + item.span(), "use parentheses instead", format!("align({})", int), Applicability::MachineApplicable @@ -798,7 +796,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec { } ast::LitKind::Str(s, _) => { err.span_suggestion( - item.span, + item.span(), "use parentheses instead", format!("align({})", s), Applicability::MachineApplicable @@ -813,7 +811,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec { } if !recognised { // Not a word we recognize - span_err!(diagnostic, item.span, E0552, + span_err!(diagnostic, item.span(), E0552, "unrecognized representation hint"); } } diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index b5fc850731404..1a8faa43fff7c 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -13,7 +13,7 @@ pub use StabilityLevel::*; use crate::ast; use crate::ast::{AttrId, Attribute, AttrStyle, Name, Ident, Path, PathSegment}; -use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind}; +use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem}; use crate::ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind, GenericParam}; use crate::mut_visit::visit_clobber; use crate::source_map::{BytePos, Spanned, respan, dummy_spanned}; @@ -64,36 +64,33 @@ pub fn is_known_lint_tool(m_item: Ident) -> bool { } impl NestedMetaItem { - /// Returns the MetaItem if self is a NestedMetaItemKind::MetaItem. + /// Returns the MetaItem if self is a NestedMetaItem::MetaItem. pub fn meta_item(&self) -> Option<&MetaItem> { - match self.node { - NestedMetaItemKind::MetaItem(ref item) => Some(item), + match *self { + NestedMetaItem::MetaItem(ref item) => Some(item), _ => None } } - /// Returns the Lit if self is a NestedMetaItemKind::Literal. + /// Returns the Lit if self is a NestedMetaItem::Literal. pub fn literal(&self) -> Option<&Lit> { - match self.node { - NestedMetaItemKind::Literal(ref lit) => Some(lit), + match *self { + NestedMetaItem::Literal(ref lit) => Some(lit), _ => None } } - /// Returns the Span for `self`. - pub fn span(&self) -> Span { - self.span - } - /// Returns `true` if this list item is a MetaItem with a name of `name`. pub fn check_name(&self, name: &str) -> bool { self.meta_item().map_or(false, |meta_item| meta_item.check_name(name)) } - /// Returns the name of the meta item, e.g., `foo` in `#[foo]`, - /// `#[foo="bar"]` and `#[foo(bar)]`, if self is a MetaItem - pub fn name(&self) -> Option { - self.meta_item().and_then(|meta_item| Some(meta_item.name())) + /// For a single-segment meta-item returns its name, otherwise returns `None`. + pub fn ident(&self) -> Option { + self.meta_item().and_then(|meta_item| meta_item.ident()) + } + pub fn ident_str(&self) -> Option<&str> { + self.ident().map(|name| name.as_str().get()) } /// Gets the string value if self is a MetaItem and the MetaItem is a @@ -108,25 +105,14 @@ impl NestedMetaItem { |meta_item| meta_item.meta_item_list().and_then( |meta_item_list| { if meta_item_list.len() == 1 { - let nested_item = &meta_item_list[0]; - if nested_item.is_literal() { - Some((meta_item.name(), nested_item.literal().unwrap())) - } else { - None + if let Some(ident) = meta_item.ident() { + if let Some(lit) = meta_item_list[0].literal() { + return Some((ident.name, lit)); + } } } - else { - None - }})) - } - - /// Returns a MetaItem if self is a MetaItem with Kind Word. - pub fn word(&self) -> Option<&MetaItem> { - self.meta_item().and_then(|meta_item| if meta_item.is_word() { - Some(meta_item) - } else { - None - }) + None + })) } /// Gets a list of inner meta items from a list MetaItem type. @@ -146,7 +132,7 @@ impl NestedMetaItem { /// Returns `true` if self is a MetaItem and the meta item is a word. pub fn is_word(&self) -> bool { - self.word().is_some() + self.meta_item().map_or(false, |meta_item| meta_item.is_word()) } /// Returns `true` if self is a MetaItem and the meta item is a ValueString. @@ -160,10 +146,6 @@ impl NestedMetaItem { } } -fn name_from_path(path: &Path) -> Name { - path.segments.last().expect("empty path in attribute").ident.name -} - impl Attribute { /// Returns `true` if the attribute's path matches the argument. If it matches, then the /// attribute is marked as used. @@ -177,10 +159,16 @@ impl Attribute { matches } - /// Returns the **last** segment of the name of this attribute. - /// e.g., `foo` for `#[foo]`, `skip` for `#[rustfmt::skip]`. - pub fn name(&self) -> Name { - name_from_path(&self.path) + /// For a single-segment attribute returns its name, otherwise returns `None`. + pub fn ident(&self) -> Option { + if self.path.segments.len() == 1 { + Some(self.path.segments[0].ident) + } else { + None + } + } + pub fn ident_str(&self) -> Option<&str> { + self.ident().map(|name| name.as_str().get()) } pub fn value_str(&self) -> Option { @@ -195,11 +183,7 @@ impl Attribute { } pub fn is_word(&self) -> bool { - self.path.segments.len() == 1 && self.tokens.is_empty() - } - - pub fn span(&self) -> Span { - self.span + self.tokens.is_empty() } pub fn is_meta_item_list(&self) -> bool { @@ -213,8 +197,16 @@ impl Attribute { } impl MetaItem { - pub fn name(&self) -> Name { - name_from_path(&self.ident) + /// For a single-segment meta-item returns its name, otherwise returns `None`. + pub fn ident(&self) -> Option { + if self.path.segments.len() == 1 { + Some(self.path.segments[0].ident) + } else { + None + } + } + pub fn ident_str(&self) -> Option<&str> { + self.ident().map(|name| name.as_str().get()) } // #[attribute(name = "value")] @@ -252,10 +244,8 @@ impl MetaItem { } } - pub fn span(&self) -> Span { self.span } - pub fn check_name(&self, name: &str) -> bool { - self.name() == name + self.path == name } pub fn is_value_str(&self) -> bool { @@ -265,14 +255,6 @@ impl MetaItem { pub fn is_meta_item_list(&self) -> bool { self.meta_item_list().is_some() } - - pub fn is_scoped(&self) -> Option { - if self.ident.segments.len() > 1 { - Some(self.ident.segments[0].ident) - } else { - None - } - } } impl Attribute { @@ -280,7 +262,7 @@ impl Attribute { pub fn meta(&self) -> Option { let mut tokens = self.tokens.trees().peekable(); Some(MetaItem { - ident: self.path.clone(), + path: self.path.clone(), node: if let Some(node) = MetaItemKind::from_tokens(&mut tokens) { if tokens.peek().is_some() { return None; @@ -326,7 +308,7 @@ impl Attribute { pub fn parse_meta<'a>(&self, sess: &'a ParseSess) -> PResult<'a, MetaItem> { Ok(MetaItem { - ident: self.path.clone(), + path: self.path.clone(), node: self.parse(sess, |parser| parser.parse_meta_item_kind())?, span: self.span, }) @@ -364,19 +346,19 @@ pub fn mk_name_value_item_str(ident: Ident, value: Spanned) -> MetaItem } pub fn mk_name_value_item(span: Span, ident: Ident, value: ast::Lit) -> MetaItem { - MetaItem { ident: Path::from_ident(ident), span, node: MetaItemKind::NameValue(value) } + MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::NameValue(value) } } pub fn mk_list_item(span: Span, ident: Ident, items: Vec) -> MetaItem { - MetaItem { ident: Path::from_ident(ident), span, node: MetaItemKind::List(items) } + MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::List(items) } } pub fn mk_word_item(ident: Ident) -> MetaItem { - MetaItem { ident: Path::from_ident(ident), span: ident.span, node: MetaItemKind::Word } + MetaItem { path: Path::from_ident(ident), span: ident.span, node: MetaItemKind::Word } } pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem { - respan(ident.span, NestedMetaItemKind::MetaItem(mk_word_item(ident))) + NestedMetaItem::MetaItem(mk_word_item(ident)) } pub fn mk_attr_id() -> AttrId { @@ -400,7 +382,7 @@ pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: MetaItem) -> Attribute Attribute { id, style: ast::AttrStyle::Inner, - path: item.ident, + path: item.path, tokens: item.node.tokens(item.span), is_sugared_doc: false, span: sp, @@ -417,7 +399,7 @@ pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute Attribute { id, style: ast::AttrStyle::Outer, - path: item.ident, + path: item.path, tokens: item.node.tokens(item.span), is_sugared_doc: false, span: sp, @@ -468,7 +450,7 @@ impl MetaItem { fn tokens(&self) -> TokenStream { let mut idents = vec![]; let mut last_pos = BytePos(0 as u32); - for (i, segment) in self.ident.segments.iter().enumerate() { + for (i, segment) in self.path.segments.iter().enumerate() { let is_first = i == 0; if !is_first { let mod_sep_span = Span::new(last_pos, @@ -488,7 +470,7 @@ impl MetaItem { where I: Iterator, { // FIXME: Share code with `parse_path`. - let ident = match tokens.next() { + let path = match tokens.next() { Some(TokenTree::Token(span, token @ Token::Ident(..))) | Some(TokenTree::Token(span, token @ Token::ModSep)) => 'arm: { let mut segments = if let Token::Ident(ident, _) = token { @@ -529,11 +511,11 @@ impl MetaItem { let node = MetaItemKind::from_tokens(tokens)?; let hi = match node { MetaItemKind::NameValue(ref lit) => lit.span.hi(), - MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(ident.span.hi()), - _ => ident.span.hi(), + MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(path.span.hi()), + _ => path.span.hi(), }; - let span = ident.span.with_hi(hi); - Some(MetaItem { ident, node, span }) + let span = path.span.with_hi(hi); + Some(MetaItem { path, node, span }) } } @@ -552,7 +534,7 @@ impl MetaItemKind { if i > 0 { tokens.push(TokenTree::Token(span, Token::Comma).into()); } - item.node.tokens().append_to_tree_and_joint_vec(&mut tokens); + item.tokens().append_to_tree_and_joint_vec(&mut tokens); } TokenTree::Delimited( DelimSpan::from_single(span), @@ -586,8 +568,8 @@ impl MetaItemKind { let mut tokens = delimited.into_trees().peekable(); let mut result = Vec::new(); while let Some(..) = tokens.peek() { - let item = NestedMetaItemKind::from_tokens(&mut tokens)?; - result.push(respan(item.span(), item)); + let item = NestedMetaItem::from_tokens(&mut tokens)?; + result.push(item); match tokens.next() { None | Some(TokenTree::Token(_, Token::Comma)) => {} _ => return None, @@ -597,32 +579,32 @@ impl MetaItemKind { } } -impl NestedMetaItemKind { - fn span(&self) -> Span { +impl NestedMetaItem { + pub fn span(&self) -> Span { match *self { - NestedMetaItemKind::MetaItem(ref item) => item.span, - NestedMetaItemKind::Literal(ref lit) => lit.span, + NestedMetaItem::MetaItem(ref item) => item.span, + NestedMetaItem::Literal(ref lit) => lit.span, } } fn tokens(&self) -> TokenStream { match *self { - NestedMetaItemKind::MetaItem(ref item) => item.tokens(), - NestedMetaItemKind::Literal(ref lit) => lit.tokens(), + NestedMetaItem::MetaItem(ref item) => item.tokens(), + NestedMetaItem::Literal(ref lit) => lit.tokens(), } } - fn from_tokens(tokens: &mut iter::Peekable) -> Option + fn from_tokens(tokens: &mut iter::Peekable) -> Option where I: Iterator, { if let Some(TokenTree::Token(span, token)) = tokens.peek().cloned() { if let Some(node) = LitKind::from_token(token) { tokens.next(); - return Some(NestedMetaItemKind::Literal(respan(span, node))); + return Some(NestedMetaItem::Literal(respan(span, node))); } } - MetaItem::from_tokens(tokens).map(NestedMetaItemKind::MetaItem) + MetaItem::from_tokens(tokens).map(NestedMetaItem::MetaItem) } } diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 2abb7e407eb02..c300ffc2d61b9 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -181,13 +181,13 @@ impl<'a> StripUnconfigured<'a> { if nested_meta_items.is_empty() { return error(meta_item.span, "`cfg` predicate is not specified", ""); } else if nested_meta_items.len() > 1 { - return error(nested_meta_items.last().unwrap().span, + return error(nested_meta_items.last().unwrap().span(), "multiple `cfg` predicates are specified", ""); } match nested_meta_items[0].meta_item() { Some(meta_item) => attr::cfg_matches(meta_item, self.sess, self.features), - None => error(nested_meta_items[0].span, + None => error(nested_meta_items[0].span(), "`cfg` predicate key cannot be a literal", ""), } }) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index b805213bb1a4c..82358679c0e82 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -601,7 +601,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { res } ProcMacroDerive(..) | BuiltinDerive(..) => { - self.cx.span_err(attr.span, &format!("`{}` is a derive mode", attr.path)); + self.cx.span_err(attr.span, &format!("`{}` is a derive macro", attr.path)); self.cx.trace_macros_diag(); invoc.fragment_kind.dummy(attr.span) } @@ -822,7 +822,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } ProcMacroDerive(..) | BuiltinDerive(..) => { - self.cx.span_err(path.span, &format!("`{}` is a derive mode", path)); + self.cx.span_err(path.span, &format!("`{}` is a derive macro", path)); self.cx.trace_macros_diag(); kind.dummy(span) } @@ -929,7 +929,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { invoc.expansion_data.mark.set_expn_info(expn_info); let span = span.with_ctxt(self.cx.backtrace()); let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this - ident: Path::from_ident(keywords::Invalid.ident()), + path: Path::from_ident(keywords::Invalid.ident()), span: DUMMY_SP, node: ast::MetaItemKind::Word, }; @@ -1520,23 +1520,23 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { self.cx.source_map().new_source_file(filename.into(), src); let include_info = vec![ - dummy_spanned(ast::NestedMetaItemKind::MetaItem( + ast::NestedMetaItem::MetaItem( attr::mk_name_value_item_str( Ident::from_str("file"), dummy_spanned(file), ), - )), - dummy_spanned(ast::NestedMetaItemKind::MetaItem( + ), + ast::NestedMetaItem::MetaItem( attr::mk_name_value_item_str( Ident::from_str("contents"), dummy_spanned(src_interned), ), - )), + ), ]; let include_ident = Ident::from_str("include"); let item = attr::mk_list_item(DUMMY_SP, include_ident, include_info); - items.push(dummy_spanned(ast::NestedMetaItemKind::MetaItem(item))); + items.push(ast::NestedMetaItem::MetaItem(item)); } Err(e) => { let lit = it @@ -1569,7 +1569,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { } } else { let mut err = self.cx.struct_span_err( - it.span, + it.span(), &format!("expected path to external documentation"), ); @@ -1590,7 +1590,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { }; err.span_suggestion( - it.span, + it.span(), "provide a file path with `=`", format!("include = \"{}\"", path), applicability, diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index bd64bb010219b..12912044e4e3d 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -380,9 +380,14 @@ pub fn compile( .map(|attr| attr .meta_item_list() .map(|list| list.iter() - .map(|it| it.name().unwrap_or_else(|| sess.span_diagnostic.span_bug( - it.span, "allow internal unstable expects feature names", - ))) + .filter_map(|it| { + let name = it.ident().map(|ident| ident.name); + if name.is_none() { + sess.span_diagnostic.span_err(it.span(), + "allow internal unstable expects feature names") + } + name + }) .collect::>().into() ) .unwrap_or_else(|| { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 280b17da0be3f..9beaabb0cd58b 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1289,9 +1289,8 @@ pub struct GatedCfg { impl GatedCfg { pub fn gate(cfg: &ast::MetaItem) -> Option { - let name = cfg.name().as_str(); GATED_CFGS.iter() - .position(|info| info.0 == name) + .position(|info| cfg.check_name(info.0)) .map(|idx| { GatedCfg { span: cfg.span, @@ -1342,16 +1341,16 @@ macro_rules! gate_feature { impl<'a> Context<'a> { fn check_attribute(&self, attr: &ast::Attribute, is_macro: bool) { debug!("check_attribute(attr = {:?})", attr); - let name = attr.name().as_str(); + let name = attr.ident_str(); for &(n, ty, _template, ref gateage) in BUILTIN_ATTRIBUTES { - if name == n { + if name == Some(n) { if let Gated(_, name, desc, ref has_feature) = *gateage { if !attr.span.allows_unstable(name) { gate_feature_fn!( self, has_feature, attr.span, name, desc, GateStrength::Hard ); } - } else if name == "doc" { + } else if n == "doc" { if let Some(content) = attr.meta_item_list() { if content.iter().any(|c| c.check_name("include")) { gate_feature!(self, external_doc, attr.span, @@ -1374,7 +1373,7 @@ impl<'a> Context<'a> { } } if !attr::is_known(attr) { - if name.starts_with("rustc_") { + if name.map_or(false, |name| name.starts_with("rustc_")) { let msg = "unless otherwise specified, attributes with the prefix `rustc_` \ are reserved for internal compiler diagnostics"; gate_feature!(self, rustc_attrs, attr.span, msg); @@ -2055,15 +2054,14 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], }; for mi in list { - let name = if let Some(word) = mi.word() { - word.name() - } else { - continue + let name = match mi.ident_str() { + Some(name) if mi.is_word() => name, + _ => continue, }; - if incomplete_features.iter().any(|f| *f == name.as_str()) { + if incomplete_features.iter().any(|f| *f == name) { span_handler.struct_span_warn( - mi.span, + mi.span(), &format!( "the feature `{}` is incomplete and may cause the compiler to crash", name @@ -2101,18 +2099,19 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], }; for mi in list { - let name = if let Some(word) = mi.word() { - word.name() - } else { - span_err!(span_handler, mi.span, E0556, - "malformed feature, expected just one word"); - continue + let name = match mi.ident() { + Some(ident) if mi.is_word() => ident.name, + _ => { + span_err!(span_handler, mi.span(), E0556, + "malformed feature, expected just one word"); + continue + } }; if let Some(edition) = edition_enabled_features.get(&name) { struct_span_warn!( span_handler, - mi.span, + mi.span(), E0705, "the feature `{}` is included in the Rust {} edition", name, @@ -2129,32 +2128,32 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) { if let Some(allowed) = allow_features.as_ref() { if allowed.iter().find(|f| *f == name.as_str()).is_none() { - span_err!(span_handler, mi.span, E0725, + span_err!(span_handler, mi.span(), E0725, "the feature `{}` is not in the list of allowed features", name); continue; } } - set(&mut features, mi.span); - features.declared_lang_features.push((name, mi.span, None)); + set(&mut features, mi.span()); + features.declared_lang_features.push((name, mi.span(), None)); continue } let removed = REMOVED_FEATURES.iter().find(|f| name == f.0); let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.0); if let Some((.., reason)) = removed.or(stable_removed) { - feature_removed(span_handler, mi.span, *reason); + feature_removed(span_handler, mi.span(), *reason); continue } if let Some((_, since, ..)) = ACCEPTED_FEATURES.iter().find(|f| name == f.0) { let since = Some(Symbol::intern(since)); - features.declared_lang_features.push((name, mi.span, since)); + features.declared_lang_features.push((name, mi.span(), since)); continue } - features.declared_lib_features.push((name, mi.span)); + features.declared_lib_features.push((name, mi.span())); } } diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 802b780869597..462346df7d76d 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -539,16 +539,14 @@ pub fn noop_visit_macro_def(macro_def: &mut MacroDef, vis: &mut T } pub fn noop_visit_meta_list_item(li: &mut NestedMetaItem, vis: &mut T) { - let Spanned { node, span } = li; - match node { - NestedMetaItemKind::MetaItem(mi) => vis.visit_meta_item(mi), - NestedMetaItemKind::Literal(_lit) => {} + match li { + NestedMetaItem::MetaItem(mi) => vis.visit_meta_item(mi), + NestedMetaItem::Literal(_lit) => {} } - vis.visit_span(span); } pub fn noop_visit_meta_item(mi: &mut MetaItem, vis: &mut T) { - let MetaItem { ident: _, node, span } = mi; + let MetaItem { path: _, node, span } = mi; match node { MetaItemKind::Word => {} MetaItemKind::List(mis) => visit_vec(mis, |mi| vis.visit_meta_list_item(mi)), @@ -1340,4 +1338,3 @@ mod tests { }) } } - diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index e93e15f9012a7..4211268f33efe 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -1,6 +1,5 @@ use crate::attr; use crate::ast; -use crate::source_map::respan; use crate::parse::{SeqSep, PResult}; use crate::parse::token::{self, Nonterminal, DelimToken}; use crate::parse::parser::{Parser, TokenType, PathStyle}; @@ -149,7 +148,7 @@ impl<'a> Parser<'a> { }; Ok(if let Some(meta) = meta { self.bump(); - (meta.ident, meta.node.tokens(meta.span)) + (meta.path, meta.node.tokens(meta.span)) } else { let path = self.parse_path(PathStyle::Mod)?; let tokens = if self.check(&token::OpenDelim(DelimToken::Paren)) || @@ -250,10 +249,10 @@ impl<'a> Parser<'a> { } let lo = self.span; - let ident = self.parse_path(PathStyle::Mod)?; + let path = self.parse_path(PathStyle::Mod)?; let node = self.parse_meta_item_kind()?; let span = lo.to(self.prev_span); - Ok(ast::MetaItem { ident, node, span }) + Ok(ast::MetaItem { path, node, span }) } crate fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> { @@ -268,18 +267,16 @@ impl<'a> Parser<'a> { /// matches meta_item_inner : (meta_item | UNSUFFIXED_LIT) ; fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> { - let lo = self.span; - match self.parse_unsuffixed_lit() { Ok(lit) => { - return Ok(respan(lo.to(self.prev_span), ast::NestedMetaItemKind::Literal(lit))) + return Ok(ast::NestedMetaItem::Literal(lit)) } Err(ref mut err) => self.diagnostic().cancel(err) } match self.parse_meta_item() { Ok(mi) => { - return Ok(respan(lo.to(self.prev_span), ast::NestedMetaItemKind::MetaItem(mi))) + return Ok(ast::NestedMetaItem::MetaItem(mi)) } Err(ref mut err) => self.diagnostic().cancel(err) } diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 01e3b29290318..bcd53dbfeb2c5 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1,7 +1,7 @@ use crate::ast::{self, Ident}; use crate::source_map::{SourceMap, FilePathMapping}; use crate::parse::{token, ParseSess}; -use crate::symbol::{Symbol, keywords}; +use crate::symbol::Symbol; use errors::{Applicability, FatalError, Diagnostic, DiagnosticBuilder}; use syntax_pos::{BytePos, CharPos, Pos, Span, NO_EXPANSION}; @@ -1249,15 +1249,11 @@ impl<'a> StringReader<'a> { // FIXME: perform NFKC normalization here. (Issue #2253) let ident = self.mk_ident(string); - if is_raw_ident && (ident.is_path_segment_keyword() || - ident.name == keywords::Underscore.name()) { - self.fatal_span_(raw_start, self.pos, - &format!("`r#{}` is not currently supported.", ident.name) - ).raise(); - } - if is_raw_ident { let span = self.mk_sp(raw_start, self.pos); + if !ident.can_be_raw() { + self.err_span(span, &format!("`{}` cannot be a raw identifier", ident)); + } self.sess.raw_identifier_spans.borrow_mut().push(span); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 22af7d47fd0a1..aa70c54a1ef8a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -895,9 +895,7 @@ impl<'a> Parser<'a> { &format!("expected identifier, found {}", self.this_token_descr())); if let token::Ident(ident, false) = &self.token { - if ident.is_reserved() && !ident.is_path_segment_keyword() && - ident.name != keywords::Underscore.name() - { + if ident.is_raw_guess() { err.span_suggestion( self.span, "you can escape reserved keywords to use them as identifiers", @@ -2335,7 +2333,7 @@ impl<'a> Parser<'a> { let meta_ident = match self.token { token::Interpolated(ref nt) => match **nt { token::NtMeta(ref meta) => match meta.node { - ast::MetaItemKind::Word => Some(meta.ident.clone()), + ast::MetaItemKind::Word => Some(meta.path.clone()), _ => None, }, _ => None, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 49e3fad4af0ff..e04e127ccf15a 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -768,11 +768,11 @@ pub trait PrintState<'a> { } fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) -> io::Result<()> { - match item.node { - ast::NestedMetaItemKind::MetaItem(ref mi) => { + match item { + ast::NestedMetaItem::MetaItem(ref mi) => { self.print_meta_item(mi) }, - ast::NestedMetaItemKind::Literal(ref lit) => { + ast::NestedMetaItem::Literal(ref lit) => { self.print_literal(lit) } } @@ -781,15 +781,15 @@ pub trait PrintState<'a> { fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> { self.ibox(INDENT_UNIT)?; match item.node { - ast::MetaItemKind::Word => self.print_attribute_path(&item.ident)?, + ast::MetaItemKind::Word => self.print_attribute_path(&item.path)?, ast::MetaItemKind::NameValue(ref value) => { - self.print_attribute_path(&item.ident)?; + self.print_attribute_path(&item.path)?; self.writer().space()?; self.word_space("=")?; self.print_literal(value)?; } ast::MetaItemKind::List(ref items) => { - self.print_attribute_path(&item.ident)?; + self.print_attribute_path(&item.path)?; self.popen()?; self.commasep(Consistent, &items[..], diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 56290fa771ba9..6f03c5854036c 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -435,9 +435,12 @@ fn get_test_runner(sd: &errors::Handler, krate: &ast::Crate) -> Option meta_item.path.clone(), + _ => sd.span_fatal(test_attr.span, "`test_runner` argument must be a path").raise() + } }) } diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index cfc3c931598a1..e73110717e979 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -17,9 +17,11 @@ struct MarkAttrs<'a>(&'a [ast::Name]); impl<'a> Visitor<'a> for MarkAttrs<'a> { fn visit_attribute(&mut self, attr: &Attribute) { - if self.0.contains(&attr.name()) { - mark_used(attr); - mark_known(attr); + if let Some(ident) = attr.ident() { + if self.0.contains(&ident.name) { + mark_used(attr); + mark_known(attr); + } } } diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index b8f96c5bc0ea9..2bb98c1bf625c 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -463,12 +463,9 @@ impl<'a> TraitDef<'a> { let mut attrs = newitem.attrs.clone(); attrs.extend(item.attrs .iter() - .filter(|a| { - match &*a.name().as_str() { - "allow" | "warn" | "deny" | "forbid" | "stable" | "unstable" => true, - _ => false, - } - }) + .filter(|a| a.ident_str().map_or(false, |name| { + ["allow", "warn", "deny", "forbid", "stable", "unstable"].contains(&name) + })) .cloned()); push(Annotatable::Item(P(ast::Item { attrs: attrs, ..(*newitem).clone() }))) } diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs index d8f8decef39b1..d5f37aff222ef 100644 --- a/src/libsyntax_ext/proc_macro_decls.rs +++ b/src/libsyntax_ext/proc_macro_decls.rs @@ -109,52 +109,67 @@ impl<'a> CollectProcMacros<'a> { None => return, }; if list.len() != 1 && list.len() != 2 { - self.handler.span_err(attr.span(), + self.handler.span_err(attr.span, "attribute must have either one or two arguments"); return } - let trait_attr = &list[0]; - let attributes_attr = list.get(1); - let trait_name = match trait_attr.name() { - Some(name) => name, + let trait_attr = match list[0].meta_item() { + Some(meta_item) => meta_item, _ => { - self.handler.span_err(trait_attr.span(), "not a meta item"); + self.handler.span_err(list[0].span(), "not a meta item"); + return + } + }; + let trait_ident = match trait_attr.ident() { + Some(trait_ident) if trait_attr.is_word() => trait_ident, + _ => { + self.handler.span_err(trait_attr.span, "must only be one word"); return } }; - if !trait_attr.is_word() { - self.handler.span_err(trait_attr.span(), "must only be one word"); - } - if deriving::is_builtin_trait(trait_name) { - self.handler.span_err(trait_attr.span(), - "cannot override a built-in #[derive] mode"); + if !trait_ident.can_be_raw() { + self.handler.span_err(trait_attr.span, + &format!("`{}` cannot be a name of derive macro", trait_ident)); + } + if deriving::is_builtin_trait(trait_ident.name) { + self.handler.span_err(trait_attr.span, + "cannot override a built-in derive macro"); } + let attributes_attr = list.get(1); let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr { if !attr.check_name("attributes") { self.handler.span_err(attr.span(), "second argument must be `attributes`") } attr.meta_item_list().unwrap_or_else(|| { self.handler.span_err(attr.span(), - "attribute must be of form: \ - `attributes(foo, bar)`"); + "attribute must be of form: `attributes(foo, bar)`"); &[] }).into_iter().filter_map(|attr| { - let name = match attr.name() { - Some(name) => name, + let attr = match attr.meta_item() { + Some(meta_item) => meta_item, _ => { self.handler.span_err(attr.span(), "not a meta item"); return None; - }, + } }; - if !attr.is_word() { - self.handler.span_err(attr.span(), "must only be one word"); - return None; + let ident = match attr.ident() { + Some(ident) if attr.is_word() => ident, + _ => { + self.handler.span_err(attr.span, "must only be one word"); + return None; + } + }; + if !ident.can_be_raw() { + self.handler.span_err( + attr.span, + &format!("`{}` cannot be a name of derive helper attribute", ident), + ); } - Some(name) + Some(ident.name) }).collect() } else { Vec::new() @@ -163,7 +178,7 @@ impl<'a> CollectProcMacros<'a> { if self.in_root && item.vis.node.is_pub() { self.derives.push(ProcMacroDerive { span: item.span, - trait_name, + trait_name: trait_ident.name, function_name: item.ident, attrs: proc_attrs, }); @@ -247,8 +262,8 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { to the same function", attr.path, prev_attr.path) }; - self.handler.struct_span_err(attr.span(), &msg) - .span_note(prev_attr.span(), "Previous attribute here") + self.handler.struct_span_err(attr.span, &msg) + .span_note(prev_attr.span, "Previous attribute here") .emit(); return; @@ -273,7 +288,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { let msg = format!("the `#[{}]` attribute may only be used on bare functions", attr.path); - self.handler.span_err(attr.span(), &msg); + self.handler.span_err(attr.span, &msg); return; } @@ -285,7 +300,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { let msg = format!("the `#[{}]` attribute is only usable with crates of the \ `proc-macro` crate type", attr.path); - self.handler.span_err(attr.span(), &msg); + self.handler.span_err(attr.span, &msg); return; } diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs index a7ac95ba9ef50..c0a9dfe6189de 100644 --- a/src/libsyntax_ext/proc_macro_server.rs +++ b/src/libsyntax_ext/proc_macro_server.rs @@ -340,12 +340,8 @@ impl Ident { if !Self::is_valid(string) { panic!("`{:?}` is not a valid identifier", string) } - if is_raw { - let normalized_sym = Symbol::intern(string); - if normalized_sym == keywords::Underscore.name() || - ast::Ident::with_empty_ctxt(normalized_sym).is_path_segment_keyword() { - panic!("`{:?}` is not a valid raw identifier", string) - } + if is_raw && !ast::Ident::from_str(string).can_be_raw() { + panic!("`{}` cannot be a raw identifier", string); } Ident { sym, is_raw, span } } diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs index f4b625f8ea2c8..0dbcb7ce0b7e2 100644 --- a/src/libsyntax_ext/test.rs +++ b/src/libsyntax_ext/test.rs @@ -227,7 +227,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic { .and_then(|mi| mi.value_str()); if list.len() != 1 || msg.is_none() { sd.struct_span_warn( - attr.span(), + attr.span, "argument must be of the form: \ `expected = \"error message\"`" ).note("Errors in this attribute were erroneously \ diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index c5301f9f174c0..e8d215a562e2c 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -484,11 +484,16 @@ impl Ident { self.name == keywords::DollarCrate.name() } - // We see this identifier in a normal identifier position, like variable name or a type. - // How was it written originally? Did it use the raw form? Let's try to guess. - pub fn is_raw_guess(self) -> bool { + /// This identifier can be a raw identifier. + pub fn can_be_raw(self) -> bool { self.name != keywords::Invalid.name() && self.name != keywords::Underscore.name() && - self.is_reserved() && !self.is_path_segment_keyword() + !self.is_path_segment_keyword() + } + + /// We see this identifier in a normal identifier position, like variable name or a type. + /// How was it written originally? Did it use the raw form? Let's try to guess. + pub fn is_raw_guess(self) -> bool { + self.can_be_raw() && self.is_reserved() } } diff --git a/src/test/ui/parser/raw/raw-literal-self.rs b/src/test/ui/parser/raw/raw-literal-self.rs index d7b9553d032d3..123a11b6f8543 100644 --- a/src/test/ui/parser/raw/raw-literal-self.rs +++ b/src/test/ui/parser/raw/raw-literal-self.rs @@ -1,3 +1,4 @@ -fn self_test(r#self: u32) { - //~^ ERROR `r#self` is not currently supported. +fn main() { + let r#self; + //~^ ERROR `self` cannot be a raw identifier } diff --git a/src/test/ui/parser/raw/raw-literal-self.stderr b/src/test/ui/parser/raw/raw-literal-self.stderr index e64332785cc51..9a330fcdf2aae 100644 --- a/src/test/ui/parser/raw/raw-literal-self.stderr +++ b/src/test/ui/parser/raw/raw-literal-self.stderr @@ -1,8 +1,8 @@ -error: `r#self` is not currently supported. - --> $DIR/raw-literal-self.rs:1:14 +error: `self` cannot be a raw identifier + --> $DIR/raw-literal-self.rs:2:9 | -LL | fn self_test(r#self: u32) { - | ^^^^^^ +LL | let r#self; + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/raw/raw-literal-underscore.rs b/src/test/ui/parser/raw/raw-literal-underscore.rs index bbedd395202cf..6d15f1e7f0afd 100644 --- a/src/test/ui/parser/raw/raw-literal-underscore.rs +++ b/src/test/ui/parser/raw/raw-literal-underscore.rs @@ -1,3 +1,4 @@ -fn underscore_test(r#_: u32) { - //~^ ERROR `r#_` is not currently supported. +fn main() { + let r#_; + //~^ ERROR `_` cannot be a raw identifier } diff --git a/src/test/ui/parser/raw/raw-literal-underscore.stderr b/src/test/ui/parser/raw/raw-literal-underscore.stderr index 9427b33afd8d4..d96b14f55a39b 100644 --- a/src/test/ui/parser/raw/raw-literal-underscore.stderr +++ b/src/test/ui/parser/raw/raw-literal-underscore.stderr @@ -1,8 +1,8 @@ -error: `r#_` is not currently supported. - --> $DIR/raw-literal-underscore.rs:1:20 +error: `_` cannot be a raw identifier + --> $DIR/raw-literal-underscore.rs:2:9 | -LL | fn underscore_test(r#_: u32) { - | ^^^ +LL | let r#_; + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/proc-macro/attribute.rs b/src/test/ui/proc-macro/attribute.rs index a0b982d75f519..ac7d0b4c2b6c9 100644 --- a/src/test/ui/proc-macro/attribute.rs +++ b/src/test/ui/proc-macro/attribute.rs @@ -4,53 +4,73 @@ #![crate_type = "proc-macro"] extern crate proc_macro; +use proc_macro::*; #[proc_macro_derive] //~^ ERROR: attribute must be of the form -pub fn foo1(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - input -} +pub fn foo1(input: TokenStream) -> TokenStream { input } -#[proc_macro_derive = "foo"] +#[proc_macro_derive = ""] //~^ ERROR: attribute must be of the form -pub fn foo2(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - input -} - -#[proc_macro_derive( - a = "b" -)] -//~^^ ERROR: must only be one word -pub fn foo3(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - input -} - -#[proc_macro_derive(b, c, d)] +pub fn foo2(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d3, a, b)] +//~^ ERROR: attribute must have either one or two arguments +pub fn foo3(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d4, attributes(a), b)] //~^ ERROR: attribute must have either one or two arguments -pub fn foo4(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - input -} +pub fn foo4(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive("a")] +//~^ ERROR: not a meta item +pub fn foo5(input: TokenStream) -> TokenStream { input } -#[proc_macro_derive(d(e))] +#[proc_macro_derive(d6 = "")] //~^ ERROR: must only be one word -pub fn foo5(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - input -} +pub fn foo6(input: TokenStream) -> TokenStream { input } -#[proc_macro_derive(f, attributes(g = "h"))] +#[proc_macro_derive(m::d7)] //~^ ERROR: must only be one word -pub fn foo6(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - input -} +pub fn foo7(input: TokenStream) -> TokenStream { input } -#[proc_macro_derive(i, attributes(j(k)))] +#[proc_macro_derive(d8(a))] //~^ ERROR: must only be one word -pub fn foo7(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - input -} +pub fn foo8(input: TokenStream) -> TokenStream { input } -#[proc_macro_derive(l, attributes(m), n)] -//~^ ERROR: attribute must have either one or two arguments -pub fn foo8(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - input -} +#[proc_macro_derive(self)] +//~^ ERROR: `self` cannot be a name of derive macro +pub fn foo9(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(PartialEq)] +//~^ ERROR: cannot override a built-in derive macro +pub fn foo10(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d11, a)] +//~^ ERROR: second argument must be `attributes` +//~| ERROR: attribute must be of form: `attributes(foo, bar)` +pub fn foo11(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d12, attributes)] +//~^ ERROR: attribute must be of form: `attributes(foo, bar)` +pub fn foo12(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d13, attributes("a"))] +//~^ ERROR: not a meta item +pub fn foo13(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d14, attributes(a = ""))] +//~^ ERROR: must only be one word +pub fn foo14(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d15, attributes(m::a))] +//~^ ERROR: must only be one word +pub fn foo15(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d16, attributes(a(b)))] +//~^ ERROR: must only be one word +pub fn foo16(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d17, attributes(self))] +//~^ ERROR: `self` cannot be a name of derive helper attribute +pub fn foo17(input: TokenStream) -> TokenStream { input } diff --git a/src/test/ui/proc-macro/attribute.stderr b/src/test/ui/proc-macro/attribute.stderr index 231eb1f106898..cc17d383569fc 100644 --- a/src/test/ui/proc-macro/attribute.stderr +++ b/src/test/ui/proc-macro/attribute.stderr @@ -1,50 +1,110 @@ -error: must only be one word - --> $DIR/attribute.rs:21:5 +error: attribute must have either one or two arguments + --> $DIR/attribute.rs:17:1 | -LL | a = "b" - | ^^^^^^^ +LL | #[proc_macro_derive(d3, a, b)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: attribute must have either one or two arguments - --> $DIR/attribute.rs:28:1 + --> $DIR/attribute.rs:21:1 + | +LL | #[proc_macro_derive(d4, attributes(a), b)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: not a meta item + --> $DIR/attribute.rs:25:21 + | +LL | #[proc_macro_derive("a")] + | ^^^ + +error: must only be one word + --> $DIR/attribute.rs:29:21 | -LL | #[proc_macro_derive(b, c, d)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[proc_macro_derive(d6 = "")] + | ^^^^^^^ error: must only be one word - --> $DIR/attribute.rs:34:21 + --> $DIR/attribute.rs:33:21 | -LL | #[proc_macro_derive(d(e))] +LL | #[proc_macro_derive(m::d7)] + | ^^^^^ + +error: must only be one word + --> $DIR/attribute.rs:37:21 + | +LL | #[proc_macro_derive(d8(a))] + | ^^^^^ + +error: `self` cannot be a name of derive macro + --> $DIR/attribute.rs:41:21 + | +LL | #[proc_macro_derive(self)] | ^^^^ +error: cannot override a built-in derive macro + --> $DIR/attribute.rs:45:21 + | +LL | #[proc_macro_derive(PartialEq)] + | ^^^^^^^^^ + +error: second argument must be `attributes` + --> $DIR/attribute.rs:49:26 + | +LL | #[proc_macro_derive(d11, a)] + | ^ + +error: attribute must be of form: `attributes(foo, bar)` + --> $DIR/attribute.rs:49:26 + | +LL | #[proc_macro_derive(d11, a)] + | ^ + +error: attribute must be of form: `attributes(foo, bar)` + --> $DIR/attribute.rs:54:26 + | +LL | #[proc_macro_derive(d12, attributes)] + | ^^^^^^^^^^ + +error: not a meta item + --> $DIR/attribute.rs:58:37 + | +LL | #[proc_macro_derive(d13, attributes("a"))] + | ^^^ + error: must only be one word - --> $DIR/attribute.rs:40:35 + --> $DIR/attribute.rs:62:37 | -LL | #[proc_macro_derive(f, attributes(g = "h"))] - | ^^^^^^^ +LL | #[proc_macro_derive(d14, attributes(a = ""))] + | ^^^^^^ error: must only be one word - --> $DIR/attribute.rs:46:35 + --> $DIR/attribute.rs:66:37 | -LL | #[proc_macro_derive(i, attributes(j(k)))] - | ^^^^ +LL | #[proc_macro_derive(d15, attributes(m::a))] + | ^^^^ -error: attribute must have either one or two arguments - --> $DIR/attribute.rs:52:1 +error: must only be one word + --> $DIR/attribute.rs:70:37 + | +LL | #[proc_macro_derive(d16, attributes(a(b)))] + | ^^^^ + +error: `self` cannot be a name of derive helper attribute + --> $DIR/attribute.rs:74:37 | -LL | #[proc_macro_derive(l, attributes(m), n)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[proc_macro_derive(d17, attributes(self))] + | ^^^^ error: attribute must be of the form `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` - --> $DIR/attribute.rs:8:1 + --> $DIR/attribute.rs:9:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ error: attribute must be of the form `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` - --> $DIR/attribute.rs:14:1 + --> $DIR/attribute.rs:13:1 | -LL | #[proc_macro_derive = "foo"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[proc_macro_derive = ""] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 18 previous errors diff --git a/src/test/ui/proc-macro/invalid-punct-ident-3.stderr b/src/test/ui/proc-macro/invalid-punct-ident-3.stderr index 6ff47e3752c5c..24371f3a2a6db 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-3.stderr +++ b/src/test/ui/proc-macro/invalid-punct-ident-3.stderr @@ -4,7 +4,7 @@ error: proc macro panicked LL | invalid_raw_ident!(); | ^^^^^^^^^^^^^^^^^^^^^ | - = help: message: `"self"` is not a valid raw identifier + = help: message: `self` cannot be a raw identifier error: aborting due to previous error diff --git a/src/test/ui/proc-macro/shadow-builtin.rs b/src/test/ui/proc-macro/shadow-builtin.rs deleted file mode 100644 index afcc0ebc3464c..0000000000000 --- a/src/test/ui/proc-macro/shadow-builtin.rs +++ /dev/null @@ -1,14 +0,0 @@ -// force-host -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; - -use proc_macro::TokenStream; - -#[proc_macro_derive(PartialEq)] -//~^ ERROR: cannot override a built-in #[derive] mode -pub fn foo(input: TokenStream) -> TokenStream { - input -} diff --git a/src/test/ui/proc-macro/shadow-builtin.stderr b/src/test/ui/proc-macro/shadow-builtin.stderr deleted file mode 100644 index 668579509dc3b..0000000000000 --- a/src/test/ui/proc-macro/shadow-builtin.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: cannot override a built-in #[derive] mode - --> $DIR/shadow-builtin.rs:10:21 - | -LL | #[proc_macro_derive(PartialEq)] - | ^^^^^^^^^ - -error: aborting due to previous error -