1
1
use crate :: cfg_eval:: cfg_eval;
2
2
3
- use rustc_ast:: { self as ast, token, ItemKind , MetaItemKind , NestedMetaItem , StmtKind } ;
3
+ use rustc_ast:: { self as ast, attr , token, ItemKind , MetaItemKind , NestedMetaItem , StmtKind } ;
4
4
use rustc_errors:: { struct_span_err, Applicability } ;
5
5
use rustc_expand:: base:: { Annotatable , ExpandResult , ExtCtxt , Indeterminate , MultiItemModifier } ;
6
6
use rustc_feature:: AttributeTemplate ;
@@ -26,32 +26,39 @@ impl MultiItemModifier for Expander {
26
26
return ExpandResult :: Ready ( vec ! [ item] ) ;
27
27
}
28
28
29
- let template =
30
- AttributeTemplate { list : Some ( "Trait1, Trait2, ..." ) , ..Default :: default ( ) } ;
31
- let attr = ecx. attribute ( meta_item. clone ( ) ) ;
32
- validate_attr:: check_builtin_attribute ( & sess. parse_sess , & attr, sym:: derive, template) ;
29
+ let result =
30
+ ecx. resolver . resolve_derives ( ecx. current_expansion . id , ecx. force_mode , & || {
31
+ let template =
32
+ AttributeTemplate { list : Some ( "Trait1, Trait2, ..." ) , ..Default :: default ( ) } ;
33
+ let attr = attr:: mk_attr_outer ( meta_item. clone ( ) ) ;
34
+ validate_attr:: check_builtin_attribute (
35
+ & sess. parse_sess ,
36
+ & attr,
37
+ sym:: derive,
38
+ template,
39
+ ) ;
33
40
34
- let derives: Vec < _ > = attr
35
- . meta_item_list ( )
36
- . unwrap_or_default ( )
37
- . into_iter ( )
38
- . filter_map ( |nested_meta| match nested_meta {
39
- NestedMetaItem :: MetaItem ( meta) => Some ( meta) ,
40
- NestedMetaItem :: Literal ( lit) => {
41
- // Reject `#[derive("Debug")]`.
42
- report_unexpected_literal ( sess, & lit) ;
43
- None
44
- }
45
- } )
46
- . map ( |meta| {
47
- // Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the paths.
48
- report_path_args ( sess, & meta) ;
49
- meta. path
50
- } )
51
- . collect ( ) ;
41
+ attr. meta_item_list ( )
42
+ . unwrap_or_default ( )
43
+ . into_iter ( )
44
+ . filter_map ( |nested_meta| match nested_meta {
45
+ NestedMetaItem :: MetaItem ( meta) => Some ( meta) ,
46
+ NestedMetaItem :: Literal ( lit) => {
47
+ // Reject `#[derive("Debug")]`.
48
+ report_unexpected_literal ( sess, & lit) ;
49
+ None
50
+ }
51
+ } )
52
+ . map ( |meta| {
53
+ // Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the paths.
54
+ report_path_args ( sess, & meta) ;
55
+ meta. path
56
+ } )
57
+ . map ( |path| ( path, None ) )
58
+ . collect ( )
59
+ } ) ;
52
60
53
- // FIXME: Try to cache intermediate results to avoid collecting same paths multiple times.
54
- match ecx. resolver . resolve_derives ( ecx. current_expansion . id , derives, ecx. force_mode ) {
61
+ match result {
55
62
Ok ( ( ) ) => ExpandResult :: Ready ( cfg_eval ( ecx, item) ) ,
56
63
Err ( Indeterminate ) => ExpandResult :: Retry ( item) ,
57
64
}
0 commit comments