Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc_parse: diagnostics migration, v4 #105670

Merged
merged 11 commits into from
Feb 2, 2023
Prev Previous commit
Next Next commit
migrate parser::ty to diagnostic structs
Xiretza committed Feb 1, 2023
commit 7631b12e3e820f00780fff345019436d36158159
35 changes: 35 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/parse.ftl
Original file line number Diff line number Diff line change
@@ -539,3 +539,38 @@ parse_dot_dot_dot_for_remaining_fields = expected field pattern, found `...`
.suggestion = to omit remaining fields, use one fewer `.`

parse_expected_comma_after_pattern_field = expected `,`

parse_return_types_use_thin_arrow = return types are denoted using `->`
.suggestion = use `->` instead

parse_need_plus_after_trait_object_lifetime = lifetime in trait object type must be followed by `+`

parse_expected_mut_or_const_in_raw_pointer_type = expected `mut` or `const` keyword in raw pointer type
.suggestion = add `mut` or `const` here

parse_lifetime_after_mut = lifetime must precede `mut`
.suggestion = place the lifetime before `mut`

parse_dyn_after_mut = `mut` must precede `dyn`
.suggestion = place `mut` before `dyn`

parse_fn_pointer_cannot_be_const = an `fn` pointer type cannot be `const`
.label = `const` because of this
.suggestion = remove the `const` qualifier

parse_fn_pointer_cannot_be_async = an `fn` pointer type cannot be `async`
.label = `async` because of this
.suggestion = remove the `async` qualifier

parse_nested_c_variadic_type = C-variadic type `...` may not be nested inside another type

parse_invalid_dyn_keyword = invalid `dyn` keyword
.help = `dyn` is only needed at the start of a trait `+`-separated list
.suggestion = remove this keyword

parse_negative_bounds_not_supported = negative bounds are not supported
.label = negative bounds are not supported
.suggestion = {$num_bounds ->
[one] remove the bound
*[other] remove the bounds
}
103 changes: 103 additions & 0 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1845,3 +1845,106 @@ pub(crate) struct ExpectedCommaAfterPatternField {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(parse_return_types_use_thin_arrow)]
pub(crate) struct ReturnTypesUseThinArrow {
#[primary_span]
#[suggestion(style = "short", code = "->", applicability = "machine-applicable")]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(parse_need_plus_after_trait_object_lifetime)]
pub(crate) struct NeedPlusAfterTraitObjectLifetime {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(parse_expected_mut_or_const_in_raw_pointer_type)]
pub(crate) struct ExpectedMutOrConstInRawPointerType {
#[primary_span]
pub span: Span,
#[suggestion(code("mut ", "const "), applicability = "has-placeholders")]
pub after_asterisk: Span,
}

#[derive(Diagnostic)]
#[diag(parse_lifetime_after_mut)]
pub(crate) struct LifetimeAfterMut {
#[primary_span]
pub span: Span,
#[suggestion(code = "&{snippet} mut", applicability = "maybe-incorrect")]
pub suggest_lifetime: Option<Span>,
pub snippet: String,
}

#[derive(Diagnostic)]
#[diag(parse_dyn_after_mut)]
pub(crate) struct DynAfterMut {
#[primary_span]
#[suggestion(code = "&mut dyn", applicability = "machine-applicable")]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(parse_fn_pointer_cannot_be_const)]
pub(crate) struct FnPointerCannotBeConst {
#[primary_span]
pub span: Span,
#[suggestion(code = "", applicability = "maybe-incorrect")]
#[label]
pub qualifier: Span,
}

#[derive(Diagnostic)]
#[diag(parse_fn_pointer_cannot_be_async)]
pub(crate) struct FnPointerCannotBeAsync {
#[primary_span]
pub span: Span,
#[suggestion(code = "", applicability = "maybe-incorrect")]
#[label]
pub qualifier: Span,
}

#[derive(Diagnostic)]
#[diag(parse_nested_c_variadic_type, code = "E0743")]
pub(crate) struct NestedCVariadicType {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(parse_invalid_dyn_keyword)]
#[help]
pub(crate) struct InvalidDynKeyword {
#[primary_span]
#[suggestion(code = "", applicability = "machine-applicable")]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(parse_negative_bounds_not_supported)]
pub(crate) struct NegativeBoundsNotSupported {
#[primary_span]
pub negative_bounds: Vec<Span>,
#[label]
pub last_span: Span,
#[subdiagnostic]
pub sub: Option<NegativeBoundsNotSupportedSugg>,
}

#[derive(Subdiagnostic)]
#[suggestion(
suggestion,
style = "tool-only",
code = "{fixed}",
applicability = "machine-applicable"
)]
pub(crate) struct NegativeBoundsNotSupportedSugg {
#[primary_span]
pub bound_list: Span,
pub num_bounds: usize,
pub fixed: String,
}
123 changes: 38 additions & 85 deletions compiler/rustc_parse/src/parser/ty.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
use super::{Parser, PathStyle, TokenType};

use crate::errors::{ExpectedFnPathFoundFnKeyword, FnPtrWithGenerics, FnPtrWithGenericsSugg};
use crate::errors::{
DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType,
FnPointerCannotBeAsync, FnPointerCannotBeConst, FnPtrWithGenerics, FnPtrWithGenericsSugg,
InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime,
NegativeBoundsNotSupported, NegativeBoundsNotSupportedSugg, NestedCVariadicType,
ReturnTypesUseThinArrow,
};
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};

