Skip to content

Commit

Permalink
vis note for no pub reexports glob import
Browse files Browse the repository at this point in the history
  • Loading branch information
bvanjoi committed Nov 5, 2023
1 parent da1e0d1 commit 1c316e1
Show file tree
Hide file tree
Showing 14 changed files with 99 additions and 30 deletions.
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ pub struct ResolverGlobalCtxt {
pub doc_link_resolutions: FxHashMap<LocalDefId, DocLinkResMap>,
pub doc_link_traits_in_scope: FxHashMap<LocalDefId, Vec<DefId>>,
pub all_macro_rules: FxHashMap<Symbol, Res<ast::NodeId>>,
pub insufficient_vis: Vec<(LocalDefId, Span, ty::Visibility)>,
}

/// Resolutions that should only be used for lowering.
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_passes/src/hir_id_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_privacy/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_privacy/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
16 changes: 14 additions & 2 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down Expand Up @@ -1810,6 +1810,7 @@ pub fn provide(providers: &mut Providers) {
effective_visibilities,
check_private_in_public,
check_mod_privacy,
report_insufficient_visibility,
..*providers
};
}
Expand Down Expand Up @@ -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) },
);
}
}
3 changes: 0 additions & 3 deletions compiler/rustc_resolve/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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;
}
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,8 @@ pub struct Resolver<'a, 'tcx> {
/// All non-determined imports.
indeterminate_imports: Vec<Import<'a>>,

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<Span>,
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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,
Expand Down
15 changes: 15 additions & 0 deletions tests/ui/imports/no-pub-reexports-but-used.rs
Original file line number Diff line number Diff line change
@@ -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;
}
15 changes: 15 additions & 0 deletions tests/ui/imports/no-pub-reexports-but-used.stderr
Original file line number Diff line number Diff line change
@@ -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

6 changes: 4 additions & 2 deletions tests/ui/imports/reexports.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
34 changes: 20 additions & 14 deletions tests/ui/privacy/issue-46209-private-enum-variant-reexport.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand All @@ -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

Expand Down
6 changes: 4 additions & 2 deletions tests/ui/privacy/private-variant-reexport.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand All @@ -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

Expand Down

0 comments on commit 1c316e1

Please sign in to comment.