Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resolve: Reduce scope of pub_use_of_private_extern_crate deprecation lint #80763

Merged
merged 1 commit into from
Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,21 @@ impl<'a> NameResolution<'a> {
}
}

// Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;`
// are permitted for backward-compatibility under a deprecation lint.
fn pub_use_of_private_extern_crate_hack(import: &Import<'_>, binding: &NameBinding<'_>) -> bool {
match (&import.kind, &binding.kind) {
(
ImportKind::Single { .. },
NameBindingKind::Import {
import: Import { kind: ImportKind::ExternCrate { .. }, .. },
..
},
) => import.vis.get() == ty::Visibility::Public,
_ => false,
}
}

impl<'a> Resolver<'a> {
crate fn resolve_ident_in_module_unadjusted(
&mut self,
Expand Down Expand Up @@ -263,10 +278,7 @@ impl<'a> Resolver<'a> {
return Err((Determined, Weak::No));
}
}
// `extern crate` are always usable for backwards compatibility, see issue #37020,
// remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`.
let usable = this.is_accessible_from(binding.vis, parent_scope.module)
|| binding.is_extern_crate();
let usable = this.is_accessible_from(binding.vis, parent_scope.module);
if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
};

Expand Down Expand Up @@ -309,10 +321,7 @@ impl<'a> Resolver<'a> {
}
}

if !(self.is_accessible_from(binding.vis, parent_scope.module) ||
// Remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`
(self.last_import_segment && binding.is_extern_crate()))
{
if !self.is_accessible_from(binding.vis, parent_scope.module) {
self.privacy_errors.push(PrivacyError {
ident,
binding,
Expand Down Expand Up @@ -455,9 +464,8 @@ impl<'a> Resolver<'a> {
binding: &'a NameBinding<'a>,
import: &'a Import<'a>,
) -> &'a NameBinding<'a> {
let vis = if binding.vis.is_at_least(import.vis.get(), self) ||
// cf. `PUB_USE_OF_PRIVATE_EXTERN_CRATE`
!import.is_glob() && binding.is_extern_crate()
let vis = if binding.vis.is_at_least(import.vis.get(), self)
|| pub_use_of_private_extern_crate_hack(import, binding)
{
import.vis.get()
} else {
Expand Down Expand Up @@ -1188,7 +1196,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
// All namespaces must be re-exported with extra visibility for an error to occur.
if !any_successful_reexport {
let (ns, binding) = reexport_error.unwrap();
if ns == TypeNS && binding.is_extern_crate() {
if pub_use_of_private_extern_crate_hack(import, binding) {
let msg = format!(
"extern crate `{}` is private, and cannot be \
re-exported (error E0365), consider declaring with \
Expand Down
2 changes: 1 addition & 1 deletion src/test/rustdoc/extern-links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#![crate_name = "foo"]

extern crate extern_links;
pub extern crate extern_links;

// @!has foo/index.html '//a' 'extern_links'
#[doc(no_inline)]
Expand Down
2 changes: 1 addition & 1 deletion src/test/rustdoc/issue-28927.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
// aux-build:issue-28927-1.rs
// ignore-cross-compile

extern crate issue_28927_1 as inner1;
pub extern crate issue_28927_1 as inner1;
pub use inner1 as foo;
8 changes: 2 additions & 6 deletions src/test/ui/pub/pub-reexport-priv-extern-crate.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![allow(unused)]

extern crate core;
pub use core as reexported_core; //~ ERROR `core` is private, and cannot be re-exported
//~^ WARN this was previously accepted
Expand All @@ -9,16 +7,14 @@ mod foo1 {
}

mod foo2 {
use foo1::core; //~ ERROR `core` is private, and cannot be re-exported
//~^ WARN this was previously accepted
use foo1::core; //~ ERROR crate import `core` is private
pub mod bar {
extern crate core;
}
}

mod baz {
pub use foo2::bar::core; //~ ERROR `core` is private, and cannot be re-exported
//~^ WARN this was previously accepted
pub use foo2::bar::core; //~ ERROR crate import `core` is private
}

fn main() {}
39 changes: 23 additions & 16 deletions src/test/ui/pub/pub-reexport-priv-extern-crate.stderr
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
error: extern crate `core` is private, and cannot be re-exported (error E0365), consider declaring with `pub`
--> $DIR/pub-reexport-priv-extern-crate.rs:4:9
error[E0603]: crate import `core` is private
--> $DIR/pub-reexport-priv-extern-crate.rs:10:15
|
LL | pub use core as reexported_core;
| ^^^^^^^^^^^^^^^^^^^^^^^
LL | use foo1::core;
| ^^^^ private crate import
|
= note: `#[deny(pub_use_of_private_extern_crate)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
note: the crate import `core` is defined here
--> $DIR/pub-reexport-priv-extern-crate.rs:6:5
|
LL | extern crate core;
| ^^^^^^^^^^^^^^^^^^

error: extern crate `core` is private, and cannot be re-exported (error E0365), consider declaring with `pub`
--> $DIR/pub-reexport-priv-extern-crate.rs:12:9
error[E0603]: crate import `core` is private
--> $DIR/pub-reexport-priv-extern-crate.rs:17:24
|
LL | use foo1::core;
| ^^^^^^^^^^
LL | pub use foo2::bar::core;
| ^^^^ private crate import
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
note: the crate import `core` is defined here
--> $DIR/pub-reexport-priv-extern-crate.rs:12:9
|
LL | extern crate core;
| ^^^^^^^^^^^^^^^^^^

error: extern crate `core` is private, and cannot be re-exported (error E0365), consider declaring with `pub`
--> $DIR/pub-reexport-priv-extern-crate.rs:20:13
--> $DIR/pub-reexport-priv-extern-crate.rs:2:9
|
LL | pub use foo2::bar::core;
| ^^^^^^^^^^^^^^^
LL | pub use core as reexported_core;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[deny(pub_use_of_private_extern_crate)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0603`.