diff options
| -rw-r--r-- | compiler/rustc_resolve/messages.ftl | 106 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 273 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/errors.rs | 267 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/macros.rs | 61 |
5 files changed, 537 insertions, 174 deletions
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index c737ad86e46..95592b1c1dd 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -38,6 +38,9 @@ resolve_attempt_to_use_non_constant_value_in_constant_with_suggestion = resolve_attempt_to_use_non_constant_value_in_constant_without_suggestion = this would need to be a `{$suggestion}` +resolve_attributes_starting_with_rustc_are_reserved = + attributes starting with `rustc` are reserved for use by the `rustc` compiler + resolve_bad_macro_import = bad macro import resolve_binding_in_never_pattern = @@ -70,12 +73,19 @@ resolve_cannot_determine_macro_resolution = cannot determine resolution for the {$kind} `{$path}` .note = import resolution is stuck, try simplifying macro imports +resolve_cannot_find_builtin_macro_with_name = + cannot find a built-in macro with name `{$ident}` + resolve_cannot_find_ident_in_this_scope = cannot find {$expected} `{$ident}` in this scope resolve_cannot_glob_import_possible_crates = cannot glob-import all possible crates +resolve_cannot_use_through_an_import = + cannot use {$article} {$descr} through an import + .note = the {$descr} imported here + resolve_change_import_binding = you can use `as` to change the binding name of the import @@ -88,6 +98,12 @@ resolve_consider_adding_macro_export = resolve_consider_declaring_with_pub = consider declaring type or module `{$ident}` with `pub` +resolve_consider_making_the_field_public = + { $number_of_fields -> + [one] consider making the field publicly accessible + *[other] consider making the fields publicly accessible + } + resolve_consider_marking_as_pub = consider marking `{$ident}` as `pub` in the imported module @@ -108,6 +124,9 @@ resolve_const_param_in_non_trivial_anon_const = resolve_const_param_in_ty_of_const_param = const parameters may not be used in the type of const parameters +resolve_constructor_private_if_any_field_private = + a constructor is private if any of the fields is private + resolve_elided_anonymous_lifetime_report_error = `&` without an explicit lifetime name cannot be used here .label = explicit lifetime name needed here @@ -133,10 +152,20 @@ resolve_extern_crate_self_requires_renaming = `extern crate self;` requires renaming .suggestion = rename the `self` crate to be able to import it +resolve_failed_resolve_unresolve_import = failed to resolve: unresolved import + +resolve_failed_resolve_unresolve_import_label = unresolved import + resolve_forward_declared_generic_param = generic parameters with a default cannot use forward declared identifiers .label = defaulted generic parameters cannot be forward declared +resolve_found_an_item_configured_out = + found an item that was configured out + +resolve_generic_arguments_in_macro_path = + generic arguments in macro path + resolve_generic_params_from_outer_item = can't use {$is_self -> [true] `Self` @@ -171,6 +200,12 @@ resolve_ident_bound_more_than_once_in_same_pattern = identifier `{$identifier}` is bound more than once in the same pattern .label = used in a pattern more than once +resolve_ident_imported_here_but_it_is_desc = + `{$imported_ident}` is imported here, but it is {$imported_ident_desc} + +resolve_ident_in_scope_but_it_is_desc = + `{$imported_ident}` is in scope, but it is {$imported_ident_desc} + resolve_imported_crate = `$crate` may not be imported resolve_imported_macro_not_found = imported macro not found @@ -190,6 +225,13 @@ resolve_is_not_directly_importable = `{$target}` is not directly importable .label = cannot be imported directly +resolve_is_private = + {$ident_descr} `{$ident}` is private + .label = private {$ident_descr} + +resolve_item_was_behind_feature = + the item is gated behind the `{$feature}` feature + resolve_items_in_traits_are_not_importable = items in traits are not importable @@ -217,6 +259,7 @@ resolve_macro_expanded_extern_crate_cannot_shadow_extern_arguments = resolve_macro_expected_found = expected {$expected}, found {$found} `{$macro_path}` + .label = not {$article} {$expected} resolve_macro_extern_deprecated = `#[macro_escape]` is a deprecated synonym for `#[macro_use]` @@ -237,11 +280,45 @@ resolve_missing_macro_rules_name = maybe you have forgotten to define a name for resolve_module_only = visibility must resolve to a module +resolve_name_defined_multiple_time = + the name `{$name}` is defined multiple times + .note = `{$name}` must be defined only once in the {$descr} namespace of this {$container} + +resolve_name_defined_multiple_time_old_binding_definition = + previous definition of the {$old_kind} `{$name}` here + +resolve_name_defined_multiple_time_old_binding_import = + previous import of the {$old_kind} `{$name}` here + +resolve_name_defined_multiple_time_redefined = + `{$name}` redefined here + +resolve_name_defined_multiple_time_reimported = + `{$name}` reimported here + resolve_name_is_already_used_as_generic_parameter = the name `{$name}` is already used for a generic parameter in this item's generic parameters .label = already used .first_use_of_name = first use of `{$name}` +resolve_name_reserved_in_attribute_namespace = + name `{$ident}` is reserved in attribute namespace + +resolve_note_and_refers_to_the_item_defined_here = + {$first -> + [true] {$dots -> + [true] the {$binding_descr} `{$binding_name}` is defined here... + *[false] the {$binding_descr} `{$binding_name}` is defined here + } + *[false] {$dots -> + [true] ...and refers to the {$binding_descr} `{$binding_name}` which is defined here... + *[false] ...and refers to the {$binding_descr} `{$binding_name}` which is defined here + } + } + +resolve_outer_ident_is_not_publicly_reexported = + {$outer_ident_descr} `{$outer_ident}` is not publicly re-exported + resolve_param_in_enum_discriminant = generic parameters may not be used in enum discriminant values .label = cannot perform const operation using `{$name}` @@ -275,6 +352,8 @@ resolve_relative_2018 = resolve_remove_surrounding_derive = remove from the surrounding `derive()` +resolve_remove_unnecessary_import = remove unnecessary import + resolve_self_import_can_only_appear_once_in_the_list = `self` import can only appear once in an import list .label = can only appear once in an import list @@ -296,13 +375,33 @@ resolve_self_in_generic_param_default = generic parameters cannot use `Self` in their defaults .label = `Self` in generic parameter default +resolve_similarly_named_defined_here = + similarly named {$candidate_descr} `{$candidate}` defined here + +resolve_single_item_defined_here = + {$candidate_descr} `{$candidate}` defined here + resolve_static_lifetime_is_reserved = invalid lifetime parameter name: `{$lifetime}` .label = 'static is a reserved lifetime name +resolve_suggestion_import_ident_directly = + import `{$ident}` directly + +resolve_suggestion_import_ident_through_reexport = + import `{$ident}` through the re-export + resolve_tool_module_imported = cannot use a tool module through an import .note = the tool module imported here +resolve_tool_only_accepts_identifiers = + `{$tool}` only accepts identifiers + .label = not an identifier + +resolve_tool_was_already_registered = + tool `{$tool}` was already registered + .label = already registered here + resolve_trait_impl_duplicate = duplicate definitions with name `{$name}`: .label = duplicate definition @@ -368,3 +467,10 @@ resolve_variable_is_not_bound_in_all_patterns = variable `{$name}` is not bound in all patterns resolve_variable_not_in_all_patterns = variable not in all patterns + +resolve_you_could_import_this_desc = you could import this {$desc} + +resolve_trait_impl_mismatch = + item `{$name}` is an associated {$kind}, which doesn't match its trait `{$trait_path}` + .label = does not match trait + .trait_impl_mismatch_label_item = item in trait \ No newline at end of file diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index a367a5f21db..12484462f82 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -6,8 +6,8 @@ use rustc_ast::{MetaItemKind, NestedMetaItem}; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{ - codes::*, pluralize, report_ambiguity_error, struct_span_code_err, Applicability, Diag, - DiagCtxt, ErrorGuaranteed, MultiSpan, SuggestionStyle, + codes::*, report_ambiguity_error, struct_span_code_err, Applicability, Diag, DiagCtxt, + ErrorGuaranteed, MultiSpan, SuggestionStyle, }; use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; @@ -29,10 +29,9 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, Span, SyntaxContext}; use thin_vec::{thin_vec, ThinVec}; -use crate::errors::{self, - AddedMacroUse, ChangeImportBinding, ChangeImportBindingSuggestion, - ConsiderAddingADerive, ExplicitUnsafeTraits, MacroDefinedLater, MacroSuggMovePosition, - MaybeMissingMacroRulesName, +use crate::errors::{ + self, AddedMacroUse, ChangeImportBinding, ChangeImportBindingSuggestion, ConsiderAddingADerive, + ExplicitUnsafeTraits, MacroDefinedLater, MacroSuggMovePosition, MaybeMissingMacroRulesName, }; use crate::imports::{Import, ImportKind}; use crate::late::{PatternSource, Rib}; @@ -226,16 +225,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ModuleKind::Block => "block", }; - let old_noun = match old_binding.is_import_user_facing() { - true => "import", - false => "definition", - }; - - let new_participle = match new_binding.is_import_user_facing() { - true => "imported", - false => "defined", - }; - let (name, span) = (ident.name, self.tcx.sess.source_map().guess_head_span(new_binding.span)); @@ -254,35 +243,51 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { (TypeNS, _) => "type", }; - let msg = format!("the name `{name}` is defined multiple times"); - - let mut err = match (old_binding.is_extern_crate(), new_binding.is_extern_crate()) { - (true, true) => struct_span_code_err!(self.dcx(), span, E0259, "{}", msg), + let code = match (old_binding.is_extern_crate(), new_binding.is_extern_crate()) { + (true, true) => E0259, (true, _) | (_, true) => match new_binding.is_import() && old_binding.is_import() { - true => struct_span_code_err!(self.dcx(), span, E0254, "{}", msg), - false => struct_span_code_err!(self.dcx(), span, E0260, "{}", msg), + true => E0254, + false => E0260, }, _ => match (old_binding.is_import_user_facing(), new_binding.is_import_user_facing()) { - (false, false) => struct_span_code_err!(self.dcx(), span, E0428, "{}", msg), - (true, true) => struct_span_code_err!(self.dcx(), span, E0252, "{}", msg), - _ => struct_span_code_err!(self.dcx(), span, E0255, "{}", msg), + (false, false) => E0428, + (true, true) => E0252, + _ => E0255, }, }; - err.note(format!( - "`{}` must be defined only once in the {} namespace of this {}", - name, - ns.descr(), - container - )); - - err.span_label(span, format!("`{name}` re{new_participle} here")); - if !old_binding.span.is_dummy() && old_binding.span != span { - err.span_label( - self.tcx.sess.source_map().guess_head_span(old_binding.span), - format!("previous {old_noun} of the {old_kind} `{name}` here"), - ); - } + let label = match new_binding.is_import_user_facing() { + true => errors::NameDefinedMultipleTimeLabel::Reimported { span, name }, + false => errors::NameDefinedMultipleTimeLabel::Redefined { span, name }, + }; + + let old_binding_label = + (!old_binding.span.is_dummy() && old_binding.span != span).then(|| { + let span = self.tcx.sess.source_map().guess_head_span(old_binding.span); + match old_binding.is_import_user_facing() { + true => errors::NameDefinedMultipleTimeOldBindingLabel::Import { + span, + name, + old_kind, + }, + false => errors::NameDefinedMultipleTimeOldBindingLabel::Definition { + span, + name, + old_kind, + }, + } + }); + + let mut err = self + .dcx() + .create_err(errors::NameDefinedMultipleTime { + span, + descr: ns.descr(), + container, + label, + old_binding_label, + }) + .with_code(code); // See https://github.com/rust-lang/rust/issues/32354 use NameBindingKind::Import; @@ -330,20 +335,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { match import { Some((import, span, true)) if should_remove_import && import.is_nested() => { - self.add_suggestion_for_duplicate_nested_use(&mut err, import, span) + self.add_suggestion_for_duplicate_nested_use(&mut err, import, span); } Some((import, _, true)) if should_remove_import && !import.is_glob() => { // Simple case - remove the entire import. Due to the above match arm, this can // only be a single use so just remove it entirely. - err.tool_only_span_suggestion( - import.use_span_with_attributes, - "remove unnecessary import", - "", - Applicability::MaybeIncorrect, + err.subdiagnostic( + self.tcx.dcx(), + errors::ToolOnlyRemoveUnnecessaryImport { + span: import.use_span_with_attributes, + }, ); } Some((import, span, _)) => { - self.add_suggestion_for_rename_of_use(&mut err, name, import, span) + self.add_suggestion_for_rename_of_use(&mut err, name, import, span); } _ => {} } @@ -444,7 +449,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { binding_span: Span, ) { assert!(import.is_nested()); - let message = "remove unnecessary import"; // Two examples will be used to illustrate the span manipulations we're doing: // @@ -460,22 +464,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // previous imports. if found_closing_brace { if let Some(span) = extend_span_to_previous_binding(self.tcx.sess, span) { - err.tool_only_span_suggestion(span, message, "", Applicability::MaybeIncorrect); + err.subdiagnostic(self.dcx(), errors::ToolOnlyRemoveUnnecessaryImport { span }); } else { // Remove the entire line if we cannot extend the span back, this indicates an // `issue_52891::{self}` case. - err.span_suggestion( - import.use_span_with_attributes, - message, - "", - Applicability::MaybeIncorrect, + err.subdiagnostic( + self.dcx(), + errors::RemoveUnnecessaryImport { span: import.use_span_with_attributes }, ); } return; } - err.span_suggestion(span, message, "", Applicability::MachineApplicable); + err.subdiagnostic(self.dcx(), errors::RemoveUnnecessaryImport { span }); } pub(crate) fn lint_if_path_starts_with_module( @@ -571,14 +573,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { resolution_error: ResolutionError<'a>, ) -> Diag<'_> { match resolution_error { - ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params, def_kind) => { + ResolutionError::GenericParamsFromOuterItem( + outer_res, + has_generic_params, + def_kind, + ) => { use errs::GenericParamsFromOuterItemLabel as Label; let static_or_const = match def_kind { - DefKind::Static{ .. } => Some(errs::GenericParamsFromOuterItemStaticOrConst::Static), + DefKind::Static { .. } => { + Some(errs::GenericParamsFromOuterItemStaticOrConst::Static) + } DefKind::Const => Some(errs::GenericParamsFromOuterItemStaticOrConst::Const), _ => None, }; - let is_self = matches!(outer_res, Res::SelfTyParam { .. } | Res::SelfTyAlias { .. }); + let is_self = + matches!(outer_res, Res::SelfTyParam { .. } | Res::SelfTyAlias { .. }); let mut err = errs::GenericParamsFromOuterItem { span, label: None, @@ -677,20 +686,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let origin_sp = origin.iter().copied().collect::<Vec<_>>(); let msp = MultiSpan::from_spans(target_sp.clone()); - let mut err = self.dcx().create_err(errors::VariableIsNotBoundInAllPatterns { - multispan: msp, - name, - }); + let mut err = self + .dcx() + .create_err(errors::VariableIsNotBoundInAllPatterns { multispan: msp, name }); for sp in target_sp { - err.subdiagnostic(self.dcx(), errors::PatternDoesntBindName { - span: sp, - name, - }); + err.subdiagnostic(self.dcx(), errors::PatternDoesntBindName { span: sp, name }); } for sp in origin_sp { - err.subdiagnostic(self.dcx(), errors::VariableNotInAllPatterns { - span: sp, - }); + err.subdiagnostic(self.dcx(), errors::VariableNotInAllPatterns { span: sp }); } if could_be_path { let import_suggestions = self.lookup_import_candidates( @@ -963,17 +966,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { code, trait_item_span, trait_path, - } => { - self.dcx().struct_span_err( + } => self + .dcx() + .create_err(errors::TraitImplMismatch { span, - format!( - "item `{name}` is an associated {kind}, which doesn't match its trait `{trait_path}`", - ), - ) - .with_code(code) - .with_span_label(span, "does not match trait") - .with_span_label(trait_item_span, "item in trait") - } + name, + kind, + trait_path, + trait_item_span, + }) + .with_code(code), ResolutionError::TraitImplDuplicate { name, trait_item_span, old_span } => self .dcx() .create_err(errs::TraitImplDuplicate { span, name, trait_item_span, old_span }), @@ -1534,17 +1536,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }; if let crate::NameBindingKind::Import { import, .. } = binding.kind { if !import.span.is_dummy() { - err.span_note( - import.span, - format!("`{ident}` is imported here, but it is {desc}"), - ); + let note = errors::IdentImporterHereButItIsDesc { + span: import.span, + imported_ident: ident, + imported_ident_desc: &desc, + }; + err.subdiagnostic(self.tcx.dcx(), note); // Silence the 'unused import' warning we might get, // since this diagnostic already covers that import. self.record_use(ident, binding, Used::Other); return; } } - err.note(format!("`{ident}` is in scope, but it is {desc}")); + let note = errors::IdentInScopeButItIsDesc { + imported_ident: ident, + imported_ident_desc: &desc, + }; + err.subdiagnostic(self.tcx.dcx(), note); return; } } @@ -1584,20 +1592,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // | ^ return false; } - let prefix = match suggestion.target { - SuggestionTarget::SimilarlyNamed => "similarly named ", - SuggestionTarget::SingleItem => "", + let span = self.tcx.sess.source_map().guess_head_span(def_span); + let candidate_descr = suggestion.res.descr(); + let candidate = suggestion.candidate; + let label = match suggestion.target { + SuggestionTarget::SimilarlyNamed => { + errors::DefinedHere::SimilarlyNamed { span, candidate_descr, candidate } + } + SuggestionTarget::SingleItem => { + errors::DefinedHere::SingleItem { span, candidate_descr, candidate } + } }; - - err.span_label( - self.tcx.sess.source_map().guess_head_span(def_span), - format!( - "{}{} `{}` defined here", - prefix, - suggestion.res.descr(), - suggestion.candidate, - ), - ); + err.subdiagnostic(self.tcx.dcx(), label); } let (span, sugg, post) = if let SuggestionTarget::SimilarlyNamed = suggestion.target @@ -1751,16 +1757,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { |b: NameBinding<'_>| if b.is_import() { &import_descr } else { &nonimport_descr }; // Print the primary message. - let descr = get_descr(binding); - let mut err = struct_span_code_err!( - self.dcx(), - ident.span, - E0603, - "{} `{}` is private", - descr, - ident - ); - err.span_label(ident.span, format!("private {descr}")); + let ident_descr = get_descr(binding); + let mut err = + self.dcx().create_err(errors::IsPrivate { span: ident.span, ident_descr, ident }); let mut not_publicly_reexported = false; if let Some((this_res, outer_ident)) = outermost_res { @@ -1784,10 +1783,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // If we suggest importing a public re-export, don't point at the definition. if point_to_def && ident.span != outer_ident.span { not_publicly_reexported = true; - err.span_label( - outer_ident.span, - format!("{} `{outer_ident}` is not publicly re-exported", this_res.descr()), - ); + let label = errors::OuterIdentIsNotPubliclyReexported { + span: outer_ident.span, + outer_ident_descr: this_res.descr(), + outer_ident, + }; + err.subdiagnostic(self.tcx.dcx(), label); } } @@ -1801,18 +1802,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { { non_exhaustive = Some(attr.span); } else if let Some(span) = ctor_fields_span { - err.span_label(span, "a constructor is private if any of the fields is private"); + let label = errors::ConstructorPrivateIfAnyFieldPrivate { span }; + err.subdiagnostic(self.tcx.dcx(), label); if let Res::Def(_, d) = res && let Some(fields) = self.field_visibility_spans.get(&d) { - err.multipart_suggestion_verbose( - format!( - "consider making the field{} publicly accessible", - pluralize!(fields.len()) - ), - fields.iter().map(|span| (*span, "pub ".to_string())).collect(), - Applicability::MaybeIncorrect, - ); + let spans = fields.iter().map(|span| *span).collect(); + let sugg = + errors::ConsiderMakingTheFieldPublic { spans, number_of_fields: fields.len() }; + err.subdiagnostic(self.tcx.dcx(), sugg); } } @@ -1895,13 +1893,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { NameBindingKind::Res(_) | NameBindingKind::Module(_) => {} } let first = binding == first_binding; - let msg = format!( - "{and_refers_to}the {item} `{name}`{which} is defined here{dots}", - and_refers_to = if first { "" } else { "...and refers to " }, - item = get_descr(binding), - which = if first { "" } else { " which" }, - dots = if next_binding.is_some() { "..." } else { "" }, - ); let def_span = self.tcx.sess.source_map().guess_head_span(binding.span); let mut note_span = MultiSpan::from_span(def_span); if !first && binding.vis.is_public() { @@ -1921,7 +1912,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { "cannot be constructed because it is `#[non_exhaustive]`", ); } - err.span_note(note_span, msg); + let note = errors::NoteAndRefersToTheItemDefinedHere { + span: note_span, + binding_descr: get_descr(binding), + binding_name: name, + first, + dots: next_binding.is_some(), + }; + err.subdiagnostic(self.tcx.dcx(), note); } // We prioritize shorter paths, non-core imports and direct imports over the alternatives. sugg_paths.sort_by_key(|(p, reexport)| (p.len(), p[0] == "core", *reexport)); @@ -1935,15 +1933,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { continue; } let path = sugg.join("::"); - err.span_suggestion_verbose( - dedup_span, - format!( - "import `{ident}` {}", - if reexport { "through the re-export" } else { "directly" } - ), - path, - Applicability::MachineApplicable, - ); + let sugg = if reexport { + errors::ImportIdent::ThroughReExport { span: dedup_span, ident, path } + } else { + errors::ImportIdent::Directly { span: dedup_span, ident, path } + }; + err.subdiagnostic(self.tcx.dcx(), sugg); break; } @@ -2523,13 +2518,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { continue; } - err.span_note(name.span, "found an item that was configured out"); + let note = errors::FoundItemConfigureOut { span: name.span }; + err.subdiagnostic(self.tcx.dcx(), note); if let MetaItemKind::List(nested) = &cfg.kind && let NestedMetaItem::MetaItem(meta_item) = &nested[0] && let MetaItemKind::NameValue(feature_name) = &meta_item.kind { - err.note(format!("the item is gated behind the `{}` feature", feature_name.symbol)); + let note = errors::ItemWasBehindFeature { feature: feature_name.symbol }; + err.subdiagnostic(self.tcx.dcx(), note); } } } diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 9a140f98c7f..e1ab5b57c3c 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -1,3 +1,4 @@ +#![allow(dead_code)] use rustc_errors::{codes::*, Applicability, MultiSpan}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{ @@ -525,8 +526,10 @@ pub(crate) struct ModuleOnly(#[primary_span] pub(crate) Span); #[diag(resolve_macro_expected_found)] pub(crate) struct MacroExpectedFound<'a> { #[primary_span] + #[label] pub(crate) span: Span, pub(crate) found: &'a str, + pub(crate) article: &'static str, pub(crate) expected: &'a str, pub(crate) macro_path: &'a str, #[subdiagnostic] @@ -955,3 +958,267 @@ pub(crate) struct VariableNotInAllPatterns { #[primary_span] pub(crate) span: Span, } + +#[derive(Diagnostic)] +#[diag(resolve_name_defined_multiple_time)] +#[note] +pub(crate) struct NameDefinedMultipleTime { + #[primary_span] + pub(crate) span: Span, + pub(crate) descr: &'static str, + pub(crate) container: &'static str, + #[subdiagnostic] + pub(crate) label: NameDefinedMultipleTimeLabel, + #[subdiagnostic] + pub(crate) old_binding_label: Option<NameDefinedMultipleTimeOldBindingLabel>, +} + +#[derive(Subdiagnostic)] +pub(crate) enum NameDefinedMultipleTimeLabel { + #[label(resolve_name_defined_multiple_time_reimported)] + Reimported { + #[primary_span] + span: Span, + name: Symbol, + }, + #[label(resolve_name_defined_multiple_time_redefined)] + Redefined { + #[primary_span] + span: Span, + name: Symbol, + }, +} + +#[derive(Subdiagnostic)] +pub(crate) enum NameDefinedMultipleTimeOldBindingLabel { + #[label(resolve_name_defined_multiple_time_old_binding_import)] + Import { + #[primary_span] + span: Span, + name: Symbol, + old_kind: &'static str, + }, + #[label(resolve_name_defined_multiple_time_old_binding_definition)] + Definition { + #[primary_span] + span: Span, + name: Symbol, + old_kind: &'static str, + }, +} + +#[derive(Diagnostic)] +#[diag(resolve_is_private, code = E0603)] +pub(crate) struct IsPrivate<'a> { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) ident_descr: &'a str, + pub(crate) ident: Ident, +} + +#[derive(Diagnostic)] +#[diag(resolve_generic_arguments_in_macro_path)] +pub(crate) struct GenericArgumentsInMacroPath { + #[primary_span] + pub(crate) span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_attributes_starting_with_rustc_are_reserved)] +pub(crate) struct AttributesStartingWithRustcAreReserved { + #[primary_span] + pub(crate) span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_cannot_use_through_an_import)] +pub(crate) struct CannotUseThroughAnImport { + #[primary_span] + pub(crate) span: Span, + pub(crate) article: &'static str, + pub(crate) descr: &'static str, + #[note] + pub(crate) binding_span: Option<Span>, +} + +#[derive(Diagnostic)] +#[diag(resolve_name_reserved_in_attribute_namespace)] +pub(crate) struct NameReservedInAttributeNamespace { + #[primary_span] + pub(crate) span: Span, + pub(crate) ident: Ident, +} + +#[derive(Diagnostic)] +#[diag(resolve_cannot_find_builtin_macro_with_name)] +pub(crate) struct CannotFindBuiltinMacroWithName { + #[primary_span] + pub(crate) span: Span, + pub(crate) ident: Ident, +} + +#[derive(Diagnostic)] +#[diag(resolve_tool_was_already_registered)] +pub(crate) struct ToolWasAlreadyRegistered { + #[primary_span] + pub(crate) span: Span, + pub(crate) tool: Ident, + #[label] + pub(crate) old_ident_span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_tool_only_accepts_identifiers)] +pub(crate) struct ToolOnlyAcceptsIdentifiers { + #[label] + #[primary_span] + pub(crate) span: Span, + pub(crate) tool: Symbol, +} + +#[derive(Subdiagnostic)] +pub(crate) enum DefinedHere { + #[label(resolve_similarly_named_defined_here)] + SimilarlyNamed { + #[primary_span] + span: Span, + candidate_descr: &'static str, + candidate: Symbol, + }, + #[label(resolve_single_item_defined_here)] + SingleItem { + #[primary_span] + span: Span, + candidate_descr: &'static str, + candidate: Symbol, + }, +} + +#[derive(Subdiagnostic)] +#[label(resolve_outer_ident_is_not_publicly_reexported)] +pub(crate) struct OuterIdentIsNotPubliclyReexported { + #[primary_span] + pub(crate) span: Span, + pub(crate) outer_ident_descr: &'static str, + pub(crate) outer_ident: Ident, +} + +#[derive(Subdiagnostic)] +#[label(resolve_constructor_private_if_any_field_private)] +pub(crate) struct ConstructorPrivateIfAnyFieldPrivate { + #[primary_span] + pub(crate) span: Span, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion( + resolve_consider_making_the_field_public, + applicability = "maybe-incorrect", + style = "verbose" +)] +pub(crate) struct ConsiderMakingTheFieldPublic { + #[suggestion_part(code = "pub ")] + pub(crate) spans: Vec<Span>, + pub(crate) number_of_fields: usize, +} + +#[derive(Subdiagnostic)] +pub(crate) enum ImportIdent { + #[suggestion( + resolve_suggestion_import_ident_through_reexport, + code = "{path}", + applicability = "machine-applicable", + style = "verbose" + )] + ThroughReExport { + #[primary_span] + span: Span, + ident: Ident, + path: String, + }, + #[suggestion( + resolve_suggestion_import_ident_directly, + code = "{path}", + applicability = "machine-applicable", + style = "verbose" + )] + Directly { + #[primary_span] + span: Span, + ident: Ident, + path: String, + }, +} + +#[derive(Subdiagnostic)] +#[note(resolve_note_and_refers_to_the_item_defined_here)] +pub(crate) struct NoteAndRefersToTheItemDefinedHere<'a> { + #[primary_span] + pub(crate) span: MultiSpan, + pub(crate) binding_descr: &'a str, + pub(crate) binding_name: Ident, + pub(crate) first: bool, + pub(crate) dots: bool, +} + +#[derive(Subdiagnostic)] +#[suggestion(resolve_remove_unnecessary_import, code = "", applicability = "maybe-incorrect")] +pub(crate) struct RemoveUnnecessaryImport { + #[primary_span] + pub(crate) span: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion( + resolve_remove_unnecessary_import, + code = "", + applicability = "maybe-incorrect", + style = "tool-only" +)] +pub(crate) struct ToolOnlyRemoveUnnecessaryImport { + #[primary_span] + pub(crate) span: Span, +} + +#[derive(Subdiagnostic)] +#[note(resolve_ident_imported_here_but_it_is_desc)] +pub(crate) struct IdentImporterHereButItIsDesc<'a> { + #[primary_span] + pub(crate) span: Span, + pub(crate) imported_ident: Ident, + pub(crate) imported_ident_desc: &'a str, +} + +#[derive(Subdiagnostic)] +#[note(resolve_ident_in_scope_but_it_is_desc)] +pub(crate) struct IdentInScopeButItIsDesc<'a> { + pub(crate) imported_ident: Ident, + pub(crate) imported_ident_desc: &'a str, +} + +#[derive(Subdiagnostic)] +#[note(resolve_found_an_item_configured_out)] +pub(crate) struct FoundItemConfigureOut { + #[primary_span] + pub(crate) span: Span, +} + +#[derive(Subdiagnostic)] +#[note(resolve_item_was_behind_feature)] +pub(crate) struct ItemWasBehindFeature { + pub(crate) feature: Symbol, +} + +#[derive(Diagnostic)] +#[diag(resolve_trait_impl_mismatch)] +pub(crate) struct TraitImplMismatch { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) name: Symbol, + pub(crate) kind: &'static str, + pub(crate) trait_path: String, + #[label(resolve_trait_impl_mismatch_label_item)] + pub(crate) trait_item_span: Span, +} diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ec11bfd96da..33c9c7fcc62 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -15,9 +15,7 @@ use rustc_ast::ptr::P; use rustc_ast::visit::{walk_list, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor}; use rustc_ast::*; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; -use rustc_errors::{ - codes::*, Applicability, DiagArgValue, IntoDiagArg, StashKey, -}; +use rustc_errors::{codes::*, Applicability, DiagArgValue, IntoDiagArg, StashKey}; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index bedf79400e3..2a23ed71753 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -123,20 +123,18 @@ pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools { match nested_meta.ident() { Some(ident) => { if let Some(old_ident) = registered_tools.replace(ident) { - let msg = format!("{} `{}` was already registered", "tool", ident); - tcx.dcx() - .struct_span_err(ident.span, msg) - .with_span_label(old_ident.span, "already registered here") - .emit(); + tcx.dcx().emit_err(errors::ToolWasAlreadyRegistered { + span: ident.span, + tool: ident, + old_ident_span: old_ident.span, + }); } } None => { - let msg = format!("`{}` only accepts identifiers", sym::register_tool); - let span = nested_meta.span(); - tcx.dcx() - .struct_span_err(span, msg) - .with_span_label(span, "not an identifier") - .emit(); + tcx.dcx().emit_err(errors::ToolOnlyAcceptsIdentifiers { + span: nested_meta.span(), + tool: sym::register_tool, + }); } } } @@ -485,13 +483,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Report errors for the resolved macro. for segment in &path.segments { if let Some(args) = &segment.args { - self.dcx().span_err(args.span(), "generic arguments in macro path"); + self.dcx().emit_err(errors::GenericArgumentsInMacroPath { span: args.span() }); } if kind == MacroKind::Attr && segment.ident.as_str().starts_with("rustc") { - self.dcx().span_err( - segment.ident.span, - "attributes starting with `rustc` are reserved for use by the `rustc` compiler", - ); + self.dcx().emit_err(errors::AttributesStartingWithRustcAreReserved { + span: segment.ident.span, + }); } } @@ -535,6 +532,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let mut err = MacroExpectedFound { span: path.span, expected, + article, found: res.descr(), macro_path: &path_str, remove_surrounding_derive: None, @@ -550,10 +548,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { err.add_as_non_derive = Some(AddAsNonDerive { macro_path: &path_str }); } - self.dcx() - .create_err(err) - .with_span_label(path.span, format!("not {article} {expected}")) - .emit(); + self.dcx().emit_err(err); return Ok((self.dummy_ext(kind), Res::Err)); } @@ -872,13 +867,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ) { if let Some(Res::NonMacroAttr(kind)) = res { if kind != NonMacroAttrKind::Tool && binding.map_or(true, |b| b.is_import()) { - let msg = - format!("cannot use {} {} through an import", kind.article(), kind.descr()); - let mut err = self.dcx().struct_span_err(span, msg); - if let Some(binding) = binding { - err.span_note(binding.span, format!("the {} imported here", kind.descr())); - } - err.emit(); + let binding_span = binding.map(|binding| binding.span); + self.dcx().emit_err(errors::CannotUseThroughAnImport { + span, + article: kind.article(), + descr: kind.descr(), + binding_span, + }); } } } @@ -889,10 +884,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if ident.name == sym::cfg || ident.name == sym::cfg_attr { let macro_kind = self.get_macro(res).map(|macro_data| macro_data.ext.macro_kind()); if macro_kind.is_some() && sub_namespace_match(macro_kind, Some(MacroKind::Attr)) { - self.dcx().span_err( - ident.span, - format!("name `{ident}` is reserved in attribute namespace"), - ); + self.dcx() + .emit_err(errors::NameReservedInAttributeNamespace { span: ident.span, ident }); } } } @@ -923,8 +916,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } } else { - let msg = format!("cannot find a built-in macro with name `{}`", item.ident); - self.dcx().span_err(item.span, msg); + self.dcx().emit_err(errors::CannotFindBuiltinMacroWithName { + span: item.span, + ident: item.ident, + }); } } |
