@@ -87,6 +87,7 @@ use parse::{Directory, ParseSess};
87
87
use parse:: parser:: { PathStyle , Parser } ;
88
88
use parse:: token:: { self , DocComment , Token , Nonterminal } ;
89
89
use print:: pprust;
90
+ use symbol:: keywords;
90
91
use tokenstream:: TokenTree ;
91
92
use util:: small_vector:: SmallVector ;
92
93
@@ -201,22 +202,27 @@ pub enum NamedMatch {
201
202
MatchedNonterminal ( Rc < Nonterminal > )
202
203
}
203
204
204
- fn nameize < I : Iterator < Item =Rc < NamedMatch > > > ( ms : & [ quoted:: TokenTree ] , mut res : I )
205
+ fn nameize < I : Iterator < Item =Rc < NamedMatch > > > ( sess : & ParseSess , ms : & [ quoted:: TokenTree ] , mut res : I )
205
206
-> NamedParseResult {
206
207
use self :: quoted:: TokenTree ;
207
208
208
- fn n_rec < I : Iterator < Item =Rc < NamedMatch > > > ( m : & TokenTree , mut res : & mut I ,
209
+ fn n_rec < I : Iterator < Item =Rc < NamedMatch > > > ( sess : & ParseSess , m : & TokenTree , mut res : & mut I ,
209
210
ret_val : & mut HashMap < Ident , Rc < NamedMatch > > )
210
211
-> Result < ( ) , ( syntax_pos:: Span , String ) > {
211
212
match * m {
212
213
TokenTree :: Sequence ( _, ref seq) => {
213
214
for next_m in & seq. tts {
214
- n_rec ( next_m, res. by_ref ( ) , ret_val) ?
215
+ n_rec ( sess , next_m, res. by_ref ( ) , ret_val) ?
215
216
}
216
217
}
217
218
TokenTree :: Delimited ( _, ref delim) => {
218
219
for next_m in & delim. tts {
219
- n_rec ( next_m, res. by_ref ( ) , ret_val) ?;
220
+ n_rec ( sess, next_m, res. by_ref ( ) , ret_val) ?;
221
+ }
222
+ }
223
+ TokenTree :: MetaVarDecl ( span, _, id) if id. name == keywords:: Invalid . name ( ) => {
224
+ if sess. missing_fragment_specifiers . borrow_mut ( ) . remove ( & span) {
225
+ return Err ( ( span, "missing fragment specifier" . to_string ( ) ) ) ;
220
226
}
221
227
}
222
228
TokenTree :: MetaVarDecl ( sp, bind_name, _) => {
@@ -237,7 +243,7 @@ fn nameize<I: Iterator<Item=Rc<NamedMatch>>>(ms: &[quoted::TokenTree], mut res:
237
243
238
244
let mut ret_val = HashMap :: new ( ) ;
239
245
for m in ms {
240
- match n_rec ( m, res. by_ref ( ) , & mut ret_val) {
246
+ match n_rec ( sess , m, res. by_ref ( ) , & mut ret_val) {
241
247
Ok ( _) => { } ,
242
248
Err ( ( sp, msg) ) => return Error ( sp, msg) ,
243
249
}
@@ -277,11 +283,13 @@ fn create_matches(len: usize) -> Vec<Vec<Rc<NamedMatch>>> {
277
283
( 0 ..len) . into_iter ( ) . map ( |_| Vec :: new ( ) ) . collect ( )
278
284
}
279
285
280
- fn inner_parse_loop ( cur_eis : & mut SmallVector < Box < MatcherPos > > ,
286
+ fn inner_parse_loop ( sess : & ParseSess ,
287
+ cur_eis : & mut SmallVector < Box < MatcherPos > > ,
281
288
next_eis : & mut Vec < Box < MatcherPos > > ,
282
289
eof_eis : & mut SmallVector < Box < MatcherPos > > ,
283
290
bb_eis : & mut SmallVector < Box < MatcherPos > > ,
284
- token : & Token , span : & syntax_pos:: Span ) -> ParseResult < ( ) > {
291
+ token : & Token ,
292
+ span : & syntax_pos:: Span ) -> ParseResult < ( ) > {
285
293
use self :: quoted:: TokenTree ;
286
294
287
295
while let Some ( mut ei) = cur_eis. pop ( ) {
@@ -375,6 +383,11 @@ fn inner_parse_loop(cur_eis: &mut SmallVector<Box<MatcherPos>>,
375
383
top_elts : Tt ( TokenTree :: Sequence ( sp, seq) ) ,
376
384
} ) ) ;
377
385
}
386
+ TokenTree :: MetaVarDecl ( span, _, id) if id. name == keywords:: Invalid . name ( ) => {
387
+ if sess. missing_fragment_specifiers . borrow_mut ( ) . remove ( & span) {
388
+ return Error ( span, "missing fragment specifier" . to_string ( ) ) ;
389
+ }
390
+ }
378
391
TokenTree :: MetaVarDecl ( ..) => {
379
392
// Built-in nonterminals never start with these tokens,
380
393
// so we can eliminate them from consideration.
@@ -422,7 +435,7 @@ pub fn parse(sess: &ParseSess,
422
435
let mut eof_eis = SmallVector :: new ( ) ;
423
436
assert ! ( next_eis. is_empty( ) ) ;
424
437
425
- match inner_parse_loop ( & mut cur_eis, & mut next_eis, & mut eof_eis, & mut bb_eis,
438
+ match inner_parse_loop ( sess , & mut cur_eis, & mut next_eis, & mut eof_eis, & mut bb_eis,
426
439
& parser. token , & parser. span ) {
427
440
Success ( _) => { } ,
428
441
Failure ( sp, tok) => return Failure ( sp, tok) ,
@@ -435,7 +448,8 @@ pub fn parse(sess: &ParseSess,
435
448
/* error messages here could be improved with links to orig. rules */
436
449
if token_name_eq ( & parser. token , & token:: Eof ) {
437
450
if eof_eis. len ( ) == 1 {
438
- return nameize ( ms, eof_eis[ 0 ] . matches . iter_mut ( ) . map ( |mut dv| dv. pop ( ) . unwrap ( ) ) ) ;
451
+ let matches = eof_eis[ 0 ] . matches . iter_mut ( ) . map ( |mut dv| dv. pop ( ) . unwrap ( ) ) ;
452
+ return nameize ( sess, ms, matches) ;
439
453
} else if eof_eis. len ( ) > 1 {
440
454
return Error ( parser. span , "ambiguity: multiple successful parses" . to_string ( ) ) ;
441
455
} else {
0 commit comments