Skip to content

Commit 81f3ae8

Browse files
authored
Rollup merge of #90628 - ken-matsui:clarify-error-messages-caused-by-reexporting-pub-crate-visibility-to-outside, r=oli-obk
Clarify error messages caused by re-exporting `pub(crate)` visibility to outside This PR clarifies error messages and suggestions caused by re-exporting pub(crate) visibility outside the crate. Here is a small example ([Rust Playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=e2cd0bd4422d4f20e6522dcbad167d3b)): ```rust mod m { pub(crate) enum E {} } pub use m::E; fn main() {} ``` This code is compiled to: ``` error[E0365]: `E` is private, and cannot be re-exported --> prog.rs:4:9 | 4 | pub use m::E; | ^^^^ re-export of private `E` | = note: consider declaring type or module `E` with `pub` error: aborting due to previous error For more information about this error, try `rustc --explain E0365`. ``` However, enum `E` is actually public to the crate, not private totally—nevertheless, rustc treats `pub(crate)` and private visibility as the same on the error messages. They are not clear and should be segmented distinctly. By applying changes in this PR, the error message below will be the following message that would be clearer: ``` error[E0365]: `E` is only public to inside of the crate, and cannot be re-exported outside --> prog.rs:4:9 | 4 | pub use m::E; | ^^^^ re-export of crate public `E` | = note: consider declaring type or module `E` with `pub` error: aborting due to previous error For more information about this error, try `rustc --explain E0365`. ```
2 parents 7354bb3 + 33ab512 commit 81f3ae8

File tree

11 files changed

+334
-32
lines changed

11 files changed

+334
-32
lines changed

compiler/rustc_resolve/src/imports.rs

+33-17
Original file line numberDiff line numberDiff line change
@@ -1180,11 +1180,17 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
11801180

11811181
let mut reexport_error = None;
11821182
let mut any_successful_reexport = false;
1183+
let mut crate_private_reexport = false;
11831184
self.r.per_ns(|this, ns| {
11841185
if let Ok(binding) = source_bindings[ns].get() {
11851186
let vis = import.vis.get();
11861187
if !binding.vis.is_at_least(vis, &*this) {
11871188
reexport_error = Some((ns, binding));
1189+
if let ty::Visibility::Restricted(binding_def_id) = binding.vis {
1190+
if binding_def_id.is_top_level_module() {
1191+
crate_private_reexport = true;
1192+
}
1193+
}
11881194
} else {
11891195
any_successful_reexport = true;
11901196
}
@@ -1207,24 +1213,34 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
12071213
import.span,
12081214
&msg,
12091215
);
1210-
} else if ns == TypeNS {
1211-
struct_span_err!(
1212-
self.r.session,
1213-
import.span,
1214-
E0365,
1215-
"`{}` is private, and cannot be re-exported",
1216-
ident
1217-
)
1218-
.span_label(import.span, format!("re-export of private `{}`", ident))
1219-
.note(&format!("consider declaring type or module `{}` with `pub`", ident))
1220-
.emit();
12211216
} else {
1222-
let msg = format!("`{}` is private, and cannot be re-exported", ident);
1223-
let note_msg =
1224-
format!("consider marking `{}` as `pub` in the imported module", ident,);
1225-
struct_span_err!(self.r.session, import.span, E0364, "{}", &msg)
1226-
.span_note(import.span, &note_msg)
1227-
.emit();
1217+
let error_msg = if crate_private_reexport {
1218+
format!(
1219+
"`{}` is only public within the crate, and cannot be re-exported outside",
1220+
ident
1221+
)
1222+
} else {
1223+
format!("`{}` is private, and cannot be re-exported", ident)
1224+
};
1225+
1226+
if ns == TypeNS {
1227+
let label_msg = if crate_private_reexport {
1228+
format!("re-export of crate public `{}`", ident)
1229+
} else {
1230+
format!("re-export of private `{}`", ident)
1231+
};
1232+
1233+
struct_span_err!(self.r.session, import.span, E0365, "{}", error_msg)
1234+
.span_label(import.span, label_msg)
1235+
.note(&format!("consider declaring type or module `{}` with `pub`", ident))
1236+
.emit();
1237+
} else {
1238+
let note_msg =
1239+
format!("consider marking `{}` as `pub` in the imported module", ident);
1240+
struct_span_err!(self.r.session, import.span, E0364, "{}", error_msg)
1241+
.span_note(import.span, &note_msg)
1242+
.emit();
1243+
}
12281244
}
12291245
}
12301246

src/test/ui/error-codes/E0365.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ mod foo {
33
}
44

