Skip to content

Commit

Permalink
migrate parser::ty to diagnostic structs
Browse files Browse the repository at this point in the history
  • Loading branch information
Xiretza committed Feb 1, 2023
1 parent 9564a30 commit 7631b12
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 85 deletions.
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
Expand Up @@ -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
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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))
}
Expand Down Expand Up @@ -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()?;
Expand Down Expand Up @@ -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());
}
Expand All @@ -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;
Expand Down Expand Up @@ -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 })))
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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>,
Expand Down Expand Up @@ -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()? {
Expand Down Expand Up @@ -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() {
Expand All @@ -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:
Expand Down

0 comments on commit 7631b12

Please sign in to comment.