Skip to content
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

Initial implementation of possible shortcircuiting collect lint #2077

Closed
wants to merge 10 commits into from

Conversation

marcusklaas
Copy link
Contributor

@marcusklaas marcusklaas commented Sep 20, 2017

This lint detects collect calls that generate collections of Option or Result and suggests instead collect into a Option<C> or Result<C, _> respectively, which has personally almost always been what I intend to do. Since this shortcircuiting feature of collect is not very discoverable, I believe this lint has some value.

There may be cases where one really does want a collection of result/ option, in which case this lint will produce a false positive. How should we deal with those? Below is a non-exhaustive list of options:

  • make the lint allow by default
  • only trigger lint when the iterator item type and its enclosing function type match (either both options or of some type Result<_, E>)
  • do not trigger lint when it is explicitly stated that we want a collection of options/ results, for example in
let collection: Vec<Option<_>> = some_iter().collect();

Oh, and mega thanks to @eddyb for his gracious guidance through the labyrinths of the rust compiler on the rust IRC!

Copy link
Contributor

@oli-obk oli-obk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say we go with an allow by default lint until we've run it on a few codebases

26 | let _result: Vec<_> = a.iter().map(Some).collect();
| ^^^^^^
|
help: if you are only interested in the `Some` values or the first `None`, try
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The message about the first None seems a little weird

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Fixed.

