Skip to content

Commit

Permalink
Merge lints into one pass
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Smith committed Oct 21, 2020
1 parent d8c6bce commit 86f2b29
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 48 deletions.
69 changes: 23 additions & 46 deletions clippy_lints/src/await_holding_invalid.rs
Expand Up @@ -49,48 +49,6 @@ declare_clippy_lint! {
"Inside an async function, holding a MutexGuard while calling await"
}

declare_lint_pass!(AwaitHoldingLock => [AWAIT_HOLDING_LOCK]);

impl LateLintPass<'_> for AwaitHoldingLock {
fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) {
use AsyncGeneratorKind::{Block, Closure, Fn};
if let Some(GeneratorKind::Async(Block | Closure | Fn)) = body.generator_kind {
let body_id = BodyId {
hir_id: body.value.hir_id,
};
let def_id = cx.tcx.hir().body_owner_def_id(body_id);
let typeck_results = cx.tcx.typeck(def_id);
check_interior_types_lock(cx, &typeck_results.generator_interior_types, body.value.span);
}
}
}

fn check_interior_types_lock(cx: &LateContext<'_>, ty_causes: &[GeneratorInteriorTypeCause<'_>], span: Span) {
for ty_cause in ty_causes {
if let rustc_middle::ty::Adt(adt, _) = ty_cause.ty.kind() {
if is_mutex_guard(cx, adt.did) {
span_lint_and_note(
cx,
AWAIT_HOLDING_LOCK,
ty_cause.span,
"this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await.",
ty_cause.scope_span.or(Some(span)),
"these are all the await points this lock is held through",
);
}
}
}
}

fn is_mutex_guard(cx: &LateContext<'_>, def_id: DefId) -> bool {
match_def_path(cx, def_id, &paths::MUTEX_GUARD)
|| match_def_path(cx, def_id, &paths::RWLOCK_READ_GUARD)
|| match_def_path(cx, def_id, &paths::RWLOCK_WRITE_GUARD)
|| match_def_path(cx, def_id, &paths::PARKING_LOT_MUTEX_GUARD)
|| match_def_path(cx, def_id, &paths::PARKING_LOT_RWLOCK_READ_GUARD)
|| match_def_path(cx, def_id, &paths::PARKING_LOT_RWLOCK_WRITE_GUARD)
}

declare_clippy_lint! {
/// **What it does:** Checks for calls to await while holding a
/// `RefCell` `Ref` or `RefMut`.
Expand Down Expand Up @@ -130,9 +88,9 @@ declare_clippy_lint! {
"Inside an async function, holding a RefCell ref while calling await"
}

declare_lint_pass!(AwaitHoldingRefCellRef => [AWAIT_HOLDING_REFCELL_REF]);
declare_lint_pass!(AwaitHolding => [AWAIT_HOLDING_LOCK, AWAIT_HOLDING_REFCELL_REF]);

impl LateLintPass<'_> for AwaitHoldingRefCellRef {
impl LateLintPass<'_> for AwaitHolding {
fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) {
use AsyncGeneratorKind::{Block, Closure, Fn};
if let Some(GeneratorKind::Async(Block | Closure | Fn)) = body.generator_kind {
Expand All @@ -141,14 +99,24 @@ impl LateLintPass<'_> for AwaitHoldingRefCellRef {
};
let def_id = cx.tcx.hir().body_owner_def_id(body_id);
let typeck_results = cx.tcx.typeck(def_id);
check_interior_types_refcell(cx, &typeck_results.generator_interior_types, body.value.span);
check_interior_types(cx, &typeck_results.generator_interior_types, body.value.span);
}
}
}

fn check_interior_types_refcell(cx: &LateContext<'_>, ty_causes: &[GeneratorInteriorTypeCause<'_>], span: Span) {
fn check_interior_types(cx: &LateContext<'_>, ty_causes: &[GeneratorInteriorTypeCause<'_>], span: Span) {
for ty_cause in ty_causes {
if let rustc_middle::ty::Adt(adt, _) = ty_cause.ty.kind() {
if is_mutex_guard(cx, adt.did) {
span_lint_and_note(
cx,
AWAIT_HOLDING_LOCK,
ty_cause.span,
"this MutexGuard is held across an 'await' point. Consider using an async-aware Mutex type or ensuring the MutexGuard is dropped before calling await.",
ty_cause.scope_span.or(Some(span)),
"these are all the await points this lock is held through",
);
}
if is_refcell_ref(cx, adt.did) {
span_lint_and_note(
cx,
Expand All @@ -163,6 +131,15 @@ fn check_interior_types_refcell(cx: &LateContext<'_>, ty_causes: &[GeneratorInte
}
}

fn is_mutex_guard(cx: &LateContext<'_>, def_id: DefId) -> bool {
match_def_path(cx, def_id, &paths::MUTEX_GUARD)
|| match_def_path(cx, def_id, &paths::RWLOCK_READ_GUARD)
|| match_def_path(cx, def_id, &paths::RWLOCK_WRITE_GUARD)
|| match_def_path(cx, def_id, &paths::PARKING_LOT_MUTEX_GUARD)
|| match_def_path(cx, def_id, &paths::PARKING_LOT_RWLOCK_READ_GUARD)
|| match_def_path(cx, def_id, &paths::PARKING_LOT_RWLOCK_WRITE_GUARD)
}

fn is_refcell_ref(cx: &LateContext<'_>, def_id: DefId) -> bool {
match_def_path(cx, def_id, &paths::REFCELL_REF) || match_def_path(cx, def_id, &paths::REFCELL_REFMUT)
}
3 changes: 1 addition & 2 deletions clippy_lints/src/lib.rs
Expand Up @@ -906,8 +906,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
]);
// end register lints, do not remove this comment, it’s used in `update_lints`

store.register_late_pass(|| box await_holding_invalid::AwaitHoldingLock);
store.register_late_pass(|| box await_holding_invalid::AwaitHoldingRefCellRef);
store.register_late_pass(|| box await_holding_invalid::AwaitHolding);
store.register_late_pass(|| box serde_api::SerdeAPI);
store.register_late_pass(|| box utils::internal_lints::CompilerLintFunctions::new());
store.register_late_pass(|| box utils::internal_lints::LintWithoutLintPass::default());
Expand Down

0 comments on commit 86f2b29

Please sign in to comment.