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.
This commit is contained in:
parent
53307473fd
commit
8d1cbb018e
@ -1177,7 +1177,7 @@ impl LintPass for InvalidNoMangleItems {
|
||||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
|
||||
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
|
||||
let suggest_make_pub = |vis: &hir::Visibility, err: &mut DiagnosticBuilder| {
|
||||
let suggest_export = |vis: &hir::Visibility, err: &mut DiagnosticBuilder| {
|
||||
let suggestion = match vis.node {
|
||||
hir::VisibilityInherited => {
|
||||
// inherited visibility is empty span at item start; need an extra space
|
||||
@ -1187,7 +1187,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
|
||||
hir::VisibilityCrate(_) => {
|
||||
Some("pub".to_owned())
|
||||
},
|
||||
hir::VisibilityPublic => None
|
||||
hir::VisibilityPublic => {
|
||||
err.help("try exporting the item with a `pub use` statement");
|
||||
None
|
||||
}
|
||||
};
|
||||
if let Some(replacement) = suggestion {
|
||||
err.span_suggestion(vis.span, "try making it public", replacement);
|
||||
@ -1203,7 +1206,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
|
||||
if !cx.access_levels.is_reachable(it.id) {
|
||||
let msg = "function is marked #[no_mangle], but not exported";
|
||||
let mut err = cx.struct_span_lint(PRIVATE_NO_MANGLE_FNS, it.span, msg);
|
||||
suggest_make_pub(&it.vis, &mut err);
|
||||
suggest_export(&it.vis, &mut err);
|
||||
err.emit();
|
||||
}
|
||||
for param in &generics.params {
|
||||
@ -1229,7 +1232,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
|
||||
!cx.access_levels.is_reachable(it.id) {
|
||||
let msg = "static is marked #[no_mangle], but not exported";
|
||||
let mut err = cx.struct_span_lint(PRIVATE_NO_MANGLE_STATICS, it.span, msg);
|
||||
suggest_make_pub(&it.vis, &mut err);
|
||||
suggest_export(&it.vis, &mut err);
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
|
@ -13,18 +13,22 @@
|
||||
#![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
|
||||
#![feature(no_debug)]
|
||||
|
||||
#[no_mangle] static SHENZHOU: usize = 1; // should suggest `pub`
|
||||
#[no_mangle] static SHENZHOU: usize = 1;
|
||||
//~^ WARN static is marked #[no_mangle]
|
||||
#[no_mangle] const DISCOVERY: usize = 1; // should suggest `pub static` rather than `const`
|
||||
//~| HELP try making it public
|
||||
#[no_mangle] const DISCOVERY: usize = 1;
|
||||
//~^ ERROR const items should never be #[no_mangle]
|
||||
//~| HELP try a static value
|
||||
|
||||
#[no_mangle] // should suggest removal (generics can't be no-mangle)
|
||||
#[no_mangle]
|
||||
//~^ HELP remove this attribute
|
||||
pub fn defiant<T>(_t: T) {}
|
||||
//~^ WARN functions generic over types must be mangled
|
||||
|
||||
#[no_mangle]
|
||||
fn rio_grande() {} // should suggest `pub`
|
||||
fn rio_grande() {}
|
||||
//~^ WARN function is marked
|
||||
//~| HELP try making it public
|
||||
|
||||
mod badlands {
|
||||
// The private-no-mangle lints shouldn't suggest inserting `pub` when the
|
||||
@ -32,14 +36,18 @@ mod badlands {
|
||||
// private module). (Issue #47383)
|
||||
#[no_mangle] pub static DAUNTLESS: bool = true;
|
||||
//~^ WARN static is marked
|
||||
//~| HELP try exporting the item with a `pub use` statement
|
||||
#[no_mangle] pub fn val_jean() {}
|
||||
//~^ WARN function is marked
|
||||
//~| HELP try exporting the item with a `pub use` statement
|
||||
|
||||
// ... but we can suggest just-`pub` instead of restricted
|
||||
#[no_mangle] pub(crate) static VETAR: bool = true;
|
||||
//~^ WARN static is marked
|
||||
//~| HELP try making it public
|
||||
#[no_mangle] pub(crate) fn crossfield() {}
|
||||
//~^ WARN function is marked
|
||||
//~| HELP try making it public
|
||||
}
|
||||
|
||||
struct Equinox {
|
||||
@ -48,20 +56,26 @@ struct Equinox {
|
||||
|
||||
#[no_debug] // should suggest removal of deprecated attribute
|
||||
//~^ WARN deprecated
|
||||
//~| HELP remove this attribute
|
||||
fn main() {
|
||||
while true { // should suggest `loop`
|
||||
while true {
|
||||
//~^ WARN denote infinite loops
|
||||
let mut a = (1); // should suggest no `mut`, no parens
|
||||
//~| HELP use `loop`
|
||||
let mut a = (1);
|
||||
//~^ WARN does not need to be mutable
|
||||
//~| HELP remove this `mut`
|
||||
//~| WARN unnecessary parentheses
|
||||
//~| HELP remove these parentheses
|
||||
// the line after `mut` has a `\t` at the beginning, this is on purpose
|
||||
let mut
|
||||
b = 1;
|
||||
//~^^ WARN does not need to be mutable
|
||||
//~| HELP remove this `mut`
|
||||
let d = Equinox { warp_factor: 9.975 };
|
||||
match d {
|
||||
Equinox { warp_factor: warp_factor } => {} // should suggest shorthand
|
||||
Equinox { warp_factor: warp_factor } => {}
|
||||
//~^ WARN this pattern is redundant
|
||||
//~| HELP remove this
|
||||
}
|
||||
println!("{} {}", a, b);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
warning: unnecessary parentheses around assigned value
|
||||
--> $DIR/suggestions.rs:54:21
|
||||
--> $DIR/suggestions.rs:64:21
|
||||
|
|
||||
LL | let mut a = (1); // should suggest no `mut`, no parens
|
||||
LL | let mut a = (1);
|
||||
| ^^^ help: remove these parentheses
|
||||
|
|
||||
note: lint level defined here
|
||||
@ -11,7 +11,7 @@ LL | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issu
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
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
|
||||
--> $DIR/suggestions.rs:49:1
|
||||
--> $DIR/suggestions.rs:57:1
|
||||
|
|
||||
LL | #[no_debug] // should suggest removal of deprecated attribute
|
||||
| ^^^^^^^^^^^ help: remove this attribute
|
||||
@ -19,9 +19,9 @@ LL | #[no_debug] // should suggest removal of deprecated attribute
|
||||
= note: #[warn(deprecated)] on by default
|
||||
|
||||
warning: variable does not need to be mutable
|
||||
--> $DIR/suggestions.rs:54:13
|
||||
--> $DIR/suggestions.rs:64:13
|
||||
|
|
||||
LL | let mut a = (1); // should suggest no `mut`, no parens
|
||||
LL | let mut a = (1);
|
||||
| ----^
|
||||
| |
|
||||
| help: remove this `mut`
|
||||
@ -33,7 +33,7 @@ LL | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issu
|
||||
| ^^^^^^^^^^
|
||||
|
||||
warning: variable does not need to be mutable
|
||||
--> $DIR/suggestions.rs:58:13
|
||||
--> $DIR/suggestions.rs:70:13
|
||||
|
|
||||
LL | let mut
|
||||
| _____________^
|
||||
@ -47,7 +47,7 @@ LL | || b = 1;
|
||||
warning: static is marked #[no_mangle], but not exported
|
||||
--> $DIR/suggestions.rs:16:14
|
||||
|
|
||||
LL | #[no_mangle] static SHENZHOU: usize = 1; // should suggest `pub`
|
||||
LL | #[no_mangle] static SHENZHOU: usize = 1;
|
||||
| -^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| help: try making it public: `pub`
|
||||
@ -55,9 +55,9 @@ LL | #[no_mangle] static SHENZHOU: usize = 1; // should suggest `pub`
|
||||
= note: #[warn(private_no_mangle_statics)] on by default
|
||||
|
||||
error: const items should never be #[no_mangle]
|
||||
--> $DIR/suggestions.rs:18:14
|
||||
--> $DIR/suggestions.rs:19:14
|
||||
|
|
||||
LL | #[no_mangle] const DISCOVERY: usize = 1; // should suggest `pub static` rather than `const`
|
||||
LL | #[no_mangle] const DISCOVERY: usize = 1;
|
||||
| -----^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| help: try a static value: `pub static`
|
||||
@ -65,19 +65,20 @@ LL | #[no_mangle] const DISCOVERY: usize = 1; // should suggest `pub static` rat
|
||||
= note: #[deny(no_mangle_const_items)] on by default
|
||||
|
||||
warning: functions generic over types must be mangled
|
||||
--> $DIR/suggestions.rs:22:1
|
||||
--> $DIR/suggestions.rs:25:1
|
||||
|
|
||||
LL | #[no_mangle] // should suggest removal (generics can't be no-mangle)
|
||||
LL | #[no_mangle]
|
||||
| ------------ help: remove this attribute
|
||||
LL | //~^ HELP remove this attribute
|
||||
LL | pub fn defiant<T>(_t: T) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: #[warn(no_mangle_generic_items)] on by default
|
||||
|
||||
warning: function is marked #[no_mangle], but not exported
|
||||
--> $DIR/suggestions.rs:26:1
|
||||
--> $DIR/suggestions.rs:29:1
|
||||
|
|
||||
LL | fn rio_grande() {} // should suggest `pub`
|
||||
LL | fn rio_grande() {}
|
||||
| -^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| help: try making it public: `pub`
|
||||
@ -85,19 +86,23 @@ LL | fn rio_grande() {} // should suggest `pub`
|
||||
= note: #[warn(private_no_mangle_fns)] on by default
|
||||
|
||||
warning: static is marked #[no_mangle], but not exported
|
||||
--> $DIR/suggestions.rs:33:18
|
||||
--> $DIR/suggestions.rs:37:18
|
||||
|
|
||||
LL | #[no_mangle] pub static DAUNTLESS: bool = true;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try exporting the item with a `pub use` statement
|
||||
|
||||
warning: function is marked #[no_mangle], but not exported
|
||||
--> $DIR/suggestions.rs:35:18
|
||||
--> $DIR/suggestions.rs:40:18
|
||||
|
|
||||
LL | #[no_mangle] pub fn val_jean() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try exporting the item with a `pub use` statement
|
||||
|
||||
warning: static is marked #[no_mangle], but not exported
|
||||
--> $DIR/suggestions.rs:39:18
|
||||
--> $DIR/suggestions.rs:45:18
|
||||
|
|
||||
LL | #[no_mangle] pub(crate) static VETAR: bool = true;
|
||||
| ----------^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -105,7 +110,7 @@ LL | #[no_mangle] pub(crate) static VETAR: bool = true;
|
||||
| help: try making it public: `pub`
|
||||
|
||||
warning: function is marked #[no_mangle], but not exported
|
||||
--> $DIR/suggestions.rs:41:18
|
||||
--> $DIR/suggestions.rs:48:18
|
||||
|
|
||||
LL | #[no_mangle] pub(crate) fn crossfield() {}
|
||||
| ----------^^^^^^^^^^^^^^^^^^^
|
||||
@ -113,17 +118,17 @@ LL | #[no_mangle] pub(crate) fn crossfield() {}
|
||||
| help: try making it public: `pub`
|
||||
|
||||
warning: denote infinite loops with `loop { ... }`
|
||||
--> $DIR/suggestions.rs:52:5
|
||||
--> $DIR/suggestions.rs:61:5
|
||||
|
|
||||
LL | while true { // should suggest `loop`
|
||||
LL | while true {
|
||||
| ^^^^^^^^^^ help: use `loop`
|
||||
|
|
||||
= note: #[warn(while_true)] on by default
|
||||
|
||||
warning: the `warp_factor:` in this pattern is redundant
|
||||
--> $DIR/suggestions.rs:63:23
|
||||
--> $DIR/suggestions.rs:76:23
|
||||
|
|
||||
LL | Equinox { warp_factor: warp_factor } => {} // should suggest shorthand
|
||||
LL | Equinox { warp_factor: warp_factor } => {}
|
||||
| ------------^^^^^^^^^^^^
|
||||
| |
|
||||
| help: remove this
|
||||
|
Loading…
Reference in New Issue
Block a user