use crate::cfg_eval::cfg_eval;
use rustc_ast as ast;
-use rustc_ast::{attr, token, GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
+use rustc_ast::{token, GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
use rustc_errors::{struct_span_err, Applicability};
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
use rustc_feature::AttributeTemplate;
ecx.resolver.resolve_derives(ecx.current_expansion.id, ecx.force_mode, &|| {
let template =
AttributeTemplate { list: Some("Trait1, Trait2, ..."), ..Default::default() };
- let attr =
- attr::mk_attr_outer(&sess.parse_sess.attr_id_generator, meta_item.clone());
- validate_attr::check_builtin_attribute(
+ validate_attr::check_builtin_meta_item(
&sess.parse_sess,
- &attr,
+ &meta_item,
+ ast::AttrStyle::Outer,
sym::derive,
template,
);
- let mut resolutions: Vec<_> = attr
- .meta_item_list()
- .unwrap_or_default()
- .into_iter()
- .filter_map(|nested_meta| match nested_meta {
- NestedMetaItem::MetaItem(meta) => Some(meta),
- NestedMetaItem::Literal(lit) => {
- // Reject `#[derive("Debug")]`.
- report_unexpected_literal(sess, &lit);
- None
- }
- })
- .map(|meta| {
- // Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the paths.
- report_path_args(sess, &meta);
- meta.path
- })
- .map(|path| (path, dummy_annotatable(), None, self.0))
- .collect();
+ let mut resolutions = match &meta_item.kind {
+ MetaItemKind::List(list) => {
+ list.iter()
+ .filter_map(|nested_meta| match nested_meta {
+ NestedMetaItem::MetaItem(meta) => Some(meta),
+ NestedMetaItem::Lit(lit) => {
+ // Reject `#[derive("Debug")]`.
+ report_unexpected_meta_item_lit(sess, &lit);
+ None
+ }
+ })
+ .map(|meta| {
+ // Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the
+ // paths.
+ report_path_args(sess, &meta);
+ meta.path.clone()
+ })
+ .map(|path| (path, dummy_annotatable(), None, self.0))
+ .collect()
+ }
+ _ => vec![],
+ };
// Do not configure or clone items unless necessary.
match &mut resolutions[..] {
bad_target
}
-fn report_unexpected_literal(sess: &Session, lit: &ast::Lit) {
+fn report_unexpected_meta_item_lit(sess: &Session, lit: &ast::MetaItemLit) {
let help_msg = match lit.token_lit.kind {
token::Str if rustc_lexer::is_ident(lit.token_lit.symbol.as_str()) => {
format!("try using `#[derive({})]`", lit.token_lit.symbol)