Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
182b7c38
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
182b7c38
编写于
4月 06, 2022
作者:
A
Alex Macleod
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix `as_deref_mut` false positives in `needless_option_as_deref`
Also moves the lint to the methods directory
上级
409a936f
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
136 addition
and
75 deletion
+136
-75
clippy_lints/src/lib.register_all.rs
clippy_lints/src/lib.register_all.rs
+1
-1
clippy_lints/src/lib.register_complexity.rs
clippy_lints/src/lib.register_complexity.rs
+1
-1
clippy_lints/src/lib.register_lints.rs
clippy_lints/src/lib.register_lints.rs
+1
-1
clippy_lints/src/lib.rs
clippy_lints/src/lib.rs
+0
-2
clippy_lints/src/methods/mod.rs
clippy_lints/src/methods/mod.rs
+29
-0
clippy_lints/src/methods/needless_option_as_deref.rs
clippy_lints/src/methods/needless_option_as_deref.rs
+37
-0
clippy_lints/src/needless_option_as_deref.rs
clippy_lints/src/needless_option_as_deref.rs
+0
-65
tests/ui/needless_option_as_deref.fixed
tests/ui/needless_option_as_deref.fixed
+29
-1
tests/ui/needless_option_as_deref.rs
tests/ui/needless_option_as_deref.rs
+29
-1
tests/ui/needless_option_as_deref.stderr
tests/ui/needless_option_as_deref.stderr
+9
-3
未找到文件。
clippy_lints/src/lib.register_all.rs
浏览文件 @
182b7c38
...
...
@@ -176,6 +176,7 @@
LintId
::
of
(
methods
::
MAP_COLLECT_RESULT_UNIT
),
LintId
::
of
(
methods
::
MAP_FLATTEN
),
LintId
::
of
(
methods
::
MAP_IDENTITY
),
LintId
::
of
(
methods
::
NEEDLESS_OPTION_AS_DEREF
),
LintId
::
of
(
methods
::
NEEDLESS_SPLITN
),
LintId
::
of
(
methods
::
NEW_RET_NO_SELF
),
LintId
::
of
(
methods
::
OK_EXPECT
),
...
...
@@ -225,7 +226,6 @@
LintId
::
of
(
needless_bool
::
NEEDLESS_BOOL
),
LintId
::
of
(
needless_borrowed_ref
::
NEEDLESS_BORROWED_REFERENCE
),
LintId
::
of
(
needless_late_init
::
NEEDLESS_LATE_INIT
),
LintId
::
of
(
needless_option_as_deref
::
NEEDLESS_OPTION_AS_DEREF
),
LintId
::
of
(
needless_question_mark
::
NEEDLESS_QUESTION_MARK
),
LintId
::
of
(
needless_update
::
NEEDLESS_UPDATE
),
LintId
::
of
(
neg_cmp_op_on_partial_ord
::
NEG_CMP_OP_ON_PARTIAL_ORD
),
...
...
clippy_lints/src/lib.register_complexity.rs
浏览文件 @
182b7c38
...
...
@@ -44,6 +44,7 @@
LintId
::
of
(
methods
::
MANUAL_SPLIT_ONCE
),
LintId
::
of
(
methods
::
MAP_FLATTEN
),
LintId
::
of
(
methods
::
MAP_IDENTITY
),
LintId
::
of
(
methods
::
NEEDLESS_OPTION_AS_DEREF
),
LintId
::
of
(
methods
::
NEEDLESS_SPLITN
),
LintId
::
of
(
methods
::
OPTION_AS_REF_DEREF
),
LintId
::
of
(
methods
::
OPTION_FILTER_MAP
),
...
...
@@ -60,7 +61,6 @@
LintId
::
of
(
needless_bool
::
BOOL_COMPARISON
),
LintId
::
of
(
needless_bool
::
NEEDLESS_BOOL
),
LintId
::
of
(
needless_borrowed_ref
::
NEEDLESS_BORROWED_REFERENCE
),
LintId
::
of
(
needless_option_as_deref
::
NEEDLESS_OPTION_AS_DEREF
),
LintId
::
of
(
needless_question_mark
::
NEEDLESS_QUESTION_MARK
),
LintId
::
of
(
needless_update
::
NEEDLESS_UPDATE
),
LintId
::
of
(
neg_cmp_op_on_partial_ord
::
NEG_CMP_OP_ON_PARTIAL_ORD
),
...
...
clippy_lints/src/lib.register_lints.rs
浏览文件 @
182b7c38
...
...
@@ -315,6 +315,7 @@
methods
::
MAP_FLATTEN
,
methods
::
MAP_IDENTITY
,
methods
::
MAP_UNWRAP_OR
,
methods
::
NEEDLESS_OPTION_AS_DEREF
,
methods
::
NEEDLESS_SPLITN
,
methods
::
NEW_RET_NO_SELF
,
methods
::
OK_EXPECT
,
...
...
@@ -386,7 +387,6 @@
needless_continue
::
NEEDLESS_CONTINUE
,
needless_for_each
::
NEEDLESS_FOR_EACH
,
needless_late_init
::
NEEDLESS_LATE_INIT
,
needless_option_as_deref
::
NEEDLESS_OPTION_AS_DEREF
,
needless_pass_by_value
::
NEEDLESS_PASS_BY_VALUE
,
needless_question_mark
::
NEEDLESS_QUESTION_MARK
,
needless_update
::
NEEDLESS_UPDATE
,
...
...
clippy_lints/src/lib.rs
浏览文件 @
182b7c38
...
...
@@ -308,7 +308,6 @@
mod
needless_continue
;
mod
needless_for_each
;
mod
needless_late_init
;
mod
needless_option_as_deref
;
mod
needless_pass_by_value
;
mod
needless_question_mark
;
mod
needless_update
;
...
...
@@ -536,7 +535,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store
.register_late_pass
(||
Box
::
new
(
ptr
::
Ptr
));
store
.register_late_pass
(||
Box
::
new
(
ptr_eq
::
PtrEq
));
store
.register_late_pass
(||
Box
::
new
(
needless_bool
::
NeedlessBool
));
store
.register_late_pass
(||
Box
::
new
(
needless_option_as_deref
::
OptionNeedlessDeref
));
store
.register_late_pass
(||
Box
::
new
(
needless_bool
::
BoolComparison
));
store
.register_late_pass
(||
Box
::
new
(
needless_for_each
::
NeedlessForEach
));
store
.register_late_pass
(||
Box
::
new
(
misc
::
MiscLints
));
...
...
clippy_lints/src/methods/mod.rs
浏览文件 @
182b7c38
...
...
@@ -41,6 +41,7 @@
mod
map_flatten
;
mod
map_identity
;
mod
map_unwrap_or
;
mod
needless_option_as_deref
;
mod
ok_expect
;
mod
option_as_ref_deref
;
mod
option_map_or_none
;
...
...
@@ -2106,6 +2107,30 @@
"using `.collect::<Vec<String>>().join(
\"\"
)` on an iterator"
}
declare_clippy_lint!
{
/// ### What it does
/// Checks for no-op uses of `Option::{as_deref, as_deref_mut}`,
/// for example, `Option<&T>::as_deref()` returns the same type.
///
/// ### Why is this bad?
/// Redundant code and improving readability.
///
/// ### Example
/// ```rust
/// let a = Some(&1);
/// let b = a.as_deref(); // goes from Option<&i32> to Option<&i32>
/// ```
/// Could be written as:
/// ```rust
/// let a = Some(&1);
/// let b = a;
/// ```
#[clippy::version
=
"1.57.0"
]
pub
NEEDLESS_OPTION_AS_DEREF
,
complexity
,
"no-op use of `deref` or `deref_mut` method to `Option`."
}
pub
struct
Methods
{
avoid_breaking_exported_api
:
bool
,
msrv
:
Option
<
RustcVersion
>
,
...
...
@@ -2193,6 +2218,7 @@ pub fn new(avoid_breaking_exported_api: bool, msrv: Option<RustcVersion>) -> Sel
UNNECESSARY_TO_OWNED
,
UNNECESSARY_JOIN
,
ERR_EXPECT
,
NEEDLESS_OPTION_AS_DEREF
,
]);
/// Extracts a method call name, args, and `Span` of the method name.
...
...
@@ -2425,6 +2451,9 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
unnecessary_lazy_eval
::
check
(
cx
,
expr
,
recv
,
arg
,
"and"
);
}
},
(
"as_deref"
|
"as_deref_mut"
,
[])
=>
{
needless_option_as_deref
::
check
(
cx
,
expr
,
recv
,
name
);
},
(
"as_mut"
,
[])
=>
useless_asref
::
check
(
cx
,
expr
,
"as_mut"
,
recv
),
(
"as_ref"
,
[])
=>
useless_asref
::
check
(
cx
,
expr
,
"as_ref"
,
recv
),
(
"assume_init"
,
[])
=>
uninit_assumed_init
::
check
(
cx
,
expr
,
recv
),
...
...
clippy_lints/src/methods/needless_option_as_deref.rs
0 → 100644
浏览文件 @
182b7c38
use
clippy_utils
::
diagnostics
::
span_lint_and_sugg
;
use
clippy_utils
::
path_res
;
use
clippy_utils
::
source
::
snippet_opt
;
use
clippy_utils
::
ty
::
is_type_diagnostic_item
;
use
clippy_utils
::
usage
::
local_used_after_expr
;
use
rustc_errors
::
Applicability
;
use
rustc_hir
::
def
::
Res
;
use
rustc_hir
::
Expr
;
use
rustc_lint
::
LateContext
;
use
rustc_span
::
sym
;
use
super
::
NEEDLESS_OPTION_AS_DEREF
;
pub
(
super
)
fn
check
(
cx
:
&
LateContext
<
'_
>
,
expr
:
&
Expr
<
'_
>
,
recv
:
&
Expr
<
'_
>
,
name
:
&
str
)
{
let
typeck
=
cx
.typeck_results
();
let
outer_ty
=
typeck
.expr_ty
(
expr
);
if
is_type_diagnostic_item
(
cx
,
outer_ty
,
sym
::
Option
)
&&
outer_ty
==
typeck
.expr_ty
(
recv
)
{
if
name
==
"as_deref_mut"
&&
recv
.is_syntactic_place_expr
()
{
let
Res
::
Local
(
binding_id
)
=
path_res
(
cx
,
recv
)
else
{
return
};
if
local_used_after_expr
(
cx
,
binding_id
,
recv
)
{
return
;
}
}
span_lint_and_sugg
(
cx
,
NEEDLESS_OPTION_AS_DEREF
,
expr
.span
,
"derefed type is same as origin"
,
"try this"
,
snippet_opt
(
cx
,
recv
.span
)
.unwrap
(),
Applicability
::
MachineApplicable
,
);
}
}
clippy_lints/src/needless_option_as_deref.rs
已删除
100644 → 0
浏览文件 @
409a936f
use
clippy_utils
::
diagnostics
::
span_lint_and_sugg
;
use
clippy_utils
::
source
::
snippet_opt
;
use
clippy_utils
::
ty
::
is_type_diagnostic_item
;
use
rustc_errors
::
Applicability
;
use
rustc_hir
::{
Expr
,
ExprKind
};
use
rustc_lint
::{
LateContext
,
LateLintPass
};
use
rustc_session
::{
declare_lint_pass
,
declare_tool_lint
};
use
rustc_span
::
symbol
::
sym
;
declare_clippy_lint!
{
/// ### What it does
/// Checks for no-op uses of Option::{as_deref,as_deref_mut},
/// for example, `Option<&T>::as_deref()` returns the same type.
///
/// ### Why is this bad?
/// Redundant code and improving readability.
///
/// ### Example
/// ```rust
/// let a = Some(&1);
/// let b = a.as_deref(); // goes from Option<&i32> to Option<&i32>
/// ```
/// Could be written as:
/// ```rust
/// let a = Some(&1);
/// let b = a;
/// ```
#[clippy::version
=
"1.57.0"
]
pub
NEEDLESS_OPTION_AS_DEREF
,
complexity
,
"no-op use of `deref` or `deref_mut` method to `Option`."
}
declare_lint_pass!
(
OptionNeedlessDeref
=>
[
NEEDLESS_OPTION_AS_DEREF
,
]);
impl
<
'tcx
>
LateLintPass
<
'tcx
>
for
OptionNeedlessDeref
{
fn
check_expr
(
&
mut
self
,
cx
:
&
LateContext
<
'tcx
>
,
expr
:
&
'tcx
Expr
<
'_
>
)
{
if
expr
.span
.from_expansion
()
{
return
;
}
let
typeck
=
cx
.typeck_results
();
let
outer_ty
=
typeck
.expr_ty
(
expr
);
if_chain!
{
if
is_type_diagnostic_item
(
cx
,
outer_ty
,
sym
::
Option
);
if
let
ExprKind
::
MethodCall
(
path
,
[
sub_expr
],
_
)
=
expr
.kind
;
let
symbol
=
path
.ident
.as_str
();
if
symbol
==
"as_deref"
||
symbol
==
"as_deref_mut"
;
if
outer_ty
==
typeck
.expr_ty
(
sub_expr
);
then
{
span_lint_and_sugg
(
cx
,
NEEDLESS_OPTION_AS_DEREF
,
expr
.span
,
"derefed type is same as origin"
,
"try this"
,
snippet_opt
(
cx
,
sub_expr
.span
)
.unwrap
(),
Applicability
::
MachineApplicable
);
}
}
}
}
tests/ui/needless_option_as_deref.fixed
浏览文件 @
182b7c38
// run-rustfix
#[warn(clippy::needless_option_as_deref)]
#![allow(unused)]
#![warn(clippy::needless_option_as_deref)]
fn main() {
// should lint
let _: Option<&usize> = Some(&1);
let _: Option<&mut usize> = Some(&mut 1);
let mut y = 0;
let mut x = Some(&mut y);
let _ = x;
// should not lint
let _ = Some(Box::new(1)).as_deref();
let _ = Some(Box::new(1)).as_deref_mut();
// #7846
let mut i = 0;
let mut opt_vec = vec![Some(&mut i)];
opt_vec[0].as_deref_mut().unwrap();
let mut i = 0;
let x = &mut Some(&mut i);
(*x).as_deref_mut();
// #8047
let mut y = 0;
let mut x = Some(&mut y);
x.as_deref_mut();
dbg!(x);
}
struct S<'a> {
opt: Option<&'a mut usize>,
}
fn from_field<'a>(s: &'a mut S<'a>) -> Option<&'a mut usize> {
s.opt.as_deref_mut()
}
tests/ui/needless_option_as_deref.rs
浏览文件 @
182b7c38
// run-rustfix
#[warn(clippy::needless_option_as_deref)]
#![allow(unused)]
#![warn(clippy::needless_option_as_deref)]
fn
main
()
{
// should lint
let
_
:
Option
<&
usize
>
=
Some
(
&
1
)
.as_deref
();
let
_
:
Option
<&
mut
usize
>
=
Some
(
&
mut
1
)
.as_deref_mut
();
let
mut
y
=
0
;
let
mut
x
=
Some
(
&
mut
y
);
let
_
=
x
.as_deref_mut
();
// should not lint
let
_
=
Some
(
Box
::
new
(
1
))
.as_deref
();
let
_
=
Some
(
Box
::
new
(
1
))
.as_deref_mut
();
// #7846
let
mut
i
=
0
;
let
mut
opt_vec
=
vec!
[
Some
(
&
mut
i
)];
opt_vec
[
0
]
.as_deref_mut
()
.unwrap
();
let
mut
i
=
0
;
let
x
=
&
mut
Some
(
&
mut
i
);
(
*
x
)
.as_deref_mut
();
// #8047
let
mut
y
=
0
;
let
mut
x
=
Some
(
&
mut
y
);
x
.as_deref_mut
();
dbg!
(
x
);
}
struct
S
<
'a
>
{
opt
:
Option
<&
'a
mut
usize
>
,
}
fn
from_field
<
'a
>
(
s
:
&
'a
mut
S
<
'a
>
)
->
Option
<&
'a
mut
usize
>
{
s
.opt
.as_deref_mut
()
}
tests/ui/needless_option_as_deref.stderr
浏览文件 @
182b7c38
error: derefed type is same as origin
--> $DIR/needless_option_as_deref.rs:
7
:29
--> $DIR/needless_option_as_deref.rs:
8
:29
|
LL | let _: Option<&usize> = Some(&1).as_deref();
| ^^^^^^^^^^^^^^^^^^^ help: try this: `Some(&1)`
...
...
@@ -7,10 +7,16 @@ LL | let _: Option<&usize> = Some(&1).as_deref();
= note: `-D clippy::needless-option-as-deref` implied by `-D warnings`
error: derefed type is same as origin
--> $DIR/needless_option_as_deref.rs:
8
:33
--> $DIR/needless_option_as_deref.rs:
9
:33
|
LL | let _: Option<&mut usize> = Some(&mut 1).as_deref_mut();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `Some(&mut 1)`
error: aborting due to 2 previous errors
error: derefed type is same as origin
--> $DIR/needless_option_as_deref.rs:13:13
|
LL | let _ = x.as_deref_mut();
| ^^^^^^^^^^^^^^^^ help: try this: `x`
error: aborting due to 3 previous errors
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录