diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 360c14afa8ba..c7bad48c24f9 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -9,7 +9,9 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_errors::codes::*; -use rustc_errors::{Applicability, Diagnostic, MultiSpan, pluralize, struct_span_code_err}; +use rustc_errors::{ + Applicability, BufferedEarlyLint, Diagnostic, MultiSpan, pluralize, struct_span_code_err, +}; use rustc_hir::Attribute; use rustc_hir::attrs::AttributeKind; use rustc_hir::attrs::diagnostic::{CustomDiagnostic, Directive, FormatArgs}; @@ -19,6 +21,7 @@ use rustc_middle::span_bug; use rustc_middle::ty::{TyCtxt, Visibility}; use rustc_session::errors::feature_err; +use rustc_session::lint::LintId; use rustc_session::lint::builtin::{ AMBIGUOUS_GLOB_REEXPORTS, EXPORTED_PRIVATE_DEPENDENCIES, HIDDEN_GLOB_REEXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE, REDUNDANT_IMPORTS, UNUSED_IMPORTS, @@ -1515,7 +1518,6 @@ fn finalize_import(&mut self, import: Import<'ra>) -> Option) -> Option) -> Option - { - err.subdiagnostic( ConsiderAddingMacroExport { - span: binding.span, - }); - err.subdiagnostic( ConsiderMarkingAsPubCrate { - vis_span: import.vis_span, - }); - } - _ => { - err.subdiagnostic( ConsiderMarkingAsPub { - span: import.span, - ident, - }); - } - } - err.emit(); + if let Some(lint) = self.report_cannot_reexport(import, binding, ident, ns) { + self.lint_buffer.add_early_lint(lint); } } @@ -1613,6 +1563,61 @@ fn finalize_import(&mut self, import: Import<'ra>) -> Option, + decl: Decl<'ra>, + ident: Ident, + ns: Namespace, + ) -> Option { + let crate_private_reexport = match decl.vis() { + Visibility::Restricted(def_id) if def_id.is_top_level_module() => true, + _ => false, + }; + + if let Some(extern_crate_id) = pub_use_of_private_extern_crate_hack(import.summary(), decl) + { + let ImportKind::Single { id, .. } = import.kind else { unreachable!() }; + let sugg = self.tcx.source_span(self.local_def_id(extern_crate_id)).shrink_to_lo(); + let diagnostic = crate::errors::PrivateExternCrateReexport { ident, sugg }; + return Some(BufferedEarlyLint { + lint_id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE), + node_id: id, + span: Some(import.span.into()), + diagnostic: diagnostic.into(), + }); + } else if ns == TypeNS { + let err = if crate_private_reexport { + self.dcx().create_err(CannotBeReexportedCratePublicNS { span: import.span, ident }) + } else { + self.dcx().create_err(CannotBeReexportedPrivateNS { span: import.span, ident }) + }; + err.emit(); + } else { + let mut err = if crate_private_reexport { + self.dcx().create_err(CannotBeReexportedCratePublic { span: import.span, ident }) + } else { + self.dcx().create_err(CannotBeReexportedPrivate { span: import.span, ident }) + }; + + match decl.kind { + // exclude decl_macro + DeclKind::Def(Res::Def(DefKind::Macro(_), def_id)) + if self.get_macro_by_def_id(def_id).macro_rules => + { + err.subdiagnostic(ConsiderAddingMacroExport { span: decl.span }); + err.subdiagnostic(ConsiderMarkingAsPubCrate { vis_span: import.vis_span }); + } + _ => { + err.subdiagnostic(ConsiderMarkingAsPub { span: import.span, ident }); + } + } + err.emit(); + } + + None + } + pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'ra>) -> bool { // This function is only called for single imports. let ImportKind::Single { source, target, ref decls, id, .. } = import.kind else {