Skip to content

Commit 8d1cbb0

Browse files
committed
private no-mangle lints: help hint note if visibility modifier is pub
If the item is `pub`, one imagines users being confused as to why it's not reachable/exported; a code suggestion is beyond our local knowledge here, but we can at least offer a prose hint. (Thanks to Vadim Petrochenkov for shooting down the present author's original bad idea for the note text.) While we're here, use proper HELP expectations instead of ad hoc comments to communicate (and now, enforce) the expected suggestions in test/ui/lint/suggestions.rs.
1 parent 5330747 commit 8d1cbb0

File tree

3 files changed

+54
-32
lines changed

3 files changed

+54
-32
lines changed

src/librustc_lint/builtin.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1177,7 +1177,7 @@ impl LintPass for InvalidNoMangleItems {
11771177

11781178
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
11791179
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
1180-
let suggest_make_pub = |vis: &hir::Visibility, err: &mut DiagnosticBuilder| {
1180+
let suggest_export = |vis: &hir::Visibility, err: &mut DiagnosticBuilder| {
11811181
let suggestion = match vis.node {
11821182
hir::VisibilityInherited => {
11831183
// inherited visibility is empty span at item start; need an extra space
@@ -1187,7 +1187,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
11871187
hir::VisibilityCrate(_) => {
11881188
Some("pub".to_owned())
11891189
},
1190-
hir::VisibilityPublic => None
1190+
hir::VisibilityPublic => {
1191+
err.help("try exporting the item with a `pub use` statement");
1192+
None
1193+
}
11911194
};
11921195
if let Some(replacement) = suggestion {
11931196
err.span_suggestion(vis.span, "try making it public", replacement);
@@ -1203,7 +1206,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
12031206
if !cx.access_levels.is_reachable(it.id) {
12041207
let msg = "function is marked #[no_mangle], but not exported";
12051208
let mut err = cx.struct_span_lint(PRIVATE_NO_MANGLE_FNS, it.span, msg);
1206-
suggest_make_pub(&it.vis, &mut err);
1209+
suggest_export(&it.vis, &mut err);
12071210
err.emit();
12081211
}
12091212
for param in &generics.params {
@@ -1229,7 +1232,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
12291232
!cx.access_levels.is_reachable(it.id) {
12301233
let msg = "static is marked #[no_mangle], but not exported";
12311234
let mut err = cx.struct_span_lint(PRIVATE_NO_MANGLE_STATICS, it.span, msg);
1232-
suggest_make_pub(&it.vis, &mut err);
1235+
suggest_export(&it.vis, &mut err);
12331236
err.emit();
12341237
}
12351238
}

src/test/ui/lint/suggestions.rs

+21-7
Original file line numberDiff line numberDiff line change
@@ -13,33 +13,41 @@
1313
#![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
1414
#![feature(no_debug)]
1515

16-
#[no_mangle] static SHENZHOU: usize = 1; // should suggest `pub`
16+
#[no_mangle] static SHENZHOU: usize = 1;
1717
//~^ WARN static is marked #[no_mangle]
18-
#[no_mangle] const DISCOVERY: usize = 1; // should suggest `pub static` rather than `const`
18+
//~| HELP try making it public
19+
#[no_mangle] const DISCOVERY: usize = 1;
1920
//~^ ERROR const items should never be #[no_mangle]
21+
//~| HELP try a static value
2022

21-
#[no_mangle] // should suggest removal (generics can't be no-mangle)
23+
#[no_mangle]
24+
//~^ HELP remove this attribute
2225
pub fn defiant<T>(_t: T) {}
2326
//~^ WARN functions generic over types must be mangled
2427

2528
#[no_mangle]
26-
fn rio_grande() {} // should suggest `pub`
29+
fn rio_grande() {}
2730
//~^ WARN function is marked
31+
//~| HELP try making it public
2832

2933
mod badlands {
3034
// The private-no-mangle lints shouldn't suggest inserting `pub` when the
3135
// item is already `pub` (but triggered the lint because, e.g., it's in a
3236
// private module). (Issue #47383)
3337
#[no_mangle] pub static DAUNTLESS: bool = true;
3438
//~^ WARN static is marked
39+
//~| HELP try exporting the item with a `pub use` statement
3540
#[no_mangle] pub fn val_jean() {}
3641
//~^ WARN function is marked
42+
//~| HELP try exporting the item with a `pub use` statement
3743

3844
// ... but we can suggest just-`pub` instead of restricted
3945
#[no_mangle] pub(crate) static VETAR: bool = true;
4046
//~^ WARN static is marked
47+
//~| HELP try making it public
4148
#[no_mangle] pub(crate) fn crossfield() {}
4249
//~^ WARN function is marked
50+
//~| HELP try making it public
4351
}
4452

4553
struct Equinox {
@@ -48,20 +56,26 @@ struct Equinox {
4856

4957
#[no_debug] // should suggest removal of deprecated attribute
5058
//~^ WARN deprecated
59+
//~| HELP remove this attribute
5160
fn main() {
52-
while true { // should suggest `loop`
61+
while true {
5362
//~^ WARN denote infinite loops
54-
let mut a = (1); // should suggest no `mut`, no parens
63+
//~| HELP use `loop`
64+
let mut a = (1);
5565
//~^ WARN does not need to be mutable
66+
//~| HELP remove this `mut`
5667
//~| WARN unnecessary parentheses
68+
//~| HELP remove these parentheses
5769
// the line after `mut` has a `\t` at the beginning, this is on purpose
5870
let mut
5971
b = 1;
6072
//~^^ WARN does not need to be mutable
73+
//~| HELP remove this `mut`
6174
let d = Equinox { warp_factor: 9.975 };
6275
match d {
63-
Equinox { warp_factor: warp_factor } => {} // should suggest shorthand
76+
Equinox { warp_factor: warp_factor } => {}
6477
//~^ WARN this pattern is redundant
78+
//~| HELP remove this
6579
}
6680
println!("{} {}", a, b);
6781
}

src/test/ui/lint/suggestions.stderr

+26-21
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
warning: unnecessary parentheses around assigned value
2-
--> $DIR/suggestions.rs:54:21
2+
--> $DIR/suggestions.rs:64:21
33
|
4-
LL | let mut a = (1); // should suggest no `mut`, no parens
4+
LL | let mut a = (1);
55
| ^^^ help: remove these parentheses
66
|
77
note: lint level defined here
@@ -11,17 +11,17 @@ LL | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issu
1111
| ^^^^^^^^^^^^^
1212

1313
warning: use of deprecated attribute `no_debug`: the `#[no_debug]` attribute was an experimental feature that has been deprecated due to lack of demand. See https://github.com/rust-lang/rust/issues/29721
14-
--> $DIR/suggestions.rs:49:1
14+
--> $DIR/suggestions.rs:57:1
1515
|
1616
LL | #[no_debug] // should suggest removal of deprecated attribute
1717
| ^^^^^^^^^^^ help: remove this attribute
1818
|
1919
= note: #[warn(deprecated)] on by default
2020

2121
warning: variable does not need to be mutable
22-
--> $DIR/suggestions.rs:54:13
22+
--> $DIR/suggestions.rs:64:13
2323
|
24-
LL | let mut a = (1); // should suggest no `mut`, no parens
24+
LL | let mut a = (1);
2525
| ----^
2626
| |
2727
| help: remove this `mut`
@@ -33,7 +33,7 @@ LL | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issu
3333
| ^^^^^^^^^^
3434

3535
warning: variable does not need to be mutable
36-
--> $DIR/suggestions.rs:58:13
36+
--> $DIR/suggestions.rs:70:13
3737
|
3838
LL | let mut
3939
| _____________^
@@ -47,83 +47,88 @@ LL | || b = 1;
4747
warning: static is marked #[no_mangle], but not exported
4848
--> $DIR/suggestions.rs:16:14
4949
|
50-
LL | #[no_mangle] static SHENZHOU: usize = 1; // should suggest `pub`
50+
LL | #[no_mangle] static SHENZHOU: usize = 1;
5151
| -^^^^^^^^^^^^^^^^^^^^^^^^^^
5252
| |
5353
| help: try making it public: `pub`
5454
|
5555
= note: #[warn(private_no_mangle_statics)] on by default
5656

5757
error: const items should never be #[no_mangle]
58-
--> $DIR/suggestions.rs:18:14
58+
--> $DIR/suggestions.rs:19:14
5959
|
60-
LL | #[no_mangle] const DISCOVERY: usize = 1; // should suggest `pub static` rather than `const`
60+
LL | #[no_mangle] const DISCOVERY: usize = 1;
6161
| -----^^^^^^^^^^^^^^^^^^^^^^
6262
| |
6363
| help: try a static value: `pub static`
6464
|
6565
= note: #[deny(no_mangle_const_items)] on by default
6666

6767
warning: functions generic over types must be mangled
68-
--> $DIR/suggestions.rs:22:1
68+
--> $DIR/suggestions.rs:25:1
6969
|
70-
LL | #[no_mangle] // should suggest removal (generics can't be no-mangle)
70+
LL | #[no_mangle]
7171
| ------------ help: remove this attribute
72+
LL | //~^ HELP remove this attribute
7273
LL | pub fn defiant<T>(_t: T) {}
7374
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
7475
|
7576
= note: #[warn(no_mangle_generic_items)] on by default
7677

7778
warning: function is marked #[no_mangle], but not exported
78-
--> $DIR/suggestions.rs:26:1
79+
--> $DIR/suggestions.rs:29:1
7980
|
80-
LL | fn rio_grande() {} // should suggest `pub`
81+
LL | fn rio_grande() {}
8182
| -^^^^^^^^^^^^^^^^^
8283
| |
8384
| help: try making it public: `pub`
8485
|
8586
= note: #[warn(private_no_mangle_fns)] on by default
8687

8788
warning: static is marked #[no_mangle], but not exported
88-
--> $DIR/suggestions.rs:33:18
89+
--> $DIR/suggestions.rs:37:18
8990
|
9091
LL | #[no_mangle] pub static DAUNTLESS: bool = true;
9192
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
93+
|
94+
= help: try exporting the item with a `pub use` statement
9295

9396
warning: function is marked #[no_mangle], but not exported
94-
--> $DIR/suggestions.rs:35:18
97+
--> $DIR/suggestions.rs:40:18
9598
|
9699
LL | #[no_mangle] pub fn val_jean() {}
97100
| ^^^^^^^^^^^^^^^^^^^^
101+
|
102+
= help: try exporting the item with a `pub use` statement
98103

99104
warning: static is marked #[no_mangle], but not exported
100-
--> $DIR/suggestions.rs:39:18
105+
--> $DIR/suggestions.rs:45:18
101106
|
102107
LL | #[no_mangle] pub(crate) static VETAR: bool = true;
103108
| ----------^^^^^^^^^^^^^^^^^^^^^^^^^^^
104109
| |
105110
| help: try making it public: `pub`
106111

107112
warning: function is marked #[no_mangle], but not exported
108-
--> $DIR/suggestions.rs:41:18
113+
--> $DIR/suggestions.rs:48:18
109114
|
110115
LL | #[no_mangle] pub(crate) fn crossfield() {}
111116
| ----------^^^^^^^^^^^^^^^^^^^
112117
| |
113118
| help: try making it public: `pub`
114119

115120
warning: denote infinite loops with `loop { ... }`
116-
--> $DIR/suggestions.rs:52:5
121+
--> $DIR/suggestions.rs:61:5
117122
|
118-
LL | while true { // should suggest `loop`
123+
LL | while true {
119124
| ^^^^^^^^^^ help: use `loop`
120125
|
121126
= note: #[warn(while_true)] on by default
122127

123128
warning: the `warp_factor:` in this pattern is redundant
124-
--> $DIR/suggestions.rs:63:23
129+
--> $DIR/suggestions.rs:76:23
125130
|
126-
LL | Equinox { warp_factor: warp_factor } => {} // should suggest shorthand
131+
LL | Equinox { warp_factor: warp_factor } => {}
127132
| ------------^^^^^^^^^^^^
128133
| |
129134
| help: remove this

0 commit comments

Comments
 (0)