55
pub use foo as foo2;
6-
//~^ ERROR `foo` is private, and cannot be re-exported [E0365]
6+
//~^ ERROR `foo` is only public within the crate, and cannot be re-exported outside [E0365]
77

88
fn main() {}

src/test/ui/error-codes/E0365.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0365]: `foo` is private, and cannot be re-exported
1+
error[E0365]: `foo` is only public within the crate, and cannot be re-exported outside
22
--> $DIR/E0365.rs:5:9
33
|
44
LL | pub use foo as foo2;
5-
| ^^^^^^^^^^^ re-export of private `foo`
5+
| ^^^^^^^^^^^ re-export of crate public `foo`
66
|
77
= note: consider declaring type or module `foo` with `pub`
88

src/test/ui/modules/issue-56411.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ macro_rules! import {
55
mod $name;
66
pub use self::$name;
77
//~^ ERROR the name `issue_56411_aux` is defined multiple times
8-
//~| ERROR `issue_56411_aux` is private, and cannot be re-exported
8+
//~| ERROR `issue_56411_aux` is only public within the crate, and cannot be re-exported outside
99

1010
)*
1111
}

src/test/ui/modules/issue-56411.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ LL | import!(("issue-56411-aux.rs", issue_56411_aux));
1515
= note: `issue_56411_aux` must be defined only once in the type namespace of this module
1616
= note: this error originates in the macro `import` (in Nightly builds, run with -Z macro-backtrace for more info)
1717

