diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 60b6d74da7b9f..f98918cba8800 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -44,13 +44,26 @@ resolve_binding_shadows_something_unacceptable = resolve_binding_shadows_something_unacceptable_suggestion = try specify the pattern arguments +resolve_cannot_be_reexported_crate_public = + `{$ident}` is only public within the crate, and cannot be re-exported outside + +resolve_cannot_be_reexported_private = + `{$ident}` is private, and cannot be re-exported + 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_determine_import_resolution = + cannot determine resolution for the import + .note = import resolution is stuck, try simplifying other imports + 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_self_type_here = can't use `Self` here @@ -60,6 +73,15 @@ resolve_change_import_binding = resolve_consider_adding_a_derive = consider adding a derive +resolve_consider_adding_macro_export = + consider adding a `#[macro_export]` to the macro in the imported module + +resolve_consider_declaring_with_pub = + consider declaring type or module `{$ident}` with `pub` + +resolve_consider_marking_as_pub = + consider marking `{$ident}` as `pub` in the imported module + resolve_const_not_member_of_trait = const `{$const_}` is not a member of trait `{$trait_}` .label = not a member of trait `{$trait_}` @@ -98,6 +120,9 @@ resolve_generic_params_from_outer_function = .label = use of generic parameter from outer function .suggestion = try using a local generic parameter instead +resolve_glob_import_doesnt_reexport = + glob import doesn't reexport anything because no candidate is public enough + resolve_help_try_using_local_generic_param = try using a local generic parameter instead @@ -122,6 +147,13 @@ resolve_invalid_asm_sym = .label = is a local variable .help = `sym` operands must refer to either a function or a static +resolve_is_not_directly_importable = + `{$target}` is not directly importable + .label = cannot be imported directly + +resolve_items_in_traits_are_not_importable = + items in traits are not importable + resolve_label_with_similar_name_reachable = a label with a similar name is reachable @@ -176,6 +208,12 @@ resolve_parent_module_reset_for_binding = resolve_proc_macro_same_crate = can't use a procedural macro from the same crate that defines it .help = you can define integration tests in a directory named `tests` +resolve_reexport_of_crate_public = + re-export of crate public `{$ident}` + +resolve_reexport_of_private = + re-export of private `{$ident}` + resolve_relative_2018 = relative paths are not supported in visibilities in 2018 edition or later .suggestion = try diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 93b626c779419..e4b89c65853d0 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -646,3 +646,84 @@ pub(crate) struct ConsiderAddingADerive { pub(crate) span: Span, pub(crate) suggestion: String, } + +#[derive(Diagnostic)] +#[diag(resolve_cannot_determine_import_resolution)] +pub(crate) struct CannotDetermineImportResolution { + #[primary_span] + pub(crate) span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_cannot_be_reexported_private, code = "E0364")] +pub(crate) struct CannotBeReexportedPrivate { + #[primary_span] + pub(crate) span: Span, + pub(crate) ident: Ident, +} + +#[derive(Diagnostic)] +#[diag(resolve_cannot_be_reexported_crate_public, code = "E0364")] +pub(crate) struct CannotBeReexportedCratePublic { + #[primary_span] + pub(crate) span: Span, + pub(crate) ident: Ident, +} + +#[derive(Diagnostic)] +#[diag(resolve_cannot_be_reexported_private, code = "E0365")] +#[note(resolve_consider_declaring_with_pub)] +pub(crate) struct CannotBeReexportedPrivateNS { + #[primary_span] + #[label(resolve_reexport_of_private)] + pub(crate) span: Span, + pub(crate) ident: Ident, +} + +#[derive(Diagnostic)] +#[diag(resolve_cannot_be_reexported_crate_public, code = "E0365")] +#[note(resolve_consider_declaring_with_pub)] +pub(crate) struct CannotBeReexportedCratePublicNS { + #[primary_span] + #[label(resolve_reexport_of_crate_public)] + pub(crate) span: Span, + pub(crate) ident: Ident, +} + +#[derive(Subdiagnostic)] +#[help(resolve_consider_adding_macro_export)] +pub(crate) struct ConsiderAddingMacroExport { + #[primary_span] + pub(crate) span: Span, +} + +#[derive(Subdiagnostic)] +#[note(resolve_consider_marking_as_pub)] +pub(crate) struct ConsiderMarkingAsPub { + #[primary_span] + pub(crate) span: Span, + pub(crate) ident: Ident, +} + +#[derive(Diagnostic)] +#[diag(resolve_cannot_glob_import_possible_crates)] +pub(crate) struct CannotGlobImportAllCrates { + #[primary_span] + pub(crate) span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_items_in_traits_are_not_importable)] +pub(crate) struct ItemsInTraitsAreNotImportable { + #[primary_span] + pub(crate) span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_is_not_directly_importable, code = "E0253")] +pub(crate) struct IsNotDirectlyImportable { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) target: Ident, +} diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index c458fc872aaef..35491ebe10cfd 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -1,8 +1,14 @@ //! A bunch of methods and structures more or less related to resolving imports. use crate::diagnostics::{import_candidates, DiagnosticMode, Suggestion}; +use crate::errors::{ + CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate, + CannotBeReexportedPrivateNS, CannotDetermineImportResolution, CannotGlobImportAllCrates, + ConsiderAddingMacroExport, ConsiderMarkingAsPub, IsNotDirectlyImportable, + ItemsInTraitsAreNotImportable, +}; use crate::Determinacy::{self, *}; -use crate::Namespace::*; +use crate::{fluent_generated as fluent, Namespace::*}; use crate::{module_to_string, names_to_string, ImportSuggestion}; use crate::{ AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingKey, ModuleKind, ResolutionError, @@ -774,9 +780,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } source_binding @ (Ok(..) | Err(Determined)) => { if source_binding.is_ok() { - let msg = format!("`{}` is not directly importable", target); - struct_span_err!(this.tcx.sess, import.span, E0253, "{}", &msg) - .span_label(import.span, "cannot be imported directly") + this.tcx + .sess + .create_err(IsNotDirectlyImportable { span: import.span, target }) .emit(); } let key = BindingKey::new(target, ns); @@ -825,9 +831,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { span_bug!(import.span, "inconsistent resolution for an import"); } } else if self.privacy_errors.is_empty() { - let msg = "cannot determine resolution for the import"; - let msg_note = "import resolution is stuck, try simplifying other imports"; - self.tcx.sess.struct_span_err(import.span, msg).note(msg_note).emit(); + self.tcx + .sess + .create_err(CannotDetermineImportResolution { span: import.span }) + .emit(); } module @@ -938,8 +945,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { && let Some(max_vis) = max_vis.get() && !max_vis.is_at_least(import.expect_vis(), self.tcx) { - let msg = "glob import doesn't reexport anything because no candidate is public enough"; - self.lint_buffer.buffer_lint(UNUSED_IMPORTS, id, import.span, msg); + self.lint_buffer.buffer_lint(UNUSED_IMPORTS, id, import.span, fluent::resolve_glob_import_doesnt_reexport); } return None; } @@ -1011,10 +1017,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { && this.ambiguity_errors.is_empty() && this.privacy_errors.is_empty() { - let msg = "cannot determine resolution for the import"; - let msg_note = - "import resolution is stuck, try simplifying other imports"; - this.tcx.sess.struct_span_err(import.span, msg).note(msg_note).emit(); + this.tcx + .sess + .create_err(CannotDetermineImportResolution { span: import.span }) + .emit(); } } Err(..) => { @@ -1172,46 +1178,43 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { msg, ); } else { - let error_msg = if crate_private_reexport { - format!( - "`{}` is only public within the crate, and cannot be re-exported outside", - ident - ) - } else { - format!("`{}` is private, and cannot be re-exported", ident) - }; - if ns == TypeNS { - let label_msg = if crate_private_reexport { - format!("re-export of crate public `{}`", ident) + let mut err = if crate_private_reexport { + self.tcx.sess.create_err(CannotBeReexportedCratePublicNS { + span: import.span, + ident, + }) } else { - format!("re-export of private `{}`", ident) + self.tcx + .sess + .create_err(CannotBeReexportedPrivateNS { span: import.span, ident }) }; - - struct_span_err!(self.tcx.sess, import.span, E0365, "{}", error_msg) - .span_label(import.span, label_msg) - .note(format!("consider declaring type or module `{}` with `pub`", ident)) - .emit(); + err.emit(); } else { - let mut err = - struct_span_err!(self.tcx.sess, import.span, E0364, "{error_msg}"); + let mut err = if crate_private_reexport { + self.tcx + .sess + .create_err(CannotBeReexportedCratePublic { span: import.span, ident }) + } else { + self.tcx + .sess + .create_err(CannotBeReexportedPrivate { span: import.span, ident }) + }; + match binding.kind { NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id)) // exclude decl_macro if self.get_macro_by_def_id(def_id).macro_rules => { - err.span_help( - binding.span, - "consider adding a `#[macro_export]` to the macro in the imported module", - ); + err.subdiagnostic(ConsiderAddingMacroExport { + span: binding.span, + }); } _ => { - err.span_note( - import.span, - format!( - "consider marking `{ident}` as `pub` in the imported module" - ), - ); + err.subdiagnostic(ConsiderMarkingAsPub { + span: import.span, + ident, + }); } } err.emit(); @@ -1317,12 +1320,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() }; let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else { - self.tcx.sess.span_err(import.span, "cannot glob-import all possible crates"); + self.tcx.sess.create_err(CannotGlobImportAllCrates { + span: import.span, + }).emit(); return; }; if module.is_trait() { - self.tcx.sess.span_err(import.span, "items in traits are not importable"); + self.tcx.sess.create_err(ItemsInTraitsAreNotImportable { span: import.span }).emit(); return; } else if ptr::eq(module, import.parent_scope.module) { return;