Skip to content

Commit 131f0c6

Browse files
committed
Auto merge of #105670 - Xiretza:rustc_parse-diagnostics-4, r=davidtwco
rustc_parse: diagnostics migration, v4 This is all the `rustc_parse` migrations I have in store right now; unfortunately life is pretty busy right now, so I won't be able to do much more in the near future. cc #100717 r? `@davidtwco`
2 parents 8789e53 + 0d0d369 commit 131f0c6

35 files changed

+1385
-656
lines changed

compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,7 @@ hir_typeck_lang_start_incorrect_param = parameter {$param_num} of the `start` la
5757
5858
hir_typeck_lang_start_incorrect_ret_ty = the return type of the `start` lang item is incorrect
5959
.suggestion = change the type from `{$found_ty}` to `{$expected_ty}`
60+
61+
hir_typeck_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml`
62+
hir_typeck_help_set_edition_standalone = pass `--edition {$edition}` to `rustc`
63+
hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide

compiler/rustc_error_messages/locales/en-US/parse.ftl

+188
Original file line numberDiff line numberDiff line change
@@ -390,3 +390,191 @@ parse_where_clause_before_tuple_struct_body = where clauses are not allowed befo
390390
.name_label = while parsing this tuple struct
391391
.body_label = the struct body
392392
.suggestion = move the body before the where clause
393+
394+
parse_async_fn_in_2015 = `async fn` is not permitted in Rust 2015
395+
.label = to use `async fn`, switch to Rust 2018 or later
396+
397+
parse_async_block_in_2015 = `async` blocks are only allowed in Rust 2018 or later
398+
399+
parse_self_argument_pointer = cannot pass `self` by raw pointer
400+
.label = cannot pass `self` by raw pointer
401+
402+
parse_visibility_not_followed_by_item = visibility `{$vis}` is not followed by an item
403+
.label = the visibility
404+
.help = you likely meant to define an item, e.g., `{$vis} fn foo() {"{}"}`
405+
406+
parse_default_not_followed_by_item = `default` is not followed by an item
407+
.label = the `default` qualifier
408+
.note = only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`
409+
410+
parse_missing_struct_for_struct_definition = missing `struct` for struct definition
411+
.suggestion = add `struct` here to parse `{$ident}` as a public struct
412+
413+
parse_missing_fn_for_function_definition = missing `fn` for function definition
414+
.suggestion = add `fn` here to parse `{$ident}` as a public function
415+
416+
parse_missing_fn_for_method_definition = missing `fn` for method definition
417+
.suggestion = add `fn` here to parse `{$ident}` as a public method
418+
419+
parse_ambiguous_missing_keyword_for_item_definition = missing `fn` or `struct` for function or struct definition
420+
.suggestion = if you meant to call a macro, try
421+
.help = if you meant to call a macro, remove the `pub` and add a trailing `!` after the identifier
422+
423+
parse_missing_trait_in_trait_impl = missing trait in a trait impl
424+
.suggestion_add_trait = add a trait here
425+
.suggestion_remove_for = for an inherent impl, drop this `for`
426+
427+
parse_missing_for_in_trait_impl = missing `for` in a trait impl
428+
.suggestion = add `for` here
429+
430+
parse_expected_trait_in_trait_impl_found_type = expected a trait, found type
431+
432+
parse_non_item_in_item_list = non-item in item list
433+
.suggestion_use_const_not_let = consider using `const` instead of `let` for associated const
434+
.label_list_start = item list starts here
435+
.label_non_item = non-item starts here
436+
.label_list_end = item list ends here
437+
.suggestion_remove_semicolon = consider removing this semicolon
438+
439+
parse_bounds_not_allowed_on_trait_aliases = bounds are not allowed on trait aliases
440+
441+
parse_trait_alias_cannot_be_auto = trait aliases cannot be `auto`
442+
parse_trait_alias_cannot_be_unsafe = trait aliases cannot be `unsafe`
443+
444+
parse_associated_static_item_not_allowed = associated `static` items are not allowed
445+
446+
parse_extern_crate_name_with_dashes = crate name using dashes are not valid in `extern crate` statements
447+
.label = dash-separated idents are not valid
448+
.suggestion = if the original crate name uses dashes you need to use underscores in the code
449+
450+
parse_extern_item_cannot_be_const = extern items cannot be `const`
451+
.suggestion = try using a static value
452+
.note = for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
453+
454+
parse_const_global_cannot_be_mutable = const globals cannot be mutable
455+
.label = cannot be mutable
456+
.suggestion = you might want to declare a static instead
457+
458+
parse_missing_const_type = missing type for `{$kind}` item
459+
.suggestion = provide a type for the item
460+
461+
parse_enum_struct_mutually_exclusive = `enum` and `struct` are mutually exclusive
462+
.suggestion = replace `enum struct` with
463+
464+
parse_unexpected_token_after_struct_name = expected `where`, `{"{"}`, `(`, or `;` after struct name
465+
parse_unexpected_token_after_struct_name_found_reserved_identifier = expected `where`, `{"{"}`, `(`, or `;` after struct name, found reserved identifier `{$token}`
466+
parse_unexpected_token_after_struct_name_found_keyword = expected `where`, `{"{"}`, `(`, or `;` after struct name, found keyword `{$token}`
467+
parse_unexpected_token_after_struct_name_found_reserved_keyword = expected `where`, `{"{"}`, `(`, or `;` after struct name, found reserved keyword `{$token}`
468+
parse_unexpected_token_after_struct_name_found_doc_comment = expected `where`, `{"{"}`, `(`, or `;` after struct name, found doc comment `{$token}`
469+
parse_unexpected_token_after_struct_name_found_other = expected `where`, `{"{"}`, `(`, or `;` after struct name, found `{$token}`
470+
471+
parse_unexpected_self_in_generic_parameters = unexpected keyword `Self` in generic parameters
472+
.note = you cannot use `Self` as a generic parameter because it is reserved for associated items
473+
474+
parse_multiple_where_clauses = cannot define duplicate `where` clauses on an item
475+
.label = previous `where` clause starts here
476+
.suggestion = consider joining the two `where` clauses into one
477+
478+
parse_nonterminal_expected_item_keyword = expected an item keyword
479+
parse_nonterminal_expected_statement = expected a statement
480+
parse_nonterminal_expected_ident = expected ident, found `{$token}`
481+
parse_nonterminal_expected_lifetime = expected a lifetime, found `{$token}`
482+
483+
parse_or_pattern_not_allowed_in_let_binding = top-level or-patterns are not allowed in `let` bindings
484+
parse_or_pattern_not_allowed_in_fn_parameters = top-level or-patterns are not allowed in function parameters
485+
parse_sugg_remove_leading_vert_in_pattern = remove the `|`
486+
parse_sugg_wrap_pattern_in_parens = wrap the pattern in parentheses
487+
488+
parse_note_pattern_alternatives_use_single_vert = alternatives in or-patterns are separated with `|`, not `||`
489+
490+
parse_unexpected_vert_vert_before_function_parameter = unexpected `||` before function parameter
491+
.suggestion = remove the `||`
492+
493+
parse_label_while_parsing_or_pattern_here = while parsing this or-pattern starting here
494+
495+
parse_unexpected_vert_vert_in_pattern = unexpected token `||` in pattern
496+
.suggestion = use a single `|` to separate multiple alternative patterns
497+
498+
parse_trailing_vert_not_allowed = a trailing `|` is not allowed in an or-pattern
499+
.suggestion = remove the `{$token}`
500+
501+
parse_dotdotdot_rest_pattern = unexpected `...`
502+
.label = not a valid pattern
503+
.suggestion = for a rest pattern, use `..` instead of `...`
504+
505+
parse_pattern_on_wrong_side_of_at = pattern on wrong side of `@`
506+
.label_pattern = pattern on the left, should be on the right
507+
.label_binding = binding on the right, should be on the left
508+
.suggestion = switch the order
509+
510+
parse_expected_binding_left_of_at = left-hand side of `@` must be a binding
511+
.label_lhs = interpreted as a pattern, not a binding
512+
.label_rhs = also a pattern
513+
.note = bindings are `x`, `mut x`, `ref x`, and `ref mut x`
514+
515+
parse_ambiguous_range_pattern = the range pattern here has ambiguous interpretation
516+
.suggestion = add parentheses to clarify the precedence
517+
518+
parse_unexpected_lifetime_in_pattern = unexpected lifetime `{$symbol}` in pattern
519+
.suggestion = remove the lifetime
520+
521+
parse_ref_mut_order_incorrect = the order of `mut` and `ref` is incorrect
522+
.suggestion = try switching the order
523+
524+
parse_mut_on_nested_ident_pattern = `mut` must be attached to each individual binding
525+
.suggestion = add `mut` to each binding
526+
parse_mut_on_non_ident_pattern = `mut` must be followed by a named binding
527+
.suggestion = remove the `mut` prefix
528+
parse_note_mut_pattern_usage = `mut` may be followed by `variable` and `variable @ pattern`
529+
530+
parse_repeated_mut_in_pattern = `mut` on a binding may not be repeated
531+
.suggestion = remove the additional `mut`s
532+
533+
parse_dot_dot_dot_range_to_pattern_not_allowed = range-to patterns with `...` are not allowed
534+
.suggestion = use `..=` instead
535+
536+
parse_enum_pattern_instead_of_identifier = expected identifier, found enum pattern
537+
538+
parse_dot_dot_dot_for_remaining_fields = expected field pattern, found `...`
539+
.suggestion = to omit remaining fields, use one fewer `.`
540+
541+
parse_expected_comma_after_pattern_field = expected `,`
542+
543+
parse_return_types_use_thin_arrow = return types are denoted using `->`
544+
.suggestion = use `->` instead
545+
546+
parse_need_plus_after_trait_object_lifetime = lifetime in trait object type must be followed by `+`
547+
548+
parse_expected_mut_or_const_in_raw_pointer_type = expected `mut` or `const` keyword in raw pointer type
549+
.suggestion = add `mut` or `const` here
550+
551+
parse_lifetime_after_mut = lifetime must precede `mut`
552+
.suggestion = place the lifetime before `mut`
553+
554+
parse_dyn_after_mut = `mut` must precede `dyn`
555+
.suggestion = place `mut` before `dyn`
556+
557+
parse_fn_pointer_cannot_be_const = an `fn` pointer type cannot be `const`
558+
.label = `const` because of this
559+
.suggestion = remove the `const` qualifier
560+
561+
parse_fn_pointer_cannot_be_async = an `fn` pointer type cannot be `async`
562+
.label = `async` because of this
563+
.suggestion = remove the `async` qualifier
564+
565+
parse_nested_c_variadic_type = C-variadic type `...` may not be nested inside another type
566+
567+
parse_invalid_dyn_keyword = invalid `dyn` keyword
568+
.help = `dyn` is only needed at the start of a trait `+`-separated list
569+
.suggestion = remove this keyword
570+
571+
parse_negative_bounds_not_supported = negative bounds are not supported
572+
.label = negative bounds are not supported
573+
.suggestion = {$num_bounds ->
574+
[one] remove the bound
575+
*[other] remove the bounds
576+
}
577+
578+
parse_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml`
579+
parse_help_set_edition_standalone = pass `--edition {$edition}` to `rustc`
580+
parse_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide

compiler/rustc_errors/src/diagnostic.rs

-13
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use rustc_data_structures::fx::FxHashMap;
77
use rustc_error_messages::fluent_value_from_str_list_sep_by_and;
88
use rustc_error_messages::FluentValue;
99
use rustc_lint_defs::{Applicability, LintExpectationId};
10-
use rustc_span::edition::LATEST_STABLE_EDITION;
1110
use rustc_span::symbol::Symbol;
1211
use rustc_span::{Span, DUMMY_SP};
1312
use std::borrow::Cow;
@@ -555,18 +554,6 @@ impl Diagnostic {
555554
self
556555
}
557556

558-
/// Help the user upgrade to the latest edition.
559-
/// This is factored out to make sure it does the right thing with `Cargo.toml`.
560-
pub fn help_use_latest_edition(&mut self) -> &mut Self {
561-
if std::env::var_os("CARGO").is_some() {
562-
self.help(&format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION));
563-
} else {
564-
self.help(&format!("pass `--edition {}` to `rustc`", LATEST_STABLE_EDITION));
565-
}
566-
self.note("for more on editions, read https://doc.rust-lang.org/edition-guide");
567-
self
568-
}
569-
570557
/// Disallow attaching suggestions this diagnostic.
571558
/// Any suggestions attached e.g. with the `span_suggestion_*` methods
572559
/// (before and after the call to `disable_suggestions`) will be ignored.

compiler/rustc_errors/src/diagnostic_builder.rs

-1
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,6 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
669669
sp: impl Into<MultiSpan>,
670670
msg: impl Into<SubdiagnosticMessage>,
671671
) -> &mut Self);
672-
forward!(pub fn help_use_latest_edition(&mut self,) -> &mut Self);
673672
forward!(pub fn set_is_lint(&mut self,) -> &mut Self);
674673

675674
forward!(pub fn disable_suggestions(&mut self,) -> &mut Self);

compiler/rustc_errors/src/diagnostic_impls.rs

+8
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,14 @@ impl IntoDiagnosticArg for rustc_data_structures::small_c_str::SmallCStr {
189189
}
190190
}
191191

192+
impl IntoDiagnosticArg for ast::Visibility {
193+
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
194+
let s = pprust::vis_to_string(&self);
195+
let s = s.trim_end().to_string();
196+
DiagnosticArgValue::Str(Cow::Owned(s))
197+
}
198+
}
199+
192200
impl IntoDiagnosticArg for Level {
193201
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
194202
DiagnosticArgValue::Str(Cow::Borrowed(self.to_cmd_flag()))

compiler/rustc_hir_typeck/src/errors.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22
use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, MultiSpan, SubdiagnosticMessage};
33
use rustc_macros::{Diagnostic, Subdiagnostic};
44
use rustc_middle::ty::Ty;
5-
use rustc_span::{symbol::Ident, Span};
5+
use rustc_span::{
6+
edition::{Edition, LATEST_STABLE_EDITION},
7+
symbol::Ident,
8+
Span,
9+
};
610

711
#[derive(Diagnostic)]
812
#[diag(hir_typeck_field_multiply_specified_in_initializer, code = "E0062")]
@@ -205,3 +209,24 @@ pub struct LangStartIncorrectRetTy<'tcx> {
205209
pub expected_ty: Ty<'tcx>,
206210
pub found_ty: Ty<'tcx>,
207211
}
212+
213+
#[derive(Subdiagnostic)]
214+
pub enum HelpUseLatestEdition {
215+
#[help(hir_typeck_help_set_edition_cargo)]
216+
#[note(hir_typeck_note_edition_guide)]
217+
Cargo { edition: Edition },
218+
#[help(hir_typeck_help_set_edition_standalone)]
219+
#[note(hir_typeck_note_edition_guide)]
220+
Standalone { edition: Edition },
221+
}
222+
223+
impl HelpUseLatestEdition {
224+
pub fn new() -> Self {
225+
let edition = LATEST_STABLE_EDITION;
226+
if std::env::var_os("CARGO").is_some() {
227+
Self::Cargo { edition }
228+
} else {
229+
Self::Standalone { edition }
230+
}
231+
}
232+
}

compiler/rustc_hir_typeck/src/expr.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::coercion::DynamicCoerceMany;
88
use crate::errors::TypeMismatchFruTypo;
99
use crate::errors::{AddressOfTemporaryTaken, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive};
1010
use crate::errors::{
11-
FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct,
11+
FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct, HelpUseLatestEdition,
1212
YieldExprOutsideOfGenerator,
1313
};
1414
use crate::fatally_break_rust;
@@ -23,8 +23,8 @@ use rustc_ast as ast;
2323
use rustc_data_structures::fx::FxHashMap;
2424
use rustc_data_structures::stack::ensure_sufficient_stack;
2525
use rustc_errors::{
26-
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
27-
ErrorGuaranteed, StashKey,
26+
pluralize, struct_span_err, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder,
27+
DiagnosticId, ErrorGuaranteed, StashKey,
2828
};
2929
use rustc_hir as hir;
3030
use rustc_hir::def::{CtorKind, DefKind, Res};
@@ -2433,7 +2433,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24332433
// We know by construction that `<expr>.await` is either on Rust 2015
24342434
// or results in `ExprKind::Await`. Suggest switching the edition to 2018.
24352435
err.note("to `.await` a `Future`, switch to Rust 2018 or later");
2436-
err.help_use_latest_edition();
2436+
HelpUseLatestEdition::new().add_to_diagnostic(&mut err);
24372437
}
24382438

24392439
err.emit();

compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -322,11 +322,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
322322
let generated_code = self
323323
.generate_inner_field_code(
324324
attr,
325-
FieldInfo {
326-
binding: binding_info,
327-
ty: inner_ty.inner_type().unwrap_or(&field.ty),
328-
span: &field.span(),
329-
},
325+
FieldInfo { binding: binding_info, ty: inner_ty, span: &field.span() },
330326
binding,
331327
)
332328
.unwrap_or_else(|v| v.to_compile_error());
@@ -418,9 +414,9 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
418414
Ok(self.add_spanned_subdiagnostic(binding, &fn_ident, slug))
419415
}
420416
SubdiagnosticKind::Note | SubdiagnosticKind::Help | SubdiagnosticKind::Warn => {
421-
if type_matches_path(info.ty, &["rustc_span", "Span"]) {
417+
if type_matches_path(info.ty.inner_type(), &["rustc_span", "Span"]) {
422418
Ok(self.add_spanned_subdiagnostic(binding, &fn_ident, slug))
423-
} else if type_is_unit(info.ty) {
419+
} else if type_is_unit(info.ty.inner_type()) {
424420
Ok(self.add_subdiagnostic(&fn_ident, slug))
425421
} else {
426422
report_type_error(attr, "`Span` or `()`")?
@@ -432,6 +428,15 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
432428
code_field,
433429
code_init,
434430
} => {
431+
if let FieldInnerTy::Vec(_) = info.ty {
432+
throw_invalid_attr!(attr, &meta, |diag| {
433+
diag
434+
.note("`#[suggestion(...)]` applied to `Vec` field is ambiguous")
435+
.help("to show a suggestion consisting of multiple parts, use a `Subdiagnostic` annotated with `#[multipart_suggestion(...)]`")
436+
.help("to show a variable set of suggestions, use a `Vec` of `Subdiagnostic`s annotated with `#[suggestion(...)]`")
437+
});
438+
}
439+
435440
let (span_field, mut applicability) = self.span_and_applicability_of_ty(info)?;
436441

437442
if let Some((static_applicability, span)) = static_applicability {
@@ -489,7 +494,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
489494
&self,
490495
info: FieldInfo<'_>,
491496
) -> Result<(TokenStream, SpannedOption<TokenStream>), DiagnosticDeriveError> {
492-
match &info.ty {
497+
match &info.ty.inner_type() {
493498
// If `ty` is `Span` w/out applicability, then use `Applicability::Unspecified`.
494499
ty @ Type::Path(..) if type_matches_path(ty, &["rustc_span", "Span"]) => {
495500
let binding = &info.binding.binding;

0 commit comments

Comments
 (0)