1 //! Checks for uses of mutex where an atomic value could be used
3 //! This lint is **warn** by default
5 use rustc
::lint
::{LateContext, LateLintPass, LintArray, LintPass}
;
6 use rustc
::ty
::{self, Ty}
;
9 use utils
::{match_type, paths, span_lint}
;
11 /// **What it does:** Checks for usages of `Mutex<X>` where an atomic will do.
13 /// **Why is this bad?** Using a mutex just to make access to a plain bool or
14 /// reference sequential is shooting flies with cannons.
15 /// `std::atomic::AtomicBool` and `std::atomic::AtomicPtr` are leaner and
18 /// **Known problems:** This lint cannot detect if the mutex is actually used
19 /// for waiting before a critical section.
23 /// let x = Mutex::new(&y);
28 "using a mutex where an atomic value could be used instead"
31 /// **What it does:** Checks for usages of `Mutex<X>` where `X` is an integral
34 /// **Why is this bad?** Using a mutex just to make access to a plain integer
36 /// shooting flies with cannons. `std::atomic::usize` is leaner and faster.
38 /// **Known problems:** This lint cannot detect if the mutex is actually used
39 /// for waiting before a critical section.
43 /// let x = Mutex::new(0usize);
48 "using a mutex for an integer type"
51 impl LintPass
for MutexAtomic
{
52 fn get_lints(&self) -> LintArray
{
53 lint_array
!(MUTEX_ATOMIC
, MUTEX_INTEGER
)
57 pub struct MutexAtomic
;
59 impl<'a
, 'tcx
> LateLintPass
<'a
, 'tcx
> for MutexAtomic
{
60 fn check_expr(&mut self, cx
: &LateContext
<'a
, 'tcx
>, expr
: &'tcx Expr
) {
61 let ty
= cx
.tables
.expr_ty(expr
);
62 if let ty
::TyAdt(_
, subst
) = ty
.sty
{
63 if match_type(cx
, ty
, &paths
::MUTEX
) {
64 let mutex_param
= subst
.type_at(0);
65 if let Some(atomic_name
) = get_atomic_name(mutex_param
) {
67 "Consider using an {} instead of a Mutex here. If you just want the locking \
68 behaviour and not the internal type, consider using Mutex<()>.",
71 match mutex_param
.sty
{
72 ty
::TyUint(t
) if t
!= ast
::UintTy
::Us
=> span_lint(cx
, MUTEX_INTEGER
, expr
.span
, &msg
),
73 ty
::TyInt(t
) if t
!= ast
::IntTy
::Is
=> span_lint(cx
, MUTEX_INTEGER
, expr
.span
, &msg
),
74 _
=> span_lint(cx
, MUTEX_ATOMIC
, expr
.span
, &msg
),
82 fn get_atomic_name(ty
: Ty
) -> Option
<(&'
static str)> {
84 ty
::TyBool
=> Some("AtomicBool"),
85 ty
::TyUint(_
) => Some("AtomicUsize"),
86 ty
::TyInt(_
) => Some("AtomicIsize"),
87 ty
::TyRawPtr(_
) => Some("AtomicPtr"),