Skip to content

Commit

Permalink
Move legacy custom derives collection into resolver.find_attr_invoc().
Browse files Browse the repository at this point in the history
  • Loading branch information
jseyfried committed Feb 12, 2017
1 parent ba7cf7c commit 4b413bc
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 37 deletions.
57 changes: 55 additions & 2 deletions src/librustc_resolve/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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);
}
}
}
36 changes: 1 addition & 35 deletions src/libsyntax/ext/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -64,20 +63,13 @@ pub fn verify_derive_attrs(cx: &mut ExtCtxt, attrs: &[ast::Attribute]) {

#[derive(PartialEq, Debug, Clone, Copy)]
pub enum DeriveType {
Legacy,
ProcMacro,
Builtin
}

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,
Expand Down Expand Up @@ -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)
})
Expand Down

0 comments on commit 4b413bc

Please sign in to comment.