@@ -82,9 +82,9 @@ use ast;
8282use ast:: { TokenTree , Name , Ident } ;
8383use codemap:: { BytePos , mk_sp, Span , Spanned } ;
8484use codemap;
85- use errors:: FatalError ;
85+ use errors:: DiagnosticBuilder ;
8686use parse:: lexer:: * ; //resolve bug?
87- use parse:: ParseSess ;
87+ use parse:: { ParseSess , PResult } ;
8888use parse:: parser:: { PathStyle , Parser } ;
8989use parse:: token:: { DocComment , MatchNt , SubstNt } ;
9090use parse:: token:: { Token , Nonterminal } ;
@@ -200,8 +200,8 @@ pub enum NamedMatch {
200200 MatchedNonterminal ( Nonterminal )
201201}
202202
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 > > > {
205205 fn n_rec ( p_s : & ParseSess , m : & TokenTree , res : & [ Rc < NamedMatch > ] ,
206206 ret_val : & mut HashMap < Name , Rc < NamedMatch > > , idx : & mut usize )
207207 -> Result < ( ) , ( codemap:: Span , String ) > {
@@ -248,16 +248,16 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>])
248248 Success ( ret_val)
249249}
250250
251- pub enum ParseResult < T > {
251+ pub enum ParseResult < ' a , T > {
252252 Success ( T ) ,
253253 /// Arm failed to match
254- Failure ( codemap :: Span , String ) ,
254+ Failure ( DiagnosticBuilder < ' a > ) ,
255255 /// Fatal error (malformed macro?). Abort compilation.
256256 Error ( codemap:: Span , String )
257257}
258258
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 > > > ;
261261
262262/// Perform a token equality check, ignoring syntax context (that is, an
263263/// unhygienic comparison)
@@ -270,11 +270,11 @@ pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool {
270270 }
271271}
272272
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 > {
278278 let mut cur_eis = Vec :: new ( ) ;
279279 cur_eis. push ( initial_matcher_pos ( Rc :: new ( ms. iter ( )
280280 . cloned ( )
@@ -445,7 +445,9 @@ pub fn parse(sess: &ParseSess,
445445 } else if eof_eis. len ( ) > 1 {
446446 return Error ( sp, "ambiguity: multiple successful parses" . to_string ( ) ) ;
447447 } 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+ ) ) ;
449451 }
450452 } else {
451453 if ( !bb_eis. is_empty ( ) && !next_eis. is_empty ( ) )
@@ -466,8 +468,10 @@ pub fn parse(sess: &ParseSess,
466468 }
467469 ) )
468470 } 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+ ) ) ;
471475 } else if !next_eis. is_empty ( ) {
472476 /* Now process the next token */
473477 while !next_eis. is_empty ( ) {
@@ -481,8 +485,12 @@ pub fn parse(sess: &ParseSess,
481485 match ei. top_elts . get_tt ( ei. idx ) {
482486 TokenTree :: Token ( span, MatchNt ( _, ident) ) => {
483487 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) ;
486494 ei. idx += 1 ;
487495 ei. match_cur += 1 ;
488496 }
@@ -500,55 +508,45 @@ pub fn parse(sess: &ParseSess,
500508 }
501509}
502510
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 > {
504512 match name {
505513 "tt" => {
506514 p. quote_depth += 1 ; //but in theory, non-quoted tts might be useful
507515 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) ) ) ;
509517 p. quote_depth -= 1 ;
510- return res;
518+ return Ok ( res) ;
511519 }
512520 _ => { }
513521 }
514522 // check at the beginning and the parser checks after each bump
515523 p. check_unknown_macro_variable ( ) ;
516524 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" ) )
523528 } ,
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" ) )
531533 } ,
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 ( ) ) ) ) ,
535537 // this could be handled like a token, since it is one
536538 "ident" => match p. token {
537539 token:: Ident ( sn) => {
538540 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 } ) ) )
540542 }
541543 _ => {
542544 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[ ..] ) ) )
546546 }
547547 } ,
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 ( ) ) ) ) ,
552550 // this is not supposed to happen, since it has been checked
553551 // when compiling the macro.
554552 _ => p. span_bug ( sp, "invalid fragment specifier" )
0 commit comments