Suggest {} around more bad const generic exprs
This commit is contained in:
parent
d3ad51b48f
commit
6b52ac240a
4 changed files with 121 additions and 18 deletions
|
@ -2030,7 +2030,7 @@ impl<'a> Parser<'a> {
|
|||
start: Span,
|
||||
mut err: DiagnosticBuilder<'a, ErrorReported>,
|
||||
) -> PResult<'a, GenericArg> {
|
||||
let is_op = AssocOp::from_token(&self.token)
|
||||
let is_op_or_dot = AssocOp::from_token(&self.token)
|
||||
.and_then(|op| {
|
||||
if let AssocOp::Greater
|
||||
| AssocOp::Less
|
||||
|
@ -2046,17 +2046,18 @@ impl<'a> Parser<'a> {
|
|||
Some(op)
|
||||
}
|
||||
})
|
||||
.is_some();
|
||||
.is_some()
|
||||
|| self.token.kind == TokenKind::Dot;
|
||||
// This will be true when a trait object type `Foo +` or a path which was a `const fn` with
|
||||
// type params has been parsed.
|
||||
let was_op =
|
||||
matches!(self.prev_token.kind, token::BinOp(token::Plus | token::Shr) | token::Gt);
|
||||
if !is_op && !was_op {
|
||||
if !is_op_or_dot && !was_op {
|
||||
// We perform these checks and early return to avoid taking a snapshot unnecessarily.
|
||||
return Err(err);
|
||||
}
|
||||
let snapshot = self.clone();
|
||||
if is_op {
|
||||
if is_op_or_dot {
|
||||
self.bump();
|
||||
}
|
||||
match self.parse_expr_res(Restrictions::CONST_EXPR, None) {
|
||||
|
@ -2080,18 +2081,7 @@ impl<'a> Parser<'a> {
|
|||
// |
|
||||
// LL | let sr: Vec<{ (u32, _, _) = vec![] };
|
||||
// | ^ ^
|
||||
err.multipart_suggestion(
|
||||
"expressions must be enclosed in braces to be used as const generic \
|
||||
arguments",
|
||||
vec![
|
||||
(start.shrink_to_lo(), "{ ".to_string()),
|
||||
(expr.span.shrink_to_hi(), " }".to_string()),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
let value = self.mk_expr_err(start.to(expr.span));
|
||||
err.emit();
|
||||
return Ok(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value }));
|
||||
return Ok(self.dummy_const_arg_needs_braces(err, start.to(expr.span)));
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
|
@ -2102,6 +2092,23 @@ impl<'a> Parser<'a> {
|
|||
Err(err)
|
||||
}
|
||||
|
||||
/// Creates a dummy const argument, and reports that the expression must be enclosed in braces
|
||||
pub fn dummy_const_arg_needs_braces(
|
||||
&self,
|
||||
mut err: DiagnosticBuilder<'a, ErrorReported>,
|
||||
span: Span,
|
||||
) -> GenericArg {
|
||||
err.multipart_suggestion(
|
||||
"expressions must be enclosed in braces to be used as const generic \
|
||||
arguments",
|
||||
vec![(span.shrink_to_lo(), "{ ".to_string()), (span.shrink_to_hi(), " }".to_string())],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
let value = self.mk_expr_err(span);
|
||||
err.emit();
|
||||
GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value })
|
||||
}
|
||||
|
||||
/// Get the diagnostics for the cases where `move async` is found.
|
||||
///
|
||||
/// `move_async_span` starts at the 'm' of the move keyword and ends with the 'c' of the async keyword
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
|
||||
use super::{Parser, TokenType};
|
||||
use super::{Parser, Restrictions, TokenType};
|
||||
use crate::maybe_whole;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, Token};
|
||||
|
@ -634,7 +634,22 @@ impl<'a> Parser<'a> {
|
|||
} else if self.token.is_keyword(kw::Const) {
|
||||
return self.recover_const_param_declaration(ty_generics);
|
||||
} else {
|
||||
return Ok(None);
|
||||
// Fall back by trying to parse a const-expr expression. If we successfully do so,
|
||||
// then we should report an error that it needs to be wrapped in braces.
|
||||
let snapshot = self.clone();
|
||||
match self.parse_expr_res(Restrictions::CONST_EXPR, None) {
|
||||
Ok(expr) => {
|
||||
return Ok(Some(self.dummy_const_arg_needs_braces(
|
||||
self.struct_span_err(expr.span, "invalid const generic expression"),
|
||||
expr.span,
|
||||
)));
|
||||
}
|
||||
Err(err) => {
|
||||
*self = snapshot;
|
||||
err.cancel();
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(Some(arg))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue