Migrate more rustc_parse diagnostics to diagnostic structs
This commit is contained in:
parent
e56d6a68db
commit
e1b1d7b029
9 changed files with 192 additions and 160 deletions
|
@ -188,7 +188,8 @@ parser_parentheses_with_struct_fields = invalid `struct` delimiters or `fn` call
|
||||||
.suggestion_no_fields_for_fn = if `{$name}` is a function, use the arguments directly
|
.suggestion_no_fields_for_fn = if `{$name}` is a function, use the arguments directly
|
||||||
|
|
||||||
parser_labeled_loop_in_break = parentheses are required around this expression to avoid confusion with a labeled break expression
|
parser_labeled_loop_in_break = parentheses are required around this expression to avoid confusion with a labeled break expression
|
||||||
.suggestion = wrap the expression in parentheses
|
|
||||||
|
parser_sugg_wrap_expression_in_parentheses = wrap the expression in parentheses
|
||||||
|
|
||||||
parser_array_brackets_instead_of_braces = this is a block expression, not an array
|
parser_array_brackets_instead_of_braces = this is a block expression, not an array
|
||||||
.suggestion = to make an array, use square brackets instead of curly braces
|
.suggestion = to make an array, use square brackets instead of curly braces
|
||||||
|
@ -231,3 +232,33 @@ parser_mismatched_closing_delimiter = mismatched closing delimiter: `{$delimiter
|
||||||
.label_unmatched = mismatched closing delimiter
|
.label_unmatched = mismatched closing delimiter
|
||||||
.label_opening_candidate = closing delimiter possibly meant for this
|
.label_opening_candidate = closing delimiter possibly meant for this
|
||||||
.label_unclosed = unclosed delimiter
|
.label_unclosed = unclosed delimiter
|
||||||
|
|
||||||
|
parser_incorrect_visibility_restriction = incorrect visibility restriction
|
||||||
|
.help = some possible visibility restrictions are:
|
||||||
|
`pub(crate)`: visible only on the current crate
|
||||||
|
`pub(super)`: visible only in the current module's parent
|
||||||
|
`pub(in path::to::module)`: visible only on the specified path
|
||||||
|
.suggestion = make this visible only to module `{$inner_str}` with `in`
|
||||||
|
|
||||||
|
parser_assignment_else_not_allowed = <assignment> ... else {"{"} ... {"}"} is not allowed
|
||||||
|
|
||||||
|
parser_expected_statement_after_outer_attr = expected statement after outer attribute
|
||||||
|
|
||||||
|
parser_doc_comment_does_not_document_anything = found a documentation comment that doesn't document anything
|
||||||
|
.help = doc comments must come before what they document, maybe a comment was intended with `//`?
|
||||||
|
.suggestion = missing comma here
|
||||||
|
|
||||||
|
parser_const_let_mutually_exclusive = `const` and `let` are mutually exclusive
|
||||||
|
.suggestion = remove `let`
|
||||||
|
|
||||||
|
parser_invalid_expression_in_let_else = a `{$operator}` expression cannot be directly assigned in `let...else`
|
||||||
|
parser_invalid_curly_in_let_else = right curly brace `{"}"}` before `else` in a `let...else` statement not allowed
|
||||||
|
|
||||||
|
parser_compound_assignment_expression_in_let = can't reassign to an uninitialized variable
|
||||||
|
.suggestion = initialize the variable
|
||||||
|
.help = if you meant to overwrite, remove the `let` binding
|
||||||
|
|
||||||
|
parser_suffixed_literal_in_attribute = suffixed literals are not allowed in attributes
|
||||||
|
.help = instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
|
||||||
|
|
||||||
|
parser_invalid_meta_item = expected unsuffixed literal or identifier, found `{$token}`
|
||||||
|
|
|
@ -624,16 +624,19 @@ pub(crate) struct LabeledLoopInBreak {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
pub sub: LabeledLoopInBreakSub,
|
pub sub: WrapExpressionInParentheses,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
|
#[multipart_suggestion(
|
||||||
pub(crate) struct LabeledLoopInBreakSub {
|
parser::sugg_wrap_expression_in_parentheses,
|
||||||
|
applicability = "machine-applicable"
|
||||||
|
)]
|
||||||
|
pub(crate) struct WrapExpressionInParentheses {
|
||||||
#[suggestion_part(code = "(")]
|
#[suggestion_part(code = "(")]
|
||||||
pub first: Span,
|
pub left: Span,
|
||||||
#[suggestion_part(code = ")")]
|
#[suggestion_part(code = ")")]
|
||||||
pub second: Span,
|
pub right: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
@ -781,3 +784,89 @@ pub(crate) struct MismatchedClosingDelimiter {
|
||||||
#[label(parser::label_unclosed)]
|
#[label(parser::label_unclosed)]
|
||||||
pub unclosed: Option<Span>,
|
pub unclosed: Option<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parser::incorrect_visibility_restriction, code = "E0704")]
|
||||||
|
#[help]
|
||||||
|
pub(crate) struct IncorrectVisibilityRestriction {
|
||||||
|
#[primary_span]
|
||||||
|
#[suggestion(code = "in {inner_str}", applicability = "machine-applicable")]
|
||||||
|
pub span: Span,
|
||||||
|
pub inner_str: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parser::assignment_else_not_allowed)]
|
||||||
|
pub(crate) struct AssignmentElseNotAllowed {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parser::expected_statement_after_outer_attr)]
|
||||||
|
pub(crate) struct ExpectedStatementAfterOuterAttr {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parser::doc_comment_does_not_document_anything, code = "E0585")]
|
||||||
|
#[help]
|
||||||
|
pub(crate) struct DocCommentDoesNotDocumentAnything {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
#[suggestion(code = ",", applicability = "machine-applicable")]
|
||||||
|
pub missing_comma: Option<Span>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parser::const_let_mutually_exclusive)]
|
||||||
|
pub(crate) struct ConstLetMutuallyExclusive {
|
||||||
|
#[primary_span]
|
||||||
|
#[suggestion(code = "const", applicability = "maybe-incorrect")]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parser::invalid_expression_in_let_else)]
|
||||||
|
pub(crate) struct InvalidExpressionInLetElse {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub operator: &'static str,
|
||||||
|
#[subdiagnostic]
|
||||||
|
pub sugg: WrapExpressionInParentheses,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parser::invalid_curly_in_let_else)]
|
||||||
|
pub(crate) struct InvalidCurlyInLetElse {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
#[subdiagnostic]
|
||||||
|
pub sugg: WrapExpressionInParentheses,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parser::compound_assignment_expression_in_let)]
|
||||||
|
#[help]
|
||||||
|
pub(crate) struct CompoundAssignmentExpressionInLet {
|
||||||
|
#[primary_span]
|
||||||
|
#[suggestion_short(code = "=", applicability = "maybe-incorrect")]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parser::suffixed_literal_in_attribute)]
|
||||||
|
#[help]
|
||||||
|
pub(crate) struct SuffixedLiteralInAttribute {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parser::invalid_meta_item)]
|
||||||
|
pub(crate) struct InvalidMetaItem {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub token: String,
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
use crate::errors::{InvalidMetaItem, SuffixedLiteralInAttribute};
|
||||||
|
|
||||||
use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle};
|
use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle};
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_ast::attr;
|
use rustc_ast::attr;
|
||||||
use rustc_ast::token::{self, Delimiter, Nonterminal};
|
use rustc_ast::token::{self, Delimiter, Nonterminal};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_errors::{error_code, Diagnostic, PResult};
|
use rustc_errors::{error_code, Diagnostic, IntoDiagnostic, PResult};
|
||||||
use rustc_span::{sym, BytePos, Span};
|
use rustc_span::{sym, BytePos, Span};
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
|
@ -337,12 +339,7 @@ impl<'a> Parser<'a> {
|
||||||
debug!("checking if {:?} is unusuffixed", lit);
|
debug!("checking if {:?} is unusuffixed", lit);
|
||||||
|
|
||||||
if !lit.kind.is_unsuffixed() {
|
if !lit.kind.is_unsuffixed() {
|
||||||
self.struct_span_err(lit.span, "suffixed literals are not allowed in attributes")
|
self.sess.emit_err(SuffixedLiteralInAttribute { span: lit.span });
|
||||||
.help(
|
|
||||||
"instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), \
|
|
||||||
use an unsuffixed version (`1`, `1.0`, etc.)",
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(lit)
|
Ok(lit)
|
||||||
|
@ -435,9 +432,9 @@ impl<'a> Parser<'a> {
|
||||||
Err(err) => err.cancel(),
|
Err(err) => err.cancel(),
|
||||||
}
|
}
|
||||||
|
|
||||||
let found = pprust::token_to_string(&self.token);
|
let token = pprust::token_to_string(&self.token).to_string();
|
||||||
let msg = format!("expected unsuffixed literal or identifier, found `{found}`");
|
Err(InvalidMetaItem { span: self.token.span, token }
|
||||||
Err(self.struct_span_err(self.token.span, &msg))
|
.into_diagnostic(&self.sess.span_diagnostic))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,34 +55,6 @@ pub(super) fn dummy_arg(ident: Ident) -> Param {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Error {
|
|
||||||
UselessDocComment,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error {
|
|
||||||
fn span_err(
|
|
||||||
self,
|
|
||||||
sp: impl Into<MultiSpan>,
|
|
||||||
handler: &Handler,
|
|
||||||
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
|
||||||
match self {
|
|
||||||
Error::UselessDocComment => {
|
|
||||||
let mut err = struct_span_err!(
|
|
||||||
handler,
|
|
||||||
sp,
|
|
||||||
E0585,
|
|
||||||
"found a documentation comment that doesn't document anything",
|
|
||||||
);
|
|
||||||
err.help(
|
|
||||||
"doc comments must come before what they document, maybe a comment was \
|
|
||||||
intended with `//`?",
|
|
||||||
);
|
|
||||||
err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) trait RecoverQPath: Sized + 'static {
|
pub(super) trait RecoverQPath: Sized + 'static {
|
||||||
const PATH_STYLE: PathStyle = PathStyle::Expr;
|
const PATH_STYLE: PathStyle = PathStyle::Expr;
|
||||||
fn to_ty(&self) -> Option<P<Ty>>;
|
fn to_ty(&self) -> Option<P<Ty>>;
|
||||||
|
@ -268,15 +240,6 @@ impl<'a> DerefMut for SnapshotParser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Parser<'a> {
|
impl<'a> Parser<'a> {
|
||||||
#[rustc_lint_diagnostics]
|
|
||||||
pub(super) fn span_err<S: Into<MultiSpan>>(
|
|
||||||
&self,
|
|
||||||
sp: S,
|
|
||||||
err: Error,
|
|
||||||
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
|
||||||
err.span_err(sp, self.diagnostic())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[rustc_lint_diagnostics]
|
#[rustc_lint_diagnostics]
|
||||||
pub fn struct_span_err<S: Into<MultiSpan>>(
|
pub fn struct_span_err<S: Into<MultiSpan>>(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -17,14 +17,14 @@ use crate::errors::{
|
||||||
InvalidIntLiteralWidth, InvalidInterpolatedExpression, InvalidLiteralSuffix,
|
InvalidIntLiteralWidth, InvalidInterpolatedExpression, InvalidLiteralSuffix,
|
||||||
InvalidLiteralSuffixOnTupleIndex, InvalidLogicalOperator, InvalidLogicalOperatorSub,
|
InvalidLiteralSuffixOnTupleIndex, InvalidLogicalOperator, InvalidLogicalOperatorSub,
|
||||||
InvalidNumLiteralBasePrefix, InvalidNumLiteralSuffix, LabeledLoopInBreak,
|
InvalidNumLiteralBasePrefix, InvalidNumLiteralSuffix, LabeledLoopInBreak,
|
||||||
LabeledLoopInBreakSub, LeadingPlusNotSupported, LeftArrowOperator, LifetimeInBorrowExpression,
|
LeadingPlusNotSupported, LeftArrowOperator, LifetimeInBorrowExpression,
|
||||||
MacroInvocationWithQualifiedPath, MalformedLoopLabel, MatchArmBodyWithoutBraces,
|
MacroInvocationWithQualifiedPath, MalformedLoopLabel, MatchArmBodyWithoutBraces,
|
||||||
MatchArmBodyWithoutBracesSugg, MissingCommaAfterMatchArm, MissingInInForLoop,
|
MatchArmBodyWithoutBracesSugg, MissingCommaAfterMatchArm, MissingInInForLoop,
|
||||||
MissingInInForLoopSub, MissingSemicolonBeforeArray, NoFieldsForFnCall, NotAsNegationOperator,
|
MissingInInForLoopSub, MissingSemicolonBeforeArray, NoFieldsForFnCall, NotAsNegationOperator,
|
||||||
NotAsNegationOperatorSub, OctalFloatLiteralNotSupported, OuterAttributeNotAllowedOnIfElse,
|
NotAsNegationOperatorSub, OctalFloatLiteralNotSupported, OuterAttributeNotAllowedOnIfElse,
|
||||||
ParenthesesWithStructFields, RequireColonAfterLabeledExpression, ShiftInterpretedAsGeneric,
|
ParenthesesWithStructFields, RequireColonAfterLabeledExpression, ShiftInterpretedAsGeneric,
|
||||||
StructLiteralNotAllowedHere, StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator,
|
StructLiteralNotAllowedHere, StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator,
|
||||||
UnexpectedTokenAfterLabel, UnexpectedTokenAfterLabelSugg,
|
UnexpectedTokenAfterLabel, UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses,
|
||||||
};
|
};
|
||||||
use crate::maybe_recover_from_interpolated_ty_qpath;
|
use crate::maybe_recover_from_interpolated_ty_qpath;
|
||||||
|
|
||||||
|
@ -1661,9 +1661,9 @@ impl<'a> Parser<'a> {
|
||||||
let lexpr = self.parse_labeled_expr(label.take().unwrap(), true)?;
|
let lexpr = self.parse_labeled_expr(label.take().unwrap(), true)?;
|
||||||
self.sess.emit_err(LabeledLoopInBreak {
|
self.sess.emit_err(LabeledLoopInBreak {
|
||||||
span: lexpr.span,
|
span: lexpr.span,
|
||||||
sub: LabeledLoopInBreakSub {
|
sub: WrapExpressionInParentheses {
|
||||||
first: lexpr.span.shrink_to_lo(),
|
left: lexpr.span.shrink_to_lo(),
|
||||||
second: lexpr.span.shrink_to_hi(),
|
right: lexpr.span.shrink_to_hi(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
Some(lexpr)
|
Some(lexpr)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::errors::UseEmptyBlockNotSemi;
|
use crate::errors::{DocCommentDoesNotDocumentAnything, UseEmptyBlockNotSemi};
|
||||||
|
|
||||||
use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error};
|
use super::diagnostics::{dummy_arg, ConsumeClosingDelim};
|
||||||
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
|
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
|
||||||
use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
|
use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, Vari
|
||||||
use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
|
use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
|
||||||
use rustc_ast::{MacArgs, MacCall, MacDelimiter};
|
use rustc_ast::{MacArgs, MacCall, MacDelimiter};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_errors::{struct_span_err, Applicability, PResult, StashKey};
|
use rustc_errors::{struct_span_err, Applicability, IntoDiagnostic, PResult, StashKey};
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
use rustc_span::lev_distance::lev_distance;
|
use rustc_span::lev_distance::lev_distance;
|
||||||
use rustc_span::source_map::{self, Span};
|
use rustc_span::source_map::{self, Span};
|
||||||
|
@ -1586,7 +1586,10 @@ impl<'a> Parser<'a> {
|
||||||
token::CloseDelim(Delimiter::Brace) => {}
|
token::CloseDelim(Delimiter::Brace) => {}
|
||||||
token::DocComment(..) => {
|
token::DocComment(..) => {
|
||||||
let previous_span = self.prev_token.span;
|
let previous_span = self.prev_token.span;
|
||||||
let mut err = self.span_err(self.token.span, Error::UselessDocComment);
|
let mut err = DocCommentDoesNotDocumentAnything {
|
||||||
|
span: self.token.span,
|
||||||
|
missing_comma: None,
|
||||||
|
};
|
||||||
self.bump(); // consume the doc comment
|
self.bump(); // consume the doc comment
|
||||||
let comma_after_doc_seen = self.eat(&token::Comma);
|
let comma_after_doc_seen = self.eat(&token::Comma);
|
||||||
// `seen_comma` is always false, because we are inside doc block
|
// `seen_comma` is always false, because we are inside doc block
|
||||||
|
@ -1595,18 +1598,13 @@ impl<'a> Parser<'a> {
|
||||||
seen_comma = true;
|
seen_comma = true;
|
||||||
}
|
}
|
||||||
if comma_after_doc_seen || self.token == token::CloseDelim(Delimiter::Brace) {
|
if comma_after_doc_seen || self.token == token::CloseDelim(Delimiter::Brace) {
|
||||||
err.emit();
|
self.sess.emit_err(err);
|
||||||
} else {
|
} else {
|
||||||
if !seen_comma {
|
if !seen_comma {
|
||||||
let sp = self.sess.source_map().next_point(previous_span);
|
let sp = self.sess.source_map().next_point(previous_span);
|
||||||
err.span_suggestion(
|
err.missing_comma = Some(sp);
|
||||||
sp,
|
|
||||||
"missing comma here",
|
|
||||||
",",
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return Err(err);
|
return Err(err.into_diagnostic(&self.sess.span_diagnostic));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -13,7 +13,6 @@ mod ty;
|
||||||
use crate::lexer::UnmatchedBrace;
|
use crate::lexer::UnmatchedBrace;
|
||||||
pub use attr_wrapper::AttrWrapper;
|
pub use attr_wrapper::AttrWrapper;
|
||||||
pub use diagnostics::AttemptLocalParseRecovery;
|
pub use diagnostics::AttemptLocalParseRecovery;
|
||||||
use diagnostics::Error;
|
|
||||||
pub(crate) use item::FnParseMode;
|
pub(crate) use item::FnParseMode;
|
||||||
pub use pat::{CommaRecoveryMode, RecoverColon, RecoverComma};
|
pub use pat::{CommaRecoveryMode, RecoverColon, RecoverComma};
|
||||||
pub use path::PathStyle;
|
pub use path::PathStyle;
|
||||||
|
@ -32,8 +31,7 @@ use rustc_ast_pretty::pprust;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_errors::PResult;
|
use rustc_errors::PResult;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError, IntoDiagnostic,
|
Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError, IntoDiagnostic, MultiSpan,
|
||||||
MultiSpan,
|
|
||||||
};
|
};
|
||||||
use rustc_session::parse::ParseSess;
|
use rustc_session::parse::ParseSess;
|
||||||
use rustc_span::source_map::{Span, DUMMY_SP};
|
use rustc_span::source_map::{Span, DUMMY_SP};
|
||||||
|
@ -42,7 +40,10 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use std::{cmp, mem, slice};
|
use std::{cmp, mem, slice};
|
||||||
|
|
||||||
use crate::errors::{MismatchedClosingDelimiter, NonStringAbiLiteral};
|
use crate::errors::{
|
||||||
|
DocCommentDoesNotDocumentAnything, IncorrectVisibilityRestriction, MismatchedClosingDelimiter,
|
||||||
|
NonStringAbiLiteral,
|
||||||
|
};
|
||||||
|
|
||||||
bitflags::bitflags! {
|
bitflags::bitflags! {
|
||||||
struct Restrictions: u8 {
|
struct Restrictions: u8 {
|
||||||
|
@ -521,9 +522,11 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
fn ident_or_err(&mut self) -> PResult<'a, (Ident, /* is_raw */ bool)> {
|
fn ident_or_err(&mut self) -> PResult<'a, (Ident, /* is_raw */ bool)> {
|
||||||
self.token.ident().ok_or_else(|| match self.prev_token.kind {
|
self.token.ident().ok_or_else(|| match self.prev_token.kind {
|
||||||
TokenKind::DocComment(..) => {
|
TokenKind::DocComment(..) => DocCommentDoesNotDocumentAnything {
|
||||||
self.span_err(self.prev_token.span, Error::UselessDocComment)
|
span: self.prev_token.span,
|
||||||
|
missing_comma: None,
|
||||||
}
|
}
|
||||||
|
.into_diagnostic(&self.sess.span_diagnostic),
|
||||||
_ => self.expected_ident_found(),
|
_ => self.expected_ident_found(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1347,23 +1350,8 @@ impl<'a> Parser<'a> {
|
||||||
let path = self.parse_path(PathStyle::Mod)?;
|
let path = self.parse_path(PathStyle::Mod)?;
|
||||||
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)`
|
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)`
|
||||||
|
|
||||||
let msg = "incorrect visibility restriction";
|
|
||||||
let suggestion = r##"some possible visibility restrictions are:
|
|
||||||
`pub(crate)`: visible only on the current crate
|
|
||||||
`pub(super)`: visible only in the current module's parent
|
|
||||||
`pub(in path::to::module)`: visible only on the specified path"##;
|
|
||||||
|
|
||||||
let path_str = pprust::path_to_string(&path);
|
let path_str = pprust::path_to_string(&path);
|
||||||
|
self.sess.emit_err(IncorrectVisibilityRestriction { span: path.span, inner_str: path_str });
|
||||||
struct_span_err!(self.sess.span_diagnostic, path.span, E0704, "{}", msg)
|
|
||||||
.help(suggestion)
|
|
||||||
.span_suggestion(
|
|
||||||
path.span,
|
|
||||||
&format!("make this visible only to module `{}` with `in`", path_str),
|
|
||||||
format!("in {}", path_str),
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use super::attr::DEFAULT_INNER_ATTR_FORBIDDEN;
|
use super::attr::DEFAULT_INNER_ATTR_FORBIDDEN;
|
||||||
use super::diagnostics::{AttemptLocalParseRecovery, Error};
|
use super::diagnostics::AttemptLocalParseRecovery;
|
||||||
use super::expr::LhsExpr;
|
use super::expr::LhsExpr;
|
||||||
use super::pat::RecoverComma;
|
use super::pat::RecoverComma;
|
||||||
use super::path::PathStyle;
|
use super::path::PathStyle;
|
||||||
|
@ -7,7 +7,12 @@ use super::TrailingToken;
|
||||||
use super::{
|
use super::{
|
||||||
AttrWrapper, BlockMode, FnParseMode, ForceCollect, Parser, Restrictions, SemiColonMode,
|
AttrWrapper, BlockMode, FnParseMode, ForceCollect, Parser, Restrictions, SemiColonMode,
|
||||||
};
|
};
|
||||||
use crate::errors::{InvalidVariableDeclaration, InvalidVariableDeclarationSub};
|
use crate::errors::{
|
||||||
|
AssignmentElseNotAllowed, CompoundAssignmentExpressionInLet, ConstLetMutuallyExclusive,
|
||||||
|
DocCommentDoesNotDocumentAnything, ExpectedStatementAfterOuterAttr, InvalidCurlyInLetElse,
|
||||||
|
InvalidExpressionInLetElse, InvalidVariableDeclaration, InvalidVariableDeclarationSub,
|
||||||
|
WrapExpressionInParentheses,
|
||||||
|
};
|
||||||
use crate::maybe_whole;
|
use crate::maybe_whole;
|
||||||
|
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
|
@ -111,11 +116,7 @@ impl<'a> Parser<'a> {
|
||||||
let bl = self.parse_block()?;
|
let bl = self.parse_block()?;
|
||||||
// Destructuring assignment ... else.
|
// Destructuring assignment ... else.
|
||||||
// This is not allowed, but point it out in a nice way.
|
// This is not allowed, but point it out in a nice way.
|
||||||
let mut err = self.struct_span_err(
|
self.sess.emit_err(AssignmentElseNotAllowed { span: e.span.to(bl.span) });
|
||||||
e.span.to(bl.span),
|
|
||||||
"<assignment> ... else { ... } is not allowed",
|
|
||||||
);
|
|
||||||
err.emit();
|
|
||||||
}
|
}
|
||||||
self.mk_stmt(lo.to(e.span), StmtKind::Expr(e))
|
self.mk_stmt(lo.to(e.span), StmtKind::Expr(e))
|
||||||
} else {
|
} else {
|
||||||
|
@ -201,9 +202,12 @@ impl<'a> Parser<'a> {
|
||||||
fn error_outer_attrs(&self, attrs: &[Attribute]) {
|
fn error_outer_attrs(&self, attrs: &[Attribute]) {
|
||||||
if let [.., last] = attrs {
|
if let [.., last] = attrs {
|
||||||
if last.is_doc_comment() {
|
if last.is_doc_comment() {
|
||||||
self.span_err(last.span, Error::UselessDocComment).emit();
|
self.sess.emit_err(DocCommentDoesNotDocumentAnything {
|
||||||
|
span: last.span,
|
||||||
|
missing_comma: None,
|
||||||
|
});
|
||||||
} else if attrs.iter().any(|a| a.style == AttrStyle::Outer) {
|
} else if attrs.iter().any(|a| a.style == AttrStyle::Outer) {
|
||||||
self.struct_span_err(last.span, "expected statement after outer attribute").emit();
|
self.sess.emit_err(ExpectedStatementAfterOuterAttr { span: last.span });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,17 +258,7 @@ impl<'a> Parser<'a> {
|
||||||
let lo = self.prev_token.span;
|
let lo = self.prev_token.span;
|
||||||
|
|
||||||
if self.token.is_keyword(kw::Const) && self.look_ahead(1, |t| t.is_ident()) {
|
if self.token.is_keyword(kw::Const) && self.look_ahead(1, |t| t.is_ident()) {
|
||||||
self.struct_span_err(
|
self.sess.emit_err(ConstLetMutuallyExclusive { span: lo.to(self.token.span) });
|
||||||
lo.to(self.token.span),
|
|
||||||
"`const` and `let` are mutually exclusive",
|
|
||||||
)
|
|
||||||
.span_suggestion(
|
|
||||||
lo.to(self.token.span),
|
|
||||||
"remove `let`",
|
|
||||||
"const",
|
|
||||||
Applicability::MaybeIncorrect,
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
self.bump();
|
self.bump();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,44 +356,27 @@ impl<'a> Parser<'a> {
|
||||||
fn check_let_else_init_bool_expr(&self, init: &ast::Expr) {
|
fn check_let_else_init_bool_expr(&self, init: &ast::Expr) {
|
||||||
if let ast::ExprKind::Binary(op, ..) = init.kind {
|
if let ast::ExprKind::Binary(op, ..) = init.kind {
|
||||||
if op.node.lazy() {
|
if op.node.lazy() {
|
||||||
let suggs = vec![
|
self.sess.emit_err(InvalidExpressionInLetElse {
|
||||||
(init.span.shrink_to_lo(), "(".to_string()),
|
span: init.span,
|
||||||
(init.span.shrink_to_hi(), ")".to_string()),
|
operator: op.node.to_string(),
|
||||||
];
|
sugg: WrapExpressionInParentheses {
|
||||||
self.struct_span_err(
|
left: init.span.shrink_to_lo(),
|
||||||
init.span,
|
right: init.span.shrink_to_hi(),
|
||||||
&format!(
|
},
|
||||||
"a `{}` expression cannot be directly assigned in `let...else`",
|
});
|
||||||
op.node.to_string()
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.multipart_suggestion(
|
|
||||||
"wrap the expression in parentheses",
|
|
||||||
suggs,
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_let_else_init_trailing_brace(&self, init: &ast::Expr) {
|
fn check_let_else_init_trailing_brace(&self, init: &ast::Expr) {
|
||||||
if let Some(trailing) = classify::expr_trailing_brace(init) {
|
if let Some(trailing) = classify::expr_trailing_brace(init) {
|
||||||
let err_span = trailing.span.with_lo(trailing.span.hi() - BytePos(1));
|
self.sess.emit_err(InvalidCurlyInLetElse {
|
||||||
let suggs = vec![
|
span: trailing.span.with_lo(trailing.span.hi() - BytePos(1)),
|
||||||
(trailing.span.shrink_to_lo(), "(".to_string()),
|
sugg: WrapExpressionInParentheses {
|
||||||
(trailing.span.shrink_to_hi(), ")".to_string()),
|
left: trailing.span.shrink_to_lo(),
|
||||||
];
|
right: trailing.span.shrink_to_hi(),
|
||||||
self.struct_span_err(
|
},
|
||||||
err_span,
|
});
|
||||||
"right curly brace `}` before `else` in a `let...else` statement not allowed",
|
|
||||||
)
|
|
||||||
.multipart_suggestion(
|
|
||||||
"try wrapping the expression in parentheses",
|
|
||||||
suggs,
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,18 +385,7 @@ impl<'a> Parser<'a> {
|
||||||
let eq_consumed = match self.token.kind {
|
let eq_consumed = match self.token.kind {
|
||||||
token::BinOpEq(..) => {
|
token::BinOpEq(..) => {
|
||||||
// Recover `let x <op>= 1` as `let x = 1`
|
// Recover `let x <op>= 1` as `let x = 1`
|
||||||
self.struct_span_err(
|
self.sess.emit_err(CompoundAssignmentExpressionInLet { span: self.token.span });
|
||||||
self.token.span,
|
|
||||||
"can't reassign to an uninitialized variable",
|
|
||||||
)
|
|
||||||
.span_suggestion_short(
|
|
||||||
self.token.span,
|
|
||||||
"initialize the variable",
|
|
||||||
"=",
|
|
||||||
Applicability::MaybeIncorrect,
|
|
||||||
)
|
|
||||||
.help("if you meant to overwrite, remove the `let` binding")
|
|
||||||
.emit();
|
|
||||||
self.bump();
|
self.bump();
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ error: right curly brace `}` before `else` in a `let...else` statement not allow
|
||||||
LL | let Some(1) = { Some(1) } else {
|
LL | let Some(1) = { Some(1) } else {
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
help: try wrapping the expression in parentheses
|
help: wrap the expression in parentheses
|
||||||
|
|
|
|
||||||
LL | let Some(1) = ({ Some(1) }) else {
|
LL | let Some(1) = ({ Some(1) }) else {
|
||||||
| + +
|
| + +
|
||||||
|
@ -15,7 +15,7 @@ error: right curly brace `}` before `else` in a `let...else` statement not allow
|
||||||
LL | let Some(1) = loop { break Some(1) } else {
|
LL | let Some(1) = loop { break Some(1) } else {
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
help: try wrapping the expression in parentheses
|
help: wrap the expression in parentheses
|
||||||
|
|
|
|
||||||
LL | let Some(1) = (loop { break Some(1) }) else {
|
LL | let Some(1) = (loop { break Some(1) }) else {
|
||||||
| + +
|
| + +
|
||||||
|
@ -26,7 +26,7 @@ error: right curly brace `}` before `else` in a `let...else` statement not allow
|
||||||
LL | let 2 = 1 + match 1 { n => n } else {
|
LL | let 2 = 1 + match 1 { n => n } else {
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
help: try wrapping the expression in parentheses
|
help: wrap the expression in parentheses
|
||||||
|
|
|
|
||||||
LL | let 2 = 1 + (match 1 { n => n }) else {
|
LL | let 2 = 1 + (match 1 { n => n }) else {
|
||||||
| + +
|
| + +
|
||||||
|
@ -37,7 +37,7 @@ error: right curly brace `}` before `else` in a `let...else` statement not allow
|
||||||
LL | let Some(1) = unsafe { unsafe_fn() } else {
|
LL | let Some(1) = unsafe { unsafe_fn() } else {
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
help: try wrapping the expression in parentheses
|
help: wrap the expression in parentheses
|
||||||
|
|
|
|
||||||
LL | let Some(1) = (unsafe { unsafe_fn() }) else {
|
LL | let Some(1) = (unsafe { unsafe_fn() }) else {
|
||||||
| + +
|
| + +
|
||||||
|
|
Loading…
Add table
Reference in a new issue