Skip to content

Commit df86ad8

Browse files
committed
Add delay_span_bug to AttrWrapper::take_for_recovery
1 parent 3be81dd commit df86ad8

File tree

3 files changed

+26
-13
lines changed

3 files changed

+26
-13
lines changed

Diff for: compiler/rustc_parse/src/parser/attr_wrapper.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use rustc_ast::tokenstream::{AttrTokenTree, DelimSpan, LazyAttrTokenStream, Spac
55
use rustc_ast::{self as ast};
66
use rustc_ast::{AttrVec, Attribute, HasAttrs, HasTokens};
77
use rustc_errors::PResult;
8-
use rustc_span::{sym, Span};
8+
use rustc_session::parse::ParseSess;
9+
use rustc_span::{sym, Span, DUMMY_SP};
910

1011
use std::convert::TryInto;
1112
use std::ops::Range;
@@ -39,8 +40,13 @@ impl AttrWrapper {
3940
pub fn empty() -> AttrWrapper {
4041
AttrWrapper { attrs: AttrVec::new(), start_pos: usize::MAX }
4142
}
42-
// FIXME: Delay span bug here?
43-
pub(crate) fn take_for_recovery(self) -> AttrVec {
43+
44+
pub(crate) fn take_for_recovery(self, sess: &ParseSess) -> AttrVec {
45+
sess.span_diagnostic.delay_span_bug(
46+
self.attrs.get(0).map(|attr| attr.span).unwrap_or(DUMMY_SP),
47+
"AttrVec is taken for recovery but no error is produced",
48+
);
49+
4450
self.attrs
4551
}
4652

Diff for: compiler/rustc_parse/src/parser/expr.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -2272,7 +2272,7 @@ impl<'a> Parser<'a> {
22722272
self.mk_block_err(cond_span.shrink_to_hi())
22732273
}
22742274
} else {
2275-
let attrs = self.parse_outer_attributes()?.take_for_recovery(); // For recovery.
2275+
let attrs = self.parse_outer_attributes()?; // For recovery.
22762276
let block = if self.check(&token::OpenDelim(Delimiter::Brace)) {
22772277
self.parse_block()?
22782278
} else {
@@ -2289,7 +2289,7 @@ impl<'a> Parser<'a> {
22892289
})?
22902290
}
22912291
};
2292-
self.error_on_if_block_attrs(lo, false, block.span, &attrs);
2292+
self.error_on_if_block_attrs(lo, false, block.span, attrs);
22932293
block
22942294
};
22952295
let els = if self.eat_keyword(kw::Else) { Some(self.parse_else_expr()?) } else { None };
@@ -2350,7 +2350,7 @@ impl<'a> Parser<'a> {
23502350
/// Parses an `else { ... }` expression (`else` token already eaten).
23512351
fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
23522352
let else_span = self.prev_token.span; // `else`
2353-
let attrs = self.parse_outer_attributes()?.take_for_recovery(); // For recovery.
2353+
let attrs = self.parse_outer_attributes()?; // For recovery.
23542354
let expr = if self.eat_keyword(kw::If) {
23552355
self.parse_if_expr()?
23562356
} else if self.check(&TokenKind::OpenDelim(Delimiter::Brace)) {
@@ -2385,7 +2385,7 @@ impl<'a> Parser<'a> {
23852385
},
23862386
}
23872387
};
2388-
self.error_on_if_block_attrs(else_span, true, expr.span, &attrs);
2388+
self.error_on_if_block_attrs(else_span, true, expr.span, attrs);
23892389
Ok(expr)
23902390
}
23912391

@@ -2394,8 +2394,13 @@ impl<'a> Parser<'a> {
23942394
ctx_span: Span,
23952395
is_ctx_else: bool,
23962396
branch_span: Span,
2397-
attrs: &[ast::Attribute],
2397+
attrs: AttrWrapper,
23982398
) {
2399+
if attrs.is_empty() {
2400+
return;
2401+
}
2402+
2403+
let attrs: &[ast::Attribute] = &attrs.take_for_recovery(self.sess);
23992404
let (attributes, last) = match attrs {
24002405
[] => return,
24012406
[x0 @ xn] | [x0, .., xn] => (x0.span.to(xn.span), xn.span),

Diff for: compiler/rustc_parse/src/parser/stmt.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_ast as ast;
1919
use rustc_ast::ptr::P;
2020
use rustc_ast::token::{self, Delimiter, TokenKind};
2121
use rustc_ast::util::classify;
22-
use rustc_ast::{AttrStyle, AttrVec, Attribute, LocalKind, MacCall, MacCallStmt, MacStmtStyle};
22+
use rustc_ast::{AttrStyle, AttrVec, LocalKind, MacCall, MacCallStmt, MacStmtStyle};
2323
use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, HasAttrs, Local, Stmt};
2424
use rustc_ast::{StmtKind, DUMMY_NODE_ID};
2525
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult};
@@ -101,7 +101,7 @@ impl<'a> Parser<'a> {
101101
self.mk_stmt(lo.to(item.span), StmtKind::Item(P(item)))
102102
} else if self.eat(&token::Semi) {
103103
// Do not attempt to parse an expression if we're done here.
104-
self.error_outer_attrs(&attrs.take_for_recovery());
104+
self.error_outer_attrs(attrs);
105105
self.mk_stmt(lo, StmtKind::Empty)
106106
} else if self.token != token::CloseDelim(Delimiter::Brace) {
107107
// Remainder are line-expr stmts.
@@ -120,7 +120,7 @@ impl<'a> Parser<'a> {
120120
}
121121
self.mk_stmt(lo.to(e.span), StmtKind::Expr(e))
122122
} else {
123-
self.error_outer_attrs(&attrs.take_for_recovery());
123+
self.error_outer_attrs(attrs);
124124
return Ok(None);
125125
}))
126126
}
@@ -199,8 +199,10 @@ impl<'a> Parser<'a> {
199199

200200
/// Error on outer attributes in this context.
201201
/// Also error if the previous token was a doc comment.
202-
fn error_outer_attrs(&self, attrs: &[Attribute]) {
203-
if let [.., last] = attrs {
202+
fn error_outer_attrs(&self, attrs: AttrWrapper) {
203+
if !attrs.is_empty()
204+
&& let attrs = attrs.take_for_recovery(self.sess)
205+
&& let attrs @ [.., last] = &*attrs {
204206
if last.is_doc_comment() {
205207
self.sess.emit_err(DocCommentDoesNotDocumentAnything {
206208
span: last.span,

0 commit comments

Comments
 (0)