fix ice reporting in lintcheck
Fixes https://github.com/rust-lang/rust-clippy/issues/12185
This PR fixes the lack of reported ICEs within lintcheck by modifying the way in which data is collected from each crate being linted.
Instead of lintcheck only reading `stdout` for warnings, it now also reads `stderr` for any potential ICE (although admittedly, it is not the cleanest method of doing so). If it is detected, it parses the ICE into its message and backtrace separately, and then adds them to the list of outputs via clippy.
Once all outputs are collected, the formatter then proceeds to generate the file as normal.
Note that this PR also has a couple of side effects:
- When clippy fails to process a package, but said failure is not an ICE, the `stderr` will be sent to the console;
- Instead of `ClippyWarning` being the primary struct for everything reported, there is now `ClippyCheckOutput`, an enum which splits the outputs into warnings and ICEs.
changelog: none
Allow `cast` lints in macros
closes: #11738
Removed the `from_expansion` guard clause for cast lints, so that these warnings can be generated for internal macros.
changelog: allow `cast` lints in macros
type certainty: clear `DefId` when an expression's type changes to non-adt
Fixes#12585
The root cause of the ICE in the linked issue was in the expression `one.x`, in the array literal.
The type of `one` is the `One` struct: an adt with a DefId, so its certainty is `Certain(def_id_of_one)`. However, the field access `.x` can then change the type (to `i32` here) and that should update that `DefId` accordingly. It does do that correctly when `one.x` would be another adt with a DefId:
97ba291d5a/clippy_utils/src/ty/type_certainty/mod.rs (L90-L91)
but when it *isn't* an adt and there is no def id (which is the case in the linked issue: `one.x` is an i32), it keeps the `DefId` of `One`, even though that's the wrong type (which would then lead to a contradiction later when joining `Certainty`s):
97ba291d5a/clippy_utils/src/ty/type_certainty/mod.rs (L92-L93)
In particular, in the linked issue, `from_array([one.x, two.x])` would try to join the `Certainty` of the two array elements, which *should* have been `[Certain(None), Certain(None)]`, because `i32`s have no `DefId`, but instead it was `[Certain(One), Certain(Two)]`, because the DefId wasn't cleared from when it was visiting `one` and `two`. This is the "contradiction" that could be seen in the ICE message
... so this changes it to clear the `DefId` when it isn't an adt.
cc `@smoelius` you implemented this initially in #11135, does this change make sense to you?
changelog: none
Reword `arc_with_non_send_sync` note and help messages
Addresses https://github.com/rust-lang/rust-clippy/issues/12608#issuecomment-2029688054
Makes the note more concise and reframes the `Rc` suggestion around whether it crosses threads currently due to a manual `Send`/`Sync` impl or may do in the future
changelog: none
FIX(12334): manual_swap auto fix
Fixed: #12334
Initialization expressions are now generated as needed if the slice index is bound to a variable.
----
changelog: Fix [`manual_swap`]
Do not suggest `assigning_clones` in `Clone` impl
This PR modifies `assigning_clones` to detect situations where the `clone` call is inside a `Clone` impl, and avoids suggesting the lint in such situations.
r? `@blyxyas`
Fixes: https://github.com/rust-lang/rust-clippy/issues/12600
changelog: Do not invoke `assigning_clones` inside `Clone` impl
rename ptr::from_exposed_addr -> ptr::with_exposed_provenance
As discussed on [Zulip](https://rust-lang.zulipchat.com/#narrow/stream/136281-t-opsem/topic/To.20expose.20or.20not.20to.20expose/near/427757066).
The old name, `from_exposed_addr`, makes little sense as it's not the address that is exposed, it's the provenance. (`ptr.expose_addr()` stays unchanged as we haven't found a better option yet. The intended interpretation is "expose the provenance and return the address".)
The new name nicely matches `ptr::without_provenance`.
avoid an ICE in `ptr_as_ptr` when getting the def_id of a local
Fixes#12616
`Res::def_id` can panic, so avoid calling it in favor of `opt_def_id`, so we can gracefully handle resolutions that don't have a `DefId` (e.g. local variables) and get a false negative in the worst case, rather than an ICE
changelog: Fix ICE in [`ptr_as_ptr`] when the cast expression is a function call to a local variable
Initialization expressions are now generated when index is bound to a variable.
FIX: Check to see if variables are used after swap
FIX: rename StmtKind::Local to StmtKind::Let
Pause review rotation for y21
Exams are coming up for me and I want to focus on that, so I'd like to pause PR assignments to me for a bit until that's over (will still continue to look at PRs that are assigned to me and might steal some PRs to review if I find the time). :)
--------------
changelog: none
Elide unit variables linted by `let_unit` and use `()` directly instead
Situation: `let_unit` lints when an expression binds a unit (`()`) to a variable. In some cases this binding may be passed down to another function. Currently, the lint removes the binding without considering usage.
fixes: #12594
changelog: Suggestion Fix [`let_unit`]. Clippy will remove unit bindings and replace all their instances in the body with `()`.
Ignore `rustc-ice-` files
When ui-test detects a crash, it writes it into a `rustc-ice-*` file. I find it a bit annoying that git always want's to add them. So this just adds these files to our `.gitignore` :D
---
changelog: none
accept `String` in `span_lint*` functions directly to avoid unnecessary clones
context: https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/Accepting.20.60Into.3C.7BSub.7DdiagMessage.3E.60.20in.20.60span_lint*.60.20functions/near/425703273
tldr: the `span_lint*` functions now accept both `String`s, which are then reused and not recloned like before, and also `&'static str`, in which case it [doesn't need to allocate](https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_error_messages/lib.rs.html#359).
Previously, it accepted `&str` and would always call `.to_string()`, which is worse in any case: it allocates for `&'static str` and forces a clone even if the caller already has a `String`.
---------
This PR has a massive diff, but the only interesting change is in the first commit, which changes the message/help/note parameter in the `span_lint*` functions to not take a `&str`, but an `impl Into<DiagMessage>`.
The second commit changes all of the errors that now occur:
- `&format!(...)` cannot be passed to `span_lint` anymore. Instead, we now simply pass `format!()` directly.
- `Into<DiagMessage>` can be `&'static str`, but not any `&str`. So this requires changing a bunch of other `&str` to `&'static str` at call sites as well.
- Added [`Sugg::into_string`](9fc88bc285/clippy_utils/src/sugg.rs (L362)), which, as opposed to `Sugg::to_string`, can take advantage of the fact that it takes ownership and is able to reuse the `String`
changelog: none
Situation: `let_unit` lints when an expression binds a unit (`()`)
to a variable. In some cases this binding may be passed down to
another function. Currently, the lint removes the binding without
considering usage.
Change: All usages of the elided variable are now replaced with `()`.
fixes: #12594
Move `box_default` to style, do not suggest turbofishes
`Box::default()` [had its `#[rustc_box]` attribute removed](https://github.com/rust-lang/rust/pull/108476/files#r1120930164) in 1.69 so is no longer a perf related lint
The lint is moved to style but no longer produces suggestions containing turbofishes, as they're often longer/more annoying to type
changelog: [`box_default`]: Move to style
r? `@llogiq`
`Box::default()` had its `#[rustc_box]` attribute removed in 1.69 so is
no longer a perf related lint
The lint is moved to style but no longer produces suggestions containing
turbofishes, as they're often longer/more annoying to type
Allow `filter_map_identity` when the closure is typed
This extends the `filter_map_identity` lint to support typed closures.
For untyped closures, we know that the program compiles, and therefore we can safely suggest using flatten.
For typed closures, they may participate in type resolution. In this case we use `Applicability::MaybeIncorrect`.
Details:
https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/Should.20.60filter_map_identity.60.20lint.20when.20closures.20are.20typed.3F
changelog: `filter_map_identity` will now suggest using flatten for typed closures.
r? `@y21` && `@Centri3`
[`type_id_on_box`]: lint on any `Box<dyn _>`
Closes#11349.
It now not only lints when calling `.type_id()` on the type `Box<dyn Any>`, but also on any `Box<dyn Trait>` where `Trait` is a subtrait of `Any`
changelog: FN: [`type_id_on_box`]: lint if `Any` is a sub trait
new lint `legacy_numeric_constants`
Rework of #10997
- uses diagnostic items
- does not lint imports of the float modules (`use std::f32`)
- does not lint usage of float constants that look like `f32::MIN`
I chose to make the float changes because the following pattern is actually pretty useful
```rust
use std::f32;
let omega = freq * 2 * f32::consts::PI;
```
and the float modules are not TBD-deprecated like the integer modules.
Closes#10995
---
changelog: New lint [`legacy_numeric_constants`]
[#12312](https://github.com/rust-lang/rust-clippy/pull/12312)
make sure checked type implements `Try` trait when linting [`question_mark`]
(indirectly) fixes: #12412 and fixes: #11983
---
changelog: make sure checked type implements `Try` trait when linting [`question_mark`]
restrict manual_clamp to const case, bring it out of nursery
Implements the plan that I described in https://github.com/rust-lang/rust-clippy/pull/9484#issuecomment-1374522054
This does two things primarily
1. Restrict `manual_clamp` such that it will only trigger if we are able to guarantee that `clamp` won't panic at runtime.
2. Bring `manual_clamp` out of nursery status and move it into the complexity group.
changelog: [`manual_clamp`]: Restrict this lint such that it only triggers if max and min are const, and max is greater than or equal to min. Then bring it out of the nursery group.
Fix typo in comment
Thank you for making Clippy better!
We're collecting our changelog from pull request descriptions.
If your PR only includes internal changes, you can just write
`changelog: none`. Otherwise, please write a short comment
explaining your change.
It's also helpful for us that the lint name is put within backticks (`` ` ` ``),
and then encapsulated by square brackets (`[]`), for example:
```
changelog: [`lint_name`]: your change
```
If your PR fixes an issue, you can add `fixes #issue_number` into this
PR description. This way the issue will be automatically closed when
your PR is merged.
If you added a new lint, here's a checklist for things that will be
checked during review or continuous integration.
- \[x] Followed [lint naming conventions][lint_naming]
- \[ ] Added passing UI tests (including committed `.stderr` file)
- \[ ] `cargo test` passes locally
- \[ ] Executed `cargo dev update_lints`
- \[ ] Added lint documentation
- \[x] Run `cargo dev fmt`
[lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
Note that you can skip the above if you are just opening a WIP PR in
order to get feedback.
Delete this line and everything above before opening your PR.
---
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog: None
`large_stack_frames`: print total size and largest component.
Instead of just saying “this function's stack frame is big”, report:
* the (presumed) size of the frame
* the size and type of the largest local contributing to that size
* the configurable limit that was exceeded (once)
Known issues:
* The lint may report an over-estimate because codegen may be able to overlap some of these locals. However, that already affected whether the lint fired at all; I believe this change is still an improvement because it gives the user much more actionable information about _why_ the lint fired.
* Please tell me a better way to determine whether a local has a variable name.
changelog: [`large_stack_frames`]: print total size and largest component.
Instead of just saying “this function's stack frame is big”, report:
* the (presumed) size of the frame
* the size and type of the largest local contributing to that size
* the configurable limit that was exceeded (once)