Skip to content

Commit 462e7e7

Browse files
authored
Rollup merge of #109003 - GuillaumeGomez:useless-anonymous-reexport-lint, r=cjgillot
Add `useless_anonymous_reexport` lint This is a follow-up of #108936. We once again show all anonymous re-exports in rustdoc, however we also wanted to add a lint to let users know that it very likely doesn't have the effect they think it has.
2 parents c8e112a + 7b0fa08 commit 462e7e7

10 files changed

+176
-4
lines changed

compiler/rustc_lint/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -508,3 +508,6 @@ lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its ass
508508
.specifically = this associated type bound is unsatisfied for `{$proj_ty}`
509509
510510
lint_opaque_hidden_inferred_bound_sugg = add this bound
511+
512+
lint_useless_anonymous_reexport = useless anonymous re-export
513+
.note = only anonymous re-exports of traits are useful, this is {$article} `{$desc}`

compiler/rustc_lint/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ mod opaque_hidden_inferred_bound;
7474
mod pass_by_value;
7575
mod passes;
7676
mod redundant_semicolon;
77+
mod reexports;
7778
mod traits;
7879
mod types;
7980
mod unused;
@@ -111,6 +112,7 @@ use noop_method_call::*;
111112
use opaque_hidden_inferred_bound::*;
112113
use pass_by_value::*;
113114
use redundant_semicolon::*;
115+
use reexports::*;
114116
use traits::*;
115117
use types::*;
116118
use unused::*;
@@ -242,6 +244,7 @@ late_lint_methods!(
242244
OpaqueHiddenInferredBound: OpaqueHiddenInferredBound,
243245
MultipleSupertraitUpcastable: MultipleSupertraitUpcastable,
244246
MapUnitFn: MapUnitFn,
247+
UselessAnonymousReexport: UselessAnonymousReexport,
245248
]
246249
]
247250
);

compiler/rustc_lint/src/lints.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1528,3 +1528,11 @@ pub struct UnusedAllocationDiag;
15281528
#[derive(LintDiagnostic)]
15291529
#[diag(lint_unused_allocation_mut)]
15301530
pub struct UnusedAllocationMutDiag;
1531+
1532+
#[derive(LintDiagnostic)]
1533+
#[diag(lint_useless_anonymous_reexport)]
1534+
#[note]
1535+
pub struct UselessAnonymousReexportDiag {
1536+
pub article: &'static str,
1537+
pub desc: &'static str,
1538+
}

compiler/rustc_lint/src/reexports.rs

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
use crate::lints::UselessAnonymousReexportDiag;
2+
use crate::{LateContext, LateLintPass, LintContext};
3+
use rustc_hir::def::DefKind;
4+
use rustc_hir::def_id::DefId;
5+
use rustc_hir::{Item, ItemKind, UseKind};
6+
use rustc_middle::ty::Visibility;
7+
use rustc_span::symbol::kw;
8+
use rustc_span::Span;
9+
10+
declare_lint! {
11+
/// The `useless_anonymous_reexport` lint checks if anonymous re-exports
12+
/// are re-exports of traits.
13+
///
14+
/// ### Example
15+
///
16+
/// ```rust,compile_fail
17+
/// #![deny(useless_anonymous_reexport)]
18+
///
19+
/// mod sub {
20+
/// pub struct Bar;
21+
/// }
22+
///
23+
/// pub use self::sub::Bar as _;
24+
/// # fn main() {}
25+
/// ```
26+
///
27+
/// {{produces}}
28+
///
29+
/// ### Explanation
30+
///
31+
/// Anonymous re-exports are only useful if it's a re-export of a trait
32+
/// in case you want to give access to it. If you re-export any other kind,
33+
/// you won't be able to use it since its name won't be accessible.
34+
pub USELESS_ANONYMOUS_REEXPORT,
35+
Warn,
36+
"useless anonymous re-export"
37+
}
38+
39+
declare_lint_pass!(UselessAnonymousReexport => [USELESS_ANONYMOUS_REEXPORT]);
40+
41+
fn emit_err(cx: &LateContext<'_>, span: Span, def_id: DefId) {
42+
let article = cx.tcx.def_descr_article(def_id);
43+
let desc = cx.tcx.def_descr(def_id);
44+
cx.emit_spanned_lint(
45+
USELESS_ANONYMOUS_REEXPORT,
46+
span,
47+
UselessAnonymousReexportDiag { article, desc },
48+
);
49+
}
50+
51+
impl<'tcx> LateLintPass<'tcx> for UselessAnonymousReexport {
52+
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
53+
if let ItemKind::Use(path, kind) = item.kind &&
54+
!matches!(kind, UseKind::Glob) &&
55+
item.ident.name == kw::Underscore &&
56+
// We only want re-exports. If it's just a `use X;`, then we ignore it.
57+
match cx.tcx.local_visibility(item.owner_id.def_id) {
58+
Visibility::Public => true,
59+
Visibility::Restricted(level) => {
60+
level != cx.tcx.parent_module_from_def_id(item.owner_id.def_id)
61+
}
62+
}
63+
{
64+
for def_id in path.res.iter().filter_map(|r| r.opt_def_id()) {
65+
match cx.tcx.def_kind(def_id) {
66+
DefKind::Trait | DefKind::TraitAlias => {}
67+
DefKind::TyAlias => {
68+
let ty = cx.tcx.type_of(def_id);
69+
if !ty.0.is_trait() {
70+
emit_err(cx, item.span, def_id);
71+
break;
72+
}
73+
}
74+
_ => {
75+
emit_err(cx, item.span, def_id);
76+
break;
77+
}
78+
}
79+
}
80+
}
81+
}
82+
}

