about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2021-02-02 20:43:30 -0800
committerManish Goregaokar <manishsmail@gmail.com>2021-02-02 20:43:30 -0800
commitc8cb90abbdff45cd936272903f14990bdcefc1cf (patch)
tree69cad02118814662fdf4c17f69e6737088521f5f
parentb56b751055a9c05e3bcbf1740865e2dc7f1ae872 (diff)
downloadrust-c8cb90abbdff45cd936272903f14990bdcefc1cf.tar.gz
rust-c8cb90abbdff45cd936272903f14990bdcefc1cf.zip
Merge commit '3e4179766bcecd712824da04356621b8df012ea4' into sync-from-clippy
-rw-r--r--CHANGELOG.md1
-rw-r--r--CONTRIBUTING.md9
-rw-r--r--clippy_dev/src/bless.rs3
-rw-r--r--clippy_dev/src/fmt.rs23
-rw-r--r--clippy_dev/src/lib.rs13
-rw-r--r--clippy_dev/src/ra_setup.rs3
-rw-r--r--clippy_dev/src/serve.rs3
-rw-r--r--clippy_lints/src/doc.rs125
-rw-r--r--clippy_lints/src/excessive_bools.rs8
-rw-r--r--clippy_lints/src/exhaustive_items.rs10
-rw-r--r--clippy_lints/src/lib.rs2
-rw-r--r--clippy_lints/src/matches.rs12
-rw-r--r--clippy_lints/src/utils/ast_utils.rs15
-rw-r--r--clippy_lints/src/utils/diagnostics.rs2
-rw-r--r--clippy_lints/src/utils/internal_lints.rs6
-rw-r--r--clippy_lints/src/utils/mod.rs31
-rw-r--r--clippy_lints/src/write.rs6
-rw-r--r--doc/adding_lints.md10
-rw-r--r--doc/basics.md2
-rw-r--r--mini-macro/src/lib.rs3
-rw-r--r--rust-toolchain2
-rw-r--r--tests/ui/doc_panics.rs95
-rw-r--r--tests/ui/doc_panics.stderr67
-rw-r--r--tests/ui/exhaustive_items.fixed23
-rw-r--r--tests/ui/exhaustive_items.rs23
-rw-r--r--tests/ui/exhaustive_items.stderr4
-rw-r--r--tests/ui/let_and_return.rs12
-rw-r--r--tests/ui/let_and_return.stderr2
-rw-r--r--tests/ui/match_overlapping_arm.rs30
-rw-r--r--tests/ui/match_overlapping_arm.stderr32
-rw-r--r--tests/ui/should_impl_trait/corner_cases.rs3
-rw-r--r--tests/ui/should_impl_trait/method_list_1.rs3
-rw-r--r--tests/ui/should_impl_trait/method_list_1.stderr28
-rw-r--r--tests/ui/should_impl_trait/method_list_2.rs3
-rw-r--r--tests/ui/should_impl_trait/method_list_2.stderr30
35 files changed, 518 insertions, 126 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dadb6832d1f..c1032204a22 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2079,6 +2079,7 @@ Released 2018-09-13
 [`missing_docs_in_private_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items
 [`missing_errors_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc
 [`missing_inline_in_public_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_inline_in_public_items
+[`missing_panics_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc
 [`missing_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc
 [`mistyped_literal_suffixes`]: https://rust-lang.github.io/rust-clippy/master/index.html#mistyped_literal_suffixes
 [`mixed_case_hex_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_case_hex_literals
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f2641a23f56..5954ab25d19 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -46,11 +46,12 @@ first read the [Basics docs](doc/basics.md).**
 
 ### Finding something to fix/improve
 
-All issues on Clippy are mentored, if you want help with a bug just ask
-@Manishearth, @flip1995, @phansch or @yaahc.
+All issues on Clippy are mentored, if you want help simply ask @Manishearth, @flip1995, @phansch
+or @llogiq directly by mentioning them in the issue or over on [Zulip]. This list may be out of date.
+All currently active mentors can be found [here](https://github.com/rust-lang/highfive/blob/master/highfive/configs/rust-lang/rust-clippy.json#L3)
 
-Some issues are easier than others. The [`good-first-issue`] label can be used to find the easy issues.
-If you want to work on an issue, please leave a comment so that we can assign it to you!
+Some issues are easier than others. The [`good-first-issue`] label can be used to find the easy
+issues. You can use `@rustbot claim` to assign the issue to yourself.
 
 There are also some abandoned PRs, marked with [`S-inactive-closed`].
 Pretty often these PRs are nearly completed and just need some extra steps
diff --git a/clippy_dev/src/bless.rs b/clippy_dev/src/bless.rs
index b877806946c..2a869e9d449 100644
--- a/clippy_dev/src/bless.rs
+++ b/clippy_dev/src/bless.rs
@@ -24,6 +24,9 @@ static CLIPPY_BUILD_TIME: SyncLazy<Option<std::time::SystemTime>> = SyncLazy::ne
     fs::metadata(path).ok()?.modified().ok()
 });
 
+/// # Panics
+///
+/// Panics if the path to a test file is broken
 pub fn bless(ignore_timestamp: bool) {
     let test_suite_dirs = [
         clippy_project_root().join("tests").join("ui"),
diff --git a/clippy_dev/src/fmt.rs b/clippy_dev/src/fmt.rs
index 6b528d219df..4d0fdadbd85 100644
--- a/clippy_dev/src/fmt.rs
+++ b/clippy_dev/src/fmt.rs
@@ -8,7 +8,7 @@ use walkdir::WalkDir;
 
 #[derive(Debug)]
 pub enum CliError {
-    CommandFailed(String),
+    CommandFailed(String, String),
     IoError(io::Error),
     RustfmtNotInstalled,
     WalkDirError(walkdir::Error),
@@ -75,8 +75,8 @@ pub fn run(check: bool, verbose: bool) {
 
     fn output_err(err: CliError) {
         match err {
-            CliError::CommandFailed(command) => {
-                eprintln!("error: A command failed! `{}`", command);
+            CliError::CommandFailed(command, stderr) => {
+                eprintln!("error: A command failed! `{}`\nstderr: {}", command, stderr);
             },
             CliError::IoError(err) => {
                 eprintln!("error: {}", err);
@@ -136,12 +136,16 @@ fn exec(
         println!("{}", format_command(&program, &dir, args));
     }
 
-    let mut child = Command::new(&program).current_dir(&dir).args(args.iter()).spawn()?;
-    let code = child.wait()?;
-    let success = code.success();
+    let child = Command::new(&program).current_dir(&dir).args(args.iter()).spawn()?;
+    let output = child.wait_with_output()?;
+    let success = output.status.success();
 
     if !context.check && !success {
-        return Err(CliError::CommandFailed(format_command(&program, &dir, args)));
+        let stderr = std::str::from_utf8(&output.stderr).unwrap_or("");
+        return Err(CliError::CommandFailed(
+            format_command(&program, &dir, args),
+            String::from(stderr),
+        ));
     }
 
     Ok(success)
@@ -177,7 +181,10 @@ fn rustfmt_test(context: &FmtContext) -> Result<(), CliError> {
     {
         Err(CliError::RustfmtNotInstalled)
     } else {
-        Err(CliError::CommandFailed(format_command(&program, &dir, args)))
+        Err(CliError::CommandFailed(
+            format_command(&program, &dir, args),
+            std::str::from_utf8(&output.stderr).unwrap_or("").to_string(),
+        ))
     }
 }
 
diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs
index 24d70d433f3..01d1fc9211a 100644
--- a/clippy_dev/src/lib.rs
+++ b/clippy_dev/src/lib.rs
@@ -236,6 +236,10 @@ pub struct FileChange {
 /// `path` is the relative path to the file on which you want to perform the replacement.
 ///
 /// See `replace_region_in_text` for documentation of the other options.
+///
+/// # Panics
+///
+/// Panics if the path could not read or then written
 pub fn replace_region_in_file<F>(
     path: &Path,
     start: &str,
@@ -283,6 +287,10 @@ where
 ///     .new_lines;
 /// assert_eq!("replace_start\na different\ntext\nreplace_end", result);
 /// ```
+///
+/// # Panics
+///
+/// Panics if start or end is not valid regex
 pub fn replace_region_in_text<F>(text: &str, start: &str, end: &str, replace_start: bool, replacements: F) -> FileChange
 where
     F: FnOnce() -> Vec<String>,
@@ -329,6 +337,11 @@ where
 }
 
 /// Returns the path to the Clippy project directory
+///
+/// # Panics
+///
+/// Panics if the current directory could not be retrieved, there was an error reading any of the
+/// Cargo.toml files or ancestor directory is the clippy root directory
 #[must_use]
 pub fn clippy_project_root() -> PathBuf {
     let current_dir = std::env::current_dir().unwrap();
diff --git a/clippy_dev/src/ra_setup.rs b/clippy_dev/src/ra_setup.rs
index a8a6a2cb1bd..a3c329b578b 100644
--- a/clippy_dev/src/ra_setup.rs
+++ b/clippy_dev/src/ra_setup.rs
@@ -8,6 +8,9 @@ use std::path::{Path, PathBuf};
 // This allows rust analyzer to analyze rustc internals and show proper information inside clippy
 // code. See https://github.com/rust-analyzer/rust-analyzer/issues/3517 and https://github.com/rust-lang/rust-clippy/issues/5514 for details
 
+/// # Panics
+///
+/// Panics if `rustc_path` does not lead to a rustc repo or the files could not be read
 pub fn run(rustc_path: Option<&str>) {
     // we can unwrap here because the arg is required by clap
     let rustc_path = PathBuf::from(rustc_path.unwrap());
diff --git a/clippy_dev/src/serve.rs b/clippy_dev/src/serve.rs
index a46c0e4d3f0..faa94859601 100644
--- a/clippy_dev/src/serve.rs
+++ b/clippy_dev/src/serve.rs
@@ -4,6 +4,9 @@ use std::process::Command;
 use std::thread;
 use std::time::{Duration, SystemTime};
 
+/// # Panics
+///
+/// Panics if the python commands could not be spawned
 pub fn run(port: u16, lint: Option<&str>) -> ! {
     let mut url = Some(match lint {
         None => format!("http://localhost:{}", port),
diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs
index fa0289c977c..75e71eb1e4c 100644
--- a/clippy_lints/src/doc.rs
+++ b/clippy_lints/src/doc.rs
@@ -1,4 +1,7 @@
-use crate::utils::{implements_trait, is_entrypoint_fn, is_type_diagnostic_item, return_ty, span_lint};
+use crate::utils::{
+    implements_trait, is_entrypoint_fn, is_type_diagnostic_item, match_panic_def_id, method_chain_args, return_ty,
+    span_lint, span_lint_and_note,
+};
 use if_chain::if_chain;
 use itertools::Itertools;
 use rustc_ast::ast::{Async, AttrKind, Attribute, FnKind, FnRetTy, ItemKind};
@@ -8,7 +11,10 @@ use rustc_data_structures::sync::Lrc;
 use rustc_errors::emitter::EmitterWriter;
 use rustc_errors::Handler;
 use rustc_hir as hir;
+use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
+use rustc_hir::{Expr, ExprKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::hir::map::Map;
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_parse::maybe_new_parser_from_source_str;
@@ -123,6 +129,37 @@ declare_clippy_lint! {
 }
 
 declare_clippy_lint! {
+    /// **What it does:** Checks the doc comments of publicly visible functions that
+    /// may panic and warns if there is no `# Panics` section.
+    ///
+    /// **Why is this bad?** Documenting the scenarios in which panicking occurs
+    /// can help callers who do not want to panic to avoid those situations.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Examples:**
+    ///
+    /// Since the following function may panic it has a `# Panics` section in
+    /// its doc comment:
+    ///
+    /// ```rust
+    /// /// # Panics
+    /// ///
+    /// /// Will panic if y is 0
+    /// pub fn divide_by(x: i32, y: i32) -> i32 {
+    ///     if y == 0 {
+    ///         panic!("Cannot divide by 0")
+    ///     } else {
+    ///         x / y
+    ///     }
+    /// }
+    /// ```
+    pub MISSING_PANICS_DOC,
+    pedantic,
+    "`pub fn` may panic without `# Panics` in doc comment"
+}
+
+declare_clippy_lint! {
     /// **What it does:** Checks for `fn main() { .. }` in doctests
     ///
     /// **Why is this bad?** The test can be shorter (and likely more readable)
@@ -166,7 +203,9 @@ impl DocMarkdown {
     }
 }
 
-impl_lint_pass!(DocMarkdown => [DOC_MARKDOWN, MISSING_SAFETY_DOC, MISSING_ERRORS_DOC, NEEDLESS_DOCTEST_MAIN]);
+impl_lint_pass!(DocMarkdown =>
+    [DOC_MARKDOWN, MISSING_SAFETY_DOC, MISSING_ERRORS_DOC, MISSING_PANICS_DOC, NEEDLESS_DOCTEST_MAIN]
+);
 
 impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
     fn check_crate(&mut self, cx: &LateContext<'tcx>, krate: &'tcx hir::Crate<'_>) {
@@ -180,7 +219,15 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
                 if !(is_entrypoint_fn(cx, cx.tcx.hir().local_def_id(item.hir_id).to_def_id())
                     || in_external_macro(cx.tcx.sess, item.span))
                 {
-                    lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers, Some(body_id));
+                    let body = cx.tcx.hir().body(body_id);
+                    let impl_item_def_id = cx.tcx.hir().local_def_id(item.hir_id);
+                    let mut fpu = FindPanicUnwrap {
+                        cx,
+                        typeck_results: cx.tcx.typeck(impl_item_def_id),
+                        panic_span: None,
+                    };
+                    fpu.visit_expr(&body.value);
+                    lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers, Some(body_id), fpu.panic_span);
                 }
             },
             hir::ItemKind::Impl(ref impl_) => {
@@ -200,7 +247,7 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
         let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
         if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
             if !in_external_macro(cx.tcx.sess, item.span) {
-                lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers, None);
+                lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers, None, None);
             }
         }
     }
@@ -211,7 +258,15 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
             return;
         }
         if let hir::ImplItemKind::Fn(ref sig, body_id) = item.kind {
-            lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers, Some(body_id));
+            let body = cx.tcx.hir().body(body_id);
+            let impl_item_def_id = cx.tcx.hir().local_def_id(item.hir_id);
+            let mut fpu = FindPanicUnwrap {
+                cx,
+                typeck_results: cx.tcx.typeck(impl_item_def_id),
+                panic_span: None,
+            };
+            fpu.visit_expr(&body.value);
+            lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers, Some(body_id), fpu.panic_span);
         }
     }
 }
@@ -223,6 +278,7 @@ fn lint_for_missing_headers<'tcx>(
     sig: &hir::FnSig<'_>,
     headers: DocHeaders,
     body_id: Option<hir::BodyId>,
+    panic_span: Option<Span>,
 ) {
     if !cx.access_levels.is_exported(hir_id) {
         return; // Private functions do not require doc comments
@@ -235,6 +291,16 @@ fn lint_for_missing_headers<'tcx>(
             "unsafe function's docs miss `# Safety` section",
         );
     }
+    if !headers.panics && panic_span.is_some() {
+        span_lint_and_note(
+            cx,
+            MISSING_PANICS_DOC,
+            span,
+            "docs for function which may panic missing `# Panics` section",
+            panic_span,
+            "first possible panic found here",
+        );
+    }
     if !headers.errors {
         if is_type_diagnostic_item(cx, return_ty(cx, hir_id), sym::result_type) {
             span_lint(
@@ -321,6 +387,7 @@ pub fn strip_doc_comment_decoration(doc: &str, comment_kind: CommentKind, span:
 struct DocHeaders {
     safety: bool,
     errors: bool,
+    panics: bool,
 }
 
 fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &'a [Attribute]) -> DocHeaders {
@@ -338,6 +405,7 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
             return DocHeaders {
                 safety: true,
                 errors: true,
+                panics: true,
             };
         }
     }
@@ -353,6 +421,7 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
         return DocHeaders {
             safety: false,
             errors: false,
+            panics: false,
         };
     }
 
@@ -394,6 +463,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
     let mut headers = DocHeaders {
         safety: false,
         errors: false,
+        panics: false,
     };
     let mut in_code = false;
     let mut in_link = None;
@@ -439,6 +509,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
                 }
                 headers.safety |= in_heading && text.trim() == "Safety";
                 headers.errors |= in_heading && text.trim() == "Errors";
+                headers.panics |= in_heading && text.trim() == "Panics";
                 let index = match spans.binary_search_by(|c| c.0.cmp(&range.start)) {
                     Ok(o) => o,
                     Err(e) => e - 1,
@@ -609,3 +680,47 @@ fn check_word(cx: &LateContext<'_>, word: &str, span: Span) {
         );
     }
 }
+
+struct FindPanicUnwrap<'a, 'tcx> {
+    cx: &'a LateContext<'tcx>,
+    panic_span: Option<Span>,
+    typeck_results: &'tcx ty::TypeckResults<'tcx>,
+}
+
+impl<'a, 'tcx> Visitor<'tcx> for FindPanicUnwrap<'a, 'tcx> {
+    type Map = Map<'tcx>;
+
+    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
+        if self.panic_span.is_some() {
+            return;
+        }
+
+        // check for `begin_panic`
+        if_chain! {
+            if let ExprKind::Call(ref func_expr, _) = expr.kind;
+            if let ExprKind::Path(QPath::Resolved(_, ref path)) = func_expr.kind;
+            if let Some(path_def_id) = path.res.opt_def_id();
+            if match_panic_def_id(self.cx, path_def_id);
+            then {
+                self.panic_span = Some(expr.span);
+            }
+        }
+
+        // check for `unwrap`
+        if let Some(arglists) = method_chain_args(expr, &["unwrap"]) {
+            let reciever_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs();
+            if is_type_diagnostic_item(self.cx, reciever_ty, sym::option_type)
+                || is_type_diagnostic_item(self.cx, reciever_ty, sym::result_type)
+            {
+                self.panic_span = Some(expr.span);
+            }
+        }
+
+        // and check sub-expressions
+        intravisit::walk_expr(self, expr);
+    }
+
+    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
+        NestedVisitorMap::OnlyBodies(self.cx.tcx.hir())
+    }
+}
diff --git a/clippy_lints/src/excessive_bools.rs b/clippy_lints/src/excessive_bools.rs
index fecde8e2743..6f22f65deac 100644
--- a/clippy_lints/src/excessive_bools.rs
+++ b/clippy_lints/src/excessive_bools.rs
@@ -160,15 +160,17 @@ impl EarlyLintPass for ExcessiveBools {
                         "consider using a state machine or refactoring bools into two-variant enums",
                     );
                 }
-            }
-            ItemKind::Impl(box ImplKind { of_trait: None, items, .. })
+            },
+            ItemKind::Impl(box ImplKind {
+                of_trait: None, items, ..
+            })
             | ItemKind::Trait(box TraitKind(.., items)) => {
                 for item in items {
                     if let AssocItemKind::Fn(box FnKind(_, fn_sig, _, _)) = &item.kind {
                         self.check_fn_sig(cx, fn_sig, item.span);
                     }
                 }
-            }
+            },
             ItemKind::Fn(box FnKind(_, fn_sig, _, _)) => self.check_fn_sig(cx, fn_sig, item.span),
             _ => (),
         }
