Skip to content

Commit

Permalink
Clarify error messages caused by re-exporting pub(crate) visibility…
Browse files Browse the repository at this point in the history
… to outside
  • Loading branch information
ken-matsui committed Nov 20, 2021
1 parent d22dd65 commit 33ab512
Show file tree
Hide file tree
Showing 11 changed files with 334 additions and 32 deletions.
50 changes: 33 additions & 17 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1180,11 +1180,17 @@ impl<'a, 'b> ImportResolver<'a, 'b> {

let mut reexport_error = None;
let mut any_successful_reexport = false;
let mut crate_private_reexport = false;
self.r.per_ns(|this, ns| {
if let Ok(binding) = source_bindings[ns].get() {
let vis = import.vis.get();
if !binding.vis.is_at_least(vis, &*this) {
reexport_error = Some((ns, binding));
if let ty::Visibility::Restricted(binding_def_id) = binding.vis {
if binding_def_id.is_top_level_module() {
crate_private_reexport = true;
}
}
} else {
any_successful_reexport = true;
}
Expand All @@ -1207,24 +1213,34 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
import.span,
&msg,
);
} else if ns == TypeNS {
struct_span_err!(
self.r.session,
import.span,
E0365,
"`{}` is private, and cannot be re-exported",
ident
)
.span_label(import.span, format!("re-export of private `{}`", ident))
.note(&format!("consider declaring type or module `{}` with `pub`", ident))
.emit();
} else {
let msg = format!("`{}` is private, and cannot be re-exported", ident);
let note_msg =
format!("consider marking `{}` as `pub` in the imported module", ident,);
struct_span_err!(self.r.session, import.span, E0364, "{}", &msg)
.span_note(import.span, &note_msg)
.emit();
let error_msg = if crate_private_reexport {
format!(
"`{}` is only public within the crate, and cannot be re-exported outside",
ident
)
} else {
format!("`{}` is private, and cannot be re-exported", ident)
};

if ns == TypeNS {
let label_msg = if crate_private_reexport {
format!("re-export of crate public `{}`", ident)
} else {
format!("re-export of private `{}`", ident)
};

struct_span_err!(self.r.session, import.span, E0365, "{}", error_msg)
.span_label(import.span, label_msg)
.note(&format!("consider declaring type or module `{}` with `pub`", ident))
.emit();
} else {
let note_msg =
format!("consider marking `{}` as `pub` in the imported module", ident);
struct_span_err!(self.r.session, import.span, E0364, "{}", error_msg)
.span_note(import.span, &note_msg)
.emit();
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/error-codes/E0365.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ mod foo {
}

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

fn main() {}
4 changes: 2 additions & 2 deletions src/test/ui/error-codes/E0365.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0365]: `foo` is private, and cannot be re-exported
error[E0365]: `foo` is only public within the crate, and cannot be re-exported outside
--> $DIR/E0365.rs:5:9
|
LL | pub use foo as foo2;
| ^^^^^^^^^^^ re-export of private `foo`
| ^^^^^^^^^^^ re-export of crate public `foo`
|
= note: consider declaring type or module `foo` with `pub`

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/modules/issue-56411.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ macro_rules! import {
mod $name;
pub use self::$name;
//~^ ERROR the name `issue_56411_aux` is defined multiple times
//~| ERROR `issue_56411_aux` is private, and cannot be re-exported
//~| ERROR `issue_56411_aux` is only public within the crate, and cannot be re-exported outside

)*
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/modules/issue-56411.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ LL | import!(("issue-56411-aux.rs", issue_56411_aux));
= note: `issue_56411_aux` must be defined only once in the type namespace of this module
= note: this error originates in the macro `import` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0365]: `issue_56411_aux` is private, and cannot be re-exported
error[E0365]: `issue_56411_aux` is only public within the crate, and cannot be re-exported outside
--> $DIR/issue-56411.rs:6:21
|
LL | pub use self::$name;
| ^^^^^^^^^^^ re-export of private `issue_56411_aux`
| ^^^^^^^^^^^ re-export of crate public `issue_56411_aux`
...
LL | import!(("issue-56411-aux.rs", issue_56411_aux));
| ------------------------------------------------ in this macro invocation
Expand Down
66 changes: 66 additions & 0 deletions src/test/ui/privacy/crate-private-reexport.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
fn f1() {}
enum E1 { V }
struct S1 {
#[rustfmt::skip]
bar: i32,
}
mod m1 {
pub use ::f1; //~ ERROR `f1` is only public within the crate, and cannot be re-exported outside
pub use ::S1; //~ ERROR `S1` is only public within the crate, and cannot be re-exported outside
pub use ::E1; //~ ERROR `E1` is only public within the crate, and cannot be re-exported outside
pub use ::E1::V; //~ ERROR `V` is only public within the crate, and cannot be re-exported outside
}

pub(crate) fn f2() {}
pub(crate) enum E2 {
V
}
pub(crate) struct S2 {
#[rustfmt::skip]
bar: i32,
}
mod m2 {
pub use ::f2; //~ ERROR `f2` is only public within the crate, and cannot be re-exported outside
pub use ::S2; //~ ERROR `S2` is only public within the crate, and cannot be re-exported outside
pub use ::E2; //~ ERROR `E2` is only public within the crate, and cannot be re-exported outside
pub use ::E2::V; //~ ERROR `V` is only public within the crate, and cannot be re-exported outside
}

mod m3 {
pub(crate) fn f3() {}
pub(crate) enum E3 {
V
}
pub(crate) struct S3 {
#[rustfmt::skip]
bar: i32,
}
}
pub use m3::f3; //~ ERROR `f3` is only public within the crate, and cannot be re-exported outside
pub use m3::S3; //~ ERROR `S3` is only public within the crate, and cannot be re-exported outside
pub use m3::E3; //~ ERROR `E3` is only public within the crate, and cannot be re-exported outside
pub use m3::E3::V; //~ ERROR `V` is only public within the crate, and cannot be re-exported outside

pub(self) fn f4() {}
pub use ::f4 as f5; //~ ERROR `f4` is only public within the crate, and cannot be re-exported outside

pub mod m10 {
pub mod m {
pub(super) fn f6() {}
pub(crate) fn f7() {}
pub(in crate::m10) fn f8() {}
}
pub use self::m::f6; //~ ERROR `f6` is private, and cannot be re-exported
pub use self::m::f7; //~ ERROR `f7` is only public within the crate, and cannot be re-exported outside
pub use self::m::f8; //~ ERROR `f8` is private, and cannot be re-exported
}
pub use m10::m::f6; //~ ERROR function `f6` is private
pub use m10::m::f7; //~ ERROR `f7` is only public within the crate, and cannot be re-exported outside
pub use m10::m::f8; //~ ERROR function `f8` is private

pub mod m11 {
pub(self) fn f9() {}
}
pub use m11::f9; //~ ERROR function `f9` is private

fn main() {}
220 changes: 220 additions & 0 deletions src/test/ui/privacy/crate-private-reexport.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
error[E0364]: `f1` is only public within the crate, and cannot be re-exported outside
--> $DIR/crate-private-reexport.rs:8:13
|
LL | pub use ::f1;
| ^^^^
|
note: consider marking `f1` as `pub` in the imported module
--> $DIR/crate-private-reexport.rs:8:13
|
LL | pub use ::f1;
| ^^^^

error[E0365]: `S1` is only public within the crate, and cannot be re-exported outside
--> $DIR/crate-private-reexport.rs:9:13
|
LL | pub use ::S1;
| ^^^^ re-export of crate public `S1`
|
= note: consider declaring type or module `S1` with `pub`

error[E0365]: `E1` is only public within the crate, and cannot be re-exported outside
--> $DIR/crate-private-reexport.rs:10:13
|
LL | pub use ::E1;
| ^^^^ re-export of crate public `E1`
|
= note: consider declaring type or module `E1` with `pub`

error[E0364]: `V` is only public within the crate, and cannot be re-exported outside
--> $DIR/crate-private-reexport.rs:11:13
|
LL | pub use ::E1::V;
| ^^^^^^^
|
note: consider marking `V` as `pub` in the imported module
--> $DIR/crate-private-reexport.rs:11:13
|
LL | pub use ::E1::V;
| ^^^^^^^

error[E0364]: `f2` is only public within the crate, and cannot be re-exported outside
--> $DIR/crate-private-reexport.rs:23:13
|
LL | pub use ::f2;
| ^^^^
|
note: consider marking `f2` as `pub` in the imported module
--> $DIR/crate-private-reexport.rs:23:13
|
LL | pub use ::f2;
| ^^^^

error[E0365]: `S2` is only public within the crate, and cannot be re-exported outside
--> $DIR/crate-private-reexport.rs:24:13
|
LL | pub use ::S2;
| ^^^^ re-export of crate public `S2`
|
= note: consider declaring type or module `S2` with `pub`

error[E0365]: `E2` is only public within the crate, and cannot be re-exported outside
--> $DIR/crate-private-reexport.rs:25:13
|
LL | pub use ::E2;
| ^^^^ re-export of crate public `E2`
|
= note: consider declaring type or module `E2` with `pub`

error[E0364]: `V` is only public within the crate, and cannot be re-exported outside
--> $DIR/crate-private-reexport.rs:26:13
|
LL | pub use ::E2::V;
| ^^^^^^^
|
note: consider marking `V` as `pub` in the imported module
--> $DIR/crate-private-reexport.rs:26:13
|
LL | pub use ::E2::V;
| ^^^^^^^

error[E0364]: `f3` is only public within the crate, and cannot be re-exported outside
--> $DIR/crate-private-reexport.rs:39:9
|
LL | pub use m3::f3;
| ^^^^^^
|
note: consider marking `f3` as `pub` in the imported module
--> $DIR/crate-private-reexport.rs:39:9
|
LL | pub use m3::f3;
| ^^^^^^

error[E0365]: `S3` is only public within the crate, and cannot be re-exported outside
--> $DIR/crate-private-reexport.rs:40:9
|
LL | pub use m3::S3;
| ^^^^^^ re-export of crate public `S3`
|
= note: consider declaring type or module `S3` with `pub`

error[E0365]: `E3` is only public within the crate, and cannot be re-exported outside
--> $DIR/crate-private-reexport.rs:41:9
|
LL | pub use m3::E3;
| ^^^^^^ re-export of crate public `E3`
|
= note: consider declaring type or module `E3` with `pub`

error[E0364]: `V` is only public within the crate, and cannot be re-exported outside
--> $DIR/crate-private-reexport.rs:42:9
|
LL | pub use m3::E3::V;
| ^^^^^^^^^
|
note: consider marking `V` as `pub` in the imported module
--> $DIR/crate-private-reexport.rs:42:9
|
LL | pub use m3::E3::V;
| ^^^^^^^^^

error[E0364]: `f4` is only public within the crate, and cannot be re-exported outside
--> $DIR/crate-private-reexport.rs:45:9
|
LL | pub use ::f4 as f5;
| ^^^^^^^^^^
|
note: consider marking `f4` as `pub` in the imported module
--> $DIR/crate-private-reexport.rs:45:9
|
LL | pub use ::f4 as f5;
| ^^^^^^^^^^

error[E0364]: `f6` is private, and cannot be re-exported
--> $DIR/crate-private-reexport.rs:53:13
|
LL | pub use self::m::f6;
| ^^^^^^^^^^^
|
note: consider marking `f6` as `pub` in the imported module
--> $DIR/crate-private-reexport.rs:53:13
|
LL | pub use self::m::f6;
| ^^^^^^^^^^^

error[E0364]: `f7` is only public within the crate, and cannot be re-exported outside
--> $DIR/crate-private-reexport.rs:54:13
|
LL | pub use self::m::f7;
| ^^^^^^^^^^^
|
note: consider marking `f7` as `pub` in the imported module
--> $DIR/crate-private-reexport.rs:54:13
|
LL | pub use self::m::f7;
| ^^^^^^^^^^^

error[E0364]: `f8` is private, and cannot be re-exported
--> $DIR/crate-private-reexport.rs:55:13
|
LL | pub use self::m::f8;
| ^^^^^^^^^^^
|
note: consider marking `f8` as `pub` in the imported module
--> $DIR/crate-private-reexport.rs:55:13
|
LL | pub use self::m::f8;
| ^^^^^^^^^^^

error[E0364]: `f7` is only public within the crate, and cannot be re-exported outside
--> $DIR/crate-private-reexport.rs:58:9
|
LL | pub use m10::m::f7;
| ^^^^^^^^^^
|
note: consider marking `f7` as `pub` in the imported module
--> $DIR/crate-private-reexport.rs:58:9
|
LL | pub use m10::m::f7;
| ^^^^^^^^^^

error[E0603]: function `f6` is private
--> $DIR/crate-private-reexport.rs:57:17
|
LL | pub use m10::m::f6;
| ^^ private function
|
note: the function `f6` is defined here
--> $DIR/crate-private-reexport.rs:49:9
|
LL | pub(super) fn f6() {}
| ^^^^^^^^^^^^^^^^^^

error[E0603]: function `f8` is private
--> $DIR/crate-private-reexport.rs:59:17
|
LL | pub use m10::m::f8;
| ^^ private function
|
note: the function `f8` is defined here
--> $DIR/crate-private-reexport.rs:51:9
|
LL | pub(in crate::m10) fn f8() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0603]: function `f9` is private
--> $DIR/crate-private-reexport.rs:64:14
|
LL | pub use m11::f9;
| ^^ private function
|
note: the function `f9` is defined here
--> $DIR/crate-private-reexport.rs:62:5
|
LL | pub(self) fn f9() {}
| ^^^^^^^^^^^^^^^^^

error: aborting due to 20 previous errors

Some errors have detailed explanations: E0364, E0365, E0603.
For more information about an error, try `rustc --explain E0364`.

0 comments on commit 33ab512

Please sign in to comment.