@@ -27,10 +27,10 @@ use syntax::ext::base::{NormalTT, Resolver as SyntaxResolver, SyntaxExtension};
27
27
use syntax:: ext:: expand:: { Expansion , mark_tts} ;
28
28
use syntax:: ext:: hygiene:: Mark ;
29
29
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} ;
31
31
use syntax:: fold:: { self , Folder } ;
32
32
use syntax:: ptr:: P ;
33
- use syntax:: symbol:: keywords;
33
+ use syntax:: symbol:: { Symbol , keywords} ;
34
34
use syntax:: util:: lev_distance:: find_best_match_for_name;
35
35
use syntax:: visit:: Visitor ;
36
36
use syntax_pos:: { Span , DUMMY_SP } ;
@@ -188,6 +188,49 @@ impl<'a> base::Resolver for Resolver<'a> {
188
188
return Some ( attrs. remove ( i) ) ;
189
189
}
190
190
}
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
+
191
234
None
192
235
}
193
236
@@ -540,4 +583,14 @@ impl<'a> Resolver<'a> {
540
583
`use {}::{};`", crate_name, name) )
541
584
. emit ( ) ;
542
585
}
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
+ }
543
596
}
0 commit comments