error_variant: "None",
})
} else if match_type(cx, normal_ty, &paths::RESULT) {
Some(Suggestion {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these lowercase?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed.

@oli-obk
Copy link
Contributor

oli-obk commented Oct 26, 2017

ping @marcusklaas

@marcusklaas
Copy link
Contributor Author

Hi! Sorry about leaving this for such a long time. Given this lint's inherent propensity of generating false positives, maybe it's better to just close this?

@oli-obk
Copy link
Contributor

oli-obk commented Oct 26, 2017

Given this lint's inherent propensity of generating false positives, maybe it's better to just close this?

I'd have added it as allow-by-default for now. I like the idea, and maybe we can run it and figure out in which cases we don't want to lint and add them as exceptions

@marcusklaas
Copy link
Contributor Author

Okay. That sounds fair. I will touch up this PR then!

@marcusklaas marcusklaas force-pushed the try-collect branch 3 times, most recently from d18648e to 35cbf2f Compare October 26, 2017 14:02
@marcusklaas
Copy link
Contributor Author

Build failure seems unrelated to PR. Master branch also fails to build.

@oli-obk
Copy link
Contributor

oli-obk commented Apr 3, 2018

Could you rebase this and use the declare_clippy_lint macro and make this lint a nursery lint?

@mati865
Copy link
Contributor

mati865 commented Jun 7, 2018

@marcusklaas ping

@marcusklaas
Copy link
Contributor Author

marcusklaas commented Jun 7, 2018 via email

@oli-obk
Copy link
Contributor

oli-obk commented Jun 7, 2018

Does somebody else want to take over? idk what the brokenness is, but it would be a shame to let this PR go to waste! It was pretty close to merging already during it's history, we should be able to get it there again.

@marcusklaas
Copy link
Contributor Author

marcusklaas commented Jun 7, 2018 via email

@flip1995
Copy link
Member

flip1995 commented Jun 8, 2018

Rebased it and fixed a few bugs, which caused ICEs in the ui/infinite_iter and the dogfood test.

@flip1995
Copy link
Member

flip1995 commented Jun 8, 2018

This lint still produces an ICE in rustfmt (travis).

This error is produced by this line:

https://github.com/marcusklaas/rust-clippy/blob/36993f89598e45ff7007568d0d188e7311c785d8/clippy_lints/src/collect.rs#L121-L124

@phansch
Copy link
Member

phansch commented Jun 8, 2018

Judging by the ICE message and the documentation of TyCtxt.normalize_erasing_regions, I think it's safe to say that the "normalization failed" path was hit. Possibly somewhere in rustc-rayon?

@phansch phansch added the S-blocked Status: marked as blocked ❌ on something else such as an RFC or other implementation work label Aug 30, 2018
@phansch
Copy link
Member

phansch commented Dec 2, 2018

Rebased it on master again, let's see if it still fails

@phansch phansch removed the S-blocked Status: marked as blocked ❌ on something else such as an RFC or other implementation work label Dec 4, 2018
@@ -69,11 +75,11 @@ struct Suggestion {

fn format_suggestion_pattern<'a, 'tcx>(
cx: &LateContext<'a, 'tcx>,
collection_ty: &TypeVariants,
collection_ty: &TyKind<'_>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TyKind should never be used directly, you can write Ty instead.
@Manishearth @oli-obk I think clippy might have a general problem wrt this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another box for rust-lang/rust#49509

@@ -84,7 +90,7 @@ fn format_suggestion_pattern<'a, 'tcx>(

buf
},
TypeVariants::TyParam(p) => p.to_string(),
TyKind::Param(p) => p.to_string(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should write these as e.g. ty::Param.

@phansch
Copy link
Member

phansch commented Dec 5, 2018

Removed the usage of TyKind in 5b7c206.

The ICE in rustfmt/rls is still there and it's caused by an incorrect use of normalize_erasing_regions here:

let assoc_item_id = assoc_item.def_id;
let substitutions = cx.tcx.mk_substs_trait(arg_ty, &[]);
let projection = cx.tcx.mk_projection(assoc_item_id, substitutions);
let normal_ty = cx.tcx.normalize_erasing_regions(
cx.param_env,
projection,
);

I'm not sure what exactly needs to be fixed, but I will try to fix it later today.

@phansch phansch self-assigned this Dec 5, 2018
@phansch phansch added the S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) label Dec 6, 2018
@bors
Copy link
Contributor

bors commented Dec 12, 2018

☔ The latest upstream changes (presumably #3529) made this pull request unmergeable. Please resolve the merge conflicts.

@flip1995
Copy link
Member

ping from triage @phansch: Any updates on this? It seems that this just needs a stderr update.

@phansch
Copy link
Member

phansch commented Dec 28, 2018

thanks @flip1995, that's news to me. I think I got stuck on fixing the ICE last time but it indeed appears to be gone. I will have another look today.

@phansch
Copy link
Member

phansch commented Dec 28, 2018

So, currently compiling rustc-rayon fails with the previous ICE. The last time I tried, I failed to extract a minimal repro from rustc-rayon but I'm going to try it again tomorrow.

@bors
Copy link
Contributor

bors commented Jan 3, 2019

☔ The latest upstream changes (presumably #3603) made this pull request unmergeable. Please resolve the merge conflicts.

@bors
Copy link
Contributor

bors commented Jan 7, 2019

☔ The latest upstream changes (presumably #3600) made this pull request unmergeable. Please resolve the merge conflicts.

@phansch phansch closed this Apr 17, 2019
@phansch phansch reopened this Apr 17, 2019
@bors
Copy link
Contributor

bors commented Apr 18, 2019

☔ The latest upstream changes (presumably #3968) made this pull request unmergeable. Please resolve the merge conflicts.

@flip1995
Copy link
Member

flip1995 commented Jun 6, 2019

half yearly ping @phansch. Should we S-inactive-closed this PR? 😄

@phansch phansch removed their assignment Jun 6, 2019
@phansch
Copy link
Member

phansch commented Jun 6, 2019

Yeah, makes sense! I currently don't have time to continue this. IIRC, if someone wants to continue this, they should try to find a minimal repro of the ICE that doesn't require rustc-rayon and go on fixing the remaining issues from there.

@phansch phansch closed this Jun 6, 2019
@phansch phansch added S-inactive-closed Status: Closed due to inactivity and removed S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Jun 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-inactive-closed Status: Closed due to inactivity
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants