]> git.lizzy.rs Git - rust.git/commitdiff
don't make crazy suggestion for unreachable braced pub-use
authorZack M. Davis <code@zackmdavis.net>
Sun, 6 May 2018 05:14:33 +0000 (22:14 -0700)
committerZack M. Davis <code@zackmdavis.net>
Fri, 11 May 2018 03:48:18 +0000 (20:48 -0700)
The Higher Intermediate Representation doesn't have spans for visibility
keywords, so we were assuming that the first whitespace-delimited token
in the item span was the `pub` to be weakened. This doesn't work for
brace-grouped `use`s, which get lowered as if they were several
individual `use` statements, but with spans that only cover the braced
path-segments. Constructing a correct suggestion here presents some
challenges—until someone works those out, we can at least protect the
dignity of our compiler marking the suggestion for `use` items as
potentially incorrect.

This resolves #50455 (but again, it would be desirable in the future to
make a correct suggestion instead of copping out like this).

src/librustc_lint/builtin.rs
src/test/ui/lint/unreachable_pub-pub_crate.rs
src/test/ui/lint/unreachable_pub-pub_crate.stderr
src/test/ui/lint/unreachable_pub.rs
src/test/ui/lint/unreachable_pub.stderr

index 5102bfe766eeff2370e63610b3043b9fa2357797..251b95a6fcb7933ac484cb9d613113ef8421f6a3 100644 (file)
@@ -1287,32 +1287,27 @@ fn get_lints(&self) -> LintArray {
 
 impl UnreachablePub {
     fn perform_lint(&self, cx: &LateContext, what: &str, id: ast::NodeId,
-                    vis: &hir::Visibility, span: Span, exportable: bool) {
+                    vis: &hir::Visibility, span: Span, exportable: bool,
+                    mut applicability: Applicability) {
         if !cx.access_levels.is_reachable(id) && *vis == hir::Visibility::Public {
+            if span.ctxt().outer().expn_info().is_some() {
+                applicability = Applicability::MaybeIncorrect;
+            }
             let def_span = cx.tcx.sess.codemap().def_span(span);
             let mut err = cx.struct_span_lint(UNREACHABLE_PUB, def_span,
                                               &format!("unreachable `pub` {}", what));
-            // visibility is token at start of declaration (can be macro
-            // variable rather than literal `pub`)
+            // We are presuming that visibility is token at start of
+            // declaration (can be macro variable rather than literal `pub`)
             let pub_span = cx.tcx.sess.codemap().span_until_char(def_span, ' ');
             let replacement = if cx.tcx.features().crate_visibility_modifier {
                 "crate"
             } else {
                 "pub(crate)"
             }.to_owned();
-            let app = if span.ctxt().outer().expn_info().is_none() {
-                // even if macros aren't involved the suggestion
-                // may be incorrect -- the user may have mistakenly
-                // hidden it behind a private module and this lint is
-                // a helpful way to catch that. However, we're trying
-                // not to change the nature of the code with this lint
-                // so it's marked as machine applicable.
-                Applicability::MachineApplicable
-            } else {
-                Applicability::MaybeIncorrect
-            };
-            err.span_suggestion_with_applicability(pub_span, "consider restricting its visibility",
-                                                   replacement, app);
+            err.span_suggestion_with_applicability(pub_span,
+                                                   "consider restricting its visibility",
+                                                   replacement,
+                                                   applicability);
             if exportable {
                 err.help("or consider exporting it for use by other crates");
             }
@@ -1321,21 +1316,31 @@ fn perform_lint(&self, cx: &LateContext, what: &str, id: ast::NodeId,
     }
 }
 
+
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub {
     fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
-        self.perform_lint(cx, "item", item.id, &item.vis, item.span, true);
+        let applicability = match item.node {
+            // suggestion span-manipulation is inadequate for `pub use
+            // module::{item}` (Issue #50455)
+            hir::ItemUse(..) => Applicability::MaybeIncorrect,
+            _ => Applicability::MachineApplicable,
+        };
+        self.perform_lint(cx, "item", item.id, &item.vis, item.span, true, applicability);
     }
 
     fn check_foreign_item(&mut self, cx: &LateContext, foreign_item: &hir::ForeignItem) {
-        self.perform_lint(cx, "item", foreign_item.id, &foreign_item.vis, foreign_item.span, true);
+        self.perform_lint(cx, "item", foreign_item.id, &foreign_item.vis,
+                          foreign_item.span, true, Applicability::MachineApplicable);
     }
 
     fn check_struct_field(&mut self, cx: &LateContext, field: &hir::StructField) {
-        self.perform_lint(cx, "field", field.id, &field.vis, field.span, false);
+        self.perform_lint(cx, "field", field.id, &field.vis, field.span, false,
+                          Applicability::MachineApplicable);
     }
 
     fn check_impl_item(&mut self, cx: &LateContext, impl_item: &hir::ImplItem) {
-        self.perform_lint(cx, "item", impl_item.id, &impl_item.vis, impl_item.span, false);
+        self.perform_lint(cx, "item", impl_item.id, &impl_item.vis, impl_item.span, false,
+                          Applicability::MachineApplicable);
     }
 }
 
index f5e6b4d3b48622d2a30b591490f41c3407a6ea07..0a1926f8ae56a11dd9ad7f91881d37c3827cbbde 100644 (file)
@@ -24,6 +24,7 @@
 mod private_mod {
     // non-leaked `pub` items in private module should be linted
     pub use std::fmt;
+    pub use std::env::{Args}; // braced-use has different item spans than unbraced
 
     pub struct Hydrogen {
         // `pub` struct fields, too
index d1711be456bcc1667babc691e12d6ea7e376a4ed..2948deb23009c64b62b33b56fa7a380974aae3b3 100644 (file)
@@ -14,7 +14,15 @@ LL | #![warn(unreachable_pub)]
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:28:5
+  --> $DIR/unreachable_pub-pub_crate.rs:27:24
+   |
+LL |     pub use std::env::{Args}; // braced-use has different item spans than unbraced
+   |                        ^^^^ help: consider restricting its visibility: `pub(crate)`
+   |
+   = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+  --> $DIR/unreachable_pub-pub_crate.rs:29:5
    |
 LL |     pub struct Hydrogen {
    |     ---^^^^^^^^^^^^^^^^
@@ -24,7 +32,7 @@ LL |     pub struct Hydrogen {
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` field
-  --> $DIR/unreachable_pub-pub_crate.rs:30:9
+  --> $DIR/unreachable_pub-pub_crate.rs:31:9
    |
 LL |         pub neutrons: usize,
    |         ---^^^^^^^^^^^^^^^^
@@ -32,7 +40,7 @@ LL |         pub neutrons: usize,
    |         help: consider restricting its visibility: `pub(crate)`
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:36:9
+  --> $DIR/unreachable_pub-pub_crate.rs:37:9
    |
 LL |         pub fn count_neutrons(&self) -> usize { self.neutrons }
    |         ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +48,7 @@ LL |         pub fn count_neutrons(&self) -> usize { self.neutrons }
    |         help: consider restricting its visibility: `pub(crate)`
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:40:5
+  --> $DIR/unreachable_pub-pub_crate.rs:41:5
    |
 LL |     pub enum Helium {}
    |     ---^^^^^^^^^^^^
@@ -50,7 +58,7 @@ LL |     pub enum Helium {}
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:41:5
+  --> $DIR/unreachable_pub-pub_crate.rs:42:5
    |
 LL |     pub union Lithium { c1: usize, c2: u8 }
    |     ---^^^^^^^^^^^^^^
@@ -60,7 +68,7 @@ LL |     pub union Lithium { c1: usize, c2: u8 }
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:42:5
+  --> $DIR/unreachable_pub-pub_crate.rs:43:5
    |
 LL |     pub fn beryllium() {}
    |     ---^^^^^^^^^^^^^^^
@@ -70,7 +78,7 @@ LL |     pub fn beryllium() {}
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:43:5
+  --> $DIR/unreachable_pub-pub_crate.rs:44:5
    |
 LL |     pub trait Boron {}
    |     ---^^^^^^^^^^^^
@@ -80,7 +88,7 @@ LL |     pub trait Boron {}
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:44:5
+  --> $DIR/unreachable_pub-pub_crate.rs:45:5
    |
 LL |     pub const CARBON: usize = 1;
    |     ---^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -90,7 +98,7 @@ LL |     pub const CARBON: usize = 1;
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:45:5
+  --> $DIR/unreachable_pub-pub_crate.rs:46:5
    |
 LL |     pub static NITROGEN: usize = 2;
    |     ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -100,7 +108,7 @@ LL |     pub static NITROGEN: usize = 2;
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:46:5
+  --> $DIR/unreachable_pub-pub_crate.rs:47:5
    |
 LL |     pub type Oxygen = bool;
    |     ---^^^^^^^^^^^^^^^^^^^^
@@ -110,7 +118,7 @@ LL |     pub type Oxygen = bool;
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:49:47
+  --> $DIR/unreachable_pub-pub_crate.rs:50:47
    |
 LL |         ($visibility: vis, $name: ident) => { $visibility struct $name {} }
    |                                               -----------^^^^^^^^^^^^^
@@ -123,7 +131,7 @@ LL |     define_empty_struct_with_visibility!(pub, Fluorine);
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:54:9
+  --> $DIR/unreachable_pub-pub_crate.rs:55:9
    |
 LL |         pub fn catalyze() -> bool;
    |         ---^^^^^^^^^^^^^^^^^^^^^^^
index 347579c3e7bb93df13e9d262e7d6561241d1e9a1..5bb67670d85c2ae6f9bcfa708e28c944ed82f2c4 100644 (file)
@@ -19,6 +19,7 @@
 mod private_mod {
     // non-leaked `pub` items in private module should be linted
     pub use std::fmt;
+    pub use std::env::{Args}; // braced-use has different item spans than unbraced
 
     pub struct Hydrogen {
         // `pub` struct fields, too
index 1d693161108db03fe6d319e84de76c90d3c94d6e..ad88c55d54013a92c97697454bdfcfcac7ef4fb4 100644 (file)
@@ -14,7 +14,15 @@ LL | #![warn(unreachable_pub)]
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:23:5
+  --> $DIR/unreachable_pub.rs:22:24
+   |
+LL |     pub use std::env::{Args}; // braced-use has different item spans than unbraced
+   |                        ^^^^ help: consider restricting its visibility: `crate`
+   |
+   = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+  --> $DIR/unreachable_pub.rs:24:5
    |
 LL |     pub struct Hydrogen {
    |     ---^^^^^^^^^^^^^^^^
@@ -24,7 +32,7 @@ LL |     pub struct Hydrogen {
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` field
-  --> $DIR/unreachable_pub.rs:25:9
+  --> $DIR/unreachable_pub.rs:26:9
    |
 LL |         pub neutrons: usize,
    |         ---^^^^^^^^^^^^^^^^
@@ -32,7 +40,7 @@ LL |         pub neutrons: usize,
    |         help: consider restricting its visibility: `crate`
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:31:9
+  --> $DIR/unreachable_pub.rs:32:9
    |
 LL |         pub fn count_neutrons(&self) -> usize { self.neutrons }
    |         ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +48,7 @@ LL |         pub fn count_neutrons(&self) -> usize { self.neutrons }
    |         help: consider restricting its visibility: `crate`
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:35:5
+  --> $DIR/unreachable_pub.rs:36:5
    |
 LL |     pub enum Helium {}
    |     ---^^^^^^^^^^^^
@@ -50,7 +58,7 @@ LL |     pub enum Helium {}
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:36:5
+  --> $DIR/unreachable_pub.rs:37:5
    |
 LL |     pub union Lithium { c1: usize, c2: u8 }
    |     ---^^^^^^^^^^^^^^
@@ -60,7 +68,7 @@ LL |     pub union Lithium { c1: usize, c2: u8 }
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:37:5
+  --> $DIR/unreachable_pub.rs:38:5
    |
 LL |     pub fn beryllium() {}
    |     ---^^^^^^^^^^^^^^^
@@ -70,7 +78,7 @@ LL |     pub fn beryllium() {}
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:38:5
+  --> $DIR/unreachable_pub.rs:39:5
    |
 LL |     pub trait Boron {}
    |     ---^^^^^^^^^^^^
@@ -80,7 +88,7 @@ LL |     pub trait Boron {}
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:39:5
+  --> $DIR/unreachable_pub.rs:40:5
    |
 LL |     pub const CARBON: usize = 1;
    |     ---^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -90,7 +98,7 @@ LL |     pub const CARBON: usize = 1;
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:40:5
+  --> $DIR/unreachable_pub.rs:41:5
    |
 LL |     pub static NITROGEN: usize = 2;
    |     ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -100,7 +108,7 @@ LL |     pub static NITROGEN: usize = 2;
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:41:5
+  --> $DIR/unreachable_pub.rs:42:5
    |
 LL |     pub type Oxygen = bool;
    |     ---^^^^^^^^^^^^^^^^^^^^
@@ -110,7 +118,7 @@ LL |     pub type Oxygen = bool;
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:44:47
+  --> $DIR/unreachable_pub.rs:45:47
    |
 LL |         ($visibility: vis, $name: ident) => { $visibility struct $name {} }
    |                                               -----------^^^^^^^^^^^^^
@@ -123,7 +131,7 @@ LL |     define_empty_struct_with_visibility!(pub, Fluorine);
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:49:9
+  --> $DIR/unreachable_pub.rs:50:9
    |
 LL |         pub fn catalyze() -> bool;
    |         ---^^^^^^^^^^^^^^^^^^^^^^^