1
- use crate :: { ast, attr} ;
2
1
use crate :: edition:: Edition ;
3
- use crate :: ext:: base:: { SyntaxExtension , SyntaxExtensionKind } ;
4
2
use crate :: ext:: base:: { DummyResult , ExtCtxt , MacResult , TTMacroExpander } ;
3
+ use crate :: ext:: base:: { SyntaxExtension , SyntaxExtensionKind } ;
5
4
use crate :: ext:: expand:: { AstFragment , AstFragmentKind } ;
6
5
use crate :: ext:: hygiene:: Transparency ;
7
- use crate :: ext:: tt:: macro_parser:: { Success , Error , Failure } ;
8
- use crate :: ext:: tt:: macro_parser:: { MatchedSeq , MatchedNonterminal } ;
9
6
use crate :: ext:: tt:: macro_parser:: { parse, parse_failure_msg} ;
7
+ use crate :: ext:: tt:: macro_parser:: { Error , Failure , Success } ;
8
+ use crate :: ext:: tt:: macro_parser:: { MatchedNonterminal , MatchedSeq } ;
10
9
use crate :: ext:: tt:: quoted;
11
10
use crate :: ext:: tt:: transcribe:: transcribe;
12
11
use crate :: feature_gate:: Features ;
13
- use crate :: parse:: { Directory , ParseSess } ;
14
12
use crate :: parse:: parser:: Parser ;
15
- use crate :: parse:: token:: { self , Token , NtTT } ;
16
13
use crate :: parse:: token:: TokenKind :: * ;
17
- use crate :: symbol:: { Symbol , kw, sym} ;
14
+ use crate :: parse:: token:: { self , NtTT , Token } ;
15
+ use crate :: parse:: { Directory , ParseSess } ;
16
+ use crate :: symbol:: { kw, sym, Symbol } ;
18
17
use crate :: tokenstream:: { DelimSpan , TokenStream , TokenTree } ;
18
+ use crate :: { ast, attr} ;
19
19
20
20
use errors:: FatalError ;
21
- use syntax_pos:: { Span , symbol:: Ident } ;
22
21
use log:: debug;
22
+ use syntax_pos:: { symbol:: Ident , Span } ;
23
23
24
- use rustc_data_structures:: fx:: { FxHashMap } ;
24
+ use rustc_data_structures:: fx:: FxHashMap ;
25
25
use std:: borrow:: Cow ;
26
26
use std:: collections:: hash_map:: Entry ;
27
27
use std:: slice;
28
28
29
- use rustc_data_structures:: sync:: Lrc ;
30
29
use errors:: Applicability ;
30
+ use rustc_data_structures:: sync:: Lrc ;
31
31
32
32
const VALID_FRAGMENT_NAMES_MSG : & str = "valid fragment specifiers are \
33
- `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal `, \
34
- `path`, `meta`, `tt`, `item` and `vis`";
33
+ `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \
34
+ `literal`, `path`, `meta`, `tt`, `item` and `vis`";
35
35
36
36
pub struct ParserAnyMacro < ' a > {
37
37
parser : Parser < ' a > ,
@@ -48,7 +48,8 @@ impl<'a> ParserAnyMacro<'a> {
48
48
let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = * self ;
49
49
let fragment = panictry ! ( parser. parse_ast_fragment( kind, true ) . map_err( |mut e| {
50
50
if parser. token == token:: Eof && e. message( ) . ends_with( ", found `<eof>`" ) {
51
- if !e. span. is_dummy( ) { // early end of macro arm (#52866)
51
+ if !e. span. is_dummy( ) {
52
+ // early end of macro arm (#52866)
52
53
e. replace_span_with( parser. sess. source_map( ) . next_point( parser. token. span) ) ;
53
54
}
54
55
let msg = & e. message[ 0 ] ;
@@ -60,7 +61,8 @@ impl<'a> ParserAnyMacro<'a> {
60
61
msg. 1 ,
61
62
) ;
62
63
}
63
- if e. span. is_dummy( ) { // Get around lack of span in error (#30128)
64
+ if e. span. is_dummy( ) {
65
+ // Get around lack of span in error (#30128)
64
66
e. replace_span_with( site_span) ;
65
67
if parser. sess. source_map( ) . span_to_filename( arm_span) . is_real( ) {
66
68
e. span_label( arm_span, "in this macro arm" ) ;
@@ -99,17 +101,11 @@ impl TTMacroExpander for MacroRulesMacroExpander {
99
101
sp : Span ,
100
102
input : TokenStream ,
101
103
def_span : Option < Span > ,
102
- ) -> Box < dyn MacResult + ' cx > {
104
+ ) -> Box < dyn MacResult + ' cx > {
103
105
if !self . valid {
104
106
return DummyResult :: any ( sp) ;
105
107
}
106
- generic_extension ( cx,
107
- sp,
108
- def_span,
109
- self . name ,
110
- input,
111
- & self . lhses ,
112
- & self . rhses )
108
+ generic_extension ( cx, sp, def_span, self . name , input, & self . lhses , & self . rhses )
113
109
}
114
110
}
115
111
@@ -119,25 +115,27 @@ fn trace_macros_note(cx: &mut ExtCtxt<'_>, sp: Span, message: String) {
119
115
}
120
116
121
117
/// Given `lhses` and `rhses`, this is the new macro we create
122
- fn generic_extension < ' cx > ( cx : & ' cx mut ExtCtxt < ' _ > ,
123
- sp : Span ,
124
- def_span : Option < Span > ,
125
- name : ast:: Ident ,
126
- arg : TokenStream ,
127
- lhses : & [ quoted:: TokenTree ] ,
128
- rhses : & [ quoted:: TokenTree ] )
129
- -> Box < dyn MacResult +' cx > {
118
+ fn generic_extension < ' cx > (
119
+ cx : & ' cx mut ExtCtxt < ' _ > ,
120
+ sp : Span ,
121
+ def_span : Option < Span > ,
122
+ name : ast:: Ident ,
123
+ arg : TokenStream ,
124
+ lhses : & [ quoted:: TokenTree ] ,
125
+ rhses : & [ quoted:: TokenTree ] ,
126
+ ) -> Box < dyn MacResult + ' cx > {
130
127
if cx. trace_macros ( ) {
131
128
trace_macros_note ( cx, sp, format ! ( "expanding `{}! {{ {} }}`" , name, arg) ) ;
132
129
}
133
130
134
131
// Which arm's failure should we report? (the one furthest along)
135
132
let mut best_failure: Option < ( Token , & str ) > = None ;
136
133
137
- for ( i, lhs) in lhses. iter ( ) . enumerate ( ) { // try each arm's matchers
134
+ for ( i, lhs) in lhses. iter ( ) . enumerate ( ) {
135
+ // try each arm's matchers
138
136
let lhs_tt = match * lhs {
139
137
quoted:: TokenTree :: Delimited ( _, ref delim) => & delim. tts [ ..] ,
140
- _ => cx. span_bug ( sp, "malformed macro lhs" )
138
+ _ => cx. span_bug ( sp, "malformed macro lhs" ) ,
141
139
} ;
142
140
143
141
match TokenTree :: parse ( cx, lhs_tt, arg. clone ( ) ) {
@@ -173,8 +171,8 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt<'_>,
173
171
ownership : cx. current_expansion . directory_ownership ,
174
172
} ;
175
173
let mut p = Parser :: new ( cx. parse_sess ( ) , tts, Some ( directory) , true , false , None ) ;
176
- p. root_module_name = cx . current_expansion . module . mod_path . last ( )
177
- . map ( |id| id. as_str ( ) . to_string ( ) ) ;
174
+ p. root_module_name =
175
+ cx . current_expansion . module . mod_path . last ( ) . map ( |id| id. as_str ( ) . to_string ( ) ) ;
178
176
179
177
p. process_potential_macro_variable ( ) ;
180
178
// Let the context choose how to interpret the result.
@@ -188,15 +186,13 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt<'_>,
188
186
site_span : sp,
189
187
macro_ident : name,
190
188
arm_span,
191
- } )
189
+ } ) ;
192
190
}
193
191
Failure ( token, msg) => match best_failure {
194
192
Some ( ( ref best_token, _) ) if best_token. span . lo ( ) >= token. span . lo ( ) => { }
195
- _ => best_failure = Some ( ( token, msg) )
196
- }
197
- Error ( err_sp, ref msg) => {
198
- cx. span_fatal ( err_sp. substitute_dummy ( sp) , & msg[ ..] )
199
- }
193
+ _ => best_failure = Some ( ( token, msg) ) ,
194
+ } ,
195
+ Error ( err_sp, ref msg) => cx. span_fatal ( err_sp. substitute_dummy ( sp) , & msg[ ..] ) ,
200
196
}
201
197
}
202
198
@@ -212,7 +208,8 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt<'_>,
212
208
213
209
// Check whether there's a missing comma in this macro call, like `println!("{}" a);`
214
210
if let Some ( ( arg, comma_span) ) = arg. add_comma ( ) {
215
- for lhs in lhses { // try each arm's matchers
211
+ for lhs in lhses {
212
+ // try each arm's matchers
216
213
let lhs_tt = match * lhs {
217
214
quoted:: TokenTree :: Delimited ( _, ref delim) => & delim. tts [ ..] ,
218
215
_ => continue ,
@@ -249,7 +246,7 @@ pub fn compile(
249
246
sess : & ParseSess ,
250
247
features : & Features ,
251
248
def : & ast:: Item ,
252
- edition : Edition
249
+ edition : Edition ,
253
250
) -> SyntaxExtension {
254
251
let lhs_nm = ast:: Ident :: new ( sym:: lhs, def. span ) ;
255
252
let rhs_nm = ast:: Ident :: new ( sym:: rhs, def. span ) ;
@@ -267,25 +264,32 @@ pub fn compile(
267
264
// ...quasiquoting this would be nice.
268
265
// These spans won't matter, anyways
269
266
let argument_gram = vec ! [
270
- quoted:: TokenTree :: Sequence ( DelimSpan :: dummy( ) , Lrc :: new( quoted:: SequenceRepetition {
271
- tts: vec![
272
- quoted:: TokenTree :: MetaVarDecl ( def. span, lhs_nm, tt_spec) ,
273
- quoted:: TokenTree :: token( token:: FatArrow , def. span) ,
274
- quoted:: TokenTree :: MetaVarDecl ( def. span, rhs_nm, tt_spec) ,
275
- ] ,
276
- separator: Some ( Token :: new(
277
- if body. legacy { token:: Semi } else { token:: Comma } , def. span
278
- ) ) ,
279
- op: quoted:: KleeneOp :: OneOrMore ,
280
- num_captures: 2 ,
281
- } ) ) ,
267
+ quoted:: TokenTree :: Sequence (
268
+ DelimSpan :: dummy( ) ,
269
+ Lrc :: new( quoted:: SequenceRepetition {
270
+ tts: vec![
271
+ quoted:: TokenTree :: MetaVarDecl ( def. span, lhs_nm, tt_spec) ,
272
+ quoted:: TokenTree :: token( token:: FatArrow , def. span) ,
273
+ quoted:: TokenTree :: MetaVarDecl ( def. span, rhs_nm, tt_spec) ,
274
+ ] ,
275
+ separator: Some ( Token :: new(
276
+ if body. legacy { token:: Semi } else { token:: Comma } ,
277
+ def. span,
278
+ ) ) ,
279
+ op: quoted:: KleeneOp :: OneOrMore ,
280
+ num_captures: 2 ,
281
+ } ) ,
282
+ ) ,
282
283
// to phase into semicolon-termination instead of semicolon-separation
283
- quoted:: TokenTree :: Sequence ( DelimSpan :: dummy( ) , Lrc :: new( quoted:: SequenceRepetition {
284
- tts: vec![ quoted:: TokenTree :: token( token:: Semi , def. span) ] ,
285
- separator: None ,
286
- op: quoted:: KleeneOp :: ZeroOrMore ,
287
- num_captures: 0
288
- } ) ) ,
284
+ quoted:: TokenTree :: Sequence (
285
+ DelimSpan :: dummy( ) ,
286
+ Lrc :: new( quoted:: SequenceRepetition {
287
+ tts: vec![ quoted:: TokenTree :: token( token:: Semi , def. span) ] ,
288
+ separator: None ,
289
+ op: quoted:: KleeneOp :: ZeroOrMore ,
290
+ num_captures: 0 ,
291
+ } ) ,
292
+ ) ,
289
293
] ;
290
294
291
295
let argument_map = match parse ( sess, body. stream ( ) , & argument_gram, None , true ) {
@@ -307,8 +311,9 @@ pub fn compile(
307
311
308
312
// Extract the arguments:
309
313
let lhses = match * argument_map[ & lhs_nm] {
310
- MatchedSeq ( ref s, _) => {
311
- s. iter ( ) . map ( |m| {
314
+ MatchedSeq ( ref s, _) => s
315
+ . iter ( )
316
+ . map ( |m| {
312
317
if let MatchedNonterminal ( ref nt) = * m {
313
318
if let NtTT ( ref tt) = * * nt {
314
319
let tt = quoted:: parse (
@@ -327,14 +332,15 @@ pub fn compile(
327
332
}
328
333
}
329
334
sess. span_diagnostic . span_bug ( def. span , "wrong-structured lhs" )
330
- } ) . collect :: < Vec < quoted :: TokenTree > > ( )
331
- }
332
- _ => sess. span_diagnostic . span_bug ( def. span , "wrong-structured lhs" )
335
+ } )
336
+ . collect :: < Vec < quoted :: TokenTree > > ( ) ,
337
+ _ => sess. span_diagnostic . span_bug ( def. span , "wrong-structured lhs" ) ,
333
338
} ;
334
339
335
340
let rhses = match * argument_map[ & rhs_nm] {
336
- MatchedSeq ( ref s, _) => {
337
- s. iter ( ) . map ( |m| {
341
+ MatchedSeq ( ref s, _) => s
342
+ . iter ( )
343
+ . map ( |m| {
338
344
if let MatchedNonterminal ( ref nt) = * m {
339
345
if let NtTT ( ref tt) = * * nt {
340
346
return quoted:: parse (
@@ -345,14 +351,15 @@ pub fn compile(
345
351
& def. attrs ,
346
352
edition,
347
353
def. id ,
348
- ) . pop ( )
349
- . unwrap ( ) ;
354
+ )
355
+ . pop ( )
356
+ . unwrap ( ) ;
350
357
}
351
358
}
352
359
sess. span_diagnostic . span_bug ( def. span , "wrong-structured lhs" )
353
- } ) . collect :: < Vec < quoted :: TokenTree > > ( )
354
- }
355
- _ => sess. span_diagnostic . span_bug ( def. span , "wrong-structured rhs" )
360
+ } )
361
+ . collect :: < Vec < quoted :: TokenTree > > ( ) ,
362
+ _ => sess. span_diagnostic . span_bug ( def. span , "wrong-structured rhs" ) ,
356
363
} ;
357
364
358
365
for rhs in & rhses {
@@ -366,16 +373,12 @@ pub fn compile(
366
373
sess,
367
374
slice:: from_ref ( lhs) ,
368
375
& mut FxHashMap :: default ( ) ,
369
- def. id
376
+ def. id ,
370
377
) ;
371
378
}
372
379
373
- let expander: Box < _ > = Box :: new ( MacroRulesMacroExpander {
374
- name : def. ident ,
375
- lhses,
376
- rhses,
377
- valid,
378
- } ) ;
380
+ let expander: Box < _ > =
381
+ Box :: new ( MacroRulesMacroExpander { name : def. ident , lhses, rhses, valid } ) ;
379
382
380
383
let default_transparency = if attr:: contains_name ( & def. attrs , sym:: rustc_transparent_macro) {
381
384
Transparency :: Transparent
@@ -385,29 +388,34 @@ pub fn compile(
385
388
Transparency :: Opaque
386
389
} ;
387
390
388
- let allow_internal_unstable = attr:: find_by_name ( & def. attrs , sym:: allow_internal_unstable)
389
- . map ( |attr| attr
390
- . meta_item_list ( )
391
- . map ( |list| list. iter ( )
392
- . filter_map ( |it| {
393
- let name = it. ident ( ) . map ( |ident| ident. name ) ;
394
- if name. is_none ( ) {
395
- sess. span_diagnostic . span_err ( it. span ( ) ,
396
- "allow internal unstable expects feature names" )
397
- }
398
- name
391
+ let allow_internal_unstable =
392
+ attr:: find_by_name ( & def. attrs , sym:: allow_internal_unstable) . map ( |attr| {
393
+ attr. meta_item_list ( )
394
+ . map ( |list| {
395
+ list. iter ( )
396
+ . filter_map ( |it| {
397
+ let name = it. ident ( ) . map ( |ident| ident. name ) ;
398
+ if name. is_none ( ) {
399
+ sess. span_diagnostic . span_err (
400
+ it. span ( ) ,
401
+ "allow internal unstable expects feature names" ,
402
+ )
403
+ }
404
+ name
405
+ } )
406
+ . collect :: < Vec < Symbol > > ( )
407
+ . into ( )
399
408
} )
400
- . collect :: < Vec < Symbol > > ( ) . into ( )
401
- )
402
- . unwrap_or_else ( || {
403
- sess. span_diagnostic . span_warn (
404
- attr. span , "allow_internal_unstable expects list of feature names. In the \
405
- future this will become a hard error. Please use `allow_internal_unstable(\
406
- foo, bar)` to only allow the `foo` and `bar` features",
407
- ) ;
408
- vec ! [ sym:: allow_internal_unstable_backcompat_hack] . into ( )
409
- } )
410
- ) ;
409
+ . unwrap_or_else ( || {
410
+ sess. span_diagnostic . span_warn (
411
+ attr. span ,
412
+ "allow_internal_unstable expects list of feature names. In the \
413
+ future this will become a hard error. Please use `allow_internal_unstable(\
414
+ foo, bar)` to only allow the `foo` and `bar` features",
415
+ ) ;
416
+ vec ! [ sym:: allow_internal_unstable_backcompat_hack] . into ( )
417
+ } )
418
+ } ) ;
411
419
412
420
let allow_internal_unsafe = attr:: contains_name ( & def. attrs , sym:: allow_internal_unsafe) ;
413
421
@@ -418,14 +426,14 @@ pub fn compile(
418
426
}
419
427
}
420
428
421
- let unstable_feature = attr :: find_stability ( & sess ,
422
- & def. attrs , def. span ) . and_then ( |stability| {
423
- if let attr:: StabilityLevel :: Unstable { issue, .. } = stability. level {
424
- Some ( ( stability. feature , issue) )
425
- } else {
426
- None
427
- }
428
- } ) ;
429
+ let unstable_feature =
430
+ attr :: find_stability ( & sess , & def. attrs , def. span ) . and_then ( |stability| {
431
+ if let attr:: StabilityLevel :: Unstable { issue, .. } = stability. level {
432
+ Some ( ( stability. feature , issue) )
433
+ } else {
434
+ None
435
+ }
436
+ } ) ;
429
437
430
438
SyntaxExtension {
431
439
kind : SyntaxExtensionKind :: LegacyBang ( expander) ,
@@ -440,10 +448,12 @@ pub fn compile(
440
448
}
441
449
}
442
450
443
- fn check_lhs_nt_follows ( sess : & ParseSess ,
444
- features : & Features ,
445
- attrs : & [ ast:: Attribute ] ,
446
- lhs : & quoted:: TokenTree ) -> bool {
451
+ fn check_lhs_nt_follows (
452
+ sess : & ParseSess ,
453
+ features : & Features ,
454
+ attrs : & [ ast:: Attribute ] ,
455
+ lhs : & quoted:: TokenTree ,
456
+ ) -> bool {
447
457
// lhs is going to be like TokenTree::Delimited(...), where the
448
458
// entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens.
449
459
if let quoted:: TokenTree :: Delimited ( _, ref tts) = * lhs {
@@ -464,19 +474,22 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[quoted::TokenTree]) -> bool {
464
474
for tt in tts {
465
475
match * tt {
466
476
TokenTree :: Token ( ..) | TokenTree :: MetaVar ( ..) | TokenTree :: MetaVarDecl ( ..) => ( ) ,
467
- TokenTree :: Delimited ( _, ref del) => if !check_lhs_no_empty_seq ( sess, & del. tts ) {
468
- return false ;
469
- } ,
477
+ TokenTree :: Delimited ( _, ref del) => {
478
+ if !check_lhs_no_empty_seq ( sess, & del. tts ) {
479
+ return false ;
480
+ }
481
+ }
470
482
TokenTree :: Sequence ( span, ref seq) => {
471
- if seq. separator . is_none ( ) && seq . tts . iter ( ) . all ( |seq_tt| {
472
- match * seq_tt {
483
+ if seq. separator . is_none ( )
484
+ && seq . tts . iter ( ) . all ( |seq_tt| match * seq_tt {
473
485
TokenTree :: MetaVarDecl ( _, _, id) => id. name == sym:: vis,
474
- TokenTree :: Sequence ( _, ref sub_seq) =>
486
+ TokenTree :: Sequence ( _, ref sub_seq) => {
475
487
sub_seq. op == quoted:: KleeneOp :: ZeroOrMore
476
- || sub_seq. op == quoted:: KleeneOp :: ZeroOrOne ,
488
+ || sub_seq. op == quoted:: KleeneOp :: ZeroOrOne
489
+ }
477
490
_ => false ,
478
- }
479
- } ) {
491
+ } )
492
+ {
480
493
let sp = span. entire ( ) ;
481
494
sess. span_diagnostic . span_err ( sp, "repetition matches empty token tree" ) ;
482
495
return false ;
@@ -517,7 +530,7 @@ fn check_lhs_duplicate_matcher_bindings(
517
530
if !check_lhs_duplicate_matcher_bindings ( sess, & del. tts , metavar_names, node_id) {
518
531
return false ;
519
532
}
520
- } ,
533
+ }
521
534
TokenTree :: Sequence ( _, ref seq) => {
522
535
if !check_lhs_duplicate_matcher_bindings ( sess, & seq. tts , metavar_names, node_id) {
523
536
return false ;
@@ -533,15 +546,17 @@ fn check_lhs_duplicate_matcher_bindings(
533
546
fn check_rhs ( sess : & ParseSess , rhs : & quoted:: TokenTree ) -> bool {
534
547
match * rhs {
535
548
quoted:: TokenTree :: Delimited ( ..) => return true ,
536
- _ => sess. span_diagnostic . span_err ( rhs. span ( ) , "macro rhs must be delimited" )
549
+ _ => sess. span_diagnostic . span_err ( rhs. span ( ) , "macro rhs must be delimited" ) ,
537
550
}
538
551
false
539
552
}
540
553
541
- fn check_matcher ( sess : & ParseSess ,
542
- features : & Features ,
543
- attrs : & [ ast:: Attribute ] ,
544
- matcher : & [ quoted:: TokenTree ] ) -> bool {
554
+ fn check_matcher (
555
+ sess : & ParseSess ,
556
+ features : & Features ,
557
+ attrs : & [ ast:: Attribute ] ,
558
+ matcher : & [ quoted:: TokenTree ] ,
559
+ ) -> bool {
545
560
let first_sets = FirstSets :: new ( matcher) ;
546
561
let empty_suffix = TokenSet :: empty ( ) ;
547
562
let err = sess. span_diagnostic . err_count ( ) ;
@@ -620,8 +635,8 @@ impl FirstSets {
620
635
621
636
// Reverse scan: Sequence comes before `first`.
622
637
if subfirst. maybe_empty
623
- || seq_rep. op == quoted:: KleeneOp :: ZeroOrMore
624
- || seq_rep. op == quoted:: KleeneOp :: ZeroOrOne
638
+ || seq_rep. op == quoted:: KleeneOp :: ZeroOrMore
639
+ || seq_rep. op == quoted:: KleeneOp :: ZeroOrOne
625
640
{
626
641
// If sequence is potentially empty, then
627
642
// union them (preserving first emptiness).
@@ -659,7 +674,6 @@ impl FirstSets {
659
674
TokenTree :: Sequence ( sp, ref seq_rep) => {
660
675
match self . first . get ( & sp. entire ( ) ) {
661
676
Some ( & Some ( ref subfirst) ) => {
662
-
663
677
// If the sequence contents can be empty, then the first
664
678
// token could be the separator token itself.
665
679
@@ -670,8 +684,8 @@ impl FirstSets {
670
684
assert ! ( first. maybe_empty) ;
671
685
first. add_all ( subfirst) ;
672
686
if subfirst. maybe_empty
673
- || seq_rep. op == quoted:: KleeneOp :: ZeroOrMore
674
- || seq_rep. op == quoted:: KleeneOp :: ZeroOrOne
687
+ || seq_rep. op == quoted:: KleeneOp :: ZeroOrMore
688
+ || seq_rep. op == quoted:: KleeneOp :: ZeroOrOne
675
689
{
676
690
// continue scanning for more first
677
691
// tokens, but also make sure we
@@ -720,7 +734,9 @@ struct TokenSet {
720
734
721
735
impl TokenSet {
722
736
// Returns a set for the empty sequence.
723
- fn empty ( ) -> Self { TokenSet { tokens : Vec :: new ( ) , maybe_empty : true } }
737
+ fn empty ( ) -> Self {
738
+ TokenSet { tokens : Vec :: new ( ) , maybe_empty : true }
739
+ }
724
740
725
741
// Returns the set `{ tok }` for the single-token (and thus
726
742
// non-empty) sequence [tok].
@@ -789,12 +805,14 @@ impl TokenSet {
789
805
//
790
806
// Requires that `first_sets` is pre-computed for `matcher`;
791
807
// see `FirstSets::new`.
792
- fn check_matcher_core ( sess : & ParseSess ,
793
- features : & Features ,
794
- attrs : & [ ast:: Attribute ] ,
795
- first_sets : & FirstSets ,
796
- matcher : & [ quoted:: TokenTree ] ,
797
- follow : & TokenSet ) -> TokenSet {
808
+ fn check_matcher_core (
809
+ sess : & ParseSess ,
810
+ features : & Features ,
811
+ attrs : & [ ast:: Attribute ] ,
812
+ first_sets : & FirstSets ,
813
+ matcher : & [ quoted:: TokenTree ] ,
814
+ follow : & TokenSet ,
815
+ ) -> TokenSet {
798
816
use quoted:: TokenTree ;
799
817
800
818
let mut last = TokenSet :: empty ( ) ;
@@ -804,11 +822,13 @@ fn check_matcher_core(sess: &ParseSess,
804
822
// then ensure T can also be followed by any element of FOLLOW.
805
823
' each_token: for i in 0 ..matcher. len ( ) {
806
824
let token = & matcher[ i] ;
807
- let suffix = & matcher[ i+ 1 ..] ;
825
+ let suffix = & matcher[ i + 1 ..] ;
808
826
809
827
let build_suffix_first = || {
810
828
let mut s = first_sets. first ( suffix) ;
811
- if s. maybe_empty { s. add_all ( follow) ; }
829
+ if s. maybe_empty {
830
+ s. add_all ( follow) ;
831
+ }
812
832
s
813
833
} ;
814
834
@@ -824,7 +844,8 @@ fn check_matcher_core(sess: &ParseSess,
824
844
let can_be_followed_by_any;
825
845
if let Err ( bad_frag) = has_legal_fragment_specifier ( sess, features, attrs, token) {
826
846
let msg = format ! ( "invalid fragment specifier `{}`" , bad_frag) ;
827
- sess. span_diagnostic . struct_span_err ( token. span ( ) , & msg)
847
+ sess. span_diagnostic
848
+ . struct_span_err ( token. span ( ) , & msg)
828
849
. help ( VALID_FRAGMENT_NAMES_MSG )
829
850
. emit ( ) ;
830
851
// (This eliminates false positives and duplicates
@@ -879,12 +900,8 @@ fn check_matcher_core(sess: &ParseSess,
879
900
// At this point, `suffix_first` is built, and
880
901
// `my_suffix` is some TokenSet that we can use
881
902
// for checking the interior of `seq_rep`.
882
- let next = check_matcher_core ( sess,
883
- features,
884
- attrs,
885
- first_sets,
886
- & seq_rep. tts ,
887
- my_suffix) ;
903
+ let next =
904
+ check_matcher_core ( sess, features, attrs, first_sets, & seq_rep. tts , my_suffix) ;
888
905
if next. maybe_empty {
889
906
last. add_all ( & next) ;
890
907
} else {
@@ -906,16 +923,17 @@ fn check_matcher_core(sess: &ParseSess,
906
923
for next_token in & suffix_first. tokens {
907
924
match is_in_follow ( next_token, & frag_spec. as_str ( ) ) {
908
925
IsInFollow :: Invalid ( msg, help) => {
909
- sess. span_diagnostic . struct_span_err ( next_token. span ( ) , & msg)
910
- . help ( help) . emit ( ) ;
926
+ sess. span_diagnostic
927
+ . struct_span_err ( next_token. span ( ) , & msg)
928
+ . help ( help)
929
+ . emit ( ) ;
911
930
// don't bother reporting every source of
912
931
// conflict for a particular element of `last`.
913
932
continue ' each_last;
914
933
}
915
934
IsInFollow :: Yes => { }
916
935
IsInFollow :: No ( possible) => {
917
- let may_be = if last. tokens . len ( ) == 1 &&
918
- suffix_first. tokens . len ( ) == 1
936
+ let may_be = if last. tokens . len ( ) == 1 && suffix_first. tokens . len ( ) == 1
919
937
{
920
938
"is"
921
939
} else {
@@ -925,12 +943,14 @@ fn check_matcher_core(sess: &ParseSess,
925
943
let sp = next_token. span ( ) ;
926
944
let mut err = sess. span_diagnostic . struct_span_err (
927
945
sp,
928
- & format ! ( "`${name}:{frag}` {may_be} followed by `{next}`, which \
929
- is not allowed for `{frag}` fragments",
930
- name=name,
931
- frag=frag_spec,
932
- next=quoted_tt_to_string( next_token) ,
933
- may_be=may_be) ,
946
+ & format ! (
947
+ "`${name}:{frag}` {may_be} followed by `{next}`, which \
948
+ is not allowed for `{frag}` fragments",
949
+ name = name,
950
+ frag = frag_spec,
951
+ next = quoted_tt_to_string( next_token) ,
952
+ may_be = may_be
953
+ ) ,
934
954
) ;
935
955
err. span_label (
936
956
sp,
@@ -942,16 +962,18 @@ fn check_matcher_core(sess: &ParseSess,
942
962
& [ t] => {
943
963
err. note ( & format ! (
944
964
"only {} is allowed after `{}` fragments" ,
945
- t,
946
- frag_spec,
965
+ t, frag_spec,
947
966
) ) ;
948
967
}
949
968
ts => {
950
969
err. note ( & format ! (
951
970
"{}{} or {}" ,
952
971
msg,
953
- ts[ ..ts. len( ) - 1 ] . iter( ) . map( |s| * s)
954
- . collect:: <Vec <_>>( ) . join( ", " ) ,
972
+ ts[ ..ts. len( ) - 1 ]
973
+ . iter( )
974
+ . map( |s| * s)
975
+ . collect:: <Vec <_>>( )
976
+ . join( ", " ) ,
955
977
ts[ ts. len( ) - 1 ] ,
956
978
) ) ;
957
979
}
@@ -1026,13 +1048,13 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> IsInFollow {
1026
1048
// since items *must* be followed by either a `;` or a `}`, we can
1027
1049
// accept anything after them
1028
1050
IsInFollow :: Yes
1029
- } ,
1051
+ }
1030
1052
"block" => {
1031
1053
// anything can follow block, the braces provide an easy boundary to
1032
1054
// maintain
1033
1055
IsInFollow :: Yes
1034
- } ,
1035
- "stmt" | "expr" => {
1056
+ }
1057
+ "stmt" | "expr" => {
1036
1058
const TOKENS : & [ & str ] = & [ "`=>`" , "`,`" , "`;`" ] ;
1037
1059
match tok {
1038
1060
TokenTree :: Token ( token) => match token. kind {
@@ -1041,7 +1063,7 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> IsInFollow {
1041
1063
} ,
1042
1064
_ => IsInFollow :: No ( TOKENS ) ,
1043
1065
}
1044
- } ,
1066
+ }
1045
1067
"pat" => {
1046
1068
const TOKENS : & [ & str ] = & [ "`=>`" , "`,`" , "`=`" , "`|`" , "`if`" , "`in`" ] ;
1047
1069
match tok {
@@ -1052,71 +1074,88 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> IsInFollow {
1052
1074
} ,
1053
1075
_ => IsInFollow :: No ( TOKENS ) ,
1054
1076
}
1055
- } ,
1077
+ }
1056
1078
"path" | "ty" => {
1057
1079
const TOKENS : & [ & str ] = & [
1058
- "`{`" , "`[`" , "`=>`" , "`,`" , "`>`" , "`=`" , "`:`" , "`;`" , "`|`" , "`as`" ,
1080
+ "`{`" , "`[`" , "`=>`" , "`,`" , "`>`" , "`=`" , "`:`" , "`;`" , "`|`" , "`as`" ,
1059
1081
"`where`" ,
1060
1082
] ;
1061
1083
match tok {
1062
1084
TokenTree :: Token ( token) => match token. kind {
1063
- OpenDelim ( token:: DelimToken :: Brace ) |
1064
- OpenDelim ( token:: DelimToken :: Bracket ) |
1065
- Comma | FatArrow | Colon | Eq | Gt | BinOp ( token:: Shr ) | Semi |
1066
- BinOp ( token:: Or ) => IsInFollow :: Yes ,
1067
- Ident ( name, false ) if name == kw:: As ||
1068
- name == kw:: Where => IsInFollow :: Yes ,
1085
+ OpenDelim ( token:: DelimToken :: Brace )
1086
+ | OpenDelim ( token:: DelimToken :: Bracket )
1087
+ | Comma
1088
+ | FatArrow
1089
+ | Colon
1090
+ | Eq
1091
+ | Gt
1092
+ | BinOp ( token:: Shr )
1093
+ | Semi
1094
+ | BinOp ( token:: Or ) => IsInFollow :: Yes ,
1095
+ Ident ( name, false ) if name == kw:: As || name == kw:: Where => {
1096
+ IsInFollow :: Yes
1097
+ }
1069
1098
_ => IsInFollow :: No ( TOKENS ) ,
1070
1099
} ,
1071
- TokenTree :: MetaVarDecl ( _, _, frag) if frag. name == sym:: block =>
1072
- IsInFollow :: Yes ,
1100
+ TokenTree :: MetaVarDecl ( _, _, frag) if frag. name == sym:: block => {
1101
+ IsInFollow :: Yes
1102
+ }
1073
1103
_ => IsInFollow :: No ( TOKENS ) ,
1074
1104
}
1075
- } ,
1105
+ }
1076
1106
"ident" | "lifetime" => {
1077
1107
// being a single token, idents and lifetimes are harmless
1078
1108
IsInFollow :: Yes
1079
- } ,
1109
+ }
1080
1110
"literal" => {
1081
1111
// literals may be of a single token, or two tokens (negative numbers)
1082
1112
IsInFollow :: Yes
1083
- } ,
1113
+ }
1084
1114
"meta" | "tt" => {
1085
1115
// being either a single token or a delimited sequence, tt is
1086
1116
// harmless
1087
1117
IsInFollow :: Yes
1088
- } ,
1118
+ }
1089
1119
"vis" => {
1090
1120
// Explicitly disallow `priv`, on the off chance it comes back.
1091
1121
const TOKENS : & [ & str ] = & [ "`,`" , "an ident" , "a type" ] ;
1092
1122
match tok {
1093
1123
TokenTree :: Token ( token) => match token. kind {
1094
1124
Comma => IsInFollow :: Yes ,
1095
1125
Ident ( name, is_raw) if is_raw || name != kw:: Priv => IsInFollow :: Yes ,
1096
- _ => if token. can_begin_type ( ) {
1097
- IsInFollow :: Yes
1098
- } else {
1099
- IsInFollow :: No ( TOKENS )
1126
+ _ => {
1127
+ if token. can_begin_type ( ) {
1128
+ IsInFollow :: Yes
1129
+ } else {
1130
+ IsInFollow :: No ( TOKENS )
1131
+ }
1100
1132
}
1101
1133
} ,
1102
- TokenTree :: MetaVarDecl ( _, _, frag) if frag. name == sym:: ident
1103
- || frag. name == sym:: ty
1104
- || frag. name == sym:: path =>
1105
- IsInFollow :: Yes ,
1134
+ TokenTree :: MetaVarDecl ( _, _, frag)
1135
+ if frag. name == sym:: ident
1136
+ || frag. name == sym:: ty
1137
+ || frag. name == sym:: path =>
1138
+ {
1139
+ IsInFollow :: Yes
1140
+ }
1106
1141
_ => IsInFollow :: No ( TOKENS ) ,
1107
1142
}
1108
- } ,
1143
+ }
1109
1144
"" => IsInFollow :: Yes , // kw::Invalid
1110
- _ => IsInFollow :: Invalid ( format ! ( "invalid fragment specifier `{}`" , frag) ,
1111
- VALID_FRAGMENT_NAMES_MSG ) ,
1145
+ _ => IsInFollow :: Invalid (
1146
+ format ! ( "invalid fragment specifier `{}`" , frag) ,
1147
+ VALID_FRAGMENT_NAMES_MSG ,
1148
+ ) ,
1112
1149
}
1113
1150
}
1114
1151
}
1115
1152
1116
- fn has_legal_fragment_specifier ( sess : & ParseSess ,
1117
- features : & Features ,
1118
- attrs : & [ ast:: Attribute ] ,
1119
- tok : & quoted:: TokenTree ) -> Result < ( ) , String > {
1153
+ fn has_legal_fragment_specifier (
1154
+ sess : & ParseSess ,
1155
+ features : & Features ,
1156
+ attrs : & [ ast:: Attribute ] ,
1157
+ tok : & quoted:: TokenTree ,
1158
+ ) -> Result < ( ) , String > {
1120
1159
debug ! ( "has_legal_fragment_specifier({:?})" , tok) ;
1121
1160
if let quoted:: TokenTree :: MetaVarDecl ( _, _, ref frag_spec) = * tok {
1122
1161
let frag_span = tok. span ( ) ;
@@ -1127,21 +1166,34 @@ fn has_legal_fragment_specifier(sess: &ParseSess,
1127
1166
Ok ( ( ) )
1128
1167
}
1129
1168
1130
- fn is_legal_fragment_specifier ( _sess : & ParseSess ,
1131
- _features : & Features ,
1132
- _attrs : & [ ast:: Attribute ] ,
1133
- frag_name : Symbol ,
1134
- _frag_span : Span ) -> bool {
1169
+ fn is_legal_fragment_specifier (
1170
+ _sess : & ParseSess ,
1171
+ _features : & Features ,
1172
+ _attrs : & [ ast:: Attribute ] ,
1173
+ frag_name : Symbol ,
1174
+ _frag_span : Span ,
1175
+ ) -> bool {
1135
1176
/*
1136
1177
* If new fragment specifiers are invented in nightly, `_sess`,
1137
1178
* `_features`, `_attrs`, and `_frag_span` will be useful here
1138
1179
* for checking against feature gates. See past versions of
1139
1180
* this function.
1140
1181
*/
1141
1182
match frag_name {
1142
- sym:: item | sym:: block | sym:: stmt | sym:: expr | sym:: pat |
1143
- sym:: lifetime | sym:: path | sym:: ty | sym:: ident | sym:: meta | sym:: tt |
1144
- sym:: vis | sym:: literal | kw:: Invalid => true ,
1183
+ sym:: item
1184
+ | sym:: block
1185
+ | sym:: stmt
1186
+ | sym:: expr
1187
+ | sym:: pat
1188
+ | sym:: lifetime
1189
+ | sym:: path
1190
+ | sym:: ty
1191
+ | sym:: ident
1192
+ | sym:: meta
1193
+ | sym:: tt
1194
+ | sym:: vis
1195
+ | sym:: literal
1196
+ | kw:: Invalid => true ,
1145
1197
_ => false ,
1146
1198
}
1147
1199
}
@@ -1151,7 +1203,9 @@ fn quoted_tt_to_string(tt: "ed::TokenTree) -> String {
1151
1203
quoted:: TokenTree :: Token ( ref token) => crate :: print:: pprust:: token_to_string ( & token) ,
1152
1204
quoted:: TokenTree :: MetaVar ( _, name) => format ! ( "${}" , name) ,
1153
1205
quoted:: TokenTree :: MetaVarDecl ( _, name, kind) => format ! ( "${}:{}" , name, kind) ,
1154
- _ => panic ! ( "unexpected quoted::TokenTree::{{Sequence or Delimited}} \
1155
- in follow set checker") ,
1206
+ _ => panic ! (
1207
+ "unexpected quoted::TokenTree::{{Sequence or Delimited}} \
1208
+ in follow set checker"
1209
+ ) ,
1156
1210
}
1157
1211
}
0 commit comments