Attach tokens to all AST types used in `Nonterminal`
We perform token capturing when we have outer attributes (for nonterminals that support attributes - e.g. `Stmt`), or when we parse a `Nonterminal` for a `macro_rules!` argument. The full list of `Nonterminals` affected by this PR is:
* `NtBlock`
* `NtStmt`
* `NtTy`
* `NtMeta`
* `NtPath`
* `NtVis`
* `NtLiteral`
Of these nonterminals, only `NtStmt` and `NtLiteral` (which is actually just an `Expr`), support outer attributes - the rest only ever have token capturing perform when they match a `macro_rules!` argument.
This makes progress towards solving https://github.com/rust-lang/rust/issues/43081 - we now collect tokens for everything that might need them. However, we still need to handle `#[cfg]`, inner attributes, and misc pretty-printing issues (e.g. #75734)
I've separated the changes into (mostly) independent commits, which could be split into individual PRs for each `Nonterminal` variant. The purpose of having them all in one PR is to do a single Crater run for all of them.
Most of the changes in this PR are trivial (adding `tokens: None` everywhere we construct the various AST structs). The significant changes are:
* `ast::Visibility` is changed from `type Visibility = Spanned<VisibilityKind>` to a `struct Visibility { kind, span, tokens }`.
* `maybe_collect_tokens` is made generic, and used for both `ast::Expr` and `ast::Stmt`.
* Some of the statement-parsing functions are refactored so that we can capture the trailing semicolon.
* `Nonterminal` and `Expr` both grew by 8 bytes, as some of the structs which are stored inline (rather than behind a `P`) now have an `Option<TokenStream>` field. Hopefully the performance impact of doing this is negligible.
Add lint panic in result
### Change
Adding a new "restriction" lint that will emit a warning when using "panic", "unimplemented" or "unreachable" in a function of type option/result.
### Motivation
Some codebases must avoid crashes at all costs, and hence functions of type option/result must return an error instead of crashing.
### Test plan
Running:
TESTNAME=panic_in_result cargo uitest ---
changelog: none
Improve the "known problems" section of `interior_mutable_key`
* Remove the mention to `Rc` and `Arc` as these are `Freeze` (despite my intuition) so the lint correctly handles already.
* Instead, explain what could cause a false positive, and mention `bytes` as an example.
---
changelog: Improved the "known problems" section of `interior_mutable_key`
improve the suggestion of the lint `unit-arg`
Fixes#5823Fixes#6015
Changes
```
help: move the expression in front of the call...
|
3 | g();
|
help: ...and use a unit literal instead
|
3 | o.map_or((), |i| f(i))
|
```
into
```
help: move the expression in front of the call and replace it with the unit literal `()`
|
3 | g();
| o.map_or((), |i| f(i))
|
```
changelog: improve the suggestion of the lint `unit-arg`
Add CONST_ITEM_MUTATION lint
Fixes#74053Fixes#55721
This PR adds a new lint `CONST_ITEM_MUTATION`.
Given an item `const FOO: SomeType = ..`, this lint fires on:
* Attempting to write directly to a field (`FOO.field = some_val`) or
array entry (`FOO.array_field[0] = val`)
* Taking a mutable reference to the `const` item (`&mut FOO`), including
through an autoderef `FOO.some_mut_self_method()`
The lint message explains that since each use of a constant creates a
new temporary, the original `const` item will not be modified.
* Remove the mention to `Rc` and `Arc` as these are `Freeze`
so the lint correctly handles already.
* Instead, explain what could cause a false positive,
and mention `bytes` as an example.
We no longer lint assignments to const item fields in the
`temporary_assignment` lint, since this is now covered by the
`CONST_ITEM_MUTATION` lint.
Additionally, we `#![allow(const_item_mutation)]` in the
`borrow_interior_mutable_const.rs` test. Clippy UI tests are run with
`-D warnings`, which seems to cause builtin lints to prevent Clippy
lints from running.
Support dataflow problems on arbitrary lattices
This PR implements last of the proposed extensions I mentioned in the design meeting for the original dataflow refactor. It extends the current dataflow framework to work with arbitrary lattices, not just `BitSet`s. This is a prerequisite for dataflow-enabled MIR const-propagation. Personally, I am skeptical of the usefulness of doing const-propagation pre-monomorphization, since many useful constants only become known after monomorphization (e.g. `size_of::<T>()`) and users have a natural tendency to hand-optimize the rest. It's probably worth exprimenting with, however, and others have shown interest cc `@rust-lang/wg-mir-opt.`
The `Idx` associated type is moved from `AnalysisDomain` to `GenKillAnalysis` and replaced with an associated `Domain` type that must implement `JoinSemiLattice`. Like before, each `Analysis` defines the "bottom value" for its domain, but can no longer override the dataflow join operator. Analyses that want to use set intersection must now use the `lattice::Dual` newtype. `GenKillAnalysis` impls have an additional requirement that `Self::Domain: BorrowMut<BitSet<Self::Idx>>`, which effectively means that they must use `BitSet<Self::Idx>` or `lattice::Dual<BitSet<Self::Idx>>` as their domain.
Most of these changes were mechanical. However, because a `Domain` is no longer always a powerset of some index type, we can no longer use an `IndexVec<BasicBlock, GenKillSet<A::Idx>>>` to store cached block transfer functions. Instead, we use a boxed `dyn Fn` trait object. I discuss a few alternatives to the current approach in a commit message.
The majority of new lines of code are to preserve existing Graphviz diagrams for those unlucky enough to have to debug dataflow analyses. I find these diagrams incredibly useful when things are going wrong and considered regressing them unacceptable, especially the pretty-printing of `MovePathIndex`s, which are used in many dataflow analyses. This required a parallel `fmt` trait used only for printing dataflow domains, as well as a refactoring of the `graphviz` module now that we cannot expect the domain to be a `BitSet`. Some features did have to be removed, such as the gen/kill display mode (which I didn't use but existed to mirror the output of the old dataflow framework) and line wrapping. Since I had to rewrite much of it anyway, I took the opportunity to switch to a `Visitor` for printing dataflow state diffs instead of using cursors, which are error prone for code that must be generic over both forward and backward analyses. As a side-effect of this change, we no longer have quadratic behavior when writing graphviz diagrams for backward dataflow analyses.
r? `@pnkfelix`
Fix FP in `same_item_push`
Don't emit a lint when the pushed item doesn't have Clone trait
Fix#5979
changelog: Fix FP in `same_item_push` not to emit a lint when the pushed item doesn't have Clone trait
useless_attribute: Permit wildcard_imports and enum_glob_use
Fixes#5918
changelog: `useless_attribute`: Permit `wildcard_imports` and `enum_glob_use` on `use` items
default_trait_access: Fix wrong suggestion
https://github.com/rust-lang/rust-clippy/issues/5975#issuecomment-683751131
> I think the underlying problem is clippy suggests code with complete parameters, not clippy triggers this lint even for complex types. AFAIK, If code compiles with `Default::default`, it doesn't need to specify any parameters, as type inference is working. (So, in this case, `default_trait_access` should suggest `RefCell::default`.)
Fixes#5975Fixes#5990
changelog: `default_trait_access`: fixed wrong suggestion
Add a lint for an async block/closure that yields a type that is itself awaitable.
This catches bugs of the form
tokio::spawn(async move {
let f = some_async_thing();
f // Oh no I forgot to await f so that work will never complete.
});
See the two XXXkhuey comments and the unfixed `_l` structure for things that need more thought.
*Please keep the line below*
changelog: none
or_fn_call: ignore nullary associated const fns
The fix in #5889 was missing associated functions.
changelog: Ignore also `const fn` methods in [`or_fun_call`]
Fixes#5693
This catches bugs of the form
tokio::spawn(async move {
let f = some_async_thing();
f // Oh no I forgot to await f so that work will never complete.
});
Fix FP in `to_string_in_display`
Don't emit a lint when `.to_string()` on anything that is not `self`
Fix#5967
changelog: Fix FP in `to_string_in_display` when calling `.to_string()` on anything that is not `self`
Corrects the float_equality_without_abs lint
Fixes an issue in the `float_equality_without_abs` lint. The lint suggestion was configured in a way that it lints the whole error and not just the subtraction part. In the current configuration the lint would suggest to change the expression in a wrong way, e.g.
```rust
let _ = (a - b) < f32::EPSILON; // before
let _ = (a - b).abs(); // after
```
This was dicovered by @flip1995. (See discussion of PR #5952).
Also the suggestion is now formatted via `utils::sugg`.
changelog: none
Fix `let_and_return` bad suggestion
Add a cast to the suggestion when the return expression has adjustments.
These adjustments are lost when the suggestion is applied.
This is similar to the problem in issue #4437.
Closes#5729
changelog: Fix `let_and_return` bad suggestion
Fix fp in `borrow_interior_mutable_const`
fixes#5796
changelog: fix false positive in `borrow_interior_mutable_const` when referencing a field behind a pointer.
Fix incorrect suggestion when `clone_on_ref_ptr` is triggered in macros
In the lint `clone_on_ref_ptr`, if the `span` is in a macro, don't expand it for suggestion.
Fixes: #2076
changelog: none
r? @ebroto
Add a cast to the suggestion when the return expression has adjustments.
These adjustments are lost when the suggestion is applied.
This is similar to the problem in issue #4437.
Closes#5729
Don't lint if it has always inline attribute
Don't trigger the lint `trivially_copy_pass_by_ref` if it has `#[inline(always)]` attribute.
Note: I am not particularly familiar with `inline` impacts, so I implemented this the way that if only `#[inline]` attribute is here (without `always`), the lint will still trigger. Also, it will still trigger if it has `#[inline(never)]`.
Just tell me if it sounds too much conservative.
Fixes: #5876
changelog: none
Prelude imports are exempt from wildcard import warnings. Until now only
imports of the form
```
use ...::prelude::*;
```
were considered. This change makes it so that the segment `prelude` can
show up anywhere, for instance:
```
use ...::prelude::v1::*;
```
Fixes#5917
Fix false positive in `PRECEDENCE` lint
Extend the lint to handle chains of methods combined with unary negation.
Closes#5924
changelog: Fix false negative in `PRECEDENCE` lint
This extends PR #73293 to handle patterns (Pat). Unlike expressions,
patterns do not support custom attributes, so we only need to capture
tokens during macro_rules! argument parsing.
Warn about assignments where left-hand side place expression is the same
as right-hand side value expression. For example, warn about assignment in:
```rust
pub struct Event {
id: usize,
x: i32,
y: i32,
}
pub fn copy_position(a: &mut Event, b: &Event) {
a.x = b.x;
a.y = a.y;
}
```
Add unnecessary lazy evaluation lint
changelog: Add [`unnecessary_lazy_evaluations`] lint that checks for usages of `unwrap_or_else` and similar functions that can be simplified.
Closes#5715
should_impl_trait - ignore methods with lifetime params
Fixes: #5617
changelog: don't lint should_implement_trait when an `Iterator::next` case has explicit parameters
Fix: keep parenthesis for suggestion in `useless_conversion` lint
Note: this lint was previously named `identity_conversion`.
fixes: #4750
changelog: fix parenthesis for `useless_conversion` lint suggestion
Add the other overloadable operations to suspicious_arithmetic_impl
In #2268 I idly mused that the other user-overloadable operations could be added to this lint. Knowing that the lint was arguably incomplete was gnawing at the back of my mind, so I figured that I might as well make this PR, particularly given the change needed was so small.
changelog: Start warning on suspicious implementations of the `BitAnd`, `BitOr`, `BitXor`, `Rem`, `Shl`, and `Shr` traits.
In #2268 I idly mused that the other user-overloadable operations could be added to this lint. Knowing that the lint was arguably incomplete was gnawing at the back of my mind, so I figured that I might as well make this PR, particularly given the change needed was so small.
Miri: Renamed "undef" to "uninit"
Renamed remaining references to "undef" to "uninit" when referring to Miri.
Impacted directories are:
- `src/librustc_codegen_llvm/consts.rs`
- `src/librustc_middle/mir/interpret/`
- `src/librustc_middle/ty/print/pretty.rs`
- `src/librustc_mir/`
- `src/tools/clippy/clippy_lints/src/consts.rs`
Upon building Miri based on the new changes it was verified that no changes needed to be made with the Miri project.
Related issue #71193
make a bunch of lints texts adhere to rustc dev guide
According to the rustc-dev guide: "The text should be matter of fact and avoid capitalization and periods, unless multiple sentences are needed"
changelog: make some lint output adhere to the rustc-dev guide
enable #[allow(clippy::unsafe_derive_deserialize)]
Before this change this lint could not be allowed as the code we are checking is automatically generated.
changelog: Enable using the `allow` attribute on top of an ADT linted by [`unsafe_derive_deserialize`].
Fixes: #5789
Fix ICE in `loops` module
changelog: Fix ICE related to `needless_collect` when a call to `iter()` was not present.
I went for restoring the old suggestion of `next().is_some()` over `get(0).is_some()` given that `iter()` is not necessarily present (could be e.g. `into_iter()` or `iter_mut()`) and that the old suggestion could change semantics, e.g. a call to `filter()` could be present between `iter()` and the collect part.
Fixes#5872
Renamed remaining references to "undef" to "uninit" when referring to Miri.
Impacted directories are:
- src/librustc_codegen_llvm/consts.rs
- src/librustc_middle/mir/interpret/
- src/librustc_middle/ty/print/pretty.rs
- src/librustc_mir/
- src/tools/clippy/clippy_lints/src/consts.rs
Upon building Miri based on the new changes it was verified that no changes needed to be made with the Miri project.
Related issue #71193
By moving `{known,used}_attrs` from `SessionGlobals` to `Session`. This
means they are accessed via the `Session`, rather than via TLS. A few
`Attr` methods and `librustc_ast` functions are now methods of
`Session`.
All of this required passing a `Session` to lots of functions that didn't
already have one. Some of these functions also had arguments removed, because
those arguments could be accessed directly via the `Session` argument.
`contains_feature_attr()` was dead, and is removed.
Some functions were moved from `librustc_ast` elsewhere because they now need
to access `Session`, which isn't available in that crate.
- `entry_point_type()` --> `librustc_builtin_macros`
- `global_allocator_spans()` --> `librustc_metadata`
- `is_proc_macro_attr()` --> `Session`
try_err: Consider Try impl for Poll when generating suggestions
There are two different implementation of `Try` trait for `Poll` type:
`Poll<Result<T, E>>` and `Poll<Option<Result<T, E>>>`. Take them into
account when generating suggestions.
For example, for `Err(e)?` suggest either `return Poll::Ready(Err(e))` or
`return Poll::Ready(Some(Err(e)))` as appropriate.
Fixes#5855
changelog: try_err: Consider Try impl for Poll when generating suggestions
Add derive_ord_xor_partial_ord lint
Fix#1621
Some remarks:
This PR follows the example of the analogous derive_hash_xor_partial_eq lint where possible.
I initially tried using the `match_path` function to identify `Ord` implementation like the derive_hash_xor_partial_eq lint currently does, for `Hash` implementations but that didn't work.
Specifically, the structs at the top level were getting paths that matched `&["$crate", "cmp", "Ord"]` instead of `&["std", "cmp", "Ord"]`. While trying to figure out what to do instead I saw the comment at the top of [clippy_lints/src/utils/paths.rs](f5d429cd76/clippy_lints/src/utils/paths.rs (L5)) that mentioned [this issue](https://github.com/rust-lang/rust-clippy/issues/5393) and suggested to use diagnostic items instead of hardcoded paths whenever possible. I looked for a way to identify `Ord` implementations with diagnostic items, but (possibly because this was the first time I had heard of diagnostic items,) I was unable to find one.
Eventually I tried using `get_trait_def_id` and comparing `DefId` values directly and that seems to work as expected. Maybe there's a better approach however?
changelog: new lint: derive_ord_xor_partial_ord
Handle mapping to Option in `map_flatten` lint
Fixes#4496
The existing [`map_flatten`](https://rust-lang.github.io/rust-clippy/master/index.html#map_flatten) lint suggests changing `expr.map(...).flatten()` to `expr.flat_map(...)` when `expr` is `Iterator`. This PR changes suggestion to `filter_map` instead of `flat_map` when mapping to `Option`, because it is more natural
Also here are some questions:
* If expression has type which implements `Iterator` trait (`match_trait_method(cx, expr, &paths::ITERATOR) == true`), how can I get type of iterator elements? Currently I use return type of closure inside `map`, but probably it is not good way
* I would like to change suggestion range to cover only `.map(...).flatten()`, that is from:
```
let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().collect();
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `flat_map` instead: `vec![5_i8; 6].into_iter().flat_map
```
to
```
let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().collect();
^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `flat_map` instead: `.flat_map(|x| 0..x)`
```
Is it ok?
* Is `map_flatten` lint intentionally in `pedantic` category, or could it be moved to `complexity`?
changelog: Handle mapping to Option in [`map_flatten`](https://rust-lang.github.io/rust-clippy/master/index.html#map_flatten) lint
needless_collect: catch x: Vec<_> = iter.collect(); x.into_iter() ...
changelog: Expand the needless_collect lint as suggested in #5627 (WIP).
This PR is WIP because I can't figure out how to make the multi-part suggestion include its changes in the source code (the fixed is identical to the source, despite the lint making suggestions). Aside from that one issue, I think this should be good.
For consistency with `Attribute::has_name` which doesn't mark the attribute as used either.
Replace all uses of `check_name` with `has_name` outside of rustc
There are two different implementation of Try trait for Poll type;
Poll<Result<T, E>> and Poll<Option<Result<T, E>>>. Take them into
account when generating suggestions.
For example, for Err(e)? suggest either return Poll::Ready(Err(e)) or
return Poll::Ready(Some(Err(e))) as appropriate.
Fix FP for `suspicious_arithmetic_impl` from `suspicious_trait_impl` …
As discussed in #3215, the `suspicious_trait_impl` lint causes too many false positives, as it is complex to find out if binary operations are suspicious or not.
This PR restricts the number of binary operations to at most one, otherwise we don't lint.
This can be seen as very conservative, but at least FP can be reduced to bare minimum.
Fixes: #3215
changelog: limit the `suspicious_arithmetic_impl` lint to one binop, to avoid many FPs
Use `(std::)f64::EPSILON` in the examples as suggested in the lints
`float_cmp(_const)` suggests using `{f32|f64}::EPSILON` and it'd be great if the docs mentioned it.
changelog: none
This commit modifies the `substitute_normalize_and_test_predicates`
query, renaming it to `impossible_predicates` and only checking
predicates which do not require substs. By making this change,
polymorphization doesn't have to explicitly support vtables.
Signed-off-by: David Wood <david@davidtw.co>
Ignore not really redundant clones of ManuallyDrop
"Redundant" clones of `ManuallyDrop` are sometimes used for the side effect of
invoking the clone, without running the drop implementation of the inner type.
In other words, they aren't really redundant. For example, futures-rs crate:
```rust
#[allow(clippy::redundant_clone)] // The clone here isn't actually redundant.
unsafe fn increase_refcount<T: ArcWake>(data: *const ()) {
// Retain Arc, but don't touch refcount by wrapping in ManuallyDrop
let arc = mem::ManuallyDrop::new(Arc::<T>::from_raw(data as *const T));
// Now increase refcount, but don't drop new refcount either
let _arc_clone: mem::ManuallyDrop<_> = arc.clone();
}
```
changelog: Ignore redundant clone lint for ManuallyDrop.
"Redundant" clones of `ManuallyDrop` are sometimes used for the side effect of
invoking the clone, without running the drop implementation of the inner type.
In other words, they aren't really redundant. For example, futures-rs crate:
```rust
#[allow(clippy::redundant_clone)] // The clone here isn't actually redundant.
unsafe fn increase_refcount<T: ArcWake>(data: *const ()) {
// Retain Arc, but don't touch refcount by wrapping in ManuallyDrop
let arc = mem::ManuallyDrop::new(Arc::<T>::from_raw(data as *const T));
// Now increase refcount, but don't drop new refcount either
let _arc_clone: mem::ManuallyDrop<_> = arc.clone();
}
```
Ignore redundant clone lint for ManuallyDrop.
Panic multiple args
changelog: Fixes bug with `panic` lint reported in #5767. I also did the same changes to the lints for `todo`, `unimplemented` and `unreachable`, so those lints should now also detect calls to those macros with a message.
Removing RHS snippet from SHADOW_UNRELATED message.
Fixes#5703
I am not sure if I reinvented the wheel here, but I could not really find a snippet function that did this truncation, so I created the function. Please tell me if there was a more obvious way to do this, I am new here. 😄
changelog: Truncates multi-line RHS in shadow_unrelated message if it has more than 5 lines.
improve advice in iter_nth_zero
fixes#5783
*Please keep the line below*
changelog: For iter_nth_zero, the "use .next()" replacement advice is on the last line of the code snippet, where it is vulnerable to truncation. Display that advice at the beginning instead.
This lint catches cases where the last statement of a closure expecting
an instance of Ord has a trailing semi-colon. It compiles since the
closure ends up return () which also implements Ord but causes
unexpected results in cases such as sort_by_key.
Fixes#5080
reprise: rebase, update and address all concerns
Rename collapsable_if fix suggestion to "collapse nested if block"
The name "try" is confusing when shown as quick fix by rust-analyzer
changelog: Rename `collapsable_if` fix suggestion to "collapse nested if block"
The "use .next()" replacement advice is on the last line of the code snippet,
where it is vulnerable to truncation. Display that advice at the beginning
instead.
closes#5783
Fix out of bounds access by checking length equality BEFORE accessing by index.
Fixes#5780
changelog: fix out of bounds access in unnested_or_patterns lint.
Edit: I did not bother reducing a testcase from `librustc_typeck` crate but I can confirm that with the change the crash no longer occurs.
Move range_minus_one to pedantic
This moves the range_minus_one lint to the pedantic category, so there
will not be any warnings emitted by default. This should work around
problems where the suggestion is impossible to resolve due to the range
consumer only accepting a specific range implementation, rather than the
`RangeBounds` trait (see #3307).
While it is possible to work around this by extracting the boundary into
a variable, I don't think clippy should encourage people to disable or
work around lints, but instead the lints should be fixable. So hopefully
this will help until a proper implementation checks what the range is
used for.
*Please keep the line below*
changelog: move [`range_minus_one`] to pedantic
Some accuracy lints for floating point operations
This will add some lints for accuracy on floating point operations suggested by @clarfon in #2040 (fixes#2040).
These are the remaining lints:
- [x] x.powi(2) => x * x
- [x] x.logN() / y.logN() => x.logbase(y)
- [x] x.logbase(E) => x.log()
- [x] x.logbase(10) => x.log10()
- [x] x.logbase(2) => x.log2().
- [x] x * PI / 180 => x.to_radians()
- [x] x * 180 / PI => x.to_degrees()
- [x] (x + 1).log() => x.log_1p()
- [x] sqrt(x * x + y * y) => x.hypot(y)
changelog: Included some accuracy lints for floating point operations
new lint: match_like_matches_macro
Suggests using the `matches!` macro from `std` where appropriate.
`redundant_pattern_matching` has been moved into the `matches` pass to allow suppressing the suggestion where `is_some` and friends are a better replacement.
changelog: new lint: `match_like_matches_macro`
This moves the range_minus_one lint to the pedantic category, so there
will not be any warnings emitted by default. This should work around
problems where the suggestion is impossible to resolve due to the range
consumer only accepting a specific range implementation, rather than the
`RangeBounds` trait (see #3307).
While it is possible to work around this by extracting the boundary into
a variable, I don't think clippy should encourage people to disable or
work around lints, but instead the lints should be fixable. So hopefully
this will help until a proper implementation checks what the range is
used for.