summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_builtin_macros/src/derive.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_builtin_macros/src/derive.rs')
-rw-r--r--compiler/rustc_builtin_macros/src/derive.rs59
1 files changed, 31 insertions, 28 deletions
diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs
index e0fb7affb..fa5a45730 100644
--- a/compiler/rustc_builtin_macros/src/derive.rs
+++ b/compiler/rustc_builtin_macros/src/derive.rs
@@ -1,7 +1,7 @@
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;
@@ -10,7 +10,7 @@ use rustc_session::Session;
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
-pub(crate) struct Expander;
+pub(crate) struct Expander(pub bool);
impl MultiItemModifier for Expander {
fn expand(
@@ -19,6 +19,7 @@ impl MultiItemModifier for Expander {
span: Span,
meta_item: &ast::MetaItem,
item: Annotatable,
+ _: bool,
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
let sess = ecx.sess;
if report_bad_target(sess, &item, span) {
@@ -32,46 +33,48 @@ impl MultiItemModifier for Expander {
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))
- .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[..] {
[] => {}
- [(_, first_item, _), others @ ..] => {
+ [(_, first_item, ..), others @ ..] => {
*first_item = cfg_eval(
sess,
features,
item.clone(),
ecx.current_expansion.lint_node_id,
);
- for (_, item, _) in others {
+ for (_, item, _, _) in others {
*item = first_item.clone();
}
}
@@ -126,7 +129,7 @@ fn report_bad_target(sess: &Session, item: &Annotatable, span: Span) -> bool {
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)