diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index f4159002eb38..96dcb458303f 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -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(); } } diff --git a/src/test/ui/lint/suggestions.rs b/src/test/ui/lint/suggestions.rs index 6c767bca74ae..4da2700cb9fd 100644 --- a/src/test/ui/lint/suggestions.rs +++ b/src/test/ui/lint/suggestions.rs @@ -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) {} //~^ 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); } diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr index adb4b8eb67d5..8e5dac8be782 100644 --- a/src/test/ui/lint/suggestions.stderr +++ b/src/test/ui/lint/suggestions.stderr @@ -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) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = 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