diff --git a/.github/workflows/clippy_bors.yml b/.github/workflows/clippy_bors.yml index ae6f1aa1b30be..f27fee87dc165 100644 --- a/.github/workflows/clippy_bors.yml +++ b/.github/workflows/clippy_bors.yml @@ -90,6 +90,11 @@ jobs: - name: Checkout uses: actions/checkout@v2.3.3 + # FIXME: should not be necessary once 1.24.2 is the default version on the windows runner + - name: Update rustup + run: rustup self update + if: runner.os == 'Windows' + - name: Install toolchain run: rustup show active-toolchain diff --git a/clippy_lints/src/manual_unwrap_or.rs b/clippy_lints/src/manual_unwrap_or.rs index cf183d4c16f12..2f579edd6ade5 100644 --- a/clippy_lints/src/manual_unwrap_or.rs +++ b/clippy_lints/src/manual_unwrap_or.rs @@ -11,7 +11,6 @@ use rustc_hir::{Arm, Expr, ExprKind, PatKind}; use rustc_lint::LintContext; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::adjustment::Adjust; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; @@ -54,21 +53,6 @@ impl LateLintPass<'_> for ManualUnwrapOr { } } -#[derive(Copy, Clone)] -enum Case { - Option, - Result, -} - -impl Case { - fn unwrap_fn_path(&self) -> &str { - match self { - Case::Option => "Option::unwrap_or", - Case::Result => "Result::unwrap_or", - } - } -} - fn lint_manual_unwrap_or<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { fn applicable_or_arm<'a>(cx: &LateContext<'_>, arms: &'a [Arm<'a>]) -> Option<&'a Arm<'a>> { if_chain! { @@ -87,9 +71,8 @@ fn lint_manual_unwrap_or<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if is_lang_ctor(cx, qpath, OptionSome) || is_lang_ctor(cx, qpath, ResultOk); if let PatKind::Binding(_, binding_hir_id, ..) = unwrap_pat.kind; if path_to_local_id(unwrap_arm.body, binding_hir_id); + if cx.typeck_results().expr_adjustments(unwrap_arm.body).is_empty(); if !contains_return_break_continue_macro(or_arm.body); - if !cx.typeck_results().expr_adjustments(unwrap_arm.body).iter() - .any(|a| matches!(a.kind, Adjust::Deref(Some(..)))); then { Some(or_arm) } else { @@ -101,10 +84,10 @@ fn lint_manual_unwrap_or<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { if_chain! { if let ExprKind::Match(scrutinee, match_arms, _) = expr.kind; let ty = cx.typeck_results().expr_ty(scrutinee); - if let Some(case) = if is_type_diagnostic_item(cx, ty, sym::option_type) { - Some(Case::Option) + if let Some(ty_name) = if is_type_diagnostic_item(cx, ty, sym::option_type) { + Some("Option") } else if is_type_diagnostic_item(cx, ty, sym::result_type) { - Some(Case::Result) + Some("Result") } else { None }; @@ -127,7 +110,7 @@ fn lint_manual_unwrap_or<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { span_lint_and_sugg( cx, MANUAL_UNWRAP_OR, expr.span, - &format!("this pattern reimplements `{}`", case.unwrap_fn_path()), + &format!("this pattern reimplements `{}::unwrap_or`", ty_name), "replace with", format!( "{}.unwrap_or({})", diff --git a/doc/basics.md b/doc/basics.md index 5226875cc210a..e2e307ce4f6cf 100644 --- a/doc/basics.md +++ b/doc/basics.md @@ -28,6 +28,8 @@ git clone git@github.com:/rust-clippy If you've already cloned Clippy in the past, update it to the latest version: ```bash +# If the upstream remote has not been added yet +git remote add upstream https://github.com/rust-lang/rust-clippy # upstream has to be the remote of the rust-lang/rust-clippy repo git fetch upstream # make sure that you are on the master branch diff --git a/tests/ui/manual_unwrap_or.fixed b/tests/ui/manual_unwrap_or.fixed index 1efecb0ba1277..3717f962745fb 100644 --- a/tests/ui/manual_unwrap_or.fixed +++ b/tests/ui/manual_unwrap_or.fixed @@ -171,4 +171,11 @@ fn format_name(name: Option<&Rc>) -> &str { } } +fn implicit_deref_ref() { + let _: &str = match Some(&"bye") { + None => "hi", + Some(s) => s, + }; +} + fn main() {} diff --git a/tests/ui/manual_unwrap_or.rs b/tests/ui/manual_unwrap_or.rs index 95d585ad18a96..989adde1f5bbb 100644 --- a/tests/ui/manual_unwrap_or.rs +++ b/tests/ui/manual_unwrap_or.rs @@ -213,4 +213,11 @@ fn format_name(name: Option<&Rc>) -> &str { } } +fn implicit_deref_ref() { + let _: &str = match Some(&"bye") { + None => "hi", + Some(s) => s, + }; +} + fn main() {}