Skip to content

Commit

Permalink
Rollup merge of rust-lang#80763 - petrochenkov:pubusecrate, r=estebank
Browse files Browse the repository at this point in the history
resolve: Reduce scope of `pub_use_of_private_extern_crate` deprecation lint

This lint was deny-by-default since July 2017, crater showed 7 uses on crates.io back then (rust-lang#42894 (comment)).

Unfortunately, the construction `pub use foo as bar` where `foo` is `extern crate foo;` was used by an older version `bitflags`, so turning it into an error causes too many regressions.
So, this PR reduces the scope of the lint instead of turning it into a hard error, and only turns some more rarely used components of it into errors.
  • Loading branch information
m-ou-se authored Mar 5, 2021
2 parents e6a6df5 + 7b021aa commit ec2619c
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 36 deletions.
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`.

0 comments on commit ec2619c

Please sign in to comment.