diff --git a/clippy_lints/src/exhaustive_items.rs b/clippy_lints/src/exhaustive_items.rs
index 32b1299efce..e3988d0038c 100644
--- a/clippy_lints/src/exhaustive_items.rs
+++ b/clippy_lints/src/exhaustive_items.rs
@@ -75,10 +75,14 @@ impl LateLintPass<'_> for ExhaustiveItems {
             if cx.access_levels.is_exported(item.hir_id);
             if !item.attrs.iter().any(|a| a.has_name(sym::non_exhaustive));
             then {
-                let (lint, msg) = if let ItemKind::Enum(..) = item.kind {
-                    (EXHAUSTIVE_ENUMS, "exported enums should not be exhaustive")
-                } else {
+                let (lint, msg) = if let ItemKind::Struct(ref v, ..) = item.kind {
+                    if v.fields().iter().any(|f| !f.vis.node.is_pub()) {
+                        // skip structs with private fields
+                        return;
+                    }
                     (EXHAUSTIVE_STRUCTS, "exported structs should not be exhaustive")
+                } else {
+                    (EXHAUSTIVE_ENUMS, "exported enums should not be exhaustive")
                 };
                 let suggestion_span = item.span.shrink_to_lo();
                 let indent = " ".repeat(indent_of(cx, item.span).unwrap_or(0));
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 54007c29c6c..5a40c00bd67 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -592,6 +592,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         &disallowed_method::DISALLOWED_METHOD,
         &doc::DOC_MARKDOWN,
         &doc::MISSING_ERRORS_DOC,
+        &doc::MISSING_PANICS_DOC,
         &doc::MISSING_SAFETY_DOC,
         &doc::NEEDLESS_DOCTEST_MAIN,
         &double_comparison::DOUBLE_COMPARISONS,
@@ -1317,6 +1318,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&derive::UNSAFE_DERIVE_DESERIALIZE),
         LintId::of(&doc::DOC_MARKDOWN),
         LintId::of(&doc::MISSING_ERRORS_DOC),
+        LintId::of(&doc::MISSING_PANICS_DOC),
         LintId::of(&empty_enum::EMPTY_ENUM),
         LintId::of(&enum_variants::MODULE_NAME_REPETITIONS),
         LintId::of(&enum_variants::PUB_ENUM_VARIANT_NAMES),
diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs
index 5f62d2d1316..ba7b9bd0424 100644
--- a/clippy_lints/src/matches.rs
+++ b/clippy_lints/src/matches.rs
@@ -1592,7 +1592,17 @@ where
                 }
             },
             (&Kind::End(a, _), &Kind::Start(b, _)) if a != Bound::Included(b) => (),
