Skip to content

Commit 148195a

Browse files
committed
Implement resolver warnings about reexporting private dependencies
1 parent 915e535 commit 148195a

File tree

4 files changed

+90
-8
lines changed

4 files changed

+90
-8
lines changed

compiler/rustc_resolve/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ resolve_forward_declared_generic_param =
160160
resolve_found_an_item_configured_out =
161161
found an item that was configured out
162162
163+
resolve_from_private_dep_in_public_reexport =
164+
{$kind} `{$descr}` from private dependency '{$krate}' is reexported
163165
resolve_generic_arguments_in_macro_path =
164166
generic arguments in macro path
165167

compiler/rustc_resolve/src/imports.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_errors::codes::*;
1010
use rustc_errors::{Applicability, MultiSpan, pluralize, struct_span_code_err};
1111
use rustc_hir::def::{self, DefKind, PartialRes};
1212
use rustc_hir::def_id::DefId;
13+
use rustc_macros::Diagnostic;
1314
use rustc_middle::metadata::{ModChild, Reexport};
1415
use rustc_middle::{span_bug, ty};
1516
use rustc_session::lint::BuiltinLintDiag;
@@ -40,6 +41,14 @@ use crate::{
4041

4142
type Res = def::Res<NodeId>;
4243

44+
#[derive(Diagnostic)]
45+
#[diag(resolve_from_private_dep_in_public_reexport)]
46+
struct FromPrivateDependencyInPublicInterface<'a> {
47+
pub kind: &'a str,
48+
pub descr: &'a str,
49+
pub krate: Symbol,
50+
}
51+
4352
/// Contains data for specific kinds of imports.
4453
#[derive(Clone)]
4554
pub(crate) enum ImportKind<'ra> {
@@ -546,6 +555,41 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
546555
self.finalize_resolutions_in(*module);
547556
}
548557

558+
for (_module_def_id, module_children) in
559+
self.tcx.with_stable_hashing_context(|hcx| self.module_children.to_sorted(&hcx, false))
560+
{
561+
for import in module_children {
562+
if !import.vis.is_public() {
563+
continue;
564+
}
565+
566+
let def::Res::<_>::Def(reexported_kind, reexported_def_id) = import.res else {
567+
continue;
568+
};
569+
570+
if let DefKind::Ctor(..) = reexported_kind {
571+
continue;
572+
}
573+
574+
if reexported_def_id.is_local() {
575+
continue;
576+
}
577+
578+
if !self.tcx.is_private_dep(reexported_def_id.krate) {
579+
continue;
580+
}
581+
582+
self.dcx()
583+
.create_warn(FromPrivateDependencyInPublicInterface {
584+
kind: import.res.descr(),
585+
descr: import.ident.as_str(),
586+
krate: self.tcx.crate_name(reexported_def_id.krate),
587+
})
588+
.with_span(import.ident.span)
589+
.emit();
590+
}
591+
}
592+
549593
let mut seen_spans = FxHashSet::default();
550594
let mut errors = vec![];
551595
let mut prev_root_id: NodeId = NodeId::ZERO;

tests/ui/privacy/pub-priv-dep/pub-priv1.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
#![deny(exported_private_dependencies)]
1010

1111
// This crate is a private dependency
12-
// FIXME: This should trigger.
1312
pub extern crate priv_dep;
13+
//~^ WARN crate `priv_dep` from private dependency 'priv_dep' is reexported
1414
// This crate is a public dependency
15-
extern crate pub_dep;
15+
pub extern crate pub_dep;
1616
// This crate is a private dependency
1717
extern crate pm;
1818

@@ -91,16 +91,16 @@ pub struct AllowedPrivType {
9191
pub allowed: OtherType,
9292
}
9393

94-
// FIXME: This should trigger.
9594
pub use priv_dep::m;
96-
// FIXME: This should trigger.
95+
//~^ WARN macro `m` from private dependency 'priv_dep' is reexported
9796
pub use pm::fn_like;
98-
// FIXME: This should trigger.
97+
//~^ WARN macro `fn_like` from private dependency 'pm' is reexported
9998
pub use pm::PmDerive;
100-
// FIXME: This should trigger.
99+
//~^ WARN macro `PmDerive` from private dependency 'pm' is reexported
101100
pub use pm::pm_attr;
101+
//~^ WARN macro `pm_attr` from private dependency 'pm' is reexported
102102

103-
// FIXME: This should trigger.
104103
pub use priv_dep::E::V1;
104+
//~^ WARN variant `V1` from private dependency 'priv_dep' is reexported
105105

106106
fn main() {}

tests/ui/privacy/pub-priv-dep/pub-priv1.stderr

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,39 @@
1+
warning: crate `priv_dep` from private dependency 'priv_dep' is reexported
2+
--> $DIR/pub-priv1.rs:12:18
3+
|
4+
LL | pub extern crate priv_dep;
5+
| ^^^^^^^^
6+
7+
warning: macro `m` from private dependency 'priv_dep' is reexported
8+
--> $DIR/pub-priv1.rs:94:19
9+
|
10+
LL | pub use priv_dep::m;
11+
| ^
12+
13+
warning: macro `fn_like` from private dependency 'pm' is reexported
14+
--> $DIR/pub-priv1.rs:96:13
15+
|
16+
LL | pub use pm::fn_like;
17+
| ^^^^^^^
18+
19+
warning: derive macro `PmDerive` from private dependency 'pm' is reexported
20+
--> $DIR/pub-priv1.rs:98:13
21+
|
22+
LL | pub use pm::PmDerive;
23+
| ^^^^^^^^
24+
25+
warning: attribute macro `pm_attr` from private dependency 'pm' is reexported
26+
--> $DIR/pub-priv1.rs:100:13
27+
|
28+
LL | pub use pm::pm_attr;
29+
| ^^^^^^^
30+
31+
warning: variant `V1` from private dependency 'priv_dep' is reexported
32+
--> $DIR/pub-priv1.rs:103:22
33+
|
34+
LL | pub use priv_dep::E::V1;
35+
| ^^
36+
137
error: type `OtherType` from private dependency 'priv_dep' in public interface
238
--> $DIR/pub-priv1.rs:29:5
339
|
@@ -90,5 +126,5 @@ LL | impl PubTraitOnPrivate for OtherType {}
90126
|
91127
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
92128

93-
error: aborting due to 14 previous errors
129+
error: aborting due to 14 previous errors; 6 warnings emitted
94130

0 commit comments

Comments
 (0)