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:
Matthias Krüger 2024-07-30 22:51:38 +02:00 committed by GitHub
commit 6f0b237c72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 51 additions and 18 deletions

View File

@ -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))

View File

@ -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);
}
}
}

View File

@ -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() {

View File

@ -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.

View File

@ -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,

View File

@ -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>`

View File

@ -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));
}

View File

@ -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() {}

View 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`
}

View 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