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

option_if_let_else suggestion inapplicable when mutable borrow or owned value is used in both branches #5822

Closed
Arnavion opened this issue Jul 19, 2020 · 5 comments · Fixed by #7573
Labels
C-bug Category: Clippy is not doing the correct thing E-hard Call for participation: This a hard problem and requires more experience or effort to work on I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied

Comments

@Arnavion
Copy link
Contributor

#[deny(clippy::option_if_let_else)]
pub fn foo(o: Option<i32>, mut f: impl FnMut(i32)) {
    if let Some(i) = o {
        f(i)
    }
    else {
        f(5)
    }
}

Apart from having the same problem as #5821, in this particular case even the suggestion of o.map_or_else(|| f(5), |i| f(i)) would be wrong because f is being used as a &mut, so it cannot be used with two closures at the same time. This also happens for f: impl FnOnce(i32).

I don't think there's any better way to write this code using any of the Option combinators, so it seems to be the lint should not fire at all.

Meta

  • cargo clippy -V: clippy 0.0.212 (39d5a61 2020-07-17)
  • rustc -Vv:
    rustc 1.47.0-nightly (39d5a61f2 2020-07-17)
    binary: rustc
    commit-hash: 39d5a61f2e4e237123837f5162cc275c2fd7e625
    commit-date: 2020-07-17
    host: x86_64-unknown-linux-gnu
    release: 1.47.0-nightly
    LLVM version: 10.0
    
@Arnavion Arnavion added the C-bug Category: Clippy is not doing the correct thing label Jul 19, 2020
@flip1995 flip1995 added E-hard Call for participation: This a hard problem and requires more experience or effort to work on I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied labels Jul 28, 2020
@rail-rain
Copy link
Contributor

I've found a real world example inside Clippy where presumably this bug led to an incorrect use of crate::util::snippet_with_applicability, which slipped into the code base along with the lint itself. I'm not sure whether we should immediately revert the change with #[allow(clippy::option_if_let_else)] for the time being or can leave it until this issue gets fixed though.

let mut applicability = Applicability::MachineApplicable;
let suggestion = expr.map_or_else(
|| {
applicability = Applicability::HasPlaceholders;
Cow::Borrowed("v")
},
|e| snippet_with_applicability(cx, e.span, "v", &mut Applicability::MachineApplicable),
);

@ebroto
Copy link
Member

ebroto commented Aug 26, 2020

Nice catch! I would say let's allow the lint for now and fix that.

BTW wouldn't this be a nice candidate for a lint? I can't think now of a case where you actually want to pass a &mut to a temporary to a function.

rail-rain added a commit to rail-rain/rust-clippy that referenced this issue Aug 26, 2020
This includes a workaround of the issue rust-lang#5822,
the cause of this little mistake.
bors added a commit that referenced this issue Aug 26, 2020
…=flip1995

Fix the wrong use of `snippet_with_applicability`

For the context, please see #5822 (comment) and #5822 (comment).

---

changelog: none
@rail-rain
Copy link
Contributor

OK, I made a PR for it (and it's just quickly merged while I'm writing this). Thanks for the reply!

Regarding an new lint, it makes sense for me; considering a function taking a mutable reference probably means the reference is some kind of an "out" parameter.

@brightly-salty
Copy link
Contributor

I still have this issue on nightly, I don't know if it's been fixed or not.

@edward-shen
Copy link

I can confirm this issue still exists as I'm running into this on cargo 1.54.0-nightly (e51522ab3 2021-05-07).

bors added a commit that referenced this issue Aug 15, 2021
Downgrade option_if_let_else to nursery

I believe that this lint's loose understanding of ownership (#5822, #6737) makes it unsuitable to be enabled by default in its current state, even as a pedantic lint.

Additionally the lint has known problems with type inference (#6137), though I may be willing to consider this a non-blocker in isolation if it weren't for the ownership false positives.

A fourth false positive involving const fn: #7567.

But on top of these, for me the biggest issue is I basically fully agree with #6137 (comment). In my experience this lint universally makes code worse even when the resulting code does compile.

---

changelog: remove [`option_if_let_else`] from default set of enabled lints
@bors bors closed this as completed in fd30241 Aug 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing E-hard Call for participation: This a hard problem and requires more experience or effort to work on I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants