Rollup merge of #128376 - compiler-errors:finish-ur-vegetables, r=jieyouxu
Mark `Parser::eat`/`check` methods as `#[must_use]` These methods return a `bool`, but we probably should either use these values or explicitly throw them away (e.g. when we just want to unconditionally eat a token if it exists). I changed a few places from `eat` to `expect`, but otherwise I tried to leave a comment explaining why the `eat` was okay. This also adds a test for the `pattern_type!` macro, which used to silently accept a missing `is` token.
This commit is contained in:
commit
6f0b237c72
@ -24,7 +24,7 @@ fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P
|
||||
let mut parser = cx.new_parser_from_tts(stream);
|
||||
|
||||
let ty = parser.parse_ty()?;
|
||||
parser.eat_keyword(sym::is);
|
||||
parser.expect_keyword(sym::is)?;
|
||||
let pat = parser.parse_pat_no_top_alt(None, None)?;
|
||||
|
||||
Ok((ty, pat))
|
||||
|
@ -3153,7 +3153,8 @@ pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> {
|
||||
|
||||
if !require_comma {
|
||||
arm_body = Some(expr);
|
||||
this.eat(&token::Comma);
|
||||
// Eat a comma if it exists, though.
|
||||
let _ = this.eat(&token::Comma);
|
||||
Ok(Recovered::No)
|
||||
} else if let Some((span, guar)) =
|
||||
this.parse_arm_body_missing_braces(&expr, arrow_span)
|
||||
@ -3654,7 +3655,7 @@ pub(super) fn parse_struct_fields(
|
||||
fields.push(f);
|
||||
}
|
||||
self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore);
|
||||
self.eat(&token::Comma);
|
||||
let _ = self.eat(&token::Comma);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +178,8 @@ pub(super) fn parse_generic_params(&mut self) -> PResult<'a, ThinVec<ast::Generi
|
||||
span: this.prev_token.span,
|
||||
});
|
||||
|
||||
this.eat(&token::Comma);
|
||||
// Eat a trailing comma, if it exists.
|
||||
let _ = this.eat(&token::Comma);
|
||||
}
|
||||
|
||||
let param = if this.check_lifetime() {
|
||||
|
@ -1192,13 +1192,14 @@ fn parse_item_foreign_mod(
|
||||
mut safety: Safety,
|
||||
) -> PResult<'a, ItemInfo> {
|
||||
let abi = self.parse_abi(); // ABI?
|
||||
// FIXME: This recovery should be tested better.
|
||||
if safety == Safety::Default
|
||||
&& self.token.is_keyword(kw::Unsafe)
|
||||
&& self.look_ahead(1, |t| t.kind == token::OpenDelim(Delimiter::Brace))
|
||||
{
|
||||
self.expect(&token::OpenDelim(Delimiter::Brace)).unwrap_err().emit();
|
||||
safety = Safety::Unsafe(self.token.span);
|
||||
self.eat_keyword(kw::Unsafe);
|
||||
let _ = self.eat_keyword(kw::Unsafe);
|
||||
}
|
||||
let module = ast::ForeignMod {
|
||||
safety,
|
||||
@ -1759,7 +1760,7 @@ pub(crate) fn parse_record_struct_body(
|
||||
}
|
||||
}
|
||||
}
|
||||
self.eat(&token::CloseDelim(Delimiter::Brace));
|
||||
self.expect(&token::CloseDelim(Delimiter::Brace))?;
|
||||
} else {
|
||||
let token_str = super::token_descr(&self.token);
|
||||
let where_str = if parsed_where { "" } else { "`where`, or " };
|
||||
@ -1902,7 +1903,7 @@ fn parse_single_struct_field(
|
||||
if let Some(_guar) = guar {
|
||||
// Handle a case like `Vec<u8>>,` where we can continue parsing fields
|
||||
// after the comma
|
||||
self.eat(&token::Comma);
|
||||
let _ = self.eat(&token::Comma);
|
||||
|
||||
// `check_trailing_angle_brackets` already emitted a nicer error, as
|
||||
// proven by the presence of `_guar`. We can continue parsing.
|
||||
|
@ -547,6 +547,7 @@ fn check(&mut self, tok: &TokenKind) -> bool {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn check_noexpect(&self, tok: &TokenKind) -> bool {
|
||||
self.token == *tok
|
||||
}
|
||||
@ -556,6 +557,7 @@ fn check_noexpect(&self, tok: &TokenKind) -> bool {
|
||||
/// the main purpose of this function is to reduce the cluttering of the suggestions list
|
||||
/// which using the normal eat method could introduce in some cases.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn eat_noexpect(&mut self, tok: &TokenKind) -> bool {
|
||||
let is_present = self.check_noexpect(tok);
|
||||
if is_present {
|
||||
@ -566,6 +568,7 @@ fn eat_noexpect(&mut self, tok: &TokenKind) -> bool {
|
||||
|
||||
/// Consumes a token 'tok' if it exists. Returns whether the given token was present.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn eat(&mut self, tok: &TokenKind) -> bool {
|
||||
let is_present = self.check(tok);
|
||||
if is_present {
|
||||
@ -577,12 +580,14 @@ pub fn eat(&mut self, tok: &TokenKind) -> bool {
|
||||
/// If the next token is the given keyword, returns `true` without eating it.
|
||||
/// An expectation is also added for diagnostics purposes.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn check_keyword(&mut self, kw: Symbol) -> bool {
|
||||
self.expected_tokens.push(TokenType::Keyword(kw));
|
||||
self.token.is_keyword(kw)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn check_keyword_case(&mut self, kw: Symbol, case: Case) -> bool {
|
||||
if self.check_keyword(kw) {
|
||||
return true;
|
||||
@ -602,6 +607,7 @@ fn check_keyword_case(&mut self, kw: Symbol, case: Case) -> bool {
|
||||
/// Otherwise, returns `false`. An expectation is also added for diagnostics purposes.
|
||||
// Public for rustc_builtin_macros and rustfmt usage.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn eat_keyword(&mut self, kw: Symbol) -> bool {
|
||||
if self.check_keyword(kw) {
|
||||
self.bump();
|
||||
@ -615,6 +621,7 @@ pub fn eat_keyword(&mut self, kw: Symbol) -> bool {
|
||||
/// If the case differs (and is ignored) an error is issued.
|
||||
/// This is useful for recovery.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn eat_keyword_case(&mut self, kw: Symbol, case: Case) -> bool {
|
||||
if self.eat_keyword(kw) {
|
||||
return true;
|
||||
@ -636,6 +643,7 @@ fn eat_keyword_case(&mut self, kw: Symbol, case: Case) -> bool {
|
||||
/// Otherwise, returns `false`. No expectation is added.
|
||||
// Public for rustc_builtin_macros usage.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn eat_keyword_noexpect(&mut self, kw: Symbol) -> bool {
|
||||
if self.token.is_keyword(kw) {
|
||||
self.bump();
|
||||
@ -648,7 +656,7 @@ pub fn eat_keyword_noexpect(&mut self, kw: Symbol) -> bool {
|
||||
/// If the given word is not a keyword, signals an error.
|
||||
/// If the next token is not the given word, signals an error.
|
||||
/// Otherwise, eats it.
|
||||
fn expect_keyword(&mut self, kw: Symbol) -> PResult<'a, ()> {
|
||||
pub fn expect_keyword(&mut self, kw: Symbol) -> PResult<'a, ()> {
|
||||
if !self.eat_keyword(kw) { self.unexpected() } else { Ok(()) }
|
||||
}
|
||||
|
||||
@ -1025,8 +1033,11 @@ fn parse_seq_to_end<T>(
|
||||
f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
|
||||
) -> PResult<'a, (ThinVec<T>, Trailing)> {
|
||||
let (val, trailing, recovered) = self.parse_seq_to_before_end(ket, sep, f)?;
|
||||
if matches!(recovered, Recovered::No) {
|
||||
self.eat(ket);
|
||||
if matches!(recovered, Recovered::No) && !self.eat(ket) {
|
||||
self.dcx().span_delayed_bug(
|
||||
self.token.span,
|
||||
"recovered but `parse_seq_to_before_end` did not give us the ket token",
|
||||
);
|
||||
}
|
||||
Ok((val, trailing))
|
||||
}
|
||||
@ -1250,7 +1261,7 @@ fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, P<Expr>> {
|
||||
if pat {
|
||||
self.psess.gated_spans.gate(sym::inline_const_pat, span);
|
||||
}
|
||||
self.eat_keyword(kw::Const);
|
||||
self.expect_keyword(kw::Const)?;
|
||||
let (attrs, blk) = self.parse_inner_attrs_and_block()?;
|
||||
let anon_const = AnonConst {
|
||||
id: DUMMY_NODE_ID,
|
||||
|
@ -313,7 +313,8 @@ pub(super) fn parse_path_segment(
|
||||
}
|
||||
|
||||
// Generic arguments are found - `<`, `(`, `::<` or `::(`.
|
||||
self.eat(&token::PathSep);
|
||||
// First, eat `::` if it exists.
|
||||
let _ = self.eat(&token::PathSep);
|
||||
let lo = self.token.span;
|
||||
let args = if self.eat_lt() {
|
||||
// `<'a, T, A = U>`
|
||||
|
@ -33,15 +33,17 @@ macro_rules! parse_or {
|
||||
}
|
||||
while parser.token.kind != TokenKind::Eof {
|
||||
// Parse a `lazy_static!` item.
|
||||
// FIXME: These `eat_*` calls should be converted to `parse_or` to avoid
|
||||
// silently formatting malformed lazy-statics.
|
||||
let vis = parse_or!(parse_visibility, rustc_parse::parser::FollowedByType::No);
|
||||
parser.eat_keyword(kw::Static);
|
||||
parser.eat_keyword(kw::Ref);
|
||||
let _ = parser.eat_keyword(kw::Static);
|
||||
let _ = parser.eat_keyword(kw::Ref);
|
||||
let id = parse_or!(parse_ident);
|
||||
parser.eat(&TokenKind::Colon);
|
||||
let _ = parser.eat(&TokenKind::Colon);
|
||||
let ty = parse_or!(parse_ty);
|
||||
parser.eat(&TokenKind::Eq);
|
||||
let _ = parser.eat(&TokenKind::Eq);
|
||||
let expr = parse_or!(parse_expr);
|
||||
parser.eat(&TokenKind::Semi);
|
||||
let _ = parser.eat(&TokenKind::Semi);
|
||||
result.push((vis, id, ty, expr));
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//@ known-bug: #123809
|
||||
type Positive = std::pat::pattern_type!(std::pat:: is 0..);
|
||||
type Positive = std::pat::pattern_type!(std::pat is 0..);
|
||||
|
||||
pub fn main() {}
|
||||
|
8
tests/ui/type/pattern_types/missing-is.rs
Normal file
8
tests/ui/type/pattern_types/missing-is.rs
Normal file
@ -0,0 +1,8 @@
|
||||
#![feature(core_pattern_type, core_pattern_types)]
|
||||
|
||||
use std::pat::pattern_type;
|
||||
|
||||
fn main() {
|
||||
let x: pattern_type!(i32 0..1);
|
||||
//~^ ERROR expected one of `!`, `(`, `+`, `::`, `<`, or `is`, found `0`
|
||||
}
|
8
tests/ui/type/pattern_types/missing-is.stderr
Normal file
8
tests/ui/type/pattern_types/missing-is.stderr
Normal file
@ -0,0 +1,8 @@
|
||||
error: expected one of `!`, `(`, `+`, `::`, `<`, or `is`, found `0`
|
||||
--> $DIR/missing-is.rs:6:30
|
||||
|
|
||||
LL | let x: pattern_type!(i32 0..1);
|
||||
| ^ expected one of `!`, `(`, `+`, `::`, `<`, or `is`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
Loading…
Reference in New Issue
Block a user