@@ -18,7 +18,8 @@ use ext::build::AstBuilder;
18
18
use attr;
19
19
use attr:: { AttrMetaMethods , WithAttrs , ThinAttributesExt } ;
20
20
use codemap;
21
- use codemap:: { Span , Spanned , ExpnInfo , NameAndSpan , MacroBang , MacroAttribute } ;
21
+ use codemap:: { Span , Spanned , ExpnInfo , ExpnId , NameAndSpan , MacroBang , MacroAttribute } ;
22
+ use config:: StripUnconfigured ;
22
23
use ext:: base:: * ;
23
24
use feature_gate:: { self , Features } ;
24
25
use fold;
@@ -33,7 +34,6 @@ use visit::Visitor;
33
34
use std_inject;
34
35
35
36
use std:: collections:: HashSet ;
36
- use std:: env;
37
37
38
38
// A trait for AST nodes and AST node lists into which macro invocations may expand.
39
39
trait MacroGenerable : Sized {
@@ -77,25 +77,35 @@ impl_macro_generable! {
77
77
"statement" , . make_stmts, lift . fold_stmt, |_span| SmallVector :: zero( ) ;
78
78
}
79
79
80
- pub fn expand_expr ( e : P < ast:: Expr > , fld : & mut MacroExpander ) -> P < ast:: Expr > {
81
- return e. and_then ( |ast:: Expr { id, node, span, attrs} | match node {
80
+ impl MacroGenerable for Option < P < ast:: Expr > > {
81
+ fn kind_name ( ) -> & ' static str { "expression" }
82
+ fn dummy ( _span : Span ) -> Self { None }
83
+ fn make_with < ' a > ( result : Box < MacResult + ' a > ) -> Option < Self > {
84
+ result. make_expr ( ) . map ( Some )
85
+ }
86
+ fn fold_with < F : Folder > ( self , folder : & mut F ) -> Self {
87
+ self . and_then ( |expr| folder. fold_opt_expr ( expr) )
88
+ }
89
+ }
82
90
91
+ pub fn expand_expr ( expr : ast:: Expr , fld : & mut MacroExpander ) -> P < ast:: Expr > {
92
+ match expr. node {
83
93
// expr_mac should really be expr_ext or something; it's the
84
94
// entry-point for all syntax extensions.
85
95
ast:: ExprKind :: Mac ( mac) => {
86
- expand_mac_invoc ( mac, None , attrs. into_attr_vec ( ) , span, fld)
96
+ expand_mac_invoc ( mac, None , expr . attrs . into_attr_vec ( ) , expr . span , fld)
87
97
}
88
98
89
99
ast:: ExprKind :: While ( cond, body, opt_ident) => {
90
100
let cond = fld. fold_expr ( cond) ;
91
101
let ( body, opt_ident) = expand_loop_block ( body, opt_ident, fld) ;
92
- fld. cx . expr ( span, ast:: ExprKind :: While ( cond, body, opt_ident) )
93
- . with_attrs ( fold_thin_attrs ( attrs, fld) )
102
+ fld. cx . expr ( expr . span , ast:: ExprKind :: While ( cond, body, opt_ident) )
103
+ . with_attrs ( fold_thin_attrs ( expr . attrs , fld) )
94
104
}
95
105
96
- ast:: ExprKind :: WhileLet ( pat, expr , body, opt_ident) => {
106
+ ast:: ExprKind :: WhileLet ( pat, cond , body, opt_ident) => {
97
107
let pat = fld. fold_pat ( pat) ;
98
- let expr = fld. fold_expr ( expr ) ;
108
+ let cond = fld. fold_expr ( cond ) ;
99
109
100
110
// Hygienic renaming of the body.
101
111
let ( ( body, opt_ident) , mut rewritten_pats) =
@@ -107,14 +117,14 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
107
117
} ) ;
108
118
assert ! ( rewritten_pats. len( ) == 1 ) ;
109
119
110
- let wl = ast:: ExprKind :: WhileLet ( rewritten_pats. remove ( 0 ) , expr , body, opt_ident) ;
111
- fld. cx . expr ( span, wl) . with_attrs ( fold_thin_attrs ( attrs, fld) )
120
+ let wl = ast:: ExprKind :: WhileLet ( rewritten_pats. remove ( 0 ) , cond , body, opt_ident) ;
121
+ fld. cx . expr ( expr . span , wl) . with_attrs ( fold_thin_attrs ( expr . attrs , fld) )
112
122
}
113
123
114
124
ast:: ExprKind :: Loop ( loop_block, opt_ident) => {
115
125
let ( loop_block, opt_ident) = expand_loop_block ( loop_block, opt_ident, fld) ;
116
- fld. cx . expr ( span, ast:: ExprKind :: Loop ( loop_block, opt_ident) )
117
- . with_attrs ( fold_thin_attrs ( attrs, fld) )
126
+ fld. cx . expr ( expr . span , ast:: ExprKind :: Loop ( loop_block, opt_ident) )
127
+ . with_attrs ( fold_thin_attrs ( expr . attrs , fld) )
118
128
}
119
129
120
130
ast:: ExprKind :: ForLoop ( pat, head, body, opt_ident) => {
@@ -132,7 +142,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
132
142
133
143
let head = fld. fold_expr ( head) ;
134
144
let fl = ast:: ExprKind :: ForLoop ( rewritten_pats. remove ( 0 ) , head, body, opt_ident) ;
135
- fld. cx . expr ( span, fl) . with_attrs ( fold_thin_attrs ( attrs, fld) )
145
+ fld. cx . expr ( expr . span , fl) . with_attrs ( fold_thin_attrs ( expr . attrs , fld) )
136
146
}
137
147
138
148
ast:: ExprKind :: IfLet ( pat, sub_expr, body, else_opt) => {
@@ -151,7 +161,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
151
161
let else_opt = else_opt. map ( |else_opt| fld. fold_expr ( else_opt) ) ;
152
162
let sub_expr = fld. fold_expr ( sub_expr) ;
153
163
let il = ast:: ExprKind :: IfLet ( rewritten_pats. remove ( 0 ) , sub_expr, body, else_opt) ;
154
- fld. cx . expr ( span, il) . with_attrs ( fold_thin_attrs ( attrs, fld) )
164
+ fld. cx . expr ( expr . span , il) . with_attrs ( fold_thin_attrs ( expr . attrs , fld) )
155
165
}
156
166
157
167
ast:: ExprKind :: Closure ( capture_clause, fn_decl, block, fn_decl_span) => {
@@ -160,22 +170,15 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
160
170
let new_node = ast:: ExprKind :: Closure ( capture_clause,
161
171
rewritten_fn_decl,
162
172
rewritten_block,
163
- fld . new_span ( fn_decl_span) ) ;
164
- P ( ast:: Expr { id : id,
173
+ fn_decl_span) ;
174
+ P ( ast:: Expr { id : expr . id ,
165
175
node : new_node,
166
- span : fld . new_span ( span) ,
167
- attrs : fold_thin_attrs ( attrs, fld) } )
176
+ span : expr . span ,
177
+ attrs : fold_thin_attrs ( expr . attrs , fld) } )
168
178
}
169
179
170
- _ => {
171
- P ( noop_fold_expr ( ast:: Expr {
172
- id : id,
173
- node : node,
174
- span : span,
175
- attrs : attrs
176
- } , fld) )
177
- }
178
- } ) ;
180
+ _ => P ( noop_fold_expr ( expr, fld) ) ,
181
+ }
179
182
}
180
183
181
184
/// Expand a macro invocation. Returns the result of expansion.
@@ -322,8 +325,9 @@ fn expand_mac_invoc<T>(mac: ast::Mac, ident: Option<Ident>, attrs: Vec<ast::Attr
322
325
return T :: dummy ( span) ;
323
326
} ;
324
327
325
- let marked = expanded. fold_with ( & mut Marker { mark : mark } ) ;
326
- let fully_expanded = marked. fold_with ( fld) ;
328
+ let marked = expanded. fold_with ( & mut Marker { mark : mark, expn_id : Some ( fld. cx . backtrace ( ) ) } ) ;
329
+ let configured = marked. fold_with ( & mut fld. strip_unconfigured ( ) ) ;
330
+ let fully_expanded = configured. fold_with ( fld) ;
327
331
fld. cx . bt_pop ( ) ;
328
332
fully_expanded
329
333
}
@@ -699,12 +703,12 @@ impl<'a> Folder for PatIdentRenamer<'a> {
699
703
mtwt:: apply_renames ( self . renames , ident. ctxt ) ) ;
700
704
let new_node =
701
705
PatKind :: Ident ( binding_mode,
702
- Spanned { span : self . new_span ( sp ) , node : new_ident} ,
706
+ Spanned { span : sp , node : new_ident} ,
703
707
sub. map ( |p| self . fold_pat ( p) ) ) ;
704
708
ast:: Pat {
705
709
id : id,
706
710
node : new_node,
707
- span : self . new_span ( span)
711
+ span : span,
708
712
}
709
713
} ,
710
714
_ => unreachable ! ( )
@@ -774,7 +778,7 @@ fn expand_annotatable(a: Annotatable,
774
778
}
775
779
_ => unreachable ! ( )
776
780
} ,
777
- span : fld . new_span ( ti. span )
781
+ span : ti. span ,
778
782
} )
779
783
}
780
784
_ => fold:: noop_fold_trait_item ( it. unwrap ( ) , fld)
@@ -914,7 +918,7 @@ fn expand_impl_item(ii: ast::ImplItem, fld: &mut MacroExpander)
914
918
}
915
919
_ => unreachable ! ( )
916
920
} ,
917
- span : fld . new_span ( ii. span )
921
+ span : ii. span ,
918
922
} ) ,
919
923
ast:: ImplItemKind :: Macro ( mac) => {
920
924
expand_mac_invoc ( mac, None , ii. attrs , ii. span , fld)
@@ -987,6 +991,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
987
991
pub fn new ( cx : & ' a mut ExtCtxt < ' b > ) -> MacroExpander < ' a , ' b > {
988
992
MacroExpander { cx : cx }
989
993
}
994
+
995
+ fn strip_unconfigured ( & mut self ) -> StripUnconfigured {
996
+ StripUnconfigured :: new ( & self . cx . cfg ,
997
+ & self . cx . parse_sess . span_diagnostic ,
998
+ self . cx . feature_gated_cfgs )
999
+ }
990
1000
}
991
1001
992
1002
impl < ' a , ' b > Folder for MacroExpander < ' a , ' b > {
@@ -996,7 +1006,15 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
996
1006
}
997
1007
998
1008
fn fold_expr ( & mut self , expr : P < ast:: Expr > ) -> P < ast:: Expr > {
999
- expand_expr ( expr, self )
1009
+ expr. and_then ( |expr| expand_expr ( expr, self ) )
1010
+ }
1011
+
1012
+ fn fold_opt_expr ( & mut self , expr : P < ast:: Expr > ) -> Option < P < ast:: Expr > > {
1013
+ expr. and_then ( |expr| match expr. node {
1014
+ ast:: ExprKind :: Mac ( mac) =>
1015
+ expand_mac_invoc ( mac, None , expr. attrs . into_attr_vec ( ) , expr. span , self ) ,
1016
+ _ => Some ( expand_expr ( expr, self ) ) ,
1017
+ } )
1000
1018
}
1001
1019
1002
1020
fn fold_pat ( & mut self , pat : P < ast:: Pat > ) -> P < ast:: Pat > {
@@ -1059,10 +1077,6 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
1059
1077
fn fold_ty ( & mut self , ty : P < ast:: Ty > ) -> P < ast:: Ty > {
1060
1078
expand_type ( ty, self )
1061
1079
}
1062
-
1063
- fn new_span ( & mut self , span : Span ) -> Span {
1064
- new_span ( self . cx , span)
1065
- }
1066
1080
}
1067
1081
1068
1082
impl < ' a , ' b > MacroExpander < ' a , ' b > {
@@ -1080,45 +1094,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
1080
1094
}
1081
1095
}
1082
1096
1083
- fn new_span ( cx : & ExtCtxt , sp : Span ) -> Span {
1084
- debug ! ( "new_span(sp={:?})" , sp) ;
1085
-
1086
- if cx. codemap ( ) . more_specific_trace ( sp. expn_id , cx. backtrace ( ) ) {
1087
- // If the span we are looking at has a backtrace that has more
1088
- // detail than our current backtrace, then we keep that
1089
- // backtrace. Honestly, I have no idea if this makes sense,
1090
- // because I have no idea why we are stripping the backtrace
1091
- // below. But the reason I made this change is because, in
1092
- // deriving, we were generating attributes with a specific
1093
- // backtrace, which was essential for `#[structural_match]` to
1094
- // be properly supported, but these backtraces were being
1095
- // stripped and replaced with a null backtrace. Sort of
1096
- // unclear why this is the case. --nmatsakis
1097
- debug ! ( "new_span: keeping trace from {:?} because it is more specific" ,
1098
- sp. expn_id) ;
1099
- sp
1100
- } else {
1101
- // This discards information in the case of macro-defining macros.
1102
- //
1103
- // The comment above was originally added in
1104
- // b7ec2488ff2f29681fe28691d20fd2c260a9e454 in Feb 2012. I
1105
- // *THINK* the reason we are doing this is because we want to
1106
- // replace the backtrace of the macro contents with the
1107
- // backtrace that contains the macro use. But it's pretty
1108
- // unclear to me. --nmatsakis
1109
- let sp1 = Span {
1110
- lo : sp. lo ,
1111
- hi : sp. hi ,
1112
- expn_id : cx. backtrace ( ) ,
1113
- } ;
1114
- debug ! ( "new_span({:?}) = {:?}" , sp, sp1) ;
1115
- if sp. expn_id . into_u32 ( ) == 0 && env:: var_os ( "NDM" ) . is_some ( ) {
1116
- panic ! ( "NDM" ) ;
1117
- }
1118
- sp1
1119
- }
1120
- }
1121
-
1122
1097
pub struct ExpansionConfig < ' feat > {
1123
1098
pub crate_name : String ,
1124
1099
pub features : Option < & ' feat Features > ,
@@ -1205,8 +1180,9 @@ pub fn expand_crate(mut cx: ExtCtxt,
1205
1180
// the ones defined here include:
1206
1181
// Marker - add a mark to a context
1207
1182
1208
- // A Marker adds the given mark to the syntax context
1209
- struct Marker { mark : Mrk }
1183
+ // A Marker adds the given mark to the syntax context and
1184
+ // sets spans' `expn_id` to the given expn_id (unless it is `None`).
1185
+ struct Marker { mark : Mrk , expn_id : Option < ExpnId > }
1210
1186
1211
1187
impl Folder for Marker {
1212
1188
fn fold_ident ( & mut self , id : Ident ) -> Ident {
@@ -1219,14 +1195,21 @@ impl Folder for Marker {
1219
1195
tts : self . fold_tts ( & node. tts ) ,
1220
1196
ctxt : mtwt:: apply_mark ( self . mark , node. ctxt ) ,
1221
1197
} ,
1222
- span : span,
1198
+ span : self . new_span ( span) ,
1199
+ }
1200
+ }
1201
+
1202
+ fn new_span ( & mut self , mut span : Span ) -> Span {
1203
+ if let Some ( expn_id) = self . expn_id {
1204
+ span. expn_id = expn_id;
1223
1205
}
1206
+ span
1224
1207
}
1225
1208
}
1226
1209
1227
1210
// apply a given mark to the given token trees. Used prior to expansion of a macro.
1228
1211
fn mark_tts ( tts : & [ TokenTree ] , m : Mrk ) -> Vec < TokenTree > {
1229
- noop_fold_tts ( tts, & mut Marker { mark : m} )
1212
+ noop_fold_tts ( tts, & mut Marker { mark : m, expn_id : None } )
1230
1213
}
1231
1214
1232
1215
/// Check that there are no macro invocations left in the AST:
0 commit comments