Move legacy custom derives collection into resolver.find_attr_invoc()
.
This commit is contained in:
parent
ba7cf7cc5d
commit
4b413bc393
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user