Add option-env-unwrap
lint
This commit is contained in:
parent
4ad6fb3fb0
commit
be1bc571c3
@ -1276,6 +1276,7 @@ Released 2018-09-13
|
|||||||
[`op_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#op_ref
|
[`op_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#op_ref
|
||||||
[`option_and_then_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_and_then_some
|
[`option_and_then_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_and_then_some
|
||||||
[`option_as_ref_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref
|
[`option_as_ref_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref
|
||||||
|
[`option_env_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_env_unwrap
|
||||||
[`option_expect_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_expect_used
|
[`option_expect_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_expect_used
|
||||||
[`option_map_or_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_or_none
|
[`option_map_or_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_or_none
|
||||||
[`option_map_unit_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unit_fn
|
[`option_map_unit_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unit_fn
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
|
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
|
||||||
|
|
||||||
[There are 354 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
|
[There are 355 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
|
||||||
|
|
||||||
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
|
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
|
||||||
|
|
||||||
|
@ -267,6 +267,7 @@ pub mod no_effect;
|
|||||||
pub mod non_copy_const;
|
pub mod non_copy_const;
|
||||||
pub mod non_expressive_names;
|
pub mod non_expressive_names;
|
||||||
pub mod open_options;
|
pub mod open_options;
|
||||||
|
pub mod option_env_unwrap;
|
||||||
pub mod overflow_check_conditional;
|
pub mod overflow_check_conditional;
|
||||||
pub mod panic_unimplemented;
|
pub mod panic_unimplemented;
|
||||||
pub mod partialeq_ne_impl;
|
pub mod partialeq_ne_impl;
|
||||||
@ -713,6 +714,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
&non_expressive_names::MANY_SINGLE_CHAR_NAMES,
|
&non_expressive_names::MANY_SINGLE_CHAR_NAMES,
|
||||||
&non_expressive_names::SIMILAR_NAMES,
|
&non_expressive_names::SIMILAR_NAMES,
|
||||||
&open_options::NONSENSICAL_OPEN_OPTIONS,
|
&open_options::NONSENSICAL_OPEN_OPTIONS,
|
||||||
|
&option_env_unwrap::OPTION_ENV_UNWRAP,
|
||||||
&overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL,
|
&overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL,
|
||||||
&panic_unimplemented::PANIC,
|
&panic_unimplemented::PANIC,
|
||||||
&panic_unimplemented::PANIC_PARAMS,
|
&panic_unimplemented::PANIC_PARAMS,
|
||||||
@ -1003,6 +1005,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
let max_fn_params_bools = conf.max_fn_params_bools;
|
let max_fn_params_bools = conf.max_fn_params_bools;
|
||||||
let max_struct_bools = conf.max_struct_bools;
|
let max_struct_bools = conf.max_struct_bools;
|
||||||
store.register_early_pass(move || box excessive_bools::ExcessiveBools::new(max_struct_bools, max_fn_params_bools));
|
store.register_early_pass(move || box excessive_bools::ExcessiveBools::new(max_struct_bools, max_fn_params_bools));
|
||||||
|
store.register_early_pass(|| box option_env_unwrap::OptionEnvUnwrap);
|
||||||
|
|
||||||
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
|
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
|
||||||
LintId::of(&arithmetic::FLOAT_ARITHMETIC),
|
LintId::of(&arithmetic::FLOAT_ARITHMETIC),
|
||||||
@ -1285,6 +1288,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
LintId::of(&non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
|
LintId::of(&non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
|
||||||
LintId::of(&non_expressive_names::MANY_SINGLE_CHAR_NAMES),
|
LintId::of(&non_expressive_names::MANY_SINGLE_CHAR_NAMES),
|
||||||
LintId::of(&open_options::NONSENSICAL_OPEN_OPTIONS),
|
LintId::of(&open_options::NONSENSICAL_OPEN_OPTIONS),
|
||||||
|
LintId::of(&option_env_unwrap::OPTION_ENV_UNWRAP),
|
||||||
LintId::of(&overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
|
LintId::of(&overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
|
||||||
LintId::of(&panic_unimplemented::PANIC_PARAMS),
|
LintId::of(&panic_unimplemented::PANIC_PARAMS),
|
||||||
LintId::of(&partialeq_ne_impl::PARTIALEQ_NE_IMPL),
|
LintId::of(&partialeq_ne_impl::PARTIALEQ_NE_IMPL),
|
||||||
@ -1590,6 +1594,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
LintId::of(&non_copy_const::BORROW_INTERIOR_MUTABLE_CONST),
|
LintId::of(&non_copy_const::BORROW_INTERIOR_MUTABLE_CONST),
|
||||||
LintId::of(&non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST),
|
LintId::of(&non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST),
|
||||||
LintId::of(&open_options::NONSENSICAL_OPEN_OPTIONS),
|
LintId::of(&open_options::NONSENSICAL_OPEN_OPTIONS),
|
||||||
|
LintId::of(&option_env_unwrap::OPTION_ENV_UNWRAP),
|
||||||
LintId::of(&ptr::MUT_FROM_REF),
|
LintId::of(&ptr::MUT_FROM_REF),
|
||||||
LintId::of(®ex::INVALID_REGEX),
|
LintId::of(®ex::INVALID_REGEX),
|
||||||
LintId::of(&serde_api::SERDE_API_MISUSE),
|
LintId::of(&serde_api::SERDE_API_MISUSE),
|
||||||
|
55
clippy_lints/src/option_env_unwrap.rs
Normal file
55
clippy_lints/src/option_env_unwrap.rs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
use crate::utils::{is_direct_expn_of, span_lint_and_help};
|
||||||
|
use if_chain::if_chain;
|
||||||
|
use rustc::lint::in_external_macro;
|
||||||
|
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||||
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use syntax::ast::*;
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
/// **What it does:** Checks for usage of `option_env!(...).unwrap()` and
|
||||||
|
/// suggests usage of the `env!` macro.
|
||||||
|
///
|
||||||
|
/// **Why is this bad?** Unwrapping the result of `option_env!` will panic
|
||||||
|
/// at run-time if the environment variable doesn't exist, whereas `env!`
|
||||||
|
/// catches it at compile-time.
|
||||||
|
///
|
||||||
|
/// **Known problems:** None.
|
||||||
|
///
|
||||||
|
/// **Example:**
|
||||||
|
///
|
||||||
|
/// ```rust,no_run
|
||||||
|
/// let _ = option_env!("HOME").unwrap();
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Is better expressed as:
|
||||||
|
///
|
||||||
|
/// ```rust,no_run
|
||||||
|
/// let _ = env!("HOME");
|
||||||
|
/// ```
|
||||||
|
pub OPTION_ENV_UNWRAP,
|
||||||
|
correctness,
|
||||||
|
"using `option_env!(...).unwrap()` to get environment variable"
|
||||||
|
}
|
||||||
|
|
||||||
|
declare_lint_pass!(OptionEnvUnwrap => [OPTION_ENV_UNWRAP]);
|
||||||
|
|
||||||
|
impl EarlyLintPass for OptionEnvUnwrap {
|
||||||
|
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||||
|
if_chain! {
|
||||||
|
if !in_external_macro(cx.sess, expr.span);
|
||||||
|
if let ExprKind::MethodCall(path_segment, args) = &expr.kind;
|
||||||
|
if path_segment.ident.as_str() == "unwrap";
|
||||||
|
if let ExprKind::Call(caller, _) = &args[0].kind;
|
||||||
|
if is_direct_expn_of(caller.span, "option_env").is_some();
|
||||||
|
then {
|
||||||
|
span_lint_and_help(
|
||||||
|
cx,
|
||||||
|
OPTION_ENV_UNWRAP,
|
||||||
|
expr.span,
|
||||||
|
"this will panic at run-time if the environment variable doesn't exist",
|
||||||
|
"consider using the `env!` macro instead"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,7 @@ pub use lint::Lint;
|
|||||||
pub use lint::LINT_LEVELS;
|
pub use lint::LINT_LEVELS;
|
||||||
|
|
||||||
// begin lint list, do not remove this comment, it’s used in `update_lints`
|
// begin lint list, do not remove this comment, it’s used in `update_lints`
|
||||||
pub const ALL_LINTS: [Lint; 354] = [
|
pub const ALL_LINTS: [Lint; 355] = [
|
||||||
Lint {
|
Lint {
|
||||||
name: "absurd_extreme_comparisons",
|
name: "absurd_extreme_comparisons",
|
||||||
group: "correctness",
|
group: "correctness",
|
||||||
@ -1498,6 +1498,13 @@ pub const ALL_LINTS: [Lint; 354] = [
|
|||||||
deprecation: None,
|
deprecation: None,
|
||||||
module: "methods",
|
module: "methods",
|
||||||
},
|
},
|
||||||
|
Lint {
|
||||||
|
name: "option_env_unwrap",
|
||||||
|
group: "correctness",
|
||||||
|
desc: "using `option_env!(...).unwrap()` to get environment variable",
|
||||||
|
deprecation: None,
|
||||||
|
module: "option_env_unwrap",
|
||||||
|
},
|
||||||
Lint {
|
Lint {
|
||||||
name: "option_expect_used",
|
name: "option_expect_used",
|
||||||
group: "restriction",
|
group: "restriction",
|
||||||
|
12
tests/ui/option_env_unwrap.rs
Normal file
12
tests/ui/option_env_unwrap.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#![warn(clippy::option_env_unwrap)]
|
||||||
|
|
||||||
|
macro_rules! option_env_unwrap {
|
||||||
|
($env: expr) => {
|
||||||
|
option_env!($env).unwrap()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _ = option_env!("HOME").unwrap();
|
||||||
|
let _ = option_env_unwrap!("HOME");
|
||||||
|
}
|
23
tests/ui/option_env_unwrap.stderr
Normal file
23
tests/ui/option_env_unwrap.stderr
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
error: this will panic at run-time if the environment variable doesn't exist
|
||||||
|
--> $DIR/option_env_unwrap.rs:10:13
|
||||||
|
|
|
||||||
|
LL | let _ = option_env!("HOME").unwrap();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::option-env-unwrap` implied by `-D warnings`
|
||||||
|
= help: consider using the `env!` macro instead
|
||||||
|
|
||||||
|
error: this will panic at run-time if the environment variable doesn't exist
|
||||||
|
--> $DIR/option_env_unwrap.rs:5:9
|
||||||
|
|
|
||||||
|
LL | option_env!($env).unwrap()
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | let _ = option_env_unwrap!("HOME");
|
||||||
|
| -------------------------- in this macro invocation
|
||||||
|
|
|
||||||
|
= help: consider using the `env!` macro instead
|
||||||
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user