-            _ => return Some((a.range(), b.range())),
+            _ => {
+                // skip if the range `a` is completely included into the range `b`
+                if let Ordering::Equal | Ordering::Less = a.cmp(&b) {
+                    let kind_a = Kind::End(a.range().node.1, a.range());
+                    let kind_b = Kind::End(b.range().node.1, b.range());
+                    if let Ordering::Equal | Ordering::Greater = kind_a.cmp(&kind_b) {
+                        return None;
+                    }
+                }
+                return Some((a.range(), b.range()));
+            },
         }
     }
 
diff --git a/clippy_lints/src/utils/ast_utils.rs b/clippy_lints/src/utils/ast_utils.rs
index 69492e84e4a..64232646972 100644
--- a/clippy_lints/src/utils/ast_utils.rs
+++ b/clippy_lints/src/utils/ast_utils.rs
@@ -247,7 +247,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
         (ForeignMod(l), ForeignMod(r)) => {
             both(&l.abi, &r.abi, |l, r| eq_str_lit(l, r))
                 && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_foreign_item_kind))
-        }
+        },
         (TyAlias(box TyAliasKind(ld, lg, lb, lt)), TyAlias(box TyAliasKind(rd, rg, rb, rt))) => {
             eq_defaultness(*ld, *rd)
                 && eq_generics(lg, rg)
@@ -259,7 +259,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
         },
         (Struct(lv, lg), Struct(rv, rg)) | (Union(lv, lg), Union(rv, rg)) => {
             eq_variant_data(lv, rv) && eq_generics(lg, rg)
-        }
+        },
         (Trait(box TraitKind(la, lu, lg, lb, li)), Trait(box TraitKind(ra, ru, rg, rb, ri))) => {
             la == ra
                 && matches!(lu, Unsafe::No) == matches!(ru, Unsafe::No)
@@ -331,15 +331,10 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
 pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
     use AssocItemKind::*;
     match (l, r) {
-        (Const(ld, lt, le), Const(rd, rt, re)) => {
-            eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re)
-        }
+        (Const(ld, lt, le), Const(rd, rt, re)) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
         (Fn(box FnKind(ld, lf, lg, lb)), Fn(box FnKind(rd, rf, rg, rb))) => {
-            eq_defaultness(*ld, *rd)
-                && eq_fn_sig(lf, rf)
-                && eq_generics(lg, rg)
-                && both(lb, rb, |l, r| eq_block(l, r))
-        }
+            eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
+        },
         (TyAlias(box TyAliasKind(ld, lg, lb, lt)), TyAlias(box TyAliasKind(rd, rg, rb, rt))) => {
             eq_defaultness(*ld, *rd)
                 && eq_generics(lg, rg)
diff --git a/clippy_lints/src/utils/diagnostics.rs b/clippy_lints/src/utils/diagnostics.rs
index 6caa04f651f..269be217c2d 100644
--- a/clippy_lints/src/utils/diagnostics.rs
+++ b/clippy_lints/src/utils/diagnostics.rs
@@ -110,7 +110,7 @@ pub fn span_lint_and_help<'a, T: LintContext>(
 pub fn span_lint_and_note<'a, T: LintContext>(
     cx: &'a T,
     lint: &'static Lint,
-    span: Span,
+    span: impl Into<MultiSpan>,
     msg: &str,
     note_span: Option<Span>,
     note: &str,
diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs
index 822863ca3e2..cccad243e1b 100644
--- a/clippy_lints/src/utils/internal_lints.rs
+++ b/clippy_lints/src/utils/internal_lints.rs
@@ -760,7 +760,7 @@ impl<'tcx> LateLintPass<'tcx> for MatchTypeOnDiagItem {
             // Extract the path to the matched type
             if let Some(segments) = path_to_matched_type(cx, ty_path);
             let segments: Vec<&str> = segments.iter().map(|sym| &**sym).collect();
-            if let Some(ty_did) = path_to_res(cx, &segments[..]).and_then(|res| res.opt_def_id());
+            if let Some(ty_did) = path_to_res(cx, &segments[..]).opt_def_id();
             // Check if the matched type is a diagnostic item
             let diag_items = cx.tcx.diagnostic_items(ty_did.krate);
             if let Some(item_name) = diag_items.iter().find_map(|(k, v)| if *v == ty_did { Some(k) } else { None });
@@ -833,7 +833,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
 // This is not a complete resolver for paths. It works on all the paths currently used in the paths
 // module.  That's all it does and all it needs to do.
 pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
-    if path_to_res(cx, path).is_some() {
+    if path_to_res(cx, path) != Res::Err {
         return true;
     }
 
@@ -906,7 +906,7 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
         }
 
         for &module in &[&paths::KW_MODULE, &paths::SYM_MODULE] {
-            if let Some(Res::Def(_, def_id)) = path_to_res(cx, module) {
+            if let Some(def_id) = path_to_res(cx, module).opt_def_id() {
                 for item in cx.tcx.item_children(def_id).iter() {
                     if_chain! {
                         if let Res::Def(DefKind::Const, item_def_id) = item.res;
diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs
index d0db3a67533..ef45f9fdcd5 100644
--- a/clippy_lints/src/utils/mod.rs
+++ b/clippy_lints/src/utils/mod.rs
@@ -309,7 +309,15 @@ pub fn match_path_ast(path: &ast::Path, segments: &[&str]) -> bool {
 
 /// Gets the definition associated to a path.
 #[allow(clippy::shadow_unrelated)] // false positive #6563
-pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Option<Res> {
+pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
+    macro_rules! try_res {
+        ($e:expr) => {
+            match $e {
+                Some(e) => e,
+                None => return Res::Err,
+            }
+        };
+    }
     fn item_child_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Option<&'tcx Export<HirId>> {
         tcx.item_children(def_id)
             .iter()
@@ -318,12 +326,12 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Option<Res> {
 
     let (krate, first, path) = match *path {
         [krate, first, ref path @ ..] => (krate, first, path),
-        _ => return None,
+        _ => return Res::Err,
     };
     let tcx = cx.tcx;
     let crates = tcx.crates();
-    let krate = crates.iter().find(|&&num| tcx.crate_name(num).as_str() == krate)?;
-    let first = item_child_by_name(tcx, krate.as_def_id(), first)?;
+    let krate = try_res!(crates.iter().find(|&&num| tcx.crate_name(num).as_str() == krate));
+    let first = try_res!(item_child_by_name(tcx, krate.as_def_id(), first));
     let last = path
         .iter()
         .copied()
@@ -343,21 +351,15 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Option<Res> {
             } else {
                 None
             }
-        })?;
-    Some(last.res)
+        });
+    try_res!(last).res
 }
 
 /// Convenience function to get the `DefId` of a trait by path.
 /// It could be a trait or trait alias.
 pub fn get_trait_def_id(cx: &LateContext<'_>, path: &[&str]) -> Option<DefId> {
-    let res = match path_to_res(cx, path) {
-        Some(res) => res,
-        None => return None,
-    };
-
-    match res {
+    match path_to_res(cx, path) {
         Res::Def(DefKind::Trait | DefKind::TraitAlias, trait_id) => Some(trait_id),
-        Res::Err => unreachable!("this trait resolution is impossible: {:?}", &path),
         _ => None,
     }
 }
@@ -1532,10 +1534,11 @@ pub fn fn_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<DefId> {
         ExprKind::Call(
             Expr {
                 kind: ExprKind::Path(qpath),
+                hir_id: path_hir_id,
                 ..
             },
             ..,
-        ) => cx.typeck_results().qpath_res(qpath, expr.hir_id).opt_def_id(),
+        ) => cx.typeck_results().qpath_res(qpath, *path_hir_id).opt_def_id(),
         _ => None,
     }
 }
diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs
index b9e97077c54..978a232bcfb 100644
--- a/clippy_lints/src/write.rs
+++ b/clippy_lints/src/write.rs
@@ -233,7 +233,11 @@ impl_lint_pass!(Write => [
 
 impl EarlyLintPass for Write {
     fn check_item(&mut self, _: &EarlyContext<'_>, item: &Item) {
-        if let ItemKind::Impl(box ImplKind { of_trait: Some(trait_ref), .. }) = &item.kind {
+        if let ItemKind::Impl(box ImplKind {
+            of_trait: Some(trait_ref),
+            ..
+        }) = &item.kind
+        {
             let trait_name = trait_ref
                 .path
                 .segments
diff --git a/doc/adding_lints.md b/doc/adding_lints.md
index fd2a7d171d0..8fd1dea9aee 100644
--- a/doc/adding_lints.md
+++ b/doc/adding_lints.md
@@ -581,15 +581,15 @@ in the following steps:
 3. Passing the configuration value to the lint impl struct:
 
     First find the struct construction in the [clippy_lints lib file](/clippy_lints/src/lib.rs). 
-    Make sure that `clippy dev update_lints` added it beforehand. The configuration value is now 
-    cloned or copied into a local value that is then passed to the impl struct like this:
+    The configuration value is now cloned or copied into a local value that is then passed to the
+    impl struct like this:
     ```rust
     // Default generated registration:
-    store.register_late_pass(|| box module::StructName);
+    store.register_*_pass(|| box module::StructName);
 
     // New registration with configuration value
     let configuration_ident = conf.configuration_ident.clone();
-    store.register_late_pass(move || box module::StructName::new(configuration_ident));
+    store.register_*_pass(move || box module::StructName::new(configuration_ident));
     ```
 
     Congratulations the work is almost done. The configuration value can now be accessed
@@ -599,7 +599,7 @@ in the following steps:
     1. The default configured value can be tested like any normal lint in [`tests/ui`](/tests/ui).
     2. The configuration itself will be tested separately in [`tests/ui-toml`](/tests/ui-toml). 
         Simply add a new subfolder with a fitting name. This folder contains a `clippy.toml` file 
-        with the configuration value and a rust file that should be linted by clippy. The test can 
+        with the configuration value and a rust file that should be linted by Clippy. The test can 
         otherwise be written as usual.
 
 ## Cheatsheet
diff --git a/doc/basics.md b/doc/basics.md
index 57f83bdf32b..a9416f3b20b 100644
--- a/doc/basics.md
+++ b/doc/basics.md
@@ -109,7 +109,7 @@ See <https://rustc-dev-guide.rust-lang.org/contributing.html#opening-a-pr>.
 | HIR          | High-Level Intermediate Representation |
 | TCX          | Type context                           |
 
-This is a concise list of abbreviations that can come up during clippy development. An extensive
+This is a concise list of abbreviations that can come up during Clippy development. An extensive
 general list can be found in the [rustc-dev-guide glossary][glossary]. Always feel free to ask if
 an abbreviation or meaning is unclear to you.
 
diff --git a/mini-macro/src/lib.rs b/mini-macro/src/lib.rs
index ba946563ec5..2b793589049 100644
--- a/mini-macro/src/lib.rs
+++ b/mini-macro/src/lib.rs
@@ -7,6 +7,9 @@ extern crate proc_macro;
 use proc_macro::{quote, TokenStream};
 
 #[proc_macro_derive(ClippyMiniMacroTest)]
+/// # Panics
+///
+/// Panics if the macro derivation fails
 pub fn mini_macro(_: TokenStream) -> TokenStream {
     quote!(
         #[allow(unused)]
diff --git a/rust-toolchain b/rust-toolchain
index f55d55d7065..b617203bef6 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2021-01-30"
+channel = "nightly-2021-02-03"
 components = ["llvm-tools-preview", "rustc-dev", "rust-src", "rustfmt"]
diff --git a/tests/ui/doc_panics.rs b/tests/ui/doc_panics.rs
new file mode 100644
index 00000000000..7ef932f367b
--- /dev/null
+++ b/tests/ui/doc_panics.rs
@@ -0,0 +1,95 @@
+#![warn(clippy::missing_panics_doc)]
+#![allow(clippy::option_map_unit_fn)]
+
+fn main() {}
+
+/// This needs to be documented
+pub fn unwrap() {
+    let result = Err("Hi");
+    result.unwrap()
+}
+
+/// This needs to be documented
+pub fn panic() {
+    panic!("This function panics")
+}
+
+/// This needs to be documented
+pub fn todo() {
+    todo!()
+}
+
+/// This needs to be documented
+pub fn inner_body(opt: Option<u32>) {
+    opt.map(|x| {
+        if x == 10 {
+            panic!()
+        }
+    });
+}
+
+/// This is documented
+///
+/// # Panics
+///
+/// Panics if `result` if an error
+pub fn unwrap_documented() {
+    let result = Err("Hi");
+    result.unwrap()
+}
+
+/// This is documented
+///
+/// # Panics
+///
+/// Panics just because
+pub fn panic_documented() {
+    panic!("This function panics")
+}
+
+/// This is documented
+///
+/// # Panics
+///
+/// Panics if `opt` is Just(10)
+pub fn inner_body_documented(opt: Option<u32>) {
+    opt.map(|x| {
+        if x == 10 {
+            panic!()
+        }
+    });
+}
+
+/// This is documented
+///
+/// # Panics
+///
+/// We still need to do this part
+pub fn todo_documented() {
+    todo!()
+}
+
+/// This is okay because it is private
+fn unwrap_private() {
+    let result = Err("Hi");
+    result.unwrap()
+}
+
+/// This is okay because it is private
+fn panic_private() {
+    panic!("This function panics")
+}
+
+/// This is okay because it is private
+fn todo_private() {
+    todo!()
+}
+
+/// This is okay because it is private
+fn inner_body_private(opt: Option<u32>) {
+    opt.map(|x| {
+        if x == 10 {
+            panic!()
+        }
+    });
+}
diff --git a/tests/ui/doc_panics.stderr b/tests/ui/doc_panics.stderr
new file mode 100644
index 00000000000..c0c4e9e4fa7
--- /dev/null
+++ b/tests/ui/doc_panics.stderr
@@ -0,0 +1,67 @@
+error: docs for function which may panic missing `# Panics` section
+  --> $DIR/doc_panics.rs:7:1
+   |
+LL | / pub fn unwrap() {
+LL | |     let result = Err("Hi");
+LL | |     result.unwrap()
+LL | | }
+   | |_^
+   |
+   = note: `-D clippy::missing-panics-doc` implied by `-D warnings`
+note: first possible panic found here
+  --> $DIR/doc_panics.rs:9:5
+   |
+LL |     result.unwrap()
+   |     ^^^^^^^^^^^^^^^
+
+error: docs for function which may panic missing `# Panics` section
+  --> $DIR/doc_panics.rs:13:1
+   |
+LL | / pub fn panic() {
+LL | |     panic!("This function panics")
+LL | | }
+   | |_^
+   |
+note: first possible panic found here
+  --> $DIR/doc_panics.rs:14:5
+   |
+LL |     panic!("This function panics")
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: docs for function which may panic missing `# Panics` section
+  --> $DIR/doc_panics.rs:18:1
+   |
+LL | / pub fn todo() {
+LL | |     todo!()
+LL | | }
+   | |_^
+   |
+note: first possible panic found here
+  --> $DIR/doc_panics.rs:19:5
+   |
+LL |     todo!()
+   |     ^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: docs for function which may panic missing `# Panics` section
+  --> $DIR/doc_panics.rs:23:1
+   |
+LL | / pub fn inner_body(opt: Option<u32>) {
+LL | |     opt.map(|x| {
+LL | |         if x == 10 {
+LL | |             panic!()
+LL | |         }
+LL | |     });
+LL | | }
+   | |_^
+   |
+note: first possible panic found here
+  --> $DIR/doc_panics.rs:26:13
+   |
+LL |             panic!()
+   |             ^^^^^^^^
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/exhaustive_items.fixed b/tests/ui/exhaustive_items.fixed
index 8174a0175ab..c209f5b4b72 100644
--- a/tests/ui/exhaustive_items.fixed
+++ b/tests/ui/exhaustive_items.fixed
@@ -56,27 +56,36 @@ pub mod enums {
 pub mod structs {
     #[non_exhaustive]
     pub struct Exhaustive {
-        foo: u8,
-        bar: String,
+        pub foo: u8,
+        pub bar: String,
     }
 
     // no warning, already non_exhaustive
     #[non_exhaustive]
     pub struct NonExhaustive {
-        foo: u8,
+        pub foo: u8,
+        pub bar: String,
+    }
+
+    // no warning, private fields
+    pub struct ExhaustivePrivateFieldTuple(u8);
+
+    // no warning, private fields
+    pub struct ExhaustivePrivateField {
+        pub foo: u8,
         bar: String,
     }
 
     // no warning, private
     struct ExhaustivePrivate {
-        foo: u8,
-        bar: String,
+        pub foo: u8,
+        pub bar: String,
     }
 
     // no warning, private
     #[non_exhaustive]
     struct NonExhaustivePrivate {
-        foo: u8,
-        bar: String,
+        pub foo: u8,
+        pub bar: String,
     }
 }
diff --git a/tests/ui/exhaustive_items.rs b/tests/ui/exhaustive_items.rs
index b476f09f8a0..6f59dbf2da5 100644
--- a/tests/ui/exhaustive_items.rs
+++ b/tests/ui/exhaustive_items.rs
@@ -53,27 +53,36 @@ pub mod enums {
 
 pub mod structs {
     pub struct Exhaustive {
-        foo: u8,
-        bar: String,
+        pub foo: u8,
+        pub bar: String,
     }
 
     // no warning, already non_exhaustive
     #[non_exhaustive]
     pub struct NonExhaustive {
-        foo: u8,
+        pub foo: u8,
+        pub bar: String,
+    }
+
+    // no warning, private fields
+    pub struct ExhaustivePrivateFieldTuple(u8);
+
+    // no warning, private fields
+    pub struct ExhaustivePrivateField {
+        pub foo: u8,
         bar: String,
     }
 
     // no warning, private
     struct ExhaustivePrivate {
-        foo: u8,
-        bar: String,
+        pub foo: u8,
+        pub bar: String,
     }
 
     // no warning, private
     #[non_exhaustive]
     struct NonExhaustivePrivate {
-        foo: u8,
-        bar: String,
+        pub foo: u8,
+        pub bar: String,
     }
 }
diff --git a/tests/ui/exhaustive_items.stderr b/tests/ui/exhaustive_items.stderr
index 7369fe75a4f..8fbab535a9b 100644
--- a/tests/ui/exhaustive_items.stderr
+++ b/tests/ui/exhaustive_items.stderr
@@ -41,8 +41,8 @@ error: exported structs should not be exhaustive
   --> $DIR/exhaustive_items.rs:55:5
    |
 LL | /     pub struct Exhaustive {
-LL | |         foo: u8,
-LL | |         bar: String,
+LL | |         pub foo: u8,
+LL | |         pub bar: String,
 LL | |     }
    | |_____^
    |
diff --git a/tests/ui/let_and_return.rs b/tests/ui/let_and_return.rs
index 73e550b3df8..e3561863c1e 100644
--- a/tests/ui/let_and_return.rs
+++ b/tests/ui/let_and_return.rs
@@ -117,7 +117,11 @@ mod no_lint_if_stmt_borrows {
             fn drop(&mut self) {}
         }
 
-        impl Foo<'_> {
+        impl<'a> Foo<'a> {
+            fn new(inner: &'a Inner) -> Self {
+                Self { inner }
+            }
+
             fn value(&self) -> i32 {
                 42
             }
@@ -132,6 +136,12 @@ mod no_lint_if_stmt_borrows {
             let value = some_foo(&x).value();
             value
         }
+
+        fn test2() -> i32 {
+            let x = Inner {};
+            let value = Foo::new(&x).value();
+            value
+        }
     }
 }
 
diff --git a/tests/ui/let_and_return.stderr b/tests/ui/let_and_return.stderr
index fe878e5f206..a6941dabeb8 100644
--- a/tests/ui/let_and_return.stderr
+++ b/tests/ui/let_and_return.stderr
@@ -28,7 +28,7 @@ LL |         5
    |
 
 error: returning the result of a `let` binding from a block
-  --> $DIR/let_and_return.rs:154:13
+  --> $DIR/let_and_return.rs:164:13
    |
 LL |             let clone = Arc::clone(&self.foo);
    |             ---------------------------------- unnecessary `let` binding
diff --git a/tests/ui/match_overlapping_arm.rs b/tests/ui/match_overlapping_arm.rs
index 97789bb766f..44c51e8112a 100644
--- a/tests/ui/match_overlapping_arm.rs
+++ b/tests/ui/match_overlapping_arm.rs
@@ -57,6 +57,36 @@ fn overlapping() {
         _ => (),
     }
 
+    match 42 {
+        5..7 => println!("5 .. 7"),
+        0..10 => println!("0 .. 10"),
+        _ => (),
+    }
+
+    match 42 {
+        5..10 => println!("5 .. 10"),
+        0..=10 => println!("0 ... 10"),
+        _ => (),
+    }
+
+    match 42 {
+        0..14 => println!("0 .. 14"),
+        5..10 => println!("5 .. 10"),
+        _ => (),
+    }
+
+    match 42 {
+        5..14 => println!("5 .. 14"),
+        0..=10 => println!("0 ... 10"),
+        _ => (),
+    }
+
+    match 42 {
+        0..7 => println!("0 .. 7"),
+        0..=10 => println!("0 ... 10"),
+        _ => (),
+    }
+
     /*
     // FIXME(JohnTitor): uncomment this once rustfmt knows half-open patterns
     match 42 {
diff --git a/tests/ui/match_overlapping_arm.stderr b/tests/ui/match_overlapping_arm.stderr
index eb20d5405a9..f25a66d634e 100644
--- a/tests/ui/match_overlapping_arm.stderr
+++ b/tests/ui/match_overlapping_arm.stderr
@@ -24,39 +24,39 @@ LL |         FOO..=11 => println!("0 ... 11"),
    |         ^^^^^^^^
 
 error: some ranges overlap
-  --> $DIR/match_overlapping_arm.rs:26:9
+  --> $DIR/match_overlapping_arm.rs:55:9
    |
-LL |         0..=5 => println!("0 ... 5"),
+LL |         0..11 => println!("0 .. 11"),
    |         ^^^^^
    |
 note: overlaps with this
-  --> $DIR/match_overlapping_arm.rs:25:9
+  --> $DIR/match_overlapping_arm.rs:56:9
    |
-LL |         2 => println!("2"),
-   |         ^
+LL |         0..=11 => println!("0 ... 11"),
+   |         ^^^^^^
 
 error: some ranges overlap
-  --> $DIR/match_overlapping_arm.rs:32:9
+  --> $DIR/match_overlapping_arm.rs:80:9
    |
-LL |         0..=2 => println!("0 ... 2"),
-   |         ^^^^^
+LL |         0..=10 => println!("0 ... 10"),
+   |         ^^^^^^
    |
 note: overlaps with this
-  --> $DIR/match_overlapping_arm.rs:31:9
+  --> $DIR/match_overlapping_arm.rs:79:9
    |
-LL |         2 => println!("2"),
-   |         ^
+LL |         5..14 => println!("5 .. 14"),
+   |         ^^^^^
 
 error: some ranges overlap
-  --> $DIR/match_overlapping_arm.rs:55:9
+  --> $DIR/match_overlapping_arm.rs:85:9
    |
-LL |         0..11 => println!("0 .. 11"),
-   |         ^^^^^
+LL |         0..7 => println!("0 .. 7"),
+   |         ^^^^
    |
 note: overlaps with this
-  --> $DIR/match_overlapping_arm.rs:56:9
+  --> $DIR/match_overlapping_arm.rs:86:9
    |
-LL |         0..=11 => println!("0 ... 11"),
+LL |         0..=10 => println!("0 ... 10"),
    |         ^^^^^^
 
 error: aborting due to 5 previous errors
diff --git a/tests/ui/should_impl_trait/corner_cases.rs b/tests/ui/should_impl_trait/corner_cases.rs
index 6c5ffe6aba8..a7f8f54f2be 100644
--- a/tests/ui/should_impl_trait/corner_cases.rs
+++ b/tests/ui/should_impl_trait/corner_cases.rs
@@ -8,7 +8,8 @@
     clippy::unused_self,
     clippy::needless_lifetimes,
     clippy::missing_safety_doc,
-    clippy::wrong_self_convention
+    clippy::wrong_self_convention,
+    clippy::missing_panics_doc
 )]
 
 use std::ops::Mul;
diff --git a/tests/ui/should_impl_trait/method_list_1.rs b/tests/ui/should_impl_trait/method_list_1.rs
index f8d248fc98d..69a3390b03b 100644
--- a/tests/ui/should_impl_trait/method_list_1.rs
+++ b/tests/ui/should_impl_trait/method_list_1.rs
@@ -8,7 +8,8 @@
     clippy::unused_self,
     clippy::needless_lifetimes,
     clippy::missing_safety_doc,
-    clippy::wrong_self_convention
+    clippy::wrong_self_convention,
+    clippy::missing_panics_doc
 )]
 
 use std::ops::Mul;
diff --git a/tests/ui/should_impl_trait/method_list_1.stderr b/tests/ui/should_impl_trait/method_list_1.stderr
index 2b7d4628c3f..86c63946516 100644
--- a/tests/ui/should_impl_trait/method_list_1.stderr
+++ b/tests/ui/should_impl_trait/method_list_1.stderr
@@ -1,5 +1,5 @@
 error: method `add` can be confused for the standard trait method `std::ops::Add::add`
-  --> $DIR/method_list_1.rs:25:5
+  --> $DIR/method_list_1.rs:26:5
    |
 LL | /     pub fn add(self, other: T) -> T {
 LL | |         unimplemented!()
@@ -10,7 +10,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Add` or choosing a less ambiguous method name
 
 error: method `as_mut` can be confused for the standard trait method `std::convert::AsMut::as_mut`
-  --> $DIR/method_list_1.rs:29:5
+  --> $DIR/method_list_1.rs:30:5
    |
 LL | /     pub fn as_mut(&mut self) -> &mut T {
 LL | |         unimplemented!()
@@ -20,7 +20,7 @@ LL | |     }
    = help: consider implementing the trait `std::convert::AsMut` or choosing a less ambiguous method name
 
 error: method `as_ref` can be confused for the standard trait method `std::convert::AsRef::as_ref`
-  --> $DIR/method_list_1.rs:33:5
+  --> $DIR/method_list_1.rs:34:5
    |
 LL | /     pub fn as_ref(&self) -> &T {
 LL | |         unimplemented!()
@@ -30,7 +30,7 @@ LL | |     }
    = help: consider implementing the trait `std::convert::AsRef` or choosing a less ambiguous method name
 
 error: method `bitand` can be confused for the standard trait method `std::ops::BitAnd::bitand`
-  --> $DIR/method_list_1.rs:37:5
+  --> $DIR/method_list_1.rs:38:5
    |
 LL | /     pub fn bitand(self, rhs: T) -> T {
 LL | |         unimplemented!()
@@ -40,7 +40,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::BitAnd` or choosing a less ambiguous method name
 
 error: method `bitor` can be confused for the standard trait method `std::ops::BitOr::bitor`
-  --> $DIR/method_list_1.rs:41:5
+  --> $DIR/method_list_1.rs:42:5
    |
 LL | /     pub fn bitor(self, rhs: Self) -> Self {
 LL | |         unimplemented!()
@@ -50,7 +50,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::BitOr` or choosing a less ambiguous method name
 
 error: method `bitxor` can be confused for the standard trait method `std::ops::BitXor::bitxor`
-  --> $DIR/method_list_1.rs:45:5
+  --> $DIR/method_list_1.rs:46:5
    |
 LL | /     pub fn bitxor(self, rhs: Self) -> Self {
 LL | |         unimplemented!()
@@ -60,7 +60,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::BitXor` or choosing a less ambiguous method name
 
 error: method `borrow` can be confused for the standard trait method `std::borrow::Borrow::borrow`
-  --> $DIR/method_list_1.rs:49:5
+  --> $DIR/method_list_1.rs:50:5
    |
 LL | /     pub fn borrow(&self) -> &str {
 LL | |         unimplemented!()
@@ -70,7 +70,7 @@ LL | |     }
    = help: consider implementing the trait `std::borrow::Borrow` or choosing a less ambiguous method name
 
 error: method `borrow_mut` can be confused for the standard trait method `std::borrow::BorrowMut::borrow_mut`
-  --> $DIR/method_list_1.rs:53:5
+  --> $DIR/method_list_1.rs:54:5
    |
 LL | /     pub fn borrow_mut(&mut self) -> &mut str {
 LL | |         unimplemented!()
@@ -80,7 +80,7 @@ LL | |     }
    = help: consider implementing the trait `std::borrow::BorrowMut` or choosing a less ambiguous method name
 
 error: method `clone` can be confused for the standard trait method `std::clone::Clone::clone`
-  --> $DIR/method_list_1.rs:57:5
+  --> $DIR/method_list_1.rs:58:5
    |
 LL | /     pub fn clone(&self) -> Self {
 LL | |         unimplemented!()
@@ -90,7 +90,7 @@ LL | |     }
    = help: consider implementing the trait `std::clone::Clone` or choosing a less ambiguous method name
 
 error: method `cmp` can be confused for the standard trait method `std::cmp::Ord::cmp`
-  --> $DIR/method_list_1.rs:61:5
+  --> $DIR/method_list_1.rs:62:5
    |
 LL | /     pub fn cmp(&self, other: &Self) -> Self {
 LL | |         unimplemented!()
@@ -100,7 +100,7 @@ LL | |     }
    = help: consider implementing the trait `std::cmp::Ord` or choosing a less ambiguous method name
 
 error: method `deref` can be confused for the standard trait method `std::ops::Deref::deref`
-  --> $DIR/method_list_1.rs:69:5
+  --> $DIR/method_list_1.rs:70:5
    |
 LL | /     pub fn deref(&self) -> &Self {
 LL | |         unimplemented!()
@@ -110,7 +110,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Deref` or choosing a less ambiguous method name
 
 error: method `deref_mut` can be confused for the standard trait method `std::ops::DerefMut::deref_mut`
-  --> $DIR/method_list_1.rs:73:5
+  --> $DIR/method_list_1.rs:74:5
    |
 LL | /     pub fn deref_mut(&mut self) -> &mut Self {
 LL | |         unimplemented!()
@@ -120,7 +120,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::DerefMut` or choosing a less ambiguous method name
 
 error: method `div` can be confused for the standard trait method `std::ops::Div::div`
-  --> $DIR/method_list_1.rs:77:5
+  --> $DIR/method_list_1.rs:78:5
    |
 LL | /     pub fn div(self, rhs: Self) -> Self {
 LL | |         unimplemented!()
@@ -130,7 +130,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Div` or choosing a less ambiguous method name
 
 error: method `drop` can be confused for the standard trait method `std::ops::Drop::drop`
-  --> $DIR/method_list_1.rs:81:5
+  --> $DIR/method_list_1.rs:82:5
    |
 LL | /     pub fn drop(&mut self) {
 LL | |         unimplemented!()
diff --git a/tests/ui/should_impl_trait/method_list_2.rs b/tests/ui/should_impl_trait/method_list_2.rs
index ed5e0d384bf..2cdc1a06fe6 100644
--- a/tests/ui/should_impl_trait/method_list_2.rs
+++ b/tests/ui/should_impl_trait/method_list_2.rs
@@ -8,7 +8,8 @@
     clippy::unused_self,
     clippy::needless_lifetimes,
     clippy::missing_safety_doc,
-    clippy::wrong_self_convention
+    clippy::wrong_self_convention,
+    clippy::missing_panics_doc
 )]
 
 use std::ops::Mul;
diff --git a/tests/ui/should_impl_trait/method_list_2.stderr b/tests/ui/should_impl_trait/method_list_2.stderr
index b6fd4356956..0142e299108 100644
--- a/tests/ui/should_impl_trait/method_list_2.stderr
+++ b/tests/ui/should_impl_trait/method_list_2.stderr
@@ -1,5 +1,5 @@
 error: method `eq` can be confused for the standard trait method `std::cmp::PartialEq::eq`
-  --> $DIR/method_list_2.rs:26:5
+  --> $DIR/method_list_2.rs:27:5
    |
 LL | /     pub fn eq(&self, other: &Self) -> bool {
 LL | |         unimplemented!()
@@ -10,7 +10,7 @@ LL | |     }
    = help: consider implementing the trait `std::cmp::PartialEq` or choosing a less ambiguous method name
 
 error: method `from_iter` can be confused for the standard trait method `std::iter::FromIterator::from_iter`
-  --> $DIR/method_list_2.rs:30:5
+  --> $DIR/method_list_2.rs:31:5
    |
 LL | /     pub fn from_iter<T>(iter: T) -> Self {
 LL | |         unimplemented!()
@@ -20,7 +20,7 @@ LL | |     }
    = help: consider implementing the trait `std::iter::FromIterator` or choosing a less ambiguous method name
 
 error: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`
-  --> $DIR/method_list_2.rs:34:5
+  --> $DIR/method_list_2.rs:35:5
    |
 LL | /     pub fn from_str(s: &str) -> Result<Self, Self> {
 LL | |         unimplemented!()
@@ -30,7 +30,7 @@ LL | |     }
    = help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name
 
 error: method `hash` can be confused for the standard trait method `std::hash::Hash::hash`
-  --> $DIR/method_list_2.rs:38:5
+  --> $DIR/method_list_2.rs:39:5
    |
 LL | /     pub fn hash(&self, state: &mut T) {
 LL | |         unimplemented!()
@@ -40,7 +40,7 @@ LL | |     }
    = help: consider implementing the trait `std::hash::Hash` or choosing a less ambiguous method name
 
 error: method `index` can be confused for the standard trait method `std::ops::Index::index`
-  --> $DIR/method_list_2.rs:42:5
+  --> $DIR/method_list_2.rs:43:5
    |
 LL | /     pub fn index(&self, index: usize) -> &Self {
 LL | |         unimplemented!()
@@ -50,7 +50,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Index` or choosing a less ambiguous method name
 
 error: method `index_mut` can be confused for the standard trait method `std::ops::IndexMut::index_mut`
-  --> $DIR/method_list_2.rs:46:5
+  --> $DIR/method_list_2.rs:47:5
    |
 LL | /     pub fn index_mut(&mut self, index: usize) -> &mut Self {
 LL | |         unimplemented!()
@@ -60,7 +60,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::IndexMut` or choosing a less ambiguous method name
 
 error: method `into_iter` can be confused for the standard trait method `std::iter::IntoIterator::into_iter`
-  --> $DIR/method_list_2.rs:50:5
+  --> $DIR/method_list_2.rs:51:5
    |
 LL | /     pub fn into_iter(self) -> Self {
 LL | |         unimplemented!()
@@ -70,7 +70,7 @@ LL | |     }
    = help: consider implementing the trait `std::iter::IntoIterator` or choosing a less ambiguous method name
 
 error: method `mul` can be confused for the standard trait method `std::ops::Mul::mul`
-  --> $DIR/method_list_2.rs:54:5
+  --> $DIR/method_list_2.rs:55:5
    |
 LL | /     pub fn mul(self, rhs: Self) -> Self {
 LL | |         unimplemented!()
@@ -80,7 +80,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Mul` or choosing a less ambiguous method name
 
 error: method `neg` can be confused for the standard trait method `std::ops::Neg::neg`
-  --> $DIR/method_list_2.rs:58:5
+  --> $DIR/method_list_2.rs:59:5
    |
 LL | /     pub fn neg(self) -> Self {
 LL | |         unimplemented!()
@@ -90,7 +90,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Neg` or choosing a less ambiguous method name
 
 error: method `next` can be confused for the standard trait method `std::iter::Iterator::next`
-  --> $DIR/method_list_2.rs:62:5
+  --> $DIR/method_list_2.rs:63:5
    |
 LL | /     pub fn next(&mut self) -> Option<Self> {
 LL | |         unimplemented!()
@@ -100,7 +100,7 @@ LL | |     }
    = help: consider implementing the trait `std::iter::Iterator` or choosing a less ambiguous method name
 
 error: method `not` can be confused for the standard trait method `std::ops::Not::not`
-  --> $DIR/method_list_2.rs:66:5
+  --> $DIR/method_list_2.rs:67:5
    |
 LL | /     pub fn not(self) -> Self {
 LL | |         unimplemented!()
@@ -110,7 +110,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Not` or choosing a less ambiguous method name
 
 error: method `rem` can be confused for the standard trait method `std::ops::Rem::rem`
-  --> $DIR/method_list_2.rs:70:5
+  --> $DIR/method_list_2.rs:71:5
    |
 LL | /     pub fn rem(self, rhs: Self) -> Self {
 LL | |         unimplemented!()
@@ -120,7 +120,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Rem` or choosing a less ambiguous method name
 
 error: method `shl` can be confused for the standard trait method `std::ops::Shl::shl`
-  --> $DIR/method_list_2.rs:74:5
+  --> $DIR/method_list_2.rs:75:5
    |
 LL | /     pub fn shl(self, rhs: Self) -> Self {
 LL | |         unimplemented!()
@@ -130,7 +130,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Shl` or choosing a less ambiguous method name
 
 error: method `shr` can be confused for the standard trait method `std::ops::Shr::shr`
-  --> $DIR/method_list_2.rs:78:5
+  --> $DIR/method_list_2.rs:79:5
    |
 LL | /     pub fn shr(self, rhs: Self) -> Self {
 LL | |         unimplemented!()
@@ -140,7 +140,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Shr` or choosing a less ambiguous method name
 
 error: method `sub` can be confused for the standard trait method `std::ops::Sub::sub`
-  --> $DIR/method_list_2.rs:82:5
+  --> $DIR/method_list_2.rs:83:5
    |
 LL | /     pub fn sub(self, rhs: Self) -> Self {
 LL | |         unimplemented!()