Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # 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