未验证 提交 3cca3c6a 编写于 作者: M Mazdak Farrokhzad 提交者: GitHub

Rollup merge of #67744 - Centril:reduce-diversity, r=petrochenkov

parser: reduce diversity in error handling mechanisms

Instead of having e.g. `span_err`, `fatal`, etc., we prefer to move towards uniformly using `struct_span_err` thus making it harder to emit fatal and/or unstructured diagnostics.

This PR also de-fatalizes some diagnostics.

r? @estebank
......@@ -890,12 +890,12 @@ fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a,
Ok(match name {
sym::item => match p.parse_item()? {
Some(i) => token::NtItem(i),
None => return Err(p.fatal("expected an item keyword")),
None => return Err(p.struct_span_err(p.token.span, "expected an item keyword")),
},
sym::block => token::NtBlock(p.parse_block()?),
sym::stmt => match p.parse_stmt()? {
Some(s) => token::NtStmt(s),
None => return Err(p.fatal("expected a statement")),
None => return Err(p.struct_span_err(p.token.span, "expected a statement")),
},
sym::pat => token::NtPat(p.parse_pat(None)?),
sym::expr => token::NtExpr(p.parse_expr()?),
......@@ -909,7 +909,8 @@ fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a,
token::NtIdent(Ident::new(name, span), is_raw)
} else {
let token_str = pprust::token_to_string(&p.token);
return Err(p.fatal(&format!("expected ident, found {}", &token_str)));
let msg = &format!("expected ident, found {}", &token_str);
return Err(p.struct_span_err(p.token.span, msg));
}
}
sym::path => token::NtPath(p.parse_path(PathStyle::Type)?),
......@@ -920,7 +921,8 @@ fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a,
token::NtLifetime(p.expect_lifetime().ident)
} else {
let token_str = pprust::token_to_string(&p.token);
return Err(p.fatal(&format!("expected a lifetime, found `{}`", &token_str)));
let msg = &format!("expected a lifetime, found `{}`", &token_str);
return Err(p.struct_span_err(p.token.span, msg));
}
}
// this is not supposed to happen, since it has been checked
......
......@@ -46,7 +46,8 @@ pub(super) fn parse_outer_attributes(&mut self) -> PResult<'a, Vec<ast::Attribut
token::DocComment(s) => {
let attr = self.mk_doc_comment(s);
if attr.style != ast::AttrStyle::Outer {
let mut err = self.fatal("expected outer doc comment");
let span = self.token.span;
let mut err = self.struct_span_err(span, "expected outer doc comment");
err.note(
"inner doc comments like this (starting with \
`//!` or `/*!`) can only appear before items",
......@@ -133,7 +134,7 @@ fn parse_attribute_with_inner_parse_policy(
"previous outer attribute"
};
let mut diagnostic = self.diagnostic().struct_span_err(attr_sp, reason);
let mut diagnostic = self.struct_span_err(attr_sp, reason);
if let Some(prev_attr_sp) = prev_attr_sp {
diagnostic
......@@ -156,7 +157,8 @@ fn parse_attribute_with_inner_parse_policy(
}
_ => {
let token_str = pprust::token_to_string(&self.token);
return Err(self.fatal(&format!("expected `#`, found `{}`", token_str)));
let msg = &format!("expected `#`, found `{}`", token_str);
return Err(self.struct_span_err(self.token.span, msg));
}
};
......@@ -231,8 +233,7 @@ pub fn parse_attr_item(&mut self) -> PResult<'a, ast::AttrItem> {
if !lit.kind.is_unsuffixed() {
let msg = "suffixed literals are not allowed in attributes";
self.diagnostic()
.struct_span_err(lit.span, msg)
self.struct_span_err(lit.span, msg)
.help(
"instead of using a suffixed literal \
(1u8, 1.0f32, etc.), use an unsuffixed version \
......@@ -332,6 +333,6 @@ fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> {
let found = pprust::token_to_string(&self.token);
let msg = format!("expected unsuffixed literal or identifier, found `{}`", found);
Err(self.diagnostic().struct_span_err(self.token.span, &msg))
Err(self.struct_span_err(self.token.span, &msg))
}
}
......@@ -157,14 +157,6 @@ fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self {
}
impl<'a> Parser<'a> {
pub fn fatal(&self, m: &str) -> DiagnosticBuilder<'a> {
self.span_fatal(self.token.span, m)
}
crate fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
self.sess.span_diagnostic.struct_span_fatal(sp, m)
}
pub(super) fn span_fatal_err<S: Into<MultiSpan>>(
&self,
sp: S,
......@@ -173,14 +165,6 @@ pub(super) fn span_fatal_err<S: Into<MultiSpan>>(
err.span_err(sp, self.diagnostic())
}
pub(super) fn bug(&self, m: &str) -> ! {
self.sess.span_diagnostic.span_bug(self.token.span, m)
}
pub(super) fn span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) {
self.sess.span_diagnostic.span_err(sp, m)
}
pub fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
self.sess.span_diagnostic.struct_span_err(sp, m)
}
......@@ -298,7 +282,7 @@ fn tokens_to_string(tokens: &[TokenType]) -> String {
)
};
self.last_unexpected_token_span = Some(self.token.span);
let mut err = self.fatal(&msg_exp);
let mut err = self.struct_span_err(self.token.span, &msg_exp);
let sp = if self.token == token::Eof {
// This is EOF; don't want to point at the following char, but rather the last token.
self.prev_span
......@@ -502,18 +486,17 @@ pub(super) fn check_trailing_angle_brackets(&mut self, segment: &PathSegment, en
let span = lo.until(self.token.span);
let total_num_of_gt = number_of_gt + number_of_shr * 2;
self.diagnostic()
.struct_span_err(
span,
&format!("unmatched angle bracket{}", pluralize!(total_num_of_gt)),
)
.span_suggestion(
span,
&format!("remove extra angle bracket{}", pluralize!(total_num_of_gt)),
String::new(),
Applicability::MachineApplicable,
)
.emit();
self.struct_span_err(
span,
&format!("unmatched angle bracket{}", pluralize!(total_num_of_gt)),
)
.span_suggestion(
span,
&format!("remove extra angle bracket{}", pluralize!(total_num_of_gt)),
String::new(),
Applicability::MachineApplicable,
)
.emit();
}
}
......@@ -762,8 +745,7 @@ pub(super) fn maybe_recover_from_bad_qpath_stage_2<T: RecoverQPath>(
path.span = ty_span.to(self.prev_span);
let ty_str = self.span_to_snippet(ty_span).unwrap_or_else(|_| pprust::ty_to_string(&ty));
self.diagnostic()
.struct_span_err(path.span, "missing angle brackets in associated item path")
self.struct_span_err(path.span, "missing angle brackets in associated item path")
.span_suggestion(
// This is a best-effort recovery.
path.span,
......@@ -1271,7 +1253,8 @@ pub(super) fn check_for_for_in_in_typo(&mut self, in_span: Span) {
pub(super) fn expected_semi_or_open_brace<T>(&mut self) -> PResult<'a, T> {
let token_str = super::token_descr(&self.token);
let mut err = self.fatal(&format!("expected `;` or `{{`, found {}", token_str));
let msg = &format!("expected `;` or `{{`, found {}", token_str);
let mut err = self.struct_span_err(self.token.span, msg);
err.span_label(self.token.span, "expected `;` or `{`");
Err(err)
}
......
......@@ -283,7 +283,7 @@ pub(super) fn parse_assoc_expr_with(
self.mk_expr(span, aopexpr, AttrVec::new())
}
AssocOp::As | AssocOp::Colon | AssocOp::DotDot | AssocOp::DotDotEq => {
self.bug("AssocOp should have been handled by special case")
self.span_bug(span, "AssocOp should have been handled by special case")
}
};
......@@ -822,7 +822,11 @@ fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Exp
} else {
// Field access `expr.f`
if let Some(args) = segment.args {
self.span_err(args.span(), "field expressions may not have generic arguments");
self.struct_span_err(
args.span(),
"field expressions may not have generic arguments",
)
.emit();
}
let span = lo.to(self.prev_span);
......@@ -1133,7 +1137,7 @@ pub fn parse_str_lit(&mut self) -> Result<ast::StrLit, Option<Lit>> {
pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
self.parse_opt_lit().ok_or_else(|| {
let msg = format!("unexpected token: {}", super::token_descr(&self.token));
self.span_fatal(self.token.span, &msg)
self.struct_span_err(self.token.span, &msg)
})
}
......@@ -1446,9 +1450,7 @@ fn error_missing_if_cond(&self, lo: Span, span: Span) -> P<ast::Block> {
self.struct_span_err(sp, "missing condition for `if` expression")
.span_label(sp, "expected if condition here")
.emit();
let expr = self.mk_expr_err(span);
let stmt = self.mk_stmt(span, ast::StmtKind::Expr(expr));
self.mk_block(vec![stmt], BlockCheckMode::Default, span)
self.mk_block_err(span)
}
/// Parses the condition of a `if` or `while` expression.
......@@ -1915,8 +1917,7 @@ fn error_on_eq_field_init(&self, field_name: Ident) {
return;
}
self.diagnostic()
.struct_span_err(self.token.span, "expected `:`, found `=`")
self.struct_span_err(self.token.span, "expected `:`, found `=`")
.span_suggestion(
field_name.span.shrink_to_hi().to(self.token.span),
"replace equals symbol with a colon",
......
......@@ -306,8 +306,7 @@ fn parse_item_implementation(
// possible public struct definition where `struct` was forgotten
let ident = self.parse_ident().unwrap();
let msg = format!("add `struct` here to parse `{}` as a public struct", ident);
let mut err =
self.diagnostic().struct_span_err(sp, "missing `struct` for struct definition");
let mut err = self.struct_span_err(sp, "missing `struct` for struct definition");
err.span_suggestion_short(
sp,
&msg,
......@@ -335,7 +334,7 @@ fn parse_item_implementation(
};
let msg = format!("missing `{}` for {} definition", kw, kw_name);
let mut err = self.diagnostic().struct_span_err(sp, &msg);
let mut err = self.struct_span_err(sp, &msg);
if !ambiguous {
self.consume_block(token::Brace, ConsumeClosingDelim::Yes);
let suggestion =
......@@ -375,7 +374,7 @@ fn parse_item_implementation(
("fn` or `struct", "function or struct", true)
};
let msg = format!("missing `{}` for {} definition", kw, kw_name);
let mut err = self.diagnostic().struct_span_err(sp, &msg);
let mut err = self.struct_span_err(sp, &msg);
if !ambiguous {
err.span_suggestion_short(
sp,
......@@ -446,9 +445,7 @@ fn parse_macro_use_or_failure(
// FAILURE TO PARSE ITEM
match visibility.node {
VisibilityKind::Inherited => {}
_ => {
return Err(self.span_fatal(self.prev_span, "unmatched visibility `pub`"));
}
_ => return Err(self.struct_span_err(self.prev_span, "unmatched visibility `pub`")),
}
if !attributes_allowed && !attrs.is_empty() {
......@@ -466,7 +463,7 @@ fn expected_item_err(&mut self, attrs: &[Attribute]) -> PResult<'a, ()> {
_ => "expected item after attributes",
};
let mut err = self.diagnostic().struct_span_err(self.prev_span, message);
let mut err = self.struct_span_err(self.prev_span, message);
if attrs.last().unwrap().is_doc_comment() {
err.span_label(self.prev_span, "this doc comment doesn't document anything");
}
......@@ -536,7 +533,6 @@ fn missing_assoc_item_kind_err(
// ^^ `sp` below will point to this
let sp = prev_span.between(self.prev_span);
let mut err = self
.diagnostic()
.struct_span_err(sp, &format!("{} for {}-item declaration", expected_kinds, item_type));
err.span_label(sp, expected_kinds);
err
......@@ -619,7 +615,7 @@ fn parse_item_impl(
// This notably includes paths passed through `ty` macro fragments (#46438).
TyKind::Path(None, path) => path,
_ => {
self.span_err(ty_first.span, "expected a trait, found type");
self.struct_span_err(ty_first.span, "expected a trait, found type").emit();
err_path(ty_first.span)
}
};
......@@ -1349,10 +1345,11 @@ fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> {
body
} else {
let token_str = super::token_descr(&self.token);
let mut err = self.fatal(&format!(
let msg = &format!(
"expected `where`, `{{`, `(`, or `;` after struct name, found {}",
token_str
));
);
let mut err = self.struct_span_err(self.token.span, msg);
err.span_label(self.token.span, "expected `where`, `{`, `(`, or `;` after struct name");
return Err(err);
};
......@@ -1375,8 +1372,8 @@ fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> {
VariantData::Struct(fields, recovered)
} else {
let token_str = super::token_descr(&self.token);
let mut err = self
.fatal(&format!("expected `where` or `{{` after union name, found {}", token_str));
let msg = &format!("expected `where` or `{{` after union name, found {}", token_str);
let mut err = self.struct_span_err(self.token.span, msg);
err.span_label(self.token.span, "expected `where` or `{` after union name");
return Err(err);
};
......@@ -1412,10 +1409,8 @@ fn parse_record_struct_body(
self.eat(&token::CloseDelim(token::Brace));
} else {
let token_str = super::token_descr(&self.token);
let mut err = self.fatal(&format!(
"expected `where`, or `{{` after struct name, found {}",
token_str
));
let msg = &format!("expected `where`, or `{{` after struct name, found {}", token_str);
let mut err = self.struct_span_err(self.token.span, msg);
err.span_label(self.token.span, "expected `where`, or `{` after struct name");
return Err(err);
}
......@@ -1603,9 +1598,8 @@ fn complain_if_pub_macro(&self, vis: &VisibilityKind, sp: Span) {
VisibilityKind::Inherited => {}
_ => {
let mut err = if self.token.is_keyword(sym::macro_rules) {
let mut err = self
.diagnostic()
.struct_span_err(sp, "can't qualify macro_rules invocation with `pub`");
let mut err =
self.struct_span_err(sp, "can't qualify macro_rules invocation with `pub`");
err.span_suggestion(
sp,
"try exporting the macro",
......@@ -1614,9 +1608,8 @@ fn complain_if_pub_macro(&self, vis: &VisibilityKind, sp: Span) {
);
err
} else {
let mut err = self
.diagnostic()
.struct_span_err(sp, "can't qualify macro invocation with `pub`");
let mut err =
self.struct_span_err(sp, "can't qualify macro invocation with `pub`");
err.help("try adjusting the macro to put `pub` inside the invocation");
err
};
......
......@@ -884,7 +884,8 @@ fn parse_paren_comma_seq<T>(
pub fn bump(&mut self) {
if self.prev_token_kind == PrevTokenKind::Eof {
// Bumping after EOF is a bad sign, usually an infinite loop.
self.bug("attempted to bump the parser past EOF (may be stuck in a loop)");
let msg = "attempted to bump the parser past EOF (may be stuck in a loop)";
self.span_bug(self.token.span, msg);
}
self.prev_span = self.meta_var_span.take().unwrap_or(self.token.span);
......@@ -1056,8 +1057,7 @@ pub fn process_potential_macro_variable(&mut self) {
_ => unreachable!(),
};
let span = self.prev_span.to(self.token.span);
self.diagnostic()
.struct_span_fatal(span, &format!("unknown macro variable `{}`", name))
self.struct_span_err(span, &format!("unknown macro variable `{}`", name))
.span_label(span, "unknown macro variable")
.emit();
self.bump();
......
......@@ -81,7 +81,8 @@ fn parse_mod_items(&mut self, term: &TokenKind, inner_lo: Span) -> PResult<'a, M
if !self.eat(term) {
let token_str = super::token_descr(&self.token);
if !self.maybe_consume_incorrect_semicolon(&items) {
let mut err = self.fatal(&format!("expected item, found {}", token_str));
let msg = &format!("expected item, found {}", token_str);
let mut err = self.struct_span_err(self.token.span, msg);
err.span_label(self.token.span, "expected item");
return Err(err);
}
......@@ -129,7 +130,7 @@ fn submod_path(
DirectoryOwnership::UnownedViaBlock => {
let msg = "Cannot declare a non-inline module inside a block \
unless it has a path attribute";
let mut err = self.diagnostic().struct_span_err(id_sp, msg);
let mut err = self.struct_span_err(id_sp, msg);
if paths.path_exists {
let msg = format!(
"Maybe `use` the module `{}` instead of redeclaring it",
......@@ -140,9 +141,8 @@ fn submod_path(
Err(err)
}
DirectoryOwnership::UnownedViaMod => {
let mut err = self
.diagnostic()
.struct_span_err(id_sp, "cannot declare a new module at this location");
let mut err =
self.struct_span_err(id_sp, "cannot declare a new module at this location");
if !id_sp.is_dummy() {
let src_path = self.sess.source_map().span_to_filename(id_sp);
if let FileName::Real(src_path) = src_path {
......@@ -263,7 +263,7 @@ fn eval_src_mod(
err.push_str(" -> ");
}
err.push_str(&path.to_string_lossy());
return Err(self.span_fatal(id_sp, &err[..]));
return Err(self.struct_span_err(id_sp, &err[..]));
}
included_mod_stack.push(path.clone());
drop(included_mod_stack);
......
......@@ -673,7 +673,7 @@ fn fatal_unexpected_non_pat(
let expected = expected.unwrap_or("pattern");
let msg = format!("expected {}, found {}", expected, super::token_descr(&self.token));
let mut err = self.fatal(&msg);
let mut err = self.struct_span_err(self.token.span, &msg);
err.span_label(self.token.span, format!("expected {}", expected));
let sp = self.sess.source_map().start_point(self.token.span);
......@@ -699,8 +699,7 @@ fn parse_pat_range_to(&mut self, re: RangeEnd, form: &str) -> PResult<'a, PatKin
let range_span = lo.to(end.span);
let begin = self.mk_expr(range_span, ExprKind::Err, AttrVec::new());
self.diagnostic()
.struct_span_err(range_span, &format!("`{}X` range patterns are not supported", form))
self.struct_span_err(range_span, &format!("`{}X` range patterns are not supported", form))
.span_suggestion(
range_span,
"try using the minimum value for the type",
......@@ -722,18 +721,17 @@ fn parse_pat_range_end_opt(&mut self, begin: &Expr, form: &str) -> PResult<'a, P
// Parsing e.g. `X..`.
let range_span = begin.span.to(self.prev_span);
self.diagnostic()
.struct_span_err(
range_span,
&format!("`X{}` range patterns are not supported", form),
)
.span_suggestion(
range_span,
"try using the maximum value for the type",
format!("{}{}MAX", pprust::expr_to_string(&begin), form),
Applicability::HasPlaceholders,
)
.emit();
self.struct_span_err(
range_span,
&format!("`X{}` range patterns are not supported", form),
)
.span_suggestion(
range_span,
"try using the maximum value for the type",
format!("{}{}MAX", pprust::expr_to_string(&begin), form),
Applicability::HasPlaceholders,
)
.emit();
Ok(self.mk_expr(range_span, ExprKind::Err, AttrVec::new()))
}
......@@ -798,7 +796,9 @@ fn parse_pat_ident(&mut self, binding_mode: BindingMode) -> PResult<'a, PatKind>
// binding mode then we do not end up here, because the lookahead
// will direct us over to `parse_enum_variant()`.
if self.token == token::OpenDelim(token::Paren) {
return Err(self.span_fatal(self.prev_span, "expected identifier, found enum pattern"));
return Err(
self.struct_span_err(self.prev_span, "expected identifier, found enum pattern")
);
}
Ok(PatKind::Ident(binding_mode, ident, sub))
......@@ -807,12 +807,8 @@ fn parse_pat_ident(&mut self, binding_mode: BindingMode) -> PResult<'a, PatKind>
/// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`).
fn parse_pat_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a, PatKind> {
if qself.is_some() {
let msg = "unexpected `{` after qualified path";
let mut err = self.fatal(msg);
err.span_label(self.token.span, msg);
return Err(err);
return self.error_qpath_before_pat(&path, "{");
}
self.bump();
let (fields, etc) = self.parse_pat_fields().unwrap_or_else(|mut e| {
e.emit();
......@@ -826,15 +822,22 @@ fn parse_pat_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a,
/// Parse tuple struct or tuple variant pattern (e.g. `Foo(...)` or `Foo::Bar(...)`).
fn parse_pat_tuple_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a, PatKind> {
if qself.is_some() {
let msg = "unexpected `(` after qualified path";
let mut err = self.fatal(msg);
err.span_label(self.token.span, msg);
return Err(err);
return self.error_qpath_before_pat(&path, "(");
}
let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or_inner())?;
Ok(PatKind::TupleStruct(path, fields))
}
/// Error when there's a qualified path, e.g. `<Foo as Bar>::Baz`
/// as the path of e.g., a tuple or record struct pattern.
fn error_qpath_before_pat(&mut self, path: &Path, token: &str) -> PResult<'a, PatKind> {
let msg = &format!("unexpected `{}` after qualified path", token);
let mut err = self.struct_span_err(self.token.span, msg);
err.span_label(self.token.span, msg);
err.span_label(path.span, "the qualified path");
Err(err)
}
/// Parses the fields of a struct-like pattern.
fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<FieldPat>, bool)> {
let mut fields = Vec::new();
......@@ -877,7 +880,8 @@ fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<FieldPat>, bool)> {
break;
}
let token_str = super::token_descr(&self.token);
let mut err = self.fatal(&format!("expected `}}`, found {}", token_str));
let msg = &format!("expected `}}`, found {}", token_str);
let mut err = self.struct_span_err(self.token.span, msg);
err.span_label(self.token.span, "expected `}`");
let mut comma_sp = None;
......
......@@ -93,7 +93,7 @@ pub fn parse_path(&mut self, style: PathStyle) -> PResult<'a, Path> {
maybe_whole!(self, NtPath, |path| {
if style == PathStyle::Mod && path.segments.iter().any(|segment| segment.args.is_some())
{
self.diagnostic().span_err(path.span, "unexpected generic arguments in path");
self.struct_span_err(path.span, "unexpected generic arguments in path").emit();
}
path
});
......@@ -325,24 +325,23 @@ fn parse_generic_args_with_leading_angle_bracket_recovery(
// Make a span over ${unmatched angle bracket count} characters.
let span = lo.with_hi(lo.lo() + BytePos(snapshot.unmatched_angle_bracket_count));
self.diagnostic()
.struct_span_err(
span,
&format!(
"unmatched angle bracket{}",
pluralize!(snapshot.unmatched_angle_bracket_count)
),
)
.span_suggestion(
span,
&format!(
"remove extra angle bracket{}",
pluralize!(snapshot.unmatched_angle_bracket_count)
),
String::new(),
Applicability::MachineApplicable,
)
.emit();
self.struct_span_err(
span,
&format!(
"unmatched angle bracket{}",
pluralize!(snapshot.unmatched_angle_bracket_count)
),
)
.span_suggestion(
span,
&format!(
"remove extra angle bracket{}",
pluralize!(snapshot.unmatched_angle_bracket_count)
),
String::new(),
Applicability::MachineApplicable,
)
.emit();
// Try again without unmatched angle bracket characters.
self.parse_generic_args()
......@@ -407,9 +406,11 @@ fn parse_generic_args(&mut self) -> PResult<'a, (Vec<GenericArg>, Vec<AssocTyCon
if self.token.is_bool_lit() {
self.parse_literal_maybe_minus()?
} else {
return Err(
self.fatal("identifiers may currently not be used for const generics")
);
let span = self.token.span;
let msg = "identifiers may currently not be used for const generics";
self.struct_span_err(span, msg).emit();
let block = self.mk_block_err(span);
self.mk_expr(span, ast::ExprKind::Block(block, None), ast::AttrVec::new())
}
} else {
self.parse_literal_maybe_minus()?
......
......@@ -193,7 +193,8 @@ fn error_outer_attrs(&self, attrs: &[Attribute]) {
if self.prev_token_kind == PrevTokenKind::DocComment {
self.span_fatal_err(self.prev_span, Error::UselessDocComment).emit();
} else if attrs.iter().any(|a| a.style == AttrStyle::Outer) {
self.span_err(self.token.span, "expected statement after outer attribute");
self.struct_span_err(self.token.span, "expected statement after outer attribute")
.emit();
}
}
}
......@@ -324,7 +325,7 @@ pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
fn error_block_no_opening_brace<T>(&mut self) -> PResult<'a, T> {
let sp = self.token.span;
let tok = super::token_descr(&self.token);
let mut e = self.span_fatal(sp, &format!("expected `{{`, found {}", tok));
let mut e = self.struct_span_err(sp, &format!("expected `{{`, found {}", tok));
let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon;
// Check to see if the user has written something like
......@@ -397,10 +398,7 @@ pub(super) fn parse_block_tail(
self.maybe_annotate_with_ascription(&mut err, false);
err.emit();
self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore);
Some(self.mk_stmt(
self.token.span,
StmtKind::Expr(self.mk_expr_err(self.token.span)),
))
Some(self.mk_stmt_err(self.token.span))
}
Ok(stmt) => stmt,
};
......@@ -478,4 +476,12 @@ pub(super) fn mk_block(&self, stmts: Vec<Stmt>, rules: BlockCheckMode, span: Spa
pub(super) fn mk_stmt(&self, span: Span, kind: StmtKind) -> Stmt {
Stmt { id: DUMMY_NODE_ID, kind, span }
}
fn mk_stmt_err(&self, span: Span) -> Stmt {
self.mk_stmt(span, StmtKind::Expr(self.mk_expr_err(span)))
}
pub(super) fn mk_block_err(&self, span: Span) -> P<Block> {
self.mk_block(vec![self.mk_stmt_err(span)], BlockCheckMode::Default, span)
}
}
......@@ -175,7 +175,9 @@ fn parse_ty_tuple_or_parens(&mut self, lo: Span, allow_plus: bool) -> PResult<'a
{
let path = match bounds.remove(0) {
GenericBound::Trait(pt, ..) => pt.trait_ref.path,
GenericBound::Outlives(..) => self.bug("unexpected lifetime bound"),
GenericBound::Outlives(..) => {
self.span_bug(ty.span, "unexpected lifetime bound")
}
};
self.parse_remaining_bounds(Vec::new(), path, lo, true)
}
......
......@@ -112,3 +112,4 @@ fn main() {}
#[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } }
//~^ ERROR expected statement after outer attribute
#[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } }
//~^ ERROR expected statement after outer attribute
......@@ -410,5 +410,11 @@ error: expected statement after outer attribute
LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } }
| ^
error: aborting due to 56 previous errors
error: expected statement after outer attribute
--> $DIR/attr-stmt-expr-attr-bad.rs:114:45
|
LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } }
| ^
error: aborting due to 57 previous errors
......@@ -2,7 +2,9 @@ error: unexpected `{` after qualified path
--> $DIR/brace-after-qualified-path-in-match.rs:3:27
|
LL | <T as Trait>::Type{key: value} => (),
| ^ unexpected `{` after qualified path
| ------------------^ unexpected `{` after qualified path
| |
| the qualified path
error: aborting due to previous error
......@@ -2,7 +2,9 @@ error: unexpected `(` after qualified path
--> $DIR/paren-after-qualified-path-in-match.rs:3:27
|
LL | <T as Trait>::Type(2) => (),
| ^ unexpected `(` after qualified path
| ------------------^ unexpected `(` after qualified path
| |
| the qualified path
error: aborting due to previous error
......@@ -5,11 +5,12 @@ LL | Some(vec![_x]) => (),
| ^^^^^^^^
| |
| unexpected `(` after qualified path
| the qualified path
| in this macro invocation
| help: use a slice pattern here instead: `[_x]`
|
= help: for more information, see https://doc.rust-lang.org/edition-guide/rust-2018/slice-patterns.html
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: aborting due to previous error
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册