Rollup merge of #112768 - NotStirred:translatable_diag/resolve1, r=WaffleLapkin

Rewrite various resolve/diagnostics errors as translatable diagnostics

additional question:

For trivial strings is it ever accepted to use `fluent_generated::foo` in a `label` for example? Or is an empty struct `Diagnostic` preferred?
This commit is contained in:
Matthias Krüger 2023-06-19 19:26:27 +02:00 committed by GitHub
commit 6de869fd23
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 105 additions and 25 deletions

View file

@ -30,6 +30,10 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{BytePos, Span, SyntaxContext};
use thin_vec::ThinVec;
use crate::errors::{
AddedMacroUse, ChangeImportBinding, ChangeImportBindingSuggestion, ConsiderAddingADerive,
ExplicitUnsafeTraits,
};
use crate::imports::{Import, ImportKind};
use crate::late::{PatternSource, Rib};
use crate::path_names_to_string;
@ -376,16 +380,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
_ => unreachable!(),
}
let rename_msg = "you can use `as` to change the binding name of the import";
if let Some(suggestion) = suggestion {
err.span_suggestion(
binding_span,
rename_msg,
suggestion,
Applicability::MaybeIncorrect,
);
err.subdiagnostic(ChangeImportBindingSuggestion { span: binding_span, suggestion });
} else {
err.span_label(binding_span, rename_msg);
err.subdiagnostic(ChangeImportBinding { span: binding_span });
}
}
@ -1382,12 +1380,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
);
if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) {
let msg = format!("unsafe traits like `{}` should be implemented explicitly", ident);
err.span_note(ident.span, msg);
err.subdiagnostic(ExplicitUnsafeTraits { span: ident.span, ident });
return;
}
if self.macro_names.contains(&ident.normalize_to_macros_2_0()) {
err.help("have you added the `#[macro_use]` on the module/import?");
err.subdiagnostic(AddedMacroUse);
return;
}
if ident.name == kw::Default
@ -1396,14 +1393,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let span = self.def_span(def_id);
let source_map = self.tcx.sess.source_map();
let head_span = source_map.guess_head_span(span);
if let Ok(head) = source_map.span_to_snippet(head_span) {
err.span_suggestion(head_span, "consider adding a derive", format!("#[derive(Default)]\n{head}"), Applicability::MaybeIncorrect);
} else {
err.span_help(
head_span,
"consider adding `#[derive(Default)]` to this enum",
);
}
err.subdiagnostic(ConsiderAddingADerive {
span: head_span.shrink_to_lo(),
suggestion: format!("#[derive(Default)]\n")
});
}
for ns in [Namespace::MacroNS, Namespace::TypeNS, Namespace::ValueNS] {
if let Ok(binding) = self.early_resolve_ident_in_lexical_scope(

View file

@ -586,3 +586,63 @@ pub(crate) enum ParamKindInEnumDiscriminant {
#[note(resolve_lifetime_param_in_enum_discriminant)]
Lifetime,
}
#[derive(Subdiagnostic)]
#[label(resolve_change_import_binding)]
pub(crate) struct ChangeImportBinding {
#[primary_span]
pub(crate) span: Span,
}
#[derive(Subdiagnostic)]
#[suggestion(
resolve_change_import_binding,
code = "{suggestion}",
applicability = "maybe-incorrect"
)]
pub(crate) struct ChangeImportBindingSuggestion {
#[primary_span]
pub(crate) span: Span,
pub(crate) suggestion: String,
}
#[derive(Diagnostic)]
#[diag(resolve_imports_cannot_refer_to)]
pub(crate) struct ImportsCannotReferTo<'a> {
#[primary_span]
pub(crate) span: Span,
pub(crate) what: &'a str,
}
#[derive(Diagnostic)]
#[diag(resolve_cannot_find_ident_in_this_scope)]
pub(crate) struct CannotFindIdentInThisScope<'a> {
#[primary_span]
pub(crate) span: Span,
pub(crate) expected: &'a str,
pub(crate) ident: Ident,
}
#[derive(Subdiagnostic)]
#[note(resolve_explicit_unsafe_traits)]
pub(crate) struct ExplicitUnsafeTraits {
#[primary_span]
pub(crate) span: Span,
pub(crate) ident: Ident,
}
#[derive(Subdiagnostic)]
#[help(resolve_added_macro_use)]
pub(crate) struct AddedMacroUse;
#[derive(Subdiagnostic)]
#[suggestion(
resolve_consider_adding_a_derive,
code = "{suggestion}",
applicability = "maybe-incorrect"
)]
pub(crate) struct ConsiderAddingADerive {
#[primary_span]
pub(crate) span: Span,
pub(crate) suggestion: String,
}

View file

@ -6,6 +6,7 @@
//! If you wonder why there's no `early.rs`, that's because it's split into three files -
//! `build_reduced_graph.rs`, `macros.rs` and `imports.rs`.
use crate::errors::ImportsCannotReferTo;
use crate::BindingKey;
use crate::{path_names_to_string, rustdoc, BindingError, Finalize, LexicalScopeBinding};
use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult};
@ -2244,12 +2245,13 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
_ => &[TypeNS],
};
let report_error = |this: &Self, ns| {
let what = if ns == TypeNS { "type parameters" } else { "local variables" };
if this.should_report_errs() {
let what = if ns == TypeNS { "type parameters" } else { "local variables" };
this.r
.tcx
.sess
.span_err(ident.span, format!("imports cannot refer to {}", what));
.create_err(ImportsCannotReferTo { span: ident.span, what })
.emit();
}
};

View file

@ -1,7 +1,9 @@
//! A bunch of methods and structures more or less related to resolving macros and
//! interface provided by `Resolver` to macro expander.
use crate::errors::{self, AddAsNonDerive, MacroExpectedFound, RemoveSurroundingDerive};
use crate::errors::{
self, AddAsNonDerive, CannotFindIdentInThisScope, MacroExpectedFound, RemoveSurroundingDerive,
};
use crate::Namespace::*;
use crate::{BuiltinMacroState, Determinacy};
use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet};
@ -793,8 +795,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
Err(..) => {
let expected = kind.descr_expected();
let msg = format!("cannot find {} `{}` in this scope", expected, ident);
let mut err = self.tcx.sess.struct_span_err(ident.span, msg);
let mut err = self.tcx.sess.create_err(CannotFindIdentInThisScope {
span: ident.span,
expected,
ident,
});
self.unresolved_macro_suggestions(&mut err, kind, &parent_scope, ident, krate);
err.emit();
}