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)`" |
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.
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.
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.rsinto mutliple files. Maybe it would be sensible to move the code from this commit into another file.