about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_resolve/messages.ftl38
-rw-r--r--compiler/rustc_resolve/src/errors.rs81
-rw-r--r--compiler/rustc_resolve/src/imports.rs93
3 files changed, 168 insertions, 44 deletions
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index 60b6d74da7b..f98918cba88 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 93b626c7794..e4b89c65853 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 c458fc872aa..35491ebe10c 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;