Skip to content

Commit c5b3a71

Browse files
committed
Fix FP of manual_unwrap_or in const fn
1 parent 1a206fc commit c5b3a71

File tree

3 files changed

+58
-5
lines changed

3 files changed

+58
-5
lines changed

clippy_lints/src/manual_unwrap_or.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt};
66
use clippy_utils::ty::is_type_diagnostic_item;
77
use if_chain::if_chain;
88
use rustc_errors::Applicability;
9-
use rustc_hir::{Arm, Expr, ExprKind, Pat, PatKind};
9+
use rustc_hir::{hir_id::HirId, intravisit::FnKind, Arm, Body, Expr, ExprKind, FnDecl, Pat, PatKind, StmtKind};
1010
use rustc_lint::LintContext;
1111
use rustc_lint::{LateContext, LateLintPass};
1212
use rustc_middle::lint::in_external_macro;
1313
use rustc_session::{declare_lint_pass, declare_tool_lint};
14-
use rustc_span::sym;
14+
use rustc_span::{source_map::Span, sym};
1515

1616
declare_clippy_lint! {
1717
/// **What it does:**
@@ -44,11 +44,34 @@ declare_clippy_lint! {
4444
declare_lint_pass!(ManualUnwrapOr => [MANUAL_UNWRAP_OR]);
4545

4646
impl LateLintPass<'_> for ManualUnwrapOr {
47-
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
48-
if in_external_macro(cx.sess(), expr.span) {
47+
fn check_fn(
48+
&mut self,
49+
cx: &LateContext<'tcx>,
50+
kind: FnKind<'tcx>,
51+
_: &'tcx FnDecl<'tcx>,
52+
body: &'tcx Body<'tcx>,
53+
span: Span,
54+
_: HirId,
55+
) {
56+
if in_external_macro(cx.sess(), span) {
4957
return;
5058
}
51-
lint_manual_unwrap_or(cx, expr);
59+
if_chain! {
60+
if let FnKind::ItemFn(_, _, header, _) = kind;
61+
if !header.is_const();
62+
let expr = &body.value;
63+
if let ExprKind::Block(block, _) = expr.kind;
64+
then {
65+
for stmt in block.stmts {
66+
if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = &stmt.kind {
67+
lint_manual_unwrap_or(cx, expr);
68+
}
69+
}
70+
if let Some(expr) = block.expr {
71+
lint_manual_unwrap_or(cx, expr);
72+
}
73+
}
74+
}
5275
}
5376
}
5477

tests/ui/manual_unwrap_or.fixed

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,19 @@ fn result_unwrap_or() {
136136
};
137137
}
138138

139+
// don't lint in const fn
140+
const fn const_fn_unwrap_or() {
141+
match Some(1) {
142+
Some(s) => s,
143+
None => 0,
144+
};
145+
}
146+
147+
const fn const_fn_unwrap() {
148+
match Ok::<&str, &str>("Alice") {
149+
Ok(s) => s,
150+
Err(_) => "Bob",
151+
};
152+
}
153+
139154
fn main() {}

tests/ui/manual_unwrap_or.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,4 +175,19 @@ fn result_unwrap_or() {
175175
};
176176
}
177177

178+
// don't lint in const fn
179+
const fn const_fn_unwrap_or() {
180+
match Some(1) {
181+
Some(s) => s,
182+
None => 0,
183+
};
184+
}
185+
186+
const fn const_fn_unwrap() {
187+
match Ok::<&str, &str>("Alice") {
188+
Ok(s) => s,
189+
Err(_) => "Bob",
190+
};
191+
}
192+
178193
fn main() {}

0 commit comments

Comments
 (0)