use ast::DUMMY_NODE_ID;
@@ -12,7 +18,7 @@ use rustc_ast::{
MacCall, MutTy, Mutability, PolyTraitRef, TraitBoundModifier, TraitObjectSyntax, Ty, TyKind,
};
use rustc_ast_pretty::pprust;
use rustc_errors::{pluralize, struct_span_err, Applicability, PResult};
use rustc_errors::{Applicability, PResult};
use rustc_span::source_map::Span;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Symbol;
@@ -233,14 +239,7 @@ impl<'a> Parser<'a> {
// Don't `eat` to prevent `=>` from being added as an expected token which isn't
// actually expected and could only confuse users
self.bump();
self.struct_span_err(self.prev_token.span, "return types are denoted using `->`")
.span_suggestion_short(
self.prev_token.span,
"use `->` instead",
"->",
Applicability::MachineApplicable,
)
.emit();
self.sess.emit_err(ReturnTypesUseThinArrow { span: self.prev_token.span });
let ty = self.parse_ty_common(
allow_plus,
AllowCVariadic::No,
@@ -328,7 +327,7 @@ impl<'a> Parser<'a> {
AllowCVariadic::No => {
// FIXME(Centril): Should we just allow `...` syntactically
// anywhere in a type and use semantic restrictions instead?
self.error_illegal_c_varadic_ty(lo);
self.sess.emit_err(NestedCVariadicType { span: lo.to(self.prev_token.span) });
TyKind::Err
}
}
@@ -431,8 +430,7 @@ impl<'a> Parser<'a> {
let lt_no_plus = self.check_lifetime() && !self.look_ahead(1, |t| t.is_like_plus());
let bounds = self.parse_generic_bounds_common(allow_plus, None)?;
if lt_no_plus {
self.struct_span_err(lo, "lifetime in trait object type must be followed by `+`")
.emit();
self.sess.emit_err(NeedPlusAfterTraitObjectLifetime { span: lo });
}
Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
}
@@ -466,14 +464,10 @@ impl<'a> Parser<'a> {
fn parse_ty_ptr(&mut self) -> PResult<'a, TyKind> {
let mutbl = self.parse_const_or_mut().unwrap_or_else(|| {
let span = self.prev_token.span;
self.struct_span_err(span, "expected `mut` or `const` keyword in raw pointer type")
.span_suggestions(
span.shrink_to_hi(),
"add `mut` or `const` here",
["mut ".to_string(), "const ".to_string()],
Applicability::HasPlaceholders,
)
.emit();
self.sess.emit_err(ExpectedMutOrConstInRawPointerType {
span,
after_asterisk: span.shrink_to_hi(),
});
Mutability::Not
});
let ty = self.parse_ty_no_plus()?;
@@ -528,16 +522,13 @@ impl<'a> Parser<'a> {
let lifetime_span = self.token.span;
let span = and_span.to(lifetime_span);

let mut err = self.struct_span_err(span, "lifetime must precede `mut`");
if let Ok(lifetime_src) = self.span_to_snippet(lifetime_span) {
err.span_suggestion(
span,
"place the lifetime before `mut`",
format!("&{} mut", lifetime_src),
Applicability::MaybeIncorrect,
);
}
err.emit();
let (suggest_lifetime, snippet) =
if let Ok(lifetime_src) = self.span_to_snippet(lifetime_span) {
(Some(span), lifetime_src)
} else {
(None, String::new())
};
self.sess.emit_err(LifetimeAfterMut { span, suggest_lifetime, snippet });

opt_lifetime = Some(self.expect_lifetime());
}
@@ -547,14 +538,7 @@ impl<'a> Parser<'a> {
{
// We have `&dyn mut ...`, which is invalid and should be `&mut dyn ...`.
let span = and_span.to(self.look_ahead(1, |t| t.span));
let mut err = self.struct_span_err(span, "`mut` must precede `dyn`");
err.span_suggestion(
span,
"place `mut` before `dyn`",
"&mut dyn",
Applicability::MachineApplicable,
);
err.emit();
self.sess.emit_err(DynAfterMut { span });

// Recovery
mutbl = Mutability::Mut;
@@ -608,10 +592,10 @@ impl<'a> Parser<'a> {
// If we ever start to allow `const fn()`, then update
// feature gating for `#![feature(const_extern_fn)]` to
// cover it.
self.error_fn_ptr_bad_qualifier(whole_span, span, "const");
self.sess.emit_err(FnPointerCannotBeConst { span: whole_span, qualifier: span });
}
if let ast::Async::Yes { span, .. } = asyncness {
self.error_fn_ptr_bad_qualifier(whole_span, span, "async");
self.sess.emit_err(FnPointerCannotBeAsync { span: whole_span, qualifier: span });
}
let decl_span = span_start.to(self.token.span);
Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params: params, decl, decl_span })))
@@ -659,19 +643,6 @@ impl<'a> Parser<'a> {
Ok(())
}

/// Emit an error for the given bad function pointer qualifier.
fn error_fn_ptr_bad_qualifier(&self, span: Span, qual_span: Span, qual: &str) {
self.struct_span_err(span, &format!("an `fn` pointer type cannot be `{}`", qual))
.span_label(qual_span, format!("`{}` because of this", qual))
.span_suggestion_short(
qual_span,
&format!("remove the `{}` qualifier", qual),
"",
Applicability::MaybeIncorrect,
)
.emit();
}

/// Parses an `impl B0 + ... + Bn` type.
fn parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> {
// Always parse bounds greedily for better error recovery.
@@ -758,16 +729,6 @@ impl<'a> Parser<'a> {
}
}

fn error_illegal_c_varadic_ty(&self, lo: Span) {
struct_span_err!(
self.sess.span_diagnostic,
lo.to(self.prev_token.span),
E0743,
"C-variadic type `...` may not be nested inside another type",
)
.emit();
}

pub(super) fn parse_generic_bounds(
&mut self,
colon_span: Option<Span>,
@@ -797,15 +758,7 @@ impl<'a> Parser<'a> {
{
if self.token.is_keyword(kw::Dyn) {
// Account for `&dyn Trait + dyn Other`.
self.struct_span_err(self.token.span, "invalid `dyn` keyword")
.help("`dyn` is only needed at the start of a trait `+`-separated list")
.span_suggestion(
self.token.span,
"remove this keyword",
"",
Applicability::MachineApplicable,
)
.emit();
self.sess.emit_err(InvalidDynKeyword { span: self.token.span });
self.bump();
}
match self.parse_generic_bound()? {
@@ -842,11 +795,7 @@ impl<'a> Parser<'a> {
bounds: &[GenericBound],
negative_bounds: Vec<Span>,
) {
let negative_bounds_len = negative_bounds.len();
let last_span = *negative_bounds.last().expect("no negative bounds, but still error?");
let mut err = self.struct_span_err(negative_bounds, "negative bounds are not supported");
err.span_label(last_span, "negative bounds are not supported");
if let Some(bound_list) = colon_span {
let sub = if let Some(bound_list) = colon_span {
let bound_list = bound_list.to(self.prev_token.span);
let mut new_bound_list = String::new();
if !bounds.is_empty() {
@@ -857,14 +806,18 @@ impl<'a> Parser<'a> {
}
new_bound_list = new_bound_list.replacen(" +", ":", 1);
}
err.tool_only_span_suggestion(

Some(NegativeBoundsNotSupportedSugg {
bound_list,
&format!("remove the bound{}", pluralize!(negative_bounds_len)),
new_bound_list,
Applicability::MachineApplicable,
);
}
err.emit();
num_bounds: negative_bounds.len(),
fixed: new_bound_list,
})
} else {
None
};

let last_span = *negative_bounds.last().expect("no negative bounds, but still error?");
self.sess.emit_err(NegativeBoundsNotSupported { negative_bounds, last_span, sub });
}

/// Parses a bound according to the grammar: