Skip to content

Commit 747e3b6

Browse files
committed
Fix false positive in missing_const_for_fn
This fixes some additional false positives with functions or methods that return types which implement drop. Since `drop` can't be const-evaluated, these cases can't be made const. Fixes #4979
1 parent 99dd0bb commit 747e3b6

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

clippy_lints/src/missing_const_for_fn.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::utils::{has_drop, is_entrypoint_fn, span_lint, trait_ref_of_method};
1+
use crate::utils::{has_drop, is_entrypoint_fn, return_ty, span_lint, trait_ref_of_method};
22
use rustc::declare_lint_pass;
33
use rustc::hir;
44
use rustc::hir::intravisit::FnKind;
@@ -91,14 +91,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn {
9191
// can skip the actual const check and return early.
9292
match kind {
9393
FnKind::ItemFn(_, _, header, ..) => {
94-
if already_const(header) {
94+
if already_const(header) || returns_dropable(cx, hir_id) {
9595
return;
9696
}
9797
},
9898
FnKind::Method(_, sig, ..) => {
9999
if trait_ref_of_method(cx, hir_id).is_some()
100100
|| already_const(sig.header)
101101
|| method_accepts_dropable(cx, sig.decl.inputs)
102+
|| returns_dropable(cx, hir_id)
102103
{
103104
return;
104105
}
@@ -128,6 +129,11 @@ fn method_accepts_dropable(cx: &LateContext<'_, '_>, param_tys: &[hir::Ty<'_>])
128129
})
129130
}
130131

132+
fn returns_dropable(cx: &LateContext<'_, '_>, ret_ty: hir::HirId) -> bool {
133+
let return_ty = return_ty(cx, ret_ty);
134+
has_drop(cx, return_ty)
135+
}
136+
131137
// We don't have to lint on something that's already `const`
132138
#[must_use]
133139
fn already_const(header: hir::FnHeader) -> bool {

tests/ui/missing_const_for_fn/cant_be_const.rs

+25
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,29 @@ mod with_drop {
8989
B
9090
}
9191
}
92+
93+
struct CustomDrop {
94+
field: i32,
95+
}
96+
97+
impl Drop for CustomDrop {
98+
fn drop(&mut self) {}
99+
}
100+
101+
struct Bar {
102+
field: CustomDrop,
103+
}
104+
105+
impl Bar {
106+
fn take(self) -> CustomDrop {
107+
self.field
108+
}
109+
}
110+
111+
fn take() -> CustomDrop {
112+
let x = Bar {
113+
field: CustomDrop { field: 1 },
114+
};
115+
x.field
116+
}
92117
}

0 commit comments

Comments
 (0)