@@ -82,9 +82,9 @@ use ast;
82
82
use ast:: { TokenTree , Name , Ident } ;
83
83
use codemap:: { BytePos , mk_sp, Span , Spanned } ;
84
84
use codemap;
85
- use errors:: FatalError ;
85
+ use errors:: DiagnosticBuilder ;
86
86
use parse:: lexer:: * ; //resolve bug?
87
- use parse:: ParseSess ;
87
+ use parse:: { ParseSess , PResult } ;
88
88
use parse:: parser:: { PathStyle , Parser } ;
89
89
use parse:: token:: { DocComment , MatchNt , SubstNt } ;
90
90
use parse:: token:: { Token , Nonterminal } ;
@@ -200,8 +200,8 @@ pub enum NamedMatch {
200
200
MatchedNonterminal ( Nonterminal )
201
201
}
202
202
203
- pub fn nameize ( p_s : & ParseSess , ms : & [ TokenTree ] , res : & [ Rc < NamedMatch > ] )
204
- -> ParseResult < HashMap < Name , Rc < NamedMatch > > > {
203
+ pub fn nameize < ' a > ( p_s : & ' a ParseSess , ms : & [ TokenTree ] , res : & [ Rc < NamedMatch > ] )
204
+ -> ParseResult < ' a , HashMap < Name , Rc < NamedMatch > > > {
205
205
fn n_rec ( p_s : & ParseSess , m : & TokenTree , res : & [ Rc < NamedMatch > ] ,
206
206
ret_val : & mut HashMap < Name , Rc < NamedMatch > > , idx : & mut usize )
207
207
-> Result < ( ) , ( codemap:: Span , String ) > {
@@ -248,16 +248,16 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>])
248
248
Success ( ret_val)
249
249
}
250
250
251
- pub enum ParseResult < T > {
251
+ pub enum ParseResult < ' a , T > {
252
252
Success ( T ) ,
253
253
/// Arm failed to match
254
- Failure ( codemap :: Span , String ) ,
254
+ Failure ( DiagnosticBuilder < ' a > ) ,
255
255
/// Fatal error (malformed macro?). Abort compilation.
256
256
Error ( codemap:: Span , String )
257
257
}
258
258
259
- pub type NamedParseResult = ParseResult < HashMap < Name , Rc < NamedMatch > > > ;
260
- pub type PositionalParseResult = ParseResult < Vec < Rc < NamedMatch > > > ;
259
+ pub type NamedParseResult < ' a > = ParseResult < ' a , HashMap < Name , Rc < NamedMatch > > > ;
260
+ pub type PositionalParseResult < ' a > = ParseResult < ' a , Vec < Rc < NamedMatch > > > ;
261
261
262
262
/// Perform a token equality check, ignoring syntax context (that is, an
263
263
/// unhygienic comparison)
@@ -270,11 +270,11 @@ pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool {
270
270
}
271
271
}
272
272
273
- pub fn parse ( sess : & ParseSess ,
274
- cfg : ast:: CrateConfig ,
275
- mut rdr : TtReader ,
276
- ms : & [ TokenTree ] )
277
- -> NamedParseResult {
273
+ pub fn parse < ' a > ( sess : & ' a ParseSess ,
274
+ cfg : ast:: CrateConfig ,
275
+ mut rdr : TtReader < ' a > ,
276
+ ms : & [ TokenTree ] )
277
+ -> NamedParseResult < ' a > {
278
278
let mut cur_eis = Vec :: new ( ) ;
279
279
cur_eis. push ( initial_matcher_pos ( Rc :: new ( ms. iter ( )
280
280
. cloned ( )
@@ -445,7 +445,9 @@ pub fn parse(sess: &ParseSess,
445
445
} else if eof_eis. len ( ) > 1 {
446
446
return Error ( sp, "ambiguity: multiple successful parses" . to_string ( ) ) ;
447
447
} else {
448
- return Failure ( sp, "unexpected end of macro invocation" . to_string ( ) ) ;
448
+ return Failure ( sess. span_diagnostic . struct_span_err (
449
+ sp, "unexpected end of macro invocation"
450
+ ) ) ;
449
451
}
450
452
} else {
451
453
if ( !bb_eis. is_empty ( ) && !next_eis. is_empty ( ) )
@@ -466,8 +468,10 @@ pub fn parse(sess: &ParseSess,
466
468
}
467
469
) )
468
470
} else if bb_eis. is_empty ( ) && next_eis. is_empty ( ) {
469
- return Failure ( sp, format ! ( "no rules expected the token `{}`" ,
470
- pprust:: token_to_string( & tok) ) ) ;
471
+ return Failure ( sess. span_diagnostic . struct_span_err (
472
+ sp, & format ! ( "no rules expected the token `{}`" ,
473
+ pprust:: token_to_string( & tok) )
474
+ ) ) ;
471
475
} else if !next_eis. is_empty ( ) {
472
476
/* Now process the next token */
473
477
while !next_eis. is_empty ( ) {
@@ -481,8 +485,12 @@ pub fn parse(sess: &ParseSess,
481
485
match ei. top_elts . get_tt ( ei. idx ) {
482
486
TokenTree :: Token ( span, MatchNt ( _, ident) ) => {
483
487
let match_cur = ei. match_cur ;
484
- ( & mut ei. matches [ match_cur] ) . push ( Rc :: new ( MatchedNonterminal (
485
- parse_nt ( & mut rust_parser, span, & ident. name . as_str ( ) ) ) ) ) ;
488
+ let nt = match parse_nt ( & mut rust_parser, span,
489
+ & ident. name . as_str ( ) ) {
490
+ Ok ( nt) => Rc :: new ( MatchedNonterminal ( nt) ) ,
491
+ Err ( diag) => return Failure ( diag)
492
+ } ;
493
+ ( & mut ei. matches [ match_cur] ) . push ( nt) ;
486
494
ei. idx += 1 ;
487
495
ei. match_cur += 1 ;
488
496
}
@@ -500,55 +508,45 @@ pub fn parse(sess: &ParseSess,
500
508
}
501
509
}
502
510
503
- pub fn parse_nt < ' a > ( p : & mut Parser < ' a > , sp : Span , name : & str ) -> Nonterminal {
511
+ pub fn parse_nt < ' a > ( p : & mut Parser < ' a > , sp : Span , name : & str ) -> PResult < ' a , Nonterminal > {
504
512
match name {
505
513
"tt" => {
506
514
p. quote_depth += 1 ; //but in theory, non-quoted tts might be useful
507
515
let res: :: parse:: PResult < ' a , _ > = p. parse_token_tree ( ) ;
508
- let res = token:: NtTT ( P ( panictry ! ( res) ) ) ;
516
+ let res = token:: NtTT ( P ( try !( res) ) ) ;
509
517
p. quote_depth -= 1 ;
510
- return res;
518
+ return Ok ( res) ;
511
519
}
512
520
_ => { }
513
521
}
514
522
// check at the beginning and the parser checks after each bump
515
523
p. check_unknown_macro_variable ( ) ;
516
524
match name {
517
- "item" => match panictry ! ( p. parse_item( ) ) {
518
- Some ( i) => token:: NtItem ( i) ,
519
- None => {
520
- p. fatal ( "expected an item keyword" ) . emit ( ) ;
521
- panic ! ( FatalError ) ;
522
- }
525
+ "item" => match try!( p. parse_item ( ) ) {
526
+ Some ( i) => Ok ( token:: NtItem ( i) ) ,
527
+ None => Err ( p. fatal ( "expected an item keyword" ) )
523
528
} ,
524
- "block" => token:: NtBlock ( panictry ! ( p. parse_block( ) ) ) ,
525
- "stmt" => match panictry ! ( p. parse_stmt( ) ) {
526
- Some ( s) => token:: NtStmt ( P ( s) ) ,
527
- None => {
528
- p. fatal ( "expected a statement" ) . emit ( ) ;
529
- panic ! ( FatalError ) ;
530
- }
529
+ "block" => Ok ( token:: NtBlock ( try!( p. parse_block ( ) ) ) ) ,
530
+ "stmt" => match try!( p. parse_stmt ( ) ) {
531
+ Some ( s) => Ok ( token:: NtStmt ( P ( s) ) ) ,
532
+ None => Err ( p. fatal ( "expected a statement" ) )
531
533
} ,
532
- "pat" => token:: NtPat ( panictry ! ( p. parse_pat( ) ) ) ,
533
- "expr" => token:: NtExpr ( panictry ! ( p. parse_expr( ) ) ) ,
534
- "ty" => token:: NtTy ( panictry ! ( p. parse_ty( ) ) ) ,
534
+ "pat" => Ok ( token:: NtPat ( try !( p. parse_pat ( ) ) ) ) ,
535
+ "expr" => Ok ( token:: NtExpr ( try !( p. parse_expr ( ) ) ) ) ,
536
+ "ty" => Ok ( token:: NtTy ( try !( p. parse_ty ( ) ) ) ) ,
535
537
// this could be handled like a token, since it is one
536
538
"ident" => match p. token {
537
539
token:: Ident ( sn) => {
538
540
p. bump ( ) ;
539
- token:: NtIdent ( Box :: new ( Spanned :: < Ident > { node : sn, span : p. span } ) )
541
+ Ok ( token:: NtIdent ( Box :: new ( Spanned :: < Ident > { node : sn, span : p. span } ) ) )
540
542
}
541
543
_ => {
542
544
let token_str = pprust:: token_to_string ( & p. token ) ;
543
- p. fatal ( & format ! ( "expected ident, found {}" ,
544
- & token_str[ ..] ) ) . emit ( ) ;
545
- panic ! ( FatalError )
545
+ Err ( p. fatal ( & format ! ( "expected ident, found {}" , & token_str[ ..] ) ) )
546
546
}
547
547
} ,
548
- "path" => {
549
- token:: NtPath ( Box :: new ( panictry ! ( p. parse_path( PathStyle :: Type ) ) ) )
550
- } ,
551
- "meta" => token:: NtMeta ( panictry ! ( p. parse_meta_item( ) ) ) ,
548
+ "path" => Ok ( token:: NtPath ( Box :: new ( try!( p. parse_path ( PathStyle :: Type ) ) ) ) ) ,
549
+ "meta" => Ok ( token:: NtMeta ( try!( p. parse_meta_item ( ) ) ) ) ,
552
550
// this is not supposed to happen, since it has been checked
553
551
// when compiling the macro.
554
552
_ => p. span_bug ( sp, "invalid fragment specifier" )
0 commit comments