From 390c3cee6a8e0c0550eb6213c0e7e5f74c4fbc31 Mon Sep 17 00:00:00 2001 From: rleungx Date: Thu, 3 May 2018 19:09:34 +0800 Subject: [PATCH] check if the token is a lifetime before parsing --- src/libsyntax/ext/tt/macro_parser.rs | 8 +++++++- src/libsyntax/parse/parser.rs | 2 +- src/test/compile-fail/macro-non-lifetime.rs | 20 ++++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 src/test/compile-fail/macro-non-lifetime.rs diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index d9c3deb30da30..71634ada89458 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -835,7 +835,13 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal { "path" => token::NtPath(panictry!(p.parse_path_common(PathStyle::Type, false))), "meta" => token::NtMeta(panictry!(p.parse_meta_item())), "vis" => token::NtVis(panictry!(p.parse_visibility(true))), - "lifetime" => token::NtLifetime(p.expect_lifetime().ident), + "lifetime" => if p.check_lifetime() { + token::NtLifetime(p.expect_lifetime().ident) + } else { + let token_str = pprust::token_to_string(&p.token); + p.fatal(&format!("expected a lifetime, found `{}`", &token_str)).emit(); + FatalError.raise(); + } // this is not supposed to happen, since it has been checked // when compiling the macro. _ => p.span_bug(sp, "invalid fragment specifier"), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 324cadc84e862..bbee03bb0d5c5 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2042,7 +2042,7 @@ impl<'a> Parser<'a> { }) } - fn check_lifetime(&mut self) -> bool { + pub fn check_lifetime(&mut self) -> bool { self.expected_tokens.push(TokenType::Lifetime); self.token.is_lifetime() } diff --git a/src/test/compile-fail/macro-non-lifetime.rs b/src/test/compile-fail/macro-non-lifetime.rs new file mode 100644 index 0000000000000..a2706e83229e5 --- /dev/null +++ b/src/test/compile-fail/macro-non-lifetime.rs @@ -0,0 +1,20 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test for issue #50381: non-lifetime passed to :lifetime. + +#![feature(macro_lifetime_matcher)] + +macro_rules! m { ($x:lifetime) => { } } + +fn main() { + m!(a); + //~^ ERROR expected a lifetime, found `a` +}