From df86ad8d36a038ee61e3ee977082ea6623613bbd Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 13 Nov 2022 13:08:58 +0000 Subject: [PATCH] Add `delay_span_bug` to `AttrWrapper::take_for_recovery` --- compiler/rustc_parse/src/parser/attr_wrapper.rs | 12 +++++++++--- compiler/rustc_parse/src/parser/expr.rs | 15 ++++++++++----- compiler/rustc_parse/src/parser/stmt.rs | 12 +++++++----- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 1b16ecb5ec2d6..c8160548763c8 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -5,7 +5,8 @@ use rustc_ast::tokenstream::{AttrTokenTree, DelimSpan, LazyAttrTokenStream, Spac use rustc_ast::{self as ast}; use rustc_ast::{AttrVec, Attribute, HasAttrs, HasTokens}; use rustc_errors::PResult; -use rustc_span::{sym, Span}; +use rustc_session::parse::ParseSess; +use rustc_span::{sym, Span, DUMMY_SP}; use std::convert::TryInto; use std::ops::Range; @@ -39,8 +40,13 @@ impl AttrWrapper { pub fn empty() -> AttrWrapper { AttrWrapper { attrs: AttrVec::new(), start_pos: usize::MAX } } - // FIXME: Delay span bug here? - pub(crate) fn take_for_recovery(self) -> AttrVec { + + pub(crate) fn take_for_recovery(self, sess: &ParseSess) -> AttrVec { + sess.span_diagnostic.delay_span_bug( + self.attrs.get(0).map(|attr| attr.span).unwrap_or(DUMMY_SP), + "AttrVec is taken for recovery but no error is produced", + ); + self.attrs } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 7355730c9ebf1..b072573af23f0 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2272,7 +2272,7 @@ impl<'a> Parser<'a> { self.mk_block_err(cond_span.shrink_to_hi()) } } else { - let attrs = self.parse_outer_attributes()?.take_for_recovery(); // For recovery. + let attrs = self.parse_outer_attributes()?; // For recovery. let block = if self.check(&token::OpenDelim(Delimiter::Brace)) { self.parse_block()? } else { @@ -2289,7 +2289,7 @@ impl<'a> Parser<'a> { })? } }; - self.error_on_if_block_attrs(lo, false, block.span, &attrs); + self.error_on_if_block_attrs(lo, false, block.span, attrs); block }; let els = if self.eat_keyword(kw::Else) { Some(self.parse_else_expr()?) } else { None }; @@ -2350,7 +2350,7 @@ impl<'a> Parser<'a> { /// Parses an `else { ... }` expression (`else` token already eaten). fn parse_else_expr(&mut self) -> PResult<'a, P> { let else_span = self.prev_token.span; // `else` - let attrs = self.parse_outer_attributes()?.take_for_recovery(); // For recovery. + let attrs = self.parse_outer_attributes()?; // For recovery. let expr = if self.eat_keyword(kw::If) { self.parse_if_expr()? } else if self.check(&TokenKind::OpenDelim(Delimiter::Brace)) { @@ -2385,7 +2385,7 @@ impl<'a> Parser<'a> { }, } }; - self.error_on_if_block_attrs(else_span, true, expr.span, &attrs); + self.error_on_if_block_attrs(else_span, true, expr.span, attrs); Ok(expr) } @@ -2394,8 +2394,13 @@ impl<'a> Parser<'a> { ctx_span: Span, is_ctx_else: bool, branch_span: Span, - attrs: &[ast::Attribute], + attrs: AttrWrapper, ) { + if attrs.is_empty() { + return; + } + + let attrs: &[ast::Attribute] = &attrs.take_for_recovery(self.sess); let (attributes, last) = match attrs { [] => return, [x0 @ xn] | [x0, .., xn] => (x0.span.to(xn.span), xn.span), diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 12753c6785c9a..9684145ad9948 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -19,7 +19,7 @@ use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, TokenKind}; use rustc_ast::util::classify; -use rustc_ast::{AttrStyle, AttrVec, Attribute, LocalKind, MacCall, MacCallStmt, MacStmtStyle}; +use rustc_ast::{AttrStyle, AttrVec, LocalKind, MacCall, MacCallStmt, MacStmtStyle}; use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, HasAttrs, Local, Stmt}; use rustc_ast::{StmtKind, DUMMY_NODE_ID}; use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult}; @@ -101,7 +101,7 @@ impl<'a> Parser<'a> { self.mk_stmt(lo.to(item.span), StmtKind::Item(P(item))) } else if self.eat(&token::Semi) { // Do not attempt to parse an expression if we're done here. - self.error_outer_attrs(&attrs.take_for_recovery()); + self.error_outer_attrs(attrs); self.mk_stmt(lo, StmtKind::Empty) } else if self.token != token::CloseDelim(Delimiter::Brace) { // Remainder are line-expr stmts. @@ -120,7 +120,7 @@ impl<'a> Parser<'a> { } self.mk_stmt(lo.to(e.span), StmtKind::Expr(e)) } else { - self.error_outer_attrs(&attrs.take_for_recovery()); + self.error_outer_attrs(attrs); return Ok(None); })) } @@ -199,8 +199,10 @@ impl<'a> Parser<'a> { /// Error on outer attributes in this context. /// Also error if the previous token was a doc comment. - fn error_outer_attrs(&self, attrs: &[Attribute]) { - if let [.., last] = attrs { + fn error_outer_attrs(&self, attrs: AttrWrapper) { + if !attrs.is_empty() + && let attrs = attrs.take_for_recovery(self.sess) + && let attrs @ [.., last] = &*attrs { if last.is_doc_comment() { self.sess.emit_err(DocCommentDoesNotDocumentAnything { span: last.span,