From 8fa9003621d0031a76b208b277c7832a06e1570a Mon Sep 17 00:00:00 2001 From: Tom Martin Date: Sun, 18 Jun 2023 07:19:19 +0100 Subject: [PATCH 1/7] Add translatable diagnostic for changing import binding --- compiler/rustc_resolve/messages.ftl | 3 +++ compiler/rustc_resolve/src/diagnostics.rs | 11 +++-------- compiler/rustc_resolve/src/errors.rs | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 539b88aa9d3..2952f82e2de 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -262,3 +262,6 @@ resolve_variable_bound_with_different_mode = variable `{$variable_name}` is bound inconsistently across alternatives separated by `|` .label = bound in different ways .first_binding_span = first binding + +resolve_change_import_binding = + you can use `as` to change the binding name of the import diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index e42b2df1a5a..0c780672ea3 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -30,6 +30,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, Span, SyntaxContext}; use thin_vec::ThinVec; +use crate::errors::{ChangeImportBinding, ChangeImportBindingSuggestion}; use crate::imports::{Import, ImportKind}; use crate::late::{PatternSource, Rib}; use crate::path_names_to_string; @@ -376,16 +377,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 }); } } diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index e88cbb955b5..b7b5e9d15bc 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -586,3 +586,22 @@ 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, +} From 50c971a0b7e645754e758709b399c6da0205167a Mon Sep 17 00:00:00 2001 From: Tom Martin Date: Sun, 18 Jun 2023 09:14:25 +0100 Subject: [PATCH 2/7] Add translatable diagnostic for invalid imports --- compiler/rustc_resolve/messages.ftl | 3 +++ compiler/rustc_resolve/src/errors.rs | 8 ++++++++ compiler/rustc_resolve/src/late.rs | 10 +++++----- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 2952f82e2de..3702f03269e 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -265,3 +265,6 @@ resolve_variable_bound_with_different_mode = resolve_change_import_binding = you can use `as` to change the binding name of the import + +resolve_imports_cannot_refer_to = + imports cannot refer to {$what} \ No newline at end of file diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index b7b5e9d15bc..a7a8aa8b957 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -605,3 +605,11 @@ pub(crate) struct ChangeImportBindingSuggestion { 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, +} diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ddd75ea3b33..e700e8c9ce0 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -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,11 @@ 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() { - this.r - .tcx - .sess - .span_err(ident.span, format!("imports cannot refer to {}", what)); + let what = if ns == TypeNS { "type parameters" } else { "local variables" }; + + let err = ImportsCannotReferTo { span: ident.span, what }; + this.r.tcx.sess.create_err(err).emit(); } }; From 355a6895425354ee2caf5df99fbe4ec9d136a460 Mon Sep 17 00:00:00 2001 From: Tom Martin Date: Sun, 18 Jun 2023 12:15:17 +0100 Subject: [PATCH 3/7] Add translatable diagnostic for cannot find in this scope --- compiler/rustc_resolve/messages.ftl | 5 ++++- compiler/rustc_resolve/src/errors.rs | 9 +++++++++ compiler/rustc_resolve/src/macros.rs | 13 ++++++++++--- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 3702f03269e..8c199ff0150 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -267,4 +267,7 @@ resolve_change_import_binding = you can use `as` to change the binding name of the import resolve_imports_cannot_refer_to = - imports cannot refer to {$what} \ No newline at end of file + imports cannot refer to {$what} + +resolve_cannot_find_ident_in_this_scope = + cannot find {$expected} `{$ident}` in this scope diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index a7a8aa8b957..0f9039912ed 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -613,3 +613,12 @@ pub(crate) struct ImportsCannotReferTo<'a> { 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, +} diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index ca4f3331b9a..4dcef8f6efd 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -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(); } From 4b5a5a4529d86cb0ff6abd539cbddebe81e0c0d1 Mon Sep 17 00:00:00 2001 From: Tom Martin Date: Sun, 18 Jun 2023 12:26:31 +0100 Subject: [PATCH 4/7] Add translatable diagnostic for various strings in resolve::unresolved_macro_suggestions --- compiler/rustc_resolve/messages.ftl | 13 ++++++++++ compiler/rustc_resolve/src/diagnostics.rs | 20 ++++++++------- compiler/rustc_resolve/src/errors.rs | 31 +++++++++++++++++++++++ 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 8c199ff0150..75799aa8b70 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -271,3 +271,16 @@ resolve_imports_cannot_refer_to = resolve_cannot_find_ident_in_this_scope = cannot find {$expected} `{$ident}` in this scope + +resolve_explicit_unsafe_traits = + unsafe traits like `{$ident}` should be implemented explicitly + +resolve_added_macro_use = + have you added the `#[macro_use]` on the module/import? + +resolve_consider_adding_a_derive = + consider adding a derive + .suggestion = FIXME + +resolve_consider_adding_a_derive_enum = + consider adding `#[derive(Default)]` to this enum diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 0c780672ea3..2a22e1ba242 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -30,7 +30,10 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, Span, SyntaxContext}; use thin_vec::ThinVec; -use crate::errors::{ChangeImportBinding, ChangeImportBindingSuggestion}; +use crate::errors::{ + AddedMacroUse, ChangeImportBinding, ChangeImportBindingSuggestion, ConsiderAddingADerive, + ConsiderAddingADeriveEnum, ExplicitUnsafeTraits, +}; use crate::imports::{Import, ImportKind}; use crate::late::{PatternSource, Rib}; use crate::path_names_to_string; @@ -1377,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 @@ -1392,12 +1394,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { 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); + err.subdiagnostic(ConsiderAddingADerive { + span: head_span, + suggestion: format!("#[derive(Default)]\n{head}") + }); } else { - err.span_help( - head_span, - "consider adding `#[derive(Default)]` to this enum", - ); + err.subdiagnostic(ConsiderAddingADeriveEnum { span: head_span }); } } for ns in [Namespace::MacroNS, Namespace::TypeNS, Namespace::ValueNS] { diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 0f9039912ed..fb70fbe2c1f 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -622,3 +622,34 @@ pub(crate) struct CannotFindIdentInThisScope<'a> { 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, +} + +#[derive(Subdiagnostic)] +#[help(resolve_consider_adding_a_derive_enum)] +pub(crate) struct ConsiderAddingADeriveEnum { + #[primary_span] + pub(crate) span: Span, +} From c07b50a2137277a518799de3e5755cd52b9ab959 Mon Sep 17 00:00:00 2001 From: Tom Martin Date: Sun, 18 Jun 2023 13:10:05 +0100 Subject: [PATCH 5/7] Fix tidy --- compiler/rustc_resolve/messages.ftl | 43 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 75799aa8b70..062f9e85a9c 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -5,6 +5,9 @@ resolve_add_as_non_derive = add as non-Derive macro `#[{$macro_path}]` +resolve_added_macro_use = + have you added the `#[macro_use]` on the module/import? + resolve_ampersand_used_without_explicit_lifetime_name = `&` without an explicit lifetime name cannot be used here .note = explicit lifetime name needed here @@ -45,9 +48,21 @@ resolve_cannot_capture_dynamic_environment_in_fn_item = can't capture dynamic environment in a fn item .help = use the `|| {"{"} ... {"}"}` closure form instead +resolve_cannot_find_ident_in_this_scope = + cannot find {$expected} `{$ident}` in this scope + resolve_cannot_use_self_type_here = can't use `Self` here +resolve_change_import_binding = + you can use `as` to change the binding name of the import + +resolve_consider_adding_a_derive = + consider adding a derive + +resolve_consider_adding_a_derive_enum = + consider adding `#[derive(Default)]` to this enum + resolve_const_not_member_of_trait = const `{$const_}` is not a member of trait `{$trait_}` .label = not a member of trait `{$trait_}` @@ -74,6 +89,9 @@ resolve_expected_found = expected module, found {$res} `{$path_str}` .label = not a module +resolve_explicit_unsafe_traits = + unsafe traits like `{$ident}` should be implemented explicitly + resolve_forward_declared_generic_param = generic parameters with a default cannot use forward declared identifiers .label = defaulted generic parameters cannot be forward declared @@ -96,6 +114,9 @@ resolve_ident_bound_more_than_once_in_same_pattern = resolve_imported_crate = `$crate` may not be imported +resolve_imports_cannot_refer_to = + imports cannot refer to {$what} + resolve_indeterminate = cannot determine resolution for the visibility @@ -262,25 +283,3 @@ resolve_variable_bound_with_different_mode = variable `{$variable_name}` is bound inconsistently across alternatives separated by `|` .label = bound in different ways .first_binding_span = first binding - -resolve_change_import_binding = - you can use `as` to change the binding name of the import - -resolve_imports_cannot_refer_to = - imports cannot refer to {$what} - -resolve_cannot_find_ident_in_this_scope = - cannot find {$expected} `{$ident}` in this scope - -resolve_explicit_unsafe_traits = - unsafe traits like `{$ident}` should be implemented explicitly - -resolve_added_macro_use = - have you added the `#[macro_use]` on the module/import? - -resolve_consider_adding_a_derive = - consider adding a derive - .suggestion = FIXME - -resolve_consider_adding_a_derive_enum = - consider adding `#[derive(Default)]` to this enum From db613750a91215a89ac25fd65cdaef02df2f73d5 Mon Sep 17 00:00:00 2001 From: Tom Martin Date: Mon, 19 Jun 2023 16:21:33 +0100 Subject: [PATCH 6/7] Reformatting --- compiler/rustc_resolve/src/late.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index e700e8c9ce0..9f4573ea025 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2247,9 +2247,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { let report_error = |this: &Self, ns| { if this.should_report_errs() { let what = if ns == TypeNS { "type parameters" } else { "local variables" }; - - let err = ImportsCannotReferTo { span: ident.span, what }; - this.r.tcx.sess.create_err(err).emit(); + this.r + .tcx + .sess + .create_err(ImportsCannotReferTo { span: ident.span, what }) + .emit(); } }; From 2027e989bce7d1c2f702d7aed383bf9cbdaf51d1 Mon Sep 17 00:00:00 2001 From: Tom Martin Date: Mon, 19 Jun 2023 16:22:21 +0100 Subject: [PATCH 7/7] Remove unreachable and untested suggestion for invalid span enum derive(Default) --- compiler/rustc_resolve/messages.ftl | 3 --- compiler/rustc_resolve/src/diagnostics.rs | 14 +++++--------- compiler/rustc_resolve/src/errors.rs | 7 ------- tests/ui/enum/suggest-default-attribute.stderr | 2 +- 4 files changed, 6 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 062f9e85a9c..60b6d74da7b 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -60,9 +60,6 @@ resolve_change_import_binding = resolve_consider_adding_a_derive = consider adding a derive -resolve_consider_adding_a_derive_enum = - consider adding `#[derive(Default)]` to this enum - resolve_const_not_member_of_trait = const `{$const_}` is not a member of trait `{$trait_}` .label = not a member of trait `{$trait_}` diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 2a22e1ba242..539b4a1d5e7 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -32,7 +32,7 @@ use thin_vec::ThinVec; use crate::errors::{ AddedMacroUse, ChangeImportBinding, ChangeImportBindingSuggestion, ConsiderAddingADerive, - ConsiderAddingADeriveEnum, ExplicitUnsafeTraits, + ExplicitUnsafeTraits, }; use crate::imports::{Import, ImportKind}; use crate::late::{PatternSource, Rib}; @@ -1393,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.subdiagnostic(ConsiderAddingADerive { - span: head_span, - suggestion: format!("#[derive(Default)]\n{head}") - }); - } else { - err.subdiagnostic(ConsiderAddingADeriveEnum { span: head_span }); - } + 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( diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index fb70fbe2c1f..93b626c7794 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -646,10 +646,3 @@ pub(crate) struct ConsiderAddingADerive { pub(crate) span: Span, pub(crate) suggestion: String, } - -#[derive(Subdiagnostic)] -#[help(resolve_consider_adding_a_derive_enum)] -pub(crate) struct ConsiderAddingADeriveEnum { - #[primary_span] - pub(crate) span: Span, -} diff --git a/tests/ui/enum/suggest-default-attribute.stderr b/tests/ui/enum/suggest-default-attribute.stderr index fb830d3f78b..b56d599a786 100644 --- a/tests/ui/enum/suggest-default-attribute.stderr +++ b/tests/ui/enum/suggest-default-attribute.stderr @@ -7,7 +7,7 @@ LL | #[default] help: consider adding a derive | LL + #[derive(Default)] -LL ~ pub enum Test { +LL | pub enum Test { | error: aborting due to previous error