span: Span,
) -> AstFragment {
let mut parser = self.cx.new_parser_from_tts(toks);
- match parse_ast_fragment(&mut parser, kind, false) {
+ match parse_ast_fragment(&mut parser, kind) {
Ok(fragment) => {
ensure_complete_parse(&mut parser, path, kind.name(), span);
fragment
pub fn parse_ast_fragment<'a>(
this: &mut Parser<'a>,
kind: AstFragmentKind,
- macro_legacy_warnings: bool,
) -> PResult<'a, AstFragment> {
Ok(match kind {
AstFragmentKind::Items => {
}
AstFragmentKind::Stmts => {
let mut stmts = SmallVec::new();
- while this.token != token::Eof &&
- // won't make progress on a `}`
- this.token != token::CloseDelim(token::Brace)
- {
- if let Some(stmt) = this.parse_full_stmt(macro_legacy_warnings)? {
+ // Won't make progress on a `}`.
+ while this.token != token::Eof && this.token != token::CloseDelim(token::Brace) {
+ if let Some(stmt) = this.parse_full_stmt()? {
stmts.push(stmt);
}
}
/// Parses a statement. This stops just before trailing semicolons on everything but items.
/// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
pub fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> {
- Ok(self.parse_stmt_without_recovery(true).unwrap_or_else(|mut e| {
+ Ok(self.parse_stmt_without_recovery().unwrap_or_else(|mut e| {
e.emit();
self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
None
}))
}
- fn parse_stmt_without_recovery(
- &mut self,
- macro_legacy_warnings: bool,
- ) -> PResult<'a, Option<Stmt>> {
+ fn parse_stmt_without_recovery(&mut self) -> PResult<'a, Option<Stmt>> {
maybe_whole!(self, NtStmt, |x| Some(x));
let attrs = self.parse_outer_attributes()?;
let path = self.parse_path(PathStyle::Expr)?;
if self.eat(&token::Not) {
- return self.parse_stmt_mac(lo, attrs.into(), path, macro_legacy_warnings);
+ return self.parse_stmt_mac(lo, attrs.into(), path);
}
let expr = if self.check(&token::OpenDelim(token::Brace)) {
lo: Span,
attrs: AttrVec,
path: ast::Path,
- legacy_warnings: bool,
) -> PResult<'a, Option<Stmt>> {
let args = self.parse_mac_args()?;
let delim = args.delim();
let kind = if delim == token::Brace || self.token == token::Semi || self.token == token::Eof
{
- StmtKind::Mac(P((mac, style, attrs.into())))
- }
- // We used to incorrectly stop parsing macro-expanded statements here.
- // If the next token will be an error anyway but could have parsed with the
- // earlier behavior, stop parsing here and emit a warning to avoid breakage.
- else if legacy_warnings
- && self.token.can_begin_expr()
- && match self.token.kind {
- // These can continue an expression, so we can't stop parsing and warn.
- token::OpenDelim(token::Paren)
- | token::OpenDelim(token::Bracket)
- | token::BinOp(token::Minus)
- | token::BinOp(token::Star)
- | token::BinOp(token::And)
- | token::BinOp(token::Or)
- | token::AndAnd
- | token::OrOr
- | token::DotDot
- | token::DotDotDot
- | token::DotDotEq => false,
- _ => true,
- }
- {
- self.warn_missing_semicolon();
StmtKind::Mac(P((mac, style, attrs)))
} else {
// Since none of the above applied, this is an expression statement macro.
// bar;
//
// which is valid in other languages, but not Rust.
- match self.parse_stmt_without_recovery(false) {
+ match self.parse_stmt_without_recovery() {
Ok(Some(stmt)) => {
if self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace))
|| do_not_suggest_help
if self.token == token::Eof {
break;
}
- let stmt = match self.parse_full_stmt(false) {
+ let stmt = match self.parse_full_stmt() {
Err(mut err) => {
self.maybe_annotate_with_ascription(&mut err, false);
err.emit();
}
/// Parses a statement, including the trailing semicolon.
- pub fn parse_full_stmt(&mut self, macro_legacy_warnings: bool) -> PResult<'a, Option<Stmt>> {
+ pub fn parse_full_stmt(&mut self) -> PResult<'a, Option<Stmt>> {
// Skip looking for a trailing semicolon when we have an interpolated statement.
maybe_whole!(self, NtStmt, |x| Some(x));
- let mut stmt = match self.parse_stmt_without_recovery(macro_legacy_warnings)? {
+ let mut stmt = match self.parse_stmt_without_recovery()? {
Some(stmt) => stmt,
None => return Ok(None),
};
}
}
StmtKind::Local(..) => {
- // We used to incorrectly allow a macro-expanded let statement to lack a semicolon.
- if macro_legacy_warnings && self.token != token::Semi {
- self.warn_missing_semicolon();
- } else {
- self.expect_semi()?;
- eat_semi = false;
- }
+ self.expect_semi()?;
+ eat_semi = false;
}
_ => {}
}
Ok(Some(stmt))
}
- fn warn_missing_semicolon(&self) {
- self.diagnostic()
- .struct_span_warn(self.token.span, {
- &format!("expected `;`, found {}", super::token_descr(&self.token))
- })
- .note({
- "this was erroneously allowed and will become a hard error in a future release"
- })
- .emit();
- }
-
pub(super) fn mk_block(&self, stmts: Vec<Stmt>, rules: BlockCheckMode, span: Span) -> P<Block> {
P(Block { stmts, id: DUMMY_NODE_ID, rules, span })
}
+++ /dev/null
-warning: expected `;`, found keyword `let`
- --> $DIR/missing-semicolon-warning.rs:6:12
- |
-LL | $( let x = $e1 )*;
- | ^^^
-...
-LL | fn main() { m!(0, 0; 0, 0); }
- | --------------- in this macro invocation
- |
- = note: this was erroneously allowed and will become a hard error in a future release
- = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
-
-warning: expected `;`, found `println`
- --> $DIR/missing-semicolon-warning.rs:7:12
- |
-LL | $( println!("{}", $e2) )*;
- | ^^^^^^^
-...
-LL | fn main() { m!(0, 0; 0, 0); }
- | --------------- in this macro invocation
- |
- = note: this was erroneously allowed and will become a hard error in a future release
- = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
-