]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/attrs.rs
Auto merge of #4551 - mikerite:fix-ice-reporting, r=llogiq
[rust.git] / clippy_lints / src / attrs.rs
index 58cd2bca95978e935f2c4643b0a3224c2a3465c8..a4b411d751998ec3f897373929ee52190d40c9f5 100644 (file)
@@ -2,7 +2,7 @@
 
 use crate::reexport::*;
 use crate::utils::{
-    in_macro, is_present_in_source, last_line_of_span, paths, snippet_opt, span_lint, span_lint_and_sugg,
+    is_present_in_source, last_line_of_span, match_def_path, paths, snippet_opt, span_lint, span_lint_and_sugg,
     span_lint_and_then, without_block_comments,
 };
 use if_chain::if_chain;
@@ -17,6 +17,7 @@
 use semver::Version;
 use syntax::ast::{AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
 use syntax::source_map::Span;
+use syntax_pos::symbol::Symbol;
 
 declare_clippy_lint! {
     /// **What it does:** Checks for items annotated with `#[inline(always)]`,
@@ -48,9 +49,9 @@
     /// **What it does:** Checks for `extern crate` and `use` items annotated with
     /// lint attributes.
     ///
-    /// This lint whitelists `#[allow(unused_imports)]` and `#[allow(deprecated)]` on
-    /// `use` items and `#[allow(unused_imports)]` on `extern crate` items with a
-    /// `#[macro_use]` attribute.
+    /// This lint whitelists `#[allow(unused_imports)]`, `#[allow(deprecated)]` and
+    /// `#[allow(unreachable_pub)]` on `use` items and `#[allow(unused_imports)]` on
+    /// `extern crate` items with a `#[macro_use]` attribute.
     ///
     /// **Why is this bad?** Lint attributes have no effect on crate imports. Most
     /// likely a `!` was forgotten.
     ///
     /// **Example:**
     /// ```rust
-    /// // Bad
-    /// #[inline(always)]
-    ///
-    /// fn not_quite_good_code(..) { ... }
-    ///
     /// // Good (as inner attribute)
     /// #![inline(always)]
     ///
-    /// fn this_is_fine(..) { ... }
+    /// fn this_is_fine() { }
+    ///
+    /// // Bad
+    /// #[inline(always)]
+    ///
+    /// fn not_quite_good_code() { }
     ///
     /// // Good (as outer attribute)
     /// #[inline(always)]
-    /// fn this_is_fine_too(..) { ... }
+    /// fn this_is_fine_too() { }
     /// ```
     pub EMPTY_LINE_AFTER_OUTER_ATTR,
     nursery,
 
 declare_clippy_lint! {
     /// **What it does:** Checks for `allow`/`warn`/`deny`/`forbid` attributes with scoped clippy
-    /// lints and if those lints exist in clippy. If there is a uppercase letter in the lint name
+    /// lints and if those lints exist in clippy. If there is an uppercase letter in the lint name
     /// (not the tool name) and a lowercase version of this lint exists, it will suggest to lowercase
     /// the lint name.
     ///
@@ -205,14 +206,14 @@ fn check_attribute(&mut self, cx: &LateContext<'a, 'tcx>, attr: &'tcx Attribute)
                     },
                     _ => {},
                 }
-                if items.is_empty() || !attr.check_name("deprecated") {
+                if items.is_empty() || !attr.check_name(sym!(deprecated)) {
                     return;
                 }
                 for item in items {
                     if_chain! {
                         if let NestedMetaItem::MetaItem(mi) = &item;
                         if let MetaItemKind::NameValue(lit) = &mi.node;
-                        if mi.check_name("since");
+                        if mi.check_name(sym!(since));
                         then {
                             check_semver(cx, item.span(), lit);
                         }
@@ -228,7 +229,7 @@ fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
         }
         match item.node {
             ItemKind::ExternCrate(..) | ItemKind::Use(..) => {
-                let skip_unused_imports = item.attrs.iter().any(|attr| attr.check_name("macro_use"));
+                let skip_unused_imports = item.attrs.iter().any(|attr| attr.check_name(sym!(macro_use)));
 
                 for attr in &item.attrs {
                     if in_external_macro(cx.sess(), attr.span) {
@@ -238,20 +239,23 @@ fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
                         if let Some(ident) = attr.ident() {
                             match &*ident.as_str() {
                                 "allow" | "warn" | "deny" | "forbid" => {
-                                    // whitelist `unused_imports` and `deprecated` for `use` items
+                                    // whitelist `unused_imports`, `deprecated` and `unreachable_pub` for `use` items
                                     // and `unused_imports` for `extern crate` items with `macro_use`
                                     for lint in lint_list {
                                         match item.node {
                                             ItemKind::Use(..) => {
-                                                if is_word(lint, "unused_imports") || is_word(lint, "deprecated") {
+                                                if is_word(lint, sym!(unused_imports))
+                                                    || is_word(lint, sym!(deprecated))
+                                                    || is_word(lint, sym!(unreachable_pub))
+                                                {
                                                     return;
                                                 }
                                             },
                                             ItemKind::ExternCrate(..) => {
-                                                if is_word(lint, "unused_imports") && skip_unused_imports {
+                                                if is_word(lint, sym!(unused_imports)) && skip_unused_imports {
                                                     return;
                                                 }
-                                                if is_word(lint, "unused_extern_crates") {
+                                                if is_word(lint, sym!(unused_extern_crates)) {
                                                     return;
                                                 }
                                             },
@@ -273,7 +277,7 @@ fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
                                                         line_span,
                                                         "if you just forgot a `!`, use",
                                                         sugg,
-                                                        Applicability::MachineApplicable,
+                                                        Applicability::MaybeIncorrect,
                                                     );
                                                 },
                                             );
@@ -315,7 +319,7 @@ fn check_clippy_lint_names(cx: &LateContext<'_, '_>, items: &[NestedMetaItem]) {
             let name = meta_item.path.segments.last().unwrap().ident.name;
             if let CheckLintNameResult::Tool(Err((None, _))) = lint_store.check_lint_name(
                 &name.as_str(),
-                Some(tool_name.as_str()),
+                Some(tool_name.name),
             );
             then {
                 span_lint_and_then(
@@ -328,7 +332,7 @@ fn check_clippy_lint_names(cx: &LateContext<'_, '_>, items: &[NestedMetaItem]) {
                             let name_lower = name.as_str().to_lowercase();
                             match lint_store.check_lint_name(
                                 &name_lower,
-                                Some(tool_name.as_str())
+                                Some(tool_name.name)
                             ) {
                                 // FIXME: can we suggest similar lint names here?
                                 // https://github.com/rust-lang/rust/pull/56992
@@ -395,7 +399,7 @@ fn is_relevant_expr(cx: &LateContext<'_, '_>, tables: &ty::TypeckTables<'_>, exp
         ExprKind::Call(path_expr, _) => {
             if let ExprKind::Path(qpath) = &path_expr.node {
                 if let Some(fun_id) = tables.qpath_res(qpath, path_expr.hir_id).opt_def_id() {
-                    !cx.match_def_path(fun_id, &paths::BEGIN_PANIC)
+                    !match_def_path(cx, fun_id, &paths::BEGIN_PANIC)
                 } else {
                     true
                 }
@@ -408,7 +412,7 @@ fn is_relevant_expr(cx: &LateContext<'_, '_>, tables: &ty::TypeckTables<'_>, exp
 }
 
 fn check_attrs(cx: &LateContext<'_, '_>, span: Span, name: Name, attrs: &[Attribute]) {
-    if in_macro(span) {
+    if span.from_expansion() {
         return;
     }
 
@@ -441,10 +445,10 @@ fn check_attrs(cx: &LateContext<'_, '_>, span: Span, name: Name, attrs: &[Attrib
         }
 
         if let Some(values) = attr.meta_item_list() {
-            if values.len() != 1 || !attr.check_name("inline") {
+            if values.len() != 1 || !attr.check_name(sym!(inline)) {
                 continue;
             }
-            if is_word(&values[0], "always") {
+            if is_word(&values[0], sym!(always)) {
                 span_lint(
                     cx,
                     INLINE_ALWAYS,
@@ -473,7 +477,7 @@ fn check_semver(cx: &LateContext<'_, '_>, span: Span, lit: &Lit) {
     );
 }
 
-fn is_word(nmi: &NestedMetaItem, expected: &str) -> bool {
+fn is_word(nmi: &NestedMetaItem, expected: Symbol) -> bool {
     if let NestedMetaItem::MetaItem(mi) = &nmi {
         mi.is_word() && mi.check_name(expected)
     } else {
@@ -487,16 +491,16 @@ impl EarlyLintPass for DeprecatedCfgAttribute {
     fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
         if_chain! {
             // check cfg_attr
-            if attr.check_name("cfg_attr");
+            if attr.check_name(sym!(cfg_attr));
             if let Some(items) = attr.meta_item_list();
             if items.len() == 2;
             // check for `rustfmt`
             if let Some(feature_item) = items[0].meta_item();
-            if feature_item.check_name("rustfmt");
+            if feature_item.check_name(sym!(rustfmt));
             // check for `rustfmt_skip` and `rustfmt::skip`
             if let Some(skip_item) = &items[1].meta_item();
-            if skip_item.check_name("rustfmt_skip") ||
-                skip_item.path.segments.last().expect("empty path in attribute").ident.name == "skip";
+            if skip_item.check_name(sym!(rustfmt_skip)) ||
+                skip_item.path.segments.last().expect("empty path in attribute").ident.name == sym!(skip);
             // Only lint outer attributes, because custom inner attributes are unstable
             // Tracking issue: https://github.com/rust-lang/rust/issues/54726
             if let AttrStyle::Outer = attr.style;