Skip to content

Commit

Permalink
Fix false positive in missing_const_for_fn
Browse files Browse the repository at this point in the history
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 rust-lang#4979
  • Loading branch information
phansch committed Jan 2, 2020
1 parent 99dd0bb commit 747e3b6
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
10 changes: 8 additions & 2 deletions clippy_lints/src/missing_const_for_fn.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::utils::{has_drop, is_entrypoint_fn, span_lint, trait_ref_of_method};
use crate::utils::{has_drop, is_entrypoint_fn, return_ty, span_lint, trait_ref_of_method};
use rustc::declare_lint_pass;
use rustc::hir;
use rustc::hir::intravisit::FnKind;
Expand Down Expand Up @@ -91,14 +91,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn {
// can skip the actual const check and return early.
match kind {
FnKind::ItemFn(_, _, header, ..) => {
if already_const(header) {
if already_const(header) || returns_dropable(cx, hir_id) {
return;
}
},
FnKind::Method(_, sig, ..) => {
if trait_ref_of_method(cx, hir_id).is_some()
|| already_const(sig.header)
|| method_accepts_dropable(cx, sig.decl.inputs)
|| returns_dropable(cx, hir_id)
{
return;
}
Expand Down Expand Up @@ -128,6 +129,11 @@ fn method_accepts_dropable(cx: &LateContext<'_, '_>, param_tys: &[hir::Ty<'_>])
})
}

fn returns_dropable(cx: &LateContext<'_, '_>, ret_ty: hir::HirId) -> bool {
let return_ty = return_ty(cx, ret_ty);
has_drop(cx, return_ty)
}

// We don't have to lint on something that's already `const`
#[must_use]
fn already_const(header: hir::FnHeader) -> bool {
Expand Down
25 changes: 25 additions & 0 deletions tests/ui/missing_const_for_fn/cant_be_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,29 @@ mod with_drop {
B
}
}

struct CustomDrop {
field: i32,
}

impl Drop for CustomDrop {
fn drop(&mut self) {}
}

struct Bar {
field: CustomDrop,
}

impl Bar {
fn take(self) -> CustomDrop {
self.field
}
}

fn take() -> CustomDrop {
let x = Bar {
field: CustomDrop { field: 1 },
};
x.field
}
}

0 comments on commit 747e3b6

Please sign in to comment.