From 1c316e1ae4e6e7f96bf2d105836c963f39d4f1f9 Mon Sep 17 00:00:00 2001 From: bohan Date: Sun, 5 Nov 2023 16:38:40 +0800 Subject: [PATCH] vis note for no pub reexports glob import --- compiler/rustc_middle/src/query/mod.rs | 5 +++ compiler/rustc_middle/src/ty/mod.rs | 1 + compiler/rustc_passes/src/hir_id_validator.rs | 2 ++ compiler/rustc_privacy/messages.ftl | 4 +++ compiler/rustc_privacy/src/errors.rs | 7 ++++ compiler/rustc_privacy/src/lib.rs | 16 +++++++-- compiler/rustc_resolve/messages.ftl | 3 -- compiler/rustc_resolve/src/imports.rs | 10 ++---- compiler/rustc_resolve/src/lib.rs | 5 +++ tests/ui/imports/no-pub-reexports-but-used.rs | 15 ++++++++ .../imports/no-pub-reexports-but-used.stderr | 15 ++++++++ tests/ui/imports/reexports.stderr | 6 ++-- ...46209-private-enum-variant-reexport.stderr | 34 +++++++++++-------- .../privacy/private-variant-reexport.stderr | 6 ++-- 14 files changed, 99 insertions(+), 30 deletions(-) create mode 100644 tests/ui/imports/no-pub-reexports-but-used.rs create mode 100644 tests/ui/imports/no-pub-reexports-but-used.stderr diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f9ec368361c5..8545ac599537 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1118,6 +1118,11 @@ rustc_queries! { eval_always desc { "checking effective visibilities" } } + + query report_insufficient_visibility(_: ()) -> () { + desc { "report these items with insufficient visibility." } + } + query check_private_in_public(_: ()) -> () { eval_always desc { "checking for private elements in public interfaces" } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f6ef1783aa41..910ebb25ab65 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -179,6 +179,7 @@ pub struct ResolverGlobalCtxt { pub doc_link_resolutions: FxHashMap, pub doc_link_traits_in_scope: FxHashMap>, pub all_macro_rules: FxHashMap>, + pub insufficient_vis: Vec<(LocalDefId, Span, ty::Visibility)>, } /// Resolutions that should only be used for lowering. diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index f825363ae39a..295fb30fe95a 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -12,6 +12,8 @@ pub fn check_crate(tcx: TyCtxt<'_>) { crate::hir_stats::print_hir_stats(tcx); } + tcx.ensure().report_insufficient_visibility(()); + #[cfg(debug_assertions)] { let errors = Lock::new(Vec::new()); diff --git a/compiler/rustc_privacy/messages.ftl b/compiler/rustc_privacy/messages.ftl index 7785f1a7f81f..f603d4b0e612 100644 --- a/compiler/rustc_privacy/messages.ftl +++ b/compiler/rustc_privacy/messages.ftl @@ -5,6 +5,10 @@ privacy_field_is_private_label = private field privacy_from_private_dep_in_public_interface = {$kind} `{$descr}` from private dependency '{$krate}' in public interface +privacy_glob_import_doesnt_reexport = + glob import doesn't reexport anything because no candidate is public enough + .note = the most public imported item is `{$max_vis}` + privacy_in_public_interface = {$vis_descr} {$kind} `{$descr}` in public interface .label = can't leak {$vis_descr} {$kind} .visibility_label = `{$descr}` declared as {$vis_descr} diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index b1242f82f4fe..bfdc16dc5d59 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -104,3 +104,10 @@ pub struct PrivateInterfacesOrBoundsLint<'a> { pub ty_descr: DiagnosticArgFromDisplay<'a>, pub ty_vis_descr: &'a str, } + +#[derive(LintDiagnostic)] +#[diag(privacy_glob_import_doesnt_reexport)] +#[note] +pub struct InsufficientVisibility { + pub max_vis: String, +} diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 4bb7e65747f7..05668dfe2a6d 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -45,8 +45,8 @@ use std::{fmt, mem}; use errors::{ FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface, - ItemIsPrivate, PrivateInterfacesOrBoundsLint, ReportEffectiveVisibility, UnnameableTypesLint, - UnnamedItemIsPrivate, + InsufficientVisibility, ItemIsPrivate, PrivateInterfacesOrBoundsLint, + ReportEffectiveVisibility, UnnameableTypesLint, UnnamedItemIsPrivate, }; fluent_messages! { "../messages.ftl" } @@ -1810,6 +1810,7 @@ pub fn provide(providers: &mut Providers) { effective_visibilities, check_private_in_public, check_mod_privacy, + report_insufficient_visibility, ..*providers }; } @@ -1936,3 +1937,14 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) { checker.check_item(id); } } + +fn report_insufficient_visibility(tcx: TyCtxt<'_>, (): ()) { + for (def_id, span, vis) in &tcx.resolutions(()).insufficient_vis { + tcx.emit_spanned_lint( + lint::builtin::UNUSED_IMPORTS, + tcx.hir().local_def_id_to_hir_id(*def_id), + *span, + InsufficientVisibility { max_vis: vis_to_string(*def_id, *vis, tcx) }, + ); + } +} diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 272483d4a987..3662edcc1c05 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -127,9 +127,6 @@ resolve_generic_params_from_outer_item_self_ty_param = can't use `Self` here resolve_generic_params_from_outer_item_ty_param = type parameter from outer item -resolve_glob_import_doesnt_reexport = - glob import doesn't reexport anything because no candidate is public enough - resolve_ident_bound_more_than_once_in_parameter_list = identifier `{$identifier}` is bound more than once in this parameter list .label = used as parameter more than once diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index b34790a925ea..b5c3c37f3c0d 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -8,7 +8,7 @@ use crate::errors::{ ItemsInTraitsAreNotImportable, }; use crate::Determinacy::{self, *}; -use crate::{fluent_generated as fluent, Namespace::*}; +use crate::Namespace::*; use crate::{module_to_string, names_to_string, ImportSuggestion}; use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment}; use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet}; @@ -989,12 +989,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { && let Some(max_vis) = max_vis.get() && !max_vis.is_at_least(import.expect_vis(), self.tcx) { - self.lint_buffer.buffer_lint( - UNUSED_IMPORTS, - id, - import.span, - fluent::resolve_glob_import_doesnt_reexport, - ); + let def_id = self.local_def_id(id); + self.insufficient_vis.push((def_id, import.span, max_vis)); } return None; } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 501747df5c90..191f4b942aa6 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -958,6 +958,8 @@ pub struct Resolver<'a, 'tcx> { /// All non-determined imports. indeterminate_imports: Vec>, + insufficient_vis: Vec<(LocalDefId, Span, ty::Visibility)>, + // Spans for local variables found during pattern resolution. // Used for suggestions during error reporting. pat_span_map: NodeMap, @@ -1340,6 +1342,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { determined_imports: Vec::new(), indeterminate_imports: Vec::new(), + insufficient_vis: Vec::new(), + pat_span_map: Default::default(), partial_res_map: Default::default(), import_res_map: Default::default(), @@ -1525,6 +1529,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { doc_link_resolutions: self.doc_link_resolutions, doc_link_traits_in_scope: self.doc_link_traits_in_scope, all_macro_rules: self.all_macro_rules, + insufficient_vis: self.insufficient_vis, }; let ast_lowering = ty::ResolverAstLowering { legacy_const_generic_args: self.legacy_const_generic_args, diff --git a/tests/ui/imports/no-pub-reexports-but-used.rs b/tests/ui/imports/no-pub-reexports-but-used.rs new file mode 100644 index 000000000000..8d78032e5e8b --- /dev/null +++ b/tests/ui/imports/no-pub-reexports-but-used.rs @@ -0,0 +1,15 @@ +// check-pass +// https://github.com/rust-lang/rust/issues/115966 + +mod m { + pub(crate) type A = u8; +} + +#[warn(unused_imports)] //~ NOTE: the lint level is defined here +pub use m::*; +//~^ WARNING: glob import doesn't reexport anything because no candidate is public enough +//~| NOTE: the most public imported item is `pub(crate)` + +fn main() { + let _: A; +} diff --git a/tests/ui/imports/no-pub-reexports-but-used.stderr b/tests/ui/imports/no-pub-reexports-but-used.stderr new file mode 100644 index 000000000000..bfac0b1e7896 --- /dev/null +++ b/tests/ui/imports/no-pub-reexports-but-used.stderr @@ -0,0 +1,15 @@ +warning: glob import doesn't reexport anything because no candidate is public enough + --> $DIR/no-pub-reexports-but-used.rs:9:9 + | +LL | pub use m::*; + | ^ + | + = note: the most public imported item is `pub(crate)` +note: the lint level is defined here + --> $DIR/no-pub-reexports-but-used.rs:8:8 + | +LL | #[warn(unused_imports)] + | ^^^^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/tests/ui/imports/reexports.stderr b/tests/ui/imports/reexports.stderr index 401e422af0f8..37a45ebf7aba 100644 --- a/tests/ui/imports/reexports.stderr +++ b/tests/ui/imports/reexports.stderr @@ -56,17 +56,19 @@ note: the lint level is defined here LL | #![warn(unused_imports)] | ^^^^^^^^^^^^^^ -warning: glob import doesn't reexport anything because no candidate is public enough +warning: unused import: `super::*` --> $DIR/reexports.rs:11:17 | LL | pub use super::*; | ^^^^^^^^ -warning: unused import: `super::*` +warning: glob import doesn't reexport anything because no candidate is public enough --> $DIR/reexports.rs:11:17 | LL | pub use super::*; | ^^^^^^^^ + | + = note: the most public imported item is `pub(a)` error: aborting due to 3 previous errors; 3 warnings emitted diff --git a/tests/ui/privacy/issue-46209-private-enum-variant-reexport.stderr b/tests/ui/privacy/issue-46209-private-enum-variant-reexport.stderr index df5968ba323b..6b1fb0d2d701 100644 --- a/tests/ui/privacy/issue-46209-private-enum-variant-reexport.stderr +++ b/tests/ui/privacy/issue-46209-private-enum-variant-reexport.stderr @@ -22,7 +22,7 @@ note: consider marking `Full` as `pub` in the imported module LL | pub use self::Lieutenant::{JuniorGrade, Full}; | ^^^^ -error: glob import doesn't reexport anything because no candidate is public enough +error: unused import: `self::Professor::*` --> $DIR/issue-46209-private-enum-variant-reexport.rs:3:13 | LL | pub use self::Professor::*; @@ -34,41 +34,47 @@ note: the lint level is defined here LL | #[deny(unused_imports)] | ^^^^^^^^^^^^^^ -error: unused import: `self::Professor::*` - --> $DIR/issue-46209-private-enum-variant-reexport.rs:3:13 - | -LL | pub use self::Professor::*; - | ^^^^^^^^^^^^^^^^^^ - error: unused imports: `Full`, `JuniorGrade` --> $DIR/issue-46209-private-enum-variant-reexport.rs:6:32 | LL | pub use self::Lieutenant::{JuniorGrade, Full}; | ^^^^^^^^^^^ ^^^^ -error: glob import doesn't reexport anything because no candidate is public enough +error: unused import: `self::PettyOfficer::*` --> $DIR/issue-46209-private-enum-variant-reexport.rs:10:13 | LL | pub use self::PettyOfficer::*; | ^^^^^^^^^^^^^^^^^^^^^ -error: unused import: `self::PettyOfficer::*` +error: unused import: `self::Crewman::*` + --> $DIR/issue-46209-private-enum-variant-reexport.rs:13:13 + | +LL | pub use self::Crewman::*; + | ^^^^^^^^^^^^^^^^ + +error: glob import doesn't reexport anything because no candidate is public enough + --> $DIR/issue-46209-private-enum-variant-reexport.rs:3:13 + | +LL | pub use self::Professor::*; + | ^^^^^^^^^^^^^^^^^^ + | + = note: the most public imported item is `pub(self)` + +error: glob import doesn't reexport anything because no candidate is public enough --> $DIR/issue-46209-private-enum-variant-reexport.rs:10:13 | LL | pub use self::PettyOfficer::*; | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: the most public imported item is `pub(self)` error: glob import doesn't reexport anything because no candidate is public enough --> $DIR/issue-46209-private-enum-variant-reexport.rs:13:13 | LL | pub use self::Crewman::*; | ^^^^^^^^^^^^^^^^ - -error: unused import: `self::Crewman::*` - --> $DIR/issue-46209-private-enum-variant-reexport.rs:13:13 | -LL | pub use self::Crewman::*; - | ^^^^^^^^^^^^^^^^ + = note: the most public imported item is `pub(crate)` error: aborting due to 9 previous errors diff --git a/tests/ui/privacy/private-variant-reexport.stderr b/tests/ui/privacy/private-variant-reexport.stderr index 2f041934a817..407638f4376c 100644 --- a/tests/ui/privacy/private-variant-reexport.stderr +++ b/tests/ui/privacy/private-variant-reexport.stderr @@ -30,7 +30,7 @@ LL | pub use ::E::V::{self}; | = note: consider declaring type or module `V` with `pub` -error: glob import doesn't reexport anything because no candidate is public enough +error: unused import: `::E::*` --> $DIR/private-variant-reexport.rs:15:13 | LL | pub use ::E::*; @@ -42,11 +42,13 @@ note: the lint level is defined here LL | #[deny(unused_imports)] | ^^^^^^^^^^^^^^ -error: unused import: `::E::*` +error: glob import doesn't reexport anything because no candidate is public enough --> $DIR/private-variant-reexport.rs:15:13 | LL | pub use ::E::*; | ^^^^^^ + | + = note: the most public imported item is `pub(crate)` error: aborting due to 5 previous errors