Skip to content

Commit 4b413bc

Browse files
committed
Move legacy custom derives collection into resolver.find_attr_invoc().
1 parent ba7cf7c commit 4b413bc

File tree

2 files changed

+56
-37
lines changed

2 files changed

+56
-37
lines changed

src/librustc_resolve/macros.rs

+55-2
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ use syntax::ext::base::{NormalTT, Resolver as SyntaxResolver, SyntaxExtension};
2727
use syntax::ext::expand::{Expansion, mark_tts};
2828
use syntax::ext::hygiene::Mark;
2929
use syntax::ext::tt::macro_rules;
30-
use syntax::feature_gate::{emit_feature_err, GateIssue, is_builtin_attr};
30+
use syntax::feature_gate::{self, emit_feature_err, GateIssue, is_builtin_attr};
3131
use syntax::fold::{self, Folder};
3232
use syntax::ptr::P;
33-
use syntax::symbol::keywords;
33+
use syntax::symbol::{Symbol, keywords};
3434
use syntax::util::lev_distance::find_best_match_for_name;
3535
use syntax::visit::Visitor;
3636
use syntax_pos::{Span, DUMMY_SP};
@@ -188,6 +188,49 @@ impl<'a> base::Resolver for Resolver<'a> {
188188
return Some(attrs.remove(i));
189189
}
190190
}
191+
192+
// Check for legacy derives
193+
for i in 0..attrs.len() {
194+
if attrs[i].name() == "derive" {
195+
let mut traits = match attrs[i].meta_item_list() {
196+
Some(traits) if !traits.is_empty() => traits.to_owned(),
197+
_ => continue,
198+
};
199+
200+
for j in 0..traits.len() {
201+
let legacy_name = Symbol::intern(&match traits[j].word() {
202+
Some(..) => format!("derive_{}", traits[j].name().unwrap()),
203+
None => continue,
204+
});
205+
if !self.builtin_macros.contains_key(&legacy_name) {
206+
continue
207+
}
208+
let span = traits.remove(j).span;
209+
self.gate_legacy_custom_derive(legacy_name, span);
210+
if traits.is_empty() {
211+
attrs.remove(i);
212+
} else {
213+
attrs[i].value = ast::MetaItem {
214+
name: attrs[i].name(),
215+
span: span,
216+
node: ast::MetaItemKind::List(traits),
217+
};
218+
}
219+
return Some(ast::Attribute {
220+
value: ast::MetaItem {
221+
name: legacy_name,
222+
span: span,
223+
node: ast::MetaItemKind::Word,
224+
},
225+
id: attr::mk_attr_id(),
226+
style: ast::AttrStyle::Outer,
227+
is_sugared_doc: false,
228+
span: span,
229+
});
230+
}
231+
}
232+
}
233+
191234
None
192235
}
193236

@@ -540,4 +583,14 @@ impl<'a> Resolver<'a> {
540583
`use {}::{};`", crate_name, name))
541584
.emit();
542585
}
586+
587+
fn gate_legacy_custom_derive(&mut self, name: Symbol, span: Span) {
588+
if !self.session.features.borrow().custom_derive {
589+
let sess = &self.session.parse_sess;
590+
let explain = feature_gate::EXPLAIN_CUSTOM_DERIVE;
591+
emit_feature_err(sess, "custom_derive", span, GateIssue::Language, explain);
592+
} else if !self.is_whitelisted_legacy_custom_derive(name) {
593+
self.session.span_warn(span, feature_gate::EXPLAIN_DEPR_CUSTOM_DERIVE);
594+
}
595+
}
543596
}

src/libsyntax/ext/derive.rs

+1-35
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use attr;
1313
use ast::{self, NestedMetaItem}; use ext::base::{ExtCtxt, SyntaxExtension};
1414
use codemap;
1515
use ext::build::AstBuilder;
16-
use feature_gate;
1716
use symbol::Symbol;
1817
use syntax_pos::Span;
1918

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

6564
#[derive(PartialEq, Debug, Clone, Copy)]
6665
pub enum DeriveType {
67-
Legacy,
6866
ProcMacro,
6967
Builtin
7068
}
7169

7270
impl DeriveType {
7371
// Classify a derive trait name by resolving the macro.
7472
pub fn classify(cx: &mut ExtCtxt, tname: Name) -> DeriveType {
75-
let legacy_derive_name = Symbol::intern(&format!("derive_{}", tname));
76-
77-
if let Ok(_) = cx.resolver.resolve_builtin_macro(legacy_derive_name) {
78-
return DeriveType::Legacy;
79-
}
80-
8173
match cx.resolver.resolve_builtin_macro(tname) {
8274
Ok(ext) => match *ext {
8375
SyntaxExtension::BuiltinDerive(..) => DeriveType::Builtin,
@@ -185,33 +177,7 @@ pub fn add_derived_markers(cx: &mut ExtCtxt, attrs: &mut Vec<ast::Attribute>) {
185177
pub fn find_derive_attr(cx: &mut ExtCtxt, attrs: &mut Vec<ast::Attribute>)
186178
-> Option<ast::Attribute> {
187179
verify_derive_attrs(cx, attrs);
188-
get_derive_attr(cx, attrs, DeriveType::Legacy).and_then(|a| {
189-
let titem = derive_attr_trait(cx, &a);
190-
titem.and_then(|titem| {
191-
let tword = titem.word().unwrap();
192-
let tname = tword.name();
193-
if !cx.ecfg.enable_custom_derive() {
194-
feature_gate::emit_feature_err(
195-
&cx.parse_sess,
196-
"custom_derive",
197-
titem.span,
198-
feature_gate::GateIssue::Language,
199-
feature_gate::EXPLAIN_CUSTOM_DERIVE
200-
);
201-
None
202-
} else {
203-
let name = Symbol::intern(&format!("derive_{}", tname));
204-
if !cx.resolver.is_whitelisted_legacy_custom_derive(name) {
205-
cx.span_warn(titem.span,
206-
feature_gate::EXPLAIN_DEPR_CUSTOM_DERIVE);
207-
}
208-
let mitem = cx.meta_word(titem.span, name);
209-
Some(cx.attribute(mitem.span, mitem))
210-
}
211-
})
212-
}).or_else(|| {
213-
get_derive_attr(cx, attrs, DeriveType::ProcMacro)
214-
}).or_else(|| {
180+
get_derive_attr(cx, attrs, DeriveType::ProcMacro).or_else(|| {
215181
add_derived_markers(cx, attrs);
216182
get_derive_attr(cx, attrs, DeriveType::Builtin)
217183
})

0 commit comments

Comments
 (0)