about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2017-02-02 00:33:42 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2017-02-12 03:22:52 +0000
commit4b413bc393d8cde89ce0d687c3ef4ea50374af2c (patch)
tree458e236cbefa1d346792e21f35017368b64ff9aa
parentba7cf7cc5daefb9f28371b8be87dc262fb55937c (diff)
downloadrust-4b413bc393d8cde89ce0d687c3ef4ea50374af2c.tar.gz
rust-4b413bc393d8cde89ce0d687c3ef4ea50374af2c.zip
Move legacy custom derives collection into `resolver.find_attr_invoc()`.
-rw-r--r--src/librustc_resolve/macros.rs57
-rw-r--r--src/libsyntax/ext/derive.rs36
2 files changed, 56 insertions, 37 deletions
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index ea3112b2463..a1699784b9d 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -27,10 +27,10 @@ use syntax::ext::base::{NormalTT, Resolver as SyntaxResolver, SyntaxExtension};
 use syntax::ext::expand::{Expansion, mark_tts};
 use syntax::ext::hygiene::Mark;
 use syntax::ext::tt::macro_rules;
-use syntax::feature_gate::{emit_feature_err, GateIssue, is_builtin_attr};
+use syntax::feature_gate::{self, emit_feature_err, GateIssue, is_builtin_attr};
 use syntax::fold::{self, Folder};
 use syntax::ptr::P;
-use syntax::symbol::keywords;
+use syntax::symbol::{Symbol, keywords};
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax::visit::Visitor;
 use syntax_pos::{Span, DUMMY_SP};
@@ -188,6 +188,49 @@ impl<'a> base::Resolver for Resolver<'a> {
                 return Some(attrs.remove(i));
             }
         }
+
+        // Check for legacy derives
+        for i in 0..attrs.len() {
+            if attrs[i].name() == "derive" {
+                let mut traits = match attrs[i].meta_item_list() {
+                    Some(traits) if !traits.is_empty() => traits.to_owned(),
+                    _ => continue,
+                };
+
+                for j in 0..traits.len() {
+                    let legacy_name = Symbol::intern(&match traits[j].word() {
+                        Some(..) => format!("derive_{}", traits[j].name().unwrap()),
+                        None => continue,
+                    });
+                    if !self.builtin_macros.contains_key(&legacy_name) {
+                        continue
+                    }
+                    let span = traits.remove(j).span;
+                    self.gate_legacy_custom_derive(legacy_name, span);
+                    if traits.is_empty() {
+                        attrs.remove(i);
+                    } else {
+                        attrs[i].value = ast::MetaItem {
+                            name: attrs[i].name(),
+                            span: span,
+                            node: ast::MetaItemKind::List(traits),
+                        };
+                    }
+                    return Some(ast::Attribute {
+                        value: ast::MetaItem {
+                            name: legacy_name,
+                            span: span,
+                            node: ast::MetaItemKind::Word,
+                        },
+                        id: attr::mk_attr_id(),
+                        style: ast::AttrStyle::Outer,
+                        is_sugared_doc: false,
+                        span: span,
+                    });
+                }
+            }
+        }
+
         None
     }
 
@@ -540,4 +583,14 @@ impl<'a> Resolver<'a> {
                              `use {}::{};`", crate_name, name))
             .emit();
     }
+
+    fn gate_legacy_custom_derive(&mut self, name: Symbol, span: Span) {
+        if !self.session.features.borrow().custom_derive {
+            let sess = &self.session.parse_sess;
+            let explain = feature_gate::EXPLAIN_CUSTOM_DERIVE;
+            emit_feature_err(sess, "custom_derive", span, GateIssue::Language, explain);
+        } else if !self.is_whitelisted_legacy_custom_derive(name) {
+            self.session.span_warn(span, feature_gate::EXPLAIN_DEPR_CUSTOM_DERIVE);
+        }
+    }
 }
diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs
index 946448eaaee..ba14a153ed2 100644
--- a/src/libsyntax/ext/derive.rs
+++ b/src/libsyntax/ext/derive.rs
@@ -13,7 +13,6 @@ use attr;
 use ast::{self, NestedMetaItem}; use ext::base::{ExtCtxt, SyntaxExtension};
 use codemap;
 use ext::build::AstBuilder;
-use feature_gate;
 use symbol::Symbol;
 use syntax_pos::Span;
 
@@ -64,7 +63,6 @@ pub fn verify_derive_attrs(cx: &mut ExtCtxt, attrs: &[ast::Attribute]) {
 
 #[derive(PartialEq, Debug, Clone, Copy)]
 pub enum DeriveType {
-    Legacy,
     ProcMacro,
     Builtin
 }
@@ -72,12 +70,6 @@ pub enum DeriveType {
 impl DeriveType {
     // Classify a derive trait name by resolving the macro.
     pub fn classify(cx: &mut ExtCtxt, tname: Name) -> DeriveType {
-        let legacy_derive_name = Symbol::intern(&format!("derive_{}", tname));
-
-        if let Ok(_) = cx.resolver.resolve_builtin_macro(legacy_derive_name) {
-            return DeriveType::Legacy;
-        }
-
         match cx.resolver.resolve_builtin_macro(tname) {
             Ok(ext) => match *ext {
                 SyntaxExtension::BuiltinDerive(..) => DeriveType::Builtin,
@@ -185,33 +177,7 @@ pub fn add_derived_markers(cx: &mut ExtCtxt, attrs: &mut Vec<ast::Attribute>) {
 pub fn find_derive_attr(cx: &mut ExtCtxt, attrs: &mut Vec<ast::Attribute>)
                         -> Option<ast::Attribute> {
     verify_derive_attrs(cx, attrs);
-    get_derive_attr(cx, attrs, DeriveType::Legacy).and_then(|a| {
-        let titem = derive_attr_trait(cx, &a);
-        titem.and_then(|titem| {
-            let tword = titem.word().unwrap();
-            let tname = tword.name();
-            if !cx.ecfg.enable_custom_derive() {
-                feature_gate::emit_feature_err(
-                    &cx.parse_sess,
-                    "custom_derive",
-                    titem.span,
-                    feature_gate::GateIssue::Language,
-                    feature_gate::EXPLAIN_CUSTOM_DERIVE
-                );
-                None
-            } else {
-                let name = Symbol::intern(&format!("derive_{}", tname));
-                if !cx.resolver.is_whitelisted_legacy_custom_derive(name) {
-                    cx.span_warn(titem.span,
-                                 feature_gate::EXPLAIN_DEPR_CUSTOM_DERIVE);
-                }
-                let mitem = cx.meta_word(titem.span, name);
-                Some(cx.attribute(mitem.span, mitem))
-            }
-        })
-    }).or_else(|| {
-        get_derive_attr(cx, attrs, DeriveType::ProcMacro)
-    }).or_else(|| {
+    get_derive_attr(cx, attrs, DeriveType::ProcMacro).or_else(|| {
         add_derived_markers(cx, attrs);
         get_derive_attr(cx, attrs, DeriveType::Builtin)
     })