@@ -87,6 +87,7 @@ use parse::{Directory, ParseSess};
8787use parse:: parser:: { PathStyle , Parser } ;
8888use parse:: token:: { self , DocComment , Token , Nonterminal } ;
8989use print:: pprust;
90+ use symbol:: keywords;
9091use tokenstream:: TokenTree ;
9192use util:: small_vector:: SmallVector ;
9293
@@ -201,22 +202,27 @@ pub enum NamedMatch {
201202 MatchedNonterminal ( Rc < Nonterminal > )
202203}
203204
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 )
205206 -> NamedParseResult {
206207 use self :: quoted:: TokenTree ;
207208
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 ,
209210 ret_val : & mut HashMap < Ident , Rc < NamedMatch > > )
210211 -> Result < ( ) , ( syntax_pos:: Span , String ) > {
211212 match * m {
212213 TokenTree :: Sequence ( _, ref seq) => {
213214 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) ?
215216 }
216217 }
217218 TokenTree :: Delimited ( _, ref delim) => {
218219 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 ( ) ) ) ;
220226 }
221227 }
222228 TokenTree :: MetaVarDecl ( sp, bind_name, _) => {
@@ -237,7 +243,7 @@ fn nameize<I: Iterator<Item=Rc<NamedMatch>>>(ms: &[quoted::TokenTree], mut res:
237243
238244 let mut ret_val = HashMap :: new ( ) ;
239245 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) {
241247 Ok ( _) => { } ,
242248 Err ( ( sp, msg) ) => return Error ( sp, msg) ,
243249 }
@@ -277,11 +283,13 @@ fn create_matches(len: usize) -> Vec<Vec<Rc<NamedMatch>>> {
277283 ( 0 ..len) . into_iter ( ) . map ( |_| Vec :: new ( ) ) . collect ( )
278284}
279285
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 > > ,
281288 next_eis : & mut Vec < Box < MatcherPos > > ,
282289 eof_eis : & mut SmallVector < Box < MatcherPos > > ,
283290 bb_eis : & mut SmallVector < Box < MatcherPos > > ,
284- token : & Token , span : & syntax_pos:: Span ) -> ParseResult < ( ) > {
291+ token : & Token ,
292+ span : & syntax_pos:: Span ) -> ParseResult < ( ) > {
285293 use self :: quoted:: TokenTree ;
286294
287295 while let Some ( mut ei) = cur_eis. pop ( ) {
@@ -375,6 +383,11 @@ fn inner_parse_loop(cur_eis: &mut SmallVector<Box<MatcherPos>>,
375383 top_elts : Tt ( TokenTree :: Sequence ( sp, seq) ) ,
376384 } ) ) ;
377385 }
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+ }
378391 TokenTree :: MetaVarDecl ( ..) => {
379392 // Built-in nonterminals never start with these tokens,
380393 // so we can eliminate them from consideration.
@@ -422,7 +435,7 @@ pub fn parse(sess: &ParseSess,
422435 let mut eof_eis = SmallVector :: new ( ) ;
423436 assert ! ( next_eis. is_empty( ) ) ;
424437
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,
426439 & parser. token , & parser. span ) {
427440 Success ( _) => { } ,
428441 Failure ( sp, tok) => return Failure ( sp, tok) ,
@@ -435,7 +448,8 @@ pub fn parse(sess: &ParseSess,
435448 /* error messages here could be improved with links to orig. rules */
436449 if token_name_eq ( & parser. token , & token:: Eof ) {
437450 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) ;
439453 } else if eof_eis. len ( ) > 1 {
440454 return Error ( parser. span , "ambiguity: multiple successful parses" . to_string ( ) ) ;
441455 } else {
0 commit comments