tests/ui/imports/issue-99695-b.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// run-rustfix
2-
#![allow(unused, nonstandard_style)]
2+
#![allow(unused, nonstandard_style, useless_anonymous_reexport)]
33
mod m {
44

55
mod p {

tests/ui/imports/issue-99695-b.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// run-rustfix
2-
#![allow(unused, nonstandard_style)]
2+
#![allow(unused, nonstandard_style, useless_anonymous_reexport)]
33
mod m {
44

55
mod p {

tests/ui/imports/issue-99695.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// run-rustfix
2-
#![allow(unused, nonstandard_style)]
2+
#![allow(unused, nonstandard_style, useless_anonymous_reexport)]
33
mod m {
44
#[macro_export]
55
macro_rules! nu {

tests/ui/imports/issue-99695.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// run-rustfix
2-
#![allow(unused, nonstandard_style)]
2+
#![allow(unused, nonstandard_style, useless_anonymous_reexport)]
33
mod m {
44
#[macro_export]
55
macro_rules! nu {

tests/ui/lint/anonymous-reexport.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#![deny(useless_anonymous_reexport)]
2+
#![crate_type = "rlib"]
3+
4+
mod my_mod {
5+
pub trait Foo {}
6+
pub type TyFoo = dyn Foo;
7+
pub struct Bar;
8+
pub type TyBar = Bar;
9+
}
10+
11+
pub use self::my_mod::Foo as _;
12+
pub use self::my_mod::TyFoo as _;
13+
pub use self::my_mod::Bar as _; //~ ERROR
14+
pub use self::my_mod::TyBar as _; //~ ERROR
15+
pub use self::my_mod::{Bar as _}; //~ ERROR
16+
pub use self::my_mod::{Bar as _, Foo as _}; //~ ERROR
17+
pub use self::my_mod::{Bar as _, TyBar as _};
18+
//~^ ERROR
19+
//~| ERROR
20+
#[allow(unused_imports)]
21+
use self::my_mod::TyBar as _;
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
error: useless anonymous re-export
2+
--> $DIR/anonymous-reexport.rs:13:1
3+
|
4+
LL | pub use self::my_mod::Bar as _;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: only anonymous re-exports of traits are useful, this is a `struct`
8+
note: the lint level is defined here
9+
--> $DIR/anonymous-reexport.rs:1:9
10+
|
11+
LL | #![deny(useless_anonymous_reexport)]
12+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
13+
14+
error: useless anonymous re-export
15+
--> $DIR/anonymous-reexport.rs:14:1
16+
|
17+
LL | pub use self::my_mod::TyBar as _;
18+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
19+
|
20+
= note: only anonymous re-exports of traits are useful, this is a `type alias`
21+
22+
error: useless anonymous re-export
23+
--> $DIR/anonymous-reexport.rs:15:24
24+
|
25+
LL | pub use self::my_mod::{Bar as _};
26+
| ^^^^^^^^
27+
|
28+
= note: only anonymous re-exports of traits are useful, this is a `struct`
29+
30+
error: useless anonymous re-export
31+
--> $DIR/anonymous-reexport.rs:16:24
32+
|
33+
LL | pub use self::my_mod::{Bar as _, Foo as _};
34+
| ^^^^^^^^
35+
|
36+
= note: only anonymous re-exports of traits are useful, this is a `struct`
37+
38+
error: useless anonymous re-export
39+
--> $DIR/anonymous-reexport.rs:17:24
40+
|
41+
LL | pub use self::my_mod::{Bar as _, TyBar as _};
42+
| ^^^^^^^^
43+
|
44+
= note: only anonymous re-exports of traits are useful, this is a `struct`
45+
46+
error: useless anonymous re-export
47+
--> $DIR/anonymous-reexport.rs:17:34
48+
|
49+
LL | pub use self::my_mod::{Bar as _, TyBar as _};
50+
| ^^^^^^^^^^
51+
|
52+
= note: only anonymous re-exports of traits are useful, this is a `type alias`
53+
54+
error: aborting due to 6 previous errors
55+

0 commit comments

Comments
 (0)