18-
error[E0365]: `issue_56411_aux` is private, and cannot be re-exported
18+
error[E0365]: `issue_56411_aux` is only public within the crate, and cannot be re-exported outside
1919
--> $DIR/issue-56411.rs:6:21
2020
|
2121
LL | pub use self::$name;
22-
| ^^^^^^^^^^^ re-export of private `issue_56411_aux`
22+
| ^^^^^^^^^^^ re-export of crate public `issue_56411_aux`
2323
...
2424
LL | import!(("issue-56411-aux.rs", issue_56411_aux));
2525
| ------------------------------------------------ in this macro invocation
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
fn f1() {}
2+
enum E1 { V }
3+
struct S1 {
4+
#[rustfmt::skip]
5+
bar: i32,
6+
}
7+
mod m1 {
8+
pub use ::f1; //~ ERROR `f1` is only public within the crate, and cannot be re-exported outside
9+
pub use ::S1; //~ ERROR `S1` is only public within the crate, and cannot be re-exported outside
10+
pub use ::E1; //~ ERROR `E1` is only public within the crate, and cannot be re-exported outside
11+
pub use ::E1::V; //~ ERROR `V` is only public within the crate, and cannot be re-exported outside
12+
}
13+
14+
pub(crate) fn f2() {}
15+
pub(crate) enum E2 {
16+
V
17+
}
18+
pub(crate) struct S2 {
19+
#[rustfmt::skip]
20+
bar: i32,
21+
}
22+
mod m2 {
23+
pub use ::f2; //~ ERROR `f2` is only public within the crate, and cannot be re-exported outside
24+
pub use ::S2; //~ ERROR `S2` is only public within the crate, and cannot be re-exported outside
25+
pub use ::E2; //~ ERROR `E2` is only public within the crate, and cannot be re-exported outside
26+
pub use ::E2::V; //~ ERROR `V` is only public within the crate, and cannot be re-exported outside
27+
}
28+
29+
mod m3 {
30+
pub(crate) fn f3() {}
31+
pub(crate) enum E3 {
32+
V
33+
}
34+
pub(crate) struct S3 {
35+
#[rustfmt::skip]
36+
bar: i32,
37+
}
38+
}
39+
pub use m3::f3; //~ ERROR `f3` is only public within the crate, and cannot be re-exported outside
40+
pub use m3::S3; //~ ERROR `S3` is only public within the crate, and cannot be re-exported outside
41+
pub use m3::E3; //~ ERROR `E3` is only public within the crate, and cannot be re-exported outside
42+
pub use m3::E3::V; //~ ERROR `V` is only public within the crate, and cannot be re-exported outside
43+
44+
pub(self) fn f4() {}
45+
pub use ::f4 as f5; //~ ERROR `f4` is only public within the crate, and cannot be re-exported outside
46+
47+
pub mod m10 {
48+
pub mod m {
49+
pub(super) fn f6() {}
50+
pub(crate) fn f7() {}
51+
pub(in crate::m10) fn f8() {}
52+
}
53+
pub use self::m::f6; //~ ERROR `f6` is private, and cannot be re-exported
54+
pub use self::m::f7; //~ ERROR `f7` is only public within the crate, and cannot be re-exported outside
55+
pub use self::m::f8; //~ ERROR `f8` is private, and cannot be re-exported
56+
}
57+
pub use m10::m::f6; //~ ERROR function `f6` is private
58+
pub use m10::m::f7; //~ ERROR `f7` is only public within the crate, and cannot be re-exported outside
59+
pub use m10::m::f8; //~ ERROR function `f8` is private
60+
61+
pub mod m11 {
62+
pub(self) fn f9() {}
63+
}
64+
pub use m11::f9; //~ ERROR function `f9` is private
65+
66+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
error[E0364]: `f1` is only public within the crate, and cannot be re-exported outside
2+
--> $DIR/crate-private-reexport.rs:8:13
3+
|
4+
LL | pub use ::f1;
5+
| ^^^^
6+
|
7+
note: consider marking `f1` as `pub` in the imported module
8+
--> $DIR/crate-private-reexport.rs:8:13
9+
|
10+
LL | pub use ::f1;
11+
| ^^^^
12+
13+
error[E0365]: `S1` is only public within the crate, and cannot be re-exported outside
14+
--> $DIR/crate-private-reexport.rs:9:13
15+
|
16+
LL | pub use ::S1;
17+
| ^^^^ re-export of crate public `S1`
18+
|
19+
= note: consider declaring type or module `S1` with `pub`
20+
21+
error[E0365]: `E1` is only public within the crate, and cannot be re-exported outside
22+
--> $DIR/crate-private-reexport.rs:10:13
23+
|
24+
LL | pub use ::E1;
25+
| ^^^^ re-export of crate public `E1`
26+
|
27+
= note: consider declaring type or module `E1` with `pub`
28+
29+
error[E0364]: `V` is only public within the crate, and cannot be re-exported outside
30+
--> $DIR/crate-private-reexport.rs:11:13
31+
|
32+
LL | pub use ::E1::V;
33+
| ^^^^^^^
34+
|
35+
note: consider marking `V` as `pub` in the imported module
36+
--> $DIR/crate-private-reexport.rs:11:13
37+
|
38+
LL | pub use ::E1::V;
39+
| ^^^^^^^
40+
41+
error[E0364]: `f2` is only public within the crate, and cannot be re-exported outside
42+
--> $DIR/crate-private-reexport.rs:23:13
43+
|
44+
LL | pub use ::f2;
45+
| ^^^^
46+
|
47+
note: consider marking `f2` as `pub` in the imported module
48+
--> $DIR/crate-private-reexport.rs:23:13
49+
|
50+
LL | pub use ::f2;
51+
| ^^^^
52+
53+
error[E0365]: `S2` is only public within the crate, and cannot be re-exported outside
54+
--> $DIR/crate-private-reexport.rs:24:13
55+
|
56+
LL | pub use ::S2;
57+
| ^^^^ re-export of crate public `S2`
58+
|
59+
= note: consider declaring type or module `S2` with `pub`
60+
61+
error[E0365]: `E2` is only public within the crate, and cannot be re-exported outside
62+
--> $DIR/crate-private-reexport.rs:25:13
63+
|
64+
LL | pub use ::E2;
65+
| ^^^^ re-export of crate public `E2`
66+
|
67+
= note: consider declaring type or module `E2` with `pub`
68+
69+
error[E0364]: `V` is only public within the crate, and cannot be re-exported outside
70+
--> $DIR/crate-private-reexport.rs:26:13
71+
|
72+
LL | pub use ::E2::V;
73+
| ^^^^^^^
74+
|
75+
note: consider marking `V` as `pub` in the imported module
76+
--> $DIR/crate-private-reexport.rs:26:13
77+
|
78+
LL | pub use ::E2::V;
79+
| ^^^^^^^
80+
81+
error[E0364]: `f3` is only public within the crate, and cannot be re-exported outside
82+
--> $DIR/crate-private-reexport.rs:39:9
83+
|
84+
LL | pub use m3::f3;
85+
| ^^^^^^
86+
|
87+
note: consider marking `f3` as `pub` in the imported module
88+
--> $DIR/crate-private-reexport.rs:39:9
89+
|
90+
LL | pub use m3::f3;
91+
| ^^^^^^
92+
93+
error[E0365]: `S3` is only public within the crate, and cannot be re-exported outside
94+
--> $DIR/crate-private-reexport.rs:40:9
95+
|
96+
LL | pub use m3::S3;
97+
| ^^^^^^ re-export of crate public `S3`
98+
|
99+
= note: consider declaring type or module `S3` with `pub`
100+
101+
error[E0365]: `E3` is only public within the crate, and cannot be re-exported outside
102+
--> $DIR/crate-private-reexport.rs:41:9
103+
|
104+
LL | pub use m3::E3;
105+
| ^^^^^^ re-export of crate public `E3`
106+
|
107+
= note: consider declaring type or module `E3` with `pub`
108+
109+
error[E0364]: `V` is only public within the crate, and cannot be re-exported outside
110+
--> $DIR/crate-private-reexport.rs:42:9
111+
|
112+
LL | pub use m3::E3::V;
113+
| ^^^^^^^^^
114+
|
115+
note: consider marking `V` as `pub` in the imported module
116+
--> $DIR/crate-private-reexport.rs:42:9
117+
|
118+
LL | pub use m3::E3::V;
119+
| ^^^^^^^^^
120+
121+
error[E0364]: `f4` is only public within the crate, and cannot be re-exported outside
122+
--> $DIR/crate-private-reexport.rs:45:9
123+
|
124+
LL | pub use ::f4 as f5;
125+
| ^^^^^^^^^^
126+
|
127+
note: consider marking `f4` as `pub` in the imported module
128+
--> $DIR/crate-private-reexport.rs:45:9
129+
|
130+
LL | pub use ::f4 as f5;
131+
| ^^^^^^^^^^
132+
133+
error[E0364]: `f6` is private, and cannot be re-exported
134+
--> $DIR/crate-private-reexport.rs:53:13
135+
|
136+
LL | pub use self::m::f6;
137+
| ^^^^^^^^^^^
138+
|
139+
note: consider marking `f6` as `pub` in the imported module
140+
--> $DIR/crate-private-reexport.rs:53:13
141+
|
142+
LL | pub use self::m::f6;
143+
| ^^^^^^^^^^^
144+
145+
error[E0364]: `f7` is only public within the crate, and cannot be re-exported outside
146+
--> $DIR/crate-private-reexport.rs:54:13
147+
|
148+
LL | pub use self::m::f7;
149+
| ^^^^^^^^^^^
150+
|
151+
note: consider marking `f7` as `pub` in the imported module
152+
--> $DIR/crate-private-reexport.rs:54:13
153+
|
154+
LL | pub use self::m::f7;
155+
| ^^^^^^^^^^^
156+
157+
error[E0364]: `f8` is private, and cannot be re-exported
158+
--> $DIR/crate-private-reexport.rs:55:13
159+
|
160+
LL | pub use self::m::f8;
161+
| ^^^^^^^^^^^
162+
|
163+
note: consider marking `f8` as `pub` in the imported module
164+
--> $DIR/crate-private-reexport.rs:55:13
165+
|
166+
LL | pub use self::m::f8;
167+
| ^^^^^^^^^^^
168+
169+
error[E0364]: `f7` is only public within the crate, and cannot be re-exported outside
170+
--> $DIR/crate-private-reexport.rs:58:9
171+
|
172+
LL | pub use m10::m::f7;
173+
| ^^^^^^^^^^
174+
|
175+
note: consider marking `f7` as `pub` in the imported module
176+
--> $DIR/crate-private-reexport.rs:58:9
177+
|
178+
LL | pub use m10::m::f7;
179+
| ^^^^^^^^^^
180+
181+
error[E0603]: function `f6` is private
182+
--> $DIR/crate-private-reexport.rs:57:17
183+
|
184+
LL | pub use m10::m::f6;
185+
| ^^ private function
186+
|
187+
note: the function `f6` is defined here
188+
--> $DIR/crate-private-reexport.rs:49:9
189+
|
190+
LL | pub(super) fn f6() {}
191+
| ^^^^^^^^^^^^^^^^^^
192+
193+
error[E0603]: function `f8` is private
194+
--> $DIR/crate-private-reexport.rs:59:17
195+
|
196+
LL | pub use m10::m::f8;
197+
| ^^ private function
198+
|
199+
note: the function `f8` is defined here
200+
--> $DIR/crate-private-reexport.rs:51:9
201+
|
202+
LL | pub(in crate::m10) fn f8() {}
203+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
204+
205+
error[E0603]: function `f9` is private
206+
--> $DIR/crate-private-reexport.rs:64:14
207+
|
208+
LL | pub use m11::f9;
209+
| ^^ private function
210+
|
211+
note: the function `f9` is defined here
212+
--> $DIR/crate-private-reexport.rs:62:5
213+
|
214+
LL | pub(self) fn f9() {}
215+
| ^^^^^^^^^^^^^^^^^
216+
217+
error: aborting due to 20 previous errors
218+
219+
Some errors have detailed explanations: E0364, E0365, E0603.
220+
For more information about an error, try `rustc --explain E0364`.

0 commit comments

Comments
 (0)