about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_lint/builtin.rs41
-rw-r--r--src/test/ui/lint/suggestions.rs6
-rw-r--r--src/test/ui/lint/suggestions.stderr28
3 files changed, 52 insertions, 23 deletions
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index a9ee1c8f176..f4159002eb3 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1177,6 +1177,23 @@ 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 suggestion = match vis.node {
+                hir::VisibilityInherited => {
+                    // inherited visibility is empty span at item start; need an extra space
+                    Some("pub ".to_owned())
+                },
+                hir::VisibilityRestricted { .. } |
+                hir::VisibilityCrate(_) => {
+                    Some("pub".to_owned())
+                },
+                hir::VisibilityPublic => None
+            };
+            if let Some(replacement) = suggestion {
+                err.span_suggestion(vis.span, "try making it public", replacement);
+            }
+        };
+
         match it.node {
             hir::ItemFn(.., ref generics, _) => {
                 if let Some(no_mangle_attr) = attr::find_by_name(&it.attrs, "no_mangle") {
@@ -1186,12 +1203,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);
-                        let insertion_span = it.span.shrink_to_lo();
-                        if it.vis.node == hir::VisibilityInherited {
-                            err.span_suggestion(insertion_span,
-                                                "try making it public",
-                                                "pub ".to_owned());
-                        }
+                        suggest_make_pub(&it.vis, &mut err);
                         err.emit();
                     }
                     for param in &generics.params {
@@ -1214,17 +1226,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
             }
             hir::ItemStatic(..) => {
                 if attr::contains_name(&it.attrs, "no_mangle") &&
-                   !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);
-                       let insertion_span = it.span.shrink_to_lo();
-                       if it.vis.node == hir::VisibilityInherited {
-                           err.span_suggestion(insertion_span,
-                                               "try making it public",
-                                               "pub ".to_owned());
-                       }
-                       err.emit();
-                }
+                    !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);
+                        err.emit();
+                    }
             }
             hir::ItemConst(..) => {
                 if attr::contains_name(&it.attrs, "no_mangle") {
diff --git a/src/test/ui/lint/suggestions.rs b/src/test/ui/lint/suggestions.rs
index e35675eacd8..6c767bca74a 100644
--- a/src/test/ui/lint/suggestions.rs
+++ b/src/test/ui/lint/suggestions.rs
@@ -34,6 +34,12 @@ mod badlands {
     //~^ WARN static is marked
     #[no_mangle] pub fn val_jean() {}
     //~^ WARN function is marked
+
+    // ... but we can suggest just-`pub` instead of restricted
+    #[no_mangle] pub(crate) static VETAR: bool = true;
+    //~^ WARN static is marked
+    #[no_mangle] pub(crate) fn crossfield() {}
+    //~^ WARN function is marked
 }
 
 struct Equinox {
diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr
index 84a2e4a91ec..adb4b8eb67d 100644
--- a/src/test/ui/lint/suggestions.stderr
+++ b/src/test/ui/lint/suggestions.stderr
@@ -1,5 +1,5 @@
 warning: unnecessary parentheses around assigned value
-  --> $DIR/suggestions.rs:48:21
+  --> $DIR/suggestions.rs:54:21
    |
 LL |         let mut a = (1); // should suggest no `mut`, no parens
    |                     ^^^ help: remove these parentheses
@@ -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:43:1
+  --> $DIR/suggestions.rs:49:1
    |
 LL | #[no_debug] // should suggest removal of deprecated attribute
    | ^^^^^^^^^^^ help: remove this attribute
@@ -19,7 +19,7 @@ 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:48:13
+  --> $DIR/suggestions.rs:54:13
    |
 LL |         let mut a = (1); // should suggest no `mut`, no parens
    |             ----^
@@ -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:52:13
+  --> $DIR/suggestions.rs:58:13
    |
 LL |            let mut
    |   _____________^
@@ -96,8 +96,24 @@ warning: function is marked #[no_mangle], but not exported
 LL |     #[no_mangle] pub fn val_jean() {}
    |                  ^^^^^^^^^^^^^^^^^^^^
 
+warning: static is marked #[no_mangle], but not exported
+  --> $DIR/suggestions.rs:39:18
+   |
+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
+   |
+LL |     #[no_mangle] pub(crate) fn crossfield() {}
+   |                  ----------^^^^^^^^^^^^^^^^^^^
+   |                  |
+   |                  help: try making it public: `pub`
+
 warning: denote infinite loops with `loop { ... }`
-  --> $DIR/suggestions.rs:46:5
+  --> $DIR/suggestions.rs:52:5
    |
 LL |     while true { // should suggest `loop`
    |     ^^^^^^^^^^ help: use `loop`
@@ -105,7 +121,7 @@ LL |     while true { // should suggest `loop`
    = note: #[warn(while_true)] on by default
 
 warning: the `warp_factor:` in this pattern is redundant
-  --> $DIR/suggestions.rs:57:23
+  --> $DIR/suggestions.rs:63:23
    |
 LL |             Equinox { warp_factor: warp_factor } => {} // should suggest shorthand
    |                       ------------^^^^^^^^^^^^