-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add lint for opt.map_or(None, f) #2128
Conversation
Change to Warn and add multiline support Fix typo Update reference
clippy_lints/src/methods.rs
Outdated
pub OPTION_MAP_OR_NONE, | ||
Warn, | ||
"using `Option.map_or(None, f)`, which is more succinctly expressed as \ | ||
`map_or_else(g, f)`" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copy paste error
clippy_lints/src/methods.rs
Outdated
/// lint use of `_.map_or(None, _)` for `Option`s | ||
fn lint_map_or_none<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, map_or_args: &'tcx [hir::Expr]) { | ||
// check if the first non-self argument to map_or() is None | ||
let map_or_arg_is_none = if let hir::Expr_::ExprPath(ref qpath) = map_or_args[1].node { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to ensure that the type is Option
before doing this check. Otherwise a random type with a map_or
function can cause this lint to panic if the map_or
has zero arguments (so just the self).
clippy_lints/src/methods.rs
Outdated
`and_then(f)` instead"; | ||
let map_or_none_snippet = snippet(cx, map_or_args[1].span, ".."); | ||
let map_or_func_snippet = snippet(cx, map_or_args[2].span, ".."); | ||
let multiline = map_or_func_snippet.lines().count() > 1 || map_or_none_snippet.lines().count() > 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please get rid of the multiline check (I know all the others still do it, but they are rather old lints). Use span_lint_and_then
+ span_suggestion
to produce the suggestion. Rustc will take care of the rest.
I think we can move out a whole chunk of tests. But don't worry about it in this PR. |
- Fix copy-paste error - Check for opt.map_or argument after ensuring that opt is an Option - Use span_lint_and_then and span_suggestion - Update reference
Thanks for addressing my comments so fast! |
You are welcome. Thanks for reviewing the pull request. |
… -> Option Result<T, E> has an `ok()` method that adapts a Result<T,E> into an Option<T>. It's possible to get around this adapter by writing Result<T,E>.map_or(None, Some). This lint is implemented as a new variant of the existing [`option_map_none` lint](rust-lang#2128)
Add new lint for `Result<T, E>.map_or(None, Some(T))` Fixes rust-lang#5414 PR Checklist --- - [x] Followed lint naming conventions (the name is a bit awkward, but it seems to conform) - [x] Added passing UI tests (including committed .stderr file) - [x] cargo test passes locally - [x] Executed cargo dev update_lints - [x] Added lint documentation - [x] Run cargo dev fmt `Result<T, E>` has an [`ok()`](https://doc.rust-lang.org/std/result/enum.Result.html#method.ok) method that adapts a `Result<T,E>` into an `Option<T>`. It's possible to get around this adapter by writing `Result<T,E>.map_or(None, Some)`. This lint is implemented as a new variant of the existing [`option_map_none` lint](rust-lang#2128)
Add new lint for `Result<T, E>.map_or(None, Some(T))` Fixes rust-lang#5414 PR Checklist --- - [x] Followed lint naming conventions (the name is a bit awkward, but it seems to conform) - [x] Added passing UI tests (including committed .stderr file) - [x] cargo test passes locally - [x] Executed cargo dev update_lints - [x] Added lint documentation - [x] Run cargo dev fmt `Result<T, E>` has an [`ok()`](https://doc.rust-lang.org/std/result/enum.Result.html#method.ok) method that adapts a `Result<T,E>` into an `Option<T>`. It's possible to get around this adapter by writing `Result<T,E>.map_or(None, Some)`. This lint is implemented as a new variant of the existing [`option_map_none` lint](rust-lang#2128)
… -> Option Result<T, E> has an `ok()` method that adapts a Result<T,E> into an Option<T>. It's possible to get around this adapter by writing Result<T,E>.map_or(None, Some). This lint is implemented as a new variant of the existing [`option_map_none` lint](rust-lang#2128)
… -> Option Result<T, E> has an `ok()` method that adapts a Result<T,E> into an Option<T>. It's possible to get around this adapter by writing Result<T,E>.map_or(None, Some). This lint is implemented as a new variant of the existing [`option_map_none` lint](rust-lang#2128)
… -> Option Result<T, E> has an `ok()` method that adapts a Result<T,E> into an Option<T>. It's possible to get around this adapter by writing Result<T,E>.map_or(None, Some). This lint is implemented as a new variant of the existing [`option_map_none` lint](rust-lang#2128)
fixes #2113
I don't know if my formatting is correct, since running rustfmt would have changed code which was not written by me. Furthermore, I hope that the implementation is correct, since this is the first time I had a look at the clippy internals.
Also, I saw that there is a move towards splitting the
methods.rs
into mutliple files. Maybe it would be sensible to move the code from this commit into another file.